turns out I should not have tried renaming FStallD to FPUStallD because that name was already used! All the same it does feel weird to have two such signals floating around \(ah pun!\)

This commit is contained in:
bbracker 2021-05-28 23:11:37 -04:00
parent 778ba6bbf5
commit 39ae743543
9 changed files with 118 additions and 99 deletions

View File

@ -40,7 +40,7 @@ vsim workopt
view wave
-- display input and output signals as hexidecimal values
do ./wave-dos/default-waves.do
do ./wave-dos/peripheral-waves.do
-- Run the Simulation
#run 5000

View File

@ -48,6 +48,11 @@ add wave /testbench/dut/hart/ieu/dp/RegWriteW
add wave -hex /testbench/dut/hart/ieu/dp/ResultW
add wave -hex /testbench/dut/hart/ieu/dp/RdW
add wave -divider
add wave -hex /testbench/dut/hart/priv/csr/ProposedEPCM
add wave -hex /testbench/dut/hart/priv/csr/TrapM
add wave -hex /testbench/dut/hart/priv/csr/UnalignedNextEPCM
add wave -hex /testbench/dut/hart/priv/csr/genblk1/csrm/WriteMEPCM
add wave -hex /testbench/dut/hart/priv/csr/genblk1/csrm/MEPC_REGW
add wave -divider
# peripherals

View File

