第六章 美好开始——我流啊流啊流
0赞按照基于Windows的语言(C、C++、C#)等编程语言的初学入门教程,第一个历程应该是“Hello World!”的例程。但由于硬件上的驱动难易程度,此例程将在在后续章程中推出。硬件工程师学习开发板的第一个例程:流水灯,一切美好的开始。
本章将会在设计代码的同时,讲解Quartus II 软件的使用,后续章节中只讲软件的思想,以及解决方案,不再做过多的累赘描述。
一、Step By Step 建立第一个工程
(1)建立第一个工程,File-New-New Quartus II Project,如下图所示,OK。
(2)Next,如下图所示,选择工程目录(不能有空格,中文路径),同时输入工程名与顶层文件名。
(3)若有现成的代码,可以直接选择添加入工程;否则,直接next,进入下一步,如下图所示:
(4)根据自己的硬件设施,选择相应的设备目标器件。
(5)Next,Finish。
二、工程代码设计
1.water_led_design工程文件结构:
如上图所示,工程分为三个模块,分别为:
(1)顶层模块 : 例化各个模块,工程的最高级别文件。
(2)分频模块 : 通过分频得到固定的频率(10Hz)。
(3)LED显示模块: 随固定频率,来操作LED灯。
2.代码设计
(1)warter_led.v模块设计
a) New-File,新建verilog文件,保存于新建在工程目录下的src文件夹中(只是为了工程文件结构组织的清晰,更善于管理)。如下图所示:
b) 输入代码,定义输入输出接口,如下所示:
module water_led
(
input clk, //global clock 50MHz
input rst_n, //global clock reset
output [5:0] led_data //user led interface
);
endmodule
(2)clk_design.v模块设计
由于系统输入时钟是50Mhz,若以50MHz的速度变换LED等,人眼压根分辨不出来。因此利用分频原理,来对50MHz进行分频,而适应人眼。本模块将50MHz分频至10Hz,人眼分辨的极限是25Hz,因此10Hz能感觉得到(可以随机修改)。Led_en的频率计算公式:clk_led_en = 50_000000/(49_000000+1) = 10Hz,具体代码如下:
module clk_design
(
input clk,
input rst_n,
output led_en
);
reg [22:0] cnt; //49_99999,100ms
parameter LED_CNT = 49_999999;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt <= 23'd0;
else if(cnt < LED_CNT)
cnt <= cnt + 1'b1;
else
cnt <= 23'd0;
end
assign led_en = (cnt == 23'd49_99999) ? 1'b1 : 1'b0;
endmodule
模块没有分频产生10Hz的频率,而是生成了10Hz的使能时钟,目的是防止时钟满天飞,使得FPGA 内部布局布线紊乱,影响全局功能。虽然如此简单的工程可以不用考虑,但是“习惯了严谨便成为了一种风范”,因此使用使能时钟,来对具体的时序进行操作。具体使能时钟、门控时钟的异同、优劣将会在后续章节中解说。
(3)led_display.v模块设计
根据输入的led_en使能信号,来操作led灯的效果,此处采用最简单的算法——递增进位。代码如下所示:
module led_display
(
input clk,
input rst_n,
input led_en,
output reg [5:0] led_data
);
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
led_data <= 6'b0;
else if(led_en)
led_data <= led_data + 1'b1;
else
led_data <= led_data;
end
endmodule
(4)从新修改water_led_design顶层文件,添加相关例化模块。最后结果如下:
module water_led_design
(
input clk, //global clock 50MHz
input rst_n, //global clock reset
output [5:0] led_data //user led interface
);
//-------------------------
//generater clock 10Hz
wire led_en;
clk_design clk_design_inst
(
.clk (clk),
.rst_n (rst_n),
.led_en (led_en)
);
//-------------------------
//set the display of led
led_display led_display_inst
(
.clk (clk),
.rst_n (rst_n),
.led_en (led_en),
.led_data (led_data)
);
endmodule
3.代码编译
(1)通过Processing-Start Compilation,或者工具栏的图标如下:
(2)编译结果如下,可见相关信息:
(3)警告的分析及解决:
a) Warming(4)如上图所示,具体解释如下:
i. 没有电容配置
ii. 没有把unused的pin设置为三态。在Assignment-Device-Device and Pin Opitions-Unused Pins,设置如下图所示:
iii. 没有电容配置
iv. 可以忽略
b) Critical Warming(5)如上图所示,具体解释如下:
i. 引脚没有分配IO
ii. 没有sdc时序约束文件
iii. 没有sdc约束文件
iv. 时序没有达到要求
v. 时序没有达到要求
出现这些警告的原因是因为Quartus II 10.1以后的版本软件,不再自带TimeQuest Timing Analyzer,只有Classic Timing Analyzer,虽然不加sdc时序约束对于一般情况也不一定会有错,但软件设计的必然会出现这样的警告。关于TimingQuest sdc,会在后续章节中阐述,此处不做具体说明。
关于Quartus II 警告信息分析以及零警告的处理,可以右击警告查看help,altera会告诉您相应的解决方案;此外,Bingo已上传Chinaaet“Quartus II 警告分析.pdf”,下载地址为:http://www.chinaaet.com/lib/detail.aspx?id=86271
初学折有不到之处可以查阅该pdf,记住,永远不要轻易忽略警告。
三、Modelsim-Altera仿真
1.为什么要仿真
首先讨论两个问题:
(1)仿真?是真的吗?
仿真,只是为了模拟真实现象,测试代码的行为以及时序的正确性;当然,仿真永远是模仿的,不可能是绝对准确的,只能在一定程度上模拟真实时序,让我们的设计变得更可靠。仿真对于电路设计者,只是一个软件测试的平台,而不是实际硬件设施的测试结果。
(2)一定要仿真吗?
未必!如果你有足够的把握时序的准确性,脑子里能够完成整个电路的时序逻辑工作流程,仿真就不是那个必须的了;对于已经成型的模块,保证时序准确的情况下,何必在徒劳的仿真呢?按常理,是现有Quartus II软件,再有仿真软件的吧,Testbench只是测试程序,链接两者之间的桥梁。
回想,在n年前的老工程师,用block中用与非门与74系列芯片设计的原理图,要仿真似乎变得很难?那些老前辈们是通过实物的测试,不断的修正、改善,最后才得到可靠的电路。
因此,仿真 不是必须的。Bingo就经常不仿真!不是说懒,是因为脑子中的电路时序逻辑,本能性的能够保证电路的准确性,或者说出了问题能够自行改正,不会失去了方向。所谓代码在电脑上,电路在脑子中,每一句行为级语言,都加增添一个电路。
当然,并非每一个人都可以这样子的。对于初学者而言,仿真是非常重要的一个过程。原因是因为在初学者脑子中,还未呈现固定逻辑实现的时序工作流程,换句话说,经验不够丰富吧。
当然在时序很复杂而且庞大时,时序仿真是必须的,因为在这种情况下,大脑的模拟也许无法跟计算机的计算速度比拟了。
前文安装Quartus II 软件章节有提到过,Quartus II 9.1以前版本,软件自带仿真器,而9.1以后的版本,需要第三方软件的支持。第三放仿真软件有很多,而用的最多的,固然是Modelsim-Altera。本章节中Quartuus II 11.0与Modelsim-Altera协同工作,仿真测试本例程的代码的时序。希望通过节的分析,对时序逻辑上有一个更深刻的认识。
2.仿真必备的知识
Altera_Modelsim仿真资料:http://www.chinaaet.com/lib/detail.aspx?id=86257
四、配置FPGA
1.配置综合
配置引脚简单的说就是通过软件的设置,将FPGA内部逻辑信号映射到IO上,具体有下面几种方法:
(1)在Assignments-Pin Planner中对应IO手动输入IO引脚
(2)Quartus II Tcl Console 手动输入,输入的格式为:“set_location_assignment PIN_28 -to clk”
(3)Tcl Scripts,通过调入tcl 文件来进行映射
(4)在Assignments-Import Assignments,通过调入(2)格式的文件来进行映射。
后面两种方法具体步骤可见网友“小时不识月”的网页教程:http://www.cnblogs.com/yuphone/archive/2010/01/18/1650612.html
配置好查看Quartus II Pin Planner,如下图所示:
配置完引脚在进行综合,就少了上述提醒没有进行引脚配置的2个警告。
注意1:对于Quartus II 中引脚配置的方法,若用最原始的第一种GUI手动输入配置,需要第一次编译后让软件在Pin Planner生成IO,然后再GUI下手动配置;若用其他三种方法,可以在第一次编译以前,用命令输入配置信息,在Quartus II 编译后,自动识别映射信息,达到同样的效果。
注意2:对于系统及的FPGA设计,由于工程之大,引脚之多,一般编译综合需要耗费很大的时间,因此一般采用不采用第一种方法,而且在第一次编译以前事先导入映射信息。
2.目标板下载模式
总而言之,Quartus II 软件只是个GUI的 用户终端,用来设计代码,综合FPGA逻辑电路,最终的目的,是通过USB Bluster、并口或者其他途径下载到目标板。具体有以下几种:
(1)配置FPGA——JTAG Mode
所谓配置FPGA就是将sof文件电路配置FPGA的SRAM(FPGA是基于SRAM格式的),在不掉电的情况下进行现场配置,验证。此方式是通过JTAG接口下载的。
(2)烧录EPCS——Active Serial Programming
所谓烧录EPCS是生成的代码信息烧录到存储芯片EPCS中,通过配置信号或者重新上电,配置FPGA SRAM;由于EPCS flash结构,因此EPCS中的掉电不丢失(类似于CPLD)。烧录EPCS有两种方法,如下
a) 通过ASP接口下载pof文件
b) 通过JTAG接口下载jic/jam文件,jic/jam文件由Quartus II 软件对sof文件进行转换后得到。
(3)Passive Serial并口下载
(4)In Socket Programming下载
以上两种模式,由于应用不是很广泛,在此不做过多阐述。
综上说明,在成本敏感,或者电路板空间苛刻的情况下,完全可以舍去ASP接口,而用JTAG来替换。考虑到Altera设计了两种接口的原因,是给用户更大的选择性,特殊场合下,可以只存在ASP接口,只进行一次烧录,而不用JTAG接口进行测试。
3.JTAG的下载
(1)在工具栏打开或者菜单栏Tool打开Programming
(2)若没找到Hardware,在Hardware Setting中找到USB Bluster。
(3)选择JTAG Mode
(4)若没有自动加载sof文件,点击Add File导入该工程的sof文件
(5)最后点击Start,等待下载完毕,如下图所示:
4.EPCS的下载
(1)在ASP模式下
a) Mode切换为Active Serial Programming模式
b) Change File为pof文件
c) 点击Start,等待下载完毕。因为Flash速度比SRAM慢,因此下载相对于Flash会较慢。
至此,可见目标板上的流水灯已递增的形式循环点亮。
(2)在JTAG模式下
a) 用Quartus II 自动生成的sof文件,通过软件转换为jic文件,步骤如下:
i. 打开File-Convert Programming File。
ii. 在Programming File Type选择jic文件。
iii. Configuration device中选择目标板对应的EPCS型号
iv. File name可默认或任意修改
v. 在File/Data area选中Flash Loader,然后右侧点击Add Device,找到自己型号的FPGA,确认。
vi. 在File/Data area选中SOF Data,然后在右侧点击Add File,加载本工程目录下的sof文件。
vii. 在File/Data area选中加载的sof文件,然后再右侧点击Properties,选中Compression(压缩),确认。(若EPCS容量允许下,可以省略此步骤,来提高下载速度)
viii. 点击Generate,生成jic文件,最终如下图所示,然后Close。
b) 打开Programming,选择JTAG Mode。
c) 选择前面生成的jic文件,选中jic文件后面的Program/Configure
d) 点击Start,等待下载完成,如下图所示:
至此,可见目标板上的流水灯已递增的形式循环点亮。
5.编程/配置失败原因
(1)USB下载器没有连接好或USB线太长(没插上,或者接口插错)
(2)设备没上电。
(3)FPGA Device型号选择错误
(4)EPCS型号选择错误
(5)布局布线不佳,导致下载时序错误
(6)FPGA芯片已损坏
(7)EPCS芯片已损坏
(8)USB Bluster已损坏