// ********************************************************************************************* // Project Version : v1.0 // Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog // ----- // Copyright (c) : 2025 Fraunhofer IIS, Department IDS // Created : 12.Jun.2025 by Lund University [commit 5b1e415] // Last Modified : 23.Oct.2025 by Aliakbar Merchant [commit 2f8f03d] // ----- // HISTORY : Date By Comments // ----------- ---------- ------------------------------------------------- // 22.Oct.2025 A.Merchant Added reset handling condition for Instr. read logic // 22.Oct.2025 A.Merchant Added reset handling condition for data write logic // ********************************************************************************************* module main_mem #( parameter int ABits = 3 // Number of address bits //parameter string MEM_INIT_FILE = "" // Optional memory initializations file )( input logic clk, // Clock input logic reset, // Active high sync reset input logic[31:0] DAddr, // Data Address input logic[31:0] IAddr, // Instruction Address input logic[31:0] DWData, // Data to write output logic[31:0] DRData, // Data read output logic[31:0] IRData, // Instruction read input logic DWE, // Data write enable, 1=Write input logic [1:0] DWidth // Access width (byte, half word, word) ); // Local Parameter localparam logic[1:0] _byte = 2'b00; // byte: 8 bits localparam logic[1:0] _half = 2'b01; // half: 16 bits localparam logic[1:0] _word = 2'b10; // word: 32 bits // Local Signals logic[31:0] RAM[2**(ABits-2)-1:0]; // Memory array 8KB(8192): ignores lowest 2 bits as 32bit-word logic[31:0] drTmp; // Temporary register to hold the data read from RAM. // memory initilizations // initial begin //if (MEM_INIT_FILE != "") begin // $readmemh(MEM_INIT_FILE, RAM); //end // end //---------------------------------------------------------------------------// //--------------------------- DATA WRITE LOGIC ---------------------------// //---------------------------------------------------------------------------// always_ff @(negedge clk) begin if (!reset) begin if (DWE) begin // RAM[DAddr[(ABits-1):2]] <= DWData; case (DWidth) _word: RAM[DAddr[(ABits-1):2]] <= DWData; _half: case (DAddr[1]) 1'b0: RAM[DAddr[(ABits-1):2]][31:16] <= DWData[15:0]; 1'b1: RAM[DAddr[(ABits-1):2]][15: 0] <= DWData[15:0]; endcase _byte: case (DAddr[1:0]) 2'b00: RAM[DAddr[(ABits-1):2]][31:24] <= DWData[7:0]; 2'b01: RAM[DAddr[(ABits-1):2]][23:16] <= DWData[7:0]; 2'b10: RAM[DAddr[(ABits-1):2]][15: 8] <= DWData[7:0]; 2'b11: RAM[DAddr[(ABits-1):2]][ 7: 0] <= DWData[7:0]; endcase default: ; endcase end end end //---------------------------------------------------------------------------// //--------------------------- DATA READ LOGIC ----------------------------// //---------------------------------------------------------------------------// always_ff @(negedge clk) begin drTmp <= RAM[DAddr[(ABits-1):2]]; end always_comb begin case (DWidth) _word: DRData = drTmp; _half: case (DAddr[1]) 1'b0: DRData = {16'b0, drTmp[31:16]}; 1'b1: DRData = {16'b0, drTmp[15: 0]}; endcase _byte: case (DAddr[1:0]) 2'b00: DRData = {24'b0, drTmp[31:24]}; 2'b01: DRData = {24'b0, drTmp[23:16]}; 2'b10: DRData = {24'b0, drTmp[15: 8]}; 2'b11: DRData = {24'b0, drTmp[ 7: 0]}; endcase default: ; endcase end //---------------------------------------------------------------------------// //----------------------- INSTRUCTION READ LOGIC -------------------------// //---------------------------------------------------------------------------// // //fetch intrcution from memory into IRData always_ff @(posedge clk) begin if (reset) IRData <= RAM[0]; else IRData <= RAM[IAddr[(ABits-1):2]]; end endmodule