S SmartDocs
Series: RISC V Hardware verilog 76 lines · Updated 2026-07-04

dmem.v

RISC_V_Hardware/verilog/rtl/dmem.v

// ============================================================
// dmem.v -- data memory, 4 KiB, byte/half/word access
// Word-addressed internally; funct3 selects size & extension.
// ============================================================
`timescale 1ns/1ps

module dmem #(
    parameter WORDS = 1024
)(
    input  wire        clk,
    input  wire        mem_read,
    input  wire        mem_write,
    input  wire [31:0] addr,
    input  wire [2:0]  funct3,     // 000 b, 001 h, 010 w, 100 bu, 101 hu
    input  wire [31:0] wdata,
    output reg  [31:0] rdata
);
    reg [31:0] mem [0:WORDS-1];
    integer i;
    initial for (i = 0; i < WORDS; i = i + 1) mem[i] = 32'b0;

    wire [29:0] windex = addr[31:2];
    wire [1:0]  boff   = addr[1:0];
    wire [31:0] word   = mem[windex];

    // read: extract + extend
    always @(*) begin
        rdata = 32'b0;
        if (mem_read) begin
            case (funct3)
                3'b000: begin // lb
                    case (boff)
                        2'd0: rdata = {{24{word[7]}},  word[7:0]};
                        2'd1: rdata = {{24{word[15]}}, word[15:8]};
                        2'd2: rdata = {{24{word[23]}}, word[23:16]};
                        2'd3: rdata = {{24{word[31]}}, word[31:24]};
                    endcase
                end
                3'b100: begin // lbu
                    case (boff)
                        2'd0: rdata = {24'b0, word[7:0]};
                        2'd1: rdata = {24'b0, word[15:8]};
                        2'd2: rdata = {24'b0, word[23:16]};
                        2'd3: rdata = {24'b0, word[31:24]};
                    endcase
                end
                3'b001: rdata = boff[1] ? {{16{word[31]}}, word[31:16]}
                                        : {{16{word[15]}}, word[15:0]};  // lh
                3'b101: rdata = boff[1] ? {16'b0, word[31:16]}
                                        : {16'b0, word[15:0]};           // lhu
                default: rdata = word;                                    // lw
            endcase
        end
    end

    // write: byte enables
    always @(posedge clk) begin
        if (mem_write) begin
            case (funct3)
                3'b000: begin // sb
                    case (boff)
                        2'd0: mem[windex][7:0]   <= wdata[7:0];
                        2'd1: mem[windex][15:8]  <= wdata[7:0];
                        2'd2: mem[windex][23:16] <= wdata[7:0];
                        2'd3: mem[windex][31:24] <= wdata[7:0];
                    endcase
                end
                3'b001: begin // sh
                    if (boff[1]) mem[windex][31:16] <= wdata[15:0];
                    else         mem[windex][15:0]  <= wdata[15:0];
                end
                default: mem[windex] <= wdata; // sw
            endcase
        end
    end
endmodule

Related articles