FDIV merge

This commit is contained in:
David Harris 2022-12-22 23:03:03 -08:00
commit 74979cdc82
39 changed files with 2373 additions and 238 deletions

View File

@ -306,12 +306,12 @@ connect_debug_port u_ila_0/probe58 [get_nets [list wallypipelinedsoc/core/hzu/CS
create_debug_port u_ila_0 probe
set_property port_width 1 [get_debug_ports u_ila_0/probe59]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe59]
connect_debug_port u_ila_0/probe59 [get_nets [list wallypipelinedsoc/core/hzu/LSUStallM ]]
connect_debug_port u_ila_0/probe59 [get_nets [list wallypipelinedsoc/core/hzu/LSUStallW ]]
create_debug_port u_ila_0 probe
set_property port_width 1 [get_debug_ports u_ila_0/probe60]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe60]
connect_debug_port u_ila_0/probe60 [get_nets [list wallypipelinedsoc/core/hzu/IFUStallF ]]
connect_debug_port u_ila_0/probe60 [get_nets [list wallypipelinedsoc/core/hzu/IFUStallD ]]
create_debug_port u_ila_0 probe
set_property port_width 1 [get_debug_ports u_ila_0/probe61]

View File

@ -120,7 +120,7 @@
`define LOGR ((`RADIX==2) ? 32'h1 : 32'h2)
`define RK (`DIVCOPIES*`LOGR) // r*k used for intdiv preproc
`define LOGK ($clog2(`DIVCOPIES))
`define LOGRK ($clog2(`RADIX*`DIVCOPIES)) // log2(R*k)
`define LOGRK ($clog2(`RK)) // log2(r*k)
// FPDUR = ceil(DIVRESLEN/(LOGR*DIVCOPIES))
// one iteration is required for the integer bit for minimally redundent radix-4
`define FPDUR ((`DIVN+1+(`LOGR*`DIVCOPIES))/(`LOGR*`DIVCOPIES)+(`RADIX/4))

View File

@ -10,7 +10,7 @@ add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/Ret
add wave -noupdate -group HDU -expand -group hazards -color Pink /testbench/dut/core/hzu/TrapM
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/LoadStallD
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/StoreStallD
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/LSUStallM
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/LSUStallW
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/MDUStallD
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/DivBusyE
add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrMisalignedFaultM
@ -191,7 +191,7 @@ add wave -noupdate -expand -group AHB /testbench/dut/core/ebu/ebu/HWRITED
add wave -noupdate -expand -group lsu -color Gold /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/interlockfsm/InterlockCurrState
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/SelHPTW
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/InterlockStall
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/LSUStallM
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/LSUStallW
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/ReadDataWordMuxM
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/ReadDataM
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/WriteDataM

View File

@ -15,7 +15,7 @@ add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/core
add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/core/hzu/RetM
add wave -noupdate -expand -group HDU -expand -group hazards -color Pink /testbench/dut/core/hzu/TrapM
add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/core/hzu/LoadStallD
add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/core/hzu/LSUStallM
add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/core/hzu/LSUStallW
add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/core/hzu/DivBusyE
add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/ExceptionM
add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrMisalignedFaultM
@ -185,7 +185,7 @@ add wave -noupdate -group ifu -expand -group itlb /testbench/dut/core/ifu/immu/i
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/IEUAdrM
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/PAdrM
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/SelHPTW
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/LSUStallM
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/LSUStallW
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/ReadDataWordMuxM
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/ReadDataM
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/WriteDataM

View File

@ -9,8 +9,8 @@ add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/BPP
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/RetM
add wave -noupdate -group HDU -expand -group hazards -color Pink /testbench/dut/core/hzu/TrapM
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/LoadStallD
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/ifu/IFUStallF
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/LSUStallM
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/ifu/IFUStallD
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/LSUStallW
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/MDUStallD
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/DivBusyE
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/FDivBusyE
@ -41,12 +41,12 @@ add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/PostSpi
add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/InstrD
add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/InstrE
add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/InstrM
add wave -noupdate -group PCS /testbench/dut/core/ifu/PCNextF
add wave -noupdate -group PCS /testbench/dut/core/PCF
add wave -noupdate -group PCS /testbench/dut/core/ifu/PCD
add wave -noupdate -group PCS /testbench/dut/core/PCE
add wave -noupdate -group PCS /testbench/dut/core/PCM
add wave -noupdate -group PCS /testbench/PCW
add wave -noupdate -expand -group PCS /testbench/dut/core/ifu/PCNextF
add wave -noupdate -expand -group PCS /testbench/dut/core/PCF
add wave -noupdate -expand -group PCS /testbench/dut/core/ifu/PCD
add wave -noupdate -expand -group PCS /testbench/dut/core/PCE
add wave -noupdate -expand -group PCS /testbench/dut/core/PCM
add wave -noupdate -expand -group PCS /testbench/PCW
add wave -noupdate -group {Decode Stage} /testbench/dut/core/ifu/PCD
add wave -noupdate -group {Decode Stage} /testbench/dut/core/ifu/InstrD
add wave -noupdate -group {Decode Stage} /testbench/InstrDName
@ -218,7 +218,7 @@ add wave -noupdate -group AHB /testbench/dut/core/ebu/ebu/HPROT
add wave -noupdate -group AHB /testbench/dut/core/ebu/ebu/HTRANS
add wave -noupdate -group AHB /testbench/dut/core/ebu/ebu/HMASTLOCK
add wave -noupdate -group lsu /testbench/dut/core/lsu/SelHPTW
add wave -noupdate -group lsu /testbench/dut/core/lsu/LSUStallM
add wave -noupdate -group lsu /testbench/dut/core/lsu/LSUStallW
add wave -noupdate -group lsu /testbench/dut/core/lsu/ReadDataWordMuxM
add wave -noupdate -group lsu /testbench/dut/core/lsu/ReadDataM
add wave -noupdate -group lsu -radix hexadecimal /testbench/dut/core/lsu/WriteDataM
@ -411,24 +411,24 @@ add wave -noupdate -group lsu -group ptwalker -expand -group types /testbench/du
add wave -noupdate -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/DTLBMissM
add wave -noupdate -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/ITLBWriteF
add wave -noupdate -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/DTLBWriteM
add wave -noupdate -expand -group plic /testbench/dut/uncore/uncore/plic/plic/UARTIntr
add wave -noupdate -expand -group plic /testbench/dut/uncore/uncore/plic/plic/GPIOIntr
add wave -noupdate -expand -group plic /testbench/dut/uncore/uncore/plic/plic/MExtInt
add wave -noupdate -expand -group plic /testbench/dut/uncore/uncore/plic/plic/SExtInt
add wave -noupdate -expand -group plic /testbench/dut/uncore/uncore/plic/plic/Dout
add wave -noupdate -expand -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/intClaim
add wave -noupdate -expand -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/intEn
add wave -noupdate -expand -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/intInProgress
add wave -noupdate -expand -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/intPending
add wave -noupdate -expand -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/intPriority
add wave -noupdate -expand -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/intThreshold
add wave -noupdate -expand -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/nextIntPending
add wave -noupdate -expand -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/requests
add wave -noupdate -expand -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/irqMatrix
add wave -noupdate -expand -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/priorities_with_irqs
add wave -noupdate -expand -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/max_priority_with_irqs
add wave -noupdate -expand -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/irqs_at_max_priority
add wave -noupdate -expand -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/threshMask
add wave -noupdate -group plic /testbench/dut/uncore/uncore/plic/plic/UARTIntr
add wave -noupdate -group plic /testbench/dut/uncore/uncore/plic/plic/GPIOIntr
add wave -noupdate -group plic /testbench/dut/uncore/uncore/plic/plic/MExtInt
add wave -noupdate -group plic /testbench/dut/uncore/uncore/plic/plic/SExtInt
add wave -noupdate -group plic /testbench/dut/uncore/uncore/plic/plic/Dout
add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/intClaim
add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/intEn
add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/intInProgress
add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/intPending
add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/intPriority
add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/intThreshold
add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/nextIntPending
add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/requests
add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/irqMatrix
add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/priorities_with_irqs
add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/max_priority_with_irqs
add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/irqs_at_max_priority
add wave -noupdate -group plic -expand -group internals /testbench/dut/uncore/uncore/plic/plic/threshMask
add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/GPIOPinsIn
add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/GPIOPinsOut
add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/GPIOPinsEn
@ -615,8 +615,12 @@ add wave -noupdate -expand -group uncore /testbench/dut/uncore/uncore/HSELRegion
add wave -noupdate -expand -group uncore /testbench/dut/uncore/uncore/HSELNoneD
add wave -noupdate -expand -group uncore /testbench/dut/uncore/uncore/HSELPLICD
add wave -noupdate -expand -group uncore /testbench/dut/uncore/uncore/HRDATA
add wave -noupdate /testbench/ResetCount
add wave -noupdate /testbench/InReset
add wave -noupdate /testbench/DCacheFlushDone
add wave -noupdate /testbench/DCacheFlushStart
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 2} {314596 ns} 1} {{Cursor 3} {314460 ns} 1} {{Cursor 4} {219681 ns} 1} {{Cursor 4} {341201 ns} 1} {{Cursor 5} {471877 ns} 0}
WaveRestoreCursors {{Cursor 2} {314596 ns} 1} {{Cursor 3} {314460 ns} 1} {{Cursor 4} {219681 ns} 1} {{Cursor 4} {341201 ns} 1} {{Cursor 5} {128608 ns} 0}
quietly wave cursor active 5
configure wave -namecolwidth 250
configure wave -valuecolwidth 194
@ -632,4 +636,4 @@ configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ns
update
WaveRestoreZoom {471640 ns} {472086 ns}
WaveRestoreZoom {128173 ns} {130237 ns}

View File

@ -65,7 +65,7 @@ module busfsm
else NextState = ADR_PHASE;
DATA_PHASE: if(HREADY) NextState = MEM3;
else NextState = DATA_PHASE;
MEM3: if(Stall) NextState = MEM3;
MEM3: if(Stall) NextState = MEM3;
else NextState = ADR_PHASE;
default: NextState = ADR_PHASE;
endcase

View File

@ -66,13 +66,14 @@ module fdivsqrt(
logic WZeroM, AZeroM, BZeroM, AZeroE, BZeroE;
logic SpecialCaseM;
logic [`DIVBLEN:0] nE, nM, mM;
logic OTFCSwapE, ALTBM, As;
logic CalcOTFCSwapE, OTFCSwapE, ALTBM, As;
logic DivStartE;
logic [`XLEN-1:0] ForwardedSrcAM;
fdivsqrtpreproc fdivsqrtpreproc(
.clk, .IFDivStartE, .Xm(XmE), .QeM, .Xe(XeE), .Fmt(FmtE), .Ye(YeE),
.Sqrt(SqrtE), .Ym(YmE), .XZeroE, .X, .DPreproc,
.nE, .nM, .mM, .OTFCSwapE, .ALTBM, .AZeroM, .BZeroM, .AZeroE, .BZeroE, .As,
.Sqrt(SqrtE), .Ym(YmE), .XZeroE, .X, .DPreproc, .ForwardedSrcAM,
.nE, .nM, .mM, .CalcOTFCSwapE, .OTFCSwapE, .ALTBM, .AZeroM, .BZeroM, .AZeroE, .BZeroE, .As,
.ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .MDUE, .W64E);
fdivsqrtfsm fdivsqrtfsm(
.clk, .reset, .FmtE, .XsE, .SqrtE, .nE,
@ -83,11 +84,11 @@ module fdivsqrt(
fdivsqrtiter fdivsqrtiter(
.clk, .Firstun, .D, .FirstU, .FirstUM, .FirstC, .MDUE, .SqrtE, // .SqrtM,
.X,.DPreproc, .FirstWS(WS), .FirstWC(WC),
.IFDivStartE, .OTFCSwapE,
.IFDivStartE, .CalcOTFCSwapE, .OTFCSwapE,
.FDivBusyE);
fdivsqrtpostproc fdivsqrtpostproc(
.WS, .WC, .D, .FirstU, .FirstUM, .FirstC, .Firstun,
.SqrtM, .SpecialCaseM, .RemOpM(Funct3M[1]), .ForwardedSrcAE,
.nM, .ALTBM, .mM, .BZeroM, .As,
.SqrtM, .SpecialCaseM, .RemOpM(Funct3M[1]), .ForwardedSrcAM,
.nM, .ALTBM, .mM, .BZeroM, .As, .OTFCSwapEM(OTFCSwapE),
.QmM, .WZeroM, .DivSM, .FPIntDivResultM);
endmodule

View File

@ -103,7 +103,7 @@ module fdivsqrtfsm(
always_comb begin
if (SqrtE) fbits = Nf + 2 + 2; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2
else fbits = Nf + 2 + `LOGR; // Nf + two fractional bits for round/guard + integer bits - try this when placing results in msbs
cycles = MDUE ? nE : (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
cycles = MDUE ? (nE + 1) : (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
end
/* verilator lint_on WIDTH */

View File

@ -36,7 +36,7 @@ module fdivsqrtiter(
input logic FDivBusyE,
input logic SqrtE, MDUE,
// input logic SqrtM,
input logic OTFCSwapE,
input logic CalcOTFCSwapE, OTFCSwapE,
input logic [`DIVb+3:0] X,
input logic [`DIVb-1:0] DPreproc,
output logic [`DIVb-1:0] D,
@ -78,9 +78,9 @@ module fdivsqrtiter(
flopen #(`DIVb+4) wcreg(clk, FDivBusyE, WCN, WC[0]);
// UOTFC Result U and UM registers/initialization mux
// Initialize U to 1.0 and UM to 0 for square root; U to 0 and UM to -1 for division
assign initU = (SqrtE & ~(MDUE)) ? {1'b1, {(`DIVb){1'b0}}} : 0;
assign initUM = (SqrtE & ~(MDUE)) ? 0 : {1'b1, {(`DIVb){1'b0}}};
// Initialize U to 1.0 and UM to 0 for square root or negative-result int division; U to 0 and UM to -1 otherwise
assign initU = ((MDUE & CalcOTFCSwapE) | (SqrtE & ~(MDUE))) ? {1'b1, {(`DIVb){1'b0}}} : 0;
assign initUM = ((MDUE & CalcOTFCSwapE) | (SqrtE & ~(MDUE))) ? 0 : {1'b1, {(`DIVb){1'b0}}};
mux2 #(`DIVb+1) Umux(UNext[`DIVCOPIES-1], initU, IFDivStartE, UMux);
mux2 #(`DIVb+1) UMmux(UMNext[`DIVCOPIES-1], initUM, IFDivStartE, UMMux);
flopen #(`DIVb+1) UReg(clk, IFDivStartE|FDivBusyE, UMux, U[0]);

