本文在Vivado2017.3上开展实验,没得板子
一、创建工程
填写文件名
一直选next
,然后进入板卡型号选择界面
选择自己的型号,添加设计资源文件
新建文件夹,存放代码文件
创建代码文件
创建成功
二、 编写工程代码
在编写程序代码之前,先来看看系统框架图
在FPGA内部生成了一个计时器,计时1s来控制LED灯。现在是有一个50MHz的晶振时钟,在晶振时钟下有一个计数器,从0开始计数,每一个时钟周期就加1,那么对于一个50MHz的晶振时钟,一个时钟周期就是20ns(1/50MHz),在一秒内,计数器就会计数5000万个时钟周期。
要实现LED交替闪烁,我们可以判断,当计数器的值大于2500万的时候,控制两个LED的翻转,比如,可以判断当小于2500的时候,01表示第一颗灯亮,10表示第二颗灯亮。
在led_twinkle.v
中输入如下Verilog代码并保存
//该代码来自正点原子
module led_twinkle(
input sys_clk , //系统时钟
input sys_rst_n, //系统复位,低电平有效
output [1:0] led //LED灯
);
//reg define
reg [25:0] cnt ;
//*****************************************************
//** main code
//*****************************************************
//对计数器的值进行判断,以输出LED的状态
assign led = (cnt < 26'd2500_0000) ? 2'b01 : 2'b10 ;// 下划线便于观看,没有实际意义
//assign led = (cnt < 26'd5) ? 2'b01 : 2'b10 ; //仅用于仿真
//计数器在0~5000_000之间进行计数
always @ (posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
cnt <= 26'd0;
else if(cnt < 26'd5000_0000)
// else if(cnt < 26'd10) //仅用于仿真
cnt <= cnt + 1'b1;
else
cnt <= 26'd0;
end
endmodule
修改代码字体大小
三、 分析综合
点击RTL ANALYSIS
下的Open Elaborated Design
等待其分析结果
点击Schematic
就可以看到由Verilog
代码生成的原理图。
点击综合Run Synthesi
,进行综合编译,检查语法错误
接着点击Run Implementation
Synthesis是将高级语言(如Verilog或VHDL)描述的设计转换为门级网表的过程。在这个过程中,综合工具将高级语言描述的设计转换为逻辑门、寄存器、LUT等基本电路元件的组合,并生成一个门级网表。这个过程中,综合工具会对设计进行优化,以提高电路的性能和减少资源的使用。
Implementation是将门级网表映射到FPGA的物理资源上的过程。在这个过程中,实现工具将门级网表映射到FPGA的LUT、寄存器、IO等物理资源上,并生成一个位流文件,该文件描述了FPGA中每个逻辑元件的位置和连接关系。这个过程中,实现工具会对设计进行布局和布线,以最大限度地提高电路的性能和减少资源的使用。
因此,Synthesis和Implementation的区别在于,Synthesis是将高级语言描述的设计转换为门级网表的过程,而Implementation是将门级网表映射到FPGA的物理资源上的过程。implementation也可以被视作将门级网表转化为物理级网表的过程。
下一步就是分配管脚,分配管脚包含手动和脚本两种方式,手动的话是按照原理图进行分配
自动的话是添加XDC文件,进行自动管脚分配
分配管脚之后 ,需要进行点击Generate Bitstream
生成比特流,然后下载到开发板上,在下载固化之前,可以先进行仿真。
三、仿真文件编写
新建tb文件
编写tb文件代码
`timescale 1ns/1ps // 时间标度 1ns精度是1ps
module tb_led_twinkle(
);
// 输入信号
reg sys_clk;
reg sys_rst_n;
// 输出信号
wire [1:0] led;
// 模拟生成时钟信号
// 当工程开始时只执行一次,一般在仿真时候使用
initial begin
sys_clk <= 1'b0;
sys_rst_n <= 1'b0; // 低电平表示复位
// 延迟等待40ns(2个时钟周期)加复位信号拉高,时钟是贯穿始终的不要写在这里
#40 sys_rst_n <= 1'b1;
end
// 每隔10ns将时钟翻转一次,相当于生成了一个周期为20ns的时钟信号
always #10 sys_clk <= ~sys_clk;
// 子模块调用
led_twinkle led_twinkle_u (
// 将端口连接到模块实例
.sys_clk(sys_clk), // 时钟信号
.sys_rst_n(sys_rst_n), // 复位信号
.led(led) // LED信号
)
endmodule
为了便于仿真观看波形,我们可以对源代码进行修改,让其5个时钟周期翻转闪烁一次
//assign led = (cnt < 26'd5)? 2'b01 : 2'b10 ; //仅用于仿真
可以看到仿真波形图已经生成了。
可以将led的显示改成二进制的显示
可以清楚看到led每隔5个时钟周期翻转闪烁一次,可以点run all运行所有的
由于没得板子,暂时无法上板验证,可以看下面的参考资料哦~~~~
本文参考资料