A massively parallel application RISC-V SOC
// SPDX-License-Identifier: CERN-OHL-S-2.0

// A basic valid-ready ram, default 32KiB

`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.
module mem
(
    input logic         clk_i,
    
    input soc_pkg::mem_in_t      core_i,
    output soc_pkg::mem_out_t    core_o
);

    logic [63:0] memory [0:soc_pkg::MEM_WORDS-1];

    always_ff @(posedge clk_i) begin     
        core_o.ready <= '0;
        
        if (core_i.valid) begin
            MemAddrFitsIntoPhys: assert(core_i.addr < (8*soc_pkg::MEM_WORDS));

            core_o.rdata <= memory[core_i.addr];    
            core_o.ready <= 1'b1;

            if (core_i.wen[0]) memory[core_i.addr][ 7: 0] <= core_i.wdata[ 7: 0];
            if (core_i.wen[1]) memory[core_i.addr][15: 8] <= core_i.wdata[15: 8];
            if (core_i.wen[2]) memory[core_i.addr][23:16] <= core_i.wdata[23:16];
            if (core_i.wen[3]) memory[core_i.addr][31:24] <= core_i.wdata[31:24];
        end
    end

    `ifndef SYNTHESIS
    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
    `endif

endmodule