FPGA使用镜像加载技能来切换运行中的比特流文件

[复制链接]
发表于 2026-2-19 12:43:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
补档声明

由于我的博客服务器和存案到期,以是选择转移到博客园平台来举行生存和记载。以后也有大概会在上面不定期更新一些技能类博客。

前言

这是一种无需重新烧录比特就能切换FPGA正在运行的比特的方法。
分为两种,一种是全局可重构,也可以叫做启动镜像切换,本质上是将两份或多份比特流同时固化到FLASH中,在运行过程及时中切换使用哪一份比特,这是基于NOR FLASH的片上实行特性(临时这么称呼,本质上是由于NOR只须要给地点就能出数据,没有译码转址这一过程) 。以是对于设置了NOR FLASH的FPGA板卡,我们可以通过ICAP原语来给出比特流加载的同步字,然后送入加载基地点,并给出加载下令,来举行当前实行比特流的切换。
另一种是部门可重构,这种要更复杂一点,但是本质上只不外是把重加载全局比特酿成了重加载部门模块的比特,以是会有个画pblock的过程,相比于全局可重构,流程会复杂很多,而且如果是中央模块的更换,由于输入输出端口的厘革,会造成一些时序束缚的标题,且无法直接使用OOC IP核,只能把IP核做成网表再调用,在我自己的工程上对于资源使用率的低沉作用不明显。本文就只着眼全局可重构。
全局可重构我现在探索出来的路径有两条,一条已经实现,就是后文的归并bit到一个mcs文件中,然后使用icape原语启动。别的的一条路是上位机通过pcie的dma通道,流式传输要切换的比特到板卡上,完成比特的切换,这条路还在探索,如果可以大概完成的话,那么对于机箱上的FPGA板卡来说,就可以让上位机生存多份比特,在运行之中任意切换,完成FPGA板卡功能的更新大概切换。
下面仅从怎么做的形貌怎样将两个工程的比特流归并到同一个mcs文件下,并使用这个mcs来对fpga举行烧录固化,并编写简单的代码来调用icape原语来对启动地点举行切换,以到达不重新烧写比特就能举行工程的切换的方法。
有关FLASH的几个工程xdc束缚

须要添加到工程的xdc中
  1. ############## FLASH ##################
  2. set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
  3. set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
  4. set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 1 [current_design]
  5. set_property CONFIG_MODE SPIx1 [current_design]
  6. # 如果 FLASH 大小大于等于 256Mb,要增加如下约束,否则高于24位的地址会被忽略,导致无法启动对应的 update 镜像
  7. set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
