赛灵思KU系列FPGA的ICAPE3原语和MultiBoot功能

参考手册ug570。

一、ICAPE3原语

1.1 ICAPE3原语的介绍

复制代码
ICAPE3 #(
      .DEVICE_ID(32'h03628093),     // Specifies the pre-programmed Device ID value to be used for simulation purposes.
      .ICAP_AUTO_SWITCH("DISABLE"), // Enable switch ICAP using sync word.
      .SIM_CFG_FILE_NAME("NONE")    // Specifies the Raw Bitstream (RBT) file to be parsed by the simulation model.
   )
ICAPE3_inst (
      .AVAIL(AVAIL),     // 1-bit output: Availability status of ICAP.
      .O(O),             // 32-bit output: Configuration data output bus.
      .PRDONE(PRDONE),   // 1-bit output: Indicates completion of Partial Reconfiguration.
      .PRERROR(PRERROR), // 1-bit output: Indicates error during Partial Reconfiguration.
      .CLK(CLK),         // 1-bit input: Clock input.
      .CSIB(CSIB),       // 1-bit input: Active-Low ICAP enable.
      .I(I),             // 32-bit input: Configuration data input bus.
      .RDWRB(RDWRB)      // 1-bit input: Read/Write Select input.
   );

各信号解释如下:

信号名称 解释
AVAIL ICAP可用标志
O 配置数据输出总线
PRDONE partial reconfiguration重配置完成标志
PRERROR partial reconfiguration重配置错误标志
CLK 时钟输入
CSIB 片选信号,低电平有效
I 配置数据输入总线
RDWRB 读写标志,高电平读,低电平写

1.2 ICAPE3完成FPGA重加载IPROG

使用ICAPE3完成IPROG功能,UG570中提供了示例的流程,如下图:

只需要按照上述流程依次配置即可。只需要注意确定好固件加载的起始地址,即Warm boot start address (Load the desired address)。

另外需要注意的是,ICAPE3的端口是32位端口,使用程序写入到其输入总线是,需要进行bit位置互换,互换方式参考下图:

本文中控制ICAPE3的示例代码如下:

复制代码
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2026/01/09 17:13:44
// Design Name: 
// Module Name: FPGA_firmware_reload
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module FPGA_firmware_reload(
	input clk,
	input rst_n,
	
	input firmware_reload_req,
	output reg firmware_reload_error = 1'b0, //高电平有效,若失败则通知CXP板卡;否则直接重新启动相机固件,此时CXP链路断开,CXP板卡重新发现设备
	
	input flash_busy  //flash忙,此时不响应reload命令

    );

reg firmware_reload_req_d1 = 1'b0;
reg firmware_reload_req_d2 = 1'b0;

//ICAPE3信号
wire ICAP_AVAIL;
wire [31:0] ICAP_O;
wire ICAP_PRDONE;
wire ICAP_PRERROR;
reg ICAP_CSIB = 1'b1;
reg [31:0] ICAP_I = 0;
reg ICAP_RDWRB = 1'b0;

//-----------相关命令字-------------------------------------
localparam DUMMY_WORD = 32'hFFFF_FFFF; // 填充字
localparam SYNC_WORD = 32'hAA99_5566; // 同步字
localparam TYPE1_NOOP = 32'h2000_0000; // TYPE1 空操作
localparam TYPE1_WBSTAR  = 32'h3002_0001; //写一个字到WBSTAR
localparam WBSTAR  = 32'h0; //指定WBSTAR地址,即程序加载起始地址
localparam TYPE1_CMD  = 32'h3000_8001; //写一个字到CMD
localparam IPROG_CMD  = 32'h0000_000F; //IPROG命令


localparam S_IDLE = 4'd0;
localparam S_JUDGE = 4'd1;
localparam S_CONFIG = 4'd2;
localparam S_END = 4'd3;

reg [3:0] state = S_IDLE; //按顺序进行相关操作,共计8条指令

reg [3:0] config_cnt = 0; //配置命令计数

// 功能:将输入数据按ICAPE3要求的格式进行转换
// 步骤:1. 每个字节内比特颠倒 2. 整体字节顺序交换
function [31:0] icap_data_swap;
    input [31:0] data_in;
    icap_data_swap = {data_in[24], data_in[25], data_in[26], data_in[27], data_in[28], data_in[29], data_in[30], data_in[31], 
					   data_in[16], data_in[17], data_in[18], data_in[19], data_in[20], data_in[21], data_in[22], data_in[23], 
					   data_in[8], data_in[9], data_in[10], data_in[11], data_in[12], data_in[13], data_in[14], data_in[15], 
					   data_in[0], data_in[1], data_in[2], data_in[3], data_in[4], data_in[5], data_in[6], data_in[7]};