@ -30,16 +30,15 @@ module hazard(
input logic reset,
// Detect hazards
input logic BPPredWrongE, CSRWritePendingDEM, RetM, TrapM,
input logic FPUStallD, LoadStallD, MulDivStallD, CSRRdStallD,
input logic LoadStallD, MulDivStallD, CSRRdStallD,
input logic DataStall, ICacheStallF,
input logic FStallD,
input logic FPUStallD,
input logic DivBusyE,
// Stall & flush outputs
output logic StallF, StallD, StallE, StallM, StallW,
output logic FlushF, FlushD, FlushE, FlushM, FlushW
);
logic BranchFlushDE;
logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause;
logic FirstUnstalledD, FirstUnstalledE, FirstUnstalledM, FirstUnstalledW;
@ -56,34 +55,29 @@ module hazard(
// A stage must stall if the next stage is stalled
// If any stages are stalled, the first stage that isn't stalled must flush.
assign BranchFlushDE = BPPredWrongE | RetM | TrapM;
assign StallFCause = CSRWritePendingDEM & ~(BranchFlushDE);
assign StallDCause = (FPUStallD | LoadStallD | MulDivStallD | CSRRdStallD | FStallD) & ~(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 StallFCause = CSRWritePendingDEM && ~(TrapM || RetM || BPPredWrongE);
assign StallDCause = (LoadStallD || MulDivStallD || CSRRdStallD || FPUStallD) && ~(TrapM || RetM || BPPredWrongE); // stall in decode if instruction is a load/mul/csr dependent on previous
assign StallECause = DivBusyE;
assign StallMCause = 0;
assign StallWCause = DataStall | ICacheStallF;
assign StallWCause = DataStall || ICacheStallF;
// Each stage stalls if the next stage is stalled or there is a cause to stall this stage.
assign StallF = StallD | StallFCause;
assign StallD = StallE | StallDCause;
assign StallE = StallM | StallECause;
assign StallM = StallW | StallMCause;
assign StallF = StallFCause || StallD;
assign StallD = StallDCause || StallE;
assign StallE = StallECause || StallM;
assign StallM = StallMCause || StallW;
assign StallW = StallWCause;
//assign FirstUnstalledD = (~StallD & StallF & ~MulDivStallD);
assign FirstUnstalledD = (~StallD & StallF);
//assign FirstUnstalledE = (~StallE & StallD & ~MulDivStallD);
assign FirstUnstalledE = (~StallE & StallD);
assign FirstUnstalledM = (~StallM & StallE);
assign FirstUnstalledW = (~StallW & StallM);;
assign FirstUnstalledD = (~StallD && StallF);
assign FirstUnstalledE = (~StallE && StallD);
assign FirstUnstalledM = (~StallM && StallE);
assign FirstUnstalledW = (~StallW && StallM);
// Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush
assign FlushF = BPPredWrongE;
assign FlushD = FirstUnstalledD || BranchFlushDE; // PCSrcE |InstrStall | CSRWritePendingDEM | RetM | TrapM;
assign FlushE = FirstUnstalledE || BranchFlushDE; // LoadStallD | PCSrcE | RetM | TrapM;
assign FlushM = FirstUnstalledM || RetM || TrapM;
assign FlushW = FirstUnstalledW | TrapM;
assign FlushD = FirstUnstalledD || TrapM || RetM || BPPredWrongE;
assign FlushE = FirstUnstalledE || TrapM || RetM || BPPredWrongE;
assign FlushM = FirstUnstalledM || TrapM || RetM;
assign FlushW = FirstUnstalledW || TrapM;
endmodule

View File

@ -37,7 +37,8 @@ module ifu (
output logic [`XLEN-1:0] InstrPAdrF,
output logic InstrReadF,
output logic ICacheStallF,
// Decode
// Decode
output logic [`XLEN-1:0] PCD,
// Execute
output logic [`XLEN-1:0] PCLinkE,
input logic PCSrcE,
@ -47,7 +48,7 @@ module ifu (
// Mem
input logic RetM, TrapM,
input logic [`XLEN-1:0] PrivilegedNextPCM,
output logic [31:0] InstrD, InstrM,
output logic [31:0] InstrD, InstrE, InstrM, InstrW,
output logic [`XLEN-1:0] PCM,
output logic [4:0] InstrClassM,
output logic BPPredDirWrongM,
@ -76,9 +77,9 @@ module ifu (
logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM;
logic PrivilegedChangePCM;
logic IllegalCompInstrD;
logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCD, PCW, PCLinkD, PCLinkM, PCNextPF, PCPF;
logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCW, PCLinkD, PCLinkM, PCNextPF, PCPF;
logic CompressedF;
logic [31:0] InstrRawD, InstrE, InstrW;
logic [31:0] InstrRawD;
localparam [31:0] nop = 32'h00000013; // instruction for NOP
logic reset_q; // *** look at this later.

View File

@ -34,8 +34,8 @@ module csr #(parameter
) (
input logic clk, reset,
input logic FlushW, StallD, StallE, StallM, StallW,
input logic [31:0] InstrM,
input logic [`XLEN-1:0] PCM, SrcAM,
input logic [31:0] InstrD,InstrE,InstrM,
input logic [`XLEN-1:0] PCF, PCD, PCE, PCM, SrcAM,
input logic InterruptM,
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM,
input logic TimerIntM, ExtIntM, SwIntM,
@ -47,6 +47,9 @@ module csr #(parameter
input logic [4:0] InstrClassM,
input logic [1:0] NextPrivilegeModeM, PrivilegeModeW,
input logic [`XLEN-1:0] CauseM, NextFaultMtvalM,
input logic BreakpointFaultM, EcallFaultM,
input logic InstrMisalignedFaultM, InstrAccessFaultM, IllegalInstrFaultM,
input logic LoadMisalignedFaultM, StoreMisalignedFaultM, LoadAccessFaultM, StoreAccessFaultM,
output logic [1:0] STATUS_MPP,
output logic STATUS_SPP, STATUS_TSR,
output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW,
@ -65,6 +68,7 @@ module csr #(parameter
output logic IllegalCSRAccessM
);
localparam NOP = 32'h13;
logic [`XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRNReadValM, CSRCReadValM, CSRReadValM;
logic [`XLEN-1:0] CSRSrcM, CSRRWM, CSRRSM, CSRRCM, CSRWriteValM;
@ -73,22 +77,32 @@ module csr #(parameter
logic WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM;
logic CSRMWriteM, CSRSWriteM, CSRUWriteM;
logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, preservedPCM, readPCM, NextCauseM, NextMtvalM;
always_ff @(posedge clk) begin
preservedPCM <= PCM;
end
mux2 #(`XLEN) pcmux(PCM, preservedPCM, InterruptM, readPCM);
//flop #(`XLEN) CSRReadPCMreg(clk, reset, PCM, readPCM);
logic MStageFailed;
logic [`XLEN-1:0] ProposedEPCM, UnalignedNextEPCM, NextEPCM, NextCauseM, NextMtvalM;
logic [11:0] CSRAdrM;
logic [11:0] SIP_REGW, SIE_REGW;
//logic [11:0] UIP_REGW, UIE_REGW = 0; // N user-mode exceptions not supported
logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM, IllegalCSRNAccessM, InsufficientCSRPrivilegeM;
logic IllegalCSRMWriteReadonlyM;
assign MStageFailed = BreakpointFaultM || EcallFaultM || InstrMisalignedFaultM || InstrAccessFaultM || IllegalInstrFaultM || LoadMisalignedFaultM || StoreMisalignedFaultM || LoadAccessFaultM || StoreAccessFaultM;
always_comb begin
if (MStageFailed)
casez({InstrD==NOP,InstrE==NOP,InstrM==NOP})
3'b??0: ProposedEPCM = PCM;
3'b?01: ProposedEPCM = PCE;
3'b011: ProposedEPCM = PCD;
3'b111: ProposedEPCM = PCF;
endcase
else
casez({InstrD==NOP,InstrE==NOP})
2'b?0: ProposedEPCM = PCE;
2'b01: ProposedEPCM = PCD;
2'b11: ProposedEPCM = PCF;
endcase
end
generate
if (`ZCSR_SUPPORTED) begin
// modify CSRs
@ -109,7 +123,7 @@ module csr #(parameter
// write CSRs
assign CSRAdrM = InstrM[31:20];
assign UnalignedNextEPCM = TrapM ? readPCM : CSRWriteValM;
assign UnalignedNextEPCM = TrapM ? ProposedEPCM : CSRWriteValM;
assign NextEPCM = `C_SUPPORTED ? {UnalignedNextEPCM[`XLEN-1:1], 1'b0} : {UnalignedNextEPCM[`XLEN-1:2], 2'b00}; // 3.1.15 alignment
assign NextCauseM = TrapM ? CauseM : CSRWriteValM;
assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM;

