icap对flash的在线升级

文章目录

  • 一、icap原语介绍(针对 S6 系列的 ICap),之后可以拓展到A7、K7当中去
  • 二、程序1设计
    • 2.1信号结构框图
    • 2.2 icap_delay设计
    • 2.3 icap_ctrl设计(可以当模板使用,之后修改关键参数即可)
  • 三、程序2设计
  • 四、下板操作

要求:设计区域 1 的程序,上电后自动加载此程序,此时开始计时如果 20 秒内没有检测到串口发送的擦除指令,那么我们启动 icap 跳转,跳转到区域 2 程序中。如果希望再次升级的话必须重新给板卡上电使得程序回到区域 1 中,并在20秒计时内通过fpga_update软件将新的应用程序更新到flash中,实现flash的在线升级。
在这里插入图片描述

设计思想:我们制作两个程序,第一个区域执行程序 1(包含flash_ctrl和icap)能实现flash控制和程序跳转功能,这个区域的程序是固定的不会被修改。第二个区域的程序 2 是我们用户设计的功能程序或者说产品程序(有更新需求的程序)。

一、icap原语介绍(针对 S6 系列的 ICap),之后可以拓展到A7、K7当中去

icap原语查找方式(ise软件):

  1. language template
    在这里插入图片描述
  2. 在弹出的对话框中找到Internal Configuration Access Port。
    在这里插入图片描述
  3. icap 实例化原语
    在这里插入图片描述
    信号解释:

