Factored out memory interface

[?]
8Cqo1QjSCQ3F66Vh3nan9N8dv1MjQSAEz8RNwt2cTacK
May 15, 2024, 4:49 AM
MOJRQVF4Q7OM2AHWAFBZOXHP5I3ZUWWKTTH6LOI5IIKB4VHXHNNQC

Dependencies

  • [2] MTNLHQLQ Focus on the hardware design by dropping alternative HDLS for Verilog

Change contents

  • edit in rtl/soc.sv at line 24
    [2.388]
    [2.388]
    mem memory();
    mem_impl memory_impl(clk, memory.impl);
  • edit in rtl/soc.sv at line 27
    [2.389][2.389:929]()
    // Memory
    struct {
    bit [3:0] wen;
    bit [31:0] addr;
    bit [31:0] rdata;
    bit [31:0] wdata;
    } mem;
    logic [31:0] memory [0:MEM_WORDS-1];
    always_ff @(posedge clk) begin
    mem.rdata <= memory[mem.addr];
    if (mem.wen[0]) memory[mem.addr][ 7: 0] <= mem.wdata[ 7: 0];
    if (mem.wen[1]) memory[mem.addr][15: 8] <= mem.wdata[15: 8];
    if (mem.wen[2]) memory[mem.addr][23:16] <= mem.wdata[23:16];
    if (mem.wen[3]) memory[mem.addr][31:24] <= mem.wdata[31:24];
    end
    // End Memory
  • edit in rtl/soc.sv at line 34
    [2.1196][2.1196:1361]()
    end
    if ($value$plusargs("mem", mem_file)) begin
    $display("[%0t] Initializing memory\n", $time);
    $readmemh(mem_file, memory);
  • file addition: mem.sv (----------)
    [2.1]
    // SPDX-License-Identifier: CERN-OHL-S-2.0
    // A simple valid-ready memory interface that can handle a single memory transfer at a time
    `default_nettype none
    `timescale 1ps/1ps
    // The core initiates a transfer by asserting valid, which stays high until the
    // peer asserts ready. All core outputs are stable over the valid period.
    // If the transfer is an instruction fetch, the core asserts instr.
    interface mem;
    bit valid;
    bit ready;
    bit instr;
    enum bit[3:0] {
    READ = 'b0000,
    WRITE_BYTE0 = 'b0001,
    WRITE_BYTE1 = 'b0010,
    WRITE_BYTE2 = 'b0100,
    WRITE_BYTE3 = 'b1000,
    WRITE_HWORD0 = 'b0011,
    WRITE_HWORD1 = 'b1100,
    WRITE_WORD = 'b1111
    } mode;
    wire [31:0] addr;
    wire [31:0] rdata;
    wire [31:0] wdata;
    modport core (
    output valid,
    input ready,
    output instr,
    output mode,
    output addr,
    input rdata,
    output wdata
    );
    modport impl (
    input valid,
    output ready,
    input instr,
    input mode,
    input addr,
    output rdata,
    input wdata
    );
    endinterface
    /* verilator lint_off DECLFILENAME */
    module mem_impl
    #(
    parameter integer MEM_WORDS = 4096
    )
    (
    input bit clk,
    mem.impl mem
    );
    logic [31:0] memory [0:MEM_WORDS-1];
    logic [3:0] wen = mem.mode;
    always_ff @(posedge clk) begin
    mem.ready <= '0;
    if (mem.valid) begin
    mem.rdata <= memory[mem.addr];
    if (wen[0]) memory[mem.addr][ 7: 0] <= mem.wdata[ 7: 0];
    if (wen[1]) memory[mem.addr][15: 8] <= mem.wdata[15: 8];
    if (wen[2]) memory[mem.addr][23:16] <= mem.wdata[23:16];
    if (wen[3]) memory[mem.addr][31:24] <= mem.wdata[31:24];
    end
    end
    // synthesis translate off
    logic [200:0] mem_file;
    initial begin
    if ($value$plusargs("mem", mem_file)) begin
    $display("[%0t] Initializing memory\n", $time);
    $readmemh(mem_file, memory);
    end
    end
    phys_mem_addr: assert property(@(posedge clk) mem.addr < (4*MEM_WORDS));
    // synthesis translate on
    endmodule
  • replacement in Makefile at line 22
    [2.2565][2.2565:2581]()
    # Generate deps
    [2.2565]
    [2.2581]
    # Generate depfiles
  • replacement in Makefile at line 43
    [2.3209][2.3209:3253]()
    $(VERILATOR) $(VERILATOR_FLAGS) rtl/soc.sv
    [2.3209]
    [2.3253]
    $(VERILATOR) $(VERILATOR_FLAGS) rtl/soc.sv -Irtl