閱讀822 返回首頁    go 阿裏雲 go 技術社區[雲棲]


ZED-Board從入門到精通(四):從傳統FPGA開發到PL開發的轉變

數字電路經過半個世紀,從分立元件到小規模集成電路、中等規模集成電路、大規模、超大規模,集成度越來越高,運算能力越來越強,功耗越來越低,人類已經將數字集成電路發展到接近摩爾定律極限。

FPGA是這樣一類數字電路,它可以反複修改自身邏輯功能,具有靈活多變的特性,設計FPGA的過程其實是遵循數字電路設計的一般流程的:

(1)需求分析

(2)抽象邏輯表示(真值表、狀態流圖)

(3)具體邏輯表示(HDL、布爾方程)

(4)將邏輯表示綜合為可實現的電路(門電路、LUT和觸發器)

(5)驗證

 

FPGA邏輯工程師一般是從應用需求出發,用Verilog或VHDL來描述算法,並通過綜合實現工具、仿真工具、調試工具來協助完成設計。

針對Xilinx器件,開發工具為ISE(Project Navigator,ISim,iMact,Chipscope),有時需要用Modelsim工具完成HDL仿真。

 

Zynq內部包含PL,資源前麵已經說過了,大量LUT,FF,DSP48E1等著你來組織,開發PL可以完全脫離PS,采用傳統開發工具ISE完成。

下麵給出隻利用PL實現流水燈的例子,希望能有拋磚引玉的功效。

上一節介紹了使用ARM控製流水燈的例子,這裏完成同樣的功能,但用PL實現控製,將PS冷落一旁,不用理它。

首先運行ISE Design Suite 14.5,打開Project Navigator軟件。

File->New Project,新建一個工程,彈出對話框如下:

按照上圖進行工程設置,然後點Next

 

 

設置器件為XC7Z020,即我們Zedboard上的主芯片型號。封裝為CLG484,速度級別為-1,語言選擇VHDL。點Next,Finish。

我們分析一下怎樣完成這個設計。數字電路都需要有時鍾源,我們的PL也不例外,板子上有專為PL提供時鍾輸入的晶振,在原理圖中找到:

可見晶振輸入為100MHz,直接送入Y9引腳(位於PL部分)。如此高的時鍾速率,需要經過分頻,LED閃爍速率最好低於10Hz,這樣人眼才能分辨出來。

用ISE提供的IP核可以實現分頻,在工程中Add Source:

選擇IP(Core Generator),輸入名稱為clk_module,如上圖,點Next。

 

 

從“FPGA Features and Design”中"Clocking“下找到Clocking Wizard,點Next,Finish。進入配置IP的環節。

 

 

第一步,默認設置,Next。。。

 

 

 

第二步,將CLK_OUT1輸出頻率設置為5MHz(貌似不能再小了),其他不改,點Next。

第三步裏把複位和鎖定引腳去掉,如下圖所示,後麵都一路Next到結束。

 

這樣生成了第一個分頻器,輸入為100MHz,輸出為5MHz,需要進一步分頻。

 

再New Source一下,選VHDL模塊,命名為myled.vhd,輸入代碼如下:

----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    20:59:03 08/16/2013 
-- Design Name: 
-- Module Name:    myled - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity myled is
    Port ( clk : in  STD_LOGIC;
			  rst : in  STD_LOGIC;
           led : out  STD_LOGIC_VECTOR(7 downto 0));
end myled;

architecture Behavioral of myled is
signal clk_5M : STD_LOGIC;
signal localbuffer :STD_LOGIC_VECTOR(7 downto 0);

component clk_module
port
 (-- Clock in ports
  CLK_IN1           : in     std_logic;
  -- Clock out ports
  CLK_OUT1          : out    std_logic
 );
end component;
begin

myclk : clk_module
  port map
   (-- Clock in ports
    CLK_IN1 => clk,
    -- Clock out ports
    CLK_OUT1 => clk_5M);
	process(clk_5M,rst)	
	variable cnt : integer := 0;
	begin
		led <= localbuffer;
		if(rst = '1') then
			localbuffer <= X"01";
		elsif(clk_5M'EVENT and clk_5M = '1')
		then
			cnt := cnt + 1;
			if (cnt = 5000000)
			then
				localbuffer <= localbuffer(6 downto 0)&localbuffer(7);
				cnt := 0;
			end if;
		end if;
	end process;
	
end Behavioral;


 

這裏使用計數器實現了分頻,輸出為1Hz。

 

Add Source,選UCF,命名myled.ucf,內容如下:

 

## 
##  This is an updated UCF file from the original version by Digilink. 
##  The CS signal has been removed and all the other signals are mapped to 
##  proper pin on the Zynq FPGA. 
##  For the reset, the middle-push button is used.
##  Modified by Farhad Abdolian (fabdolian@seemaconsulting.com) Nov. 5, 2012
##

Net "clk" LOC=Y9 | IOSTANDARD=LVCMOS33;
Net "clk" TNM_NET = sys_clk_pin;
TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 100000 kHz;

NET "led[0]" LOC = T22;
NET "led[1]" LOC = T21;
NET "led[2]" LOC = U22;
NET "led[3]" LOC = U21;
NET "led[4]" LOC = V22;
NET "led[5]" LOC = W22;
NET "led[6]" LOC = U19;
NET "led[7]" LOC = U14;
NET "led[7]" IOSTANDARD = LVCMOS33;
NET "led[6]" IOSTANDARD = LVCMOS33;
NET "led[5]" IOSTANDARD = LVCMOS33;
NET "led[4]" IOSTANDARD = LVCMOS33;
NET "led[3]" IOSTANDARD = LVCMOS33;
NET "led[2]" IOSTANDARD = LVCMOS33;
NET "led[1]" IOSTANDARD = LVCMOS33;
NET "led[0]" IOSTANDARD = LVCMOS33;

#We use the center push button as the reset for this project
Net "rst" LOC = P16 | IOSTANDARD = LVCMOS33;


源文件都已經OK,接下來進行綜合、實現、生成bit、iMPACT下載即可(按照標準FPGA開發流程),效果與前麵的實驗相同,略去不表。這裏由於邏輯比較簡單,省去了功能仿真、時序仿真等流程。真正的邏輯開發最好經過仿真後再下載到硬件中。

 

從上麵這個例子發現,不考慮ARM時,PL部分開發與普通的FPGA開發並沒有任何區別。

 

恰恰是由於ARM的存在,我們的PL可以實現更多複雜的功能!

 

1. DDR控製。采用邏輯來實現DDR2存儲器訪問非常複雜,調試也非常耗費時間。ARM核的存在,使得PL可以借助ARM來做DDR2控製器,訪問時隻需遵循PS與PL之間的通信協議——AXI就可以了。

2. 操作係統。同樣,FPGA上運行操作係統是一件費力不討好的事情,浪費大量邏輯資源,如果用軟核實現CPU,性能又不高。如果有ARM硬核負責操作係統的日常維護,必要時FPGA仍然通過AXI總線與ARM上的操作係統進行交互。

3. 網絡。

4. USB通信

 

從傳統FPGA開發到Zynq上PL開發需要改變一個觀念:邏輯可以實現一切。嵌入硬核恰恰說明一點:有些事還是別讓邏輯來做!

最後更新:2017-04-03 16:48:59

  上一篇:go poj 1966 Cable TV Network 點聯通度
  下一篇:go When does the Oracle library for st_shapelib.dll need to be changed?