mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-03 18:25:27 +00:00
FDIV merge
This commit is contained in:
commit
74979cdc82
@ -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]
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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 */
|
||||
|
@ -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]);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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: #####
|
||||
|
@ -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
|
@ -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
|
@ -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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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: #####
|
||||
|
@ -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
|
@ -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
|
Loading…
Reference in New Issue
Block a user