forked from Github_Repos/cvw
Merge branch 'main' of https://github.com/openhwgroup/cvw into main
This commit is contained in:
commit
069ca0ec29
@ -1,12 +1,15 @@
|
|||||||
# core-v-wally
|
# core-v-wally
|
||||||
Configurable RISC-V Processor
|
|
||||||
|
|
||||||
Wally is a 5-stage pipelined processor configurable to support all the standard RISC-V options, incluidng RV32/64, A, C, F, D, and M extensions, FENCE.I, and the various privileged modes and CSRs. It is written in SystemVerilog. It passes the RISC-V Arch Tests and boots Linux on an FPGA.
|
Wally is a 5-stage pipelined processor configurable to support all the standard RISC-V options, incluidng RV32/64, A, C, F, D, Q, M, and Zb* extensions, virtual memory, PMP, and the various privileged modes and CSRs. It provides optional caches, branch prediction, and standard RISC-V peripherals (CLINT, PLIC, UART, GPIO). Wally is written in SystemVerilog. It passes the RISC-V Arch Tests and boots Linux on an FPGA. Configurations range from a minimal RV32E core to a fully featured RV64GC application processor.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Wally is described in an upcoming textbook, *RISC-V System-on-Chip Design*, by Harris, Stine, Thompson, and Harris. Users should follow the setup instructions below. A system administrator must install CAD tools using the directions further down.
|
Wally is described in an upcoming textbook, *RISC-V System-on-Chip Design*, by Harris, Stine, Thompson, and Harris. Users should follow the setup instructions below. A system administrator must install CAD tools using the directions further down.
|
||||||
|
|
||||||
|
# Verification
|
||||||
|
|
||||||
|
Wally is presently at Technology Readiness Level 4, passing the RISC-V compatibility test suite and custom tests, and booting Linux in simulation and on an FPGA. See the [Test Plan](docs/testplan.md) for details.
|
||||||
|
|
||||||
# New User Setup
|
# New User Setup
|
||||||
|
|
||||||
New users may wish to do the following setup to access the server via a GUI and use a text editor.
|
New users may wish to do the following setup to access the server via a GUI and use a text editor.
|
||||||
|
@ -1,6 +1,29 @@
|
|||||||
# CORE-V Wally Test Plan
|
# CORE-V Wally Design Verification Test Plan
|
||||||
|
|
||||||
|
CORE-V Wally is functionally tested in the following ways. Each test is run in lock-step against ImperasDV to ensure all architectural state is correct after each instruction.
|
||||||
|
|
||||||
|
| Functions | Coverage Method | Status |
|
||||||
|
| ----------- | ----------- |----|
|
||||||
|
| Instructions | riscv-arch-test | Pass |
|
||||||
|
| Privileged Unit | wally-riscv-arch-test | Pass |
|
||||||
|
| Virtual Memory | wally-riscv-arch-test | Pass |
|
||||||
|
| PMP | wally-riscv-arch-test | Pass
|
||||||
|
| Peripherals | wally-riscv-arch-test | Pass |
|
||||||
|
| Floating-Point | TestFloat | Pass |
|
||||||
|
| General | Code Coverage | 91% |
|
||||||
|
| General | Boot Linux in Sim | Pass |
|
||||||
|
| General | Boot Linux on FPGA | Pass |
|
||||||
|
|
||||||
|
|
||||||
|
The following performance validation is also run:
|
||||||
|
| Function | Method | Status |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Overall Performance | embench | Pass|
|
||||||
|
| Overall Performance | coremark | Pass |
|
||||||
|
| Branch Predictor | *** | Pass |
|
||||||
|
| Cache Miss Rate | *** | Pass |
|
||||||
|
|
||||||
|
|
||||||
CORE-V Wally is tested in the following ways:
|
|
||||||
|
|
||||||
* Run [RISC-V Architecture Compatibility Tests](https://github.com/riscv-non-isa/riscv-arch-test) in lock-step against the ImperasDV reference model.
|
* Run [RISC-V Architecture Compatibility Tests](https://github.com/riscv-non-isa/riscv-arch-test) in lock-step against the ImperasDV reference model.
|
||||||
* Run custom tests to cover virtual memory, PMP, privileged unit, and peripherals in lock step against ImperasDV.
|
* Run custom tests to cover virtual memory, PMP, privileged unit, and peripherals in lock step against ImperasDV.
|
||||||
|
@ -31,11 +31,14 @@
|
|||||||
do GetLineNum.do
|
do GetLineNum.do
|
||||||
|
|
||||||
# LZA (i<64) statement confuses coverage tool
|
# LZA (i<64) statement confuses coverage tool
|
||||||
# This is ugly to exlcude the whole file - is there a better option? // coverage off isn't working
|
# DH 4/22/23: Exclude all LZAs
|
||||||
coverage exclude -srcfile lzc.sv
|
coverage exclude -srcfile lzc.sv
|
||||||
|
|
||||||
# FDIVSQRT has
|
# DH 4/22/23: FDIVSQRT can't go directly from done to busy again
|
||||||
coverage exclude -scope /core/fpu/fpu/fdivsqrt/fdivsqrtfsm -ftrans state DONE->BUSY
|
coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -ftrans state DONE->BUSY
|
||||||
|
# DH 4/22/23: The busy->idle transition only occurs if a FlushE occurs while the divider is busy. The flush is caused by a trap or return,
|
||||||
|
# which won't happen while the divider is busy.
|
||||||
|
coverage exclude -scope /dut/core/fpu/fpu/fdivsqrt/fdivsqrtfsm -ftrans state BUSY->IDLE
|
||||||
|
|
||||||
### Exclude D$ states and logic for the I$ instance
|
### Exclude D$ states and logic for the I$ instance
|
||||||
# This is cleaner than trying to set an I$-specific pragma in cachefsm.sv (which would exclude it for the D$ instance too)
|
# This is cleaner than trying to set an I$-specific pragma in cachefsm.sv (which would exclude it for the D$ instance too)
|
||||||
@ -52,7 +55,7 @@ set end [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag-end: icache case"]
|
|||||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange $start-$end
|
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange $start-$end
|
||||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache WRITEBACKStatement"]
|
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache WRITEBACKStatement"]
|
||||||
# exclude Atomic Operation logic
|
# exclude Atomic Operation logic
|
||||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache storeAMO"] -item e 1 -fecexprrow 6
|
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: cache AnyMiss"] -item e 1 -fecexprrow 6
|
||||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache storeAMO1"] -item e 1 -fecexprrow 2-4
|
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache storeAMO1"] -item e 1 -fecexprrow 2-4
|
||||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache AnyUpdateHit"] -item e 1 -fecexprrow 2
|
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache AnyUpdateHit"] -item e 1 -fecexprrow 2
|
||||||
# cache write logic
|
# cache write logic
|
||||||
@ -77,6 +80,19 @@ for {set i 0} {$i < $numcacheways} {incr i} {
|
|||||||
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: icache SetValidEN"] -item e 1 -fecexprrow 4
|
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: icache SetValidEN"] -item e 1 -fecexprrow 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
## D$ Exclusions.
|
||||||
|
# InvalidateCache is I$ only:
|
||||||
|
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: dcache InvalidateCheck"] -item b 2
|
||||||
|
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: dcache InvalidateCheck"] -item s 1
|
||||||
|
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: dcache CacheEn"] -item e 1 -fecexprrow 12
|
||||||
|
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: cache AnyMiss"] -item e 1 -fecexprrow 4
|
||||||
|
set numcacheways 4
|
||||||
|
for {set i 0} {$i < $numcacheways} {incr i} {
|
||||||
|
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: dcache invalidateway"] -item be 1 -fecexprrow 4
|
||||||
|
}
|
||||||
|
# D$ writeback, flush, write_line, or flush_writeback states can't be cancelled by a flush
|
||||||
|
coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -ftrans CurrState STATE_WRITEBACK->STATE_READY STATE_FLUSH->STATE_READY STATE_WRITE_LINE->STATE_READY STATE_FLUSH_WRITEBACK->STATE_READY
|
||||||
|
|
||||||
|
|
||||||
# Excluding peripherals as sources of instructions for the ifu
|
# Excluding peripherals as sources of instructions for the ifu
|
||||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/clintdec
|
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/clintdec
|
||||||
@ -112,3 +128,7 @@ set line [GetLineNum ../src/mmu/pmachecker.sv "WriteAccessM \\| ExecuteAccessF"]
|
|||||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 1-5
|
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 1-5
|
||||||
set line [GetLineNum ../src/mmu/pmachecker.sv "ReadAccessM \\| ExecuteAccessF"]
|
set line [GetLineNum ../src/mmu/pmachecker.sv "ReadAccessM \\| ExecuteAccessF"]
|
||||||
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 1-3
|
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 1-3
|
||||||
|
|
||||||
|
# Excluding reset and clear for impossible case in the wficountreg in privdec
|
||||||
|
set line [GetLineNum ../src/generic/flop/floprc.sv "reset \\| clear"]
|
||||||
|
coverage exclude -scope /dut/core/priv/priv/pmd/wfi/wficountreg -linerange $line-$line -item c 1 -feccondrow 2
|
||||||
|
@ -28,6 +28,7 @@ regressionDir = os.path.dirname(os.path.abspath(__file__))
|
|||||||
os.chdir(regressionDir)
|
os.chdir(regressionDir)
|
||||||
|
|
||||||
coverage = '-coverage' in sys.argv
|
coverage = '-coverage' in sys.argv
|
||||||
|
fp = '-fp' in sys.argv
|
||||||
|
|
||||||
TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr'])
|
TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr'])
|
||||||
# name: the name of this test configuration (used in printing human-readable
|
# name: the name of this test configuration (used in printing human-readable
|
||||||
@ -140,6 +141,9 @@ if (coverage): # delete all but 64gc tests when running coverage
|
|||||||
"arch64zi", "wally64a", "wally64periph", "wally64priv",
|
"arch64zi", "wally64a", "wally64periph", "wally64priv",
|
||||||
"arch64zba", "arch64zbb", "arch64zbc", "arch64zbs",
|
"arch64zba", "arch64zbb", "arch64zbc", "arch64zbs",
|
||||||
"imperas64f", "imperas64d", "imperas64c", "imperas64i"]
|
"imperas64f", "imperas64d", "imperas64c", "imperas64i"]
|
||||||
|
if (fp):
|
||||||
|
tests64gc.append("arch64f")
|
||||||
|
tests64gc.append("arch64d")
|
||||||
coverStr = '-coverage'
|
coverStr = '-coverage'
|
||||||
else:
|
else:
|
||||||
coverStr = ''
|
coverStr = ''
|
||||||
|
17
src/cache/cachefsm.sv
vendored
17
src/cache/cachefsm.sv
vendored
@ -69,7 +69,7 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
|||||||
);
|
);
|
||||||
|
|
||||||
logic resetDelay;
|
logic resetDelay;
|
||||||
logic AMO, StoreAMO;
|
logic StoreAMO;
|
||||||
logic AnyUpdateHit, AnyHit;
|
logic AnyUpdateHit, AnyHit;
|
||||||
logic AnyMiss;
|
logic AnyMiss;
|
||||||
logic FlushFlag;
|
logic FlushFlag;
|
||||||
@ -86,16 +86,15 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
|||||||
|
|
||||||
statetype CurrState, NextState;
|
statetype CurrState, NextState;
|
||||||
|
|
||||||
assign AMO = CacheAtomic[1] & (&CacheRW);
|
assign StoreAMO = CacheRW[0]; // AMO operations assert CacheRW[0]
|
||||||
assign StoreAMO = AMO | CacheRW[0];
|
|
||||||
|
|
||||||
assign AnyMiss = (StoreAMO | CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: icache storeAMO
|
assign AnyMiss = (StoreAMO | CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss
|
||||||
assign AnyUpdateHit = (StoreAMO) & CacheHit; // exclusion-tag: icache storeAMO1
|
assign AnyUpdateHit = (StoreAMO) & CacheHit; // exclusion-tag: icache storeAMO1
|
||||||
assign AnyHit = AnyUpdateHit | (CacheRW[1] & CacheHit); // exclusion-tag: icache AnyUpdateHit
|
assign AnyHit = AnyUpdateHit | (CacheRW[1] & CacheHit); // exclusion-tag: icache AnyUpdateHit
|
||||||
assign FlushFlag = FlushAdrFlag & FlushWayFlag;
|
assign FlushFlag = FlushAdrFlag & FlushWayFlag;
|
||||||
|
|
||||||
// outputs for the performance counters.
|
// outputs for the performance counters.
|
||||||
assign CacheAccess = (AMO | CacheRW[1] | CacheRW[0]) & CurrState == STATE_READY; // exclusion-tag: icache CacheW
|
assign CacheAccess = (|CacheRW) & CurrState == STATE_READY; // exclusion-tag: icache CacheW
|
||||||
assign CacheMiss = CacheAccess & ~CacheHit;
|
assign CacheMiss = CacheAccess & ~CacheHit;
|
||||||
|
|
||||||
// special case on reset. When the fsm first exists reset the
|
// special case on reset. When the fsm first exists reset the
|
||||||
@ -110,10 +109,10 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
|||||||
always_comb begin
|
always_comb begin
|
||||||
NextState = STATE_READY;
|
NextState = STATE_READY;
|
||||||
case (CurrState) // exclusion-tag: icache state-case
|
case (CurrState) // exclusion-tag: icache state-case
|
||||||
STATE_READY: if(InvalidateCache) NextState = STATE_READY;
|
STATE_READY: if(InvalidateCache) NextState = STATE_READY; // exclusion-tag: dcache InvalidateCheck
|
||||||
else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH;
|
else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH;
|
||||||
else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; // exclusion-tag: icache FETCHStatement
|
else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; // exclusion-tag: icache FETCHStatement
|
||||||
else if(AnyMiss & LineDirty) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
|
else if(AnyMiss) /* & LineDirty */ NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
|
||||||
else NextState = STATE_READY;
|
else NextState = STATE_READY;
|
||||||
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
|
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
|
||||||
else NextState = STATE_FETCH;
|
else NextState = STATE_FETCH;
|
||||||
@ -160,6 +159,8 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
|||||||
assign SelFlush = (CurrState == STATE_READY & FlushCache) |
|
assign SelFlush = (CurrState == STATE_READY & FlushCache) |
|
||||||
(CurrState == STATE_FLUSH) |
|
(CurrState == STATE_FLUSH) |
|
||||||
(CurrState == STATE_FLUSH_WRITEBACK);
|
(CurrState == STATE_FLUSH_WRITEBACK);
|
||||||
|
// coverage off -item e 1 -fecexprrow 1
|
||||||
|
// (state is always FLUSH_WRITEBACK when FlushWayFlag & CacheBusAck)
|
||||||
assign FlushAdrCntEn = (CurrState == STATE_FLUSH_WRITEBACK & FlushWayFlag & CacheBusAck) |
|
assign FlushAdrCntEn = (CurrState == STATE_FLUSH_WRITEBACK & FlushWayFlag & CacheBusAck) |
|
||||||
(CurrState == STATE_FLUSH & FlushWayFlag & ~LineDirty);
|
(CurrState == STATE_FLUSH & FlushWayFlag & ~LineDirty);
|
||||||
assign FlushWayCntEn = (CurrState == STATE_FLUSH & ~LineDirty) |
|
assign FlushWayCntEn = (CurrState == STATE_FLUSH & ~LineDirty) |
|
||||||
@ -181,6 +182,6 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
|||||||
(CurrState == STATE_WRITE_LINE) |
|
(CurrState == STATE_WRITE_LINE) |
|
||||||
resetDelay;
|
resetDelay;
|
||||||
assign SelFetchBuffer = CurrState == STATE_WRITE_LINE | CurrState == STATE_READ_HOLD;
|
assign SelFetchBuffer = CurrState == STATE_WRITE_LINE | CurrState == STATE_READ_HOLD;
|
||||||
assign CacheEn = (~Stall | FlushCache | AnyMiss) | (CurrState != STATE_READY) | reset | InvalidateCache;
|
assign CacheEn = (~Stall | FlushCache | AnyMiss) | (CurrState != STATE_READY) | reset | InvalidateCache; // exclusion-tag: dcache CacheEn
|
||||||
|
|
||||||
endmodule // cachefsm
|
endmodule // cachefsm
|
||||||
|
2
src/cache/cacheway.sv
vendored
2
src/cache/cacheway.sv
vendored
@ -155,7 +155,7 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
|||||||
if (reset) ValidBits <= #1 '0;
|
if (reset) ValidBits <= #1 '0;
|
||||||
if(CacheEn) begin
|
if(CacheEn) begin
|
||||||
ValidWay <= #1 ValidBits[CacheSet];
|
ValidWay <= #1 ValidBits[CacheSet];
|
||||||
if(InvalidateCache) ValidBits <= #1 '0;
|
if(InvalidateCache) ValidBits <= #1 '0; // exclusion-tag: dcache invalidateway
|
||||||
else if (SetValidEN) ValidBits[CacheSet] <= #1 SetValidWay;
|
else if (SetValidEN) ValidBits[CacheSet] <= #1 SetValidWay;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -138,10 +138,10 @@ module fctrl (
|
|||||||
endcase
|
endcase
|
||||||
7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000)
|
7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000)
|
||||||
ControlsD = `FCTRLW'b0_1_10_00_000_0_0_0; // fclass
|
ControlsD = `FCTRLW'b0_1_10_00_000_0_0_0; // fclass
|
||||||
else if (Funct3D == 3'b000 & Rs2D == 5'b00000)
|
else if (Funct3D == 3'b000 & Rs2D == 5'b00000 & SupportedFmt)
|
||||||
ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0; // fmv.x.w / fmv.x.d to int register
|
ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0; // fmv.x.w/d/h/q fp to int register
|
||||||
7'b111100?: if (Funct3D == 3'b000 & Rs2D == 5'b00000)
|
7'b111100?: if (Funct3D == 3'b000 & Rs2D == 5'b00000 & SupportedFmt)
|
||||||
ControlsD = `FCTRLW'b1_0_00_00_011_0_0_0; // fmv.w.x / fmv.d.x to fp reg
|
ControlsD = `FCTRLW'b1_0_00_00_011_0_0_0; // fmv.w/d/h/q.x int to fp reg
|
||||||
7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00)
|
7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00)
|
||||||
ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h)
|
ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h)
|
||||||
7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01)
|
7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01)
|
||||||
|
@ -57,43 +57,43 @@ module fdivsqrt(
|
|||||||
|
|
||||||
logic [`DIVb+3:0] WS, WC; // Partial remainder components
|
logic [`DIVb+3:0] WS, WC; // Partial remainder components
|
||||||
logic [`DIVb+3:0] X; // Iterator Initial Value (from dividend)
|
logic [`DIVb+3:0] X; // Iterator Initial Value (from dividend)
|
||||||
logic [`DIVb-1:0] DPreproc, D; // Iterator Divisor
|
logic [`DIVb+3:0] D; // Iterator Divisor
|
||||||
logic [`DIVb:0] FirstU, FirstUM; // Intermediate result values
|
logic [`DIVb:0] FirstU, FirstUM; // Intermediate result values
|
||||||
logic [`DIVb+1:0] FirstC; // Step tracker
|
logic [`DIVb+1:0] FirstC; // Step tracker
|
||||||
logic Firstun; // Quotient selection
|
logic Firstun; // Quotient selection
|
||||||
logic WZeroE; // Early termination flag
|
logic WZeroE; // Early termination flag
|
||||||
|
logic [`DURLEN-1:0] CyclesE; // FSM cycles
|
||||||
logic SpecialCaseM; // Divide by zero, square root of negative, etc.
|
logic SpecialCaseM; // Divide by zero, square root of negative, etc.
|
||||||
logic DivStartE; // Enable signal for flops during stall
|
logic DivStartE; // Enable signal for flops during stall
|
||||||
|
|
||||||
// Integer div/rem signals
|
// Integer div/rem signals
|
||||||
logic BZeroM; // Denominator is zero
|
logic BZeroM; // Denominator is zero
|
||||||
logic IntDivM; // Integer operation
|
logic IntDivM; // Integer operation
|
||||||
logic [`DIVBLEN:0] nE, nM, mM; // Shift amounts
|
logic [`DIVBLEN:0] nM, mM; // Shift amounts
|
||||||
logic NegQuotM, ALTBM, AsM, W64M; // Special handling for postprocessor
|
logic NegQuotM, ALTBM, AsM, W64M; // Special handling for postprocessor
|
||||||
logic [`XLEN-1:0] AM; // Original Numerator for postprocessor
|
logic [`XLEN-1:0] AM; // Original Numerator for postprocessor
|
||||||
logic ISpecialCaseE; // Integer div/remainder special cases
|
logic ISpecialCaseE; // Integer div/remainder special cases
|
||||||
|
|
||||||
fdivsqrtpreproc fdivsqrtpreproc( // Preprocessor
|
fdivsqrtpreproc fdivsqrtpreproc( // Preprocessor
|
||||||
.clk, .IFDivStartE, .Xm(XmE), .Ym(YmE), .Xe(XeE), .Ye(YeE),
|
.clk, .IFDivStartE, .Xm(XmE), .Ym(YmE), .Xe(XeE), .Ye(YeE),
|
||||||
.Fmt(FmtE), .Sqrt(SqrtE), .XZeroE, .Funct3E,
|
.FmtE, .SqrtE, .XZeroE, .Funct3E, .QeM, .X, .D, .CyclesE,
|
||||||
.QeM, .X, .DPreproc,
|
|
||||||
// Int-specific
|
// Int-specific
|
||||||
.ForwardedSrcAE, .ForwardedSrcBE, .IntDivE, .W64E, .ISpecialCaseE,
|
.ForwardedSrcAE, .ForwardedSrcBE, .IntDivE, .W64E, .ISpecialCaseE,
|
||||||
.nE, .BZeroM, .nM, .mM, .AM,
|
.BZeroM, .nM, .mM, .AM,
|
||||||
.IntDivM, .W64M, .NegQuotM, .ALTBM, .AsM);
|
.IntDivM, .W64M, .NegQuotM, .ALTBM, .AsM);
|
||||||
|
|
||||||
fdivsqrtfsm fdivsqrtfsm( // FSM
|
fdivsqrtfsm fdivsqrtfsm( // FSM
|
||||||
.clk, .reset, .FmtE, .XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE,
|
.clk, .reset, .XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE,
|
||||||
.FDivStartE, .XsE, .SqrtE, .WZeroE, .FlushE, .StallM,
|
.FDivStartE, .XsE, .SqrtE, .WZeroE, .FlushE, .StallM,
|
||||||
.FDivBusyE, .IFDivStartE, .FDivDoneE, .SpecialCaseM,
|
.FDivBusyE, .IFDivStartE, .FDivDoneE, .SpecialCaseM, .CyclesE,
|
||||||
// Int-specific
|
// Int-specific
|
||||||
.IDivStartE, .ISpecialCaseE, .nE, .IntDivE);
|
.IDivStartE, .ISpecialCaseE, .IntDivE);
|
||||||
|
|
||||||
fdivsqrtiter fdivsqrtiter( // CSA Iterator
|
fdivsqrtiter fdivsqrtiter( // CSA Iterator
|
||||||
.clk, .IFDivStartE, .FDivBusyE, .SqrtE, .X, .DPreproc,
|
.clk, .IFDivStartE, .FDivBusyE, .SqrtE, .X, .D,
|
||||||
.D, .FirstU, .FirstUM, .FirstC, .Firstun, .FirstWS(WS), .FirstWC(WC));
|
.FirstU, .FirstUM, .FirstC, .Firstun, .FirstWS(WS), .FirstWC(WC));
|
||||||
|
|
||||||
fdivsqrtpostproc fdivsqrtpostproc( // Postprocessor
|
fdivsqrtpostproc fdivsqrtpostproc( // Postprocessor
|
||||||
.clk, .reset, .StallM, .WS, .WC, .D, .FirstU, .FirstUM, .FirstC,
|
.clk, .reset, .StallM, .WS, .WC, .D, .FirstU, .FirstUM, .FirstC,
|
||||||
.SqrtE, .Firstun, .SqrtM, .SpecialCaseM,
|
.SqrtE, .Firstun, .SqrtM, .SpecialCaseM,
|
||||||
.QmM, .WZeroE, .DivStickyM,
|
.QmM, .WZeroE, .DivStickyM,
|
||||||
|
76
src/fpu/fdivsqrt/fdivsqrtcycles.sv
Normal file
76
src/fpu/fdivsqrt/fdivsqrtcycles.sv
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// fdivsqrtcycles.sv
|
||||||
|
//
|
||||||
|
// Written: David_Harris@hmc.edu, me@KatherineParry.com, cturek@hmc.edu, amaiuolo@hmc.edu
|
||||||
|
// Modified: 18 April 2022
|
||||||
|
//
|
||||||
|
// Purpose: Determine number of cycles for divsqrt
|
||||||
|
//
|
||||||
|
// Documentation: RISC-V System on Chip Design Chapter 13
|
||||||
|
//
|
||||||
|
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
//
|
||||||
|
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||||
|
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||||
|
// may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://solderpad.org/licenses/SHL-2.1/
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||||
|
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
// either express or implied. See the License for the specific language governing permissions
|
||||||
|
// and limitations under the License.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
`include "wally-config.vh"
|
||||||
|
|
||||||
|
module fdivsqrtcycles(
|
||||||
|
input logic [`FMTBITS-1:0] FmtE,
|
||||||
|
input logic SqrtE,
|
||||||
|
input logic IntDivE,
|
||||||
|
input logic [`DIVBLEN:0] nE,
|
||||||
|
output logic [`DURLEN-1:0] CyclesE
|
||||||
|
);
|
||||||
|
logic [`DURLEN+1:0] Nf, fbits; // number of fractional bits
|
||||||
|
// DIVN = `NF+3
|
||||||
|
// NS = NF + 1
|
||||||
|
// N = NS or NS+2 for div/sqrt.
|
||||||
|
|
||||||
|
/* verilator lint_off WIDTH */
|
||||||
|
if (`FPSIZES == 1)
|
||||||
|
assign Nf = `NF;
|
||||||
|
else if (`FPSIZES == 2)
|
||||||
|
always_comb
|
||||||
|
case (FmtE)
|
||||||
|
1'b0: Nf = `NF1;
|
||||||
|
1'b1: Nf = `NF;
|
||||||
|
endcase
|
||||||
|
else if (`FPSIZES == 3)
|
||||||
|
always_comb
|
||||||
|
case (FmtE)
|
||||||
|
`FMT: Nf = `NF;
|
||||||
|
`FMT1: Nf = `NF1;
|
||||||
|
`FMT2: Nf = `NF2;
|
||||||
|
endcase
|
||||||
|
else if (`FPSIZES == 4)
|
||||||
|
always_comb
|
||||||
|
case(FmtE)
|
||||||
|
`S_FMT: Nf = `S_NF;
|
||||||
|
`D_FMT: Nf = `D_NF;
|
||||||
|
`H_FMT: Nf = `H_NF;
|
||||||
|
`Q_FMT: Nf = `Q_NF;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
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
|
||||||
|
if (`IDIV_ON_FPU) CyclesE = IntDivE ? ((nE + 1)/`DIVCOPIES) : (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
|
||||||
|
else CyclesE = (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
|
||||||
|
end
|
||||||
|
/* verilator lint_on WIDTH */
|
||||||
|
|
||||||
|
endmodule
|
@ -29,32 +29,27 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module fdivsqrtfsm(
|
module fdivsqrtfsm(
|
||||||
input logic clk,
|
input logic clk, reset,
|
||||||
input logic reset,
|
input logic XInfE, YInfE,
|
||||||
input logic [`FMTBITS-1:0] FmtE,
|
input logic XZeroE, YZeroE,
|
||||||
input logic XInfE, YInfE,
|
input logic XNaNE, YNaNE,
|
||||||
input logic XZeroE, YZeroE,
|
input logic FDivStartE, IDivStartE,
|
||||||
input logic XNaNE, YNaNE,
|
input logic XsE, WZeroE,
|
||||||
input logic FDivStartE, IDivStartE,
|
input logic SqrtE,
|
||||||
input logic XsE,
|
input logic StallM, FlushE,
|
||||||
input logic SqrtE,
|
input logic IntDivE,
|
||||||
input logic StallM,
|
input logic ISpecialCaseE,
|
||||||
input logic FlushE,
|
input logic [`DURLEN-1:0] CyclesE,
|
||||||
input logic WZeroE,
|
output logic IFDivStartE,
|
||||||
input logic IntDivE,
|
output logic FDivBusyE, FDivDoneE,
|
||||||
input logic [`DIVBLEN:0] nE,
|
output logic SpecialCaseM
|
||||||
input logic ISpecialCaseE,
|
|
||||||
output logic IFDivStartE,
|
|
||||||
output logic FDivBusyE, FDivDoneE,
|
|
||||||
output logic SpecialCaseM
|
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype;
|
typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype;
|
||||||
statetype state;
|
statetype state;
|
||||||
|
|
||||||
logic [`DURLEN-1:0] step;
|
|
||||||
logic [`DURLEN-1:0] cycles;
|
|
||||||
logic SpecialCaseE, FSpecialCaseE;
|
logic SpecialCaseE, FSpecialCaseE;
|
||||||
|
logic [`DURLEN-1:0] step;
|
||||||
|
|
||||||
// FDivStartE and IDivStartE come from fctrl, reflecitng the start of floating-point and possibly integer division
|
// FDivStartE and IDivStartE come from fctrl, reflecitng the start of floating-point and possibly integer division
|
||||||
assign IFDivStartE = (FDivStartE | (IDivStartE & `IDIV_ON_FPU)) & (state == IDLE) & ~StallM;
|
assign IFDivStartE = (FDivStartE | (IDivStartE & `IDIV_ON_FPU)) & (state == IDLE) & ~StallM;
|
||||||
@ -67,53 +62,11 @@ module fdivsqrtfsm(
|
|||||||
else assign SpecialCaseE = FSpecialCaseE;
|
else assign SpecialCaseE = FSpecialCaseE;
|
||||||
flopenr #(1) SpecialCaseReg(clk, reset, IFDivStartE, SpecialCaseE, SpecialCaseM); // save SpecialCase for checking in fdivsqrtpostproc
|
flopenr #(1) SpecialCaseReg(clk, reset, IFDivStartE, SpecialCaseE, SpecialCaseM); // save SpecialCase for checking in fdivsqrtpostproc
|
||||||
|
|
||||||
// DIVN = `NF+3
|
|
||||||
// NS = NF + 1
|
|
||||||
// N = NS or NS+2 for div/sqrt.
|
|
||||||
|
|
||||||
// *** CT 4/13/23 move cycles calculation back to preprocesor
|
|
||||||
/* verilator lint_off WIDTH */
|
|
||||||
logic [`DURLEN+1:0] Nf, fbits; // number of fractional bits
|
|
||||||
if (`FPSIZES == 1)
|
|
||||||
assign Nf = `NF;
|
|
||||||
else if (`FPSIZES == 2)
|
|
||||||
always_comb
|
|
||||||
case (FmtE)
|
|
||||||
1'b0: Nf = `NF1;
|
|
||||||
1'b1: Nf = `NF;
|
|
||||||
endcase
|
|
||||||
else if (`FPSIZES == 3)
|
|
||||||
always_comb
|
|
||||||
case (FmtE)
|
|
||||||
`FMT: Nf = `NF;
|
|
||||||
`FMT1: Nf = `NF1;
|
|
||||||
`FMT2: Nf = `NF2;
|
|
||||||
endcase
|
|
||||||
else if (`FPSIZES == 4)
|
|
||||||
always_comb
|
|
||||||
case(FmtE)
|
|
||||||
`S_FMT: Nf = `S_NF;
|
|
||||||
`D_FMT: Nf = `D_NF;
|
|
||||||
`H_FMT: Nf = `H_NF;
|
|
||||||
`Q_FMT: Nf = `Q_NF;
|
|
||||||
endcase
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
if (`IDIV_ON_FPU) cycles = IntDivE ? ((nE + 1)/`DIVCOPIES) : (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
|
|
||||||
else cycles = (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
|
|
||||||
end
|
|
||||||
|
|
||||||
/* verilator lint_on WIDTH */
|
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
if (reset | FlushE) begin
|
if (reset | FlushE) begin
|
||||||
state <= #1 IDLE;
|
state <= #1 IDLE;
|
||||||
end else if (IFDivStartE) begin // IFDivStartE implies stat is IDLE
|
end else if (IFDivStartE) begin // IFDivStartE implies stat is IDLE
|
||||||
// end else if ((state == IDLE) & IFDivStartE) begin // IFDivStartE implies stat is IDLE
|
step <= CyclesE;
|
||||||
step <= cycles;
|
|
||||||
if (SpecialCaseE) state <= #1 DONE;
|
if (SpecialCaseE) state <= #1 DONE;
|
||||||
else state <= #1 BUSY;
|
else state <= #1 BUSY;
|
||||||
end else if (state == BUSY) begin
|
end else if (state == BUSY) begin
|
||||||
|
@ -33,9 +33,7 @@ module fdivsqrtiter(
|
|||||||
input logic IFDivStartE,
|
input logic IFDivStartE,
|
||||||
input logic FDivBusyE,
|
input logic FDivBusyE,
|
||||||
input logic SqrtE,
|
input logic SqrtE,
|
||||||
input logic [`DIVb+3:0] X,
|
input logic [`DIVb+3:0] X, D,
|
||||||
input logic [`DIVb-1:0] DPreproc,
|
|
||||||
output logic [`DIVb-1:0] D,
|
|
||||||
output logic [`DIVb:0] FirstU, FirstUM,
|
output logic [`DIVb:0] FirstU, FirstUM,
|
||||||
output logic [`DIVb+1:0] FirstC,
|
output logic [`DIVb+1:0] FirstC,
|
||||||
output logic Firstun,
|
output logic Firstun,
|
||||||
@ -95,16 +93,11 @@ module fdivsqrtiter(
|
|||||||
mux2 #(`DIVb+2) cmux(C[`DIVCOPIES], initC, IFDivStartE, NextC);
|
mux2 #(`DIVb+2) cmux(C[`DIVCOPIES], initC, IFDivStartE, NextC);
|
||||||
flopen #(`DIVb+2) creg(clk, FDivBusyE, NextC, C[0]);
|
flopen #(`DIVb+2) creg(clk, FDivBusyE, NextC, C[0]);
|
||||||
|
|
||||||
// Divisior register
|
|
||||||
flopen #(`DIVb) dreg(clk, IFDivStartE, DPreproc, D);
|
|
||||||
|
|
||||||
// Divisor Selections
|
// Divisor Selections
|
||||||
// - choose the negitive version of what's being selected
|
assign DBar = ~D; // for -D
|
||||||
// - D is a 0.b mantissa
|
|
||||||
assign DBar = {3'b111, 1'b0, ~D};
|
|
||||||
if(`RADIX == 4) begin : d2
|
if(`RADIX == 4) begin : d2
|
||||||
assign DBar2 = {2'b11, 1'b0, ~D, 1'b1};
|
assign D2 = D << 1; // for 2D, only used in R4
|
||||||
assign D2 = {2'b0, 1'b1, D, 1'b0};
|
assign DBar2 = ~D2; // for -2D, only used in R4
|
||||||
end
|
end
|
||||||
|
|
||||||
// k=DIVCOPIES of the recurrence logic
|
// k=DIVCOPIES of the recurrence logic
|
||||||
|
@ -32,7 +32,7 @@ module fdivsqrtpostproc(
|
|||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
input logic StallM,
|
input logic StallM,
|
||||||
input logic [`DIVb+3:0] WS, WC,
|
input logic [`DIVb+3:0] WS, WC,
|
||||||
input logic [`DIVb-1:0] D,
|
input logic [`DIVb+3: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 SqrtE,
|
input logic SqrtE,
|
||||||
@ -46,7 +46,7 @@ module fdivsqrtpostproc(
|
|||||||
output logic [`XLEN-1:0] FIntDivResultM
|
output logic [`XLEN-1:0] FIntDivResultM
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [`DIVb+3:0] W, Sum, DM;
|
logic [`DIVb+3:0] W, Sum;
|
||||||
logic [`DIVb:0] PreQmM;
|
logic [`DIVb:0] PreQmM;
|
||||||
logic NegStickyM;
|
logic NegStickyM;
|
||||||
logic weq0E, WZeroM;
|
logic weq0E, WZeroM;
|
||||||
@ -67,7 +67,7 @@ module fdivsqrtpostproc(
|
|||||||
|
|
||||||
assign FirstK = ({1'b1, FirstC} & ~({1'b1, FirstC} << 1));
|
assign FirstK = ({1'b1, FirstC} & ~({1'b1, FirstC} << 1));
|
||||||
assign FZeroSqrtE = {FirstUM[`DIVb], FirstUM, 2'b0} | {FirstK,1'b0}; // F for square root
|
assign FZeroSqrtE = {FirstUM[`DIVb], FirstUM, 2'b0} | {FirstK,1'b0}; // F for square root
|
||||||
assign FZeroDivE = {3'b001,D,1'b0}; // F for divide
|
assign FZeroDivE = D << 1; // F for divide
|
||||||
mux2 #(`DIVb+4) fzeromux(FZeroDivE, FZeroSqrtE, SqrtE, FZeroE);
|
mux2 #(`DIVb+4) fzeromux(FZeroDivE, FZeroSqrtE, SqrtE, FZeroE);
|
||||||
csa #(`DIVb+4) fadd(WS, WC, FZeroE, 1'b0, WSF, WCF); // compute {WCF, WSF} = {WS + WC + FZero};
|
csa #(`DIVb+4) fadd(WS, WC, FZeroE, 1'b0, WSF, WCF); // compute {WCF, WSF} = {WS + WC + FZero};
|
||||||
aplusbeq0 #(`DIVb+4) wcfpluswsfeq0(WCF, WSF, wfeq0E);
|
aplusbeq0 #(`DIVb+4) wcfpluswsfeq0(WCF, WSF, wfeq0E);
|
||||||
@ -102,11 +102,10 @@ module fdivsqrtpostproc(
|
|||||||
logic signed [`DIVb+3:0] PreResultM, PreIntResultM;
|
logic signed [`DIVb+3:0] PreResultM, PreIntResultM;
|
||||||
|
|
||||||
assign W = $signed(Sum) >>> `LOGR;
|
assign W = $signed(Sum) >>> `LOGR;
|
||||||
assign DM = {4'b0001, D};
|
|
||||||
assign UnsignedQuotM = {3'b000, PreQmM};
|
assign UnsignedQuotM = {3'b000, PreQmM};
|
||||||
|
|
||||||
// Integer remainder: sticky and sign correction muxes
|
// Integer remainder: sticky and sign correction muxes
|
||||||
mux2 #(`DIVb+4) normremdmux(W, W+DM, NegStickyM, NormRemDM);
|
mux2 #(`DIVb+4) normremdmux(W, W+D, NegStickyM, NormRemDM);
|
||||||
mux2 #(`DIVb+4) normremsmux(NormRemDM, -NormRemDM, AsM, NormRemM);
|
mux2 #(`DIVb+4) normremsmux(NormRemDM, -NormRemDM, AsM, NormRemM);
|
||||||
mux2 #(`DIVb+4) quotresmux(UnsignedQuotM, -UnsignedQuotM, NegQuotM, NormQuotM);
|
mux2 #(`DIVb+4) quotresmux(UnsignedQuotM, -UnsignedQuotM, NegQuotM, NormQuotM);
|
||||||
|
|
||||||
|
@ -33,54 +33,59 @@ module fdivsqrtpreproc (
|
|||||||
input logic IFDivStartE,
|
input logic IFDivStartE,
|
||||||
input logic [`NF:0] Xm, Ym,
|
input logic [`NF:0] Xm, Ym,
|
||||||
input logic [`NE-1:0] Xe, Ye,
|
input logic [`NE-1:0] Xe, Ye,
|
||||||
input logic [`FMTBITS-1:0] Fmt,
|
input logic [`FMTBITS-1:0] FmtE,
|
||||||
input logic Sqrt,
|
input logic SqrtE,
|
||||||
input logic XZeroE,
|
input logic XZeroE,
|
||||||
input logic [2:0] Funct3E,
|
input logic [2:0] Funct3E,
|
||||||
output logic [`NE+1:0] QeM,
|
output logic [`NE+1:0] QeM,
|
||||||
output logic [`DIVb+3:0] X,
|
output logic [`DIVb+3:0] X, D,
|
||||||
output logic [`DIVb-1:0] DPreproc,
|
|
||||||
// Int-specific
|
// Int-specific
|
||||||
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
||||||
input logic IntDivE, W64E,
|
input logic IntDivE, W64E,
|
||||||
output logic ISpecialCaseE,
|
output logic ISpecialCaseE,
|
||||||
output logic [`DIVBLEN:0] nE, nM, mM,
|
output logic [`DURLEN-1:0] CyclesE,
|
||||||
|
output logic [`DIVBLEN:0] nM, mM,
|
||||||
output logic NegQuotM, ALTBM, IntDivM, W64M,
|
output logic NegQuotM, ALTBM, IntDivM, W64M,
|
||||||
output logic AsM, BZeroM,
|
output logic AsM, BZeroM,
|
||||||
output logic [`XLEN-1:0] AM
|
output logic [`XLEN-1:0] AM
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [`DIVb-1:0] XPreproc;
|
logic [`DIVb-1:0] Xfract, Dfract;
|
||||||
logic [`DIVb:0] PreSqrtX;
|
logic [`DIVb:0] PreSqrtX;
|
||||||
logic [`DIVb+3:0] DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed
|
logic [`DIVb+3:0] DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed
|
||||||
logic [`NE+1:0] QeE; // Quotient Exponent (FP only)
|
logic [`NE+1:0] QeE; // Quotient Exponent (FP only)
|
||||||
logic [`DIVb-1:0] IFX, IFD; // Correctly-sized inputs for iterator, selected from int or fp input
|
logic [`DIVb-1:0] IFX, IFD; // Correctly-sized inputs for iterator, selected from int or fp input
|
||||||
logic [`DIVBLEN:0] mE, ell; // Leading zeros of inputs
|
logic [`DIVBLEN:0] mE, nE, ell; // Leading zeros of inputs
|
||||||
logic NumerZeroE; // Numerator is zero (X or A)
|
logic NumerZeroE; // Numerator is zero (X or A)
|
||||||
logic AZeroE, BZeroE; // A or B is Zero for integer division
|
logic AZeroE, BZeroE; // A or B is Zero for integer division
|
||||||
logic signedDiv; // signed division
|
logic SignedDivE; // signed division
|
||||||
logic NegQuotE; // Integer quotient is negative
|
logic NegQuotE; // Integer quotient is negative
|
||||||
logic AsE, BsE; // Signs of integer inputs
|
logic AsE, BsE; // Signs of integer inputs
|
||||||
logic [`XLEN-1:0] AE; // input A after W64 adjustment
|
logic [`XLEN-1:0] AE; // input A after W64 adjustment
|
||||||
|
logic ALTBE;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
// Integer Preprocessing
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
if (`IDIV_ON_FPU) begin:intpreproc // Int Supported
|
if (`IDIV_ON_FPU) begin:intpreproc // Int Supported
|
||||||
logic [`XLEN-1:0] BE, PosA, PosB;
|
logic [`XLEN-1:0] BE, PosA, PosB;
|
||||||
|
|
||||||
// Extract inputs, signs, zero, depending on W64 mode if applicable
|
// Extract inputs, signs, zero, depending on W64 mode if applicable
|
||||||
assign signedDiv = ~Funct3E[0];
|
assign SignedDivE = ~Funct3E[0];
|
||||||
|
|
||||||
// Source handling
|
// Source handling
|
||||||
if (`XLEN==64) begin // 64-bit, supports W64
|
if (`XLEN==64) begin // 64-bit, supports W64
|
||||||
mux2 #(64) amux(ForwardedSrcAE, {{32{ForwardedSrcAE[31] & signedDiv}}, ForwardedSrcAE[31:0]}, W64E, AE);
|
mux2 #(64) amux(ForwardedSrcAE, {{32{ForwardedSrcAE[31] & SignedDivE}}, ForwardedSrcAE[31:0]}, W64E, AE);
|
||||||
mux2 #(64) bmux(ForwardedSrcBE, {{32{ForwardedSrcBE[31] & signedDiv}}, ForwardedSrcBE[31:0]}, W64E, BE);
|
mux2 #(64) bmux(ForwardedSrcBE, {{32{ForwardedSrcBE[31] & SignedDivE}}, ForwardedSrcBE[31:0]}, W64E, BE);
|
||||||
end else begin // 32 bits only
|
end else begin // 32 bits only
|
||||||
assign AE = ForwardedSrcAE;
|
assign AE = ForwardedSrcAE;
|
||||||
assign BE = ForwardedSrcBE;
|
assign BE = ForwardedSrcBE;
|
||||||
end
|
end
|
||||||
assign AZeroE = ~(|AE);
|
assign AZeroE = ~(|AE);
|
||||||
assign BZeroE = ~(|BE);
|
assign BZeroE = ~(|BE);
|
||||||
assign AsE = AE[`XLEN-1] & signedDiv;
|
assign AsE = AE[`XLEN-1] & SignedDivE;
|
||||||
assign BsE = BE[`XLEN-1] & signedDiv;
|
assign BsE = BE[`XLEN-1] & SignedDivE;
|
||||||
assign NegQuotE = AsE ^ BsE; // Integer Quotient is negative
|
assign NegQuotE = AsE ^ BsE; // Integer Quotient is negative
|
||||||
|
|
||||||
// Force integer inputs to be postiive
|
// Force integer inputs to be postiive
|
||||||
@ -90,33 +95,35 @@ module fdivsqrtpreproc (
|
|||||||
// Select integer or floating point inputs
|
// Select integer or floating point inputs
|
||||||
mux2 #(`DIVb) ifxmux({Xm, {(`DIVb-`NF-1){1'b0}}}, {PosA, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFX);
|
mux2 #(`DIVb) ifxmux({Xm, {(`DIVb-`NF-1){1'b0}}}, {PosA, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFX);
|
||||||
mux2 #(`DIVb) ifdmux({Ym, {(`DIVb-`NF-1){1'b0}}}, {PosB, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFD);
|
mux2 #(`DIVb) ifdmux({Ym, {(`DIVb-`NF-1){1'b0}}}, {PosB, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFD);
|
||||||
|
mux2 #(1) numzmux(XZeroE, AZeroE, IntDivE, NumerZeroE);
|
||||||
|
|
||||||
end else begin // Int not supported
|
end else begin // Int not supported
|
||||||
assign IFX = {Xm, {(`DIVb-`NF-1){1'b0}}};
|
assign IFX = {Xm, {(`DIVb-`NF-1){1'b0}}};
|
||||||
assign IFD = {Ym, {(`DIVb-`NF-1){1'b0}}};
|
assign IFD = {Ym, {(`DIVb-`NF-1){1'b0}}};
|
||||||
|
assign NumerZeroE = XZeroE;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
// Integer & FP leading zero and normalization shift
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
// count leading zeros for Subnorm FP and to normalize integer inputs
|
// count leading zeros for Subnorm FP and to normalize integer inputs
|
||||||
lzc #(`DIVb) lzcX (IFX, ell);
|
lzc #(`DIVb) lzcX (IFX, ell);
|
||||||
lzc #(`DIVb) lzcY (IFD, mE);
|
lzc #(`DIVb) lzcY (IFD, mE);
|
||||||
|
|
||||||
// Normalization shift: shift off leading one
|
// Normalization shift: shift off leading one
|
||||||
assign XPreproc = (IFX << ell) << 1;
|
assign Xfract = (IFX << ell) << 1;
|
||||||
assign DPreproc = (IFD << mE) << 1;
|
assign Dfract = (IFD << mE) << 1;
|
||||||
|
|
||||||
// append leading 1 (for nonzero inputs)
|
// *** CT: move to fdivsqrtintpreshift
|
||||||
// shift square root to be in range [1/4, 1)
|
|
||||||
// Normalized numbers are shifted right by 1 if the exponent is odd
|
//////////////////////////////////////////////////////
|
||||||
// Denormalized numbers have Xe = 0 and an unbiased exponent of 1-BIAS. They are shifted right if the number of leading zeros is odd.
|
// Integer Right Shift to digit boundary
|
||||||
mux2 #(`DIVb+1) sqrtxmux({~XZeroE, XPreproc}, {1'b0, ~XZeroE, XPreproc[`DIVb-1:1]}, (Xe[0] ^ ell[0]), PreSqrtX);
|
// Determine DivXShifted (X shifted to digit boundary)
|
||||||
assign DivX = {3'b000, ~NumerZeroE, XPreproc};
|
// and nE (number of fractional digits)
|
||||||
// *** CT 4/13/23 Create D output here with leading 1 appended as well, use in the other modules
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
// ***CT: factor out fdivsqrtcycles
|
|
||||||
if (`IDIV_ON_FPU) begin:intrightshift // Int Supported
|
if (`IDIV_ON_FPU) begin:intrightshift // Int Supported
|
||||||
logic [`DIVBLEN:0] ZeroDiff, p;
|
logic [`DIVBLEN:0] ZeroDiff, p;
|
||||||
logic ALTBE;
|
|
||||||
|
|
||||||
// calculate number of fractional bits p
|
// calculate number of fractional bits p
|
||||||
assign ZeroDiff = mE - ell; // Difference in number of leading zeros
|
assign ZeroDiff = mE - ell; // Difference in number of leading zeros
|
||||||
@ -126,31 +133,68 @@ module fdivsqrtpreproc (
|
|||||||
// Integer special cases (terminate immediately)
|
// Integer special cases (terminate immediately)
|
||||||
assign ISpecialCaseE = BZeroE | ALTBE;
|
assign ISpecialCaseE = BZeroE | ALTBE;
|
||||||
|
|
||||||
/* verilator lint_off WIDTH */
|
|
||||||
// calculate number of fractional digits nE and right shift amount RightShiftX to complete in discrete number of steps
|
// calculate number of fractional digits nE and right shift amount RightShiftX to complete in discrete number of steps
|
||||||
|
|
||||||
if (`LOGRK > 0) begin // more than 1 bit per cycle
|
if (`LOGRK > 0) begin // more than 1 bit per cycle
|
||||||
logic [`LOGRK-1:0] IntTrunc, RightShiftX;
|
logic [`LOGRK-1:0] IntTrunc, RightShiftX;
|
||||||
logic [`DIVBLEN:0] TotalIntBits, IntSteps;
|
logic [`DIVBLEN:0] TotalIntBits, IntSteps;
|
||||||
|
/* verilator lint_off WIDTH */
|
||||||
assign TotalIntBits = `LOGR + p; // Total number of result bits (r integer bits plus p fractional bits)
|
assign TotalIntBits = `LOGR + p; // Total number of result bits (r integer bits plus p fractional bits)
|
||||||
assign IntTrunc = TotalIntBits % `RK; // Truncation check for ceiling operator
|
assign IntTrunc = TotalIntBits % `RK; // Truncation check for ceiling operator
|
||||||
assign IntSteps = (TotalIntBits >> `LOGRK) + |IntTrunc; // Number of steps for int div
|
assign IntSteps = (TotalIntBits >> `LOGRK) + |IntTrunc; // Number of steps for int div
|
||||||
assign nE = (IntSteps * `DIVCOPIES) - 1; // Fractional digits
|
assign nE = (IntSteps * `DIVCOPIES) - 1; // Fractional digits
|
||||||
assign RightShiftX = `RK - 1 - ((TotalIntBits - 1) % `RK); // Right shift amount
|
assign RightShiftX = `RK - 1 - ((TotalIntBits - 1) % `RK); // Right shift amount
|
||||||
assign DivXShifted = DivX >> RightShiftX; // shift X by up to R*K-1 to complete in nE steps
|
assign DivXShifted = DivX >> RightShiftX; // shift X by up to R*K-1 to complete in nE steps
|
||||||
|
/* verilator lint_on WIDTH */
|
||||||
end else begin // radix 2 1 copy doesn't require shifting
|
end else begin // radix 2 1 copy doesn't require shifting
|
||||||
assign nE = p;
|
assign nE = p;
|
||||||
assign DivXShifted = DivX;
|
assign DivXShifted = DivX;
|
||||||
end
|
end
|
||||||
/* verilator lint_on WIDTH */
|
end else begin
|
||||||
|
assign ISpecialCaseE = 0;
|
||||||
|
end
|
||||||
|
|
||||||
// Selet integer or floating-point operands
|
// CT *** fdivsqrtfplead1
|
||||||
mux2 #(1) numzmux(XZeroE, AZeroE, IntDivE, NumerZeroE);
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
// Floating-Point Preprocessing
|
||||||
|
// append leading 1 (for nonzero inputs)
|
||||||
|
// shift square root to be in range [1/4, 1)
|
||||||
|
// Normalized numbers are shifted right by 1 if the exponent is odd
|
||||||
|
// Denormalized numbers have Xe = 0 and an unbiased exponent of 1-BIAS. They are shifted right if the number of leading zeros is odd.
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
assign DivX = {3'b000, ~NumerZeroE, Xfract};
|
||||||
|
|
||||||
|
// Sqrt is initialized on step one as R(X-1), so depends on Radix
|
||||||
|
mux2 #(`DIVb+1) sqrtxmux({~XZeroE, Xfract}, {1'b0, ~XZeroE, Xfract[`DIVb-1:1]}, (Xe[0] ^ ell[0]), PreSqrtX);
|
||||||
|
if (`RADIX == 2) assign SqrtX = {3'b111, PreSqrtX};
|
||||||
|
else assign SqrtX = {2'b11, PreSqrtX, 1'b0};
|
||||||
|
mux2 #(`DIVb+4) prexmux(DivX, SqrtX, SqrtE, PreShiftX);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
// Selet integer or floating-point operands
|
||||||
|
//////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
if (`IDIV_ON_FPU) begin
|
||||||
mux2 #(`DIVb+4) xmux(PreShiftX, DivXShifted, IntDivE, X);
|
mux2 #(`DIVb+4) xmux(PreShiftX, DivXShifted, IntDivE, X);
|
||||||
|
end else begin
|
||||||
|
assign X = PreShiftX;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Divisior register
|
||||||
|
flopen #(`DIVb+4) dreg(clk, IFDivStartE, {4'b0001, Dfract}, D);
|
||||||
|
|
||||||
|
// Floating-point exponent
|
||||||
|
fdivsqrtexpcalc expcalc(.Fmt(FmtE), .Xe, .Ye, .Sqrt(SqrtE), .XZero(XZeroE), .ell, .m(mE), .Qe(QeE));
|
||||||
|
flopen #(`NE+2) expreg(clk, IFDivStartE, QeE, QeM);
|
||||||
|
|
||||||
|
// Number of FSM cycles (to FSM)
|
||||||
|
fdivsqrtcycles cyclecalc(.FmtE, .SqrtE, .IntDivE, .nE, .CyclesE);
|
||||||
|
|
||||||
|
if (`IDIV_ON_FPU) begin:intpipelineregs
|
||||||
// pipeline registers
|
// pipeline registers
|
||||||
flopen #(1) mdureg(clk, IFDivStartE, IntDivE, IntDivM);
|
flopen #(1) mdureg(clk, IFDivStartE, IntDivE, IntDivM);
|
||||||
flopen #(1) altbreg(clk, IFDivStartE, ALTBE, ALTBM);
|
flopen #(1) altbreg(clk, IFDivStartE, ALTBE, ALTBM);
|
||||||
flopen #(1) negquotreg(clk, IFDivStartE, NegQuotE, NegQuotM);
|
flopen #(1) negquotreg(clk, IFDivStartE, NegQuotE, NegQuotM);
|
||||||
flopen #(1) bzeroreg(clk, IFDivStartE, BZeroE, BZeroM);
|
flopen #(1) bzeroreg(clk, IFDivStartE, BZeroE, BZeroM);
|
||||||
@ -160,18 +204,7 @@ module fdivsqrtpreproc (
|
|||||||
flopen #(`XLEN) srcareg(clk, IFDivStartE, AE, AM);
|
flopen #(`XLEN) srcareg(clk, IFDivStartE, AE, AM);
|
||||||
if (`XLEN==64)
|
if (`XLEN==64)
|
||||||
flopen #(1) w64reg(clk, IFDivStartE, W64E, W64M);
|
flopen #(1) w64reg(clk, IFDivStartE, W64E, W64M);
|
||||||
end else begin
|
|
||||||
assign NumerZeroE = XZeroE;
|
|
||||||
assign X = PreShiftX;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
// Sqrt is initialized on step one as R(X-1), so depends on Radix
|
|
||||||
if (`RADIX == 2) assign SqrtX = {3'b111, PreSqrtX};
|
|
||||||
else assign SqrtX = {2'b11, PreSqrtX, 1'b0};
|
|
||||||
mux2 #(`DIVb+4) prexmux(DivX, SqrtX, Sqrt, PreShiftX);
|
|
||||||
|
|
||||||
// Floating-point exponent
|
|
||||||
fdivsqrtexpcalc expcalc(.Fmt, .Xe, .Ye, .Sqrt, .XZero(XZeroE), .ell, .m(mE), .Qe(QeE));
|
|
||||||
flopen #(`NE+2) expreg(clk, IFDivStartE, QeE, QeM);
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -30,8 +30,7 @@
|
|||||||
|
|
||||||
/* verilator lint_off UNOPTFLAT */
|
/* verilator lint_off UNOPTFLAT */
|
||||||
module fdivsqrtstage2 (
|
module fdivsqrtstage2 (
|
||||||
input logic [`DIVb-1:0] D,
|
input logic [`DIVb+3:0] D, DBar,
|
||||||
input logic [`DIVb+3:0] DBar,
|
|
||||||
input logic [`DIVb:0] U, UM,
|
input logic [`DIVb:0] U, UM,
|
||||||
input logic [`DIVb+3:0] WS, WC,
|
input logic [`DIVb+3:0] WS, WC,
|
||||||
input logic [`DIVb+1:0] C,
|
input logic [`DIVb+1:0] C,
|
||||||
@ -66,7 +65,7 @@ module fdivsqrtstage2 (
|
|||||||
always_comb
|
always_comb
|
||||||
if (up) Dsel = DBar;
|
if (up) Dsel = DBar;
|
||||||
else if (uz) Dsel = '0;
|
else if (uz) Dsel = '0;
|
||||||
else Dsel = {4'b0001, D}; // un
|
else Dsel = D; // un
|
||||||
|
|
||||||
// Partial Product Generation
|
// Partial Product Generation
|
||||||
// WSA, WCA = WS + WC - qD
|
// WSA, WCA = WS + WC - qD
|
||||||
|
@ -29,8 +29,7 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module fdivsqrtstage4 (
|
module fdivsqrtstage4 (
|
||||||
input logic [`DIVb-1:0] D,
|
input logic [`DIVb+3:0] D, DBar, D2, DBar2,
|
||||||
input logic [`DIVb+3:0] DBar, D2, DBar2,
|
|
||||||
input logic [`DIVb:0] U,UM,
|
input logic [`DIVb:0] U,UM,
|
||||||
input logic [`DIVb+3:0] WS, WC,
|
input logic [`DIVb+3:0] WS, WC,
|
||||||
input logic [`DIVb+1:0] C,
|
input logic [`DIVb+1:0] C,
|
||||||
@ -75,7 +74,7 @@ module fdivsqrtstage4 (
|
|||||||
4'b1000: Dsel = DBar2;
|
4'b1000: Dsel = DBar2;
|
||||||
4'b0100: Dsel = DBar;
|
4'b0100: Dsel = DBar;
|
||||||
4'b0000: Dsel = '0;
|
4'b0000: Dsel = '0;
|
||||||
4'b0010: Dsel = {3'b0, 1'b1, D};
|
4'b0010: Dsel = D;
|
||||||
4'b0001: Dsel = D2;
|
4'b0001: Dsel = D2;
|
||||||
default: Dsel = 'x;
|
default: Dsel = 'x;
|
||||||
endcase
|
endcase
|
||||||
|
@ -171,7 +171,8 @@ module csrm #(parameter
|
|||||||
IllegalCSRMAccessM = !(`S_SUPPORTED) & (CSRAdrM == MEDELEG | CSRAdrM == MIDELEG); // trap on DELEG register access when no S or N-mode
|
IllegalCSRMAccessM = !(`S_SUPPORTED) & (CSRAdrM == MEDELEG | CSRAdrM == MIDELEG); // trap on DELEG register access when no S or N-mode
|
||||||
if (CSRAdrM >= PMPADDR0 & CSRAdrM < PMPADDR0 + `PMP_ENTRIES) // reading a PMP entry
|
if (CSRAdrM >= PMPADDR0 & CSRAdrM < PMPADDR0 + `PMP_ENTRIES) // reading a PMP entry
|
||||||
CSRMReadValM = {{(`XLEN-(`PA_BITS-2)){1'b0}}, PMPADDR_ARRAY_REGW[CSRAdrM - PMPADDR0]};
|
CSRMReadValM = {{(`XLEN-(`PA_BITS-2)){1'b0}}, PMPADDR_ARRAY_REGW[CSRAdrM - PMPADDR0]};
|
||||||
else if (CSRAdrM >= PMPCFG0 & CSRAdrM < PMPCFG0 + `PMP_ENTRIES/4) begin
|
else if (CSRAdrM >= PMPCFG0 & CSRAdrM < PMPCFG0 + `PMP_ENTRIES/4 & (`XLEN==32 | CSRAdrM[0] == 0)) begin
|
||||||
|
// only odd-numbered PMPCFG entries exist in RV64
|
||||||
if (`XLEN==64) begin
|
if (`XLEN==64) begin
|
||||||
entry = ({CSRAdrM[11:1], 1'b0} - PMPCFG0)*4; // disregard odd entries in RV64
|
entry = ({CSRAdrM[11:1], 1'b0} - PMPCFG0)*4; // disregard odd entries in RV64
|
||||||
CSRMReadValM = {PMPCFG_ARRAY_REGW[entry+7],PMPCFG_ARRAY_REGW[entry+6],PMPCFG_ARRAY_REGW[entry+5],PMPCFG_ARRAY_REGW[entry+4],
|
CSRMReadValM = {PMPCFG_ARRAY_REGW[entry+7],PMPCFG_ARRAY_REGW[entry+6],PMPCFG_ARRAY_REGW[entry+5],PMPCFG_ARRAY_REGW[entry+4],
|
||||||
|
@ -122,7 +122,10 @@ module csrsr (
|
|||||||
logic [1:0] EndiannessPrivMode;
|
logic [1:0] EndiannessPrivMode;
|
||||||
always_comb begin
|
always_comb begin
|
||||||
if (SelHPTW) EndiannessPrivMode = `S_MODE;
|
if (SelHPTW) EndiannessPrivMode = `S_MODE;
|
||||||
|
//coverage off -item c 1 -feccondrow 1
|
||||||
|
// status.MPRV always gets reset upon leaving machine mode, so MPRV will never be high when out of machine mode
|
||||||
else if (PrivilegeModeW == `M_MODE & STATUS_MPRV) EndiannessPrivMode = STATUS_MPP;
|
else if (PrivilegeModeW == `M_MODE & STATUS_MPRV) EndiannessPrivMode = STATUS_MPP;
|
||||||
|
//coverage on
|
||||||
else EndiannessPrivMode = PrivilegeModeW;
|
else EndiannessPrivMode = PrivilegeModeW;
|
||||||
|
|
||||||
case (EndiannessPrivMode)
|
case (EndiannessPrivMode)
|
||||||
|
@ -53,7 +53,17 @@ string tvpaths[] = '{
|
|||||||
"lsu",
|
"lsu",
|
||||||
"vm64check",
|
"vm64check",
|
||||||
"pmp",
|
"pmp",
|
||||||
"tlbKP"
|
"dcache1",
|
||||||
|
"dcache2",
|
||||||
|
"pmpcfg",
|
||||||
|
"pmpcfg1",
|
||||||
|
"pmpcfg2",
|
||||||
|
"tlbKP",
|
||||||
|
"tlbMP",
|
||||||
|
"tlbM3",
|
||||||
|
"tlbASID",
|
||||||
|
"tlbGLB",
|
||||||
|
"ifuCamlineWrite"
|
||||||
};
|
};
|
||||||
|
|
||||||
string coremark[] = '{
|
string coremark[] = '{
|
||||||
|
@ -63,6 +63,9 @@ trap_handler:
|
|||||||
bgez t0, exception # if msb is clear, it is an exception
|
bgez t0, exception # if msb is clear, it is an exception
|
||||||
|
|
||||||
interrupt: # must be a timer interrupt
|
interrupt: # must be a timer interrupt
|
||||||
|
li t0, -1 # set mtimecmp to biggest number so it doesnt interrupt again
|
||||||
|
li t1, 0x02004000 # MTIMECMP in CLINT
|
||||||
|
sd t0, 0(t1)
|
||||||
j trap_return # clean up and return
|
j trap_return # clean up and return
|
||||||
|
|
||||||
exception:
|
exception:
|
||||||
|
83
tests/coverage/dcache1.S
Normal file
83
tests/coverage/dcache1.S
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#include "WALLY-init-lib.h"
|
||||||
|
main:
|
||||||
|
// start way test #1
|
||||||
|
li t0, 0x80100000
|
||||||
|
.align 6
|
||||||
|
// i$ boundary, way test #1
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
sd zero, 0(t0)
|
||||||
|
sd zero, 0(t0)
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
// start way test #2
|
||||||
|
li t0, 0x80101000
|
||||||
|
.align 6
|
||||||
|
// i$ boundary, way test #2
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
sd zero, 0(t0)
|
||||||
|
sd zero, 0(t0)
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
// start way test #3
|
||||||
|
li t0, 0x80102000
|
||||||
|
.align 6
|
||||||
|
// i$ boundary, way test #3
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
sd zero, 0(t0)
|
||||||
|
sd zero, 0(t0)
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
// start way test #4
|
||||||
|
li t0, 0x80103000
|
||||||
|
.align 6
|
||||||
|
// i$ boundary, way test #4
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
sd zero, 0(t0)
|
||||||
|
sd zero, 0(t0)
|
||||||
|
.word 0x00000013
|
||||||
|
.word 0x00000013
|
||||||
|
j done
|
86
tests/coverage/dcache1.py
Normal file
86
tests/coverage/dcache1.py
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
####################
|
||||||
|
# dcache1.py
|
||||||
|
#
|
||||||
|
# Written: avercruysse@hmc.edu 18 April 2023
|
||||||
|
#
|
||||||
|
# Purpose: Test Coverage for D$
|
||||||
|
# (For each way, trigger a CacheDataMem write enable while chip enable is low)
|
||||||
|
#
|
||||||
|
# A component of the CORE-V-WALLY configurable RISC-V project.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
#
|
||||||
|
# Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||||
|
# except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||||
|
# may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://solderpad.org/licenses/SHL-2.1/
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||||
|
# License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
# either express or implied. See the License for the specific language governing permissions
|
||||||
|
# and limitations under the License.
|
||||||
|
################################################
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
test_name = "dcache1.S"
|
||||||
|
dcache_num_ways = 4
|
||||||
|
dcache_way_size_in_bytes = 4096
|
||||||
|
# warning i$ line size is not currently parameterized.
|
||||||
|
|
||||||
|
# arbitrary start location of where I send stores to.
|
||||||
|
mem_start_addr = 0x80100000
|
||||||
|
|
||||||
|
# pointer to the start of unused memory (strictly increasing)
|
||||||
|
mem_addr = mem_start_addr
|
||||||
|
|
||||||
|
|
||||||
|
def wl(line="", comment=None, fname=test_name):
|
||||||
|
with open(fname, "a") as f:
|
||||||
|
instr = False if (":" in line or
|
||||||
|
".align" in line or
|
||||||
|
"# include" in line) else True
|
||||||
|
indent = 6 if instr else 0
|
||||||
|
comment = "// " + comment if comment is not None else ""
|
||||||
|
to_write = " " * indent + line + comment + "\n"
|
||||||
|
f.write(to_write)
|
||||||
|
|
||||||
|
|
||||||
|
def write_repro_instrs():
|
||||||
|
"""
|
||||||
|
Assumes that the store location has been fetched to d$, and is in t0.
|
||||||
|
"""
|
||||||
|
for i in range(16): # write a whole cache set.
|
||||||
|
if i == 12:
|
||||||
|
wl('sd zero, 0(t0)') # D$ write to set PCM = PCF + 8 for proper alignment (stallD will happen).
|
||||||
|
elif i == 13:
|
||||||
|
# the store in question happens here, at adresses 0x34, 0x74
|
||||||
|
wl('sd zero, 0(t0)') # it should hit this time
|
||||||
|
else:
|
||||||
|
# can't be a NOP or anything else that is encoded as compressed.
|
||||||
|
# this is because the branch predictor will use the wrong address
|
||||||
|
# so the IFU cache miss will come late.
|
||||||
|
wl('.word 0x00000013') # addi x0, x0, 0 (canonical NOP, uncompressed).
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if os.path.exists(test_name):
|
||||||
|
os.remove(test_name)
|
||||||
|
# os.rename(test_name, test_name + ".old")
|
||||||
|
wl(comment="This file is generated by dcache1.py (run that script manually)")
|
||||||
|
wl('#include "WALLY-init-lib.h"')
|
||||||
|
wl('main:')
|
||||||
|
|
||||||
|
# excercise all 4 D$ ways. If they're not all full, it uses the first empty.
|
||||||
|
# So we are sure all 4 ways are exercised.
|
||||||
|
for i in range(dcache_num_ways):
|
||||||
|
wl(comment=f"start way test #{i+1}")
|
||||||
|
wl(f'li t0, {hex(mem_addr)}')
|
||||||
|
wl(f'.align 6') # start at i$ set boundary. 6 lsb bits are zero.
|
||||||
|
wl(comment=f"i$ boundary, way test #{i+1}")
|
||||||
|
write_repro_instrs()
|
||||||
|
mem_addr += dcache_way_size_in_bytes # so that we excercise a new D$ way.
|
||||||
|
|
||||||
|
wl("j done")
|
49
tests/coverage/dcache2.S
Normal file
49
tests/coverage/dcache2.S
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// dcache2.S
|
||||||
|
//
|
||||||
|
// Written: avercruysse@hmc.edu 18 April 2023
|
||||||
|
//
|
||||||
|
// Purpose: Test Coverage for D$
|
||||||
|
// (for all 4 cache ways, trigger a FlushStage while SetDirtyWay=1)
|
||||||
|
//
|
||||||
|
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
//
|
||||||
|
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||||
|
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||||
|
// may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://solderpad.org/licenses/SHL-2.1/
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||||
|
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
// either express or implied. See the License for the specific language governing permissions
|
||||||
|
// and limitations under the License.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "WALLY-init-lib.h"
|
||||||
|
main:
|
||||||
|
// way 0
|
||||||
|
li t0, 0x80100770
|
||||||
|
sd zero, 0(t0)
|
||||||
|
sd zero, 1(t0)
|
||||||
|
|
||||||
|
// way 1
|
||||||
|
li t0, 0x80101770
|
||||||
|
sd zero, 0(t0)
|
||||||
|
sd zero, 1(t0)
|
||||||
|
|
||||||
|
// way 2
|
||||||
|
li t0, 0x80102770
|
||||||
|
sd zero, 0(t0)
|
||||||
|
sd zero, 1(t0)
|
||||||
|
|
||||||
|
// way 3
|
||||||
|
li t0, 0x80103770
|
||||||
|
sd zero, 0(t0)
|
||||||
|
sd zero, 1(t0)
|
||||||
|
|
||||||
|
j done
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
main:
|
main:
|
||||||
|
|
||||||
#bseti t0, zero, 14 # turn on FPU
|
bseti t0, zero, 14 # turn on FPU
|
||||||
csrs mstatus, t0
|
csrs mstatus, t0
|
||||||
|
|
||||||
#Pull denormalized FP number from memory and pass it to fclass.S for coverage
|
#Pull denormalized FP number from memory and pass it to fclass.S for coverage
|
||||||
@ -105,6 +105,25 @@ main:
|
|||||||
# fcvt.w.q a0, ft0
|
# fcvt.w.q a0, ft0
|
||||||
# fcvt.q.d ft3, ft0
|
# fcvt.q.d ft3, ft0
|
||||||
|
|
||||||
|
// fdivsqrt: test busy->idle transition caused by a FlushE while divider is busy (when interrupt arrives)
|
||||||
|
// This code doesn't actually trigger a busy->idle transition because the pending timer interrupt doesn't occur until the division finishes.
|
||||||
|
li t0, 0x3F812345 # random value slightly bigger than 1
|
||||||
|
li t1, 0x3F823456
|
||||||
|
fmv.w.x ft0, t0 # move int to fp register
|
||||||
|
fmv.w.x ft1, t1
|
||||||
|
li t0, -1 # set mtimecmp to biggest number so it doesnt interrupt again
|
||||||
|
li t1, 0x02004000 # MTIMECMP in CLINT
|
||||||
|
sd t0, 0(t1)
|
||||||
|
csrsi mstatus, 0b1000 # enable interrupts with mstatus.MIE
|
||||||
|
li t1, 0x0200bff8 # read MTIME in CLINT
|
||||||
|
ld t0, 0(t1)
|
||||||
|
addi t0, t0, 11
|
||||||
|
li t1, 0x02004000 # MTIMECMP in CLINT
|
||||||
|
sd t0, 0(t1) # write mtime+10 to cause interrupt soon This is very touchy timing and is sensitive to cache line fetch latency
|
||||||
|
nop
|
||||||
|
fdiv.s ft2, ft1, ft0 # should get interrupted, triggering a flush
|
||||||
|
csrci mstatus, 0b1000 # disable interrupts with mstatus.MIE
|
||||||
|
|
||||||
# Completing branch coverage in fctrl.sv
|
# Completing branch coverage in fctrl.sv
|
||||||
.word 0x38007553 // Testing the all False case for 119 - funct7 under, op = 101 0011
|
.word 0x38007553 // Testing the all False case for 119 - funct7 under, op = 101 0011
|
||||||
.word 0x40000053 // Line 145 All False Test case - illegal instruction?
|
.word 0x40000053 // Line 145 All False Test case - illegal instruction?
|
||||||
@ -146,3 +165,4 @@ TestData2:
|
|||||||
.int 0xbf800000 #FP -1.0
|
.int 0xbf800000 #FP -1.0
|
||||||
.int 0x7fa00000 #SNaN
|
.int 0x7fa00000 #SNaN
|
||||||
.int 0x3fffffff #OverFlow Test
|
.int 0x3fffffff #OverFlow Test
|
||||||
|
DivTestData:
|
||||||
|
146
tests/coverage/ifuCamlineWrite.S
Normal file
146
tests/coverage/ifuCamlineWrite.S
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// ifuCamlineWrite.S
|
||||||
|
//
|
||||||
|
// Written: Miles Cook <mdcook@g.hmc.edu> and Kevin Box <kbox@g.hmc.edu> 4/17
|
||||||
|
//
|
||||||
|
// Acknowledgements: The pagetable and outline for this test was written by Manuel Mendoza
|
||||||
|
// and Noah Limpert.
|
||||||
|
//
|
||||||
|
// Purpose: Test coverage for TLBCamlines in IFU
|
||||||
|
//
|
||||||
|
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
//
|
||||||
|
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||||
|
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||||
|
// may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://solderpad.org/licenses/SHL-2.1/
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||||
|
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
// either express or implied. See the License for the specific language governing permissions
|
||||||
|
// and limitations under the License.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// load code to initalize stack, handle interrupts, terminate
|
||||||
|
|
||||||
|
#include "WALLY-init-lib.h"
|
||||||
|
|
||||||
|
# run-elf.bash find this in project description
|
||||||
|
main:
|
||||||
|
# Page table root address at 0x80010000
|
||||||
|
li t5, 0x9000000000080010
|
||||||
|
csrw satp, t5
|
||||||
|
|
||||||
|
# switch to supervisor mode
|
||||||
|
li a0, 1
|
||||||
|
ecall
|
||||||
|
|
||||||
|
li t0, 0x80015000 # base addr
|
||||||
|
|
||||||
|
li t2, 0 # i = 0
|
||||||
|
li t3, 33 # Max amount of Loops = 32
|
||||||
|
|
||||||
|
loop: bge t2, t3, finished # exit loop if i >= loops
|
||||||
|
li t4, 0x1000
|
||||||
|
li t1, 0x00008067 # load in jalr
|
||||||
|
sw t1, 0 (t0)
|
||||||
|
fence.I
|
||||||
|
jalr t0
|
||||||
|
add t0, t0, t4
|
||||||
|
addi t2, t2, 1
|
||||||
|
j loop
|
||||||
|
|
||||||
|
finished:
|
||||||
|
j done
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
# Page table situated at 0x80010000
|
||||||
|
pagetable:
|
||||||
|
.8byte 0x200044C1 // old page table was 200040 which just pointed to itself! wrong
|
||||||
|
|
||||||
|
.align 12
|
||||||
|
.8byte 0x0000000000000000
|
||||||
|
.8byte 0x00000000200048C1
|
||||||
|
.8byte 0x00000000200048C1
|
||||||
|
|
||||||
|
|
||||||
|
.align 12
|
||||||
|
.8byte 0x0000000020004CC1
|
||||||
|
//.8byte 0x00000200800CF// ADD IN THE MEGAPAGE should 3 nibbles of zeros be removed?
|
||||||
|
|
||||||
|
.align 12
|
||||||
|
#80000000
|
||||||
|
.8byte 0x200000CF
|
||||||
|
.8byte 0x200004CF
|
||||||
|
.8byte 0x200008CF
|
||||||
|
.8byte 0x20000CCF
|
||||||
|
|
||||||
|
.8byte 0x200010CF
|
||||||
|
.8byte 0x200014CF
|
||||||
|
.8byte 0x200018CF
|
||||||
|
.8byte 0x20001CCF
|
||||||
|
|
||||||
|
.8byte 0x200020CF
|
||||||
|
.8byte 0x200024CF
|
||||||
|
.8byte 0x200028CF
|
||||||
|
.8byte 0x20002CCF
|
||||||
|
|
||||||
|
.8byte 0x200030CF
|
||||||
|
.8byte 0x200034CF
|
||||||
|
.8byte 0x200038CF
|
||||||
|
.8byte 0x20003CCF
|
||||||
|
|
||||||
|
.8byte 0x200040CF
|
||||||
|
.8byte 0x200044CF
|
||||||
|
.8byte 0x200048CF
|
||||||
|
.8byte 0x20004CCF
|
||||||
|
|
||||||
|
.8byte 0x200050CF
|
||||||
|
.8byte 0x200054CF
|
||||||
|
.8byte 0x200058CF
|
||||||
|
.8byte 0x20005CCF
|
||||||
|
|
||||||
|
.8byte 0x200060CF
|
||||||
|
.8byte 0x200064CF
|
||||||
|
.8byte 0x200068CF
|
||||||
|
.8byte 0x20006CCF
|
||||||
|
|
||||||
|
.8byte 0x200070CF
|
||||||
|
.8byte 0x200074CF
|
||||||
|
.8byte 0x200078CF
|
||||||
|
.8byte 0x20007CCF
|
||||||
|
|
||||||
|
.8byte 0x200080CF
|
||||||
|
.8byte 0x200084CF
|
||||||
|
.8byte 0x200088CF
|
||||||
|
.8byte 0x20008CCF
|
||||||
|
|
||||||
|
.8byte 0x200090CF
|
||||||
|
.8byte 0x200094CF
|
||||||
|
.8byte 0x200098CF
|
||||||
|
.8byte 0x20009CCF
|
||||||
|
|
||||||
|
.8byte 0x200100CF
|
||||||
|
.8byte 0x200104CF
|
||||||
|
.8byte 0x200108CF
|
||||||
|
.8byte 0x20010CCF
|
||||||
|
|
||||||
|
.8byte 0x200110CF
|
||||||
|
.8byte 0x200114CF
|
||||||
|
.8byte 0x200118CF
|
||||||
|
.8byte 0x20011CCF
|
||||||
|
|
||||||
|
.8byte 0x200120CF
|
||||||
|
.8byte 0x200124CF
|
||||||
|
.8byte 0x200128CF
|
||||||
|
.8byte 0x20012CCF
|
||||||
|
|
||||||
|
.8byte 0x200130CF
|
||||||
|
.8byte 0x200134CF
|
106
tests/coverage/pmpcfg.S
Normal file
106
tests/coverage/pmpcfg.S
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
// pmpcfg part 1
|
||||||
|
// Kevin Wan, kewan@hmc.edu, 4/18/2023
|
||||||
|
// Liam Chalk, lchalk@hmc.edu, 4/25/2023
|
||||||
|
// locks each pmpXcfg bit field in order, from X = 15 to X = 0, with the A[1:0] field set to TOR.
|
||||||
|
// See the next part in pmpcfg1.S
|
||||||
|
|
||||||
|
#include "WALLY-init-lib.h"
|
||||||
|
main:
|
||||||
|
|
||||||
|
li t0, 0x90000000
|
||||||
|
csrw pmpaddr0, t0
|
||||||
|
li t0, 0x00000017
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
|
||||||
|
li t0, 0x90000000
|
||||||
|
csrw pmpaddr2, t0
|
||||||
|
li t0, 0x00000017
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
|
||||||
|
li t0, 0x90000000
|
||||||
|
csrw pmpaddr0, t0
|
||||||
|
li t0, 0x00001700
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
|
||||||
|
li t0, 0x90000000
|
||||||
|
csrw pmpaddr0, t0
|
||||||
|
li t0, 0x00001700
|
||||||
|
csrw pmpcfg1, t0
|
||||||
|
|
||||||
|
li t0, 0x90000000
|
||||||
|
csrw pmpaddr0, t0
|
||||||
|
li t0, 0x00001700
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
|
||||||
|
li t0, 0x90000000
|
||||||
|
csrw pmpaddr0, t0
|
||||||
|
li t0, 0x00001700
|
||||||
|
csrw pmpcfg3, t0
|
||||||
|
|
||||||
|
li t0, 0x90000000
|
||||||
|
csrw pmpaddr1, t0
|
||||||
|
li t0, 0x00001700
|
||||||
|
csrw pmpcfg1, t0
|
||||||
|
|
||||||
|
li t0, 0x90000000
|
||||||
|
csrw pmpaddr2, t0
|
||||||
|
li t0, 0x00001700
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
|
||||||
|
li t0, 0x90000000
|
||||||
|
csrw pmpaddr3, t0
|
||||||
|
li t0, 0x00001700
|
||||||
|
csrw pmpcfg3, t0
|
||||||
|
|
||||||
|
li t0, 0x90000000
|
||||||
|
csrw pmpaddr0, t0
|
||||||
|
li t0, 0x00170000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
|
||||||
|
li t0, 0x90000000
|
||||||
|
csrw pmpaddr2, t0
|
||||||
|
li t0, 0x00170000
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
|
||||||
|
li t0, 0x90000000
|
||||||
|
csrw pmpaddr0, t0
|
||||||
|
li t0, 0x17000000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
|
||||||
|
li t0, 0x90000000
|
||||||
|
csrw pmpaddr2, t0
|
||||||
|
li t0, 0x17000000
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
|
||||||
|
li t0, 0x8800000000000000
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x88000000000000
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x880000000000
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x8800000000
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x88000000
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x880000
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x8800
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x88
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x8800000000000000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
li t0, 0x88000000000000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
li t0, 0x880000000000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
li t0, 0x8800000000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
li t0, 0x88000000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
li t0, 0x880000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
li t0, 0x8800
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
|
||||||
|
j done
|
48
tests/coverage/pmpcfg1.S
Normal file
48
tests/coverage/pmpcfg1.S
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// another set of pmpcfg tests. A new file is made because pmpcfg register fields are
|
||||||
|
// locked forever after writing 1 to the lock bit for the first time.
|
||||||
|
|
||||||
|
// Kevin Wan, kewan@hmc.edu, 4/13/2023
|
||||||
|
// This set tests locking the pmpXcfg fields in descending order again, without setting the TOR bits.
|
||||||
|
// for the other part of the tests, see pmpcfg.S
|
||||||
|
|
||||||
|
#include "WALLY-init-lib.h"
|
||||||
|
main:
|
||||||
|
li t0, 0x800
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
li t0, 0x8000000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
|
||||||
|
li t0, 0x8000000000000000
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x80000000000000
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x800000000000
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x8000000000
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x80000000
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x800000
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x8000
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x80
|
||||||
|
csrw pmpcfg2, t0
|
||||||
|
li t0, 0x8000000000000000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
li t0, 0x80000000000000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
li t0, 0x800000000000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
li t0, 0x8000000000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
li t0, 0x80000000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
li t0, 0x800000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
li t0, 0x8000
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
j done
|
12
tests/coverage/pmpcfg2.S
Normal file
12
tests/coverage/pmpcfg2.S
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// pmpcfg part 3
|
||||||
|
// Kevin Wan, kewan@hmc.edu, 4/18/2023
|
||||||
|
// locks each pmpXcfg bit field in order, from X = 15 to X = 0, with the A[1:0] field set to TOR.
|
||||||
|
// See the next part in pmpcfg1.S
|
||||||
|
|
||||||
|
#include "WALLY-init-lib.h"
|
||||||
|
main:
|
||||||
|
li t0, 0x80
|
||||||
|
csrw pmpcfg0, t0
|
||||||
|
|
||||||
|
|
||||||
|
j done
|
@ -189,6 +189,7 @@ main:
|
|||||||
li t1, -1
|
li t1, -1
|
||||||
csrw mcounteren, t1
|
csrw mcounteren, t1
|
||||||
|
|
||||||
|
|
||||||
# Go to supervisor mode
|
# Go to supervisor mode
|
||||||
li a0, 1
|
li a0, 1
|
||||||
ecall
|
ecall
|
||||||
|
133
tests/coverage/tlbASID.S
Normal file
133
tests/coverage/tlbASID.S
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// tlbASID.S
|
||||||
|
//
|
||||||
|
// Written: mmendozamanriquez@hmc.edu 4 April 2023
|
||||||
|
// nlimpert@hmc.edu
|
||||||
|
//
|
||||||
|
// Purpose: Test coverage for LSU
|
||||||
|
//
|
||||||
|
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
//
|
||||||
|
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||||
|
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||||
|
// may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://solderpad.org/licenses/SHL-2.1/
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||||
|
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
// either express or implied. See the License for the specific language governing permissions
|
||||||
|
// and limitations under the License.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// load code to initalize stack, handle interrupts, terminate
|
||||||
|
|
||||||
|
#include "WALLY-init-lib.h"
|
||||||
|
|
||||||
|
# run-elf.bash find this in project description
|
||||||
|
main:
|
||||||
|
# Page table root address at 0x80010000
|
||||||
|
li t5, 0x9000000000080080 // try making asid = 0.
|
||||||
|
csrw satp, t5
|
||||||
|
|
||||||
|
# sfence.vma x0, x0
|
||||||
|
|
||||||
|
# switch to supervisor mode
|
||||||
|
li a0, 1
|
||||||
|
ecall
|
||||||
|
|
||||||
|
li t0, 0xC0000000
|
||||||
|
|
||||||
|
li t2, 0 # i = 0
|
||||||
|
li t5, 0 # j = 0 // now use as a counter for new asid loop
|
||||||
|
li t3, 32 # Max amount of Loops = 32
|
||||||
|
|
||||||
|
loop: bge t2, t3, nASID # exit loop if i >= loops
|
||||||
|
lw t1, 0(t0)
|
||||||
|
li t4, 0x1000
|
||||||
|
add t0, t0, t4
|
||||||
|
addi t2, t2, 1
|
||||||
|
j loop
|
||||||
|
|
||||||
|
nASID: bne t5, zero, finished
|
||||||
|
li a0, 3 // go
|
||||||
|
ecall
|
||||||
|
li t5, 0x9000100000080080 // try making asid = 1
|
||||||
|
csrw satp, t5
|
||||||
|
li a0, 1
|
||||||
|
ecall
|
||||||
|
li t2, 0
|
||||||
|
li t0, 0xC0000000
|
||||||
|
li t5, 1 // make this not zero.
|
||||||
|
j loop
|
||||||
|
|
||||||
|
|
||||||
|
finished:
|
||||||
|
j done
|
||||||
|
|
||||||
|
.data
|
||||||
|
.align 19
|
||||||
|
# level 3 Page table situated at 0x8008 0000, should point to 8008,1000
|
||||||
|
pagetable:
|
||||||
|
.8byte 0x200204C1
|
||||||
|
|
||||||
|
.align 12 // level 2 page table, contains direction to a gigapageg
|
||||||
|
.8byte 0x0
|
||||||
|
.8byte 0x0
|
||||||
|
.8byte 0x200000CF // gigapage that starts at 8000 0000 goes to C000 0000
|
||||||
|
.8byte 0x200208C1 // pointer to next page table entry at 8008 2000
|
||||||
|
|
||||||
|
.align 12 // level 1 page table, points to level 0 page table
|
||||||
|
.8byte 0x20020CC1
|
||||||
|
|
||||||
|
.align 12 // level 0 page table, points to address C000 0000 // FOR NOW ALL OF THESE GO TO 8 instead of C cause they start with 2
|
||||||
|
.8byte 0x200000CF // access xC000 0000
|
||||||
|
.8byte 0x200004CF // access xC000 1000
|
||||||
|
.8byte 0x200008CF // access xC000 2000
|
||||||
|
.8byte 0x20000CCF // access xC000 3000
|
||||||
|
|
||||||
|
.8byte 0x200010CF // access xC000 4000
|
||||||
|
.8byte 0x200014CF
|
||||||
|
.8byte 0x200018CF
|
||||||
|
.8byte 0x20001CCF
|
||||||
|
|
||||||
|
.8byte 0x200020CF // access xC000 8000
|
||||||
|
.8byte 0x200024CF
|
||||||
|
.8byte 0x200028CF
|
||||||
|
.8byte 0x20002CCF
|
||||||
|
|
||||||
|
.8byte 0x200030CF // access xC000 C000
|
||||||
|
.8byte 0x200034CF
|
||||||
|
.8byte 0x200038CF
|
||||||
|
.8byte 0x20003CCF
|
||||||
|
|
||||||
|
.8byte 0x200040CF // access xC001 0000
|
||||||
|
.8byte 0x200044CF
|
||||||
|
.8byte 0x200048CF
|
||||||
|
.8byte 0x20004CCF
|
||||||
|
|
||||||
|
.8byte 0x200050CF // access xC001 4000
|
||||||
|
.8byte 0x200054CF
|
||||||
|
.8byte 0x200058CF
|
||||||
|
.8byte 0x20005CCF
|
||||||
|
|
||||||
|
.8byte 0x200060CF // access xC001 8000
|
||||||
|
.8byte 0x200064CF
|
||||||
|
.8byte 0x200068CF
|
||||||
|
.8byte 0x20006CCF
|
||||||
|
|
||||||
|
.8byte 0x200070CF // access xC001 C000
|
||||||
|
.8byte 0x200074CF
|
||||||
|
.8byte 0x200078CF
|
||||||
|
.8byte 0x20007CCF
|
||||||
|
|
||||||
|
.8byte 0x200080CF // access xC002 0000
|
||||||
|
.8byte 0x200084CF
|
||||||
|
.8byte 0x200088CF
|
||||||
|
.8byte 0x20008CCF
|
||||||
|
|
||||||
|
|
134
tests/coverage/tlbGLB.S
Normal file
134
tests/coverage/tlbGLB.S
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// tlbGLB.S
|
||||||
|
//
|
||||||
|
// Written: mmendozamanriquez@hmc.edu 4 April 2023
|
||||||
|
// nlimpert@hmc.edu
|
||||||
|
//
|
||||||
|
// Purpose: coverage for the global check.
|
||||||
|
//
|
||||||
|
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
//
|
||||||
|
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||||
|
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||||
|
// may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://solderpad.org/licenses/SHL-2.1/
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||||
|
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
// either express or implied. See the License for the specific language governing permissions
|
||||||
|
// and limitations under the License.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
// load code to initalize stack, handle interrupts, terminate
|
||||||
|
|
||||||
|
#include "WALLY-init-lib.h"
|
||||||
|
|
||||||
|
# run-elf.bash find this in project description
|
||||||
|
main:
|
||||||
|
# Page table root address at 0x80010000
|
||||||
|
li t5, 0x9000000000080080 // try making asid = 0.
|
||||||
|
csrw satp, t5
|
||||||
|
|
||||||
|
# sfence.vma x0, x0
|
||||||
|
|
||||||
|
# switch to supervisor mode
|
||||||
|
li a0, 1
|
||||||
|
ecall
|
||||||
|
|
||||||
|
li t0, 0xC0000000
|
||||||
|
|
||||||
|
li t2, 0 # i = 0
|
||||||
|
li t5, 0 # j = 0 // now use as a counter for new asid loop
|
||||||
|
li t3, 32 # Max amount of Loops = 32
|
||||||
|
|
||||||
|
loop: bge t2, t3, nASID # exit loop if i >= loops
|
||||||
|
lw t1, 0(t0)
|
||||||
|
li t4, 0x1000
|
||||||
|
add t0, t0, t4
|
||||||
|
addi t2, t2, 1
|
||||||
|
j loop
|
||||||
|
|
||||||
|
nASID: bne t5, zero, finished
|
||||||
|
li a0, 3 // go
|
||||||
|
ecall
|
||||||
|
li t5, 0x9000100000080080 // try making asid = 1
|
||||||
|
csrw satp, t5
|
||||||
|
li a0, 1
|
||||||
|
ecall
|
||||||
|
li t2, 0
|
||||||
|
li t0, 0xC0000000
|
||||||
|
li t5, 1 // make this not zero.
|
||||||
|
j loop
|
||||||
|
|
||||||
|
|
||||||
|
finished:
|
||||||
|
j done
|
||||||
|
|
||||||
|
.data
|
||||||
|
.align 19
|
||||||
|
# level 3 Page table situated at 0x8008 0000, should point to 8008,1000
|
||||||
|
pagetable:
|
||||||
|
.8byte 0x200204C1
|
||||||
|
|
||||||
|
.align 12 // level 2 page table, contains direction to a gigapageg
|
||||||
|
.8byte 0x0
|
||||||
|
.8byte 0x0
|
||||||
|
.8byte 0x200000CF // gigapage that starts at 8000 0000 goes to C000 0000
|
||||||
|
.8byte 0x200208C1 // pointer to next page table entry at 8008 2000
|
||||||
|
|
||||||
|
.align 12 // level 1 page table, points to level 0 page table
|
||||||
|
.8byte 0x20020CE1
|
||||||
|
|
||||||
|
.align 12 // level 0 page table, points to address C000 0000 // FOR NOW ALL OF THESE GO TO 8 instead of C cause they start with 2
|
||||||
|
.8byte 0x200000CF // access xC000 0000
|
||||||
|
.8byte 0x200004CF // access xC000 1000
|
||||||
|
.8byte 0x200008CF // access xC000 2000
|
||||||
|
.8byte 0x20000CCF // access xC000 3000
|
||||||
|
|
||||||
|
.8byte 0x200010EF // access xC000 4000
|
||||||
|
.8byte 0x200014EF
|
||||||
|
.8byte 0x200018EF
|
||||||
|
.8byte 0x20001CEF
|
||||||
|
|
||||||
|
.8byte 0x200020EF // access xC000 8000
|
||||||
|
.8byte 0x200024EF
|
||||||
|
.8byte 0x200028EF
|
||||||
|
.8byte 0x20002CEF
|
||||||
|
|
||||||
|
.8byte 0x200030EF // access xC000 C000
|
||||||
|
.8byte 0x200034EF
|
||||||
|
.8byte 0x200038EF
|
||||||
|
.8byte 0x20003CEF
|
||||||
|
|
||||||
|
.8byte 0x200040EF // access xC001 0000
|
||||||
|
.8byte 0x200044EF
|
||||||
|
.8byte 0x200048EF
|
||||||
|
.8byte 0x20004CEF
|
||||||
|
|
||||||
|
.8byte 0x200050EF // access xC001 4000
|
||||||
|
.8byte 0x200054EF
|
||||||
|
.8byte 0x200058EF
|
||||||
|
.8byte 0x20005CEF
|
||||||
|
|
||||||
|
.8byte 0x200060EF // access xC001 8000
|
||||||
|
.8byte 0x200064EF
|
||||||
|
.8byte 0x200068EF
|
||||||
|
.8byte 0x20006CEF
|
||||||
|
|
||||||
|
.8byte 0x200070EF // access xC001 C000
|
||||||
|
.8byte 0x200074eF
|
||||||
|
.8byte 0x200078EF
|
||||||
|
.8byte 0x20007CEF
|
||||||
|
|
||||||
|
.8byte 0x200080EF // access xC002 0000
|
||||||
|
.8byte 0x200084EF
|
||||||
|
.8byte 0x200088EF
|
||||||
|
.8byte 0x20008CEF
|
||||||
|
|
||||||
|
|
155
tests/coverage/tlbM3.S
Normal file
155
tests/coverage/tlbM3.S
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// tlbKP.S
|
||||||
|
//
|
||||||
|
// Written: mmendozamanriquez@hmc.edu 4 April 2023
|
||||||
|
// nlimpert@hmc.edu
|
||||||
|
//
|
||||||
|
// Purpose: Test coverage for LSU
|
||||||
|
//
|
||||||
|
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
//
|
||||||
|
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||||
|
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||||
|
// may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://solderpad.org/licenses/SHL-2.1/
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||||
|
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
// either express or implied. See the License for the specific language governing permissions
|
||||||
|
// and limitations under the License.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// load code to initalize stack, handle interrupts, terminate
|
||||||
|
|
||||||
|
#include "WALLY-init-lib.h"
|
||||||
|
|
||||||
|
# run-elf.bash find this in project description
|
||||||
|
main:
|
||||||
|
# Page table root address at 0x80010000
|
||||||
|
li t5, 0x9000000000080010
|
||||||
|
csrw satp, t5
|
||||||
|
|
||||||
|
# sfence.vma x0, x0
|
||||||
|
|
||||||
|
# switch to supervisor mode
|
||||||
|
li a0, 1
|
||||||
|
ecall
|
||||||
|
|
||||||
|
li t0, 0x1000
|
||||||
|
|
||||||
|
li t2, 0 # i = 0
|
||||||
|
li t3, 64 # Max amount of Loops = 32
|
||||||
|
li t4, 0x1000
|
||||||
|
|
||||||
|
loop: bge t2, t3, interim # exit loop if i >= loops
|
||||||
|
lw t1, 0(t0)
|
||||||
|
# sfence.vma x0, x0
|
||||||
|
add t0, t0, t4
|
||||||
|
addi t2, t2, 1
|
||||||
|
j loop
|
||||||
|
|
||||||
|
interim:
|
||||||
|
li t0, 0xFFFFFFFF000
|
||||||
|
li t2, 0 # i = 0
|
||||||
|
|
||||||
|
|
||||||
|
loop2:bge t2, t3, finished # exit loop if i >= loops
|
||||||
|
lw t1, 0(t0)
|
||||||
|
add t0, t0, t4
|
||||||
|
addi t2, t2, 1
|
||||||
|
j loop2
|
||||||
|
|
||||||
|
finished:
|
||||||
|
j done
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
# Page table situated at 0x80010000
|
||||||
|
pagetable:
|
||||||
|
.8byte 0x200044C1 // old page table was 200040 which just pointed to itself! wrong
|
||||||
|
|
||||||
|
.align 12
|
||||||
|
.8byte 0x00000000200048C1
|
||||||
|
.8byte 0x00000000200048C1
|
||||||
|
.8byte 0x00000000200048C1
|
||||||
|
|
||||||
|
|
||||||
|
.align 12
|
||||||
|
.8byte 0x0000000020004CC1
|
||||||
|
//.8byte 0x00000200800CF// ADD IN THE MEGAPAGE should 3 nibbles of zeros be removed?
|
||||||
|
|
||||||
|
.align 12
|
||||||
|
#80000000
|
||||||
|
.8byte 0x200000CF
|
||||||
|
.8byte 0x200004CF
|
||||||
|
.8byte 0x200008CF
|
||||||
|
.8byte 0x20000CCF
|
||||||
|
|
||||||
|
.8byte 0x200010CF
|
||||||
|
.8byte 0x200014CF
|
||||||
|
.8byte 0x200018CF
|
||||||
|
.8byte 0x20001CCF
|
||||||
|
|
||||||
|
.8byte 0x200020CF
|
||||||
|
.8byte 0x200024CF
|
||||||
|
.8byte 0x200028CF
|
||||||
|
.8byte 0x20002CCF
|
||||||
|
|
||||||
|
.8byte 0x200030CF
|
||||||
|
.8byte 0x200034CF
|
||||||
|
.8byte 0x200038CF
|
||||||
|
.8byte 0x20003CCF
|
||||||
|
|
||||||
|
.8byte 0x200040CF
|
||||||
|
.8byte 0x200044CF
|
||||||
|
.8byte 0x200048CF
|
||||||
|
.8byte 0x20004CCF
|
||||||
|
|
||||||
|
.8byte 0x200050CF
|
||||||
|
.8byte 0x200054CF
|
||||||
|
.8byte 0x200058CF
|
||||||
|
.8byte 0x20005CCF
|
||||||
|
|
||||||
|
.8byte 0x200060CF
|
||||||
|
.8byte 0x200064CF
|
||||||
|
.8byte 0x200068CF
|
||||||
|
.8byte 0x20006CCF
|
||||||
|
|
||||||
|
.8byte 0x200070CF
|
||||||
|
.8byte 0x200074CF
|
||||||
|
.8byte 0x200078CF
|
||||||
|
.8byte 0x20007CCF
|
||||||
|
|
||||||
|
.8byte 0x200080CF
|
||||||
|
.8byte 0x200084CF
|
||||||
|
.8byte 0x200088CF
|
||||||
|
.8byte 0x20008CCF
|
||||||
|
|
||||||
|
.8byte 0x200090CF
|
||||||
|
.8byte 0x200094CF
|
||||||
|
.8byte 0x200098CF
|
||||||
|
.8byte 0x20009CCF
|
||||||
|
|
||||||
|
.8byte 0x2000A0CF
|
||||||
|
.8byte 0x2000A4CF
|
||||||
|
.8byte 0x2000A8CF
|
||||||
|
.8byte 0x2000ACCF
|
||||||
|
|
||||||
|
.8byte 0x2000B0CF
|
||||||
|
.8byte 0x2000B4CF
|
||||||
|
.8byte 0x2000B8CF
|
||||||
|
.8byte 0x2000BCCF
|
||||||
|
|
||||||
|
.8byte 0x2000C0CF
|
||||||
|
.8byte 0x2000C4CF
|
||||||
|
.8byte 0x2000C8CF
|
||||||
|
.8byte 0x2000CCCF
|
||||||
|
|
||||||
|
.8byte 0x2000D0CF
|
||||||
|
.8byte 0x2000D4CF
|
163
tests/coverage/tlbMP.S
Normal file
163
tests/coverage/tlbMP.S
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
///////////////////////////////////////////
|
||||||
|
// tlbMP.S
|
||||||
|
//
|
||||||
|
// Written: mmendozamanriquez@hmc.edu 4 April 2023
|
||||||
|
// nlimpert@hmc.edu
|
||||||
|
//
|
||||||
|
// Purpose: Test coverage for LSU
|
||||||
|
//
|
||||||
|
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
//
|
||||||
|
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||||
|
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||||
|
// may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://solderpad.org/licenses/SHL-2.1/
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||||
|
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
// either express or implied. See the License for the specific language governing permissions
|
||||||
|
// and limitations under the License.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// load code to initalize stack, handle interrupts, terminate
|
||||||
|
|
||||||
|
#include "WALLY-init-lib.h"
|
||||||
|
|
||||||
|
# run-elf.bash find this in project description
|
||||||
|
main:
|
||||||
|
# Page table root address at 0x80010000
|
||||||
|
li t5, 0x9000000000080010
|
||||||
|
csrw satp, t5
|
||||||
|
|
||||||
|
# sfence.vma x0, x0
|
||||||
|
|
||||||
|
# switch to supervisor mode
|
||||||
|
li a0, 1
|
||||||
|
ecall
|
||||||
|
li t5, 0
|
||||||
|
li t0, 0x84000000 // go to first megapage
|
||||||
|
li t4, 0x1000 // put this outside the loop.
|
||||||
|
li t2, 0 # i = 0
|
||||||
|
li t3, 32 # Max amount of Loops = 16
|
||||||
|
|
||||||
|
loop: bge t2, t3, lKP # exit loop if i >= loops
|
||||||
|
lw t1, 0(t0)
|
||||||
|
add t0, t0, t4
|
||||||
|
addi t2, t2, 1
|
||||||
|
j loop
|
||||||
|
|
||||||
|
lKP: bne t5, zero, finished
|
||||||
|
li t0, 0x80000000
|
||||||
|
slli t4, t4, 9
|
||||||
|
addi t5, t5, 1
|
||||||
|
li t2, 0
|
||||||
|
j loop
|
||||||
|
|
||||||
|
finished:
|
||||||
|
j done
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
# Page table situated at 0x80010000
|
||||||
|
pagetable:
|
||||||
|
.8byte 0x200044C1
|
||||||
|
|
||||||
|
.align 12
|
||||||
|
.8byte 0x00000000200048C1
|
||||||
|
.8byte 0x00000000200048C1
|
||||||
|
.8byte 0x00000000200048C1
|
||||||
|
|
||||||
|
|
||||||
|
.align 12 // megapages starting at 8000 0000 going to 8480 0000 (32*2 MiB beyond that)
|
||||||
|
|
||||||
|
.8byte 0x200000CF // access 8000,0000
|
||||||
|
.8byte 0x200800CF // access 8020,0000
|
||||||
|
.8byte 0x201000CF // acesss 8040,0000
|
||||||
|
.8byte 0x201800CF // acesss 8060,0000
|
||||||
|
|
||||||
|
.8byte 0x202000CF // access 8080,0000
|
||||||
|
.8byte 0x202800CF // access 80A0,0000
|
||||||
|
.8byte 0x203000CF // access 80C0,0000
|
||||||
|
.8byte 0x203800CF // access 80E0,0000
|
||||||
|
|
||||||
|
.8byte 0x204000CF // access 8100,0000
|
||||||
|
.8byte 0x204800CF
|
||||||
|
.8byte 0x205000CF
|
||||||
|
.8byte 0x205800CF
|
||||||
|
|
||||||
|
.8byte 0x206000CF // access 8180,0000
|
||||||
|
.8byte 0x206800CF
|
||||||
|
.8byte 0x207000CF
|
||||||
|
.8byte 0x207800CF
|
||||||
|
|
||||||
|
.8byte 0x208000CF // access 8200,0000
|
||||||
|
.8byte 0x208800CF
|
||||||
|
.8byte 0x209000CF
|
||||||
|
.8byte 0x209800CF
|
||||||
|
|
||||||
|
.8byte 0x20A000CF // access 8280,0000
|
||||||
|
.8byte 0x20A800CF
|
||||||
|
.8byte 0x20B000CF
|
||||||
|
.8byte 0x20B800CF
|
||||||
|
|
||||||
|
.8byte 0x20C000CF // access 8300,0000
|
||||||
|
.8byte 0x20C800CF
|
||||||
|
.8byte 0x20D000CF
|
||||||
|
.8byte 0x20D800CF
|
||||||
|
|
||||||
|
.8byte 0x20E000CF // access 8380,0000
|
||||||
|
.8byte 0x20E800CF
|
||||||
|
.8byte 0x20F000CF
|
||||||
|
.8byte 0x20F800CF
|
||||||
|
|
||||||
|
.8byte 0x20004CC1
|
||||||
|
// Kilopage entry, for addresses from 8400, 0000 to 841F, FFFF
|
||||||
|
// point to ...
|
||||||
|
|
||||||
|
.align 12 // should start at 84000000
|
||||||
|
.8byte 0x210000CF
|
||||||
|
.8byte 0x210004CF
|
||||||
|
.8byte 0x210008CF
|
||||||
|
.8byte 0x21000CCF
|
||||||
|
|
||||||
|
.8byte 0x210010CF
|
||||||
|
.8byte 0x210014CF
|
||||||
|
.8byte 0x210018CF
|
||||||
|
.8byte 0x21001CCF
|
||||||
|
|
||||||
|
.8byte 0x210020CF
|
||||||
|
.8byte 0x210024CF
|
||||||
|
.8byte 0x210028CF
|
||||||
|
.8byte 0x21002CCF
|
||||||
|
|
||||||
|
.8byte 0x210030CF
|
||||||
|
.8byte 0x210034CF
|
||||||
|
.8byte 0x210038CF
|
||||||
|
.8byte 0x21003CCF
|
||||||
|
|
||||||
|
.8byte 0x210040CF
|
||||||
|
.8byte 0x210044CF
|
||||||
|
.8byte 0x210048CF
|
||||||
|
.8byte 0x21004CCF
|
||||||
|
|
||||||
|
.8byte 0x210050CF
|
||||||
|
.8byte 0x210054CF
|
||||||
|
.8byte 0x210058CF
|
||||||
|
.8byte 0x21005CCF
|
||||||
|
|
||||||
|
.8byte 0x210060CF
|
||||||
|
.8byte 0x210064CF
|
||||||
|
.8byte 0x210068CF
|
||||||
|
.8byte 0x21006CCF
|
||||||
|
|
||||||
|
.8byte 0x210070CF
|
||||||
|
.8byte 0x210074CF
|
||||||
|
.8byte 0x210078CF
|
||||||
|
.8byte 0x21007CCF
|
||||||
|
|
Loading…
Reference in New Issue
Block a user