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,//输入时钟,不要超过100Minput		rst_n,//复位输入output		SW,	//输入为低电平启动镜像1,输入为高电平启动镜像2output		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,//输入时钟,不要超过100Minput		rst_n,//复位输入output		SW,	//输入为低电平启动镜像1,输入为高电平启动镜像2output		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 image1input   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 writtento WBSTAR[23:0]. For SPI 32-bit addressing mode, WBSTAR[23:0] are sent as address bits [31:8]. Thelower 8 bits of the address are undefined and the value could be as high as 0xFF. Any bitstream at theWBSTAR 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;begincase(index)0 :icap_lut={32'hFFFFFFFF         };//Dummy Word1 :icap_lut={32'hAA995566         };//Sync Word2 :icap_lut={32'h20000000         };//Type 1 NO OP3 :icap_lut={32'h30020001         };//Type 1 Write 1 Words to WBSTAR4 :icap_lut={next_image_addr      };//Warm Boot Start Address (Load the Desired Address)5 :icap_lut={32'h30008001         };//Type 1 Write 1 Words to CMD6 :icap_lut={32'h0000000F         };//IPROG Command7 :icap_lut={32'h20000000         };//Type 1 NO OPdefault:icap_lut=0;endcaseendendfunctionreg		[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)beginif(!rst_n) beginstate<=0;icap2_csn<=1;boot_sel_lock<=img_index;index<=0;endelse case(state)0:beginboot_sel_lock<=boot_sel;if(boot_sel_lock!=img_index)state<=1;end1:beginif(index==8) beginstate<=0;index<=0;endelse beginstate<=2;index<=index+1;icap2_csn<=0;icap2_din<=command_swapped;endend2:begin state<=3;icap2_csn<=1;end3:state<=1;default:state<=0;endcaseendendmodule

注意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.mzph.cn/news/170624.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

详解#define

我们要知道&#xff0c;#define后面定义的标识符只进行替换而不进行计算&#xff0c;我们不能根据惯性自动给它计算了&#xff0c;这样可能会出错。 目录 1.关于#define 1.1#define定义标识符 1.2#define定义宏 1.3#define的替换规则 2.#和## 1.# 2.## 3.带副作用的宏参…

力扣labuladong——一刷day50

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣100. 相同的树二、力扣1367. 二叉树中的链表三、力扣105. 从前序与中序遍历序列构造二叉树四、力扣654. 最大二叉树 前言 最常见的&#xff0c;二叉树的…

git查看某个commit属于哪个分支方法(如何查看commit属于哪个分支)

有时候&#xff0c;当我们由于业务需求很多时&#xff0c;基于同一个分支新建的项目分支也会很多。 在某个时间节点&#xff0c;我们需要合并部分功能点时&#xff0c;我们会忘了这个分支是否已经合入哪个功能点&#xff0c;我们就会查看所有的commit记录&#xff0c;当我们找到…

python生成邀请码,手机验证码

python生成邀请码,手机验证码 使用python生成邀请码,手机验证码,大小写字母,数字等,示例代码如下。 1、获取随机码 import randomdef get_random_code(is_digit=False, num=6):获取随机码:param is_digit: 是否为全数字:param num: 长度:return:if is_digit:sequence =…

1.4 8位加法器

1.半加器 2.全加器 半加器: 完整模拟1位加法 1.A,B 接受端,接受1或0 , 2个电信号 2.异或门 做为结果: 1^10, 0^00, 1^01, 0^11 与编程中的: 异或一致 3.与门 做为进位: 1&11,1&00,0&10, 0&01 与编程中的: 与一致 4.半加器实现1位的加法运算,比如:A端: …

[Java]线程详解

Java线程 一、线程介绍 程序 是为完成特定任务、用某种语言编写的一组指令的集合&#xff08;简单来说就是写的代码&#xff09;。 进程 进程是指运行中的程序&#xff0c;比如我们使用的QQ&#xff0c;就启动了一个进程&#xff0c;操作系统会对该进程分配内存空间。当我…

Docker pause/unpause命令

docker pause &#xff1a;暂停容器中所有的进程。 docker unpause &#xff1a;恢复容器中所有的进程。 语法 docker pause CONTAINER [CONTAINER...]docker unpause CONTAINER [CONTAINER...]实例 暂停数据库容器db01提供服务。 docker pause db01恢复数据库容器db01提供…

QXDM Filter使用指南

QXDM Filter使用指南 1. QXDM简介2 如何制作和导入Filter2.1 制作Filter2.1.1 制作Windows环境下Filter2.1.2 制作Linux环境下Filter 2.2 Windows环境下导入Filter 3 Filter配置3.1 注册拨号问题3.1.1 LOG Packets(OTA)3.1.2 LOG Packets3.1.3 Event Reports3.1.4 Message Pack…

