RISC_V_LAB hinzugefügt

This commit is contained in:
muellerlu
2026-06-09 08:33:18 +02:00
commit 3c0ec38544
233 changed files with 90271 additions and 0 deletions
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.
+60
View File
@@ -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
+52
View File
@@ -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
+135
View File
@@ -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
+231
View File
@@ -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
+117
View File
@@ -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
+37
View File
@@ -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
+44
View File
@@ -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