> 文章列表 > FPGA学习笔记(二):时序逻辑之计数器

FPGA学习笔记(二):时序逻辑之计数器

FPGA学习笔记(二):时序逻辑之计数器

与组合逻辑(给定输入,输出是确定的,与时间无关)相比较,时序逻辑不仅仅与输入信号相关,还与时钟信号相关。

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 - 1counter <= 0; // ºÍÉÏÃæÒ»ÐÐÒ»Æð×ö£¬ÐèҪʹÓÃbegin¿éʵÏÖelsecounter <= counter + 1'd1;always@(posedge clk or negedge reset_n) // œöœöʱÖÓÉÏÉýÑصœÀŽ»òÕßžŽÎ»ÐźŲúÉú²Å»áŒ€»îÏÂÃæµÄŽúÂë¿éif(!reset_n)led <= 0;else if(counter == 25000000) led <= !led;elsecounter <= counter + 1'd1;
endmodule

二者差值并非绝对的 500ms,问题出在计数变量的初始化上。
在这里插入图片描述

时序逻辑的 test_bench 怎么写?

`timescale 1ns/1nsmodule 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 beginreset_n = 0;#201reset_n = 1;#2000000000;$stop;endendmodule

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 clockinput 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)
beginif (!rst_n)beginled <= 1'b0 ;timer_cnt <= 32'd0 ;endelse if(timer_cnt >= 32'd199_999_999)   //1 second counter, 200M-1=199999999beginled <= ~led;timer_cnt <= 32'd0;endelsebeginled <= led;timer_cnt <= timer_cnt + 32'd1;endend
//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 中已封装好的库。

在这里插入图片描述
在这里插入图片描述
时钟

FPGA学习笔记(二):时序逻辑之计数器
核心板:
在这里插入图片描述
核心板:
在这里插入图片描述
扩展板:

在这里插入图片描述
扩展板:

在这里插入图片描述
核心板:

在这里插入图片描述

在 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 自带的仿真工具输出波形验证流水灯程序设计结果:

  1. 设置 VIvado 的仿真配置:

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
不添加 IO 端口,

  1. 编辑内容,首先定义输入和输出信号,实例化 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 Inputssys_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 
  1. 点击 Run Simulation ,选择 Run Behavioral Simulation,进行行为级仿真。

下载

连接 JTAG 线缆,调整到 JTAG 模式启动,开发板上电、

在 HARDWARE MANAGER 界面,点击 Auto Connect 自动连接设备。

选择 FPGA 芯片,右键选择 Program Device,点击 Program。

下载完成后,可以看到 PL LED 每秒钟变化一次。

只有 PL 工程不能直接烧写 Flash。