在Verilog中编写RAM的更好方法

时间:2011-10-03 03:27:38

标签: verilog vlsi

在编写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
    
  3. 有什么建议吗?

5 个答案:

答案 0 :(得分:9)

这取决于您的要求。

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

  2. 您的输出数据将在与写入时相同的时钟周期内提供,尽管相对于时钟的传播延迟较长。

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

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

答案 1 :(得分:7)

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

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:0)

模块mem_try(      clk,//控制信号使ram同步      addr,//必须从中获取数据的地址      data_in,//输入数据      rd      wr,//控制信号高电平写入,低电平读取;      // rst,//输入控制信号      // rd_count,      // wr_count,      data_out //数据读出     );

  parameter addr_length=32,data_width=32,ram_depth= 1 << addr_length;
  input [data_width-1:0]data_in;
  input clk,rd,wr;
  input [addr_length-1:0]addr;
  output reg [data_width-1:0]data_out;
  reg[data_width-1:0]ram[ram_depth-1:0];//ram variable decalaration 
  assign write_only =wr&~rd ;
  assign read_only =~wr&rd ;

  always@(posedge clk) begin

  if(write_only) begin
     ram[addr]<=data_in;
  end


  if(read_only) begin    
    data_out<=ram[addr];
  end

  end         

endmodule

我为32x32 ram编写了此代码,并希望在设计中推断出块ram,但是vivado将其视为分布式ram

答案 4 :(得分:-1)

在第二个程序中,会出现编译错误,因为我们无法分配&#39;一个值为&#39; Reg&#39;。 它会出错:&#39; 注册在连续作业的左侧是非法的&#39;