icap对flash的在线升级

news2024/9/22 1:31:22

文章目录

  • 一、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) begin
	if (rst == 1'b1) begin
		stop_flag <= 1'b0;
	end
	else if (rx_flag== 1'b1 && rx_data == 8'hee) begin
		stop_flag <= 1'b1;
	end
end

// 接收到擦除指令之前保持计数,接收到指令后停止计数(不是清0)
always @(posedge sclk or posedge rst) begin
	if (rst == 1'b1) begin
		time_cnt <= 'd0;
	end
	else if (stop_flag == 1'b1) begin
		time_cnt <= time_cnt;
	end
	else begin
		time_cnt <= time_cnt + 1'b1;
	end
end

// icap执行跳转的标志,当计数超过20s后,执行icap完成跳转。
always @(posedge sclk or posedge rst) begin
	if (rst == 1'b1) begin
		icap_flag <= 1'b0;
	end
	else if (time_cnt >= TIMER_END) begin
		icap_flag <= 1'b1;
	end
	else begin
		icap_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.coloradmin.cn/o/1666310.html

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

相关文章

如何同时或者按顺序间隔启动多个程序

首先&#xff0c;需要用到的这个工具&#xff1a; 度娘网盘 提取码&#xff1a;qwu2 蓝奏云 提取码&#xff1a;2r1z 1、打开工具&#xff0c;切换到定时器模块&#xff0c;快捷键&#xff1a;Ctrl3 2、新建一个定时器&#xff0c;我这里演示同时打开多个程序&#xff08;比…

在shell程序里如何从文件中获取第n行

问题&#xff1a; 有没有一种“规范”的方式来做到这一点&#xff1f;我一直在使用 head -n | tail -1&#xff0c;它可以做到这一点&#xff0c;但我一直想知道是否有一个Bash工具&#xff0c;专门从文件中提取一行(或一段行)。 所谓“规范”&#xff0c;我指的是一个主要功…

HTML五彩缤纷的爱心

写在前面 小编准备了一个五彩缤纷的爱心&#xff0c;送给各位小美女们~ 在桌面创建一个.txt文本文件&#xff0c;把代码复制进去&#xff0c;将后缀.txt改为.html&#xff0c;然后就可以双击运行啦&#xff01; HTML简介 HTML&#xff08;超文本标记语言&#xff09;是一种…

Stable Diffusion是什么?

目录 一、Stable Diffusion是什么&#xff1f; 二、Stable Diffusion的基本原理 三、Stable Diffusion有哪些运用领域&#xff1f; 一、Stable Diffusion是什么&#xff1f; Stable Diffusion是一个先进的人工智能图像生成模型&#xff0c;它能够根据文本描述创造出高质量的图…

VMware安装centos7教程

文章目录 1、centos7的ios镜像下载2、CentOS7安装3、Centos配置 其他教程&#xff1a; 1、VMware Workstation 16 Pro安装教程 2、VMwarePro16安装Ubuntu16.04图文教程 1、centos7的ios镜像下载 官网&#xff1a;https://vault.centos.org/ 阿里云&#xff1a;https://develo…

Idea入门:一分钟创建一个Java工程

一&#xff0c;新建一个Java工程 1&#xff0c;启动Idea后&#xff0c;选择 [New Project] 2&#xff0c;完善工程信息 填写工程名称&#xff0c;根据实际用途取有意义的英文名称选择Java语言&#xff0c;可以看到还支持Kotlin、Javascript等语言选择包管理和项目构建工具Mav…

新闻资讯微信小程序开发后端+php【附源码,文档说明】

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

2024最新版JavaScript逆向爬虫教程-------基础篇之无限debugger的原理与绕过

目录 一、无限debugger的原理与绕过1.1 案例介绍1.2 实现原理1.3 绕过debugger方法1.3.1 禁用所有断点1.3.2 禁用局部断点1.3.3 替换文件1.3.4 函数置空与hook 二、补充2.1 改写JavaScript文件2.2 浏览器开发者工具中出现的VM开头的JS文件是什么&#xff1f; 三、实战 一、无限…

Java构造方法详解

在Java方法内部定义一个局部变量时&#xff0c;必须要初始化&#xff0c;否则就会编译失败&#xff0c;如下&#xff1a; 要让上述代码通过编译&#xff0c;只需在使用a之前给a赋一个初始值即可 如果是对象&#xff1a;下面用一个日期类演示 我们没有给年月日赋值&#xff0c;…

laravel8 导入 excel常见问题

上传xls 或 xlsx 文件后&#xff0c;文件解析为 zip 格式&#xff0c;输入正常情况&#xff0c;不影响解析 里面的内容 遇到解析内容&#xff0c;解析为空的情况&#xff0c;可能是 因为excel 存在多个 Sheet1 造成&#xff0c;服务器不能解析一个 Sheet1 的情况&#xff0…

阿里开源编程大模型 CodeQwen1.5:64K92编程语言,Code和SQL编程,评测接近GPT-4-Turbo

前言 阿里巴巴最近发布的CodeQwen1.5模型标志着其在编程语言模型领域的一次重大突破。这款开源模型不仅支持高达92种编程语言和64K的上下文长度&#xff0c;而且在多项性能评测中显示出接近或超过当前行业领导者GPT-4-Turbo的能力。 Huggingface模型下载&#xff1a;https://h…

# ERROR: node with name “rabbit“ already running on “MS-ITALIJUXHAMJ“ 解决方案

ERROR: node with name “rabbit” already running on “MS-ITALIJUXHAMJ” 解决方案 一、问题描述&#xff1a; 1、启动 rabbitmq-server.bat 服务时&#xff0c;出错 Error 2、查询 rabbitmqctl status 状态时&#xff0c;出错 Error 3、停止 rabbitmqctl stop 服务时&a…

如何使用CertCrunchy从SSL证书中发现和识别潜在的主机名称

关于CertCrunchy CertCrunchy是一款功能强大的网络侦查工具&#xff0c;该工具基于纯Python开发&#xff0c;广大研究人员可以利用该工具轻松从SSL证书中发现和识别潜在的主机信息。 支持的在线源 该工具支持从在线源或给定IP地址范围获取SSL证书的相关数据&#xff0c;并检索…

A Dexterous Hand-Arm Teleoperation System

A Dexterous Hand-Arm Teleoperation System Based on Hand Pose Estimation and Active Vision解读 摘要1. 简介2.相关工作2.1 机器人遥操作2.2 主动视觉&#xff08;Active Vision&#xff09; 3. 硬件设置4. 基于视觉的机器人手部姿态估计4.1 Transteleop4.2 Dataset 5. 主动…

【基础绘图】 09.小提琴图

效果图&#xff1a; 主要步骤&#xff1a; 1. 数据准备&#xff1a;生成随机数组 2. 数据处理&#xff1a;计算四分位数、中位数、均值、最大最小值 3. 图像绘制&#xff1a;绘制小提琴图 详细代码&#xff1a;着急的直接拖到最后有完整代码 步骤一&#xff1a;导入库包及…

使用C#和NMODBUS快速搭建MODBUS从站模拟器

MODBUS是使用广泛的协议&#xff0c;通讯测试时进行有使用。Modbus通讯分为主站和从站&#xff0c;使用RS485通讯时同一个网络内只能有一个主站&#xff0c;多个从站。使用TCP通讯时没有这方面的限制&#xff0c;可以同时支持多个主站的通讯读写。 开发测试时有各种复杂的需求&…

Milvus中那些年重要的基本概念

Milvus是一款开源的云原生向量数据库&#xff0c;专为海量向量数据的存储、检索和管理而设计。它支持实时的向量相似度搜索&#xff0c;适用于各种AI和机器学习应用场景。以下是Milvus的一些基本概念&#xff1a; 非结构化数据 非结构化数据是指那些不遵循特定数据模型或格式、…

npm无法安装node-sass 的问题

安装 node-sass 的问题呈现&#xff1a;4.9.0版本无法下载 Downloading binary from https://github.com/sass/node-sass/releases/download/v4.9.0/win32-x64-72_binding.node Cannot download "https://github.com/sass/node-sass/releases/download/v4.9.0/win32-x64-…

Linux服务器常用巡检命令,查看日志

查看日志 3.1 通过journalctl命令查看系统日志 命令&#xff1a;journalctl 3.2 通过tail查看系统日志 查看日志文件多少行代码&#xff1a;tail -n [行数] [日志文件] 4. 服务状态 4.1 查看指定服务的状态 命令&#xff1a;systemctl status <service> 比如查看防火墙…

React 第三十四章 React 渲染流程

现代前端框架都可以总结为一个公式&#xff1a;UI f&#xff08;state&#xff09; 上面的公式还可以进行一个拆分&#xff1a; 根据自变量&#xff08;state&#xff09;的变化计算出 UI 的变化根据 UI 变化执行具体的宿主环境的 API 对应的公式&#xff1a; const state…