1、DEVICE_ID:不同芯片的DEVICE_ID不相同,在使用该原语时,要查找对应芯片的ID ;
2、SIM_CFG_FILE_NAME:仿真使用,默认即可。
3、BUSY:原语对应的忙信号
4、O:配置数据的输出
5、CE:原语的使能信号,低电平有效
6、CLK:原语的时钟信号
7、I:原语配置数据的输入信号,位宽为16bit需要按照步骤传输以下数据,
(其中 opcode 指的是器件 read 的命令(基于 spi 的 flash read 命令为 03h)
在这里插入图片描述
8、WRITE:读写原语的使能信号,低电平有效

需要注意的是:在我们传输这些配置数据时,需要将这些配置数据按照 byte 为单位,进行高低位互换,如下:
在这里插入图片描述

二、程序1设计

2.1信号结构框图

在这里插入图片描述

其中flash_ctrl模块之前已经实现:
这里介绍一下icap_delay 模块和 icap_ctrl模块(重点)

2.2 icap_delay设计

module icap_delay(input	wire 		sclk,input	wire 		rst,output	reg 		icap_flag,input	wire 		rx_flag,input	wire [7:0]	rx_data,output	wire 		led);parameter TIMER_END = 1000000000-1;
reg 	[31:0]	time_cnt;
reg				stop_flag;assign led = 1;// 接收到擦除指令的标志
always @(posedge sclk or posedge rst) beginif (rst == 1'b1) beginstop_flag <= 1'b0;endelse if (rx_flag== 1'b1 && rx_data == 8'hee) beginstop_flag <= 1'b1;end
end// 接收到擦除指令之前保持计数,接收到指令后停止计数(不是清0)
always @(posedge sclk or posedge rst) beginif (rst == 1'b1) begintime_cnt <= 'd0;endelse if (stop_flag == 1'b1) begintime_cnt <= time_cnt;endelse begintime_cnt <= time_cnt + 1'b1;end
end// icap执行跳转的标志,当计数超过20s后,执行icap完成跳转。
always @(posedge sclk or posedge rst) beginif (rst == 1'b1) beginicap_flag <= 1'b0;endelse if (time_cnt >= TIMER_END) beginicap_flag <= 1'b1;endelse beginicap_flag <= 1'b0;end
end
endmodule 

2.3 icap_ctrl设计(可以当模板使用,之后修改关键参数即可)

上面介绍了icap执行的关键就是向icap中顺序输入数据,且数据需要按照字节进行高低位互换。
顺序执行采用状态机跳转的方式即可。
在这里插入图片描述

module	icap_ctrl( 
input	wire	sclk	,
input	wire	rst_n	,
input	wire	pi_flag	
);wire		clk	;
reg		c_en	;
reg		wr_en	;
reg[15:0]	i_data	;	
wire[15:0]	i_crop	;reg[15:0]	state	;//使用时每个byte高低位需要互换
parameter	DUM_WORD	=	16'hFFFF;//空闲字
parameter	SYNC_WORD1	=	16'hAA99;//同步字1
parameter	SYNC_WORD2	=	16'h5566;//同步字2
parameter	GEN_WORD1	=	16'h3261;//向General1写1个type1的字数据
parameter	LOW_ADDR	=	16'h0000;//16位起始地址											-----------------根据flash实际划分的地址进行修改
parameter	GEN_WORD2	=	16'h3281;//向General2写1个type1的字数据
parameter	HIG_ADDR	=	16'h0310;//读操作码及高8位地址,操作码为0x03 read 0x0b fast Ready	-----------------根据flash实际划分的地址进行修改
parameter	GEN_WORD3	=	16'h32A1;//向General3写1个type1的字数据	
parameter	LOW_ADDR_BACK	=	16'h0000;//fallback起始低16位地址							    -----------------根据flash实际划分的地址进行修改
parameter	GEN_WORD4	=	16'h32C1;//向General4写1个type1的字数据	
parameter	HIG_ADDR_BACK	=	16'h0300;//读操作码及fallback高8位地址,操作码为0x03		    -----------------根据flash实际划分的地址进行修改
parameter	GEN_CMD_WORD	=	16'h30A1;//向CMD写1个type1的字数据	
parameter	IPROG_CMD	=	16'h000E;//IPROG命令
parameter	NOP_CMD		=	16'h2000;//空命令//状态
parameter	S_DUM_WORD	=	16'h0001;//空闲字
parameter	S_SYNC_WORD1	=	16'h0002;//同步字1
parameter	S_SYNC_WORD2	=	16'h0004;//同步字2
parameter	S_GEN_WORD1	=	16'h0008;//向General1写1个type1的字数据
parameter	S_LOW_ADDR	=	16'h0010;//16位起始地址
parameter	S_GEN_WORD2	=	16'h0020;//向General2写1个type1的字数据
parameter	S_HIG_ADDR	=	16'h0040;//操作码及高8位地址,操作码为0x03 普通读 0x0b FAST read
parameter	S_GEN_WORD3	=	16'h0080;//向General3写1个type1的字数据	
parameter	S_LOW_ADDR_BACK	=	16'h0100;//fallback起始低16位地址
parameter	S_GEN_WORD4	=	16'h0200;//向General4写1个type1的字数据	
parameter	S_HIG_ADDR_BACK	=	16'h0400;//操作码及fallback高8位地址
parameter	S_GEN_CMD_WORD	=	16'h0800;//向CMD写1个type1的字数据	
parameter	S_IPROG_CMD	=	16'h1000;//IPROG命令
parameter	S_NOP_CMD1	=	16'h2000;//空命令
parameter	S_NOP_CMD2	=	16'h4000;//空命令
parameter	S_NOP_CMD3	=	16'h8000;//空命令always@(posedge	sclk	or	negedge	rst_n)if(rst_n==1'b0)	state	<=	S_DUM_WORD;else case(state)S_DUM_WORD:if(pi_flag==1'b1)state	<=	S_SYNC_WORD1;S_SYNC_WORD1:state	<=	S_SYNC_WORD2;S_SYNC_WORD2:state	<=	S_GEN_WORD1;S_GEN_WORD1:state	<=	S_LOW_ADDR;S_LOW_ADDR:state	<=	S_GEN_WORD2;S_GEN_WORD2:state	<=	S_HIG_ADDR;S_HIG_ADDR:state	<=	S_GEN_WORD3;S_GEN_WORD3:state	<=	S_LOW_ADDR_BACK;S_LOW_ADDR_BACK:state	<=	S_GEN_WORD4;S_GEN_WORD4:state	<=	S_HIG_ADDR_BACK;S_HIG_ADDR_BACK:state	<=	S_GEN_CMD_WORD;S_GEN_CMD_WORD:state	<=	S_IPROG_CMD;S_IPROG_CMD:state	<=	S_NOP_CMD1;S_NOP_CMD1:state	<=	S_NOP_CMD2;S_NOP_CMD2:state	<=	S_NOP_CMD3;S_NOP_CMD3:state	<=	S_DUM_WORD;default:state	<=	S_DUM_WORD;endcase//先拉低写使能,再拉低时钟使能
always@(posedge	sclk	or	negedge	rst_n)if(rst_n==1'b0)	c_en	<=	1'b1;else if(state==S_SYNC_WORD2)c_en	<=	1'b0;else if(state==S_DUM_WORD)c_en	<=	1'b1;//先拉低写使能,再拉低时钟使能
always@(posedge	sclk	or	negedge	rst_n)if(rst_n==1'b0)	wr_en	<=	1'b1;else if(state==S_SYNC_WORD1)wr_en	<=	1'b0;else if(state==S_DUM_WORD)wr_en	<=	1'b1;//发送控制字
always@(posedge	sclk	or	negedge	rst_n)if(rst_n==1'b0)	i_data	<=	DUM_WORD;else case(state)S_DUM_WORD:i_data	<=	DUM_WORD;S_SYNC_WORD1:i_data	<=	SYNC_WORD1;S_SYNC_WORD2:i_data	<=	SYNC_WORD2;    S_GEN_WORD1:                           i_data	<=	GEN_WORD1;     S_LOW_ADDR:                            i_data	<=	LOW_ADDR;      S_GEN_WORD2:                           i_data	<=	GEN_WORD2;     S_HIG_ADDR:                            i_data	<=	HIG_ADDR;      S_GEN_WORD3:                           i_data	<=	GEN_WORD3;     S_LOW_ADDR_BACK:                       i_data	<=	LOW_ADDR_BACK; S_GEN_WORD4:                           i_data	<=	GEN_WORD4;     S_HIG_ADDR_BACK:                       i_data	<=	HIG_ADDR_BACK; S_GEN_CMD_WORD:                        i_data	<=	GEN_CMD_WORD;  S_IPROG_CMD:                           i_data	<=	IPROG_CMD;     S_NOP_CMD1:                            i_data	<=	NOP_CMD;       S_NOP_CMD2:                            i_data	<=	NOP_CMD;       S_NOP_CMD3:                            i_data	<=	NOP_CMD;      default:i_data	<=	NOP_CMD;endcase//对输入的数据按字节为单位进行高低位互换	
assign	i_crop	=	{i_data[8],i_data[9],i_data[10],i_data[11],i_data[12],i_data[13],i_data[14],i_data[15],i_data[0],i_data[1],i_data[2],i_data[3],i_data[4],i_data[5],i_data[6],i_data[7]};//实例化icap原语		
ICAP_SPARTAN6 #(                                                                                          
.DEVICE_ID('h4001093),     //不同型号的芯片,ID号不同 x9 ID='h4001093
.SIM_CFG_FILE_NAME("NONE")  // Specifies the Raw Bitstream (RBT) file to be parsed by the simulationendmodule// model                                                                
)                                                                                                      
ICAP_SPARTAN6_inst (                                                                                   
.BUSY(BUSY),   // 1-bit output: Busy/Ready output                                                   
.O(O),         // 16-bit output: Configuartion data output bus                                      
.CE(c_en),       // 1-bit input: Active-Low ICAP Enable input                                         
.CLK(sclk),     // 1-bit input: Clock input                                                          
.I(i_crop),         // 16-bit input: Configuration data input bus                                        
.WRITE(wr_en)  // 1-bit input: Read/Write control input                                             
);  endmodule    

三、程序2设计

这里直接使用之前设计的一个呼吸灯

四、下板操作

关于操作方面,首先要有一个意识:fpga首先要有flash控制的功能(这是前提!!),然后才能执行对flash进行读写等操作)。

这里介绍一下老师提供的一个小软件,fpga_update,界面如下,可以实现flash的写操作。
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/689144.html

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

相关文章

Edge视频增强功能

edge://flags/#edge-video-super-resolution 搜索Video查找 Microsoft Video Super Resolution 设置为Enabled

Selenium 保存会话信息避免重复登录实战!

前言 • 在一些实际开发场景中&#xff0c;我们在使用 Selenium 做自动化测试时需要保留用户的会话信息&#xff0c;从而避免重复登录&#xff0c;今天这篇文章就带大家实战如何使用 Selenium 保存会话信息。 版本 • Python 3.x 整体思路 • 当我们打开页面时&#xff0c;…

Android system property运作流程源码分析

一.序 前文分析了build.prop这个系统属性文件的生成&#xff0c;每个属性都有一个名称和值&#xff0c;他们都是字符串格式。属性被大量使用在Android系统中&#xff0c;用来记录系统设置或进程之间的信息交换。属性是在整个系统中全局可见的。每个进程可以get/set属性&#x…

【教学类-54-01】20240510超级对对碰(圆点拼图)(9*5、0-255随机)

作品展示 背景需求&#xff1a; 奕娃幼儿园小中大班益智区超级对对碰 - 小红书#幼儿园益智区 #幼儿园益智区素材 #幼儿园区域材料 #幼儿园环创https://www.xiaohongshu.com/discovery/item/6279bb4d000000002103be71?app_platformandroid&ignoreEngagetrue&app_ve…

【Redis】Redis 事务

Redis 的事务的本质是一组命令的批处理。这组命令在执行过程中会被顺序地、一次性 全部执行完毕&#xff0c;只要没有出现语法错误&#xff0c;这组命令在执行期间不会被中断 1.事务特性 仅保证了数据的一致性 这组命令中的某些命令的执行失败不会影响其它命令的执行&#xff…

如何挑选家用洗地机?需要注意什么?这四款洗地机性价比超高

洗地机结合了扫、拖、吸的功能&#xff0c;一台机器&#xff0c;一个推拉的动作便可以清理干净地面上的干湿垃圾&#xff0c;大大的节省了我们做家务的清洁时间&#xff0c;提升了生活质量。但是面对市面上众多的洗地机型号&#xff0c;我们要怎么去挑选呢&#xff0c;需要主要…

Linux下安装mysql8.0(以tar.xz包安装--编译安装)

前言&#xff1a;原文在我的博客网站中&#xff0c;持续更新数通、系统方面的知识&#xff0c;欢迎来访&#xff01; Linux下安装mysql8.0&#xff08;以tar.xz包安装--编译安装&#xff09;https://myweb.myskillstree.cn/126.html 目录 一、下载对应自己glic版本的MySQL …

论文解读--High-resolution Automotive Radar Point Cloud Imaging and Processing

高分辨汽车雷达点云成像和处理 摘要 汽车雷达具有体积小、硬件成本低、全天候工作、高分辨率等公认的优点&#xff0c;是高级驾驶辅助系统(ADAS)必不可少的一类重要传感器。然而&#xff0c;低角度分辨率和低成像性能的限制很难满足下一阶段ADAS的需要。新兴的4D成像雷达采用多…

如何打破数据管理僵局,释放数据资产价值?[AMT企源案例]

引言 数据是企业信息运作的核心和基础&#xff0c;是影响企业决策的关键要素&#xff0c;而主数据是数据中的最基础和公共的部分。面临长期以来的数据治理缺失导致的杂论局面&#xff0c;如何有条不紊推进主数据管理&#xff0c;让数据资产“活”起来&#xff1f;S集团的做法非…

Python可以自学但是千万不要乱学,避免“埋头苦学”的陷阱!

前言 Python可以自学但是千万不要乱学&#xff01; 归根结底因为学习是个反人性的过程&#xff01; 复盘没学下去的网课&#xff0c;都有以下特点&#xff1a; &#x1f605; 臣妾听不懂啊&#xff01; 初次接触编程遇到太多抽象高深的概念&#xff0c;不了解老师口中的一个…

Android APP读写外置SD卡无权限 java.io.IOException: Permission denied

在物联网应用里&#xff0c;app需要对挂载SD卡读写文件&#xff0c;从 Android 4.4&#xff08;KitKat&#xff09;版本开始&#xff0c;Google 引入了一项名为 "Storage Access Framework" 的新功能&#xff0c;该功能限制了应用对外部存储的直接读写权限,要不然就是…

【电容】芯片旁边为什么要接0.1uf(100nF)电容,退耦电容是什么意思,为什么要大电容并小电容

系列文章目录 1.元件基础 2.电路设计 3.PCB设计 4.元件焊接 5.板子调试 6.程序设计 7.算法学习 8.编写exe 9.检测标准 10.项目举例 11.职业规划 ** 一般芯片旁边为什么都会放一个小电容&#xff0c;而且大部分情况下都是100nF ** 1、为什么要放这个电容 首先我们知道这个…