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 create_debug_port u_ila_0 probe
set_property port_width 1 [get_debug_ports u_ila_0/probe59] 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] 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 create_debug_port u_ila_0 probe
set_property port_width 1 [get_debug_ports u_ila_0/probe60] 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] 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 create_debug_port u_ila_0 probe
set_property port_width 1 [get_debug_ports u_ila_0/probe61] 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 LOGR ((`RADIX==2) ? 32'h1 : 32'h2)
`define RK (`DIVCOPIES*`LOGR) // r*k used for intdiv preproc `define RK (`DIVCOPIES*`LOGR) // r*k used for intdiv preproc
`define LOGK ($clog2(`DIVCOPIES)) `define LOGK ($clog2(`DIVCOPIES))
`define LOGRK ($clog2(`RADIX*`DIVCOPIES)) // log2(R*k) `define LOGRK ($clog2(`RK)) // log2(r*k)
// FPDUR = ceil(DIVRESLEN/(LOGR*DIVCOPIES)) // FPDUR = ceil(DIVRESLEN/(LOGR*DIVCOPIES))
// one iteration is required for the integer bit for minimally redundent radix-4 // one iteration is required for the integer bit for minimally redundent radix-4
`define FPDUR ((`DIVN+1+(`LOGR*`DIVCOPIES))/(`LOGR*`DIVCOPIES)+(`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 -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/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/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/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/DivBusyE
add wave -noupdate -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrMisalignedFaultM 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 -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/SelHPTW
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/InterlockStall 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/ReadDataWordMuxM
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/ReadDataM add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/ReadDataM
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/WriteDataM 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 /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 -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/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 -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/ExceptionM
add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrMisalignedFaultM 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/IEUAdrM
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/PAdrM 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/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/ReadDataWordMuxM
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/ReadDataM add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/ReadDataM
add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/WriteDataM 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 /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 -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/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/ifu/IFUStallD
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/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/DivBusyE
add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/FDivBusyE 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/InstrD
add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/InstrE 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 {instruction pipeline} /testbench/dut/core/ifu/InstrM
add wave -noupdate -group PCS /testbench/dut/core/ifu/PCNextF add wave -noupdate -expand -group PCS /testbench/dut/core/ifu/PCNextF
add wave -noupdate -group PCS /testbench/dut/core/PCF add wave -noupdate -expand -group PCS /testbench/dut/core/PCF
add wave -noupdate -group PCS /testbench/dut/core/ifu/PCD add wave -noupdate -expand -group PCS /testbench/dut/core/ifu/PCD
add wave -noupdate -group PCS /testbench/dut/core/PCE add wave -noupdate -expand -group PCS /testbench/dut/core/PCE
add wave -noupdate -group PCS /testbench/dut/core/PCM add wave -noupdate -expand -group PCS /testbench/dut/core/PCM
add wave -noupdate -group PCS /testbench/PCW 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/PCD
add wave -noupdate -group {Decode Stage} /testbench/dut/core/ifu/InstrD add wave -noupdate -group {Decode Stage} /testbench/dut/core/ifu/InstrD
add wave -noupdate -group {Decode Stage} /testbench/InstrDName 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/HTRANS
add wave -noupdate -group AHB /testbench/dut/core/ebu/ebu/HMASTLOCK 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/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/ReadDataWordMuxM
add wave -noupdate -group lsu /testbench/dut/core/lsu/ReadDataM add wave -noupdate -group lsu /testbench/dut/core/lsu/ReadDataM
add wave -noupdate -group lsu -radix hexadecimal /testbench/dut/core/lsu/WriteDataM 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/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/ITLBWriteF
add wave -noupdate -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/DTLBWriteM 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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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/GPIOPinsIn
add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/GPIOPinsOut add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/GPIOPinsOut
add wave -noupdate -group GPIO /testbench/dut/uncore/uncore/gpio/gpio/GPIOPinsEn 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/HSELNoneD
add wave -noupdate -expand -group uncore /testbench/dut/uncore/uncore/HSELPLICD 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 -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] 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 quietly wave cursor active 5
configure wave -namecolwidth 250 configure wave -namecolwidth 250
configure wave -valuecolwidth 194 configure wave -valuecolwidth 194
@ -632,4 +636,4 @@ configure wave -griddelta 40
configure wave -timeline 0 configure wave -timeline 0
configure wave -timelineunits ns configure wave -timelineunits ns
update update
WaveRestoreZoom {471640 ns} {472086 ns} WaveRestoreZoom {128173 ns} {130237 ns}

View File

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

View File

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

View File

@ -103,7 +103,7 @@ module fdivsqrtfsm(
always_comb begin always_comb begin
if (SqrtE) fbits = Nf + 2 + 2; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2 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 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 end
/* verilator lint_on WIDTH */ /* verilator lint_on WIDTH */

View File

@ -36,7 +36,7 @@ module fdivsqrtiter(
input logic FDivBusyE, input logic FDivBusyE,
input logic SqrtE, MDUE, input logic SqrtE, MDUE,
// input logic SqrtM, // input logic SqrtM,
input logic OTFCSwapE, input logic CalcOTFCSwapE, OTFCSwapE,
input logic [`DIVb+3:0] X, input logic [`DIVb+3:0] X,
input logic [`DIVb-1:0] DPreproc, input logic [`DIVb-1:0] DPreproc,
output logic [`DIVb-1:0] D, output logic [`DIVb-1:0] D,
@ -78,9 +78,9 @@ module fdivsqrtiter(
flopen #(`DIVb+4) wcreg(clk, FDivBusyE, WCN, WC[0]); flopen #(`DIVb+4) wcreg(clk, FDivBusyE, WCN, WC[0]);
// UOTFC Result U and UM registers/initialization mux // 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 // 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 = (SqrtE & ~(MDUE)) ? {1'b1, {(`DIVb){1'b0}}} : 0; assign initU = ((MDUE & CalcOTFCSwapE) | (SqrtE & ~(MDUE))) ? {1'b1, {(`DIVb){1'b0}}} : 0;
assign initUM = (SqrtE & ~(MDUE)) ? 0 : {1'b1, {(`DIVb){1'b0}}}; 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) Umux(UNext[`DIVCOPIES-1], initU, IFDivStartE, UMux);
mux2 #(`DIVb+1) UMmux(UMNext[`DIVCOPIES-1], initUM, IFDivStartE, UMMux); mux2 #(`DIVb+1) UMmux(UMNext[`DIVCOPIES-1], initUM, IFDivStartE, UMMux);
flopen #(`DIVb+1) UReg(clk, IFDivStartE|FDivBusyE, UMux, U[0]); 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-1:0] D,
input logic [`DIVb:0] FirstU, FirstUM, input logic [`DIVb:0] FirstU, FirstUM,
input logic [`DIVb+1:0] FirstC, input logic [`DIVb+1:0] FirstC,
input logic Firstun, input logic Firstun, SqrtM, SpecialCaseM, OTFCSwapEM,
input logic SqrtM, input logic [`XLEN-1:0] ForwardedSrcAM,
input logic SpecialCaseM,
input logic [`XLEN-1:0] ForwardedSrcAE,
input logic RemOpM, ALTBM, BZeroM, As, input logic RemOpM, ALTBM, BZeroM, As,
input logic [`DIVBLEN:0] nM, mM, input logic [`DIVBLEN:0] nM, mM,
output logic [`DIVb:0] QmM, output logic [`DIVb:0] QmM,
@ -54,7 +52,7 @@ module fdivsqrtpostproc(
logic [`DIVBLEN:0] NormShiftM; logic [`DIVBLEN:0] NormShiftM;
logic [`DIVb:0] IntQuotM, NormQuotM; logic [`DIVb:0] IntQuotM, NormQuotM;
logic [`DIVb+3:0] IntRemM, NormRemM; 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 // 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); aplusbeq0 #(`DIVb+4) wspluswceq0(WS, WC, weq0);
@ -106,12 +104,12 @@ module fdivsqrtpostproc(
// Integer division: Special cases // Integer division: Special cases
always_comb always_comb
if(ALTBM) begin if (BZeroM) begin
IntQuotM = '0;
IntRemM = {{(`DIVb-`XLEN+4){1'b0}}, ForwardedSrcAE};
end else if (BZeroM) begin
IntQuotM = '1; 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 end else if (WZeroM) begin
if (weq0) begin if (weq0) begin
IntQuotM = FirstU; IntQuotM = FirstU;
@ -130,14 +128,19 @@ module fdivsqrtpostproc(
NormShiftM = (mM + (`DIVBLEN+1)'(`DIVa)); NormShiftM = (mM + (`DIVBLEN+1)'(`DIVa));
PreResultM = IntRemM; PreResultM = IntRemM;
end else begin end else begin
NormShiftM = ((`DIVBLEN+1)'(`DIVb) - (nM << `LOGR)); NormShiftM = ((`DIVBLEN+1)'(`DIVb) - (nM * (`DIVBLEN+1)'(`LOGR)));
PreResultM = {3'b000, IntQuotM}; 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 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 // 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 FPIntDivResultM = PreFPIntDivResultM[`XLEN-1:0];
assign PreQmM = NegStickyM ? FirstUM : FirstU; // Select U or U-1 depending on negative sticky bit 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 [2:0] Funct3E,
input logic MDUE, W64E, input logic MDUE, W64E,
output logic [`DIVBLEN:0] nE, nM, mM, 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 [`NE+1:0] QeM,
output logic [`DIVb+3:0] X, 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; logic [`DIVb-1:0] XPreproc;
@ -55,12 +56,12 @@ module fdivsqrtpreproc (
// Intdiv signals // Intdiv signals
logic [`DIVb-1:0] IFNormLenX, IFNormLenD; logic [`DIVb-1:0] IFNormLenX, IFNormLenD;
logic [`XLEN-1:0] PosA, PosB; logic [`XLEN-1:0] PosA, PosB;
logic Bs, CalcOTFCSwapE, ALTBE; logic Bs, ALTBE;
logic [`XLEN-1:0] A64, B64; logic [`XLEN-1:0] A64, B64;
logic [`DIVBLEN:0] mE; logic [`DIVBLEN:0] mE;
logic [`DIVBLEN:0] ZeroDiff, IntBits, RightShiftX; logic [`DIVBLEN:0] ZeroDiff, IntBits, RightShiftX;
logic [`DIVBLEN:0] pPlusr, pPrCeil, p, ell; logic [`DIVBLEN:0] pPlusr, pPrCeil, p, ell;
logic [`LOGRK-1:0] pPrTrunc; logic [`LOGRK:0] pPrTrunc;
logic [`DIVb+3:0] PreShiftX; logic [`DIVb+3:0] PreShiftX;
logic NumZeroE; logic NumZeroE;
@ -91,12 +92,16 @@ module fdivsqrtpreproc (
assign ALTBE = ZeroDiff[`DIVBLEN]; // A less than B assign ALTBE = ZeroDiff[`DIVBLEN]; // A less than B
assign p = ALTBE ? '0 : ZeroDiff; assign p = ALTBE ? '0 : ZeroDiff;
/* verilator lint_off WIDTH */
assign pPlusr = (`DIVBLEN)'(`LOGR) + p; 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 pPrCeil = (pPlusr >> `LOGRK) + {{`DIVBLEN{1'b0}}, |(pPrTrunc)};
assign nE = (pPrCeil << `LOGK) - 1; assign nE = (pPrCeil * (`DIVBLEN+1)'(`DIVCOPIES)) - {{(`DIVBLEN){1'b0}}, 1'b1};
assign IntBits = (`DIVBLEN)'(`RK) + p; assign IntBits = (`DIVBLEN)'(`LOGR) + p - {{(`DIVBLEN){1'b0}}, 1'b1};
assign RightShiftX = (`DIVBLEN)'(`RK) - {{(`DIVBLEN-`RK){1'b0}}, IntBits[`RK-1:0]}; 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; assign NumZeroE = MDUE ? AZeroE : XZeroE;
@ -125,7 +130,7 @@ module fdivsqrtpreproc (
flopen #(1) bzeroreg(clk, IFDivStartE, BZeroE, BZeroM); flopen #(1) bzeroreg(clk, IFDivStartE, BZeroE, BZeroM);
flopen #(`DIVBLEN+1) nreg(clk, IFDivStartE, nE, nM); flopen #(`DIVBLEN+1) nreg(clk, IFDivStartE, nE, nM);
flopen #(`DIVBLEN+1) mreg(clk, IFDivStartE, mE, mM); 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)); expcalc expcalc(.Fmt, .Xe, .Ye, .Sqrt, .XZeroE, .ell, .m(mE), .Qe(QeE));
endmodule endmodule

View File

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

View File

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

View File

@ -60,7 +60,7 @@ module fdivsqrtstage2 (
// 0000 = 0 // 0000 = 0
// 0010 = -1 // 0010 = -1
// 0001 = -2 // 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 // Sqrt F generation
fdivsqrtfgen2 fgen2(.up, .uz, .C(CNext), .U, .UM, .F); fdivsqrtfgen2 fgen2(.up, .uz, .C(CNext), .U, .UM, .F);
@ -82,7 +82,7 @@ module fdivsqrtstage2 (
assign CNext = {1'b1, C[`DIVb+1:1]}; assign CNext = {1'b1, C[`DIVb+1:1]};
// Unified On-The-Fly Converter to accumulate result // 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 endmodule

View File

@ -65,7 +65,7 @@ module fdivsqrtstage4 (
assign WCmsbs = WC[`DIVb+3:`DIVb-4]; assign WCmsbs = WC[`DIVb+3:`DIVb-4];
assign WSmsbs = WS[`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 assign un = 1'b0; // unused for radix 4
// F generation logic // F generation logic
@ -94,7 +94,7 @@ module fdivsqrtstage4 (
assign CNext = {2'b11, C[`DIVb+1:2]}; assign CNext = {2'b11, C[`DIVb+1:2]};
// On-the-fly converter to accumulate result // 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 endmodule

View File

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

View File

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

View File

@ -34,7 +34,7 @@ module hazard(
// Detect hazards // Detect hazards
(* mark_debug = "true" *) input logic BPPredWrongE, CSRWriteFenceM, RetM, TrapM, (* mark_debug = "true" *) input logic BPPredWrongE, CSRWriteFenceM, RetM, TrapM,
(* mark_debug = "true" *) input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD, (* 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 FCvtIntStallD, FPUStallD,
(* mark_debug = "true" *) input logic DivBusyE,FDivBusyE, (* mark_debug = "true" *) input logic DivBusyE,FDivBusyE,
(* mark_debug = "true" *) input logic EcallFaultM, BreakpointFaultM, (* mark_debug = "true" *) input logic EcallFaultM, BreakpointFaultM,
@ -86,7 +86,8 @@ module hazard(
assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause; 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 // 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 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 // Stall each stage for cause or if the next stage is stalled
assign #1 StallF = StallFCause | StallD; assign #1 StallF = StallFCause | StallD;

Binary file not shown.

View File

@ -33,38 +33,36 @@
`include "wally-config.vh" `include "wally-config.vh"
module bpred module bpred (
(input logic clk, reset, input logic clk, reset,
input logic StallF, StallD, StallE, StallM, input logic StallF, StallD, StallE, StallM,
input logic FlushD, FlushE, FlushM, input logic FlushD, FlushE, FlushM,
// Fetch stage // Fetch stage
// the prediction // the prediction
input logic [31:0] InstrD, input logic [31:0] InstrD, // Decompressed decode stage instruction
input logic [`XLEN-1:0] PCNextF, // *** forgot to include this one on the I/O list input logic [`XLEN-1:0] PCNextF, // Next Fetch Address
input logic [`XLEN-1:0] PCPlus2or4F, input logic [`XLEN-1:0] PCPlus2or4F, // PCF+2/4
output logic [`XLEN-1:0] PCNext1F, output logic [`XLEN-1:0] PCNext1F, // Branch Predictor predicted or corrected fetch address on miss prediction
output logic [`XLEN-1:0] NextValidPCE, // The address of the currently executing instruction output logic [`XLEN-1:0] NextValidPCE, // Address of next valid instruction after the instruction in the Memory stage.
// Update Predictor // Update Predictor
input logic [`XLEN-1:0] PCE, // The address of the currently executing instruction input logic [`XLEN-1:0] PCF, // Fetch stage instruction address.
input logic [`XLEN-1:0] PCF, // The address of the currently executing instruction 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. // *** 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. // *** the specifics of how this is encode is subject to change.
input logic PCSrcE, // AKA Branch Taken input logic PCSrcE, // Executation stage branch is taken
// Signals required to check the branch prediction accuracy. input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address
input logic [`XLEN-1:0] IEUAdrE, // The branch destination if the branch is taken. input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
input logic [`XLEN-1:0] PCD, // The address the branch predictor took. output logic [4:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
input logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
output logic [4:0] InstrClassM,
// Report branch prediction status // Report branch prediction status
output logic BPPredWrongE, output logic BPPredWrongE, // Prediction is wrong.
output logic BPPredDirWrongM, output logic BPPredDirWrongM, // Prediction direction is wrong.
output logic BTBPredPCWrongM, output logic BTBPredPCWrongM, // Prediction target wrong.
output logic RASPredPCWrongM, output logic RASPredPCWrongM, // RAS prediction is wrong.
output logic BPPredClassNonCFIWrongM output logic BPPredClassNonCFIWrongM // Class prediction is wrong.
); );
logic BTBValidF; logic BTBValidF;
@ -126,13 +124,11 @@ module bpred
// 1) A direction (1 = Taken, 0 = Not Taken) // 1) A direction (1 = Taken, 0 = Not Taken)
// 2) Any information which is necessary for the predictor to build its next state. // 2) Any information which is necessary for the predictor to build its next state.
// For a 2 bit table this is the prediction count. // For a 2 bit table this is the prediction count.
assign SelBPPredF = ((BPInstrClassF[0] & BPPredF[1] & BTBValidF) | assign SelBPPredF = ((BPInstrClassF[0] & BPPredF[1] & BTBValidF) |
BPInstrClassF[3] | BPInstrClassF[3] |
(BPInstrClassF[2] & BTBValidF) | (BPInstrClassF[2] & BTBValidF) |
BPInstrClassF[1] & BTBValidF) ; BPInstrClassF[1] & BTBValidF) ;
// Part 2 Branch target address prediction // Part 2 Branch target address prediction
// *** For now the BTB will house the direct and indirect targets // *** For now the BTB will house the direct and indirect targets
@ -162,12 +158,10 @@ module bpred
.pushPC(PCLinkE)); .pushPC(PCLinkE));
assign BPPredPCF = BPInstrClassF[3] ? RASPCF : BTBPredPCF; assign BPPredPCF = BPInstrClassF[3] ? RASPCF : BTBPredPCF;
// The prediction and its results need to be passed through the pipeline // The prediction and its results need to be passed through the pipeline
// *** for other predictors will will be different. // *** for other predictors will will be different.
// *** should these be flushed?
flopenr #(2) BPPredRegD(.clk(clk), flopenr #(2) BPPredRegD(.clk(clk),
.reset(reset), .reset(reset),
.en(~StallD), .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[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[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 assign InstrClassD[0] = InstrD[6:0] == 7'h63; // branch
flopenrc #(5) InstrClassRegE(.clk, .reset, .en(~StallE), .clear(FlushE), .d(InstrClassD), .q(InstrClassE)); flopenrc #(5) InstrClassRegE(clk, reset, FlushE, ~StallE, InstrClassD, InstrClassE);
flopenrc #(5) InstrClassRegM(.clk, .reset, .en(~StallM), .clear(FlushM), .d(InstrClassE), .q(InstrClassM)); flopenrc #(5) InstrClassRegM(clk, reset, FlushM, ~StallM, InstrClassE, InstrClassM);
flopenrc #(1) BPPredWrongMReg(.clk, .reset, .en(~StallM), .clear(FlushM), .d(BPPredWrongE), .q(BPPredWrongM)); flopenrc #(1) BPPredWrongMReg(clk, reset, FlushM, ~StallM, BPPredWrongE, BPPredWrongM);
// branch predictor // branch predictor
flopenrc #(4) BPPredWrongRegM(.clk, .reset, .en(~StallM), .clear(FlushM), flopenrc #(4) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
.d({BPPredDirWrongE, BTBPredPCWrongE, RASPredPCWrongE, BPPredClassNonCFIWrongE}), {BPPredDirWrongE, BTBPredPCWrongE, RASPredPCWrongE, BPPredClassNonCFIWrongE},
.q({BPPredDirWrongM, BTBPredPCWrongM, RASPredPCWrongM, BPPredClassNonCFIWrongM})); {BPPredDirWrongM, BTBPredPCWrongM, RASPredPCWrongM, BPPredClassNonCFIWrongM});
// pipeline the class // pipeline the class
flopenrc #(5) BPInstrClassRegD(.clk(clk), flopenrc #(5) BPInstrClassRegD(clk, reset, FlushD, ~StallD, BPInstrClassF, BPInstrClassD);
.reset(reset), flopenrc #(5) BPInstrClassRegE(clk, reset, FlushE, ~StallE, BPInstrClassD, BPInstrClassE);
.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.
// Check the prediction
// first check if the target or fallthrough address matches what was predicted. // first check if the target or fallthrough address matches what was predicted.
assign TargetWrongE = IEUAdrE != PCD; assign TargetWrongE = IEUAdrE != PCD;
assign FallThroughWrongE = PCLinkE != 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 // 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 // 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. // need this information to verify the accuracy of the predictors.
//assign BPPredWrongE = ((PredictionPCWrongE | BPPredDirWrongE) & (|InstrClassE)) | PredictionInstrClassWrongE;
assign BPPredWrongE = (PredictionPCWrongE & |InstrClassE) | BPPredClassNonCFIWrongE; 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. // 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. // Finally if the real instruction class is non CFI but the predictor said it was we need to count.
assign BPPredClassNonCFIWrongE = PredictionInstrClassWrongE & ~|InstrClassE; assign BPPredClassNonCFIWrongE = PredictionInstrClassWrongE & ~|InstrClassE;
// Update predictors // 2 bit saturating counter
satCounter2 BPDirUpdate(.BrDir(PCSrcE), .OldState(BPPredE), .NewState(UpdateBPPredE));
satCounter2 BPDirUpdate(.BrDir(PCSrcE),
.OldState(BPPredE),
.NewState(UpdateBPPredE));
// Selects the BP or PC+2/4. // 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. // 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. // 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. // If the fence/csrw was predicted as a taken branch then we select PCF, rather PCE.
// could also just use PCM+4, or PCLinkM // Effectively this is PCM+4 or the non-existant PCLinkM
// ONLY valid for class prediction. add option for class prediction. // if(`BPCLASS) begin
// if(`BPCLASS) begin mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPPredWrongM, NextValidPCE);
mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(.d0(PCE), .d1(PCF), .s(BPPredWrongM), .y(NextValidPCE)); // end else begin
// end else begin // assign NextValidPCE = PCE;
// assign NextValidPCE = PCE; // end
// 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 endmodule

View File

@ -38,7 +38,7 @@ module ifu (
// Bus interface // Bus interface
(* mark_debug = "true" *) input logic [`XLEN-1:0] HRDATA, (* mark_debug = "true" *) input logic [`XLEN-1:0] HRDATA,
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] IFUHADDR, (* 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 [2:0] IFUHBURST,
(* mark_debug = "true" *) output logic [1:0] IFUHTRANS, (* mark_debug = "true" *) output logic [1:0] IFUHTRANS,
(* mark_debug = "true" *) output logic [2:0] IFUHSIZE, (* mark_debug = "true" *) output logic [2:0] IFUHSIZE,
@ -113,7 +113,7 @@ module ifu (
logic SelNextSpillF; logic SelNextSpillF;
logic ICacheFetchLine; logic ICacheFetchLine;
logic BusStall; logic BusStall;
logic ICacheStallF, IFUCacheBusStallF; logic ICacheStallF, IFUCacheBusStallD;
logic GatedStallD; logic GatedStallD;
(* mark_debug = "true" *) logic [31:0] PostSpillInstrRawF; (* mark_debug = "true" *) logic [31:0] PostSpillInstrRawF;
// branch predictor signal // branch predictor signal
@ -121,8 +121,6 @@ module ifu (
logic BusCommittedF, CacheCommittedF; logic BusCommittedF, CacheCommittedF;
logic SelIROM; logic SelIROM;
assign PCFExt = {2'b00, PCFSpill}; assign PCFExt = {2'b00, PCFSpill};
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
@ -130,9 +128,8 @@ module ifu (
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
if(`C_SUPPORTED) begin : SpillSupport if(`C_SUPPORTED) begin : SpillSupport
spillsupport #(`ICACHE) spillsupport(.clk, .reset, .StallF, .Flush(FlushD), .PCF, .PCPlus4F, .PCNextF, .InstrRawF(InstrRawF),
spillsupport #(`ICACHE) spillsupport(.clk, .reset, .StallF, .Flush(TrapM), .PCF, .PCPlus4F, .PCNextF, .InstrRawF(InstrRawF), .InstrDAPageFaultF, .IFUCacheBusStallD, .ITLBMissF, .PCNextFSpill, .PCFSpill,
.InstrDAPageFaultF, .IFUCacheBusStallF, .ITLBMissF, .PCNextFSpill, .PCFSpill,
.SelNextSpillF, .PostSpillInstrRawF, .CompressedF); .SelNextSpillF, .PostSpillInstrRawF, .CompressedF);
end else begin : NoSpillSupport end else begin : NoSpillSupport
assign PCNextFSpill = PCNextF; assign PCNextFSpill = PCNextF;
@ -222,7 +219,7 @@ module ifu (
cache #(.LINELEN(`ICACHE_LINELENINBITS), cache #(.LINELEN(`ICACHE_LINELENINBITS),
.NUMLINES(`ICACHE_WAYSIZEINBYTES*8/`ICACHE_LINELENINBITS), .NUMLINES(`ICACHE_WAYSIZEINBYTES*8/`ICACHE_LINELENINBITS),
.NUMWAYS(`ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .DCACHE(0)) .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), .FetchBuffer, .CacheBusAck(ICacheBusAck),
.CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF), .CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF),
.CacheBusRW, .CacheBusRW,
@ -239,7 +236,7 @@ module ifu (
ahbcacheinterface #(WORDSPERLINE, LINELEN, LOGBWPL, `ICACHE) ahbcacheinterface #(WORDSPERLINE, LINELEN, LOGBWPL, `ICACHE)
ahbcacheinterface(.HCLK(clk), .HRESETn(~reset), ahbcacheinterface(.HCLK(clk), .HRESETn(~reset),
.HRDATA, .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), .Funct3(3'b010), .HADDR(IFUHADDR), .HREADY(IFUHREADY), .HWRITE(IFUHWRITE), .CacheBusAdr(ICacheBusAdr),
.BeatCount(), .Cacheable(CacheableF), .SelBusBeat(), .WriteDataM('0), .BeatCount(), .Cacheable(CacheableF), .SelBusBeat(), .WriteDataM('0),
.CacheBusAck(ICacheBusAck), .HWDATA(), .CacheableOrFlushCacheM(1'b0), .CacheReadDataWordM('0), .CacheBusAck(ICacheBusAck), .HWDATA(), .CacheableOrFlushCacheM(1'b0), .CacheReadDataWordM('0),
@ -258,7 +255,7 @@ module ifu (
// assign BusRW = IFURWF & ~{IgnoreRequest, IgnoreRequest} & ~{SelIROM, SelIROM}; // assign BusRW = IFURWF & ~{IgnoreRequest, IgnoreRequest} & ~{SelIROM, SelIROM};
assign IFUHSIZE = 3'b010; 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(), .HRDATA(HRDATA), .HTRANS(IFUHTRANS), .HWRITE(IFUHWRITE), .HWDATA(),
.HWSTRB(), .BusRW, .ByteMask(), .WriteData('0), .HWSTRB(), .BusRW, .ByteMask(), .WriteData('0),
.Stall(GatedStallD), .BusStall, .BusCommitted(BusCommittedF), .FetchBuffer(FetchBuffer)); .Stall(GatedStallD), .BusStall, .BusCommitted(BusCommittedF), .FetchBuffer(FetchBuffer));
@ -276,8 +273,8 @@ module ifu (
assign InstrRawF = IROMInstrF; assign InstrRawF = IROMInstrF;
end end
assign IFUCacheBusStallF = ICacheStallF | BusStall; assign IFUCacheBusStallD = ICacheStallF | BusStall;
assign IFUStallF = IFUCacheBusStallF | SelNextSpillF; assign IFUStallD = IFUCacheBusStallD | SelNextSpillF;
assign GatedStallD = StallD & ~SelNextSpillF; assign GatedStallD = StallD & ~SelNextSpillF;
flopenl #(32) AlignedInstrRawDFlop(clk, reset | FlushD, ~StallD, PostSpillInstrRawF, nop, InstrRawD); 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:2] PCPlus4F,
input logic [`XLEN-1:0] PCNextF, input logic [`XLEN-1:0] PCNextF,
input logic [31:0] InstrRawF, input logic [31:0] InstrRawF,
input logic IFUCacheBusStallF, input logic IFUCacheBusStallD,
input logic ITLBMissF, input logic ITLBMissF,
input logic InstrDAPageFaultF, input logic InstrDAPageFaultF,
output logic [`XLEN-1:0] PCNextFSpill, 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)); mux2 #(`XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCFSpill));
assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1]; 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) always_ff @(posedge clk)
if (reset | Flush) CurrState <= #1 STATE_READY; if (reset | Flush) CurrState <= #1 STATE_READY;
@ -77,7 +77,7 @@ module spillsupport #(parameter CACHE_ENABLED)
case (CurrState) case (CurrState)
STATE_READY: if (TakeSpillF) NextState = STATE_SPILL; STATE_READY: if (TakeSpillF) NextState = STATE_SPILL;
else NextState = STATE_READY; else NextState = STATE_READY;
STATE_SPILL: if(IFUCacheBusStallF | StallF) NextState = STATE_SPILL; STATE_SPILL: if(IFUCacheBusStallD | StallF) NextState = STATE_SPILL;
else NextState = STATE_READY; else NextState = STATE_READY;
default: NextState = STATE_READY; default: NextState = STATE_READY;
endcase endcase
@ -85,7 +85,7 @@ module spillsupport #(parameter CACHE_ENABLED)
assign SelSpillF = (CurrState == STATE_SPILL); assign SelSpillF = (CurrState == STATE_SPILL);
assign SelNextSpillF = (CurrState == STATE_READY & TakeSpillF) | assign SelNextSpillF = (CurrState == STATE_READY & TakeSpillF) |
(CurrState == STATE_SPILL & IFUCacheBusStallF); (CurrState == STATE_SPILL & IFUCacheBusStallD);
assign SpillSaveF = (CurrState == STATE_READY) & TakeSpillF; assign SpillSaveF = (CurrState == STATE_READY) & TakeSpillF;
assign SavedInstr = CACHE_ENABLED ? InstrRawF[15:0] : InstrRawF[31:16]; assign SavedInstr = CACHE_ENABLED ? InstrRawF[15:0] : InstrRawF[31:16];

View File

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

View File

@ -42,7 +42,7 @@ module hptw (
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] ReadDataM, // page table entry from LSU input logic [`XLEN-1:0] ReadDataM, // page table entry from LSU
input logic [`XLEN-1:0] WriteDataM, 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 [2:0] Funct3M,
input logic [6:0] Funct7M, input logic [6:0] Funct7M,
input logic ITLBMissF, input logic ITLBMissF,
@ -117,7 +117,7 @@ module hptw (
// State flops // State flops
flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissOrDAFaultM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB) 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 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; IDLE: if (TLBMiss) NextWalkerState = InitialWalkerState;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
L3_ADR: NextWalkerState = L3_RD; // first access in SV48 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; else NextWalkerState = L2_ADR;
L2_ADR: if (InitialWalkerState == L2_ADR | ValidNonLeafPTE) NextWalkerState = L2_RD; // first access in SV39 L2_ADR: if (InitialWalkerState == L2_ADR | ValidNonLeafPTE) NextWalkerState = L2_RD; // first access in SV39
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
L2_RD: if (DCacheStallM) NextWalkerState = L2_RD; L2_RD: if (DCacheStallW) NextWalkerState = L2_RD;
else NextWalkerState = L1_ADR; else NextWalkerState = L1_ADR;
L1_ADR: if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32 L1_ADR: if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32
else if (ValidNonLeafPTE) NextWalkerState = L1_RD; else if (ValidNonLeafPTE) NextWalkerState = L1_RD;
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
L1_RD: if (DCacheStallM) NextWalkerState = L1_RD; L1_RD: if (DCacheStallW) NextWalkerState = L1_RD;
else NextWalkerState = L0_ADR; else NextWalkerState = L0_ADR;
L0_ADR: if (ValidNonLeafPTE) NextWalkerState = L0_RD; L0_ADR: if (ValidNonLeafPTE) NextWalkerState = L0_RD;
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
L0_RD: if (DCacheStallM) NextWalkerState = L0_RD; L0_RD: if (DCacheStallW) NextWalkerState = L0_RD;
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
LEAF: if (`HPTW_WRITES_SUPPORTED & DAPageFault) NextWalkerState = UPDATE_PTE; LEAF: if (`HPTW_WRITES_SUPPORTED & DAPageFault) NextWalkerState = UPDATE_PTE;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
UPDATE_PTE: if(DCacheStallM) NextWalkerState = UPDATE_PTE; UPDATE_PTE: if(DCacheStallW) NextWalkerState = UPDATE_PTE;
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
default: NextWalkerState = IDLE; // should never be reached default: NextWalkerState = IDLE; // should never be reached
endcase // case (WalkerState) endcase // case (WalkerState)
@ -306,5 +306,5 @@ module hptw (
endmodule endmodule
// another idea. We keep gating the control by ~FlushW, but this adds considerable length to the critical path. // 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. // 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]; var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0];
// IMem stalls // IMem stalls
logic IFUStallF; logic IFUStallD;
logic LSUStallM; logic LSUStallW;
@ -174,7 +174,7 @@ module wallypipelinedcore (
.FlushD, .FlushE, .FlushM, .FlushW, .FlushD, .FlushE, .FlushM, .FlushW,
// Fetch // Fetch
.HRDATA, .PCF, .IFUHADDR, .PCNext2F, .HRDATA, .PCF, .IFUHADDR, .PCNext2F,
.IFUStallF, .IFUHBURST, .IFUHTRANS, .IFUHSIZE, .IFUStallD, .IFUHBURST, .IFUHTRANS, .IFUHSIZE,
.IFUHREADY, .IFUHWRITE, .IFUHREADY, .IFUHWRITE,
.ICacheAccess, .ICacheMiss, .ICacheAccess, .ICacheMiss,
@ -247,7 +247,7 @@ module wallypipelinedcore (
lsu lsu( lsu lsu(
.clk, .reset, .StallM, .FlushM, .StallW, .clk, .reset, .StallM, .FlushM, .StallW,
.FlushW(TrapM), .FlushW,
// CPU interface // CPU interface
.MemRWM, .Funct3M, .Funct7M(InstrM[31:25]), .MemRWM, .Funct3M, .Funct7M(InstrM[31:25]),
.AtomicM, .AtomicM,
@ -285,7 +285,7 @@ module wallypipelinedcore (
.InstrDAPageFaultF, .InstrDAPageFaultF,
.PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW, .PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW,
.LSUStallM); // change to LSUStallM .LSUStallW); // change to LSUStallW
// *** Ross: please make EBU conditional when only supporting internal memories // *** Ross: please make EBU conditional when only supporting internal memories
@ -319,7 +319,7 @@ module wallypipelinedcore (
hazard hzu( hazard hzu(
.BPPredWrongE, .CSRWriteFenceM, .RetM, .TrapM, .BPPredWrongE, .CSRWriteFenceM, .RetM, .TrapM,
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD, .LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
.LSUStallM, .IFUStallF, .LSUStallW, .IFUStallD,
.FCvtIntStallD, .FPUStallD, .FCvtIntStallD, .FPUStallD,
.DivBusyE, .FDivBusyE, .DivBusyE, .FDivBusyE,
.EcallFaultM, .BreakpointFaultM, .EcallFaultM, .BreakpointFaultM,

View File

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

View File

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

View File

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

View File

@ -35,8 +35,8 @@ RVTEST_CODE_BEGIN
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
j main_code j main_code
# Thanks to MTVEC[1:0], trap handler addresses need to be aligned to a 4-byte boundary # 64 byte alignment for vectored traps to align with xtev
.align 2 .align 6
################### ###################
################### ###################
trap_handler: ##### 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 x6, x6, 4
addi x16, x16, 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 END_TESTS
TEST_STACK_AND_DATA 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 00000000
00006000 # read SD = 1, FS = 11 00006000 # read SD = 1, FS = 11
80000000 80000000
00000002 # mcause from attempting fmv with status.FS cleared
00000000
0000000b # mcause from M mode ecall from test termination 0000000b # mcause from M mode ecall from test termination
00000000 00000000
deadbeef deadbeef
@ -1020,5 +1022,3 @@ deadbeef
deadbeef deadbeef
deadbeef deadbeef
deadbeef deadbeef
deadbeef
deadbeef

View File

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

View File

@ -35,8 +35,8 @@ RVTEST_CODE_BEGIN
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
j main_code j main_code
# Thanks to MTVEC[1:0], trap handler addresses need to be aligned to a 4-byte boundary # 64 byte alignment for vectored traps to align with xtev
.align 2 .align 6
################### ###################
################### ###################
trap_handler: ##### 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 x6, x6, 8
addi x16, x16, 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 END_TESTS
TEST_STACK_AND_DATA 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