endfunction



// 状态机
always @(posedge clk) 
begin
    firmware_reload_req_d1 <= firmware_reload_req;
    firmware_reload_req_d2 <= firmware_reload_req_d1;
    ICAP_CSIB <= 1'b1; //片选信号,默认高电平
    ICAP_RDWRB <= 1'b1;//读写信号,默认高电平读
    case(state)
        S_IDLE: begin
            config_cnt <= 0;
            if(!firmware_reload_req_d2 & firmware_reload_req_d1) begin //firmware_reload_req上升沿
                state <= S_JUDGE;
                firmware_reload_error <= 1'b0;
            end
        end
        S_JUDGE : begin 
            if(ICAP_AVAIL) begin//ICAPE3准备好
                state <= S_CONFIG;
            end
            else begin
                state <= S_IDLE;
                firmware_reload_error <= 1'b1;
            end
        end
        S_CONFIG: begin
            if(config_cnt <= 7 ) begin
                config_cnt <= config_cnt + 1'b1;
                ICAP_CSIB <= 1'b0;
                ICAP_RDWRB <= 1'b0;
            end
            else begin
                state <= S_END;
            end
            case(config_cnt)
                4'd0 : ICAP_I <= icap_data_swap(DUMMY_WORD); //发送填充字
                4'd1 : ICAP_I <= icap_data_swap(SYNC_WORD); //发送同步字
                4'd2 : ICAP_I <= icap_data_swap(TYPE1_NOOP); //发送TYPE1 空操作
                4'd3 : ICAP_I <= icap_data_swap(TYPE1_WBSTAR); //写一个字到WBSTAR
                4'd4 : ICAP_I <= icap_data_swap(WBSTAR); //指定WBSTAR地址,即程序加载起始地址
                4'd5 : ICAP_I <= icap_data_swap(TYPE1_CMD); //写一个字到CMD
                4'd6 : ICAP_I <= icap_data_swap(IPROG_CMD); //IPROG命令
                4'd7 : ICAP_I <= icap_data_swap(TYPE1_NOOP); //发送TYPE1 空操作
            endcase
        end
        S_END: begin
            if(ICAP_PRDONE) begin
                state <= S_IDLE;
                if(ICAP_PRERROR)
                    firmware_reload_error <= 1'b1;
            end
        end
    endcase
end




    
ICAPE3 #(
    .DEVICE_ID(32'h03628093),     // Specifies the pre-programmed Device ID value to be used for simulation purposes.
    .ICAP_AUTO_SWITCH("DISABLE"), // Enable switch ICAP using sync word.
    .SIM_CFG_FILE_NAME("NONE")    // Specifies the Raw Bitstream (RBT) file to be parsed by the simulation model.
)
ICAPE3_inst (
    .AVAIL(ICAP_AVAIL),     // 1-bit output: Availability status of ICAP.
    .O(ICAP_O),             // 32-bit output: Configuration data output bus.
    .PRDONE(ICAP_PRDONE),   // 1-bit output: Indicates completion of Partial Reconfiguration.
    .PRERROR(ICAP_PRERROR), // 1-bit output: Indicates error during Partial Reconfiguration.
    .CLK(clk),         // 1-bit input: Clock input.
    .CSIB(ICAP_CSIB),       // 1-bit input: Active-Low ICAP enable.
    .I(ICAP_I),             // 32-bit input: Configuration data input bus.
    .RDWRB(ICAP_RDWRB)      // 1-bit input: Read/Write Select input.
);
    

endmodule

本文中验证IPROG是否成功,采用的方法是:

第一步,烧录到FLASH中一个程序,控制LED闪烁。

第二步,通过JTAG烧录一个新的程序,控制LED常亮。新的程序中含有IPROG功能。

第三步,通过VIO控制程序重新加载FLASH中的固件,此时LED闪烁,证明IPROG成功。

具备ICAPE3原语并实现FPGA重新加载的工程文件如下:

https://download.csdn.net/download/yindq1220/92556644https://download.csdn.net/download/yindq1220/92556644

