vivado中bram的种类与使用

vivado中bram的分类

在vivado中打开IP catalog,在其中搜索“block memory”即可找到bram的相关IP。bram共有以下几类:
在这里插入图片描述
前三项分别是:单端口ram、简化版双端口ram和真正的双端口ram。

那么我们分别例化看一下它们的工作时序。

单端口ram

初始化

vivado给出了一种比较方便的给ram赋初值的方式:通过load一个.coe文件给ram赋初值,我在这里使用的.coe文件内容如下:
在这里插入图片描述
文件里一共存储了16个16位的16进制数,所以在设置IP的时候将位宽(每个位置多少位)和深度(一共有多少个位置)都设置成16。

工作时序

单端口ram的工作时序如下图所示:

在这里插入图片描述
对于某一个周期读到的地址,在下一个周期将该地址所存储的数据通过output口输出出来。由于单端口ram只有一个端口,这个端口既要负责读数,还要负责写数,因此用WEA信号(write enable A)来做区分,当WEA=0时,只读不写,在下一个周期将地址对应的数输出;当WEA=1时,执行的操作将是把DinA的内容写入地址对应的地方,但是本次输出依然是该地址原来的值(不过从此就被DinA的内容替换掉了)。

仿真验证

写一个testbench来验证一下,仿真波形如下:
在这里插入图片描述
其中addr就从0到F一直遍历,WEA一直为1,所以第一次遍历时虽然已经将16’h4399写到了每一个角落,但是读的时候依然是各个位置原来的值,第二次再遍历的时候读到的才是16’h4399。

简化的双端口RAM

初始化

同单端口RAM的初始化,这里连用的.coe文件都是一样的。

端口定义

该IP的端口定义如下图所示:
在这里插入图片描述
可见这种RAM有A和B两个端口,A口负责写,B口负责读,两个端口各自有各自的clk,addr和enable。A口多了一个wea作为写使能、一个dina作为写数据的输入,B口多了一个doutb作为读数据的输出。值得注意的是,和单端口RAM有一个明显的区别,改写某地址的数据时,RAM的输出不是该地址的原来的数据,而是写入的数据。这一点会在后面的仿真中得到验证。

仿真结果

仿真结果如下所示:
在这里插入图片描述
第一次遍历地址时,WEA信号为0,RAM只读不写,output输出的就是RAM里存储的内容。第二次遍历地址时,WEA信号为1,从此output输出的就不再是RAM原有的内容,而是即将写入的内容,这也是单端口RAM和简易双端口RAM的区别。

双端口RAM

初始化

同单端口RAM的初始化,这里连用的.coe文件都是一样的。

端口定义

该IP的端口定义如下图所示:
在这里插入图片描述
如上图所示是真正的双端口bram的IP端口定义。两个端口各自有clk信号、addr信号、端口使能、写使能、写数输入、读数输出。也就是说两个端口都能读数、都能写数。那么就依次仿真它的各种功能。

功能仿真

单端口读数

先仿真单端口读数,分别将enB和enA置为0,仅让一个端口发挥作用。
在这里插入图片描述
在这里插入图片描述
这和单端口RAM读数是一样的,没被使能的端口输出0,使能的端口读出RAM所存储的内容。

双端口读数

将addrb设置成addra的下一个数,可以利用双端口同时读两个数。
在这里插入图片描述

双端口一读一写

首先令读写操作的地址不同,接着上边的addrb比addra多1的设定,让B口读,A口写。这样第一次遍历将读到RAM存储的原值,第二次遍历将读到A写入的值,我令A口写入16位的16进制数16’h4399,下面用仿真来验证猜想。
在这里插入图片描述
观察B端口的输出,猜想得到证实。观察A端口的输出可以得到另一个结论,当某端口的写使能激活时,该端口的输出是写入的数据。下面仿真一下双端口读写操作同一地址会怎样。
在这里插入图片描述
在这里插入图片描述
由仿真波形可知,A口写B口读并且读写地址为同一地址时,B口无法读到RAM原有的值,而是输出即将写的内容(也就是A口的写输入,在本例中是16’h4399);但A口读B口写则不同,A口依然能读出RAM原有的值,而在第二次遍历时才输出B口写入的值,即16’h2200(当然B口的输出一直是16’h2200),因此猜想A口和B口并不是完全一致的端口,这个猜想有待参考文档来证实。

双端口写数据

在这里插入图片描述
如图所示,在写阶段双端口均写入数据,A口将所有偶地址写入16’h4399,B口将所有奇地址写入16’h2200。后面的读数据读出的结果是16’h4399和16’h2200交替,证实了这一点。双端口可以同时写,大大提高了数据传输效率。那么如果双端口同时写一个地址会发生什么呢?下面用仿真来验证。
在这里插入图片描述
如图,在写数阶段,A口和B口输出各自的写输入,即分别是16’h4399和16’h2200,但是不可能两个数写入同一个地址因为根本写不下。从读阶段的波形可以看出,写进去的是16’h2200,也就是B口的内容。从仿真得出的结论是:A口和B口对同一地址进行写操作时,写入的是B口的数据。但仿真未必是连板时真实发生的,所以连板实验时未必如此。