View File

@ -109,74 +109,74 @@ module csrsr (
// complex register with reset, write enable, and the ability to update other bits in certain cases
always_ff @(posedge clk, posedge reset)
if (reset) begin
STATUS_SUM_INT <= 0;
STATUS_MPRV_INT <= 0; // Per Priv 3.3
STATUS_FS_INT <= 0; //2'b01; // busybear: change all these reset values to 0
STATUS_MPP <= 0; //`M_MODE;
STATUS_SPP <= 0; //1'b1;
STATUS_MPIE <= 0; //1;
STATUS_SPIE <= 0; //`S_SUPPORTED;
STATUS_UPIE <= 0; // `U_SUPPORTED;
STATUS_MIE <= 0; // Per Priv 3.3
STATUS_SIE <= 0; //`S_SUPPORTED;
STATUS_UIE <= 0; //`U_SUPPORTED;
STATUS_SUM_INT <= #1 0;
STATUS_MPRV_INT <= #1 0; // Per Priv 3.3
STATUS_FS_INT <= #1 0; //2'b01; // busybear: change all these reset values to 0
STATUS_MPP <= #1 0; //`M_MODE;
STATUS_SPP <= #1 0; //1'b1;
STATUS_MPIE <= #1 0; //1;
STATUS_SPIE <= #1 0; //`S_SUPPORTED;
STATUS_UPIE <= #1 0; // `U_SUPPORTED;
STATUS_MIE <= #1 0; // Per Priv 3.3
STATUS_SIE <= #1 0; //`S_SUPPORTED;
STATUS_UIE <= #1 0; //`U_SUPPORTED;
end else if (~StallW) begin
if (WriteMSTATUSM) begin
STATUS_SUM_INT <= CSRWriteValM[18];
STATUS_MPRV_INT <= CSRWriteValM[17];
STATUS_FS_INT <= CSRWriteValM[14:13];
STATUS_MPP <= STATUS_MPP_NEXT;
STATUS_SPP <= `S_SUPPORTED & CSRWriteValM[8];
STATUS_MPIE <= CSRWriteValM[7];
STATUS_SPIE <= `S_SUPPORTED & CSRWriteValM[5];
STATUS_UPIE <= `U_SUPPORTED & CSRWriteValM[4];
STATUS_MIE <= CSRWriteValM[3];
STATUS_SIE <= `S_SUPPORTED & CSRWriteValM[1];
STATUS_UIE <= `U_SUPPORTED & CSRWriteValM[0];
STATUS_SUM_INT <= #1 CSRWriteValM[18];
STATUS_MPRV_INT <= #1 CSRWriteValM[17];
STATUS_FS_INT <= #1 CSRWriteValM[14:13];
STATUS_MPP <= #1 STATUS_MPP_NEXT;
STATUS_SPP <= #1 `S_SUPPORTED & CSRWriteValM[8];
STATUS_MPIE <= #1 CSRWriteValM[7];
STATUS_SPIE <= #1 `S_SUPPORTED & CSRWriteValM[5];
STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4];
STATUS_MIE <= #1 CSRWriteValM[3];
STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1];
STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0];
end else if (WriteSSTATUSM) begin // write a subset of the STATUS bits
STATUS_SUM_INT <= CSRWriteValM[18];
STATUS_FS_INT <= CSRWriteValM[14:13];
STATUS_SPP <= `S_SUPPORTED & CSRWriteValM[8];
STATUS_SPIE <= `S_SUPPORTED & CSRWriteValM[5];
STATUS_UPIE <= `U_SUPPORTED & CSRWriteValM[4];
STATUS_SIE <= `S_SUPPORTED & CSRWriteValM[1];
STATUS_UIE <= `U_SUPPORTED & CSRWriteValM[0];
STATUS_SUM_INT <= #1 CSRWriteValM[18];
STATUS_FS_INT <= #1 CSRWriteValM[14:13];
STATUS_SPP <= #1 `S_SUPPORTED & CSRWriteValM[8];
STATUS_SPIE <= #1 `S_SUPPORTED & CSRWriteValM[5];
STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4];
STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1];
STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0];
end else if (WriteUSTATUSM) begin // write a subset of the STATUS bits
STATUS_FS_INT <= CSRWriteValM[14:13];
STATUS_UPIE <= `U_SUPPORTED & CSRWriteValM[4];
STATUS_UIE <= `U_SUPPORTED & CSRWriteValM[0];
STATUS_FS_INT <= #1 CSRWriteValM[14:13];
STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4];
STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0];
end else begin
if (FloatRegWriteW) STATUS_FS_INT <=2'b11; // mark Float State dirty
if (FloatRegWriteW) STATUS_FS_INT <= #12'b11; // mark Float State dirty
if (TrapM) begin
// Update interrupt enables per Privileged Spec p. 21
// y = PrivilegeModeW
// x = NextPrivilegeModeM
// Modes: 11 = Machine, 01 = Supervisor, 00 = User
if (NextPrivilegeModeM == `M_MODE) begin
STATUS_MPIE <= STATUS_MIE;
STATUS_MIE <= 0;
STATUS_MPP <= PrivilegeModeW;
STATUS_MPIE <= #1 STATUS_MIE;
STATUS_MIE <= #1 0;
STATUS_MPP <= #1 PrivilegeModeW;
end else if (NextPrivilegeModeM == `S_MODE) begin
STATUS_SPIE <= STATUS_SIE;
STATUS_SIE <= 0;
STATUS_SPP <= PrivilegeModeW[0]; // *** seems to disagree with P. 56
STATUS_SPIE <= #1 STATUS_SIE;
STATUS_SIE <= #1 0;
STATUS_SPP <= #1 PrivilegeModeW[0]; // *** seems to disagree with P. 56
end else begin // user mode
STATUS_UPIE <= STATUS_UIE;
STATUS_UIE <= 0;
STATUS_UPIE <= #1 STATUS_UIE;
STATUS_UIE <= #1 0;
end
end else if (mretM) begin // Privileged 3.1.6.1
STATUS_MIE <= STATUS_MPIE;
STATUS_MPIE <= 1;
STATUS_MPP <= `U_SUPPORTED ? `U_MODE : `M_MODE; // per spec, not sure why
STATUS_MPRV_INT <= 0; // per 20210108 draft spec
STATUS_MIE <= #1 STATUS_MPIE;
STATUS_MPIE <= #1 1;
STATUS_MPP <= #1 `U_SUPPORTED ? `U_MODE : `M_MODE; // per spec, not sure why
STATUS_MPRV_INT <= #1 0; // per 20210108 draft spec
end else if (sretM) begin
STATUS_SIE <= STATUS_SPIE;
STATUS_SPIE <= `S_SUPPORTED;
STATUS_SPP <= 0; // Privileged 4.1.1
STATUS_MPRV_INT <= 0; // per 20210108 draft spec
STATUS_SIE <= #1 STATUS_SPIE;
STATUS_SPIE <= #1 `S_SUPPORTED;
STATUS_SPP <= #1 0; // Privileged 4.1.1
STATUS_MPRV_INT <= #1 0; // per 20210108 draft spec
end else if (uretM) begin
STATUS_UIE <= STATUS_UPIE;
STATUS_UPIE <= `U_SUPPORTED;
STATUS_UIE <= #1 STATUS_UPIE;
STATUS_UPIE <= #1 `U_SUPPORTED;
end
// *** add code to track STATUS_FS_INT for dirty floating point registers
end

