<位半字节字节...>使用verilog在32位内存中进行内存访问

时间:2012-01-31 06:21:20

标签: verilog

这是我在Verilog中的可合成内存模型。

    module memory(
        output reg [31:0] data_out,
        input [31:0] address,
        input [31:0] data_in, 
        input write_enable,
        input clk
    );
        reg [31:0] memory [0:255];

        always @(posedge clk) begin
            if (write_enable) begin
                memory[address] <= data_in;
            end
            data_out <= memory[address];
        end

    endmodule

例如:

memory[32'h10]包含0xAAAAAAAA

我只想在内存0xFF中写入一个字节address 0x10,以便

memory[32'h10]包含0xFFAAAAAA

您能否推荐一种改变我的代码的好方法,以便我只能访问内存模块中的一位,半字节,字节,半字或字?

2 个答案:

答案 0 :(得分:2)

  1. 您只声明了256个32位字,但您的地址总线是32位宽,允许最多2 ^ 32个32位字。您可能希望将地址总线宽度减少到8位,以匹配您声明的字数。

  2. 对于Xilinx FPGA,我使用CORE Generator工具实例化一个或多个宽度和深度正确的BlockRAM。 BlockRAM可以选择支持单个字节使能。

  3. 此代码可能有效,但我还没有尝试过

    module memory (
        output reg [31:0] data_out,
        input [7:0] address,
        input [31:0] data_in, 
        input [3:0] write_enable,
        input clk
    );
    
    reg [31:0] memory [0:255];
    
    reg [31:0] memory_in = 0; // wire reg
    
    always @* begin : combinational_logic
        memory_in = memory[address];
        if (write_enable[3])
            memory_in[31:24] = data_in[31:24];
        if (write_enable[2])
            memory_in[23:16] = data_in[23:16];
        if (write_enable[1])
            memory_in[15:8] = data_in[15:8];
        if (write_enable[0])
            memory_in[7:0] = data_in[7:0];
    end
    
    always @(posedge clk) begin : sequential_logic
        if (|write_enable) begin
            memory[address] <= memory_in;
        end
        data_out <= memory[address];
    end
    

    endmodule

答案 1 :(得分:1)

“好方法”取决于您的综合目标。如果它是FPGA,您应该考虑对大型存储器进行逐位写访问通常不是一个好主意。这可能会阻止内存映射到RAM资源,从而大大增加了路由成本。

通常直接支持字节启用。您可以在第159页上查看Xilinx编码指南here,其中描述了字节使能。