118 lines
4.5 KiB
Systemverilog
118 lines
4.5 KiB
Systemverilog
// *********************************************************************************************
|
|
// 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
|