当前位置: 首页 > article >正文

xilinx FPGA multi boot之镜像切换

最近做的了一个无线通信的项目,需要在同一套设备上实现两套不同的波形软件,因为FPGA的逻辑资源不够同时放下两套代码,因此采用了镜像切换的方式来实现,xilinx的专业术语叫multi boot功能 。意思是在一片Flash中的不同地址放两个代码镜像,通过FPGA的任意一个IO切换镜像。详细概念可以参考UG470,PG134等文档,本文仅讲具体的实现代码。

既然是多镜像,意思就是同一套硬件,有多套软件。类似于同一台电脑,可以装了一个linux系统,又装了一个win7系统,甚至多套系统。开机时由用户选择启动哪个系统。
本示例包含2个工程镜像,使用512Mbit的QSPI flash。工程1的镜像放在0地址,工程2的镜像放在地址0x02000000。当外部输入引脚SW为低电平时加载第一个镜像,否则加载第二个镜像。每当SW电平变化,都会启动镜像切换。
第一个工程的顶层如下:

module project1(
	input		CLK,//输入时钟,不要超过100M
	input		rst_n,//复位输入
	output		SW,	//输入为低电平启动镜像1,输入为高电平启动镜像2
	output		LED1,//镜像1亮,镜像2灭
	output		LED2 //镜像1灭,镜像2亮
    );
    
	assign 	LED1 = 1;
	assign 	LED2 = 0;        
    
    mult_boot mult_boot_inst(
        .clk        (CLK),
        .rst_n      (rst_n),
        .img_index  (0),
        .boot_sel   (SW));
endmodule

第二个工程顶层如下:

module project2(
	input		CLK,//输入时钟,不要超过100M
	input		rst_n,//复位输入
	output		SW,	//输入为低电平启动镜像1,输入为高电平启动镜像2
	output		LED1,//镜像1亮,镜像2灭
	output		LED2 //镜像1灭,镜像2亮
    );
    
	assign 	LED1 = 0;
	assign 	LED2 = 1;        
    
    mult_boot mult_boot_inst(
        .clk        (CLK),
        .rst_n      (rst_n),
        .img_index  (1),
        .boot_sel   (SW));
endmodule

注意两个工程都需要调用mult_boot模块,不同的工程img_index输入不一样。工程1设置为0,工程2设置为1。
如果你的SPI flash大于128Mb,必须加上如下约束:
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]

mult_boot.v代码如下:

