21

哪种代码更适合编写 RAM?

  1. 分配data_out内部always块:

    module memory(
        output reg [7:0] data_out,
        input [7:0] address,
        input [7:0] data_in, 
        input write_enable,
        input clk
    );
        reg [7:0] memory [0:255];
    
        always @(posedge clk) begin
            if (write_enable) begin
                memory[address] <= data_in;
            end
            data_out <= memory[address];
        end
    
    endmodule
    
  2. data_out使用assign语句赋值:

    module memory(
        output [7:0] data_out,
        input [7:0] address,
        input [7:0] data_in, 
        input write_enable,
        input clk
    );
        reg [7:0] memory [0:255];
    
        always @(posedge clk) begin
            if (write_enable) begin
                memory[address] <= data_in;
            end
        end
    
        assign data_out = memory[address];
    
    endmodule
    

有什么建议吗?

4

4 回答 4

12

这取决于您的要求。

  1. 这会注册您的内存输出。如果你把它合成到门,你将比情况 2 多 16 个触发器。这意味着你使用了更多的区域。这也意味着与情况 2 相比,您的输出相对于时钟的传播延迟更小。此外,输出数据在下一个时钟周期之前将不可用。

  2. 您的输出数据将在写入时的同一时钟周期内可用,尽管相对于时钟具有更长的传播延迟。

您需要根据自己的要求决定使用哪个。

第三种选择是使用生成的 RAM,这是一个硬宏。与情况 1 和 2 相比,这应该具有面积、功率和可能的时序优势。

于 2011-10-03T13:05:33.087 回答
8

添加到工具的答案 - 如果您使用异步读取方法(案例 2),它不会映射到 FPGA 中的 RAM 块,因为我知道的所有主要架构中的 RAM 块都有同步读取。

于 2011-10-05T12:27:14.200 回答
1

两种形式都有效,具体取决于您想要的流水线类型。我始终建议遵循 Xilinx RAM 编码指南——这是确保代码综合成正确 FGPA 结构的好方法。

例如,您的示例 1 将合成到 Xilinx BRAM(即专用 Block Ram),因为它是同步读取,而您的示例 2 将合成到 Xilinx 分布式 RAM(因为它是异步读取)。

请参阅赛灵思文档 UG901(Vivado 设计套件用户指南)中 RAM HDL 编码技术部分的编码指南。它还很好地描述了 RAM 的同步读取和异步读取之间的区别。

于 2016-12-21T22:14:57.537 回答
-2

在第二个程序中,会出现编译错误,因为我们无法将值“分配”给“Reg”。它会给出一个错误说:'寄存器在连续赋值的左侧是非法的'

于 2014-09-29T21:51:40.380 回答