二、MULTIBOOT功能的实现

根据上一章节,可以自行设计不同的逻辑,使用ICAPE3原语,实现在FLASH中不同地址的固件的加载,实现多种多样的MULTIBOOT的功能。本章节中就不在赘述。

本章节讲述将IPROG命令嵌入到bit文件中的具体操作方式,使用golden程序和update程序的切换。

2.1 MULTIBOOT工程介绍

上电后的操作流程基本如下:

如何能实现这种嵌入式的IPROG命令?将IPROG命令嵌入到bit文件中,自动实现上电后启动update程序?实现方式比较简单,只需要添加约束文件即可,在golden工程和update工程中均添加约束文件。

golden工程中添加如下的约束文件:

复制代码
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
##################golden镜像约束#############
set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]
set_property BITSTREAM.CONFIG.NEXT_CONFIG_ADDR 32'h01000000 [current_design]
#由于fallback使用SPIx1,因此请确定一定有此配置
set_property CONFIG_MODE SPIX1 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 1 [current_design]
# 如果 FLASH 大小大于等于 256Mb,要增加如下约束,否则高于24位的地址会被忽略,导致无法启动对应的 update 镜像
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]

#超时时间=设置值* 20ns  此处的20ns为配置速率的时钟周期。此处设置超时时间为5s
set_property BITSTREAM.CONFIG.TIMER_CFG 32'hEE6B280 [current_design]
##################golden镜像约束#############

注意,在golden工程中,约束的update的配置地址是32'h01000000,那么update程序的起始地址即为32'h01000000。

update工程中添加的约束文件如下:

复制代码
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
##################MultiBoot镜像约束#############
set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]
set_property CONFIG_MODE SPIX1 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 1 [current_design]
#由于fallback使用SPIx1,因此请确定一定有此配置

# 如果 FLASH 大小大于等于 256Mb,要增加如下约束,否则高于24位的地址会被忽略,导致无法启动对应的 update 镜像
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]

#超时时间=设置值* 20ns  此处的20ns为配置速率的时钟周期。此处设置超时时间为5s
set_property BITSTREAM.CONFIG.TIMER_CFG 32'hEE6B280 [current_design]
##################MultiBoot镜像约束#############

需要注意的是,golden工程的约束和update工程的约束,需要基本保持一致。

2.2 MULTIBOOT的工程示例

第一步,编译golden工程和update工程,编译完成后,得到两个bit文件。

第二步,生成MULTIBOOT配置文件。在vivado中,点击 "Tool -> generate memory configuration File",按照如下图方式填写:

第三步,将得到的MCS文件烧录到FLASH中,重新上电启动,可以看到运行的是update的程序;

第四步,若想验证update程序异常时,是否能回到golden程序,则手动将mcs文件中update的文件修改几个字符,然后重新将错误的mcs文件烧录到FLASH中。此时可以看到运行的是golden程序。

编写的golden程序工程和update程序工程如下:

https://download.csdn.net/download/yindq1220/92556767https://download.csdn.net/download/yindq1220/92556767

相关推荐
Flamingˢ2 小时前
FPGA实战:基于Verilog的数码管动态扫描驱动设计与仿真验证
fpga开发
GateWorld2 小时前
跨时钟域同步(CDC)握手协议
fpga开发·cdc·asic·跨时钟域同步·握手协议
Flamingˢ4 小时前
Verilog中reg与wire的区别:从语法到实战
学习·fpga开发·硬件工程
数字芯片实验室4 小时前
边界值测试:一个”==”引发的芯片bug
fpga开发·bug
9527华安4 小时前
FPGA实现Aurora8B10B视频转UVC传输,基于GTP高速收发器+FT602芯片架构,提供4套工程源码和技术支持
fpga开发·gtp·uvc·aurora8b10b·ft602
tiantianuser4 小时前
RDMA设计31:RoCE v2 发送模块3
fpga开发·rdma·cmac·roce v2
海涛高软1 天前
verlog中阻塞赋值和非阻塞赋值
fpga开发
tiantianuser1 天前
RDMA设计29:RoCE v2 发送及接收模块设计2
服务器·fpga开发·rdma·fpga设计·高速传输
9527华安1 天前
FPGA实现GTP光口视频转USB3.0 UVC,基于Aurora8B10B+FT602芯片架构,提供4套工程源码和技术支持
fpga开发·gtp·usb3.0·uvc·aurora8b10b·ft602