学到了ICAP,做做笔记。
具体可参考:FPGA中ICAP原语的使用——Multiboot功能的实现_朽月的博客-CSDN博客
ICAP是管理内部配置访问端口的原语,于是我学习的第一个原语。对于原语的概念简而言之就是类似IP核的存在,是既成的电路结构,但是不需要通过IP窗格来调用。
// ICAP_SPARTAN6 : In order to incorporate this function into the design,
// Verilog : the following instance declaration needs to be placed
// instance : in the body of the design code. The instance name
// declaration : (ICAP_SPARTAN6_inst) and/or the port declarations within the
// code : parenthesis may be changed to properly reference and
// : connect this function to the design. All inputs
// : and outputs must be connected.
// <-----Cut code below this line---->
// ICAP_SPARTAN6: Internal Configuration Access Port
// Spartan-6
// Xilinx HDL Language Template, version 14.7
ICAP_SPARTAN6 #(
.DEVICE_ID(0'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
// model
)
ICAP_SPARTAN6_inst (
.BUSY(BUSY), // 1-bit output: Busy/Ready output
.O(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(I), // 16-bit input: Configuration data input bus
.WRITE(WRITE) // 1-bit input: Read/Write control input
);
// End of ICAP_SPARTAN6_inst instantiation
对于ICAP我们需要关注的几点有:
DEVICE_ID设备ID,这和核心芯片的型号有关,翻找UG380可以取得对应信息;
I:环境配置输入,写个状态机按顺序输入即可。
WRITE:读写控制信号。
其余的都有注释,输出信号也不用太关心,CE是使能,肯定要使能的吧。
其中配置需求如下:
FPGA上电时,自00_0000H地址加载BIOS程序,加载完成以后跳转自区域2。
*一般而言上电读取的便是BIOS程序,跳转地址则是产品工作的程序。
上电BIOS程序需要具备对Flash的读写功能,以便对区域2的程序进行升级。
若是均分地址,则跳转至01_0000H地址(Multboot start address)。
若跳转不成功或读取BIN失败,则跳转至00_0000H地址(Fallback start address)。
Multboot start address:FPGA Flash配置完成后的跳转地址
Fallback start address:读取BIN文件失败或跳转失败的时候的跳转地址。
(结合我在网络升级与FLASH-CSDN博客)中的笔记:
FPGA产品总是需要一个出厂程序的,也需要一个升级失败以后的选择,否则升级失败就没法继续升级,甚至变砖,岂不是非常不方便?Fallback start address便是提供了一个返回出厂程序或者重新进行升级的可能性。
Fallback start address的具体填写需要仰仗Flash的容量决定,例如16MB的内存意味着2^4*2^20bit = 2^21byte=10_0000_0000_0000_0000_0000b=2_0_0_0_0_0h个地址,
若是分为一半便是0~0_FFFFF和100000~1FFFFF两个区域。
其中写入两个程序,则程序1的启动地址是00_0000,程序1的启动地址则是10_0000。
所以OPCODE+ADDR =
(命令:例如读的0011B也就是03H)+(地址的高八位0000_0010B也就是01H)。
0301 H = 0000_0010_0000_0001 B。
FPGA可以通过XILINX自带的工具烧写MCS到Flash里,也可以通过第三方软件烧写BIN进Flash里,当然XILINX工具也有这个功能,因为BIN是二进制文件,其内容是程序本身,而MCS文件则包含了其每一行在内存中的地址,HEX也包含了其的地址,所以在单片机中烧写的通常都是HEX文件,毕竟BIN文件没有包含的话就需要自行制定,依赖于工具支持。(烧写的时候也可以指定地址,工具一般会提供)。
上电以后,如果我们需要通过工具向Flash里读写数据,首先我们需要通过JTAG的方式烧入Flash读写擦除程序,这是为FPGA提供一个能与第三方软件交互的桥梁。
烧写完成,通过第三方软件将BIN文件烧入Flash中指定好的地址即可。
这里为了模拟产品的运作,可以先行将“Flash读写擦除程序”的BIN格式烧入地址00_0000中,这样上电以后自动运作的便是这个“Flash读写擦除程序”,我们便可以通过串口的方式,将其他的程序通过这个程序来写入到Flash的其他地址,实现一个在线升级的工作。
“Flash读写擦除程序”主要承担了一个什么角色呢?
其需要能完成Flash操作的大部分必要指令,并且通过例化ICAP来完成一个地址跳转的操作。通过把这个程序的BIN烧入到FPGA内部,FPGA就能完成对Flash其他区域程序的更改等一系列功能了,断电以后也不会取消,并且通过这个程序,能够完成从这个Flash区域的程序到其他Flash区域的程序的一个切换,
即“正常工作”情况下,FPGA会先加载这个程序在区域0,如果没有其他需求就跳转到正常工作的区域1,如果有其他需求就在满足要求的情况下对其他区域的程序进行修改,读失败或跳转失败就再跳回这个区域0,类似于把这个程序作为BIOS程序使用。