FPGA基础知识(十八):Xilinx Block Memory IP核(3)--Single Dual Port RAM 详解

《FPGA基础知识》系列导航  

         本专栏专为FPGA新手打造的Xilinx平台入门指南。旨在手把手带你走通从代码、仿真、约束到生成比特流并烧录的全过程。

       本篇是该系列的第十八篇内容

       上一篇:FPGA基础知识(十七):Xilinx Block Memory IP核(2)--单端口 RAM 的三种操作模式详解-优快云博客

       下一篇:关注我,第一时间获取更新!! 


1 核心概念:读写分离的存储架构

        想象一个双车道收费站:一条车道专门负责车辆进入(写入数据),另一条车道专门负责车辆离开(读取数据),两者互不干扰,同时运行。这正是Simple Dual Port RAM的核心设计哲学。

与单端口RAM的本质区别在于:单端口RAM只能在同一个时钟下进行读写操作,而Simple Dual Port RAM可以进行异步读写。但与True Dual Port RAM(两个端口都可读写)不同,它的端口角色是固定的:Port A专用于写,Port B专用于读。

2 IP核配置与使用

2.1 端口信号

        端口信号如下图所示:

        信号说明如下:

ENTITY blk_mem_gen_0 IS
  PORT (
    --- 端口A:写端口
    clka : IN STD_LOGIC;  --- Port A的时钟
    ena : IN STD_LOGIC;   --- Port A使能信号
    wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);   --- 写使能,高电平有效,与clka同步
    addra : IN STD_LOGIC_VECTOR(3 DOWNTO 0);  --- 写地址
    dina : IN STD_LOGIC_VECTOR(31 DOWNTO 0);  --- 写数据
    
    --- 端口B:读端口
    clkb : IN STD_LOGIC;  --- Port B的时钟
    enb : IN STD_LOGIC;  --- Port B的使能信号
    addrb : IN STD_LOGIC_VECTOR(3 DOWNTO 0);  --- 读地址
    doutb : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)  --- 读数据
  );
END blk_mem_gen_0;

        关键时序特性:读操作有一个固定的时钟周期延迟。当你在第N个时钟周期给出读地址后,数据将在第N+1个时钟周期出现在输出端口。如果启用了输出寄存器选项,延迟会变为两个周期,但这能显著改善时序性能。

2.2 属性配置

        在Simple Dual Port RAM下对应的配置选项有两页,一个是Port A一个是Port B,Port A的Mode可以选择No change / Write First / Read First  而 Port B只能设定Write First模式,即到达Port B的数据就是直接可以输出的。

        我们根据上述配置,看一下时序:

        Port A依据ena 和 wea 给对应的地址addra写入数据,Port B依据enb从对应的地址addrb读出数据,port A与Port B的时钟是异步的,其实这非常类似于异步FIFO,这个是配置为No change模式的情况。

3 三种工作模式的深度剖析

        当读写地址恰好相同时,Simple Dual Port RAM的行为由所选的工作模式决定。这三种模式是设计中最微妙也最重要的部分:

3.1 No Change模式

        当发生地址冲突时,读端口输出保持不变,不反映写入的新数据,也不保证是旧数据。

// No Change 模式
always_ff @(posedge clk) begin
    if (we) begin
        ram[addr] <= din;  // 仅执行写操作,输出dout保持不变
    end else begin
        dout <= ram[addr]; // 非写时,正常输出
    end
en

        适用场景:适用于设计上能保证避免地址冲突的系统,或对读取数据实时性要求不高的场景,这种模式通常功耗最低。

3.2 Write First模式

        与Read First相反,Write First模式下新写入的数据会立即出现在输出端口。这意味着写操作"覆盖"了该地址的当前可见状态。

适用场景:适用于需要数据"透明"传递或旁路写入的场景,如实时数据流处理。

当我们配置Write First,即写优先模式,
Port B的输出还是要依赖enb和addrb给的时机,
所以我们可以通过调整enb和addrb的时机达到边写边读的效果。

程序只做参考说明,不是实际实现方式哈

// Write First 模式 (类似边写边读)
always_ff @(posedge clk) begin
    if (we) begin
        ram[addr] <= din;  // 新数据写入RAM
        dout <= din;       // 同时,新数据直接送到输出端口
    end else begin
        dout <= ram[addr];
    end
end

assign enb = ena;
assign addrb = addra;

3.3  Read First模式

        在这种模式下,当对同一地址进行读写时,系统会先读出旧数据,然后再写入新数据。这保证了读操作总能获取到写入前该地址存储的内容。

当我们配置为Read First,即读优先,
那上一次我们讲过,读优先就是可以先读出老数据再写入新数据,防止老数据丢失,
那我们依旧可以通过调整enb和addrb的时机以读取老数据

// Read First 模式 (类似先读后写)
always_ff @(posedge clk) begin
    if (we) begin
        dout <= ram[addr]; // 时钟沿来时,先输出旧数据
        ram[addr] <= din;  // 同时将新数据写入RAM
    end else begin
        dout <= ram[addr]; // 非写时,正常输出
    end
end

适用场景:适用于需要严格数据一致性的系统,例如在写入前需要备份旧值或执行读-修改-写操作。

4 总结

  • 角色固定:Simple Dual Port RAM的A口写、B口读,结构清晰,非常适合单向数据流缓冲。

  • 延迟特性:读操作有至少一个时钟周期的延迟。如果启用了输出寄存器,则延迟为两个周期。

  • 模式是关键Write FirstRead FirstNo Change 三种模式解决了读写地址冲突时的行为问题,选择取决于具体应用逻辑。

  • 独立与共享:两个端口的时钟、使能、地址线完全独立,但访问的是同一块物理内存空间。

        希望今天的分享能帮助大家更好地理解和使用Simple Dual Port RAM。在实际项目中,结合设计需求选择合适的配置,可以极大地提高系统的效率和可靠性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FPGA_小田老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值