这样生成了第一个分频器,输入为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开发需要改变一个观念:逻辑可以实现一切。嵌入硬核恰恰说明一点:有些事还是别让逻辑来做!