View File

@ -31,8 +31,8 @@ module privileged (
input logic FlushW,
input logic CSRReadM, CSRWriteM,
input logic [`XLEN-1:0] SrcAM,
input logic [31:0] InstrM,
input logic [`XLEN-1:0] PCM,
input logic [`XLEN-1:0] PCF,PCD,PCE,PCM,
input logic [31:0] InstrD, InstrE, InstrM, InstrW,
output logic [`XLEN-1:0] CSRReadValW,
output logic [`XLEN-1:0] PrivilegedNextPCM,
output logic RetM, TrapM,

View File

@ -68,8 +68,8 @@ module wallypipelinedhart (
logic [`XLEN-1:0] SrcAM;
logic [2:0] Funct3E;
// logic [31:0] InstrF;
logic [31:0] InstrD, InstrM;
logic [`XLEN-1:0] PCE, PCM, PCLinkE, PCLinkW;
logic [31:0] InstrD, InstrE, InstrM, InstrW;
logic [`XLEN-1:0] PCD, PCE, PCM, PCLinkE, PCLinkW;
logic [`XLEN-1:0] PCTargetE;
logic [`XLEN-1:0] CSRReadValW, MulDivResultW;
logic [`XLEN-1:0] PrivilegedNextPCM;

View File

@ -29,6 +29,7 @@
module testbench();
parameter DEBUG = 0;
parameter TESTSPERIPH = 0; // set to 0 for regression
parameter TESTSPRIV = 0; // set to 0 for regression
logic clk;
logic reset;
@ -516,9 +517,11 @@ string tests32f[] = '{
tests = testsBP64;
// testsbp should not run the other tests. It starts at address 0 rather than
// 0x8000_0000, the next if must remain an else if.
end else if (TESTSPERIPH) begin
end else if (TESTSPERIPH)
tests = tests64periph;
end else begin
else if (TESTSPRIV)
tests = tests64p;
else begin
tests = {tests64p,tests64i,tests64periph};
if (`C_SUPPORTED) tests = {tests, tests64ic};
else tests = {tests, tests64iNOc};
@ -531,9 +534,11 @@ string tests32f[] = '{
//tests = {tests64a, tests};
end else begin // RV32
// *** add the 32 bit bp tests
if (TESTSPERIPH) begin
if (TESTSPERIPH)
tests = tests32periph;
end else begin
else if (TESTSPRIV)
tests = tests32p;
else begin
tests = {tests32i, tests32p};//,tests32periph}; *** broken at the moment
if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic};
else tests = {tests, tests32iNOc};