最近被这么一个工作折腾了好几天:一个非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多线程开了……
在Vivado安装文件夹\Vivado\version\scripts
中新建一个init.tcl
,里面写
set_param general.maxThreads 8
这样下次运行Vivado是自动开启8线程,综合实现比较快……
将寄存器定义在BRAM上
这个页面的附件中给出了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
。
实际使用中可根据需要选择保留其中一组引脚。
综合后可检查Projec