// ********************************************************************************************* // 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 // ********************************************************************************************* `default_nettype wire module main_mem #( parameter int ABits = 13 // 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] irTmp; logic[31:0] drTmp; // Temporary register to hold the data read from RAM. logic [10:0] mem_addr; // 11-bit word address for MemGen_32_11 logic [31:0] mem_wdata; // 32-bit data bus for MemGen_32_11 logic [31:0] mem_rdata; // 32-bit data bus for MemGen_32_11 MemGen_32_11 RAM ( .chip_en (1'b1), .clock (clk), .addr (mem_addr), .rd_en (!DWE), .rd_data (mem_rdata), .wr_en (DWE), .wr_data (mem_wdata) ); // 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 mem_addr <= 0; end else begin if (DWE) begin mem_addr <= DAddr[(ABits-1):2]; // RAM[DAddr[(ABits-1):2]] <= DWData; case (DWidth) _word: mem_wdata <= DWData; _half: case (DAddr[1]) 1'b0: mem_wdata [31:16] <= DWData[15:0]; 1'b1: mem_wdata [15: 0] <= DWData[15:0]; endcase _byte: case (DAddr[1:0]) 2'b00: mem_wdata [31:24] <= DWData[7:0]; 2'b01: mem_wdata [23:16] <= DWData[7:0]; 2'b10: mem_wdata [15: 8] <= DWData[7:0]; 2'b11: mem_wdata [ 7: 0] <= DWData[7:0]; endcase default: ; endcase end else begin mem_addr <= IAddr[(ABits-1):2]; end end end //---------------------------------------------------------------------------// //--------------------------- DATA READ LOGIC ----------------------------// //---------------------------------------------------------------------------// always_ff @(negedge clk) begin drTmp <= mem_rdata; 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) begin IRData <= mem_rdata; end else begin IRData <= mem_rdata; end end endmodule