Vue3 封装组件库并发布到npm仓库

一、创建 Vue3 TS Vite 项目 输入项目名称&#xff0c;并依次选择需要安装的依赖项 npm create vuelatest 项目目录结构截图如下&#xff1a; 二、编写组件代码、配置项和本地打包测试组件 在项目根目录新建 package 文件夹用于存放组件 &#xff08;以customVideo为例&a…

利用Python实现顺序栈

1 问题 在常用的数据结构中&#xff0c;有一批结构被称为容器——栈与队列。那该怎么利用Python学习栈这种结构的特性并用Python实现其相关操作呢&#xff1f; 2 方法 栈相对于是一个容器&#xff0c;而这个容器里包含的是一些元素。同时&#xff0c;栈是保证元素后进先出关系的…

系列十六、Spring IOC容器的扩展点

一、概述 Spring IOC容器的扩展点是指在IOC加载的过程中&#xff0c;如何对即将要创建的bean进行扩展。 二、扩展点 2.1、BeanDefinitionRegistryPostProcessor 2.1.1、概述 BeanDefinitionRegistryPostProcessor是bean定义的后置处理器&#xff0c;在BeanDefinition加载后&a…

C++知识点总结(7):玩转高精度除法

一、复习高低精度 一个数分为两种类型&#xff1a; 1. 高精度数&#xff0c;即一个长度特别长的数&#xff0c;使用 long long 也无法存储的一类数字。 2. 低精度数&#xff0c;即一个普通的数&#xff0c;可以使用 long long 来存储。 由于高精度除法比较简单&#xff0c;…

卸载11.3的cuda,安装11.8的cuda及cudnn

linux查看cudnn版本_linux查看cudnn版本命令_在学习的王哈哈的博客-CSDN博客文章浏览阅读2.9k次&#xff0c;点赞6次&#xff0c;收藏6次。英伟达官方文档查看cuda版本cat /usr/local/cuda/version.txt或者nvcc --version 或者 nvcc -V查看cudnn版本网上都是这个但是不行cat /u…

【超强笔记软件】Obsidian实现免费无限流量无套路云同步

【超强笔记软件】Obsidian如何实现免费无限流量无套路云同步&#xff1f; 目录 一、简介 软件特色演示&#xff1a; 二、使用免费群晖虚拟机搭建群晖Synology Drive服务&#xff0c;实现局域网同步 1 安装并设置Synology Drive套件 2 局域网内同步文件测试 三、内网穿透群…

Stable-Diffusion——Windows部署教程

Windows 参考文章&#xff1a;从零开始&#xff0c;手把手教你本地部署Stable Diffusion Webui AI绘画(非最新版) 一键脚本安装 默认环境安装在项目路径的venv下 conda create -n df_env python3.10安装pytorch&#xff1a;&#xff08;正常用国内网就行&#xff09; python -…

【Python篇】详细讲解正则表达式

文章目录 &#x1f339;什么是正则表达式&#x1f354;语法字符类别重复次数组合模式 ✨例子 &#x1f339;什么是正则表达式 正则表达式&#xff08;Regular Expression&#xff09;&#xff0c;简称为正则或正则表达式&#xff0c;是一种用于匹配、查找和操作文本字符串的工…

Linux:docker基础操作(3)

docker的介绍 Linux&#xff1a;Docker的介绍&#xff08;1&#xff09;-CSDN博客https://blog.csdn.net/w14768855/article/details/134146721?spm1001.2014.3001.5502 通过yum安装docker Linux&#xff1a;Docker-yum安装&#xff08;2&#xff09;-CSDN博客https://blog.…

华为OD机试2023年最新题库(Python、JAVA、C++、JS)

我是一名软件开发培训机构老师&#xff0c;我的学生已经有上百人通过了华为OD机试&#xff0c;学生们每次考完试&#xff0c;会把题目拿出来一起交流分享。 重要&#xff1a;2023年11月份开始&#xff0c;考的都是OD统一考试&#xff08;C卷&#xff09;&#xff0c;题库已经整…

mysql使用--存储程序

1.概述 存储程序可以封装一些语句&#xff0c;为用户提供一种简单的方式来调用这个存储程序&#xff0c;从而间接执行其封装的语句。 根据调用方式的不同&#xff0c;可把存储程序分为存储例程、触发器、事件几种类型。其中&#xff0c;存储例程又可被细分为存储函数和存储过程…

openssl+ ECC + linux 签名校验开发实例(C++)

文章目录 ECC签名过程&#xff08;ECDSA签名&#xff09;ECC验证过程&#xff08;ECDSA验证&#xff09;C示例代码 ECC&#xff08;Elliptic Curve Cryptography&#xff09;是一种基于椭圆曲线数学结构的密码学技术。在ECC中&#xff0c;签名和验证过程使用的是数字签名算法&a…