微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 有人写过bmm文件,用过data2mem工具吗

有人写过bmm文件,用过data2mem工具吗

时间:10-02 整理:3721RD 点击:
bmm文件用于描述memory结构,data2mem读取bmm信息,可以直接修改bitstream,更新memory初始化内容。现在一个1kx48bit的rom有1kx36+1k16bit的rom组成,但是不知道怎么写这个设计的BMM文件。
我想这么来写的,但是貌似不对啊,data2mem的文档看了几遍了,还是搞不定啊。
ADDRESS_SPACE inst RAMB16 [0x00000000:0x000017FF]
   BUS_BLOCK
     top/rom1024/U0/xst_blk_mem_generator/gnativebmg.native_blk_mem_gen/valid.cstr/ramloop[1].ram.r/v6_init.ram/SP.SIMPLE_PRIM36.ram [47:16] PLACED=X2Y33;
     top/rom1024/U0/xst_blk_mem_generator/gnativebmg.native_blk_mem_gen/valid.cstr/ramloop[0].ram.r/v6_init.ram/SP.SIMPLE_PRIM18.ram [15:0] PLACED=X2Y64;
   END_BUS_BLOCK;
END_ADDRESS_SPACE;

在EDK中实用才行。

在EDK中实用才行。

呃,我的就是一个单独的硬件设计,唉,那就没办法了。
看了那么多文档,感觉也是可以的解决的,有两种方法解决这个问题,不过到最后还总是差一点的感觉,纠结了很长时间了。

你有在设计中直接实例化primitive BRAM吗? 比如RAMB18E1
我在data2mem文档里看到,如果自己用primitive BRAM构建RAM块,工具会自动生成BMM文件,这样我只要提供初始化数据,就可以用data2mem更新bit stream了。
我看到文档里面有个例子,可以在代码里初始化这个BRAM块,但是不能自动生成bmm文件,如果用INIT_FILE应该就可以了。
不过不知道INIT_FILE里面要求的文件格式,试着用mif,coe以及mem文件,都不好使。

RAMB18E1 #(
// Colision check: Values ("ALL", "WARNING_ONLY", "GENERATE_X_ONLY" or "NONE")
.SIM_COLLISION_CHECK("ALL"),
// DOA_REG, DOB_REG: Optional output register (0 or 1)
.DOA_REG(0),
.DOB_REG(0),
// INITP_00 to INITP_07: Initial contents of parity memory array
//.INITP_00(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INITP_01(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INITP_02(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INITP_03(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INITP_04(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INITP_05(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INITP_06(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INITP_07(256'h0000000000000000000000000000000000000000000000000000000000000000),
//INIT_00 to INIT_3F: Initial contents of data memory array
//.INIT_00(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_01(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_02(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_03(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_04(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_05(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_06(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_07(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_08(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_09(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_0A(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_0B(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_0C(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_0D(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_0E(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_0F(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_10(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_11(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_12(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_13(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_14(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_15(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_16(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_17(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_18(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_19(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_1A(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_1B(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_1C(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_1D(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_1E(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_1F(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_20(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_21(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_22(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_23(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_24(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_25(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_26(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_27(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_28(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_29(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_2A(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_2B(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_2C(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_2D(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_2E(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_2F(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_30(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_31(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_32(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_33(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_34(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_35(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_36(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_37(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_38(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_39(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_3A(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_3B(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_3C(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_3D(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_3E(256'h0000000000000000000000000000000000000000000000000000000000000000),
//.INIT_3F(256'h0000000000000000000000000000000000000000000000000000000000000000),
// INIT_A, INIT_B: Initial values on output ports
.INIT_A(18'h00000),
.INIT_B(18'h00000),
.INIT_FILE("file.mem"), // RAM init file
//.INIT_FILE("NONE"),
.RAM_MODE("TDP"), // "SDP" or "TDP"
.RDADDR_COLLISION_HWCONFIG("DELAYED_WRITE"), // "PERFORMANCE" or
// "DELAYED_WRITE"
// READ_WIDTH_A/B, WRITE_WIDTH_A/B: Read/write width per port
.READ_WIDTH_A(18), // 0,1,2,4,9,18,36
.READ_WIDTH_B(18), // 0,1,2,4,9,18
.WRITE_WIDTH_A(18), // 0,1,2,4,9,18
.WRITE_WIDTH_B(18), // 0,1,2,4,9,18,36
// RSTREG_PRIORITY_A, RSTREG_PRIORITY_B: Reset or enable priority ("RSTREG" or "REGCE")
.RSTREG_PRIORITY_A("RSTREG"),
.RSTREG_PRIORITY_B("RSTREG"),
// SRVAL_A, SRVAL_B: Set/reset value for output
.SRVAL_A(18'h00000),
.SRVAL_B(18'h00000),
// WriteMode: Value on output upon a write ("WRITE_FIRST", "READ_FIRST", or "NO_CHANGE")
.WRITE_MODE_A("WRITE_FIRST"),
.WRITE_MODE_B("WRITE_FIRST")
)
RAMB18E1_inst (
// Port A Data: 16-bit (each) output: Port A data
.DOADO(data_outA), // 16-bit output: A port data/LSB data output
.DOPADOP(DOPADOP), // 2-bit output: A port parity/LSB parity output
// Port B Data: 16-bit (each) output: Port B data
.DOBDO(data_outB), // 16-bit output: B port data/MSB data output
.DOPBDOP(DOPBDOP), // 2-bit output: B port parity/MSB parity output
// Port A Address/Control Signals: 14-bit (each) input: Port A address and control signals (read port
// when RAM_MODE="SDP")
.ADDRARDADDR(addrA), // 14-bit input: A port address/Read address input
.CLKARDCLK(clk), // 1-bit input: A port clock/Read clock input
.ENARDEN(ENARDEN), // 1-bit input: A port enable/Read enable input
.REGCEAREGCE(REGCEAREGCE), // 1-bit input: A port register enable/Register enable input
.RSTRAMARSTRAM(RSTRAMARSTRAM), // 1-bit input: A port set/reset input
.RSTREGARSTREG(RSTREGARSTREG), // 1-bit input: A port register set/reset input
.WEA(WEA), // 2-bit input: A port write enable input
// Port A Data: 16-bit (each) input: Port A data
.DIADI(data_inA), // 16-bit input: A port data/LSB data input
.DIPADIP(DIPADIP), // 2-bit input: A port parity/LSB parity input

// Port B Address/Control Signals: 14-bit (each) input: Port B address and control signals (write port
// when RAM_MODE="SDP")
.ADDRBWRADDR(addrB), // 14-bit input: B port address/Write address input
.CLKBWRCLK(clk), // 1-bit input: B port clock/Write clock input
.ENBWREN(ENBWREN), // 1-bit input: B port enable/Write enable input
.REGCEB(REGCEB), // 1-bit input: B port register enable input
.RSTRAMB(RSTRAMB), // 1-bit input: B port set/reset input
.RSTREGB(RSTREGB), // 1-bit input: B port register set/reset input
.WEBWE(WEBWE), // 4-bit input: B port write enable/Write enable input

// Port B Data: 16-bit (each) input: Port B data
.DIBDI(data_inB), // 16-bit input: B port data/MSB data input
.DIPBDIP(DIPBDIP) // 2-bit input: B port parity/MSB parity input
);


回复 2# solarwafer

我以前试过,应为不清楚coe文件与生成的memory 的Init_file 的对应关系,很难自己弄,你可以突破一下。

我看文档上写的是用mem格式,你试过coe格式。
唉,知道的都试了个遍,总也不对,蛋都碎了。

没错。有人写过(我写过)bmm独立使用data2mem,花了不少功夫,成功了。
提醒:
1) data2mem有dump .bit功能,通过这个功能可以把数据dump出来以判断自己弄的字节顺序。
2) 我是软件编译生成bin, 自己写个工具转换.bin成.mem, .coe, .mif 3种文件。.mem给data2mem用。.coe给coregen用,.mif Xilinx block ram仿真模型用。
3) .bmm反标功能必须要用,ISE反标之后,生成的是xx_bd.bmm。
4) Using Data2Mem in a Non-EDK design (data2mem_standalone.pdf)这篇pdf必须要看透。
5) FPGA editor必须用的到,把instance明确的找到,然后写到.bmm
5) 如果不知道字节数据对应顺序,调试方法 a) 生成block ram:coregen + .coe生成.ngc网表 b) 用.ngc生成.bit 同时反标生成xx_bd.bmm c) data2mem dump出来,看看字节序是否对。
其实比较复杂,一时半回说不清楚,祝你好运。

