眼高手低不可取,必须动手去做去调才能逐渐进步。本文是一个简单的FPGA工程,实现了根据按键输入,对应不同LED输出的简单功能。包含了实验资源介绍,仿真内容,实验过程,Verilog设计代码,以及功能/时序仿真,详细展示了FPGA的开发流程和操作细节。
目录
一、资源介绍
二、仿真内容
1、内容:
2、目的:
三、实验过程
1、新建ISE工程:
2、Veilog设计电路
新建设计文件
Veilog设计
功能仿真
时序仿真
一些细节
3、上板验证
引脚分配
上板验证
四、笔记总结
1、FPGA开发流程
2、软件
3、设计经验
4、注意
五、参考资料
EDA工具:ISE14.7
仿真软件:Modelsim
芯片:Spartan6
开发板:AX309
仿真相关开发板资源介绍:
1、LED
开发板为共阴极LED,即输入为1才能点亮LED。LED电路以及LED连接到FPGA芯片的引脚如下:
可以看出,FPGA芯片的这几个引脚连接到LED上,而LED是共阴极。要想驱动LED,就需要在这几个引脚输出高电平。
2、按键
按键电路以及按键连接到FPGA芯片的引脚如下:
可以看出,FPGA芯片的这几个引脚连接到按键上,而按键按下时会将引脚与地连接。即:这几个引脚作为芯片的输入,按键按下时,输入为0,反之输入为1;
配合按键实现LED的不同显示:
选择File->New Project:
随后设置工程名称,以及工程文件存放的位置,点击NEXT:
随后选择器件型号等参数:
主要为:系列(family)-型号(Device)-封装(package)-语言(Language)
点击Next后,出现工程的设置信息。检查出现问题,点击Back回到之前的设置部分重新设置;检查无误后点击Finish完成工程创建。
开始电路设计的第一步就是新建Veriliog设计文件,不同EDA软件的新建过程或者文件名称略有差异,但是本质都是Verilog设计文件。
以ISE为例:
点击Project->New Source,或者直接在工程文件上右键,即可得到新建文件选项(类似,如果要直接添加已有的设计文件,可以直接点击Add Source选择文件实现添加):
选择文件类型为Verilog Module(即Verilog的电路设计文件) ,设置文件名称以及存储路径,默认将设计文件添加到当前工程中(如右下角√)
点击Next,同样为新建设计文件的配置信息,检查出现问题,点击Back回到之前的设置部分重新设置;检查无误后点击Finish完成设计文件创建。
注意:
不同EDA软件的新建过程或者文件名称存在差异,但是本质都是一样的。即:先创建一个工程,设置工程名称以及存储,选择器件(即工程要在怎样的平台运行)。工程设置完成需要添加设计文件,测试文件,管脚约束等等,同样有文件名称、存储位置、文件类型等的选择。
如quartus新建Verilog设计文件的步骤如下:
设计代码如下:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: CLL guoliang
//
// Create Date: 11:41:34 05/17/2020
// Design Name:
// Module Name: led_test
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module led_test(
input clk,
input rst_n,
input key1,
input key2,
output reg [3:0]led
);
//
//parameter LEDP = 49_999;
//
reg [31:0]cnt;
reg key2_r;
wire key2_f;
// 功能描述-led显示部分
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
led <= 4'b1111;//复位/默认led全亮
end
else if(!key1)
begin
if(cnt == 32'd49)// key1按下时,led按照1s间隔闪烁
begin
led <= ~led;
end
else
begin
led <= led;
end
end
else if(!key2)
begin
if(key2_f)// key2按下时,led首先初始化为只有一个灯亮,随后led按照1s间隔流水闪烁
begin
led <= 4'b0001;
end
else if(cnt == 32'd49)
begin
led <= {led[2:0],led[3]};
end
else
begin
led <= led;
end
end
else
begin
led <= 4'b1111;
end
end
// 功能描述-计数部分(分频)
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
cnt <= 32'd0;
end
else if(cnt==32'd49)
begin
cnt <= 32'd0;
end
else
begin
cnt <= cnt+1'b1;
end
end
// 功能描述-key2_f生成(按键2按下时,led流水灯初始化)
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
key2_r <= 1'b1;
end
else
begin
key2_r <= key2;
end
end
assign key2_f = key2_r & (~key2);
endmodule
注意:
设计完成,双击Synthesize-XST,执行综合,验证设计是否存在语法错误;无误时会生成相应的RTL硬件电路。
Consel中显示综合结果,显示综合成功与否,如果出错应该返回设计进行查错与修改。可进一步点击Errors和Warnings,查看设计中存在的错误与警告。
新建测试文件,与新建设计文件类似,但是此处选择文件类型为Veilog Test Fixture;随后设置文件名称、存储位置等。
随后点击Next,转至设计源文件选择界面(ISE自动生成测试文件,因此必须选择测试文件对应哪一个设计文件)
选择完成点击Next,转至信息界面,显示测试文件位置,类型,名称,以及对应哪一个设计文件。确认无误后点击Finish。
测试文件添加完成后,选择simulation进入仿真界面,这时就能看见测试文件。双击打开,可以看到测试文件确实对应之前选定的led设计文件(测试文件中已经进行了模块例化)。但是测试文件只是一个大致框架,需要进一步按照个人意愿修改扩充。
仿真文件如下:
`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: guoliang CLL
//
// Create Date: 13:16:31 05/17/2020
// Design Name: led_test
// Module Name: F:/IseFiles/led_test/tsb/led_tsb.v
// Project Name: led_test
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: led_test
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////
module led_tsb;
// Inputs
reg clk;
reg rst_n;
reg key1;
reg key2;
// Outputs
wire [3:0] led;
// Instantiate the Unit Under Test (UUT)
led_test uut (
.clk(clk),
.rst_n(rst_n),
.key1(key1),
.key2(key2),
.led(led)
);
initial
begin
clk = 1;
forever #10 clk = ~clk;
end
initial
begin
// Initialize Inputs
rst_n = 0;
key1 = 1;
key2 = 1;
// Wait 100 ns for global reset to finish
#100;
rst_n = 1;
key1 = 0;
#(20000)
key1 = 1;
key2 = 0;
#20000;
$stop;
end
endmodule
测试文件编写完成以后,选中测试文件,随后双击Simulate Behavioral Model,启动仿真。 仿真结果如下:
可以看出:
默认(复位结束)LED为全亮(1111);
按键1按下(为0),按键2未按下(为1)时:LED按照一定周期亮灭交替,与设计一致。
按键1未按下(为1),按键2按下(为0)时:LED开始按照同样的周期进行流水循环,并且流水循环初始化(即led=0001)只进行了一次,与设计一致。
led状态的改变在计数到49处发生,说明LED周期也和设计一致。
至此,功能仿真验证通过。
在功能仿真部分,我们设置了激励,验证了设计的逻辑无误。完成功能仿真后,我们需要进行布局布线,随后进行时序仿真。
要进行时序仿真,首先需要进行实现(布局布线),即将综合输出的逻辑网表翻译成所选器件的底层模块与硬件原语(翻译过程),将设计映射到器件结构上(映射过程),进行布局布线(布局布线过程)。
双击Implement Design,进行实现。
翻译-映射-布局布线成功后,即可调用Modelsim进行时序仿真。 操作类似,选择Simulation选项,随后选择Post-Route仿真模式,选定仿真测试文件,随后双击Simulate Post-Place 选项,唤起Modelsim执行时序仿真。
可以看出,时序仿真的时候,计数值相比于clk的上升沿存在一定的时延;同样,led状态的转换相比于计数值,也存在一定的时延。作为比较,下图是功能仿真的结果:
可以看出,时序仿真时,计数值cnt在clk上升沿来临后一段时间才会改变;
led状态的转换,发生在时钟上升沿来临后,并且计数值为49以后,因此滞后于计数值改变。
1、为便于修改计数值,设计中最好不要将计数值写死,否则修改起来需要全篇改动,增加额外的工作量。
2、每次修改了设计文件,或者测试文件后,不必要再次重启Modelsim进行仿真,而需要在Modelsim中Recompile改动了的文件,Restart仿真即可。
详细:
在WORK中找到修改了的文件,右键点击Recompile,完成后Restart仿真即可。
3、Modelsim中如何添加模块内部信号到波形窗口。
在sim栏中,选中希望观测的模块,然后右键,选择add wave即可将该模块中所有的信号添加到波形界面;也可以左键选中该模块,然后在右侧隔壁的Objects窗口中,可以选择你希望观测的信号,然后右键,选择add wave按钮。
详见:【Modelsim常见问题】如何添加子模块信号到波形窗口观测
4、文件存放时注意区分类型,如工程文件存放在prj文件夹,测试文件放在tsb文件夹,设计文件放在rtl文件夹等,通过这样的操作可以方便以后的文件管理。
上板验证的首要任务应该完成引脚分配,此处采用约束文件方式进行管脚约束。
新建一个Text文件,在其中进行管脚约束,随后按照.ucf格式存储。
约束文件如下:
##
NET clk LOC = T8 | TNM_NET = sys_clk_pin | IOSTANDARD = "LVCMOS33";
TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 50000 kHz;
##
##
NET rst_n LOC = L3 | IOSTANDARD = "LVCMOS33"; ## Reset Button
##
########LED Pin define#####################
NET led<0> LOC = P4 | IOSTANDARD = "LVCMOS33"; ## LED1
NET led<1> LOC = N5 | IOSTANDARD = "LVCMOS33"; ## LED2
NET led<2> LOC = P5 | IOSTANDARD = "LVCMOS33"; ## LED3
NET led<3> LOC = M6 | IOSTANDARD = "LVCMOS33"; ## LED4
NET key1 LOC = C3 | IOSTANDARD = "LVCMOS33"; ## key1
NET key2 LOC = D3 | IOSTANDARD = "LVCMOS33"; ## key2
保存后,需要将编写的约束文件添加到工程中:ADD Source,选择对应文件,添加后可以在工程目录看到。
保存项目,点击Generate Programming File 进行编译,生成bit流文件,用于FPGA的配置。 编译成功后,可以在console窗口看到成功信息。
至此,经过了工程建立,Verilog代码的编写与调试,经过了功能仿真,布局布线,时序仿真,端口分配,生成bit流文件,以及期间不断地调试修改。终于可以将bit流文件下载到板子上进行实际验证。
双击Configure Target Device打开iMpact软件进行FPGA的下载。
双击Boundary Scan进行JTAG链路扫描。
随后,右键选择Initialize Chain ,初始化链路后识别到FPGA芯片。
双击芯片,即可选择要下载的bit文件,选择后,点击右键选择Program进行下载,下载成功会有提示。
至此,可以观测板子上的现象,进一步验证设计。
实测:看不出LED闪烁---原因是之前为了便于仿真,将延时设置为了1us(49计数),频率过高导致无法分辨;
修改设计文件,再次仿真成功!
至此,led实验基本结束。如果要固化程序,则需要进一步将配置文件下载到掉电不丢失的Flash中。此处不再进行。
黑金Sparten6开发板AX309教程
小梅哥系列学习教材