复制代码
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]压缩比特,这是一个蛮有效的选项,如果不使用压缩比特的话,那么任何一个工程,岂论代码有多简单大概多复杂,都会天生一个同样巨细的,未颠末压缩的比特,对于7k325t会占用大概11MB的巨细,更复杂的片子会更大。如果启用了,就会根据工程代码的复杂水平对比特举行压缩,一样平常来说都挺有效果的,能把最简单的LED流水灯工程压缩到几百KB的水平。能把我的工程压缩到5.5MB左右巨细
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]设置烧录速率,50M是SPI时钟线上的时钟频率,一样平常的SPI存储芯片都能支持这个速率。
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 1SPI宽度,这是用于控制烧录步调的接口的,由于我们要使用Fallback,以是这里必须是x1
set_property CONFIG_MODE SPIx1设置模式宽度,和上面一样
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design] 启用32bit地点线模式,如果FLASH巨细大于即是256Mb,也就是32MB,须要启用这个束缚,而且写入镜像的地点线的方法须要变动,见后文。我的板子上的s25fl256巨细恰恰是256Mb,以是得开。
multiboot模块的调用方法示例
  1.     // ^ 全局可重构
  2.     multiboot_ctrl multiboot_ctrl_inst (
  3.         .clk  (clk_out_100),
  4.         .rst_n(sys_rst_n),
  5.         .multiboot_start(~reconfig_key_n),   // 使用外部按键触发
  6.         .multiboot_addr (32'h00500000),   // 加载0x00500000处的Golden Image
  7.         .busy_o()
  8.     );
复制代码
这里要留意的是给地点的要求,如果前面使能了32bit地点线,则要根据下文把multiboot_addr[31:8]写到WBSTAR[23:0]
[code]// ^ ICAP 原语实现程控 multiboot(多重启动),K7须要使用 ICAPE2 原语module multiboot_ctrl (    input wire clk,    input wire rst_n,    input wire        multiboot_start,  //触发Multiboot, 上升沿有效    input wire [31:0] multiboot_addr,   //要启动的Muliboot Image的起始地点    output reg busy_o);    //-------------------ICAPE2原语-----------------------------    wire        ICAPE2_CLK;    wire [31:0] ICAPE2_O;    reg         ICAPE2_CSIB;    wire [31:0] ICAPE2_I;    reg         ICAPE2_RDWRB;    assign ICAPE2_CLK = clk;    ICAPE2 #(        .DEVICE_ID         (32'h3651093),  // Specifies the pre-programmed Device ID value to be used for simulation purposes. K7-325T的为32'h3651093        .ICAP_WIDTH("X32"),  // Specifies the input and output data width.        .SIM_CFG_FILE_NAME("NONE")  // Specifies the Raw Bitstream (RBT) file to be parsed by the simulation model.    ) ICAPE2_inst (        .O    (ICAPE2_O),     // 32-bit output: Configuration data output bus        .CLK  (ICAPE2_CLK),   // 1-bit input: Clock Input        .CSIB (ICAPE2_CSIB),  // 1-bit input: Active-Low ICAP Enable        .I    (ICAPE2_I),     // 32-bit input: Configuration data input bus        .RDWRB(ICAPE2_RDWRB)  // 1-bit input: Read/Write Select input    1对应rd,0对应wr    );    wire [31:0] Dummy = 32'hFFFFFFFF;    wire [31:0] Sync_Word = 32'hAA995566;    wire [31:0] NOOP = 32'h20000000;    wire [31:0] WR_WBSTAR = 32'h30020001;    /*When using ICAPE2 to set the WBSTAR address, the 24 most significant address bits should be written  to WBSTAR[23:0]. For SPI 32-bit addressing mode, WBSTAR[23:0] are sent as address bits [31:8]. The  lower 8 bits of the address are undefined and the value could be as high as 0xFF. Any bitstream  at the WBSTAR address should contain 256 dummy bytes before the start of the bitstream.*/    wire [31:0] WBSTAR = {3'b000, 5'h0, multiboot_addr[31:8]};    wire [31:0] WR_CMD = 32'h30008001;    wire [31:0] IPROG = 32'h0000000F;    //ICAPE2 字节序翻转    reg  [31:0]  wrdat;    assign ICAPE2_I = {        wrdat[24],        wrdat[25],        wrdat[26],        wrdat[27],        wrdat[28],        wrdat[29],        wrdat[30],        wrdat[31],        wrdat[16],        wrdat[17],        wrdat[18],        wrdat[19],        wrdat[20],        wrdat[21],        wrdat[22],        wrdat[23],        wrdat[8],        wrdat[9],        wrdat[10],        wrdat[11],        wrdat[12],        wrdat[13],        wrdat[14],        wrdat[15],        wrdat[0],        wrdat[1],        wrdat[2],        wrdat[3],        wrdat[4],        wrdat[5],        wrdat[6],        wrdat[7]    };    //------------------------FSM----------------------------------    localparam S_IDLE = 16'h0001;    localparam S_DUMMY = 16'h0002;    localparam S_SYN_WORD = 16'h0004;    localparam S_NOOP1 = 16'h0008;    localparam S_WR_WBSTAR = 16'h0010;    localparam S_WBSTAR = 16'h0020;    localparam S_WR_CMD = 16'h0040;    localparam S_IPROG = 16'h0080;    localparam S_NOOP2 = 16'h0100;    localparam S_STOP = 16'h0200;    wire multiboot_start_pe;    reg  multiboot_start_d0;    reg  multiboot_start_d1;    assign multiboot_start_pe = multiboot_start_d0 & (~multiboot_start_d1);    always @(posedge clk) begin        multiboot_start_d0
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表