You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BRAM读写实现及代码问题咨询:独立读写信号可行性

BRAM代码检查与读写机制疑问解答

一、Verilog代码概念错误检查

1. 顶层模块(bram_dual)问题

  • 端口方向错误:rd_en被定义为output,但它是控制读操作的使能信号,应作为input使用。当前模块未驱动rd_en,测试平台也未对其赋值,导致信号悬空,读输出read_data状态不确定。
  • 复位范围遗漏:RAM数组为ram[0:23](共24个单元),但复位循环条件是i<23,仅初始化了ram[0]到ram[22],ram[23]未被复位会残留未知值,应改为i<=23或i<24。
  • 复位赋值位宽不匹配:复位时赋值{24{1'b0}},但RAM位宽是[17:0](18位),位宽不匹配会引发语法或综合错误,需改为{18{1'b0}}。
  • 读操作设计不合理:用组合逻辑assign read_data=rd_en ? ram[addr_w]:0读取数据,一是复用写地址无法实现独立读地址;二是组合逻辑读取易产生毛刺,读写同地址时会出现竞争冒险。双端口BRAM的读操作建议同步到时钟沿,使用独立读地址。

2. 测试平台(tb_bram)问题

  • rd_en信号悬空:作为DUT的输入(修正后),测试平台未对其赋值,导致读输出无有效控制。
  • 写操作逻辑错误:时序块内的for循环会在单个时钟周期内完成所有迭代,最终wrt_data和addr_w只会被赋值为22,无法实现逐周期写入每个地址,需用计数器实现逐周期递增地址和数据。
  • 写使能未触发:复位释放后wr_en始终为0,没有触发写操作的逻辑,需在复位后将wr_en置1,或设计控制逻辑启动写流程。

二、BRAM独立读写使能与地址的实现问题

完全可以为BRAM设置独立的读写使能(wr_en、rd_en)和地址(addr_w、addr_r),这正是双端口BRAM的标准设计方式,实际编码可直接实现。以下是修正后的双端口BRAM示例代码:

module bram_dual_port (
    input         clk,
    input         rst,
    // 写端口
    input         wr_en,
    input  [4:0]  addr_w,
    input  [17:0] wrt_data,
    // 读端口
    input         rd_en,
    input  [4:0]  addr_r,
    output reg [17:0] read_data
);

reg [17:0] ram[0:23];
integer i;

// 写操作:同步时钟,复位初始化
always @(posedge clk) begin
    if (rst) begin
        for (i = 0; i <= 23; i = i + 1) begin
            ram[i] <= {18{1'b0}};
        end
    end else begin
        if (wr_en) begin
            ram[addr_w] <= wrt_data;
        end
    end
end

// 读操作:同步时钟,独立读地址与读使能
always @(posedge clk) begin
    if (rst) begin
        read_data <= {18{1'b0}};
    end else begin
        if (rd_en) begin
            read_data <= ram[addr_r];
        end
    end
end

endmodule

关键说明:

  • 写端口和读端口完全独立,各自有专属的使能信号和地址信号。
  • 读写操作均同步到时钟上升沿,避免组合逻辑带来的不稳定问题。
  • 复位时同时初始化RAM数组和读输出,保证初始状态可控。

内容的提问来源于stack exchange,提问作者superb ranjeet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 10:16:26