多谢你的建议,试了一个简单的例子,确实可以,只是我有大量的ROM,需要批处理才行,通过FPGA editor读取instance name这一步没法批处理。

ROM多的话,实现之前用在UCF文件中直接做好约束就可以。



    估计我们说的不是一个问题.
FPGA editor只是把instance找出来,建立.bmm,此时LOC信息并不需要.把这个.bmm在ISE里面设置一下,ISE会自动生成带LOC信息的_bd.bmm
这个.bmm只要建立一次,永久使用.因为只要你相关的设计不改,instance是不会变的.
一个.bmm可以包含所有的memory block

我明白你说的问题,有一点不清楚的是,设计里面有多个不相关的RAM块,都可以写在一个BMM文件里,但是分散的数据文件怎么才能和这个BMM文件对应?

什么情况。可以通过ISE生成一个rom,里面包含一个.v文件一个数据文件,使用coe是可以的 你对照文档上面有不同的文件格式你自己选择一个 我前两天刚刚弄过一次。



    分散的memory block
你给每memory block赋予不同的起始地址空间,就好了.
这些地址空间,仅对.mem生效,跟实际的物理地址,是没有绝对关系的.
比如
ROM1 定到 00010000-0001FFFF
ROM2定到 00020000-0002FFFF
ROM3定到 00030000-0003FFFF
等等.
只要你的.mem中的@地址, 跟你的.bmm能够对应上,就可以了.

恩,明白了。这样的话,看来我不用分析xdl写脚本来提取bmm文件了,可以按照你之前的方式,手动写bmm文件,工具自动配上loc信息,就基本上搞定了。多谢啦。

由于考虑到设计将来规模可能会改变,每次都要去FPGA editor读BRAM的instance也比较麻烦,后来就写了一个脚本,从xdl文件里读取我需要初始化的BRAM的instance名字以及LOC,然后生成BMM文件,我已经检查过了,前后都没问题了。但是看到你之前写的建议,要生成mif文件用于仿真,我生成了mif文件,但是怎么能把同一个RAM block的多个instance 初始化成不同的内容,实现仿真呢?

刚好遇到这种问题。

小白学习中

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top