VIVADO中通过updatemem更新BlockRAM内容
在FPGA当中,SRAM一般是通过Block RAM实现的,如果在一些含有自定义的CPU CORE的FPGA中,我们希望更新CPU的程序而不经过重新编译,这个时候就需要通过updatemem修改生成的bit中的RAM中的内容,从而实现新固件的烧写,在ISE中这个操作是通过write_mem实现的,而升级到vivado之后,相应的工具变成updatemem,虽然工具有变化,但是实际的内容并没有太多变化,之前用的Memory位置描述是一个bmm文件,现在变成了mmi文件,相应的格式也有一定的变化,下面我们来看一下具体的实现过程。
首先我们知道FPGA中的SRAM一般是BlockRAM实现的,FPGA中block ram也有很多种类,在生成block的时候,FPGA一般会根据面积或者功耗动态的规划RAM的实现方式,因为一般SRAM会比较大,所以常常需要多块block ram拼接起来,这里就涉及到一个拼接方式,为了简化各种不同的拼接组合,我们选择采用固定的block ram类型比如(512x36)的block实现拼接,因为我们的设计中RAM和ROM的数据宽度一般是32位的,所以就不会涉及数据位上面的拼接操作,只是在地址空间上会罗列更多的block ram.
在更新bit文件的内容的时候我们需要知道RAM的位置信息,这个可以通过打开PR之后的dcp文件,在工程中查找blockram就可以列出所有用到的RAM信息,里面也包含了地址信息,通过这些地址信息我们就可以去生成我们需要的mmi文件,一个mmi文件的例子如下:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<MemInfo Minor="0" Version="1">
<Processor Endianness="little" InstPath="dummy">
<AddressSpace Begin="0" End="16383" Name="bram">
<BusBlock>
<BitLane MemType="RAMB32" Placement="X8Y62">
<DataWidth LSB="0" MSB="31"/>
<AddressRange Begin="0" End="4095"/>
<Parity NumBits="0" ON="false"/>
</BitLane>
</BusBlock>
<BusBlock>
<BitLane MemType="RAMB32" Placement="X8Y61">
<DataWidth LSB="0" MSB="31"/>
<AddressRange Begin="0" End="4095"/>
<Parity NumBits="0" ON="false"/>
</BitLane>
</BusBlock>
<BusBlock>
<BitLane MemType="RAMB32" Placement="X8Y64">
<DataWidth LSB="0" MSB="31"/>
<AddressRange Begin="0" End="4095"/>
<Parity NumBits="0" ON="false"/>
</BitLane>
</BusBlock>
<BusBlock>
<BitLane MemType="RAMB32" Placement="X8Y63">
<DataWidth LSB="0" MSB="31"/>
<AddressRange Begin="0" End="4095"/>
<Parity NumBits="0" ON="false"/>
</BitLane>
</BusBlock>
</AddressSpace>
</Processor>
<Config>
<Option Name="Part" Val="xcvu440-flga2892-1-c"/>
</Config>
</MemInfo>
有了mmi文件之后我们就可以通过如下的命令更新需要的bit文件了:
updatemem -meminfo rom.mmi -data ss.elf -bit rom_top.bit -proc dummy -out new.bit -force
为了方便起见,我写了一个从dcp中提取位置信息的脚本:
proc write_mmi {cell_name max_addr} {
set proj [current_project]
set filename "${cell_name}.mmi"
set fileout [open $filename "w"]
set brams [get_cells -hier -filter [list REF_NAME =~ RAMB* && NAME =~ "*${cell_name}*"]]
puts $fileout "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
puts $fileout "<MemInfo Version=\"1\" Minor=\"0\">"
puts $fileout " <Processor Endianness=\"Little\" InstPath=\"dummy\">"
puts $fileout " <AddressSpace Name=\"bram\" Begin=\"0\" End=\"${max_addr}\">"
puts $fileout " <BusBlock>"
foreach cell $brams {
puts $cell
puts $fileout " <BitLane MemType=\"RAMB32\" Placement=\"[get_property LOC $cell]\">"
puts $fileout " <DataWidth LSB=\"0\" MSB=\"31\"/>"
puts $fileout " <AddressRange Begin=\"0\" End=\"4095\"/>"
puts $fileout " <Parity NumBits=\"0\" ON=\"false\"/>"
puts $fileout " </BitLane>"
puts $fileout ""
}
puts $fileout " </BusBlock>"
puts $fileout " </AddressSpace>"
puts $fileout "</Processor>"
puts $fileout "<Config>"
puts $fileout " <Option Name=\"Part\" Val=\"[get_property PART [current_project ]]\"/>"
puts $fileout "</Config>"
puts $fileout "</MemInfo>"
puts "MMI file ($filename) created successfully."
close $fileout
}
两个参数,cell_name是RAM所在路径包含的一个字符串,后面一个是总的地址空间范围,以上。
最后更新于 2019-05-05 05:48:18 并被添加「」标签,已有 10870 位童鞋阅读过。
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。
Hi 博主,你好,感性分享;
有一个问题请教一下,我这边采用vivado 2018.3的版本,发现在tcl窗口输入update,并没有先是updatemem 或者update_mem的命令,请问这个和vivado软件版本有关系吗?