Vivado中用HDL定义BRAM存储器并用updatemem合成bit文件

最近被这么一个工作折腾了好几天:一个非ipi的vivado工程(需要全部verilog手写),在artix-7 fpga中实现了一个arm cortex-m0 designstart软核(老版,没有debug模块),存放arm程序的存储器是实现在fpga片上ram上的;arm程序用keil mdk编写,我希望在测试这个程序时,不用每次都重新综合一遍fpga。
总体来说这个需求是:
vivado;
全部hdl,非ipi;
无处理器(在vivado看来m0 designstart不是处理器);
存储器放在bram上;
替换bitstream中的bram初始化,而不用重新综合整个逻辑。
这件事看上去肯定是能做到的嘛。然而vivado要用新的updatemem命令来替换以前ise中的data2mem,我发现在无处理器的工程上,相关资料比较少……
这里总结一下整个实现过程。使用环境是vivado 2015.2。
先把vivado多线程开了……
参考资料:
[xilinx ar# 53090] vivado - is it possible to run tcl commands during initialization of the vivado or planahead tools?
在vivado安装文件夹vivadoversionscripts中新建一个init.tcl,里面写
set_param general.maxthreads 8
这样下次运行vivado是自动开启8线程,综合实现比较快……
将寄存器定义在bram上
参考资料:?
[xilinx ar# 54778] design assistant for vivado synthesis - help with synthesis hdl attribute support - keep, keep_hierarchy, ram_style, rom_style
这个页面的附件中给出了ram_style属性的例子,以verilog为例:
module ram_inf_64x1d_2 (a, dpra, clk, din, we, spo, dpo);
parameter addresswidth = 6;
parameter bitwidth = 1;
parameter depth = 34;
input clk, din, we;
input [addresswidth-1:0] a, dpra;
output spo, dpo;
(* ram_style = block *)
reg [bitwidth-1:0] ram [depth-1:0];
reg [addresswidth-1:0] read_dpra;
reg [addresswidth-1:0] read_a;
always @(posedge clk) begin
if (we) begin
ram [a] <= din;
end
read_a <= a;
read_dpra <= dpra;
end
assign spo = ram [read_a];
assign dpo = ram [read_dpra];
endmodule
上面代码展示了如何将寄存器数组reg ram强制定义在block ram上,并展示了两种访问方式:
单口访问:地址a、输入数据din、输出数据spo;
输入、输出分别访问:输入地址a、输入数据din、输出地址dpra、输出数据dpo。
实际使用中可根据需要选择保留其中一组引脚。
综合后可检查project summary和warning看是否成功综合成bram。建议这段module直接使用,不做逻辑上的修改。
查看bram模块的实现情况
参考资料:?
[xilinx ar# 59259] 2013.4 - vivado ipi - write_bmm support with non-processor based designs?
这个帖子是针对bmm的,但其中提到了如何查看实现出的bram模块的位置,以及怎样知道每个模块分配的行、列地址范围。
把工程implement一下,然后打开implemented design。
在打开的implemented design里面ctrl+f搜索所有的bmem:
搜索结果长这样:
每一行就是综合出的一个bram模块。选中其中一行,在它的属性里可以看到:
其中比较重要的是模块的名字(比如xxxxx/ram_reg_0)、位置(比如x1y7)、行和列的地址范围([0:16383]和[0:1])。
为bram cell添加bmm属性
参考资料:?
[xilinx论坛] a method to fix poor combination lbm of ipi microblaze design?
我们需要做的是在vivado工程里添加一个xdc约束文件,包含类似下面的内容:
create_property bmm_info_memory_device cell -type string
set_property bmm_info_memory_device {[ 0: 1][0:16383]} [get_cells u_block_ram/ram_reg_0]
set_property bmm_info_memory_device {[ 2: 3][0:16383]} [get_cells u_block_ram/ram_reg_1]
set_property bmm_info_memory_device {[ 4: 5][0:16383]} [get_cells u_block_ram/ram_reg_2]
set_property bmm_info_memory_device {[ 6: 7][0:16383]} [get_cells u_block_ram/ram_reg_3]
# 后面还有好几个,最后是ram_reg_15
除了第一行定义属性之外,后面每一行都对应上面搜索到的一个bram模块(当然不需要初始化的bram就不用写了)。
这里有两个字段需要根据实际工程来改写:一个是类似[ 0: 1][0:16383]这样的地址范围,另一个是u_block_ram/ram_reg_0这样的cell名字。其他都是不用动的。
我的工程里用到了64kbytes的ram,总共使用了16个ramb36模块,所以我的xdc文件中有16行,最后到{[30:31][0:16383]} [get_cells u_block_ram/ram_reg_15]。
添加xdc文件之后把工程再次综合实现一遍。
添加mmi文件
参考资料:
[xilinx ug898] vivado design suite user guide: embedded processor hardware design?
[xilinx ar# 63041] 2015.1 - vivado ip integrator - write_mem_info does not create mmi file?
上面一个文档里有一章专门讲mmi文件和updatemem命令。
下面帖子里描述了如何在有memory controller ip的block design中生成mmi文件,并附了一个tcl脚本。虽然我的系统中既没有memory controller、也没有block design,但资料还是有很大的参考意义。
实际上我把这个例子做了一遍,然后改写了它生成的mmi。
mmi文件大概是这个模样:
又是xml,现在不写几个xml都不好意思说自己用过vivado……
这段代码主要需要修改的是:
里面:name是自己随便起的;0和65535是分别是最小和最大地址,这里面地址的单位是字节,总共64kbytes,与总线是32位无关;另外这个地址应该是可以不从0起始的。
每一个里面:msb、lsb、begin、end这些和上面xdc约束文件中的每一项是对应的,placement根据implemented design中搜索的结果来定。
里面:根据自己的fpga型号修改,这个不用多说。
p.s. 在以前做bmm文件的时候,像placement这种值是可以综合器自动帮助填写的,暂时还没发现如何在自定义bram时在mmi文件上实现类似功能。
合成bitstream
参考资料:?
[xilinx ar# 63041] 2015.1 - vivado ip integrator - write_mem_info does not create mmi file?
首先生成要往bram里烧写的数据,mem或elf格式。我这里是keil mdk编译的可执行文件,直接把axf扩展名改成elf就能用。
把mmi、elf文件都放在vivado工程的.runsimpl_1文件夹下,在vivado中运行tcl命令:
cd {c:on_processor_mmiproject_1.runsimpl_1}
updatemem -force --meminfo mmi文件名.mmi --data elf文件名.elf --bit 原始的bit文件.bit --proc dummy --out download.bit
其中c:on_processor_mmiproject_1.runsimpl_1改成自己的工程文件夹。
updatemem后面跟着的是一行命令,比较长。
祈祷没有错误吧,然后可以看到impl_1文件夹中多了一个download.bit文件。
这一段可以看到vivado重新launch_runs了write_bitstream,生成了一个新的bit文件,但并没有再次综合实现。
最后用hardware manager把bitstream下载到fpga中。
如何更新数据
比如说我用keil mdk重新编译出了一个elf,那么只需要再次运行
updatemem -force --meminfo xxx.mmi --data yyy.elf --bit zzz.bit --proc dummy --out download.bit
就可以得到合成后的bitstream,不需要再次综合。
总结
编写hdl文件,将寄存器强制定义在bram上;
综合实现一遍;
在xdc约束文件中添加bmm属性;
编写mmi文件;
运行updatemem合成bitstream。
关于data2mem
这里记录一下在查找资料过程中查到的利用bmm合成bit的资料,待之后尝试。
[xilinx ug658] data2mem user guide?
xilinx的data2mem使用手册,支持到ise 14.7。
[xilinx answer 46945] data2mem usage and debugging guide?
xilinx整理的data2mem相关问答,相当于上面手册的补充说明,更实用一些的内容。
using data2mem in a non-edk design?
xilinx的另一篇文档,内容如其名。
loading bram data?
这个wiki中作者记录了用data2mem合成avr核的存储器数据的各种方法,使用的环境是ise 12.4。
spartan3 picoblaze how to make .bmm file work?
这个帖子下面walter dvorak的回复提到了ise可以自动生成bmm文件中的placed字段,使用的环境是ise9.1.3。
using xilinx data2mem to patch block rams?
这个帖子把生成bmm到使用data2mem的过程总结的比较完整,其中也提到了上面那个walter dvorak的回复。

FPGA在音乐科技及医疗照护领域的应用
我国陆续出台了很多政策 支持民用无人机的发展
三星电子与丹麦顶级音响公司合作,共同开发下一代显示器
《城市数字孪生标准化白皮书(2022版)》正式发布(附全文下载)
Mentor Graphics获得TSMC 10nm FinFET工艺技术认证
Vivado中用HDL定义BRAM存储器并用updatemem合成bit文件
WiSA Technologies宣布推出其无线多通道音频技术授权计划
从微控制器到执行器——电机驱动器应用的集成方案
基于深亚微米VLSI的物理验证可实现加快芯片研发速度
微软宣布开发的产品将不再支持IE浏览器
工地扬尘在线监测系统功能的基本介绍
Carmicro出0.4mm间距芯片级封装EMI滤波器
多重生物识别技术及未来发展前景
便于观看度数的智能水表的原理及设计
河南省首套人脸智能识别系统落户南阳理工
艾迈斯欧司朗举办2022“万物光感”光学技术研讨会, 全景式光学传感解决方案“秀肌肉”
Adam Tayloy玩转MicroZed系列59:Zynq与PicoBlaze第4章
过压或欠压动作电路
NVIDIA发布RTX 30系列游戏本
中国光伏装机量增长量与全球比较