RISC_V_LAB hinzugefügt
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Executable
+60
@@ -0,0 +1,60 @@
|
||||
module MemGen_32_11 #(
|
||||
parameter data_width = 32,
|
||||
parameter addr_width = 11,
|
||||
parameter mem_depth = 2048
|
||||
)(
|
||||
input chip_en,
|
||||
input clock,
|
||||
input [addr_width-1:0]addr,
|
||||
output reg [data_width-1:0]rd_data,
|
||||
input rd_en,
|
||||
|
||||
input wr_en,
|
||||
input [data_width-1:0]wr_data
|
||||
);
|
||||
// Bank selection: 1 bit selects one of 2 banks
|
||||
reg [1:0] mem_sel ;
|
||||
wire [31:0] mem_data_out [1:0];
|
||||
|
||||
// Address decoder and output multiplexer
|
||||
always @(*)
|
||||
begin
|
||||
if ( chip_en == 1'b1 )
|
||||
case (addr[10])
|
||||
1'b0 : begin mem_sel = 2'b01; rd_data = mem_data_out[0]; end
|
||||
1'b1 : begin mem_sel = 2'b10; rd_data = mem_data_out[1]; end
|
||||
endcase
|
||||
else
|
||||
begin
|
||||
mem_sel = 2'b00;
|
||||
rd_data = 32'h00000000;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
genvar i;
|
||||
// Instantiate 2 banks, each with 2 halves (low + high 16 bits)
|
||||
generate
|
||||
for (i = 0; i < 2; i = i + 1) begin
|
||||
MemGen_16_10 U_lo (
|
||||
.chip_en(mem_sel[i]),
|
||||
.clock(clock),
|
||||
.addr(addr[9:0]),
|
||||
.rd_en(rd_en),
|
||||
.rd_data(mem_data_out[i][15:0]),
|
||||
.wr_en(wr_en),
|
||||
.wr_data(wr_data[15:0])
|
||||
);
|
||||
MemGen_16_10 U_hi (
|
||||
.chip_en(mem_sel[i]),
|
||||
.clock(clock),
|
||||
.addr(addr[9:0]),
|
||||
.rd_en(rd_en),
|
||||
.rd_data(mem_data_out[i][31:16]),
|
||||
.wr_en(wr_en),
|
||||
.wr_data(wr_data[31:16])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,52 @@
|
||||
// *********************************************************************************************
|
||||
// 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 Bomin Kim [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// 15.Oct.2025 Bomin Kim Refactored ALU logic from decoder into this file
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
module alu (
|
||||
input logic[2:0] aluOp,
|
||||
input logic aluNegAr,
|
||||
input logic aluBypass,
|
||||
input logic[31:0] op1,
|
||||
input logic[31:0] op2,
|
||||
output logic[31:0] result,
|
||||
output logic eqFlag
|
||||
);
|
||||
|
||||
// Local parameters; list of aluOp
|
||||
localparam logic[2:0] f3add = 3'b000;
|
||||
localparam logic[2:0] f3sl = 3'b001;
|
||||
localparam logic[2:0] f3slt = 3'b010;
|
||||
localparam logic[2:0] f3sltU = 3'b011;
|
||||
localparam logic[2:0] f3xor = 3'b100;
|
||||
localparam logic[2:0] f3sr = 3'b101;
|
||||
localparam logic[2:0] f3or = 3'b110;
|
||||
localparam logic[2:0] f3and = 3'b111;
|
||||
|
||||
// ALU logic
|
||||
always_comb begin : ALU
|
||||
eqFlag = op1 == op2;
|
||||
if (aluBypass) result = op1;
|
||||
else case(aluOp)
|
||||
f3add: result = aluNegAr ? op1 - op2 : op1 + op2;
|
||||
f3sl: result = op1 << op2[4:0];
|
||||
f3slt: result = {31'b0, $signed(op1) < $signed(op2)};
|
||||
f3sltU: result = {31'b0, $unsigned(op1) < $unsigned(op2)};
|
||||
f3xor: result = op1 ^ op2;
|
||||
f3sr: result = aluNegAr ? $signed(op1) >>> op2[4:0] : $signed(op1) >> op2[4:0];
|
||||
f3or: result = op1 | op2;
|
||||
f3and: result = op1 & op2;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,135 @@
|
||||
// *********************************************************************************************
|
||||
// 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 Hussein Elzomor [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// 15.Oct.2025 H.Elzomor Renamed file and module from soc to cpu
|
||||
// 15.Oct.2025 H.Elzomor Added an initial condition for clk_12p5
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
module cpu (
|
||||
output logic[7:0] led,
|
||||
input logic[6:0] btn,
|
||||
input logic clk_25mhz,
|
||||
input logic scan_mode //for defining if we are in scan or in functional mode
|
||||
);
|
||||
|
||||
// Local Signals
|
||||
// Clock & Reset
|
||||
logic clk;
|
||||
logic clk12p5;
|
||||
logic reset;
|
||||
// PC
|
||||
logic[31:0] CurrentPC;
|
||||
logic[31:0] JumpOrBranchPC;
|
||||
logic JumpOrBranch;
|
||||
logic[31:0] NextPC;
|
||||
// Memory
|
||||
logic[31:0] DAddr;
|
||||
logic[31:0] WData;
|
||||
logic[31:0] RData;
|
||||
logic[31:0] Instruction;
|
||||
logic WrMem;
|
||||
logic[1:0] DWidth;
|
||||
// Register File;
|
||||
logic[4:0] Rs1;
|
||||
logic[4:0] Rs2;
|
||||
logic[4:0] Rd;
|
||||
logic[31:0] RRs1;
|
||||
logic[31:0] RRs2;
|
||||
logic[31:0] WRd;
|
||||
logic WrReg;
|
||||
// Protection
|
||||
logic Illegal;
|
||||
|
||||
// Logic
|
||||
// Clock (12.5MHz)
|
||||
//assign clk = scan_mode ? clk_25mhz : clk12p5;
|
||||
assign clk = clk_25mhz;
|
||||
|
||||
// always_ff @(posedge clk_25mhz) begin
|
||||
// if (reset)
|
||||
// clk12p5 <= 1'b0;
|
||||
// else if (!scan_mode)
|
||||
// clk12p5 <= ~clk12p5;
|
||||
// end
|
||||
// Reset
|
||||
assign reset = ~btn[0];
|
||||
|
||||
// LED
|
||||
assign led[0] = Illegal;
|
||||
assign led[1] = WrMem;
|
||||
assign led[7:2] = NextPC[7:2];
|
||||
|
||||
// Module Instantiation
|
||||
// Decoder
|
||||
decoder theDecoder (
|
||||
// PC
|
||||
.CurrentPC(CurrentPC),
|
||||
.JumpOrBranchPC(JumpOrBranchPC),
|
||||
.JumpOrBranch(JumpOrBranch),
|
||||
// Memory
|
||||
.DAddr(DAddr),
|
||||
.WData(WData),
|
||||
.RData(RData),
|
||||
.Instruction(Instruction),
|
||||
.WrMem(WrMem),
|
||||
.DWidth(DWidth),
|
||||
// Register File
|
||||
.Rs1(Rs1),
|
||||
.Rs2(Rs2),
|
||||
.Rd(Rd),
|
||||
.RRs1(RRs1),
|
||||
.RRs2(RRs2),
|
||||
.WRd(WRd),
|
||||
.WrReg(WrReg),
|
||||
// Protection
|
||||
.Illegal(Illegal)
|
||||
);
|
||||
|
||||
// Register File
|
||||
reg_file theRegisters (
|
||||
.Rs1(Rs1),
|
||||
.Rs2(Rs2),
|
||||
.Rd(Rd),
|
||||
.RRs1(RRs1),
|
||||
.RRs2(RRs2),
|
||||
.WRd(WRd),
|
||||
.WrReg(WrReg),
|
||||
.reset(reset),
|
||||
.clk(clk)
|
||||
);
|
||||
|
||||
// PC
|
||||
pc thePC (
|
||||
.CurrentPC(CurrentPC),
|
||||
.JumpOrBranchPC(JumpOrBranchPC),
|
||||
.JumpOrBranch(JumpOrBranch),
|
||||
.NextPC(NextPC),
|
||||
.reset(reset),
|
||||
.clk(clk)
|
||||
);
|
||||
|
||||
// Main Memory
|
||||
main_mem #(
|
||||
.MEM_INIT_FILE("") // Memory loading driven from the TB
|
||||
) theMem (
|
||||
.DAddr(DAddr),
|
||||
.IAddr(NextPC),
|
||||
.DWData(WData),
|
||||
.DRData(RData),
|
||||
.IRData(Instruction),
|
||||
.DWE(WrMem),
|
||||
.DWidth(DWidth),
|
||||
.reset(reset),
|
||||
.clk(clk)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,231 @@
|
||||
// *********************************************************************************************
|
||||
// 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 Hussein Elzomor [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// 15.Oct.2025 H.Elzomor Moved PC and ALU logic to their respective files
|
||||
// 15.Oct.2025 H.Elzomor Absorbed the branching logic into the decoder logic
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
module decoder (
|
||||
// PC
|
||||
input logic[31:0] CurrentPC,
|
||||
output logic[31:0] JumpOrBranchPC,
|
||||
output logic JumpOrBranch,
|
||||
// Memory
|
||||
output logic[31:0] DAddr,
|
||||
output logic[31:0] WData,
|
||||
input logic[31:0] RData,
|
||||
input logic[31:0] Instruction,
|
||||
output logic WrMem,
|
||||
output logic[1:0] DWidth,
|
||||
// Register File
|
||||
output logic[4:0] Rs1,
|
||||
output logic[4:0] Rs2,
|
||||
output logic[4:0] Rd,
|
||||
input logic[31:0] RRs1,
|
||||
input logic[31:0] RRs2,
|
||||
output logic[31:0] WRd,
|
||||
output logic WrReg,
|
||||
// Protection
|
||||
output logic Illegal
|
||||
);
|
||||
|
||||
// Local Parameters
|
||||
// OpCode: set a local parameter for each operation
|
||||
localparam logic[6:0] opLd = 7'b0000011;
|
||||
localparam logic[6:0] opAluImm = 7'b0010011;
|
||||
localparam logic[6:0] opUpPC = 7'b0010111;
|
||||
localparam logic[6:0] opSt = 7'b0100011;
|
||||
localparam logic[6:0] opAlu = 7'b0110011;
|
||||
localparam logic[6:0] opUpImm = 7'b0110111;
|
||||
localparam logic[6:0] opBranch = 7'b1100011;
|
||||
localparam logic[6:0] opJALR = 7'b1100111;
|
||||
localparam logic[6:0] opJAL = 7'b1101111;
|
||||
|
||||
// Func7: set a local parameter for each function 7
|
||||
localparam logic[6:0] f7neg = 7'b0100000;
|
||||
|
||||
// Func3: set a local parameter for each function 3
|
||||
// Load/Store
|
||||
localparam logic[2:0] f3byte = 3'b000;
|
||||
localparam logic[2:0] f3half = 3'b001;
|
||||
localparam logic[2:0] f3word = 3'b010;
|
||||
localparam logic[2:0] f3byteU = 3'b100;
|
||||
localparam logic[2:0] f3halfU = 3'b101;
|
||||
// ALU
|
||||
localparam logic[2:0] f3add = 3'b000;
|
||||
localparam logic[2:0] f3sl = 3'b001;
|
||||
localparam logic[2:0] f3slt = 3'b010;
|
||||
localparam logic[2:0] f3sltU = 3'b011;
|
||||
localparam logic[2:0] f3xor = 3'b100;
|
||||
localparam logic[2:0] f3sr = 3'b101;
|
||||
localparam logic[2:0] f3or = 3'b110;
|
||||
localparam logic[2:0] f3and = 3'b111;
|
||||
// Branch
|
||||
localparam logic[2:0] f3beq = 3'b000;
|
||||
localparam logic[2:0] f3bne = 3'b001;
|
||||
localparam logic[2:0] f3blt = 3'b100;
|
||||
localparam logic[2:0] f3bge = 3'b101;
|
||||
localparam logic[2:0] f3bltU = 3'b110;
|
||||
localparam logic[2:0] f3bgeU = 3'b111;
|
||||
|
||||
// Local Signals
|
||||
// Instruction breakdown (excluding I/O)
|
||||
logic[6:0] theOp;
|
||||
logic[2:0] theFunct3;
|
||||
logic[6:0] theFunct7;
|
||||
logic[31:0] i_imm;
|
||||
logic[31:0] s_imm;
|
||||
logic[31:0] b_imm;
|
||||
logic[31:0] u_imm;
|
||||
logic[31:0] j_imm;
|
||||
// ALU
|
||||
logic[2:0] aluOp;
|
||||
logic aluNegAr;
|
||||
logic aluBypass;
|
||||
logic[31:0] op1;
|
||||
logic[31:0] op2;
|
||||
logic[31:0] result;
|
||||
logic eqFlag;
|
||||
|
||||
// Instruction breakdown: assign values
|
||||
// OpCode and functions 3/7
|
||||
assign theOp = Instruction[6:0];
|
||||
assign theFunct3 = Instruction[14:12];
|
||||
assign theFunct7 = Instruction[31:25];
|
||||
// Registers
|
||||
assign Rs1 = Instruction[19:15];
|
||||
assign Rs2 = Instruction[24:20];
|
||||
assign Rd = Instruction[11:7];
|
||||
// Immediates
|
||||
always_comb begin : Immediate_Generator
|
||||
i_imm = {{21{Instruction[31]}}, Instruction[30:20]};
|
||||
s_imm = {{21{Instruction[31]}}, Instruction[30:25], Instruction[11:7]};
|
||||
b_imm = {{20{Instruction[31]}}, Instruction[7], Instruction[30:25], Instruction[11:8], 1'b0};
|
||||
u_imm = {Instruction[31:12], 12'b0};
|
||||
j_imm = {{12{Instruction[31]}}, Instruction[19:12], Instruction[20], Instruction[30:21], 1'b0};
|
||||
end
|
||||
|
||||
// Decoder Logic
|
||||
always_comb begin : Main_Decoder
|
||||
// Factored port/signal values
|
||||
JumpOrBranch = '0;
|
||||
JumpOrBranchPC = '0;
|
||||
DAddr = '0;
|
||||
WData = RRs2;
|
||||
WrMem = '0;
|
||||
DWidth = f3word[1:0];
|
||||
WrReg = '1;
|
||||
Illegal = '0;
|
||||
aluOp = theFunct3;
|
||||
aluNegAr = '0;
|
||||
aluBypass = '0;
|
||||
op1 = RRs1;
|
||||
op2 = RRs2;
|
||||
// OpCode Cases
|
||||
case(theOp)
|
||||
opLd: begin
|
||||
DAddr = RRs1 + i_imm;
|
||||
DWidth = theFunct3[1:0];
|
||||
aluBypass = '1;
|
||||
op1 = RData;
|
||||
case(theFunct3)
|
||||
f3byte: op1[31:8] = {24{RData[7]}};
|
||||
f3byteU: op1[31:8] = {24{1'b0}};
|
||||
f3half: op1[31:16] = {16{RData[15]}};
|
||||
f3halfU: op1[31:16] = {16{1'b0}};
|
||||
f3word: ;
|
||||
default: begin
|
||||
Illegal = '1;
|
||||
WrReg = '0;
|
||||
JumpOrBranch = '1;
|
||||
JumpOrBranchPC = CurrentPC;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
opAluImm: begin
|
||||
op2 = i_imm;
|
||||
aluOp = theFunct3;
|
||||
aluNegAr = (theFunct7 == f7neg) & (theFunct3 == f3sr);
|
||||
end
|
||||
opUpPC: begin
|
||||
op1 = u_imm;
|
||||
op2 = CurrentPC;
|
||||
aluOp = f3add;
|
||||
end
|
||||
opSt: begin
|
||||
WrReg = '0;
|
||||
WrMem = '1;
|
||||
DAddr = RRs1 + s_imm;
|
||||
DWidth = theFunct3[1:0];
|
||||
end
|
||||
opAlu: begin
|
||||
aluOp = theFunct3;
|
||||
aluNegAr = (theFunct7 == f7neg) & ((theFunct3 == f3add) | (theFunct3 == f3sr));
|
||||
end
|
||||
opUpImm: begin
|
||||
op1 = u_imm;
|
||||
aluBypass = '1;
|
||||
end
|
||||
opBranch: begin
|
||||
WrReg = '0;
|
||||
JumpOrBranchPC = CurrentPC + b_imm;
|
||||
aluOp = f3slt;
|
||||
case(theFunct3)
|
||||
f3beq : begin JumpOrBranch = ( eqFlag)? '1 : '0; end
|
||||
f3bne : begin JumpOrBranch = (~eqFlag)? '1 : '0; end
|
||||
f3blt : begin JumpOrBranch = ( result[0])? '1 : '0; end
|
||||
f3bge : begin JumpOrBranch = (~result[0])? '1 : '0; end
|
||||
f3bltU: begin aluOp = f3sltU; JumpOrBranch = ( result[0])? '1 : '0; end
|
||||
f3bgeU: begin aluOp = f3sltU; JumpOrBranch = (~result[0])? '1 : '0; end
|
||||
default: begin
|
||||
Illegal = '1;
|
||||
JumpOrBranch = '1;
|
||||
JumpOrBranchPC = CurrentPC;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
opJALR: begin
|
||||
JumpOrBranch = '1;
|
||||
JumpOrBranchPC = (RRs1 + i_imm) & 32'hFFFFFFFE;
|
||||
op1 = CurrentPC;
|
||||
op2 = 4;
|
||||
aluOp = f3add;
|
||||
end
|
||||
opJAL: begin
|
||||
JumpOrBranch = '1;
|
||||
JumpOrBranchPC = CurrentPC + j_imm;
|
||||
op1 = CurrentPC;
|
||||
op2 = 4;
|
||||
aluOp = f3add;
|
||||
end
|
||||
default: begin
|
||||
Illegal = '1;
|
||||
WrReg = '0;
|
||||
JumpOrBranch = '1;
|
||||
JumpOrBranchPC = CurrentPC;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// ALU module instantiation
|
||||
alu theALU (
|
||||
.aluOp(aluOp),
|
||||
.aluNegAr(aluNegAr),
|
||||
.aluBypass(aluBypass),
|
||||
.op1(op1),
|
||||
.op2(op2),
|
||||
.result(result),
|
||||
.eqFlag(eqFlag)
|
||||
);
|
||||
assign WRd = result;
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,117 @@
|
||||
// *********************************************************************************************
|
||||
// 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
|
||||
@@ -0,0 +1,37 @@
|
||||
// *********************************************************************************************
|
||||
// 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 Bomin Kim [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// 15.Oct.2025 Bomin Kim Moved NextPC logic from decoder into PC
|
||||
// 15.Oct.2025 Bomin Kim Removed reset condition from combinational logic
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
module pc (
|
||||
output logic[31:0] CurrentPC,
|
||||
input logic[31:0] JumpOrBranchPC,
|
||||
input logic JumpOrBranch,
|
||||
output logic[31:0] NextPC,
|
||||
input logic reset,
|
||||
input logic clk
|
||||
);
|
||||
|
||||
// NextPC logic; next-state function
|
||||
always_comb begin : Next_PC
|
||||
if (JumpOrBranch) NextPC = JumpOrBranchPC;
|
||||
else NextPC = CurrentPC + 4;
|
||||
end
|
||||
|
||||
// CurrentPC logic; state register
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) CurrentPC <= '0;
|
||||
else CurrentPC <= NextPC;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,44 @@
|
||||
// *********************************************************************************************
|
||||
// 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 Bomin Kim [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// 15.Oct.2025 Bomin Kim Added reset handling condition
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
module reg_file (
|
||||
input logic[4:0] Rs1,
|
||||
input logic[4:0] Rs2,
|
||||
input logic[4:0] Rd,
|
||||
output logic[31:0] RRs1,
|
||||
output logic[31:0] RRs2,
|
||||
input logic[31:0] WRd,
|
||||
input logic WrReg,
|
||||
input logic reset,
|
||||
input logic clk
|
||||
);
|
||||
|
||||
// Define the registers array
|
||||
logic[31:0] registers[31:1];
|
||||
|
||||
// Register file reading
|
||||
assign RRs1 = Rs1 == 0 ? '0 : registers[Rs1];
|
||||
assign RRs2 = Rs2 == 0 ? '0 : registers[Rs2];
|
||||
|
||||
// Register file writing
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
for (int i=1; i<32; i++)
|
||||
registers[i] <= '0;
|
||||
end else begin
|
||||
if (WrReg & Rd != 0) registers[Rd] <= WRd;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user