【从零开始走进FPGA】美好开始——我流啊流啊流
发布时间:2016-2-24 09:57
发布者:designapp
按照基于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) 输入代码,定义输入输出接口,如下所示: [color=]module water_led [color=] ( [color=] input clk, //global clock 50MHz [color=] input rst_n, //global clock reset [color=] output [5:0] led_data //user led interface [color=] ); [color=] endmodule (2)clk_design.v模块设计 由于系统输入时钟是50Mhz,若以50MHz的速度变换LED等,人眼压根分辨不出来。因此利用分频原理,来对50MHz进行分频,而适应人眼。本模块将50MHz分频至10Hz,人眼分辨的极限是25Hz,因此10Hz能感觉得到(可以随机修改)。Led_en的频率计算公式:clk_led_en = 50_000000/(49_000000+1) = 10Hz,具体代码如下: [color=]module clk_design [color=] ( [color=] input clk, [color=] input rst_n, [color=] output led_en [color=] ); [color=] reg [22:0] cnt; //49_99999,100ms [color=] parameter LED_CNT = 49_999999; [color=] always@(posedge clk or negedge rst_n) [color=] begin [color=] if(!rst_n) cnt else if(cnt cnt [color=] else cnt [color=] end [color=] assign led_en = (cnt == 23'd49_99999) ? 1'b1 : 1'b0; [color=] endmodule 模块没有分频产生10Hz的频率,而是生成了10Hz的使能时钟,目的是防止时钟满天飞,使得FPGA 内部布局布线紊乱,影响全局功能。虽然如此简单的工程可以不用考虑,但是“习惯了严谨便成为了一种风范”,因此使用使能时钟,来对具体的时序进行操作。具体使能时钟、门控时钟的异同、优劣将会在后续章节中解说。 (3)led_display.v模块设计 根据输入的led_en使能信号,来操作led灯的效果,此处采用最简单的算法——递增进位。代码如下所示: [color=]module led_display [color=] ( [color=] input clk, [color=] input rst_n, [color=] input led_en, [color=] output reg [5:0] led_data [color=] ); [color=] always@(posedge clk or negedge rst_n) [color=] begin [color=] if(!rst_n) led_data [color=] else if(led_en) led_data [color=] else led_data [color=] end [color=] endmodule [color=] (4)从新修改water_led_design顶层文件,添加相关例化模块。最后结果如下: [color=] module water_led_design [color=] ( [color=] input clk, //global clock 50MHz [color=] input rst_n, //global clock reset [color=] output [5:0] led_data //user led interface [color=] ); [color=] //------------------------- [color=] //generater clock 10Hz [color=] wire led_en; [color=] clk_design clk_design_inst [color=] ( [color=] .clk (clk), [color=] .rst_n (rst_n), [color=] .led_en (led_en) [color=] ); [color=] //------------------------- [color=] //set the display of led [color=] led_display led_display_inst [color=] ( [color=] .clk (clk), [color=] .rst_n (rst_n), [color=] .led_en (led_en), [color=] .led_data (led_data) [color=] ); [color=] 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已损坏 |
网友评论