Chapter 20:国产FPGA之烧入多个版本的固件
0赞第二十章
国产FPGA之烧入多个版本的固件
Altera FPGA有RSU--Remote system upgrade,即远程系统更新,可以通过外部控制来切换EPCSx基地址,来实现多个版本的固件的运行。
AstroII也有,AstroII 支持多配置映像in system configuration (ISC),不过亮点是,他不用外部控制,自带CPU,自己就能解决问题,牛了个逼啊O(∩_∩)O哈哈~
用户可以根据系统的运行情况和外部条件不用关闭电源选择合适的配置映像配置AstroII 并运行新的设计。配置文件包含FPGA的配置数据和MCU的代码。
AstroII 集成了高性能增强型8051MCU, MCU 对AstroII 的操作都简化为MCU对SFR 的操作,MCU对AstroII 的操作就是软件对SFR 的读写,非常灵活易用。 AstroII 的8051MCU 可以很方便地读写配置 SPI FLASH的多余空间。于ISC 功能相结合,AstroII 就能方便的实现在线更新并运行。
ISC示意图
MCU对AstroII 的ISC 操作都是通过读写扩展的SFR 来进行的,AstroII 的硬件配置逻辑实际控制对SPI FLASH 的操作,不需要其他任何硬件设计。 AstroⅡ的配置Image 由FPGA 配置数据和MSS的8051程序代码组成,FPGA 配置数据大小基本上一样,MSS的代码随程序的的大小变化。
整个系统的运行,代码从Flash中启动,每个版本的Image放在Flash不同地址中,2个版本的代码,系统运行流程图如下所示:
(1)配置SPI flash接口
(2)例化SPI接口,fpga部分代码如下
module isc_design
(
//input clk, //10MHz 外部晶振
output [7:0] led_data //8位LED灯
);
//-----------------------------
//振荡器例化
wire clk_1106; //11.06MHz
myOscillator u_myOscillator
(
.clkout (clk_1106)
);
//-----------------------------
//PLL例化
wire clkcpu; //8051内核全局时钟
myPll u_myPll
(
.clkin (clk_1106), // Reference clock input.
.clkcpu (clkcpu) // Main clock output.
);
//----------------------------
//spi interface
wire scko;
wire [7:0] spssn;
wire misoi;
wire mosio ;
mySPIInterface u_mySPIInterface
(
.sclk (scko),
.cson (spssn[0]),
.sdi (mosio),
.sdo (misoi)
);
//--------------------------------
//8051内核例化
mySystem u_mySystem
(
//8051 MSS时钟
.clkcpu (clkcpu), //8051内核时钟
//Fabric总结结构接口
.reset (1'b1), //始终有效
.clkcpuen (),
.clkperen (),
.ro (),
.swd (),
//通用IO口
.port0i (),
.port1i (),
.port2i (),
.port3i (),
.port0o (led_data), //P0端口为流水灯
.port1o (),
.port2o (),
.port3o (),
//SPI总线接口
.scki (),
.scko (scko),
.scktri (),
.ssn (1'b1),
.misoi (misoi),
.misoo (),
.misotri (),
.mosii (),
.mosio (mosio),
.mositri (),
.spssn (spssn),
//emif外部存储接口
.clkemif (),
.memack (),
.memdatai (),
.memdatao (),
.memaddr (),
.memwr (),
.memrd (),
//4K的DPRAM 接口
.clkb (),
.cenb (),
.wenb (),
.db (),
.ab (),
.qb ()
);
endmodule
(3)不同版本的8051代码如下(流水灯、闪烁灯)(当然fpga部分也可以不同)
版本1:流水灯代码
#include
#include
void Delay_ms(unsigned int cnt);
void ISCReq (unsigned char id);
void main()
{
unsigned char i,j;
unsigned char led_data;
I2CSPISEL = I2CSPISEL|0x1; //I2CSPISEL SFR的第0位置1.使能SPI接口
P0 = 0xff;
j = 3;
while(j--)
{
led_data = 0x01;
for(i=0; i<8; i++)
{
P0 = ~led_data; //低电平亮
Delay_ms(200); //延时500ms
led_data = led_data << 1;
}
}
P0 = 0xff;
//重配置flash地址
EAL = 0;
Delay_ms(2000);
ISCReq(0x01);
_nop_();
EAL = 1;
}
//ms延时函数
void Delay_ms(unsigned int cnt)
{
unsigned int i;
while(cnt--)
{
for(i=0; i<255; i++);
}
}
//根据id 设置新的配置映像地址
void ISCReq (unsigned char id)
{
ISCADDR0 = 0;
ISCADDR1 = 0;
ISCADDR2 = id; //0,1
ISCADDR3 = 0;
ISCEN = 1; // recfg
_nop_();
}
版本2为闪烁灯代码,直接将上述P0操作部分换成下面:
P0 = 0xff;
j = 3;
while(j--)
{
for(i=0; i<8; i++)
{
P0 = ~P0; //低电平亮
Delay_ms(200); //延时500ms
}
}
P0 = 0xff;
//重配置flash地址
EAL = 0;
Delay_ms(2000);
ISCReq(0x00);
_nop_();
EAL = 1;
(4)Primance中分别在mySystem中加载不同HEX,生成不同的2个acf
(5)用Configuration Packer打包两个acf文件,生成mcf文件
(6)打开mcf文件,可以查看每个image的基地址(一般小代码偏移0x010000)
(7)Download mcf文件,搞定