与组合逻辑(给定输入,输出是确定的,与时间无关)相比较,时序逻辑不仅仅与输入信号相关,还与时钟信号相关。
D触发器:在上升沿时(CLK)才将输出(Q)修改为当前的输入值(D),具有存储的性质。
1s 闪烁的 LED 灯
注意根据时钟频率计算计数量。
时序逻辑使用 posedge 表示时钟信号。
module led_flash (
    clk,
    reset_n,
    led
);
    input clk, reset_n;
    output reg led;
    
    reg [24:0] counter;
    
    // ÍÆŒö·ÖΪÁœžö always£¬ÓÐÖúÓÚ·ÖÎö×ÛºÏ
    
    always@(posedge clk or negedge reset_n) // œöœöʱÖÓÉÏÉýÑØµœÀŽ»òÕßžŽÎ»ÐźŲúÉú²Å»áŒ€»îÏÂÃæµÄŽúÂë¿é
        if(!reset_n)
                counter <= 0; // ·Ç×èÈûž³Öµ
        else if(counter == 25000000) // ×¢ÒâÕâÀïÓŠžÃ 25000000 - 1
                counter <= 0; // ºÍÉÏÃæÒ»ÐÐÒ»Æð×ö£¬ÐèҪʹÓÃbegin¿éʵÏÖ
        else
            counter <= counter + 1'd1;
        
    always@(posedge clk or negedge reset_n) // œöœöʱÖÓÉÏÉýÑØµœÀŽ»òÕßžŽÎ»ÐźŲúÉú²Å»áŒ€»îÏÂÃæµÄŽúÂë¿é
        if(!reset_n)
                led <= 0;
        else if(counter == 25000000) 
                led <= !led;
        else
            counter <= counter + 1'd1;
endmodule
二者差值并非绝对的 500ms,问题出在计数变量的初始化上。
 
时序逻辑的 test_bench 怎么写?
`timescale 1ns/1ns
module led_flush_tb();
    
    reg clk;
    reg reset_n;
    wire led;
    
    led_flash led_flash_example (
        .clk(clk),
        .reset_n(reset_n),
        .led(led)
    );
    initial clk = 1;
    always #10 clk = ~clk; // ÊŒÖÕ10ns·×ªÒ»ŽÎ
    
    initial begin
        reset_n = 0;
        #201
        reset_n = 1;
        #2000000000;
        $stop;
    end
endmodule
AXU3EG LED 灯实验
LED 灯控制实验,每秒钟控制开发板上的 LED 灯翻转一次。
Zynq 相比较其它 ARM 平台,其可以使用 PL 端资源定制很多 ARM 端的外设。
LED 硬件介绍
开发板的 PL 端连接了一个红色的 LED 灯,完全由 PL 端控制。如果 PL_LED1 为高电平,三极管导通,灯会亮,否则熄灭。

 扩展板:确定 LED 和 PL 管脚的绑定关系。
 
核心板:
 
创建 Vivado 工程

 
 
 输入工程名和工程存放目录,工程路径不能有中文空格。
 
 工程类型中选择 RTL Project。
 
 目标语言选择 Verilog,VHDL 也可以使用,支持多语言混合编程,并可以在这里创建文件。
 
 
 
 
 选择器件。
 
 
 点击 Finish 完成工程创建。
 
 在弹出的模块定义中可以指定端口,这里暂不指定。
 
 
 双击 led2.v 文件编写,这里定义了一个 32 位寄存器 timer,用于循环计数 0~199999999(1秒钟),计数到 199999999 的时候,寄存器 timer 变为 0,并翻转四个 LED,原来 LED 是灭的话就会点亮,如果原来 LED 为亮的话,就会熄灭。由于输入时钟为 200MHz 的差分时钟,因此需要添加 IBUFDS 原语连接差分信号。
`timescale 1ns / 1ps 
module led(
//Differential system clock
    input sys_clk_p,
    input sys_clk_n,
    input rst_n,
(* MARK_DEBUG="true" *)    output reg  led
    );
(* MARK_DEBUG="true" *)reg[31:0] timer_cnt;
wire sys_clk ;
IBUFDS IBUFDS_inst (
      .O(sys_clk),   // 1-bit output: Buffer output
      .I(sys_clk_p),   // 1-bit input: Diff_p buffer input (connect directly to top-level port)
      .IB(sys_clk_n)  // 1-bit input: Diff_n buffer input (connect directly to top-level port)
   );