View File

@ -35,10 +35,8 @@ module fdivsqrtpostproc(
input logic [`DIVb-1:0] D,
input logic [`DIVb:0] FirstU, FirstUM,
input logic [`DIVb+1:0] FirstC,
input logic Firstun,
input logic SqrtM,
input logic SpecialCaseM,
input logic [`XLEN-1:0] ForwardedSrcAE,
input logic Firstun, SqrtM, SpecialCaseM, OTFCSwapEM,
input logic [`XLEN-1:0] ForwardedSrcAM,
input logic RemOpM, ALTBM, BZeroM, As,
input logic [`DIVBLEN:0] nM, mM,
output logic [`DIVb:0] QmM,
@ -54,7 +52,7 @@ module fdivsqrtpostproc(
logic [`DIVBLEN:0] NormShiftM;
logic [`DIVb:0] IntQuotM, NormQuotM;
logic [`DIVb+3:0] IntRemM, NormRemM;
logic [`DIVb+3:0] PreResultM, PreFPIntDivResultM;
logic signed [`DIVb+3:0] PreResultM, PreFPIntDivResultM;
// check for early termination on an exact result. If the result is not exact, the sticky should be set
aplusbeq0 #(`DIVb+4) wspluswceq0(WS, WC, weq0);
@ -106,12 +104,12 @@ module fdivsqrtpostproc(
// Integer division: Special cases
always_comb
if(ALTBM) begin
IntQuotM = '0;
IntRemM = {{(`DIVb-`XLEN+4){1'b0}}, ForwardedSrcAE};
end else if (BZeroM) begin
if (BZeroM) begin
IntQuotM = '1;
IntRemM = {{(`DIVb-`XLEN+4){1'b0}}, ForwardedSrcAE};
IntRemM = {{(`DIVb-`XLEN+4){1'b0}}, ForwardedSrcAM};
end else if (ALTBM) begin
IntQuotM = '0;
IntRemM = {{(`DIVb-`XLEN+4){1'b0}}, ForwardedSrcAM};
end else if (WZeroM) begin
if (weq0) begin
IntQuotM = FirstU;
@ -130,14 +128,19 @@ module fdivsqrtpostproc(
NormShiftM = (mM + (`DIVBLEN+1)'(`DIVa));
PreResultM = IntRemM;
end else begin
NormShiftM = ((`DIVBLEN+1)'(`DIVb) - (nM << `LOGR));
PreResultM = {3'b000, IntQuotM};
NormShiftM = ((`DIVBLEN+1)'(`DIVb) - (nM * (`DIVBLEN+1)'(`LOGR)));
if (BZeroM | (~ALTBM & OTFCSwapEM)) begin
PreResultM = {3'b111, IntQuotM};
end else begin
PreResultM = {3'b000, IntQuotM};
end
//PreResultM = {IntQuotM[`DIVb], IntQuotM[`DIVb], IntQuotM[`DIVb], IntQuotM}; // Suspicious Sign Extender
end
// division takes the result from the next cycle, which is shifted to the left one more time so the square root also needs to be shifted
assign PreFPIntDivResultM = ($signed(PreResultM) >>> NormShiftM) + {{(`DIVb+3){1'b0}}, (PostIncM & ~RemOpM)};
assign PreFPIntDivResultM = $signed(PreResultM >>> NormShiftM) + {{(`DIVb+3){1'b0}}, (PostIncM & ~RemOpM)};
assign FPIntDivResultM = PreFPIntDivResultM[`XLEN-1:0];
assign PreQmM = NegStickyM ? FirstUM : FirstU; // Select U or U-1 depending on negative sticky bit

View File

@ -42,10 +42,11 @@ module fdivsqrtpreproc (
input logic [2:0] Funct3E,
input logic MDUE, W64E,
output logic [`DIVBLEN:0] nE, nM, mM,
output logic OTFCSwapE, ALTBM, As, AZeroM, BZeroM, AZeroE, BZeroE,
output logic CalcOTFCSwapE, OTFCSwapE, ALTBM, As, AZeroM, BZeroM, AZeroE, BZeroE,
output logic [`NE+1:0] QeM,
output logic [`DIVb+3:0] X,
output logic [`DIVb-1:0] DPreproc
output logic [`DIVb-1:0] DPreproc,
output logic [`XLEN-1:0] ForwardedSrcAM
);
logic [`DIVb-1:0] XPreproc;
@ -55,12 +56,12 @@ module fdivsqrtpreproc (
// Intdiv signals
logic [`DIVb-1:0] IFNormLenX, IFNormLenD;
logic [`XLEN-1:0] PosA, PosB;
logic Bs, CalcOTFCSwapE, ALTBE;
logic Bs, ALTBE;
logic [`XLEN-1:0] A64, B64;
logic [`DIVBLEN:0] mE;
logic [`DIVBLEN:0] ZeroDiff, IntBits, RightShiftX;
logic [`DIVBLEN:0] pPlusr, pPrCeil, p, ell;
logic [`LOGRK-1:0] pPrTrunc;
logic [`LOGRK:0] pPrTrunc;
logic [`DIVb+3:0] PreShiftX;
logic NumZeroE;
@ -91,12 +92,16 @@ module fdivsqrtpreproc (
assign ALTBE = ZeroDiff[`DIVBLEN]; // A less than B
assign p = ALTBE ? '0 : ZeroDiff;
/* verilator lint_off WIDTH */
assign pPlusr = (`DIVBLEN)'(`LOGR) + p;
assign pPrTrunc = pPlusr[`LOGRK-1:0];
assign pPrTrunc = pPlusr % `RK;
//assign pPrTrunc = (`LOGRK == 0) ? 0 : pPlusr[`LOGRK-1:0];
assign pPrCeil = (pPlusr >> `LOGRK) + {{`DIVBLEN{1'b0}}, |(pPrTrunc)};
assign nE = (pPrCeil << `LOGK) - 1;
assign IntBits = (`DIVBLEN)'(`RK) + p;
assign RightShiftX = (`DIVBLEN)'(`RK) - {{(`DIVBLEN-`RK){1'b0}}, IntBits[`RK-1:0]};
assign nE = (pPrCeil * (`DIVBLEN+1)'(`DIVCOPIES)) - {{(`DIVBLEN){1'b0}}, 1'b1};
assign IntBits = (`DIVBLEN)'(`LOGR) + p - {{(`DIVBLEN){1'b0}}, 1'b1};
assign RightShiftX = ((`DIVBLEN)'(`RK) - 1) - (IntBits % `RK);
//assign RightShiftX = (`LOGRK == 0) ? 0 : ((`DIVBLEN)'(`RK) - 1) - {{(`DIVBLEN - `RK){1'b0}}, IntBits[`LOGRK-1:0]};
/* verilator lint_on WIDTH */
assign NumZeroE = MDUE ? AZeroE : XZeroE;
@ -125,7 +130,7 @@ module fdivsqrtpreproc (
flopen #(1) bzeroreg(clk, IFDivStartE, BZeroE, BZeroM);
flopen #(`DIVBLEN+1) nreg(clk, IFDivStartE, nE, nM);
flopen #(`DIVBLEN+1) mreg(clk, IFDivStartE, mE, mM);
//flopen #(`XLEN) srcareg(clk, IFDivStartE, ForwardedSrcAE, ForwardedSrcAM); //HERE
flopen #(`XLEN) srcareg(clk, IFDivStartE, ForwardedSrcAE, ForwardedSrcAM);
expcalc expcalc(.Fmt, .Xe, .Ye, .Sqrt, .XZeroE, .ell, .m(mE), .Qe(QeE));
endmodule

View File

@ -32,7 +32,6 @@
module fdivsqrtqsel2 (
input logic [3:0] ps, pc,
input logic swap,
output logic up, uz, un
);
@ -56,11 +55,7 @@ module fdivsqrtqsel2 (
(ps[0]&pc[0])))));
// Produce digit = +1, 0, or -1
assign pos = magnitude & ~sign;
assign up = magnitude & ~sign;
assign uz = ~magnitude;
assign neg = magnitude & sign;
// Check for swap (int div only)
assign un = swap ? pos : neg;
assign up = swap ? neg : pos;
assign un = magnitude & sign;
endmodule

View File

@ -34,7 +34,7 @@ module fdivsqrtqsel4cmp (
input logic [2:0] Dmsbs,
input logic [4:0] Smsbs,
input logic [7:0] WSmsbs, WCmsbs,
input logic SqrtE, j1, OTFCSwapE, MDUE,
input logic SqrtE, j1, MDUE,
output logic [3:0] udigit
);
logic [6:0] Wmsbs;
@ -86,12 +86,9 @@ module fdivsqrtqsel4cmp (
// Compare residual W to selection constants to choose digit
always_comb
if ($signed(Wmsbs) >= $signed(mk2)) udigitsel = 4'b1000; // choose 2
else if ($signed(Wmsbs) >= $signed(mk1)) udigitsel = 4'b0100; // choose 1
else if ($signed(Wmsbs) >= $signed(mk0)) udigitsel = 4'b0000; // choose 0
else if ($signed(Wmsbs) >= $signed(mkm1)) udigitsel = 4'b0010; // choose -1
else udigitsel = 4'b0001; // choose -2
assign udigitswap = {udigitsel[0], udigitsel[1], udigitsel[2], udigitsel[3]};
assign udigit = OTFCSwapE ? udigitswap : udigitsel;
if ($signed(Wmsbs) >= $signed(mk2)) udigit = 4'b1000; // choose 2
else if ($signed(Wmsbs) >= $signed(mk1)) udigit = 4'b0100; // choose 1
else if ($signed(Wmsbs) >= $signed(mk0)) udigit = 4'b0000; // choose 0
else if ($signed(Wmsbs) >= $signed(mkm1)) udigit = 4'b0010; // choose -1
else udigit = 4'b0001; // choose -2
endmodule

View File

@ -60,7 +60,7 @@ module fdivsqrtstage2 (
// 0000 = 0
// 0010 = -1
// 0001 = -2
fdivsqrtqsel2 qsel2(WS[`DIVb+3:`DIVb], WC[`DIVb+3:`DIVb], OTFCSwapE, up, uz, un);
fdivsqrtqsel2 qsel2(WS[`DIVb+3:`DIVb], WC[`DIVb+3:`DIVb], up, uz, un);
// Sqrt F generation
fdivsqrtfgen2 fgen2(.up, .uz, .C(CNext), .U, .UM, .F);
@ -82,7 +82,7 @@ module fdivsqrtstage2 (
assign CNext = {1'b1, C[`DIVb+1:1]};
// Unified On-The-Fly Converter to accumulate result
fdivsqrtuotfc2 uotfc2(.up, .uz, .C(CNext), .U, .UM, .UNext, .UMNext);
fdivsqrtuotfc2 uotfc2(.up, .un, .swap(OTFCSwapE), .C(CNext), .U, .UM, .UNext, .UMNext);
endmodule

View File

@ -65,7 +65,7 @@ module fdivsqrtstage4 (
assign WCmsbs = WC[`DIVb+3:`DIVb-4];
assign WSmsbs = WS[`DIVb+3:`DIVb-4];
fdivsqrtqsel4cmp qsel4(.Dmsbs, .Smsbs, .WSmsbs, .WCmsbs, .SqrtE, .j1, .udigit, .OTFCSwapE, .MDUE);
fdivsqrtqsel4cmp qsel4(.Dmsbs, .Smsbs, .WSmsbs, .WCmsbs, .SqrtE, .j1, .udigit, .MDUE);
assign un = 1'b0; // unused for radix 4
// F generation logic
@ -94,7 +94,7 @@ module fdivsqrtstage4 (
assign CNext = {2'b11, C[`DIVb+1:2]};
// On-the-fly converter to accumulate result
fdivsqrtuotfc4 fdivsqrtuotfc4(.udigit, .Sqrt(SqrtE), .C(CNext[`DIVb:0]), .U, .UM, .UNext, .UMNext);
fdivsqrtuotfc4 fdivsqrtuotfc4(.udigit, .swap(OTFCSwapE), .Sqrt(SqrtE), .C(CNext[`DIVb:0]), .U, .UM, .UNext, .UMNext);
endmodule

View File

@ -34,7 +34,7 @@
// Unified OTFC, Radix 2 //
///////////////////////////////
module fdivsqrtuotfc2(
input logic up, uz,
input logic up, un, swap,
input logic [`DIVb+1:0] C,
input logic [`DIVb:0] U, UM,
output logic [`DIVb:0] UNext, UMNext
@ -42,20 +42,24 @@ module fdivsqrtuotfc2(
// The on-the-fly converter transfers the divsqrt
// bits to the quotient as they come.
logic [`DIVb:0] K;
logic unSwap, upSwap;
// Check for swap (int div only)
assign unSwap = swap ? up : un;
assign upSwap = swap ? un : up;
assign K = (C[`DIVb:0] & ~(C[`DIVb:0] << 1));
always_comb begin
if (up) begin
if (upSwap) begin
UNext = U | K;
UMNext = U;
end else if (uz) begin
UNext = U;
UMNext = UM | K;
end else begin // If up and uz are not true, then un is
end else if (unSwap) begin
UNext = UM | K;
UMNext = UM;
end
end else begin // If up and un are not true, then uz is
UNext = U;
UMNext = UM | K;
end
end
endmodule

View File

@ -32,7 +32,7 @@
module fdivsqrtuotfc4(
input logic [3:0] udigit,
input logic Sqrt,
input logic Sqrt, swap,
input logic [`DIVb:0] U, UM,
input logic [`DIVb:0] C,
output logic [`DIVb:0] UNext, UMNext
@ -41,25 +41,29 @@ module fdivsqrtuotfc4(
// bits to the quotient as they come.
// Use this otfc for division and square root.
logic [3:0] udigitswap, udigitsel;
logic [`DIVb:0] K1, K2, K3;
assign K1 = (C&~(C << 1)); // K
assign K2 = ((C << 1)&~(C << 2)); // 2K
assign K3 = (C & ~(C << 2)); // 3K
assign udigitswap = {udigit[0], udigit[1], udigit[2], udigit[3]};
assign udigitsel = swap ? udigitswap : udigit;
always_comb begin
if (udigit[3]) begin
if (udigitsel[3]) begin // +2
UNext = U | K2;
UMNext = U | K1;
end else if (udigit[2]) begin
end else if (udigitsel[2]) begin // +1
UNext = U | K1;
UMNext = U;
end else if (udigit[1]) begin
end else if (udigitsel[1]) begin // -1
UNext = UM | K3;
UMNext = UM | K2;
end else if (udigit[0]) begin
end else if (udigitsel[0]) begin // -2
UNext = UM | K2;
UMNext = UM | K1;
end else begin // udigit = 0
end else begin // 0
UNext = U;
UMNext = UM | K3;
end

View File

@ -34,7 +34,7 @@ module hazard(
// Detect hazards
(* mark_debug = "true" *) input logic BPPredWrongE, CSRWriteFenceM, RetM, TrapM,
(* mark_debug = "true" *) input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD,
(* mark_debug = "true" *) input logic LSUStallM, IFUStallF,
(* mark_debug = "true" *) input logic LSUStallW, IFUStallD,
(* mark_debug = "true" *) input logic FCvtIntStallD, FPUStallD,
(* mark_debug = "true" *) input logic DivBusyE,FDivBusyE,
(* mark_debug = "true" *) input logic EcallFaultM, BreakpointFaultM,
@ -86,7 +86,8 @@ module hazard(
assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause;
// WFI terminates if any enabled interrupt is pending, even if global interrupts are disabled. It could also terminate with TW trap
assign StallMCause = ((wfiM) & (~TrapM & ~IntPendingM));
assign StallWCause = (IFUStallF | LSUStallM) & ~TrapM;
//assign StallWCause = (IFUStallD | LSUStallW) & ~TrapM;
assign StallWCause = (IFUStallD & ~FlushDCause) | (LSUStallW & ~FlushWCause);
// Stall each stage for cause or if the next stage is stalled
assign #1 StallF = StallFCause | StallD;

Binary file not shown.

View File

@ -33,38 +33,36 @@
`include "wally-config.vh"
module bpred
(input logic clk, reset,
module bpred (
input logic clk, reset,
input logic StallF, StallD, StallE, StallM,
input logic FlushD, FlushE, FlushM,
// Fetch stage
// the prediction
input logic [31:0] InstrD,
input logic [`XLEN-1:0] PCNextF, // *** forgot to include this one on the I/O list
input logic [`XLEN-1:0] PCPlus2or4F,
output logic [`XLEN-1:0] PCNext1F,
output logic [`XLEN-1:0] NextValidPCE, // The address of the currently executing instruction
input logic [31:0] InstrD, // Decompressed decode stage instruction
input logic [`XLEN-1:0] PCNextF, // Next Fetch Address
input logic [`XLEN-1:0] PCPlus2or4F, // PCF+2/4
output logic [`XLEN-1:0] PCNext1F, // Branch Predictor predicted or corrected fetch address on miss prediction
output logic [`XLEN-1:0] NextValidPCE, // Address of next valid instruction after the instruction in the Memory stage.
// Update Predictor
input logic [`XLEN-1:0] PCE, // The address of the currently executing instruction
input logic [`XLEN-1:0] PCF, // The address of the currently executing instruction
input logic [`XLEN-1:0] PCF, // Fetch stage instruction address.
input logic [`XLEN-1:0] PCD, // Decode stage instruction address. Also the address the branch predictor took.
input logic [`XLEN-1:0] PCE, // Execution stage instruction address.
// 1 hot encoding
// return, jump register, jump, branch
// *** after reviewing the compressed instruction set I am leaning towards having the btb predict the instruction class.
// *** the specifics of how this is encode is subject to change.
input logic PCSrcE, // AKA Branch Taken
// Signals required to check the branch prediction accuracy.
input logic [`XLEN-1:0] IEUAdrE, // The branch destination if the branch is taken.
input logic [`XLEN-1:0] PCD, // The address the branch predictor took.
input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
output logic [4:0] InstrClassM,
input logic PCSrcE, // Executation stage branch is taken
input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address
input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
output logic [4:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
// Report branch prediction status
output logic BPPredWrongE,
output logic BPPredDirWrongM,
output logic BTBPredPCWrongM,
output logic RASPredPCWrongM,
output logic BPPredClassNonCFIWrongM
output logic BPPredWrongE, // Prediction is wrong.
output logic BPPredDirWrongM, // Prediction direction is wrong.
output logic BTBPredPCWrongM, // Prediction target wrong.
output logic RASPredPCWrongM, // RAS prediction is wrong.
output logic BPPredClassNonCFIWrongM // Class prediction is wrong.
);
logic BTBValidF;
@ -126,13 +124,11 @@ module bpred
// 1) A direction (1 = Taken, 0 = Not Taken)
// 2) Any information which is necessary for the predictor to build its next state.
// For a 2 bit table this is the prediction count.
assign SelBPPredF = ((BPInstrClassF[0] & BPPredF[1] & BTBValidF) |
BPInstrClassF[3] |
(BPInstrClassF[2] & BTBValidF) |
BPInstrClassF[1] & BTBValidF) ;
// Part 2 Branch target address prediction
// *** For now the BTB will house the direct and indirect targets
@ -162,12 +158,10 @@ module bpred
.pushPC(PCLinkE));
assign BPPredPCF = BPInstrClassF[3] ? RASPCF : BTBPredPCF;
// The prediction and its results need to be passed through the pipeline
// *** for other predictors will will be different.
// *** should these be flushed?
flopenr #(2) BPPredRegD(.clk(clk),
.reset(reset),
.en(~StallD),
@ -188,37 +182,20 @@ module bpred
assign InstrClassD[2] = InstrD[6:0] == 7'h67 & (InstrD[19:15] & 5'h1B) != 5'h01 & (InstrD[11:7] & 5'h1B) != 5'h01; // jump register, but not return
assign InstrClassD[1] = InstrD[6:0] == 7'h6F & (InstrD[11:7] & 5'h1B) != 5'h01; // jump, RD != x1 or x5
assign InstrClassD[0] = InstrD[6:0] == 7'h63; // branch
flopenrc #(5) InstrClassRegE(.clk, .reset, .en(~StallE), .clear(FlushE), .d(InstrClassD), .q(InstrClassE));
flopenrc #(5) InstrClassRegM(.clk, .reset, .en(~StallM), .clear(FlushM), .d(InstrClassE), .q(InstrClassM));
flopenrc #(1) BPPredWrongMReg(.clk, .reset, .en(~StallM), .clear(FlushM), .d(BPPredWrongE), .q(BPPredWrongM));
flopenrc #(5) InstrClassRegE(clk, reset, FlushE, ~StallE, InstrClassD, InstrClassE);
flopenrc #(5) InstrClassRegM(clk, reset, FlushM, ~StallM, InstrClassE, InstrClassM);
flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM);
// branch predictor
flopenrc #(4) BPPredWrongRegM(.clk, .reset, .en(~StallM), .clear(FlushM),
.d({BPPredDirWrongE, BTBPredPCWrongE, RASPredPCWrongE, BPPredClassNonCFIWrongE}),
.q({BPPredDirWrongM, BTBPredPCWrongM, RASPredPCWrongM, BPPredClassNonCFIWrongM}));
flopenrc #(4) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
{BPPredDirWrongE, BTBPredPCWrongE, RASPredPCWrongE, BPPredClassNonCFIWrongE},
{BPPredDirWrongM, BTBPredPCWrongM, RASPredPCWrongM, BPPredClassNonCFIWrongM});
// pipeline the class
flopenrc #(5) BPInstrClassRegD(.clk(clk),
.reset(reset),
.en(~StallD),
.clear(FlushD),
.d(BPInstrClassF),
.q(BPInstrClassD));
flopenrc #(5) BPInstrClassRegE(.clk(clk),
.reset(reset),
.en(~StallE),
.clear(FlushE),
.d(BPInstrClassD),
.q(BPInstrClassE));
// Check the prediction makes execution.
flopenrc #(5) BPInstrClassRegD(clk, reset, FlushD, ~StallD, BPInstrClassF, BPInstrClassD);
flopenrc #(5) BPInstrClassRegE(clk, reset, FlushE, ~StallE, BPInstrClassD, BPInstrClassE);
// Check the prediction
// first check if the target or fallthrough address matches what was predicted.
assign TargetWrongE = IEUAdrE != PCD;
assign FallThroughWrongE = PCLinkE != PCD;
@ -239,10 +216,6 @@ module bpred
// We want to output to the instruction fetch if the PC fetched was wrong. If by chance the predictor was wrong about
// the direction or class, but correct about the target we don't have the flush the pipeline. However we still
// need this information to verify the accuracy of the predictors.
//assign BPPredWrongE = ((PredictionPCWrongE | BPPredDirWrongE) & (|InstrClassE)) | PredictionInstrClassWrongE;
assign BPPredWrongE = (PredictionPCWrongE & |InstrClassE) | BPPredClassNonCFIWrongE;
// If we have a jump, jump register or jal or jalr and the PC is wrong we need to increment the performance counter.
@ -252,35 +225,22 @@ module bpred
// Finally if the real instruction class is non CFI but the predictor said it was we need to count.
assign BPPredClassNonCFIWrongE = PredictionInstrClassWrongE & ~|InstrClassE;
// Update predictors
satCounter2 BPDirUpdate(.BrDir(PCSrcE),
.OldState(BPPredE),
.NewState(UpdateBPPredE));
// 2 bit saturating counter
satCounter2 BPDirUpdate(.BrDir(PCSrcE), .OldState(BPPredE), .NewState(UpdateBPPredE));
// Selects the BP or PC+2/4.
mux2 #(`XLEN) pcmux0(.d0(PCPlus2or4F), .d1(BPPredPCF), .s(SelBPPredF), .y(PCNext0F));
mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPredPCF, SelBPPredF, PCNext0F);
// If the prediction is wrong select the correct address.
mux2 #(`XLEN) pcmux1(.d0(PCNext0F), .d1(PCCorrectE), .s(BPPredWrongE), .y(PCNext1F));
mux2 #(`XLEN) pcmux1(PCNext0F, PCCorrectE, BPPredWrongE, PCNext1F);
// Correct branch/jump target.
mux2 #(`XLEN) pccorrectemux(.d0(PCLinkE), .d1(IEUAdrE), .s(PCSrcE), .y(PCCorrectE));
mux2 #(`XLEN) pccorrectemux(PCLinkE, IEUAdrE, PCSrcE, PCCorrectE);
// If the fence/csrw was predicted as a taken branch then we select PCF, rather PCE.
// could also just use PCM+4, or PCLinkM
// ONLY valid for class prediction. add option for class prediction.
// if(`BPCLASS) begin
mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(.d0(PCE), .d1(PCF), .s(BPPredWrongM), .y(NextValidPCE));
// end else begin
// assign NextValidPCE = PCE;
// end
// Effectively this is PCM+4 or the non-existant PCLinkM
// if(`BPCLASS) begin
mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPPredWrongM, NextValidPCE);
// end else begin
// assign NextValidPCE = PCE;
// end
//logic [`XLEN-1:0] PCLinkM;
//flopenr #(`XLEN) PCPEReg(clk, reset, ~StallM, PCLinkE, PCLinkM);
//assign NextValidPCE = PCLinkM;
// of the three, the mux is the cheapest, but the least clear.
// this could move entirely into ifu with no relation to bp with the third.
endmodule

View File

@ -38,7 +38,7 @@ module ifu (
// Bus interface
(* mark_debug = "true" *) input logic [`XLEN-1:0] HRDATA,
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] IFUHADDR,
(* mark_debug = "true" *) output logic IFUStallF,
(* mark_debug = "true" *) output logic IFUStallD,
(* mark_debug = "true" *) output logic [2:0] IFUHBURST,
(* mark_debug = "true" *) output logic [1:0] IFUHTRANS,
(* mark_debug = "true" *) output logic [2:0] IFUHSIZE,
@ -113,7 +113,7 @@ module ifu (
logic SelNextSpillF;
logic ICacheFetchLine;
logic BusStall;
logic ICacheStallF, IFUCacheBusStallF;
logic ICacheStallF, IFUCacheBusStallD;
logic GatedStallD;
(* mark_debug = "true" *) logic [31:0] PostSpillInstrRawF;
// branch predictor signal
@ -121,8 +121,6 @@ module ifu (
logic BusCommittedF, CacheCommittedF;
logic SelIROM;
assign PCFExt = {2'b00, PCFSpill};
/////////////////////////////////////////////////////////////////////////////////////////////
@ -130,9 +128,8 @@ module ifu (
/////////////////////////////////////////////////////////////////////////////////////////////
if(`C_SUPPORTED) begin : SpillSupport
spillsupport #(`ICACHE) spillsupport(.clk, .reset, .StallF, .Flush(TrapM), .PCF, .PCPlus4F, .PCNextF, .InstrRawF(InstrRawF),
.InstrDAPageFaultF, .IFUCacheBusStallF, .ITLBMissF, .PCNextFSpill, .PCFSpill,
spillsupport #(`ICACHE) spillsupport(.clk, .reset, .StallF, .Flush(FlushD), .PCF, .PCPlus4F, .PCNextF, .InstrRawF(InstrRawF),
.InstrDAPageFaultF, .IFUCacheBusStallD, .ITLBMissF, .PCNextFSpill, .PCFSpill,
.SelNextSpillF, .PostSpillInstrRawF, .CompressedF);
end else begin : NoSpillSupport
assign PCNextFSpill = PCNextF;
@ -222,7 +219,7 @@ module ifu (
cache #(.LINELEN(`ICACHE_LINELENINBITS),
.NUMLINES(`ICACHE_WAYSIZEINBYTES*8/`ICACHE_LINELENINBITS),
.NUMWAYS(`ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .DCACHE(0))
icache(.clk, .reset, .FlushStage(TrapM), .Stall(GatedStallD),
icache(.clk, .reset, .FlushStage(FlushD), .Stall(GatedStallD),
.FetchBuffer, .CacheBusAck(ICacheBusAck),
.CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF),
.CacheBusRW,
@ -239,7 +236,7 @@ module ifu (
ahbcacheinterface #(WORDSPERLINE, LINELEN, LOGBWPL, `ICACHE)
ahbcacheinterface(.HCLK(clk), .HRESETn(~reset),
.HRDATA,
.Flush(TrapM), .CacheBusRW, .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .HWSTRB(),
.Flush(FlushD), .CacheBusRW, .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .HWSTRB(),
.Funct3(3'b010), .HADDR(IFUHADDR), .HREADY(IFUHREADY), .HWRITE(IFUHWRITE), .CacheBusAdr(ICacheBusAdr),
.BeatCount(), .Cacheable(CacheableF), .SelBusBeat(), .WriteDataM('0),
.CacheBusAck(ICacheBusAck), .HWDATA(), .CacheableOrFlushCacheM(1'b0), .CacheReadDataWordM('0),
@ -258,7 +255,7 @@ module ifu (
// assign BusRW = IFURWF & ~{IgnoreRequest, IgnoreRequest} & ~{SelIROM, SelIROM};
assign IFUHSIZE = 3'b010;
ahbinterface #(0) ahbinterface(.HCLK(clk), .Flush(TrapM), .HRESETn(~reset), .HREADY(IFUHREADY),
ahbinterface #(0) ahbinterface(.HCLK(clk), .Flush(FlushD), .HRESETn(~reset), .HREADY(IFUHREADY),
.HRDATA(HRDATA), .HTRANS(IFUHTRANS), .HWRITE(IFUHWRITE), .HWDATA(),
.HWSTRB(), .BusRW, .ByteMask(), .WriteData('0),
.Stall(GatedStallD), .BusStall, .BusCommitted(BusCommittedF), .FetchBuffer(FetchBuffer));
@ -276,8 +273,8 @@ module ifu (
assign InstrRawF = IROMInstrF;
end
assign IFUCacheBusStallF = ICacheStallF | BusStall;
assign IFUStallF = IFUCacheBusStallF | SelNextSpillF;
assign IFUCacheBusStallD = ICacheStallF | BusStall;
assign IFUStallD = IFUCacheBusStallD | SelNextSpillF;
assign GatedStallD = StallD & ~SelNextSpillF;
flopenl #(32) AlignedInstrRawDFlop(clk, reset | FlushD, ~StallD, PostSpillInstrRawF, nop, InstrRawD);

View File

@ -40,7 +40,7 @@ module spillsupport #(parameter CACHE_ENABLED)
input logic [`XLEN-1:2] PCPlus4F,
input logic [`XLEN-1:0] PCNextF,
input logic [31:0] InstrRawF,
input logic IFUCacheBusStallF,
input logic IFUCacheBusStallD,
input logic ITLBMissF,
input logic InstrDAPageFaultF,
output logic [`XLEN-1:0] PCNextFSpill,
@ -67,7 +67,7 @@ module spillsupport #(parameter CACHE_ENABLED)
mux2 #(`XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCFSpill));
assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1];
assign TakeSpillF = SpillF & ~IFUCacheBusStallF & ~(ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF));
assign TakeSpillF = SpillF & ~IFUCacheBusStallD & ~(ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF));
always_ff @(posedge clk)
if (reset | Flush) CurrState <= #1 STATE_READY;
@ -77,7 +77,7 @@ module spillsupport #(parameter CACHE_ENABLED)
case (CurrState)
STATE_READY: if (TakeSpillF) NextState = STATE_SPILL;
else NextState = STATE_READY;
STATE_SPILL: if(IFUCacheBusStallF | StallF) NextState = STATE_SPILL;
STATE_SPILL: if(IFUCacheBusStallD | StallF) NextState = STATE_SPILL;
else NextState = STATE_READY;
default: NextState = STATE_READY;
endcase
@ -85,7 +85,7 @@ module spillsupport #(parameter CACHE_ENABLED)
assign SelSpillF = (CurrState == STATE_SPILL);
assign SelNextSpillF = (CurrState == STATE_READY & TakeSpillF) |
(CurrState == STATE_SPILL & IFUCacheBusStallF);
(CurrState == STATE_SPILL & IFUCacheBusStallD);
assign SpillSaveF = (CurrState == STATE_READY) & TakeSpillF;
assign SavedInstr = CACHE_ENABLED ? InstrRawF[15:0] : InstrRawF[31:16];

View File

@ -40,7 +40,7 @@
module lsu (
input logic clk, reset,
input logic StallM, FlushM, StallW, FlushW,
output logic LSUStallM,
output logic LSUStallW,
// connected to cpu (controls)
input logic [1:0] MemRWM,
input logic [2:0] Funct3M,
@ -103,7 +103,7 @@ module lsu (
logic [1:0] LSUAtomicM;
(* mark_debug = "true" *) logic [`XLEN+1:0] IHAdrM;
logic GatedStallW;
logic DCacheStallM;
logic DCacheStallW;
logic CacheableM;
logic BusStall;
logic HPTWStall;
@ -120,7 +120,7 @@ module lsu (
flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM);
assign IEUAdrExtM = {2'b00, IEUAdrM};
assign IEUAdrExtE = {2'b00, IEUAdrE};
assign LSUStallM = DCacheStallM | HPTWStall | BusStall;
assign LSUStallW = DCacheStallW | HPTWStall | BusStall;
/////////////////////////////////////////////////////////////////////////////////////////////
// HPTW(only needed if VM supported)
@ -130,7 +130,7 @@ module lsu (
if(`VIRTMEM_SUPPORTED) begin : VIRTMEM_SUPPORTED
hptw hptw(.clk, .reset, .MemRWM, .AtomicM, .ITLBMissF, .ITLBWriteF,
.DTLBMissM, .DTLBWriteM, .InstrDAPageFaultF, .DataDAPageFaultM,
.FlushW, .DCacheStallM, .SATP_REGW, .PCF,
.FlushW, .DCacheStallW, .SATP_REGW, .PCF,
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW,
.ReadDataM(ReadDataM[`XLEN-1:0]), .WriteDataM, .Funct3M, .LSUFunct3M, .Funct7M, .LSUFunct7M,
.IEUAdrExtM, .PTE, .IHWriteDataM, .PageType, .PreLSURWM, .LSUAtomicM,
@ -257,7 +257,7 @@ module lsu (
.FlushCache(CacheFlushM), .NextAdr(IEUAdrE[11:0]), .PAdr(PAdrM),
.ByteMask(ByteMaskM), .BeatCount(BeatCount[AHBWLOGBWPL-1:AHBWLOGBWPL-LLENLOGBWPL]),
.CacheWriteData(LSUWriteDataM), .SelHPTW,
.CacheStall(DCacheStallM), .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess),
.CacheStall(DCacheStallW), .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess),
.CacheCommitted(DCacheCommittedM),
.CacheBusAdr(DCacheBusAdr), .ReadDataWord(DCacheReadDataWordM),
.FetchBuffer, .CacheBusRW,
@ -296,14 +296,14 @@ module lsu (
if(`DTIM_SUPPORTED) mux2 #(`XLEN) ReadDataMux2(FetchBuffer, DTIMReadDataWordM, SelDTIM, ReadDataWordMuxM);
else assign ReadDataWordMuxM = FetchBuffer[`XLEN-1:0];
assign LSUHBURST = 3'b0;
assign {DCacheStallM, DCacheCommittedM, DCacheMiss, DCacheAccess} = '0;
assign {DCacheStallW, DCacheCommittedM, DCacheMiss, DCacheAccess} = '0;
end
end else begin: nobus // block: bus
assign LSUHWDATA = '0;
assign ReadDataWordMuxM = DTIMReadDataWordM;
assign {BusStall, BusCommittedM} = '0;
assign {DCacheMiss, DCacheAccess} = '0;
assign {DCacheStallM, DCacheCommittedM} = '0;
assign {DCacheStallW, DCacheCommittedM} = '0;
end
/////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -42,7 +42,7 @@ module hptw (
input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] ReadDataM, // page table entry from LSU
input logic [`XLEN-1:0] WriteDataM,
input logic DCacheStallM, // stall from LSU
input logic DCacheStallW, // stall from LSU
input logic [2:0] Funct3M,
input logic [6:0] Funct7M,
input logic ITLBMissF,
@ -117,7 +117,7 @@ module hptw (
// State flops
flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissOrDAFaultM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB)
assign PRegEn = HPTWRW[1] & ~DCacheStallM | UpdatePTE;
assign PRegEn = HPTWRW[1] & ~DCacheStallW | UpdatePTE;
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache
@ -254,24 +254,24 @@ module hptw (
IDLE: if (TLBMiss) NextWalkerState = InitialWalkerState;
else NextWalkerState = IDLE;
L3_ADR: NextWalkerState = L3_RD; // first access in SV48
L3_RD: if (DCacheStallM) NextWalkerState = L3_RD;
L3_RD: if (DCacheStallW) NextWalkerState = L3_RD;
else NextWalkerState = L2_ADR;
L2_ADR: if (InitialWalkerState == L2_ADR | ValidNonLeafPTE) NextWalkerState = L2_RD; // first access in SV39
else NextWalkerState = LEAF;
L2_RD: if (DCacheStallM) NextWalkerState = L2_RD;
L2_RD: if (DCacheStallW) NextWalkerState = L2_RD;
else NextWalkerState = L1_ADR;
L1_ADR: if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32
else if (ValidNonLeafPTE) NextWalkerState = L1_RD;
else NextWalkerState = LEAF;
L1_RD: if (DCacheStallM) NextWalkerState = L1_RD;
L1_RD: if (DCacheStallW) NextWalkerState = L1_RD;
else NextWalkerState = L0_ADR;
L0_ADR: if (ValidNonLeafPTE) NextWalkerState = L0_RD;
else NextWalkerState = LEAF;
L0_RD: if (DCacheStallM) NextWalkerState = L0_RD;
L0_RD: if (DCacheStallW) NextWalkerState = L0_RD;
else NextWalkerState = LEAF;
LEAF: if (`HPTW_WRITES_SUPPORTED & DAPageFault) NextWalkerState = UPDATE_PTE;
else NextWalkerState = IDLE;
UPDATE_PTE: if(DCacheStallM) NextWalkerState = UPDATE_PTE;
UPDATE_PTE: if(DCacheStallW) NextWalkerState = UPDATE_PTE;
else NextWalkerState = LEAF;
default: NextWalkerState = IDLE; // should never be reached
endcase // case (WalkerState)
@ -306,5 +306,5 @@ module hptw (
endmodule
// another idea. We keep gating the control by ~FlushW, but this adds considerable length to the critical path.
// should we do this differently? For example TLBMiss is gated by ~FlushW and then drives HPTWStall, which drives LSUStallM, which drives
// should we do this differently? For example TLBMiss is gated by ~FlushW and then drives HPTWStall, which drives LSUStallW, which drives
// the hazard unit to issue stall and flush controlls. ~FlushW already suppresses these in the hazard unit.

View File

@ -119,8 +119,8 @@ module wallypipelinedcore (
var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0];
// IMem stalls
logic IFUStallF;
logic LSUStallM;
logic IFUStallD;
logic LSUStallW;
@ -174,7 +174,7 @@ module wallypipelinedcore (
.FlushD, .FlushE, .FlushM, .FlushW,
// Fetch
.HRDATA, .PCF, .IFUHADDR, .PCNext2F,
.IFUStallF, .IFUHBURST, .IFUHTRANS, .IFUHSIZE,
.IFUStallD, .IFUHBURST, .IFUHTRANS, .IFUHSIZE,
.IFUHREADY, .IFUHWRITE,
.ICacheAccess, .ICacheMiss,
@ -247,7 +247,7 @@ module wallypipelinedcore (
lsu lsu(
.clk, .reset, .StallM, .FlushM, .StallW,
.FlushW(TrapM),
.FlushW,
// CPU interface
.MemRWM, .Funct3M, .Funct7M(InstrM[31:25]),
.AtomicM,
@ -285,7 +285,7 @@ module wallypipelinedcore (
.InstrDAPageFaultF,
.PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW,
.LSUStallM); // change to LSUStallM
.LSUStallW); // change to LSUStallW
// *** Ross: please make EBU conditional when only supporting internal memories
@ -319,7 +319,7 @@ module wallypipelinedcore (
hazard hzu(
.BPPredWrongE, .CSRWriteFenceM, .RetM, .TrapM,
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
.LSUStallM, .IFUStallF,
.LSUStallW, .IFUStallD,
.FCvtIntStallD, .FPUStallD,
.DivBusyE, .FDivBusyE,
.EcallFaultM, .BreakpointFaultM,

View File

@ -153,6 +153,9 @@ logic [3:0] dummy;
logic HREADY;
logic HSELEXT;
logic InitializingMemories;
integer ResetCount, ResetThreshold;
logic InReset;
// instantiate device to be tested
assign GPIOPinsIn = 0;
@ -201,6 +204,9 @@ logic [3:0] dummy;
initial
begin
ResetCount = 0;
ResetThreshold = 2;
InReset = 1;
test = 1;
totalerrors = 0;
testadr = 0;
@ -251,7 +257,6 @@ logic [3:0] dummy;
updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray);
$display("Read memfile %s", memfilename);
end
reset_ext = 1; # 42; reset_ext = 0;
end
// generate clock to sequence tests
@ -265,8 +270,19 @@ logic [3:0] dummy;
// assign debugmemoryadr = dut.uncore.uncore.ram.ram.memory.RAM[5140];
// check results
assign reset_ext = InReset;
always @(negedge clk)
begin
InitializingMemories = 0;
if(InReset == 1) begin
// once the test inidicates it's done we need to immediately hold reset for a number of cycles.
if(ResetCount < ResetThreshold) ResetCount = ResetCount + 1;
else begin // hit reset threshold so we remove reset.
InReset = 0;
ResetCount = 0;
end
end else begin
if (TEST == "coremark")
if (dut.core.priv.priv.EcallFaultM) begin
$display("Benchmark: coremark is done.");
@ -274,7 +290,8 @@ logic [3:0] dummy;
end
// Termination condition (i.e. we finished running current test)
if (DCacheFlushDone) begin
integer begin_signature_addr;
integer begin_signature_addr;
InReset = 1;
begin_signature_addr = ProgramAddrLabelArray["begin_signature"];
if (!begin_signature_addr)
$display("begin_signature addr not found in %s", ProgramLabelMapFile);
@ -357,6 +374,7 @@ logic [3:0] dummy;
$stop;
end
else begin
InitializingMemories = 1;
// If there are still additional tests to run, read in information for the next test
//pathname = tvpaths[tests[0]];
if (riscofTest) memfilename = {pathname, tests[test], "/ref/ref.elf.memfile"};
@ -378,8 +396,8 @@ logic [3:0] dummy;
updateProgramAddrLabelArray(ProgramAddrMapFile, ProgramLabelMapFile, ProgramAddrLabelArray);
$display("Read memfile %s", memfilename);
end
reset_ext = 1; # 47; reset_ext = 0;
end
end // if (DCacheFlushDone)
end
end // always @ (negedge clk)

View File

@ -1805,6 +1805,7 @@ string imperas32f[] = '{
"rv64i_m/privilege/src/WALLY-status-mie-01.S",
"rv64i_m/privilege/src/WALLY-status-sie-01.S",
"rv64i_m/privilege/src/WALLY-status-tw-01.S",
"rv64i_m/privilege/src/WALLY-status-tvm-01.S",
"rv64i_m/privilege/src/WALLY-stvec-01.S",
"rv64i_m/privilege/src/WALLY-trap-01.S",
"rv64i_m/privilege/src/WALLY-trap-s-01.S",
@ -1891,6 +1892,7 @@ string imperas32f[] = '{
"rv32i_m/privilege/src/WALLY-status-mie-01.S",
"rv32i_m/privilege/src/WALLY-status-sie-01.S",
"rv32i_m/privilege/src/WALLY-status-tw-01.S",
"rv32i_m/privilege/src/WALLY-status-tvm-01.S",
"rv32i_m/privilege/src/WALLY-stvec-01.S",
"rv32i_m/privilege/src/WALLY-trap-01.S",
"rv32i_m/privilege/src/WALLY-trap-s-01.S",

View File

@ -2,6 +2,7 @@
80006000 # read SD = 1, FS = 11
00004000 # read written SD = 1, FS = 10
80006000 # read SD = 1, FS = 11
00000002 # mcause from attempting fmv with status.FS cleared
0000000b # mcause from M mode ecall from test termination
deadbeef
deadbeef
@ -1021,4 +1022,3 @@ deadbeef
deadbeef
deadbeef
deadbeef
deadbeef

View File

@ -299,8 +299,7 @@ end_trap_triggers:
// --------------------------------------------------------------------------------------------
//.align 6
.align 2
.align 6
trap_handler_\MODE\():
j trap_unvectored_\MODE\() // for the unvectored implimentation: jump past this table of addresses into the actual handler
// *** ASSUMES that a cause value of 0 for an interrupt is unimplemented

View File

@ -35,8 +35,8 @@ RVTEST_CODE_BEGIN
# ---------------------------------------------------------------------------------------------
j main_code
# Thanks to MTVEC[1:0], trap handler addresses need to be aligned to a 4-byte boundary
.align 2
# 64 byte alignment for vectored traps to align with xtev
.align 6
###################
###################
trap_handler: #####

View File

@ -71,6 +71,10 @@ sw x29, 0(x6) // read dirty FS, SD bits, which should be 11 and 1 respectively
addi x6, x6, 4
addi x16, x16, 4
li x29, 0x6000
csrc mstatus, x29 // clear FS to be 00, disabling floating point
fmv.s ft0, ft0 // should be an illegal instruction with fs set to 00
END_TESTS
TEST_STACK_AND_DATA

View File

@ -0,0 +1,45 @@
///////////////////////////////////////////
//
// WALLY-status-tvm
//
// Author: Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
//
// Created 2022-12-22
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "WALLY-TEST-LIB-32.h"
RVTEST_ISA("RV32I")
RVTEST_CASE(0,"//check ISA:=regex(.*32.*);check ISA:=regex(.*I.*); def Drvtest_mtrap_routine=True;def TEST_CASE_1=True;def NO_SAIL=True;", status-tvm)
INIT_TESTS
TRAP_HANDLER m//, EXT_SIGNATURE=1 // turn on recording mtval and status bits on traps
li x28, 0x100000
csrs mstatus, x28 // set mstatus.TVM bit to 1
GOTO_S_MODE // go to S mode so the TVM can be triggered
csrw satp, x28 // attempt to write satp should cause illegal instruction with TVM
csrr x28, satp // attempt to read satp should cause illegal instruction with TVM
sfence.vma x0, x0 // attempt to call sfence should cause illegal instruction with TVM
END_TESTS
TEST_STACK_AND_DATA

View File

@ -6,6 +6,8 @@
00000000
00006000 # read SD = 1, FS = 11
80000000
00000002 # mcause from attempting fmv with status.FS cleared
00000000
0000000b # mcause from M mode ecall from test termination
00000000
deadbeef
@ -1020,5 +1022,3 @@ deadbeef
deadbeef
deadbeef
deadbeef
deadbeef
deadbeef

View File

@ -293,8 +293,7 @@ end_trap_triggers:
//
// --------------------------------------------------------------------------------------------
//.align 6
.align 3
.align 6
trap_handler_\MODE\():
j trap_unvectored_\MODE\() // for the unvectored implimentation: jump past this table of addresses into the actual handler
// *** ASSUMES that a cause value of 0 for an interrupt is unimplemented

View File

@ -35,8 +35,8 @@ RVTEST_CODE_BEGIN
# ---------------------------------------------------------------------------------------------
j main_code
# Thanks to MTVEC[1:0], trap handler addresses need to be aligned to a 4-byte boundary
.align 2
# 64 byte alignment for vectored traps to align with xtev
.align 6
###################
###################
trap_handler: #####

View File

@ -70,6 +70,10 @@ sd x29, 0(x6) // read dirty FS, SD bits, which should be 11 and 1 respectively
addi x6, x6, 8
addi x16, x16, 8
li x29, 0x6000
csrc mstatus, x29 // clear FS to be 00, disabling floating point
fmv.s ft0, ft0 // should be an illegal instruction with fs set to 00
END_TESTS
TEST_STACK_AND_DATA

View File

@ -0,0 +1,45 @@
///////////////////////////////////////////
//
// WALLY-status-tvm
//
// Author: Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
//
// Created 2022-12-22
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "WALLY-TEST-LIB-64.h"
RVTEST_ISA("RV64I")
RVTEST_CASE(0,"//check ISA:=regex(.*64.*);check ISA:=regex(.*I.*); def Drvtest_mtrap_routine=True;def TEST_CASE_1=True;def NO_SAIL=True;", status-tvm)
INIT_TESTS
TRAP_HANDLER m//, EXT_SIGNATURE=1 // turn on recording mtval and status bits on traps
li x28, 0x100000
csrs mstatus, x28 // set mstatus.TVM bit to 1
GOTO_S_MODE // go to S mode so the TVM can be triggered
csrw satp, x28 // attempt to write satp should cause illegal instruction with TVM
csrr x28, satp // attempt to read satp should cause illegal instruction with TVM
sfence.vma x0, x0 // attempt to call sfence should cause illegal instruction with TVM
END_TESTS
TEST_STACK_AND_DATA