Merge branch 'main' into busybear

This commit is contained in:
Noah Boorstin 2021-02-28 20:45:08 +00:00
commit bcc0010498
9 changed files with 48 additions and 32 deletions

View File

@ -72,7 +72,7 @@ add wave /testbench/InstrEName
add wave -hex /testbench/dut/hart/ieu/dp/SrcAE
add wave -hex /testbench/dut/hart/ieu/dp/SrcBE
add wave -hex /testbench/dut/hart/ieu/dp/ALUResultE
add wave /testbench/dut/hart/ieu/dp/PCSrcE
#add wave /testbench/dut/hart/ieu/dp/PCSrcE
add wave -divider
add wave -hex /testbench/dut/hart/ifu/PCM
add wave -hex /testbench/dut/hart/ifu/InstrM

View File

@ -28,7 +28,7 @@
module hazard(
// Detect hazards
input logic PCSrcE, CSRWritePendingDEM, RetM, TrapM,
input logic LoadStallD, MulDivStallD,
input logic LoadStallD, MulDivStallD, CSRRdStallD,
input logic InstrStall, DataStall,
// Stall & flush outputs
output logic StallF, StallD, StallE, StallM, StallW,
@ -54,7 +54,8 @@ module hazard(
assign BranchFlushDE = PCSrcE | RetM | TrapM;
assign StallFCause = CSRWritePendingDEM & ~(BranchFlushDE);
assign StallDCause = LoadStallD | MulDivStallD; // stall in decode if instruction is a load/mul dependent on previous
assign StallDCause = (LoadStallD | MulDivStallD | CSRRdStallD) & ~(BranchFlushDE); // stall in decode if instruction is a load/mul/csr dependent on previous
// assign StallDCause = LoadStallD | MulDivStallD | CSRRdStallD; // stall in decode if instruction is a load/mul/csr dependent on previous
assign StallECause = 0;
assign StallMCause = 0;
assign StallWCause = DataStall | InstrStall;

View File

@ -29,9 +29,7 @@
module controller(
input logic clk, reset,
// Decode stage control signals
input logic [6:0] OpD,
input logic [2:0] Funct3D,
input logic [6:0] Funct7D,
input logic [31:0] InstrD,
output logic [2:0] ImmSrcD,
input logic IllegalIEUInstrFaultD,
output logic IllegalBaseInstrFaultD,
@ -42,13 +40,13 @@ module controller(
output logic [4:0] ALUControlE,
output logic ALUSrcAE, ALUSrcBE,
output logic TargetSrcE,
output logic MemReadE, // for Hazard Unit
output logic MemReadE, CSRReadE, // for Hazard Unit
output logic [2:0] Funct3E,
output logic MulDivE, W64E,
// Memory stage control signals
input logic StallM, FlushM,
output logic [1:0] MemRWM,
output logic CSRWriteM, PrivilegedM,
output logic CSRReadM, CSRWriteM, PrivilegedM,
output logic [2:0] Funct3M,
output logic RegWriteM, // for Hazard Unit
// Writeback stage control signals
@ -60,6 +58,11 @@ module controller(
output logic CSRWritePendingDEM
);
logic [6:0] OpD;
logic [2:0] Funct3D;
logic [6:0] Funct7D;
logic [4:0] Rs1D;
// pipelined control signals
logic RegWriteD, RegWriteE;
logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM;
@ -70,6 +73,8 @@ module controller(
logic [4:0] ALUControlD;
logic ALUSrcAD, ALUSrcBD;
logic TargetSrcD, W64D, MulDivD;
logic CSRZeroSrcD;
logic CSRReadD;
logic CSRWriteD, CSRWriteE;
logic InstrValidE, InstrValidM;
logic PrivilegedD, PrivilegedE;
@ -80,14 +85,19 @@ module controller(
logic zeroE, ltE, ltuE;
logic unused;
// Extract fields
assign OpD = InstrD[6:0];
assign Funct3D = InstrD[14:12];
assign Funct7D = InstrD[31:25];
assign Rs1D = InstrD[19:15];
// Main Instruction Decoder
// *** decoding of non-IEU instructions should also go here, and should be gated by MISA bits in a generate so
// *** perhaps decoding of non-IEU instructions should also go here, and should be gated by MISA bits in a generate so
// they don't get generated if that mode is disabled
generate
always_comb
case(OpD)
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_TargetSrc_W64_CSRWrite_Privileged_MulDiv_Illegal
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_TargetSrc_W64_CSRRead_Privileged_MulDiv_Illegal
7'b0000011: ControlsD = 21'b1_000_01_10_001_0_00_0_0_0_0_0_0_0; // lw
7'b0100011: ControlsD = 21'b0_001_01_01_000_0_00_0_0_0_0_0_0_0; // sw
7'b0110011: if (Funct7D == 7'b0000000 || Funct7D == 7'b0100000)
@ -126,10 +136,13 @@ module controller(
// squash control signals if coming from an illegal compressed instruction
assign IllegalBaseInstrFaultD = ControlsD[0];
assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
ResultSrcD, BranchD, ALUOpD, JumpD, TargetSrcD, W64D, CSRWriteD,
ResultSrcD, BranchD, ALUOpD, JumpD, TargetSrcD, W64D, CSRReadD,
PrivilegedD, MulDivD, unused} = ControlsD & ~IllegalIEUInstrFaultD;
// *** move Privileged, CSRwrite?? Or move controller out of IEU into datapath and handle all instructions
assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source?
assign CSRWriteD = CSRReadD & !(CSRZeroSrcD && InstrD[13]); // Don't write if setting or clearing zeros
// ALU Decoding *** should move to ALU for better modularity
assign sltD = (Funct3D == 3'b010);
assign sltuD = (Funct3D == 3'b011);
@ -147,9 +160,9 @@ module controller(
endcase
// Execute stage pipeline control register and logic
flopenrc #(24) controlregE(clk, reset, FlushE, ~StallE,
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, TargetSrcD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, 1'b1},
{RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, InstrValidE});
flopenrc #(25) controlregE(clk, reset, FlushE, ~StallE,
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, TargetSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, 1'b1},
{RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, InstrValidE});
// Branch Logic
assign {zeroE, ltE, ltuE} = FlagsE;
@ -170,15 +183,14 @@ module controller(
assign MemReadE = MemRWE[1];
// Memory stage pipeline control register
flopenrc #(12) controlregM(clk, reset, FlushM, ~StallM,
{RegWriteE, ResultSrcE, MemRWE, CSRWriteE, PrivilegedE, Funct3E, InstrValidE},
{RegWriteM, ResultSrcM, MemRWM, CSRWriteM, PrivilegedM, Funct3M, InstrValidM});
flopenrc #(13) controlregM(clk, reset, FlushM, ~StallM,
{RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, InstrValidE},
{RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, InstrValidM});
// Writeback stage pipeline control register
flopenrc #(5) controlregW(clk, reset, FlushW, ~StallW,
{RegWriteM, ResultSrcM, InstrValidM},
{RegWriteW, ResultSrcW, InstrValidW});
// *** improve this so CSR reads don't trigger this signal and cause pipeline flushes
assign CSRWritePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM;
endmodule

View File

@ -28,11 +28,11 @@
module forward(
// Detect hazards
input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW,
input logic MemReadE, MulDivE,
input logic MemReadE, MulDivE, CSRReadE,
input logic RegWriteM, RegWriteW,
// Forwarding controls
output logic [1:0] ForwardAE, ForwardBE,
output logic LoadStallD, MulDivStallD
output logic LoadStallD, MulDivStallD, CSRRdStallD
);
always_comb begin
@ -47,7 +47,9 @@ module forward(
else if ((Rs2E == RdW) & RegWriteW) ForwardBE = 2'b01;
end
// Stall on dependent operations that finish in Mem Stage and can't bypass in time
assign LoadStallD = MemReadE & ((Rs1D == RdE) | (Rs2D == RdE));
assign MulDivStallD = MulDivE & & ((Rs1D == RdE) | (Rs2D == RdE)); // *** extend with stalls for divide
assign MulDivStallD = MulDivE & ((Rs1D == RdE) | (Rs2D == RdE)); // *** extend with stalls for divide
assign CSRRdStallD = CSRReadE & ((Rs1D == RdE) | (Rs2D == RdE));
endmodule

View File

@ -51,10 +51,10 @@ module ieu (
// hazards
input logic StallE, StallM, StallW,
input logic FlushE, FlushM, FlushW,
output logic LoadStallD, MulDivStallD,
output logic LoadStallD, MulDivStallD, CSRRdStallD,
output logic PCSrcE,
output logic CSRWriteM, PrivilegedM,
output logic CSRReadM, CSRWriteM, PrivilegedM,
output logic CSRWritePendingDEM
);
@ -69,9 +69,9 @@ module ieu (
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW;
logic [1:0] ForwardAE, ForwardBE;
logic RegWriteM, RegWriteW;
logic MemReadE;
logic MemReadE, CSRReadE;
controller c(.OpD(InstrD[6:0]), .Funct3D(InstrD[14:12]), .Funct7D(InstrD[31:25]), .*);
controller c(.*);
datapath dp(.*);
forward fw(.*);
endmodule

View File

@ -31,7 +31,7 @@ module csr (
input logic FlushW, StallW,
input logic [31:0] InstrM,
input logic [`XLEN-1:0] PCM, SrcAM,
input logic CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM,
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM,
input logic TimerIntM, ExtIntM, SwIntM,
input logic InstrValidW, FloatRegWriteW, LoadStallD,
input logic [1:0] NextPrivilegeModeM, PrivilegeModeW,
@ -111,7 +111,7 @@ module csr (
(CSRAdrM[9:8] == 2'b01 && PrivilegeModeW == `U_MODE);
assign IllegalCSRAccessM = (IllegalCSRCAccessM && IllegalCSRMAccessM &&
IllegalCSRSAccessM && IllegalCSRUAccessM && IllegalCSRNAccessM ||
InsufficientCSRPrivilegeM) && CSRWriteM;
InsufficientCSRPrivilegeM) && CSRReadM;
end else begin // CSRs not implemented
assign STATUS_MPP = 2'b11;
assign STATUS_SPP = 2'b0;
@ -132,7 +132,7 @@ module csr (
assign STATUS_SIE = 0;
assign FRM_REGW = 0;
assign CSRReadValM = 0;
assign IllegalCSRAccessM = CSRWriteM;
assign IllegalCSRAccessM = CSRReadM;
end
endgenerate
endmodule

View File

@ -29,7 +29,7 @@
module privileged (
input logic clk, reset,
input logic FlushW,
input logic CSRWriteM,
input logic CSRReadM, CSRWriteM,
input logic [`XLEN-1:0] SrcAM,
input logic [31:0] InstrM,
input logic [`XLEN-1:0] PCM,

View File

@ -60,7 +60,7 @@ module wallypipelinedhart (
// new signals that must connect through DP
logic MulDivE, W64E;
logic CSRWriteM, PrivilegedM;
logic CSRReadM, CSRWriteM, PrivilegedM;
logic [`XLEN-1:0] SrcAE, SrcBE;
logic [`XLEN-1:0] SrcAM;
logic [2:0] Funct3E;
@ -81,7 +81,7 @@ module wallypipelinedhart (
logic PCSrcE;
logic CSRWritePendingDEM;
logic LoadStallD, MulDivStallD;
logic LoadStallD, MulDivStallD, CSRRdStallD;
logic [4:0] SetFflagsM;
logic [2:0] FRM_REGW;
logic FloatRegWriteW;

View File

@ -90,6 +90,7 @@ string tests64iNOc[] = {
"rv64i/I-MISALIGN_JMP-01","2000"
};
string tests64i[] = '{
"rv64i/I-MISALIGN_LDST-01", "2010",
"rv64i/I-ADD-01", "3000",
"rv64i/I-ADDI-01", "3000",
"rv64i/I-ADDIW-01", "3000",
@ -322,7 +323,7 @@ string tests32i[] = {
tests = {tests64i};
if (`C_SUPPORTED % 2 == 1) tests = {tests, tests64ic};
else tests = {tests, tests64iNOc};
if (`M_SUPPORTED % 2 == 1) tests = {tests64m, tests};
if (`M_SUPPORTED % 2 == 1) tests = {tests, tests64m};
end else begin // RV32
tests = {tests32i};
if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic};