提要:
如果想通过axi总线控制bram,调用axi_bram_ctrl模块,那么后端的bram必须要配置成Bram Ctrl MODE;
如果是全部自己写代码控制bram,建议用stand alone MODE,地址线的分配跟思维一致;
最理想的方式是双口ram一侧是axi的bram-ctrl模式,另一侧是stand-alone模式给user控制,但是mode只能选一种;
True Dual Port RAM TYPE,Width-32,Depth-2048,MemSize-8192;
一、配置
blk_mem_gen_0: Bram Controller MODE;默认使用32bit-addr;默认勾选Byte Write Enable,32bit-width的每个byte都能单独控制,we[3:0];
blk_mem_gen_1: Stand Alone MODE,2K-depth对应 11bit-addr,addr[10:0];没有勾选 Byte Write Enable 则是一个we[0:0]控制整条位宽;
blk_mem_gen_2: Stand Alone MODE,勾选了 Byte Write Enable,则每个byte单独受控,we[3:0];
二、综合
告警bram接口类型不匹配,配成stand alone的话Type都是other。
如果前端使用axi_bram_ctrl模块来控制,那后面的blk_mem_gen要配置成bram controller模式,不然很明显会不匹配。
三、实现
ctrl与mem之间的地址线不一致,系统默认连接低位线。
点开synthesis或者implement中的schematic原理图,查看实际连接情况
blk_mem_gen_0侧的addr连接(bram ctrl mode)
2K的depth需要11bit-addr,而8K的size需要13bit-addr。(addr[1:0]应该是预留给寻址单个byte用的,读byte地址+1),读位宽4byte的话地址+4;
所以从mem外壳接口来看,addr[1:0]是悬空不用的,实际addr从[2]开始;user在操作的时候,地址是按照+4来增加的。
但是实际ctrl与mem连接中,除了addr[12:2]对接外,其他都是n/c的,[31:13] [1:0]。所以想控制单独byte只能控制we[3:0]。
在ctrl侧,同样[1:0]也是n/c;[11:2]与ctrl内部的Q[9:0]连接,内部的bram_addr_a[0]控制最高位[12];(是否也能为RAMB36E1块的片选功能预留?)
blk_mem_gen_1/2侧的addr连接(stand alone mode)
首先在mem侧外部的[10:0]直接跟内部的RAMB36E1块[10:0]直连;
在ctrl侧外部,跟其低[10:0]相连;
进入ctrl内部,却只有[10:2]跟控制触发器Q[8:0]对接,低位[1:0]置0,仍然是bram_ctrl模式,低位用来控制byte,导致只能间隔读写1/4的RAM空间;
结论是:bram ctrl模式下,连接地址是从[2]开始的,[1:0]没有连接;但是在stand alone模式下,地址都是从[0]开始连接的,而在ctrl侧低[1:0]又是跳开的,那么只能操作RAM的[0] [4][8][...];
在bram ctrl mod下,ctrl与mem之间的we[3:0]是一一对应的;
到内部的RAMB36E1,是两个we[]控制16bit宽度,所以是每个we[]控制一个byte;
在stand alone mode下,ctrl的we[3:0]只有[0]跟mem的we相连
在2个RAMB36E1内部,是共用这一个we信号
结论是:we信号单独控制还是统一控制都可以。
两个16位宽的ram组成一个32位宽的bram。RAMB36E1是36kb的ram块,兼容8bit和9bit字节,即4KB的size。
告警mem0少一个connection,点开design_1.v文件,发现少了doutb接口,这里没有用到,忽略。
//