转自 https://www.cnblogs.com/liujinggang/p/9818217.html 侵删
软件平台:
操作系统:Windows 7 64-bit
开发套件:ISE14.7
硬件平台:
FPGA型号:XC6SLX45-CSG324
QSPI Flash型号:W25Q128BV
在FPGA开发过程中,如果我们把bit文件下载到FPGA中,那么当FPGA掉电以后,bit文件就丢失,再次上电的时候,代码就不会运行了。如果想掉电以后,代码还可以运行,那么必须把编译好的文件下载到外部的QSPI Flash中。当文件下载到外部的QSPI Flash中以后,由于QSPI Flash是一种非易失性存储器,掉电以后里面的数据并不会丢失,待重新上电以后,FPGA会自动读取QSPI Flash中的数据把代码加载到FPGA内部的RAM中运行。
由于bit不能直接下载到QSPI Flash中,所以必须先把bit文件转化为.mcs文件或者.bin文件,然后才能下载到QSPI Flash中。
本文主要教大家如何把bit文件转化为.bin文件和.mcs文件,然后下载到外部的QSPI Flash中。同时为了加快上电以后FPGA加载QSPI Flash中mcs文件的速度,我们可以把bit文件配置为4线模式(前提是你的硬件必须支持四线模式),并修改加载的时钟频率,从而大大加快FPGA的启动速度。
1、把编译好的bit文件转化为.bin文件
2、把编译好的bit文件转化为.mcs文件
3、把.bin文件或者.mcs文件烧录到外部的QSPI Flash中
4、修改.bit文件的模式以及支持的时钟频率
module led_top ( input I_clk , input I_rst_n , output [3:0] O_led_out ); reg [31:0] R_cnt_ls ; wire W_clk_ls ; reg R_clk_ls_reg ; reg [3:0] R_led_out_reg ; ////////////////////////////////////////////////////////////////// // 功能:产生1s的时钟 ////////////////////////////////////////////////////////////////// always @(posedge I_clk or negedge I_rst_n) begin if(!I_rst_n) begin R_cnt_ls <= 32'd0 ; R_clk_ls_reg <= 1'b1 ; end else if(R_cnt_ls == 32'd24_999_999) begin R_cnt_ls <= 32'd0 ; R_clk_ls_reg <= ~R_clk_ls_reg ; end else R_cnt_ls <= R_cnt_ls + 1'b1 ; end assign W_clk_ls = R_clk_ls_reg ; ////////////////////////////////////////////////////////////////// // 功能:对输出寄存器进行移位产生流水效果 ////////////////////////////////////////////////////////////////// always @(posedge W_clk_ls or negedge I_rst_n) begin if(!I_rst_n) R_led_out_reg <= 4'b0001 ; else if(R_led_out_reg == 4'b1000) R_led_out_reg <= 4'b0001 ; else R_led_out_reg <= R_led_out_reg << 1 ; end assign O_led_out = ~R_led_out_reg ; endmodule
写好待测代码,并添加物理约束文件绑定好管脚,我的开发板上的约束文件如下
NET I_clk LOC = V10 | TNM_NET = sys_clk_pin | IOSTANDARD = "LVCMOS33"; TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 50000 kHz; NET I_rst_n LOC = N4 | IOSTANDARD = "LVCMOS15"; ## SW2 pushbutton NET O_led_out<0> LOC = V5 | IOSTANDARD = "LVCMOS33"; ## LED1 NET O_led_out<1> LOC = R3 | IOSTANDARD = "LVCMOS33"; ## LED2 NET O_led_out<2> LOC = T3 | IOSTANDARD = "LVCMOS33"; ## LED3 NET O_led_out<3> LOC = T4 | IOSTANDARD = "LVCMOS33"; ## LED4
1、编写好代码和约束文件,双击Generate Programming File成bit
2、如果上一步你没做任何设置的话你的工程目录下只会产生一个bit文件,如果需要产生bin文件的话,选中Generate Programming File,右键选择Process Properties...
3、在弹出的窗口中单击General Options,并勾选-g Binary选项,并点击最下面的OK
4、Generate Programming File前面变成了“问号”图标
5、重新双击Generate Programming File,完毕以后工程目录就生成了.bin文件
在ISE不支持bin文件下载到QSPI Flash,但是Vivado支持,后续会有Vivado调试教程以及烧录教程。
1、编写好代码和约束文件,双击Generate Programming File成.bit文件
2、双击Configure Target Device
3、在弹出的窗口中点击OK
4、在弹出的ISE iMPACT中双击Create PROM File(PROM File Formatter)
5、在弹出的PROM File Formatter窗口中选择Configure Signal FPGA,并点击右边绿色的箭头进入Step 2
6、然后选择Storage Device(bits)为外部QSPI Flash的容量,我的QSPI Flash型号是W25Q128BV,容量为128Mbits,所以我选择128M。接着点击的Add Storage Device,然后点击绿色的箭头进入Step 3
7、点击上图中的Add Storage Device,然后点击下图的箭头进入Step3
8、设置Output File Name为.mcs文件的名字,我设置为和.bit文件的名字相同(这一项可以随便设置)。设置Output File Location为.bit文件所在的目录(这一项也可以随便设置),File Format设置为MCS。
9、点击上图中最下面的OK,弹出以下窗口
10、在上图中直接点击OK,在弹出的新窗口中选择要转化的.bit文件并点击右下角的“打开”
11、在弹出的新窗口中选择NO
12、在弹出的新窗口中选择OK
13、双击左侧的Generate File...,生成.mcs文件
14、生成完毕以后会出现Generate Succeeded字样
15、工程目录下出现了.mcs文件
16、双击Boundary Scan
17、点击Initialize Chain图标(这一步一定要保证开发板处于上电状态并且Jtag线连接正常)
18、在弹出的窗口中选择NO(因为我们马上要把.mcs烧录到Flash中,而不是下载.bit文件,所以选择NO)
19、在新弹出的窗口中选择OK
20、双击FPGA上面的那个虚线框包裹起来的图标
21、在弹出的文件选择窗口中选择之前生成好的.mcs文件,并点击打开
22、接着在弹出的新窗口中选择芯片型号为W25Q128BV,Data Width为1,点击OK
23、选中FPGA上面的FLASH图标,右键在弹出的菜单中单击Program
24、在弹出的新窗口中选择OK
25、接着就进入了烧录QSPI Flash的过程,这个过程与下载.bit相比要慢的多,需要耐心等待
26、下载成功以后出现Successful字样
27、接着关掉开发板的电源然后再打开,等一小段时间以后,程序就开始自动运行了。
可以发现,产生的.mcs文件只有3.89M,但是重新上电到程序开始执行却花费了好几秒的时间,如果工程十分庞大,则FPGA选型的时候势必会选择逻辑资源更多的FPGA,那么编译后产生的.mcs文件会大的多,上电后加载的时间也会更长,所以在实际项目中,往往会修改bit文件的配置参数来加快上电以后代码的加载速度。具体步骤如下
1、编写好代码和约束文件,双击Generate Programming File成bit
2、选中Generate Programming File,右键选择Process Properties...
3、在弹出的窗口中单击Configuration Options,并设置Configuration Rate为26MHz,设置Set SPI Configuration Bus Width参数为4。并点击最下面的OK
注意:Configuration Rate这个参数的值不能超过你使用的QSPI Flash芯片手册中指定的最高的读频率,大多数QSPI Flash的芯片手册会在第一页说它们支持的频率高达100M甚至更高,但是其实这个频率并不是指芯片支持的读数据频率,Flash芯片支持的读数据频率一定要在芯片手册电气特性(Electrical Characteristics)那一节找。如果你选择的时钟频率超过QSPI Flash支持的最高读取频率太多,出现的现象就是FPGA根本无法加载QSPI Flash中的镜像文件导致FPGA启动失败;如果你选择的时钟频率超过QSPI Flash支持的最高读取频率一点点的话,出现的现象就是FPGA加载QSPI Flash中的镜像文件大概率失败。所以一般选择的Configuration Rate参数值要稍微低于QSPI Flash支持的最高读频率。
举三个例子:
Micron公司的N25Q064A支持的最高频率为108MHz,但支持的读命令频率为54MHz,对于这个器件来说Configuration Rate不能选的高于54MHz
Macronix公司的MX25L25645G支持的最高频率为133MHz,但支持的读命令频率为50MHz,对于这个器件来说Configuration Rate不能选的高于50MHz
本文使用的Winbond公司的W25Q128BV支持的最高频率为104MHz,但支持的读命令频率为33MHz,对于这个器件来说Configuration Rate不能选的高于33MHz,我们选择为26MHz
另外要说明的是Configuration Rate这个值对于不同的FPGA来说,值的范围不同。我当前使用的XC6SLX45支持的最高频率仅为26MHz,而XC7K325T支持的最高频率高达66MHz。
还有一点要注意的是,Set SPI Configuration Bus Width可以设置为4的前提是你的开发板上QSPI Flash和FPGA之间四根数据线都是连通的,并且PCB上建议做好四根数据线的蛇形等长。
4、接着重新生成.bit文件,然后把.bit文件按照上文的方法生成.mcs文件下载到QSPI Flash中,这个过程不在重复。
5、烧录完毕以后,重新给开发板断电然后再上电,你会发现上电的瞬间,程序就开始运行了,几乎感觉不到等待的时间。由于XC6SLX45这个器件的资源相较于7系列FPGA来说逻辑资源并不算多,生成的mcs文件并不算大,所以才这么快,而对于高端一点的FPGA来说,FPGA编译后的镜像文件能达到十几兆甚至更大,比如XC7K325t生成的镜像文件约为10M左右,所以即使你这么设置了还是有一点延时的,不过比单线肯定是要快的多。注意,生成的FPGA镜像文件大小与FPGA型号有关,与逻辑代码的多少无关,在同一块FPGA中,你写一个流水灯的代码和调用了几个FFT,FIR数字滤波器IP核的信号处理代码生成的FPGA镜像文件的大小是相同的。
至此,整个实验过程全部完毕。
1、在生成bit文件的设置中勾选-g Binary选项可以生成bin文件
2、在生成mcs文件之间提前对bit进行速率与位宽的设置可以提高FPGA从Flash加载程序的速度
3、设置Configuration Rate参数之前一定要阅读QPSI Flash芯片手册的电气特性(Electrical Characteristics)一节,找到支持的最高频率。