FPGA入门实例一:LFSR
一:任务:
要求使用Verilog语言在Xilinx Virtex-6开发板上实现线性反馈移位寄存器(LFSR)的硬件逻辑设计。
二:前期准备:
基本上完成一个简单的设计需要用到以下几个软件
逻辑:Uedit32(硬件狗吐血推荐)
综合:ISE14.1
仿真:Modelsim SE 10.1b
分析:Chipscope Pro
三:设计流程
逻辑:
首先当然是RTL级设计,俗称硬件逻辑设计。使用的是Uedit32,这个软件相当于一个记事本,但编辑功能十分强大,简直是写Verilog代码的神器,具体下载安装,使用技巧详见(http://blog.163.com/bubble_fish/blog/static/23724712920146180178713/)。 见识了Uedit32的方便快捷后,在写代码之前,小编给大家说几个注意事项。工作过的朋友肯定知道,公司里是很强调代码书写规范的,特别是对于大的设计。如果不按规范做,一个月后调试发现错误,回头再看自己写的代码,估计很多信号都忘了,更不要说检错了;如果一个项目做了一半离职了,接班的人估计得从头开始设计;如果在原版本基础上增加新功能,很可能也要从头来过,很难做到设计的可重用性。这里有一份组长在我第一天实习时就给我的Verilog书写规范,分享给大家,真心希望跟我一样的小白在写代码之前仔细阅读(http://blog.163.com/bubble_fish/blog/static/237247129201461692652979/)。了解书写规范后,我们对任务进行分析。线性反馈移位寄存器(LFSR)的工作原理及应用详见博文(http://blog.sina.com.cn/s/blog_62d9edac01015lsd.html)。以下是Verilog源码:
1 module LFSR 2 ( 3 input usr_clk, //时钟 4 input rst, //复位 5 output reg [2:0] dout //data_out 6 ); 7 8 parameter INIT = 3'h1; //初始值 9 parameter COFF = 3'h4; //生成多项式 10 11 reg [2:0] dout_next; 12 always @ (posedge usr_clk or posedge rst) 13 if(rst) dout <= INIT; 14 else dout <= dout_next; 15 16 integer i; 17 always@(*) 18 begin 19 dout_next[0] <= dout[2]; 20 for(i=1; i<3; i=i+1) 21 if(COFF[3-i]) dout_next[i] <= dout[i-1]^dout[2]; 22 else dout_next[i] <= dout[i-1]; 23 end 24 25 endmodule
综合:
对于xilinx的开发板,使用ISE做为综合工具。软件的使用方法不作介绍,网上一搜一大把。这里只给大家留一个附件,包含全部工程文件和.ucf用户约束(http://download.csdn.net/download/yuzeren48/7644573)。
图1:综合界面
根据LFSR工作原理加上自己定义的参数COFF(3’b100),可知整个LFSR是由一个异或门和三个触发器构成,我们点开Synthesize-XST下的View RTL Schematic,即可看到由代码生成的门级电路,与预期一致。
图2:RTL Schematic
仿真:
ISE是自带仿真软件Isim的,但实际使用效果不是很好。所以我们采用更专业的modelsim来做仿真。Modelsim的具体安装、配置说明详见(请自行百度,如有问题请留言小编)。配置好modelsim后,我们需要写一个testbench来对我们刚才的设计做验证,testbench的作用其实就是给原设计添加各种输入激励信号,然后观察输出信号的波形。具体怎么写testbench请自行百度《编写高效率的testbench》。这里给出本设计的testbench源码
1 `timescale 1 ns / 1 ns 2 3 module lfsr_tb; 4 5 reg rst; 6 reg usr_clk; 7 wire [2 : 0] dout ; 8 9 LFSR UUT ( 10 .rst (rst), 11 .usr_clk (usr_clk), 12 .dout (dout) 13 ); 14 15 always #20 usr_clk = ~usr_clk; 16 17 initial begin 18 $display("lfsr_tb start..."); 19 rst = 1; 20 usr_clk = 0; 21 #100; 22 rst = 0; 23 #10000; 24 $stop; 25 end 26 27 endmodule
下面小编给大家简单写一下modelsim的仿真步骤。
1、 新建一个Sim文件夹,将需要用到的源文件文件,testbench文件(.h .v)放进去
2、 打开modelsim,File-New-Project
3、 把目录指定为刚才建好的文件夹,添加.v文件到Project中
4、 对Project中的.v文件右键,选择Compile-Compile All
5、 选择Library标签,找到work,点击+展开
6、 对已经编译好的.v文件右键,选择simulate without optimization
7、 此时会弹出Sim标签栏,对要仿真的文件右键,选择Add wave
8、 设定仿真时间,例如1000ns
9、 点击工具栏按钮Run
图3展示LFSR仿真结果
图3: LFSR仿真波形
分析:
分析用到的软件主要是Chipscope pro,Chipscope的使用方法详见(百度文库搜索“ChipScope Pro实例教程”)。它跟modelsim的主要区别在于这是真正的板级调试。我们需要根据不同的开发板编写用户约束文件(.ucf),经过ISE综合,布局布线后生成bit文件写入FPGA。ChipScope Pro 的主要功能是通过JTAG 口、在线实时地读出FPGA 的内部信号。这里就有一个问题产生:为什么要用ChipScope来观察信号?我们把输入信号直接连上LED,观察LED的亮灭不就知道信号是怎么跳变的吗?小编就用我们刚编写的实例来简单解释一下这个问题:我们开发板使用的时钟信号是33MHz,dout在每个时钟上升沿都会发生一次跳变,一秒钟会发生33000000次跳变,这种高速跳变肉眼无法分辨,所以根本无法通过LED的亮灭来观测dout变化。图4左上角即为LED显示的dout变化。
图4 板级调试
针对本次设计任务,尽可能多的说明chipscope的用途。决定同时使用ICON核、ILA核、VIO核来分析输入输出信号。具体的操作步骤详见博文(http://blog.163.com/bubble_fish/blog/static/237247129201461682452592/)。图5为检测到的数据波形。
图5 chipscope抓包截图