一:xilinx FPGA 在线升级方案:(系统搭建:MicroBlaze软核处理器,uart控制器,Axi-lite-user用户通信接口,MIG DDR3控制器,中断控制器等,以太网控制器)
1.跑一个microblaze,引出一个网口和一个串口。
2.串口实现控制台功能,可以修改本机ip地址。
3.网口有dhcp功能。
4.通过浏览器页面访问microblaze,上传固件,cpu拿到数据后写到flash中,可选做校验。
5.网页做个进度条。
6.可选读出flash内容,指定起始地址和长度。
7.microblaze可访问逻辑寄存器。
8.网页可显示逻辑版本号,即固件版本号
二:流程
设计使用uart接收上位机发送的在线设计程序;在软核中解析uart协议;将烧写程序写到DDR中;利用AXI-LITE用户通信接口,给PL端发送在线更新指令,PL实现将DDR中在线升级程序搬到Flash中。
三:PS端
uart接收数据协议主要在uart接收中断中实现;接收完下载数据后,通过完成标志下发在线更新指令;逻辑收到更新指令,搬运数据到Flash。
四:PL端——PL端接收到在线更新指令,实现将DDR中在线升级程序搬到Flash中
1.设计一个Flash控制器。以便将完成低速数据的存储
2.其中Flash clk管脚配置方法:通过原语STARTUPE2。
3.移植黑金的UART驱动,FLASH(擦除,写,读)代码。
2.1 端口设计
spi_flash_control #(
parameter [31:0] SYSCLK = 32'd100_000_000,
parameter [31:0] SPICLK = 32'd10_000_000
)(
input sys_clk,
input sys_rst,
input cmd_start,
input [31:0] cmd_addr,
input [31:0] wr_data, //write 4 byte
output [31:0] rd_data, //read 4 byte
output reg cmd_done,
output flash_cs_n,
output flash_sclk,
input flash_sdi,
output flash_sdo
);
端口介绍:
cmd_start:发起命令,启动控制器;
cmd_addr:命令与地址;高8bit为命令,低24bit为地址;如果命令与地址无关,则低位为0;
wr_data:写数据;一次写4字节;
rd_data:读数据,一次读4自己;
cmd_done:命令完成,控制器完成一次操作。
二:串口接收mcs文件,通过flash的两个区实现在线升级:
有的项目需要远程更新固件,更新完成后断电、重启即可。那远程更新是如何实现的呢?用的最多的应该是以太网或者自定义的局域网为主,当然还可以使用pcie、串口之类的,像xilinx还有golden image,以防止远程更新失败启动不起来,它主要是flash存有两个启动文件,正常情况下启动默认的,当默认的被损坏,就从备用的启动。本文章主要讲解的是STARTUPE2原语,这和远程更新有什么关系呢?请接着向下看。
我们知道,fpga掉电丢失,一般使用外部flash存储代码,flash有spi、bpi、qspi等接口,外部存储器的时钟管脚一般与fpga的CCLK_0连接,当使用远程更新时,首先fpga内部有控制flash的驱动(即逻辑控制flash时序),当然flash时钟也需要控制了,但这时时钟管脚已经连接到CCLK_0,那该如何操作啊,你直接约束分配管脚试试,是通不过的,这时STARTUPE2就派上用场了,那该如何使用啊,如
1.
STARTUPE2 #(
.PROG_USR("FALSE"), // Activate program event security feature. Requires encrypted bitstreams.
.SIM_CCLK_FREQ(0.0) // Set the Configuration Clock Frequency(ns) for simulation
)
STARTUPE2_inst
(
.CFGCLK(), // 1-bit output: Configuration main clock output
.CFGMCLK(), // 1-bit output: Configuration internal oscillator clock output
.EOS(), // 1-bit output: Active high output signal indicating the End Of Startup.
.PREQ(), // 1-bit output: PROGRAM request to fabric output
.CLK(0), // 1-bit input: User start-up clock input
.GSR(0), // 1-bit input: Global Set/Reset input (GSR cannot be used for the port name)
.GTS(0), // 1-bit input: Global 3-state input (GTS cannot be used for the port name)
.KEYCLEARB(1), // 1-bit input: Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM)
.PACK(1), // 1-bit input: PROGRAM acknowledge input
.USRCCLKO(flash_clk), // 1-bit input: User CCLK input
.USRCCLKTS(0), // 1-bit input: User CCLK 3-state enable input
.USRDONEO(1), // 1-bit input: User DONE pin output control
.USRDONETS(1) // 1-bit input: User DONE 3-state enable outpu
);
1.1
其中flash_clk就是你时序控制的flash时钟信号,连接到这就行了,其它的不需要改动,也无需约束此管脚(因为此管脚不需要在顶层作为输出信号了)。当然你也可以例化qspi ip看里面是如何使用
1.2
bin文件没有bit反序,二进制文件。MCS bit反序了,是ASCII文件,带有地址和校验。对于我们升级来说,bin文件就可以了。(该文件类型是借鉴于之前的项目应用)
1.3 流程
所以在线升级的简单设计就是拿到bin文件后,先根据bin文件大小擦除扇区,擦除每个扇区是是需要时间的,在手册里也有说明,擦除命令之间留出间隔即可,再从0开始直接写bin文件就可以了,写完后再读出校验。
1.4
multiboot 即 flash多重启动加载方式,常用于远程加载场景中,当远程加载失败时,flash会启动应急预案,将另一块地址的备用程序拿来作为加载FPGA的程序,防止由远程固化失败导致的FPGA启动不了的情况。