module mult_boot(
    input   clk,
    input   img_index,  //constant to 0 for image0,1 for image1
    input   rst_n,
    input   boot_sel    //0=boot image0;1=boot image1;
);

    parameter [31:0]    IMAGE0_ADDR  = 32'h0;
    parameter [31:0]    IMAGE1_ADDR  = 32'h02000000;
    
    /*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..*/
    localparam [31:0]    WBSTAR_IMAGE0_ADDR  = {8'h0,IMAGE0_ADDR[31:8]};
    localparam [31:0]    WBSTAR_IMAGE1_ADDR  = {8'h0,IMAGE1_ADDR[31:8]};

    reg     [1:0]   state;
    reg             boot_sel_lock;
    wire    [31:0]  next_image_addr = (boot_sel_lock==0)? WBSTAR_IMAGE0_ADDR:WBSTAR_IMAGE1_ADDR;
    reg     [2:0]   index;
    reg     [31:0]  icap2_din;
    reg             icap2_csn;

   ICAPE2 #(
      .DEVICE_ID(0'h3691093),     // Specifies the pre-programmed Device ID value to be used for simulation
                                  // purposes.
      .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(),       // 32-bit output: Configuration data output bus
      .CLK(clk),            // 1-bit input: Clock Input
      .CSIB(icap2_csn),     // 1-bit input: Active-Low ICAP Enable
      .I(icap2_din),        // 32-bit input: Configuration data input bus
      .RDWRB(1'b0)         // 1-bit input: Read_n/Write Select input
   );

    function [31:0] icap_lut;
    input   [7:0]   index;
        begin
            case(index)
            0 :icap_lut={32'hFFFFFFFF         };//Dummy Word
            1 :icap_lut={32'hAA995566         };//Sync Word
            2 :icap_lut={32'h20000000         };//Type 1 NO OP
            3 :icap_lut={32'h30020001         };//Type 1 Write 1 Words to WBSTAR
            4 :icap_lut={next_image_addr      };//Warm Boot Start Address (Load the Desired Address)
            5 :icap_lut={32'h30008001         };//Type 1 Write 1 Words to CMD
            6 :icap_lut={32'h0000000F         };//IPROG Command
            7 :icap_lut={32'h20000000         };//Type 1 NO OP
            default:icap_lut=0;
            endcase
        end
    endfunction

	reg		[31:0]	command;
	always @ (posedge clk) command <= icap_lut(index);
        
    wire [31:0] command_swapped = {
        command[24],command[25],command[26],command[27],command[28],command[29],command[30],command[31],
        command[16],command[17],command[18],command[19],command[20],command[21],command[22],command[23],
        command[ 8],command[ 9],command[10],command[11],command[12],command[13],command[14],command[15],
        command[ 0],command[ 1],command[ 2],command[ 3],command[ 4],command[ 5],command[ 6],command[ 7]};        

    always @ (negedge clk or negedge rst_n)
    begin
        if(!rst_n) begin
            state<=0;icap2_csn<=1;boot_sel_lock<=img_index;index<=0;
        end
        else case(state)
            0:begin
                boot_sel_lock<=boot_sel;
                if(boot_sel_lock!=img_index)
                    state<=1;
            end
            1:begin
                if(index==8) begin
                    state<=0;index<=0;
                end
                else begin
                    state<=2;index<=index+1;icap2_csn<=0;icap2_din<=command_swapped;
                end
            end
            2:begin state<=3;icap2_csn<=1;end
            3:state<=1;
            default:state<=0;
        endcase
    end

endmodule

注意DEVICE_ID的值要根据具体FPGA的型号填入不同的值,V7系列请参考UG470的第14页。

最终实现的效果:SW输入0则加载第一个工程的镜像,LED1亮。SW输入1则加载第二个工程的镜像,LED2亮。
附上两个工程的bit文件合成一个mcs文件的脚本:

write_cfgmem  -format mcs -size 64 -interface SPIx4 -loadbit {up 0x00000000 "project1.bit" up 0x02000000 "project2.bit" } -force -file "merged.mcs"

有相关问题请留言


http://www.kler.cn/a/145249.html

相关文章:

  • 网站快速收录:利用新闻源的优势
  • Java基础知识总结(三十二)--API--- java.lang.Runtime
  • < OS 有关> BaiduPCS-Go 程序的 菜单脚本 Script: BaiduPCS-Go.Menu.sh (bdgo.sh)
  • 微服务入门(go)
  • 护眼好帮手:Windows显示器调节工具
  • 计算机网络之计算机网络主要性能
  • github timeout 问题解决 与访问加速
  • 从代码执行,看单片机内存的分配
  • Java中static、final、static final的区别
  • 第三节-Android10.0 Binder通信原理(三)-ServiceManager篇
  • MidJourney笔记(3)-Prompts
  • Linux加强篇005-用户身份与文件权限
  • 【ARM 嵌入式 编译系列 2.3 -- GCC 中指定 ARMv8-M 的 Thumb 指令集参数详细介绍】
  • 【cppcheck 静态代码分析工具使用教程】
  • 100元预算,轻松涨粉1000!腾讯运营面试秘籍大揭秘!
  • 美国汽车零部件巨头 AutoZone 遭遇网络攻击
  • Blender学习--模型贴图傻瓜级教程
  • C# 忽略大小写
  • C++ vector迭代器失效
  • libbz2 for Mac OS makefile
  • C语言--利用选择法对数组中的10个整数按由小到大排序
  • 13年老鸟总结,性能测试方法汇总+性能响应很慢排查方法(详全)
  • Linux内核--内存管理(十三)vmalloc的实现
  • 流程图是什么,用什么软件做?
  • WIFI模块(esp-01s)获取网络时间与天气信息
  • VCenter连接主机提示:未验证主机SSL证书的真实性