使用ZYNQ实现单LUT内容的动态修改(一)PL端OOC设计流程
一,摘要
本文主要用于记录作者本人实现ZYNQ动态修改LUT内容过程中主要参考的资料,实现的步骤,遇到的问题等。主要参考的文章链接如下:https://cloud.tencent.com/developer/article/1528881,其中该工作大部分的原理部分该篇博客都有介绍,本篇博客不再赘述。
在此我主要介绍一下使用Vivado进行部分动态重构系统的开发流程,AXI_HWICAP IP基本的使用方法,以及通过ARM部分实现LUT内容动态修改的程序流程(此部分见下篇博客)。
二,系统框图
系统结构主要如上图,其中LUT的读写操作由PS端的程序控制,通过PC端的串口助手可以观察读取的配置帧数据,设置要修改的LUT位置以及修改后的LUT中的新数据。
三,PL工程的创建,综合,布局布线。
考虑到调试过程中可能要多次设置目标LUT的初始值来搞清楚bitstream中数据与LUT中数据的映射关系,为了提高该系统的编译调试效率,本文针对目标操作的LUT采取局部动态重构的设计方法。实际应用中不采用部分重构设计流程也可以对LUT进行动态读写。
以下是本次设计使用Vivado进行部分重构系统开发的整体流程:
- 使用Vivado创建整个设计,将部分重构模块保留为空模块。综合工程生成静态设计的.dcp文件(如top_syn_static.dcp)。
- 综合部分重构模块的源文件,生成对应的.dcp文件(如:pr_lut_syn.dcp)。
- 打开第一步生成的top_syn_static.dcp,读入第二步生成的pr_lut_syn.dcp,设置重构属性,保存设计点。
- 为重构模块指定重构区域,读入约束文件。
- 优化,布局,布线,保存设计点。
- 生成bitstream文件,及ila调试相关文件。
- 将重构模块清除保留为黑盒,将其他部分在布局布线后的级别上保存其设计点。
- 打开上一步保存的设计点,读入新的重构模块,优化,布局布线,保存设计点,生成bitstream等。
- 使用pr_verify指令对生成的bitstream进行验证。
第一步,创建设计。
可直接在给出的工程目录下面执行脚本自动创建,综合,以及硬件的导出。在工程目录下执行以下代码(windows下需要在Vivado的命令行下操作):
source ./tcl/step1_create_project.tcl
具体工程文件结构如下图所示:
其中原理图部分如下:
这一步我们要用到的文件为.\vivado\lut_modify.runs\synth_1\top.dcp,我们需要将此文件复制到.\checkpoints\synth\static\路径下,便于后续操作。
当然也可以自己手动来创建工程,编写相关文件。
第二步,综合重构模块
直接执行脚本文件即可,脚本代码如下:
read_verilog ./src/rms/pr_lut1/pr_lut.v
synth_design -mode out_of_context -flatten_hierarchy rebuilt -top pr_lut -part xc7z020clg400-1
write_checkpoint ./checkpoints/synth/rms/pr_lut1.dcp
close_design
close_project
以下是重构模块的verilog代码,该模块例化一个内部的固定位置的LUT,便于我们以后寻址更改其内部内容:
`timescale 1ns/1ps //*******************
//DEFINE MODULE PORT
//*******************
module pr_lut ( input clk ,input rst ,input [5:0] din ,output reg dout ) ;//*********************
//INNER SIGNAL DECLARATION
//*********************
//REGS
reg [5:0] din_ff ;//WIRESwire dout_pre ;
//*********************
//MAIN CORE
//*********************
always @(posedge clk or posedge rst) beginif (rst == 1'b1) begindin_ff <= 'd0 ;endelse begindin_ff <= din ;end
endalways @(posedge clk or posedge rst) beginif (rst == 1'b1) begindout <= 'd0 ;endelse begindout <= dout_pre ;end
end
// 0001 0010 0011(* DONT_TOUCH= "TRUE" *) (*BEL="D6LUT",LOC="SLICE_X57Y53"*) LUT6 #(.INIT(64'h1234123412341234) // Specify LUT Contents ) LUT6_inst_D_right (.O(dout_pre), // LUT general output.I0(din_ff[0]), // LUT input.I1(din_ff[1]), // LUT input.I2(din_ff[2]), // LUT input.I3(din_ff[3]), // LUT input.I4(din_ff[4]), // LUT input.I5(din_ff[5]) // LUT input);//*********************
endmodule
该步操作主要生成的文件如下图,后面可用不同lut初始值的rm来创建完整设计,方便在bitstream文件中找到目标lut配置数据的位置及内容。便于分析bitstream配置数据同实际LUT中数据的映射关系:
第三步,打开设计点,读入重构模块,划分重构区域
执行以下脚本
open_checkpoint ./checkpoints/synth/static/top.dcp
read_checkpoint -cell pr_lut_0 ./checkpoints/synth/rms/pr_lut1.dcp
set_property HD.RECONFIGURABLE 1 [get_cells pr_lut_0]
write_checkpoint ./checkpoints/synth/top_link_lut.dcp -force #划分重构区域。
startgroup
create_pblock pblock_pr_lut_0
resize_pblock pblock_pr_lut_0 -add {SLICE_X54Y50:SLICE_X59Y59 RAMB18_X3Y20:RAMB18_X3Y23 RAMB36_X3Y10:RAMB36_X3Y11}
add_cells_to_pblock pblock_pr_lut_0 [get_cells [list pr_lut_0]] -clear_locs
endgroup
其中为重构模块划分重构区域手动操作如下图,然后在layout上面绘制相应的重构区域即可,注意:此例中由于指定了LUT的位置信息,所以重构区域必须覆盖到该LUT的物理区域。
此例中划分的重构区域如下:
第四步,优化,布局布线,保存设计点,生成.bit及.rbt文件。
直接执行以下命令:
opt_design
place_design
route_design
write_checkpoint -force ./checkpoints/implement/top_route_design.dcp
write_checkpoint -force -cell pr_lut_0 ./checkpoints/implement/pr_lut_instance_route_design.dcp
write_bitstream -raw_bitfile ./bitstreams/top1 -force
write_debug_probes -force ./bitstreams/top
执行上述命令后可以观察到器件已经完成布局布线,此时可生成对应的bitstream文件及部分bitstream文件。我们可通过生成的top.rbt来分析top.bit的结构,(top.rbt为top.bit的二进制asii格式表示,可通过python脚本来将rbt文件转换为16进制格式表示数据并保存为txt文件,后续我们从器件中读配置数据的时候要与之进行对比,来验证读操作的正确性)
第五步,保存静态设计。
脚本命令如下:
update_design -cell pr_lut_0 -black_box
lock_design -level routing
write_checkpoint -force ./checkpoints/routed/static_route_design.dcpupdate_design -buffer_ports -cell pr_lut_0
place_design
route_design
write_checkpoint -force ./checkpoints/implement/top_route_design.dcp
close_project
第六步,读入新的重构模块,生成的完整bit文件及部分bit文件。
脚本和上面操作多有重复,这里不再给出。
本操作的意义在于利用前面保存过的静态设计,载入新的重构模块进行综合,布局布线,大大减少了整个工程综合,布局布线的时间成本。
针对此次设计任务需求,需要多次更改目标LUT的初始值,采用此种设计流程能够大大减少后期bitstream文件的生成时间,而不必牵一发而动全身,每次都浪费这么长的时间来进行类似的操作。
第七步,验证两个设计是否兼容。
脚本命令如下:
pr_verify -initial ./checkpoints/implement/top_route_design.dcp -additional {./checkpoints/implement/top_route_design2.dcp }
close_project
验证结果如下图
至此整个重构系统基于Vivado的脱离上下文的设计流程结束。
四、AXI_HWICAP相关信息
相关寄存器如下表:
读写配置:
- 将bitstream写进写FIFO寄存器进行配置。
- 从读FIFO寄存器读取配置bitstream。
- 向CR寄存器写值去启动bitstream的读取或写入,控制寄存器决定了数据传输的方向。向控制寄存器写入0x00000001开始写配置。写0x00000002开始读配置。
- 状态寄存器的Done位表明了ICAPEn接口是否处于忙碌状态,并不代表读配置或写配置是否成功完成。
- 在成功进行读或者写配置之后硬件清零CR寄存器。
- 在CR寄存器未被清零的情况下,软件不能初始化另一个读或写配置操作。
精简模式下写序列:
- 将指令写进写FIFO寄存器进行配置。
- 向控制寄存器写控制字初始化写指令。
- 成功完成配置后硬件清零控制寄存器位。
- 向写FIFO寄存器写入第二个指令,写控制字执行向ICAPEn端口的写操作。
- 继续执行上述操作直到所有指令被写到ICAPEn端口。
中止:
- 向控制寄存器写控制字开始bitstream读写。
- 将bitstream写入到FIFO寄存器执行配置,从读FIFO寄存器获取读取到的bitstream。
- 向控制寄存器的第五位写1来执行中止。
- 状态寄存器的Done位显示了ICAPEn端口是否正处于忙碌状态,不表示读,写操作成功完成。
- 在成功执行中止操作后硬件清零控制寄存器位。
- 在CR寄存器未被清零的情况下,软件不能初始化另一个读或写配置操作。
注意:
- 帧是配置数据允许被读或写的最小粒度。
- 修改单个LUT内容必须读出整帧,修改后再将整帧数据读入。
五、总结
本篇博客主要记录了使用Vivado工具进行脱离上下文(Out Of Context)方式进行开发的流程。以本篇生成的硬件系统为基础,可以进一步通过PS端的软件编程来实现对目标LUT的内容进行修改,亦可通过软件来为PR区域加载不同的重构模块来实现FPGA内部电路的动态重构。
使用ZYNQ实现单LUT内容的动态修改(一)PL端OOC设计流程相关推荐
- android 状态栏一体化 fragment,单Activity多Fragment动态修改状态栏颜色功能
目录介绍 1.关于如何集成 2.关于如何使用 3.关于鸣谢 4.关于版本更新说明 5.关于其他介绍 0.说明 状态栏工具类,应该可以满足绝大多数的使用场景.具体可以参考代码案例,欢迎star!! 1. ...
- Logback中使用TurboFilter实现日志级别等内容的动态修改
可能看到这个标题,读者会问:要修改日志的级别,不是直接修改log.xxx就好了吗?为何要搞那么复杂呢? 所以,先说一下场景,为什么要通过TurboFilter去动态的修改日志级别.我们在使用Java开 ...
- Zynq笔记(一) —PL端(FPGA部分)的设计流程
文章目录 前言 一.PL部分 1.创建工程 2.添加.V文件 3.编写程序后分析综合(就是普通的verilog程序) 4.编写仿真文件并进行仿真(和上述方法一样,只是在添加文件的时候选择仿真文件即可) ...
- Tkinter组件Label动态修改内容
最近在使用组件Lable时,遇见了text内容不能动态修改,最后发现是自己写错了. 动态修改现在发现有两种方法,一种是修改Lable的text属性的办法,一种是用varibale的双向绑定, 首页是t ...
- 怎么改vue项目的标题_Vue动态修改网页标题的方法及遇到问题
业务需求,进入页面的时候,网页有个默认标题,加载的网页内容不同时,标题需要变更. 例:功能授权,功能授权(张三). Vue下有很多的方式去修改网页标题,这里总结下解决此问题的几种方案: 一.最笨方案 ...
- 生成PL设备树及动态加载PL程序和设备树
实验说明 操作环境: Windows 7/10 64bit Xilinx Vivado 2017.4 Ubuntu 14.04 表 1 开发板型号 是否支持本实验 TLZ7x-EasyEVM 支持 T ...
- springBoot下使用quartz定时任务;动态修改任务执行时间
先上依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spri ...
- antd 动态添加表单_ZooTeam 拍了拍你,来看看如何设计动态化表单
? 这是第 58篇不掺水的原创,想要了解更多,请戳上方蓝色字体:政采云前端团队关注我们吧- 本文首发于政采云前端团队博客:ZooTeam 拍了拍你,来看看如何设计动态化表单 https://www.z ...
- layui追加或动态修改表单元素不生效
转自:https://blog.csdn.net/qq_29712303/article/details/80030757 在layui的post中请求后台,获取数据,数据获取后修改html页面中内容 ...
- 无表单不业务,动态表单让业务系统更高级
编者按:表单对于业务系统有什么意义?本文分析了业务系统和表单的关系,并比较了普通表单和动态表单和优劣,指出动态表单对业务系统的增益,最后介绍了动态表单的应用实践. 关键词:低代码平台:表单引擎:动态表 ...
最新文章
- AIX下删除LV后的现场保护和数据恢复方案
- 输出整数的位数、按位输出(两种)以及逆序输出
- 如何生成WebPart的部署文件(wsp文件)
- 通俗易懂讲解RPC、SpringCloud、Dubbo、Zookeeper、Hadoop、hive等概念的区别
- 小米净水器压力传感器_净水器中RO的完整形式是什么?
- 从一个简单的“欢迎“页面开始小程序之旅
- Oracle经典面试题,你都掌握了吗?
- 访问被拒绝:“Interop.jmail”
- (第三场) C Shuffle Cards 【STL_rope || splay】
- MySQL数据库分区的概念与2大好处(1)
- delete postman 传参_Postman高级应用——串行传参和动态传参详解
- 软件工程的完整生命周期
- 上班可明目张胆摸鱼玩的游戏(这谁能看出是在玩游戏)
- 一个字符等于多少磅?
- 【Python 打开Raw data】
- iOS 将状态栏设置成白色
- 计算机上无线网络开关在哪里,笔记本电脑的无线网开关在哪里打开
- oracle 推进scn号
- 理解特征向量/特征空间和样本空间
- 您的计算机无法启动后,在多次尝试后,你的电脑上的操作系统仍无法启动