网络升级FPGA方案调研与调试
根据相关项目需求,需要提供通过网络更新FPGA固化程序的功能。相关关键字为多重启动,Multiboot,个人理解多重启动是指FPGA的配置文件包含两个以上,可以有策略的选择加载哪一个配置文件。
BIT文件是加了一些文本信息头的二进制配置文件,当然这些文本信息头不会被配置进FPGA。
如图是一个工程的bit文件。文本信息头包含bit流名称、FPGA型号、用户ID、时间等,图中例子中可以看出bit流名是ZD_Monitor_64S。
BIN文件是不包含二进制信息头的二进制配置文件,对比BIT文件图如下。
可以对比看出,BIN文件不带文本信息头。
MCS文件是一种INTER HEX文件;常用与XILINX专用工具结合烧录FPGA flash。关于INTER HEX文件的分析详情,参见文档INTER HEX文件分析.docx
关于这三种配置文件的格式详细说明,以SPARTAN-6为例参见文档ug380 Spartan-6 FPGA Configuration.pdf第5章Configuration Data File Formate以及同章节的Bitstream Composition
配置文件从flash的第一个地址开始存储,当在实现Multiboot功能时,在线更新时配置文件存放的地址需要仔细考究。
远程更新FLASH时,结合Multiboot更加安全,如果镜像更新不成功,起码还有一个黄金镜像(golden image)可以用。
关于Multiboot功能,请参考相关技术介绍章节。
从配置文件的格式我们了解到,配置文件一般都由配置头+配置数据+校验组成,当然不同系列FPGA也是有很大的区别的,但是总的来说,都是这个结构。
FPGA加载配置文件肯定是从flash的0地址开始的;先读配置头,配置头数据中有一些指令,例如地址跳转指令等,根据配置头里的一些指令操作,来进行接下来的读取配置数据过程;最后是验证校验是否正确,如果正确,配置完成,如果不正确,自动跳转到golden image的地址位置重新读取配置数据,如果再次失败的话,配置失败。
核心要求即为FPGA用户逻辑能主动访问外部flash芯片。
FPGA与外挂flash的引脚连接如果是复用引脚,如果是这种连接方式,FPGA在加载完毕配置文件后,这些复用引脚可以被内部逻辑使用,也就可以主动访问到外部flash。
FPGA(V4系列FPGA)与外挂flash的引脚连接如果是专用引脚,这样在加载完毕配置文件后,不能被内部逻辑使用,内部逻辑也就不能访问到外部flash,更新flash也就无从谈起。
但是有一种解决方案,如下图所示。
从图中可以看出,PROM有两个接口供外部访问。所以这种解决方案的核心就是选型具有两种接口的PROM或者flash,这样用FPGA的普通iO引脚主动访问PROM或者FLASH,完成远程数据更新。
FPGA多重配置允许动态进行多个下载文件之间的切换,当引导配置过程中检测到出错时,FPGA会触发一个回退标志确保一个已知的好的文件可以被加载进来。具体如下图所示:
简而言之,就是你的.mcs文件里包含有两个或更多的下载文件,然后地址0的位置开始存放一个可用的下载文件(多数是升级前那个旧的文件),后面的地址(ADDR_1)存放你将要更新的文件。当下载时,FPGA会先从ADDR_1读取更新的文件,若这个过程发生错误的话就会回到地址0,读取之前的文件,确保设备仍能正常工作。MultiBoot的使用需要ICAP核乃至STARTUP核。详情请参考xapp1247-multiboot-spi.pdf
全称是Internal Configuration Access Port内部配置实现接口,实现多重配置功能时,必须调用FPGA内部的ICAP核。用户逻辑通过ICAP核启动重配置,启动重配置的过程实际就是IPROG命令的发出,接受对象是FPGA内部的配置控制器(假定它存在,其实它真存在),发出这些命令的接口就是ICAP。关于ICAP的详细技术细节(以spartan-6为例)请参考文档ug380 Spartan-6 FPGA Configuration.pdf第4章User Primitives以及Spartan-6 Libraries Guide for Schematic Designs.pdf 的Page-239
IRPOG命令序列是实现FPGA重加载的重要环节。IPROG命令的效果与在PROGRAM_B引脚产生一个脉冲的效果类似,但是IPROG命令不对重配置逻辑(或者说配置控制器)进行复位。IPROG命令序列触发FPGA从SPI Flash中重新加载比特文件,加载地址是命令序列中指定的地址。以spartan-6为例,IPROG命令序列如下图所示。
FPGA内的重配置逻辑接收到IPROG命令后,FPGA执行复位操作,但不对重配置逻辑进行复位,并且将INIT_B和DONE引脚拉低。FPGA清除了所有的配置存储后,INIT_B端口被拉高。最后,指定的地址值被用来重新配置FPGA。关于IPROG的详细技术细节(以spartan-6为例)请参考文档ug380 Spartan-6 FPGA Configuration.pdf第7章Reconfiguration and MultiBoot
这是一个原语的前缀,其主要功能是在FPGA启动后提供给用户逻辑一个接口来控制全局信号,例如所有寄存器的复位、所以iO设置成三态等。当然不同型号的FPGA控制的信号不一样,例如7系列FPGA中,配置接口的CCLK是专用接口,这个原语就可以控制配置接口的CCLK,让其输出时钟信号;而spartan-6就没有这个控制,应为spartan-6的配置引脚都是复用的,配置完成后,都可以被用户逻辑使用,输出个时钟是完全没有问题的。关于STARTUP的详细技术细节(以spartan-6为例)请参考文档ug380 Spartan-6 FPGA Configuration.pdf第4章User Primitives以及Spartan-6 Libraries Guide for Schematic Designs.pdf 的Page-610
调试环境:
1、ISE14.7、Windows10
2、Spartan6-XC6SLX100-2fgg676,flash位M25P64,基于SS第二版项目板卡
Multiboot的两种实现方法。
在xilinx官方应用参考手册xapp733-multiboot-sem-controller.pdf中指出,实现多重启动有具体如下两种方法,也即,通过ISE软件设置和ICAP方式。这两种方法可以单独使用也可以配合使用。
方法一:通过ISE软件设置的方式实现多重启动
需要建立两个bit工程,备用工程golden和多重启动工程Multiboot
这两个工程中不需要ICAP原语。
golden工程bit生成设置如下
-g next_config _addr设置中高8位代表读取FLASH的SPI操作码,具体可参考flash数据手册
此处可以是03也可以是0B
Multiboot工程bit生成设置如下
多重启动MCS烧录文件生成步骤如下
1、设置生成参数、flash容量、路径、bit版本数量
2、添加golden工程bit文件
3、设置Multiboot工程bit文件存放在FLASH的地址、添加bit文件,一路OK生成即可
方法二:通过ICAP方式实现多重启动
也需要配置BIT生成设置。具体设置如下
golden和Multiboot设置的唯一区别是Other Bitgen Command Line Options需要加上
-g next_config_register_write:Disable
除了bit生成设置外,还需要再两个工程中都添加ICAP驱动逻辑,以及设置好相应跳转地址
MCS上传方法同上。
两种方法协同使用情况
bit生成配置和方法一相同。
ICAP使用与方法二相同。
MCS文件生成方法同上。
特别注意(调了好久,原来发现是驱动写的不严谨):
ICAP驱动逻辑错误会导致MCS烧录失败,启动失败。
调试过程中ICMP_CTRL.v代码文件中的cnt没有初始化为32,导致烧写失败、配置不成功
module ICMP_CTRL(
input clk,
input start,
input [23:0] MultiBoot_addr,
input [23:0] Fallback_addr
);
localparam SPIx1 = 8'h0B;//也可以是03,具体参考flash数据手册,查看相关操作码
reg CE=1;
reg WRITE=0;
reg [15:0] I=0;
reg [16:0] cnt=16'D32;
always @ (negedge clk)
begin
if(start)
cnt <= 16'd0;
else
if(cnt < 16'd32)
cnt <= cnt + 1'b1;
else
cnt <= 16'd32;
end
always @ (negedge clk)
begin
case(cnt)
16'd1 : begin
CE <= 1'b1;
I <= 16'd0;
WRITE <= 0;
end
16'd2 : begin
CE <= 1'b0;
I <= 16'hFFFF;
WRITE <= 0;
end
16'd3 : begin
CE <= 1'b0;
I <= 16'hFFFF;
WRITE <= 0;
end
16'd4 : begin
CE <= 1'b0;
I <= 16'hAA99;
WRITE <= 0;
end
16'd5 : begin
CE <= 1'b0;
I <= 16'h5566;
WRITE <= 0;
end
16'd6 : begin
CE <= 1'b0;
I <= 16'h3261;
WRITE <= 0;
end
16'd7 : begin
CE <= 1'b0;
I <= MultiBoot_addr[15:0];
WRITE <= 0;
end
16'd8 : begin
CE <= 1'b0;
I <= 16'h3281;
WRITE <= 0;
end
16'd9 : begin
CE <= 1'b0;
I <= {SPIx1,MultiBoot_addr[23:16]};
WRITE <= 0;
end
16'd10 : begin
CE <= 1'b0;
I <= 16'h32A1;
WRITE <= 0;
end
16'd11 : begin
CE <= 1'b0;
I <= Fallback_addr[15:0];
WRITE <= 0;
end
16'd12 : begin
CE <= 1'b0;
I <= 16'h32C1;
WRITE <= 0;
end
16'd13 : begin
CE <= 1'b0;
I <= {SPIx1,Fallback_addr[23:16]};
WRITE <= 0;
end
16'd14 : begin
CE <= 1'b0;
I <= 16'H30A1;
WRITE <= 0;
end
16'd15 : begin
CE <= 1'b0;
I <= 16'H000E;
WRITE <= 0;
end
16'd16 : begin
CE <= 1'b0;
I <= 16'H2000;
WRITE <= 0;
end
16'd17 : begin
CE <= 1'b0;
I <= 16'H2000;
WRITE <= 0;
end
16'd18 : begin
CE <= 1'b0;
I <= 16'H2000;
WRITE <= 0;
end
16'd19 : begin
CE <= 1'b0;
I <= 16'H2000;
WRITE <= 0;
end
16'd20 : begin
CE <= 1'b1;
I <= 16'H2000;
WRITE <= 0;
end
default : begin
CE <= 1'b1;
I <= 16'H0000;
WRITE <= 0;
end
endcase
end
wire [15:0] icap_i;
assign icap_i[15] = I[ 8];
assign icap_i[14] = I[ 9];
assign icap_i[13] = I[10];
assign icap_i[12] = I[11];
assign icap_i[11] = I[12];
assign icap_i[10] = I[13];
assign icap_i[ 9] = I[14];
assign icap_i[ 8] = I[15];
assign icap_i[ 7] = I[ 0];
assign icap_i[ 6] = I[ 1];
assign icap_i[ 5] = I[ 2];
assign icap_i[ 4] = I[ 3];
assign icap_i[ 3] = I[ 4];
assign icap_i[ 2] = I[ 5];
assign icap_i[ 1] = I[ 6];
assign icap_i[ 0] = I[ 7];
ICAP_SPARTAN6 #(
.DEVICE_ID(32'h4000093), // Specifies the pre-programmed Device ID value
.SIM_CFG_FILE_NAME("NONE") // Specifies the Raw Bitstream (RBT) file to be parsed by the simulation
)
ICAP_SPARTAN6_inst(
.BUSY(), // 1-bit output: Busy/Ready output
.O(), // 16-bit output: Configuartion data output bus
.CE(CE), // 1-bit input: Active-Low ICAP Enable input
.CLK(clk), // 1-bit input: Clock input
.I(icap_i), // 16-bit input: Configuration data input bus
.WRITE(1'b0) // 1-bit input: Read/Write control input
);
endmodule
主要参考:
Spartan6 Mutiboot实现方法记录 - 朝雾之归乡 - 博客园.html
FPGA多重配置在LED显示控制系统中的应用.pdf