1

This is my synthesizable memory model in 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

For example:

memory[32'h10] contains 0xAAAAAAAA

I just want to write one byte of data 0xFF in memory address 0x10 so that

memory[32'h10] contains 0xFFAAAAAA

Can you recommend a good way to change my code so that I can access only one bit, half-byte, byte, halfword, or word in my memory module?

2 Answers 2

2

What 'a good way' is depends on your synthesis target. If it's an FPGA you should consider that bit-wise write access for large memories is generally not a good idea. This will possibly prevent the memory from mapping to RAM resources, dramatically increasing routing costs.

Byte enables are generally directly supported. You can view the Xilinx coding guidelines here where it describes byte enables on page 159.

Sign up to request clarification or add additional context in comments.

Comments

2
  1. You only declared 256 words of 32-bits, but your address bus is 32-bits wide, allowing up to 2^32 words of 32-bits. You might want to reduce your address bus width to 8-bits to match the number of words you declared.

  2. For Xilinx FPGAs I use the CORE Generator tool to instantiate one or more BlockRAMs of the right width and depth. BlockRAMs have an option to support individual byte enables.

  3. This code might work, but I haven't tried it

    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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.