2021-05-07

网络升级FPGA方案调研与调试

 

需求概述

根据相关项目需求,需要提供通过网络更新FPGA固化程序的功能。相关关键字为多重启动,Multiboot,个人理解多重启动是指FPGA的配置文件包含两个以上,可以有策略的选择加载哪一个配置文件。

 

BIT、BIN、MCS文件格式

BIT文件是加了一些文本信息头的二进制配置文件,当然这些文本信息头不会被配置进FPGA。

2021-05-07_第1张图片

如图是一个工程的bit文件。文本信息头包含bit流名称、FPGA型号、用户ID、时间等,图中例子中可以看出bit流名是ZD_Monitor_64S。

BIN文件是不包含二进制信息头的二进制配置文件,对比BIT文件图如下。

2021-05-07_第2张图片

可以对比看出,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

配置文件从flash的第一个地址开始存储,当在实现Multiboot功能时,在线更新时配置文件存放的地址需要仔细考究。

远程更新FLASH时,结合Multiboot更加安全,如果镜像更新不成功,起码还有一个黄金镜像(golden image)可以用。

  1. 如果不考虑Multiboot,我们可以从0地址开始逐一存放。
  2. 如果考虑Multiboot,我们就需要考虑镜像文件的存放地址了,需要配置头中的信息对应起来。

关于Multiboot功能,请参考相关技术介绍章节。

 

FPGA从FLASH中读取配置文件

从配置文件的格式我们了解到,配置文件一般都由配置头+配置数据+校验组成,当然不同系列FPGA也是有很大的区别的,但是总的来说,都是这个结构。

FPGA加载配置文件肯定是从flash的0地址开始的;先读配置头,配置头数据中有一些指令,例如地址跳转指令等,根据配置头里的一些指令操作,来进行接下来的读取配置数据过程;最后是验证校验是否正确,如果正确,配置完成,如果不正确,自动跳转到golden image的地址位置重新读取配置数据,如果再次失败的话,配置失败。

 

远程更新FPGA固件的硬件要求

核心要求即为FPGA用户逻辑能主动访问外部flash芯片。

 

FPGA与外挂flash的引脚连接如果是复用引脚,如果是这种连接方式,FPGA在加载完毕配置文件后,这些复用引脚可以被内部逻辑使用,也就可以主动访问到外部flash。

 

FPGA(V4系列FPGA)与外挂flash的引脚连接如果是专用引脚,这样在加载完毕配置文件后,不能被内部逻辑使用,内部逻辑也就不能访问到外部flash,更新flash也就无从谈起。

但是有一种解决方案,如下图所示。

2021-05-07_第3张图片

从图中可以看出,PROM有两个接口供外部访问。所以这种解决方案的核心就是选型具有两种接口的PROM或者flash,这样用FPGA的普通iO引脚主动访问PROM或者FLASH,完成远程数据更新。

 

实现步骤

  1. FPGA通过网络更新的前提条件是,FPGA用户逻辑以太网接口和主动配置flash功能启动。
  2. 固化程序通过网络传输给FPGA。其中涉及固化程序的格式、数据的缓存等问题。
  3. FPGA将通过网络接口接受到的更新文件写到flash中。其中涉及到写flash写时序、写地址等问题。
  4. 断电后再次启动,新版本程序启用。

 

相关技术介绍

MultiBoot:多重配置启动

FPGA多重配置允许动态进行多个下载文件之间的切换,当引导配置过程中检测到出错时,FPGA会触发一个回退标志确保一个已知的好的文件可以被加载进来。具体如下图所示:

2021-05-07_第4张图片

简而言之,就是你的.mcs文件里包含有两个或更多的下载文件,然后地址0的位置开始存放一个可用的下载文件(多数是升级前那个旧的文件),后面的地址(ADDR_1)存放你将要更新的文件。当下载时,FPGA会先从ADDR_1读取更新的文件,若这个过程发生错误的话就会回到地址0,读取之前的文件,确保设备仍能正常工作。MultiBoot的使用需要ICAP核乃至STARTUP核。详情请参考xapp1247-multiboot-spi.pdf

ICAP核

全称是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

 

IPROG命令序列

IRPOG命令序列是实现FPGA重加载的重要环节。IPROG命令的效果与在PROGRAM_B引脚产生一个脉冲的效果类似,但是IPROG命令不对重配置逻辑(或者说配置控制器)进行复位。IPROG命令序列触发FPGA从SPI Flash中重新加载比特文件,加载地址是命令序列中指定的地址。以spartan-6为例,IPROG命令序列如下图所示。

2021-05-07_第5张图片

FPGA内的重配置逻辑接收到IPROG命令后,FPGA执行复位操作,但不对重配置逻辑进行复位,并且将INIT_B和DONE引脚拉低。FPGA清除了所有的配置存储后,INIT_B端口被拉高。最后,指定的地址值被用来重新配置FPGA。关于IPROG的详细技术细节(以spartan-6为例)请参考文档ug380 Spartan-6 FPGA Configuration.pdf第7章Reconfiguration and MultiBoot

 

STARTUP

这是一个原语的前缀,其主要功能是在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方式。这两种方法可以单独使用也可以配合使用。

2021-05-07_第6张图片

方法一:通过ISE软件设置的方式实现多重启动

需要建立两个bit工程,备用工程golden和多重启动工程Multiboot

这两个工程中不需要ICAP原语。

golden工程bit生成设置如下

-g next_config _addr设置中高8位代表读取FLASH的SPI操作码,具体可参考flash数据手册

此处可以是03也可以是0B

2021-05-07_第7张图片

2021-05-07_第8张图片

Multiboot工程bit生成设置如下

2021-05-07_第9张图片

2021-05-07_第10张图片

多重启动MCS烧录文件生成步骤如下

1、设置生成参数、flash容量、路径、bit版本数量

2021-05-07_第11张图片

2、添加golden工程bit文件

2021-05-07_第12张图片

2021-05-07_第13张图片

3、设置Multiboot工程bit文件存放在FLASH的地址、添加bit文件,一路OK生成即可

2021-05-07_第14张图片

2021-05-07_第15张图片

方法二:通过ICAP方式实现多重启动

也需要配置BIT生成设置。具体设置如下

2021-05-07_第16张图片

2021-05-07_第17张图片

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

参考文档列表

  1. ug380 Spartan-6 FPGA Configuration.pdf
  2. ug616 Spartan-6 Libraries Guide for Schematic Designs.pdf
  3. ug385 Spartan-6 FPGA Packaging and Pinouts.pdf
  4. ug071 Virtex-4 FPGA Configuration User Guide.pdf
  5. ug075 Virtex-4 FPGA Packaging and Pinout Specification.pdf
  6. ug620 Virtex-4 Libraries Guide for Schematic Designs.pdf
  7. ug470_7Series_Config.pdf
  8. ug475_7Series_Pkg_Pinout.pdf
  9. xapp1247-multiboot-spi.pdf
  10. 10https://blog.csdn.net/Reborn_Lee/article/details/88937338 MultiBoot设计参考链接

 

 

 

你可能感兴趣的:(fpga)