always@(posedge sys_clk)
begin
    if (!rst_n)
    begin
      led <= 1'b0 ;
      timer_cnt <= 32'd0 ;
    end
    else if(timer_cnt >= 32'd199_999_999)   //1 second counter, 200M-1=199999999
    begin
        led <= ~led;
        timer_cnt <= 32'd0;
    end
    else
    begin
        led <= led;
        timer_cnt <= timer_cnt + 32'd1;
    end
    
end
//Instantiate ila in source file
//ila ila_inst(
//  .clk(sys_clk),
//  .probe0(timer_cnt),
//  .probe1(led)
//  );
endmodule
添加管脚约束
Vivado 使用的约束文件格式为 xdc 文件。xdc 文件里主要是完成管脚的约束、时钟的约束、以及组的约束。这里我们需要对 led.v 程序中的输入输出端口分配到 FPGA 的真实管脚上。

- Open Elaborated Design:将RTL源代码翻译转换成对应的电路。
- Run Synthesis:同样提供了显示详细电路的功能,相比较前者,更偏向于显示 Xilinx 中已封装好的库。

 
 时钟

 核心板:
 
 核心板:
 
 扩展板:

 扩展板:

 核心板:

在 I/O Ports 中可以看到管脚分配情况。
 
 将复位信号 rst_n 绑定到 PL 端的按键,给 LED 和时钟分配管脚、电平标准,完成后 Ctrl + S,弹出窗口,保存约束文件,文件类型默认为 XDC。

打开生成的 led2.xdc 文件,最基本的 XDC 编写语法:
普通 IO 口只需要约束引脚号和电压,管脚约束:
set_property PACKAGE_PIN "引脚编号" [get_ports "端口名称"]
电平信号约束:
set_property IOSTANDARD "电平标准" [get_ports "端口名称"]
电平标准中 ”LVCMOSS33“ 后面的数字指 FPGA 的 BANK 电压,LED 所在 BANK 电压为 3.3 伏,Vivado 默认要求为所有 IO 分配正确的电平标准和管脚编号。
添加时序约束
先分析综合,然后点击 Constraints Wizard:

 
 时序约束向导分析出设计中的时钟,这里把 sys_clk_p 频率设置为 200MHz,然后点击 Skip to Finish,结束时序约束向导。
 
 
 这个时候 led.xdc 文件已经更新,点击 Reload 重新加载文件,并保存文件。
 
 
生成 BIT 文件

 查看目前状态:
 
Vivado 仿真
利用 Vivado 自带的仿真工具输出波形验证流水灯程序设计结果:
- 设置 VIvado 的仿真配置:

 2. 在 Simulation Settings 窗口中进行如下配置,这里设置成 50ms,其它默认。
 
 3. 添加激励测试文件,点击 Project Manager 下的 Add Sources 图标:

 
 
 
 不添加 IO 端口,
- 编辑内容,首先定义输入和输出信号,实例化 led_test 模块,让 led_test 程序作为本测试程序的一部分,再添加复位和时钟的激励。
`timescale 1ns / 1ps
//
// Module Name: vtf_led_test
//
module vtf_led_test;
// Inputs
reg sys_clk_p;
reg rst_n ;
wire sys_clk_n;
// Outputs
wire led;
// Instantiate the Unit Under Test (UUT)
led uut (
    .sys_clk_p(sys_clk_p),  
    .sys_clk_n(sys_clk_n),     
    .rst_n(rst_n),
    .led(led)
 );
initial 
begin
// Initialize Inputs
    sys_clk_p = 0;
    rst_n = 0;
// Wait for global reset to finish
	#1000;
    rst_n = 1; 
end
//Create clock
always #2.5 sys_clk_p = ~ sys_clk_p;  
assign  sys_clk_n = ~sys_clk_p ;
endmodule 
- 点击 Run Simulation ,选择 Run Behavioral Simulation,进行行为级仿真。
下载
连接 JTAG 线缆,调整到 JTAG 模式启动,开发板上电、
在 HARDWARE MANAGER 界面,点击 Auto Connect 自动连接设备。
选择 FPGA 芯片,右键选择 Program Device,点击 Program。
下载完成后,可以看到 PL LED 每秒钟变化一次。
只有 PL 工程不能直接烧写 Flash。





![YumRepo Error: All mirror URLs are not using ftp, http[s] or file解决办法](https://img-blog.csdnimg.cn/f52718ef424445db87f2d099bcbefcee.png)





![PMP项目管理-[第五章]范围管理](https://img-blog.csdnimg.cn/4cfaa76a85e849cc8a1342f36915c990.png)







