包含4位led流水灯的Verilog HDL程序文件,RTL原理图时序仿真、板载时钟、led[0]-led[3]的对应引脚编号等内容。
实验主要通过一个变量counter来进行计时,每0.2s进行一次二极管灯的切换,然后通过连接达芬奇开发板二极管的I/O口进行对二极管的控制。
对主程序实现来说,要注意流水灯的循环,在第四个管亮后,要重新让第一个管亮,所以每次都要让led[3]的值赋值给最左边的led[0],即led[3:0] <= {led[2:0],led[3]};
对于仿真程序,要注意我们是50Mhz 的时钟,周期则为 1/50Mhz=20ns,所以每 10ns,电平取反一次,才能正常计时。
对于约束程序,要注意使用的是LVCMOS33标准,且要保证命名的统一。
首先进行工程的创建,然后创建一个design source进行主程序的编写,,然后进行仿真程序的编写,创建一个simulation source,然后定义仿真时间单位 1ns 和仿真时间精度为 1ns,然后设置时钟周期为 20ns,初始化寄存器,例化led模块,代码如下:
//主程序代码
module flow_led(
input system_clock , //系统时钟
input system_reset, //系统复位
output reg [3:0] led //4个LED灯
);
reg [23:0] counter;//24位计数器
//计数器顺序语句,计时 0.2 秒,仿真时设为10,输入时钟为50MHz
always @(posedge system_clock or negedge system_reset)//pos上升同步变1,neg下降同步变0
begin
if (!system_reset)//系统重置时,重新计时
counter <= 24'd0;
else if (counter < 24'd1000_0000)
//else if (counter < 24'd9) //仅用于仿真
counter <= counter + 1'b1;
else
counter <= 24'd0;
end
//移位顺序语句控制led灯 IO 口的电平
always @(posedge system_clock or negedge system_reset)
begin
if (!system_reset)//上电检测,默认亮第一个管
led <= 4'b0001;
else if(counter == 24'd1000_0000)
//else if(counter == 24'd9) //仅用于仿真
led[3:0] <= {led[2:0],led[3]}; //左移一位,注意最左边的数循环回最右边
else
led <= led; //超时后常亮
end
endmodule
//仿真程序代码
`timescale 1ns/1ns // 定义仿真时间单位 1ns 和仿真时间精度为 1ns
module flow_led_tb;
parameter T = 20; // 时钟周期为 20ns
reg system_clock;
reg system_reset;
wire [3:0] led;
//初始化寄存器
initial
begin
system_clock = 1'b0;
system_reset = 1'b0; // 复位
#(T+1) system_reset = 1'b1; // 在第 21ns 的时候复位信号设为1
end
//50Mhz 的时钟,周期则为 1/50Mhz=20ns,所以每 10ns,电平取反一次,才能正常计时
always #(T/2) system_clock = ~system_clock;
//例化led模块
flow_led u0_flow_led
(
.system_clock (system_clock ),
.system_reset (system_reset),
.led (led )
);
Endmodule
//约束程序代码
set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
set_property PACKAGE_PIN R2 [get_ports {led[0]}]
set_property PACKAGE_PIN R3 [get_ports {led[1]}]
set_property PACKAGE_PIN V2 [get_ports {led[2]}]
set_property PACKAGE_PIN Y2 [get_ports {led[3]}]
set_property PACKAGE_PIN R4 [get_ports system_clock]
set_property PACKAGE_PIN U2 [get_ports system_reset]
set_property IOSTANDARD LVCMOS33 [get_ports system_clock]
set_property IOSTANDARD LVCMOS33 [get_ports system_reset]
#管脚约束,定义每个管脚电平标准和每个管脚对应的变量是哪个
修改一下主程序中的计数周期后进行仿真测试,点击run simulation后测试结果如下
可以看到,led灯按照0001-0010-0100-1000的顺序不断循环,时间周期为0.2s,led灯交替亮起,可见实验代码没有问题。
之后进行约束程序的编写,首先创建一个constraints,然后定义每个管脚电平标准和每个管脚对应的变量是哪个,之后点击Open Elaborated Designed进行所有程序的编译,产生的RTL图和编译结果如下
可见所有的程序没有问题,下面运行run synthesis和run implementation查看最终实现结果,然后运行generate bitstream下载比特流,结果如下
可见实验最终结果没有问题,比特流下载成功。
之后我们点击open hardware manager,给达芬奇开发板接上电源,并用正点原子通过电脑usb口与开发板进行连接,在vivado识别到开发板后,直接右键点击program device运行程序,运行结果如下,可见流水灯正常运行,实验结束。