<think>嗯,用户想降低Vivado工程中的BRAM资源占用率,我得仔细想想怎么回答这个问题。首先,BRAMFPGA中的块RAM,通常用于存储大量数据。优化BRAM使用的方法可能有很多种,我需要回忆一下常见的优化策略。 首先,可能要考虑数据位宽优化。比如,如果用户的数据位宽不是标准的,可能会有浪费。例如,使用18位数据而BRAM是18Kb的,可能需要调整位宽来匹配。另外,使用更小的数据类型,比如用8位代替16位,可以减少资源占用。 然后是存储结构优化。BRAM的配置模式有很多种,比如真双端口、简单双端口等。如果设计不需要双端口,改用单端口模式可以节省资源。另外,合理选择深度和宽度,避免不必要的分割,比如将一个大RAM拆分成多个小RAM可能会更高效。 资源复用也是一个关键点。比如,如果某些数据可以分时复用同一个BRAM,通过时分复用的方式,减少实例化的次数。或者共享BRAM,多个模块共享同一块内存区域,但需要处理好访问冲突。 算法和架构优化方面,可能可以考虑压缩数据,比如用算法减少存储的数据量。或者流水线设计,减少中间数据的存储需求。另外,流式处理可以边处理边传输,避免缓存大量数据。 使用分布式RAM代替BRAM也是一个方法,因为LUTRAM更适合小容量存储,可以节省BRAM资源。但需要注意容量限制,超过一定大小可能还是需要BRAM。 代码优化方面,检查HDL代码是否有不必要的存储结构,比如避免无意识的寄存器推断。使用Vivado的资源管理工具分析BRAM使用情况,定位高占用模块。 最后,参考文档和工具建议,比如Vivado用户指南中的BRAM优化章节,以及使用CORE Generator配置IP核的参数。 需要验证这些方法是否有效,可能需要用户实际尝试并根据结果调整。同时,要提醒用户优化时需权衡性能,比如使用分布式RAM可能增加LUT的消耗,需要综合考虑资源分配。</think>在 Vivado 项目中优化 BRAM 资源使用量可通过以下 7 种方法实现: ### 1. 数据位宽优化 - **位宽对齐**:BRAM 最小单元为 18Kb,当数据位宽非 18/36 的整数倍时会产生资源浪费。例如存储 32 位数据时可组合使用两个 18Kb BRAM,优于单独使用 36Kb BRAM - **位宽压缩**:使用最小必要位宽,如将 `integer` 类型改为 `std_logic_vector(7 downto 0)` ```vhdl -- 原设计 signal data_store : std_logic_vector(31 downto 0); -- 优化后 signal data_store : std_logic_vector(15 downto 0); ``` ### 2. 存储结构优化 - **配置模式选择**:真双端口模式比简单双端口多消耗 30% 资源[^1]。优先选用简单双端口或单端口模式 - **深度分割**:将大容量存储分割为多个小容量 BRAM,利用 BRAM 级联特性 ```verilog // 原设计 reg [31:0] memory [0:4095]; // 优化为 4 个 1024 深度的 BRAM genvar i; generate for(i=0; i<4; i=i+1) begin blk_mem_gen_0 mem_inst ( .addra(addr[9:0]), .dina(data_in), .douta(data_out[i]) ); end endgenerate ``` ### 3. 资源复用技术 - **时分复用**:通过多路选择器实现 BRAM 分时复用 ```systemverilog always_comb begin case(time_slot) 0: bram_wr_en = moduleA_wr_en; 1: bram_wr_en = moduleB_wr_en; endcase end ``` ### 4. 算法级优化 - **数据压缩**:采用 delta 编码存储差值而非绝对值 - **流式处理**:设计改为流水线架构,减少中间数据存储需求 ### 5. 替代存储方案 - **分布式 RAM**:小于 2Kb 的存储改用 LUTRAM ```vhdl attribute ram_style : string; attribute ram_style of small_ram : signal is "distributed"; ``` ### 6. 代码风格优化 - 避免无意中生成 BRAM 的代码模式: ```verilog // 会推断出 BRAM 的写法 reg [31:0] mem [0:1023]; always @(posedge clk) begin if(we) mem[addr] <= din; dout <= mem[addr]; end // 改用寄存器实现小存储 (* ram_style = "registers" *) reg [7:0] small_mem [0:31]; ``` ### 7. 工具辅助优化 - 使用 Vivado 的 `report_utilization` 命令生成资源报告 - 通过 `set_property` 指令强制指定实现方式: ```tcl set_property RAM_STYLE Block [get_cells large_mem] ``` ### 验证方法 1. 建立基线:原始设计的 BRAM 使用量 2. 逐步应用上述优化方法 3. 对比综合后资源报告 4. 使用 ILA 核验证功能正确性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值