最近被這么一個工作折騰了好幾天:一個非IPI的Vivado工程(需要全部Verilog手寫),在Artix-7 FPGA中實(shí)現(xiàn)了一個ARM Cortex-M0 DesignStart軟核(老版,沒有debug模塊),存放ARM程序的存儲器是實(shí)現(xiàn)在FPGA片上RAM上的;ARM程序用Keil MDK編寫,我希望在測試這個程序時(shí),不用每次都重新綜合一遍FPGA。
總體來說這個需求是:
Vivado;
全部HDL,非IPI;
無處理器(在Vivado看來M0 DesignStart不是處理器);
存儲器放在BRAM上;
替換Bitstream中的BRAM初始化,而不用重新綜合整個邏輯。
這件事看上去肯定是能做到的嘛。然而Vivado要用新的updatemem命令來替換以前ISE中的data2mem,我發(fā)現(xiàn)在無處理器的工程上,相關(guān)資料比較少……
這里總結(jié)一下整個實(shí)現(xiàn)過程。使用環(huán)境是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
這樣下次運(yùn)行Vivado是自動開啟8線程,綜合實(shí)現(xiàn)比較快……
將寄存器定義在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
上面代碼展示了如何將寄存器數(shù)組reg ram強(qiáng)制定義在Block RAM上,并展示了兩種訪問方式:
單口訪問:地址a、輸入數(shù)據(jù)din、輸出數(shù)據(jù)spo;
輸入、輸出分別訪問:輸入地址a、輸入數(shù)據(jù)din、輸出地址dpra、輸出數(shù)據(jù)dpo。
實(shí)際使用中可根據(jù)需要選擇保留其中一組引腳。
綜合后可檢查Project Summary和warning看是否成功綜合成BRAM。建議這段module直接使用,不做邏輯上的修改。
查看BRAM模塊的實(shí)現(xiàn)情況
參考資料:?
[Xilinx AR# 59259] 2013.4 - Vivado IPI - write_bmm Support with non-processor Based Designs?
這個帖子是針對bmm的,但其中提到了如何查看實(shí)現(xiàn)出的BRAM模塊的位置,以及怎樣知道每個模塊分配的行、列地址范圍。
把工程Implement一下,然后打開Implemented Design。
在打開的Implemented Design里面Ctrl+F搜索所有的BMEM:
搜索結(jié)果長這樣:
每一行就是綜合出的一個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約束文件,包含類似下面的內(nèi)容:
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
除了第一行定義屬性之外,后面每一行都對應(yīng)上面搜索到的一個BRAM模塊(當(dāng)然不需要初始化的BRAM就不用寫了)。
這里有兩個字段需要根據(jù)實(shí)際工程來改寫:一個是類似[ 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文件之后把工程再次綜合實(shí)現(xiàn)一遍。
添加mmi文件
評論