diff --git a/.gitignore b/.gitignore index b745e3c63..047e9ed7a 100644 --- a/.gitignore +++ b/.gitignore @@ -51,4 +51,5 @@ fpga/generator/*.jou examples/asm/sumtest/sumtest examples/asm/example/example examples/C/sum/sum +examples/C/fir/fir diff --git a/.gitmodules b/.gitmodules index d434c3db8..ba8877ce5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,9 +17,6 @@ [submodule "addins/embench-iot"] path = addins/embench-iot url = https://github.com/embench/embench-iot -[submodule "addins/book_flow"] - path = addins/book_flow - url = https://github.com/stineje/book_flow [submodule "addins/sky130_osu_sc_t18"] path = addins/sky130_osu_sc_t18 url = https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t18 diff --git a/addins/book_flow b/addins/book_flow deleted file mode 160000 index 5ef17d725..000000000 --- a/addins/book_flow +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5ef17d725e472ef414e5581bf25805236e6a60ca diff --git a/examples/C/fir/Makefile b/examples/C/fir/Makefile index b1f4738cc..c27e423a5 100644 --- a/examples/C/fir/Makefile +++ b/examples/C/fir/Makefile @@ -5,7 +5,7 @@ $(TARGET).objdump: $(TARGET) spike $(TARGET) $(TARGET): $(TARGET).c Makefile - riscv64-unknown-elf-gcc -o $(TARGET) -g -O\ + riscv64-unknown-elf-gcc -o $(TARGET) -g -O2\ -march=rv64gc -mabi=lp64d -mcmodel=medany \ -nostdlib -static -lm -fno-tree-loop-distribute-patterns \ -T../common/test.ld -I../common \ diff --git a/examples/C/fir/fir b/examples/C/fir/fir index f395b2e7e..4266f84b9 100755 Binary files a/examples/C/fir/fir and b/examples/C/fir/fir differ diff --git a/examples/C/fir/fir.c b/examples/C/fir/fir.c index c2a6f67b2..bbc5a1e1c 100644 --- a/examples/C/fir/fir.c +++ b/examples/C/fir/fir.c @@ -3,6 +3,7 @@ // Finite Impulse Response Filter #include // supports printf +#include // supports fabs #include "util.h" // supports verify void fir(int N, int M, double X[], double c[], double Y[]) { diff --git a/pipelined/config/rv32etim/wally-config.vh b/pipelined/config/rv32etim/wally-config.vh index 450506701..58e31d2cd 100644 --- a/pipelined/config/rv32etim/wally-config.vh +++ b/pipelined/config/rv32etim/wally-config.vh @@ -86,10 +86,10 @@ // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits `define BOOTROM_SUPPORTED 1'b1 `define BOOTROM_BASE 34'h00001000 -`define BOOTROM_RANGE 34'h00000FFF +`define BOOTROM_RANGE 34'h000000FF `define RAM_SUPPORTED 1'b1 `define RAM_BASE 34'h80000000 -`define RAM_RANGE 34'h0000FFFF +`define RAM_RANGE 34'h000003FF `define EXT_MEM_SUPPORTED 1'b0 `define EXT_MEM_BASE 34'h80000000 `define EXT_MEM_RANGE 34'h07FFFFFF @@ -129,6 +129,6 @@ `define TWO_BIT_PRELOAD "../config/rv32ic/twoBitPredictor.txt" `define BTB_PRELOAD "../config/rv32ic/BTBPredictor.txt" -`define BPRED_ENABLED 1 +`define BPRED_ENABLED 0 `define BPTYPE "BPGSHARE" // BPLOCALPAg or BPGLOBAL or BPTWOBIT or BPGSHARE `define TESTSBP 0 diff --git a/pipelined/fpu-testfloat/FMA/tbgen/tb.sv b/pipelined/fpu-testfloat/FMA/tbgen/tb.sv index 621429aa4..57c4e2ff0 100644 --- a/pipelined/fpu-testfloat/FMA/tbgen/tb.sv +++ b/pipelined/fpu-testfloat/FMA/tbgen/tb.sv @@ -129,11 +129,11 @@ assign FmtE = 1'b1; assign BiasE = 13'h3ff; -assign wnan = FmtE ? &FMAResM[`FLEN-2:`NF] && |FMAResM[`NF-1:0] : &FMAResM[30:23] && |FMAResM[22:0]; -// assign XNaNE = FmtE ? &X[62:52] && |X[51:0] : &X[62:55] && |X[54:32]; -// assign YNaNE = FmtE ? &Y[62:52] && |Y[51:0] : &Y[62:55] && |Y[54:32]; -// assign ZNaNE = FmtE ? &Z[62:52] && |Z[51:0] : &Z[62:55] && |Z[54:32]; -assign ansnan = FmtE ? &ans[`FLEN-2:`NF] && |ans[`NF-1:0] : &ans[30:23] && |ans[22:0]; +assign wnan = FmtE ? &FMAResM[`FLEN-2:`NF] & |FMAResM[`NF-1:0] : &FMAResM[30:23] & |FMAResM[22:0]; +// assign XNaNE = FmtE ? &X[62:52] & |X[51:0] : &X[62:55] & |X[54:32]; +// assign YNaNE = FmtE ? &Y[62:52] & |Y[51:0] : &Y[62:55] & |Y[54:32]; +// assign ZNaNE = FmtE ? &Z[62:52] & |Z[51:0] : &Z[62:55] & |Z[54:32]; +assign ansnan = FmtE ? &ans[`FLEN-2:`NF] & |ans[`NF-1:0] : &ans[30:23] & |ans[22:0]; // instantiate device under test logic [3*`NF+5:0] SumE, SumM; @@ -179,9 +179,9 @@ always @(posedge clk) // check results on falling edge of clk always @(negedge clk) begin - if((FmtE==1'b1) & (FMAFlgM != flags[4:0] || (!wnan && (FMAResM != ans)) || (wnan && ansnan && ~((XNaNE && (FMAResM[`FLEN-2:0] == {XExpE,1'b1,X[`NF-2:0]})) || (YNaNE && (FMAResM[`FLEN-2:0] == {YExpE,1'b1,Y[`NF-2:0]})) || (ZNaNE && (FMAResM[`FLEN-2:0] == {ZExpE,1'b1,Z[`NF-2:0]})) || (FMAResM[`FLEN-2:0] == ans[`FLEN-2:0]))))) begin + if((FmtE==1'b1) & (FMAFlgM != flags[4:0] | (!wnan & (FMAResM != ans)) | (wnan & ansnan & ~((XNaNE & (FMAResM[`FLEN-2:0] == {XExpE,1'b1,X[`NF-2:0]})) | (YNaNE & (FMAResM[`FLEN-2:0] == {YExpE,1'b1,Y[`NF-2:0]})) | (ZNaNE & (FMAResM[`FLEN-2:0] == {ZExpE,1'b1,Z[`NF-2:0]})) | (FMAResM[`FLEN-2:0] == ans[`FLEN-2:0]))))) begin // fp = $fopen("/home/kparry/riscv-wally/pipelined/src/fpu/FMA/tbgen/results.dat","w"); - // if((FmtE==1'b1) & (FMAFlgM != flags[4:0] || (FMAResM != ans))) begin + // if((FmtE==1'b1) & (FMAFlgM != flags[4:0] | (FMAResM != ans))) begin $display( "%h %h %h %h %h %h %h Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags); if(FMAResM == 64'h8000000000000000) $display( "FMAResM=-zero "); if(XDenormE) $display( "xdenorm "); @@ -190,35 +190,35 @@ always @(posedge clk) if(FMAFlgM[4] != 0) $display( "invld "); if(FMAFlgM[2] != 0) $display( "ovrflw "); if(FMAFlgM[1] != 0) $display( "unflw "); - if(FMAResM[`FLEN] && FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} && FMAResM[`NF-1:0] == 0) $display( "FMAResM=-inf "); - if(~FMAResM[`FLEN] && FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} && FMAResM[`NF-1:0] == 0) $display( "FMAResM=+inf "); - if(FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} && FMAResM[`NF-1:0] != 0 && ~FMAResM[`NF-1]) $display( "FMAResM=sigNaN "); - if(FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} && FMAResM[`NF-1:0] != 0 && FMAResM[`NF-1]) $display( "FMAResM=qutNaN "); - if(ans[`FLEN] && ans[`FLEN-2:`NF] == {`NE{1'b1}} && ans[`NF-1:0] == 0) $display( "ans=-inf "); - if(~ans[`FLEN] && ans[`FLEN-2:`NF] == {`NE{1'b1}} && ans[`NF-1:0] == 0) $display( "ans=+inf "); - if(ans[`FLEN-2:`NF] == {`NE{1'b1}} && ans[`NF-1:0] != 0 && ~ans[`NF-1]) $display( "ans=sigNaN "); - if(ans[`FLEN-2:`NF] == {`NE{1'b1}} && ans[`NF-1:0] != 0 && ans[`NF-1]) $display( "ans=qutNaN "); + if(FMAResM[`FLEN] & FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} & FMAResM[`NF-1:0] == 0) $display( "FMAResM=-inf "); + if(~FMAResM[`FLEN] & FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} & FMAResM[`NF-1:0] == 0) $display( "FMAResM=+inf "); + if(FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} & FMAResM[`NF-1:0] != 0 & ~FMAResM[`NF-1]) $display( "FMAResM=sigNaN "); + if(FMAResM[`FLEN-2:`NF] == {`NE{1'b1}} & FMAResM[`NF-1:0] != 0 & FMAResM[`NF-1]) $display( "FMAResM=qutNaN "); + if(ans[`FLEN] & ans[`FLEN-2:`NF] == {`NE{1'b1}} & ans[`NF-1:0] == 0) $display( "ans=-inf "); + if(~ans[`FLEN] & ans[`FLEN-2:`NF] == {`NE{1'b1}} & ans[`NF-1:0] == 0) $display( "ans=+inf "); + if(ans[`FLEN-2:`NF] == {`NE{1'b1}} & ans[`NF-1:0] != 0 & ~ans[`NF-1]) $display( "ans=sigNaN "); + if(ans[`FLEN-2:`NF] == {`NE{1'b1}} & ans[`NF-1:0] != 0 & ans[`NF-1]) $display( "ans=qutNaN "); errors = errors + 1; //if (errors == 10) $stop; end - if((FmtE==1'b0)&(FMAFlgM != flags[4:0] || (!wnan && (FMAResM != ans)) || (wnan && ansnan && ~(((XNaNE && (FMAResM[30:0] == {X[30:23],1'b1,X[21:0]})) || (YNaNE && (FMAResM[30:0] == {Y[30:23],1'b1,Y[21:0]})) || (ZNaNE && (FMAResM[30:0] == {Z[30:23],1'b1,Z[21:0]})) || (FMAResM[30:0] == ans[30:0]))) ))) begin + if((FmtE==1'b0)&(FMAFlgM != flags[4:0] | (!wnan & (FMAResM != ans)) | (wnan & ansnan & ~(((XNaNE & (FMAResM[30:0] == {X[30:23],1'b1,X[21:0]})) | (YNaNE & (FMAResM[30:0] == {Y[30:23],1'b1,Y[21:0]})) | (ZNaNE & (FMAResM[30:0] == {Z[30:23],1'b1,Z[21:0]})) | (FMAResM[30:0] == ans[30:0]))) ))) begin $display( "%h %h %h %h %h %h %h Wrong ",X,Y, Z, FMAResM, ans, FMAFlgM, flags); if(FMAResM == 64'h8000000000000000) $display( "FMAResM=-zero "); - if(~(|X[30:23]) && |X[22:0]) $display( "xdenorm "); - if(~(|Y[30:23]) && |Y[22:0]) $display( "ydenorm "); - if(~(|Z[30:23]) && |Z[22:0]) $display( "zdenorm "); + if(~(|X[30:23]) & |X[22:0]) $display( "xdenorm "); + if(~(|Y[30:23]) & |Y[22:0]) $display( "ydenorm "); + if(~(|Z[30:23]) & |Z[22:0]) $display( "zdenorm "); if(FMAFlgM[4] != 0) $display( "invld "); if(FMAFlgM[2] != 0) $display( "ovrflw "); if(FMAFlgM[1] != 0) $display( "unflw "); if(FMAResM == 64'hFF80000000000000) $display( "FMAResM=-inf "); if(FMAResM == 64'h7F80000000000000) $display( "FMAResM=+inf "); - if(&FMAResM[30:23] && |FMAResM[22:0] && ~FMAResM[22]) $display( "FMAResM=sigNaN "); - if(&FMAResM[30:23] && |FMAResM[22:0] && FMAResM[22] ) $display( "FMAResM=qutNaN "); + if(&FMAResM[30:23] & |FMAResM[22:0] & ~FMAResM[22]) $display( "FMAResM=sigNaN "); + if(&FMAResM[30:23] & |FMAResM[22:0] & FMAResM[22] ) $display( "FMAResM=qutNaN "); if(ans == 64'hFF80000000000000) $display( "ans=-inf "); if(ans == 64'h7F80000000000000) $display( "ans=+inf "); - if(&ans[30:23] && |ans[22:0] && ~ans[22] ) $display( "ans=sigNaN "); - if(&ans[30:23] && |ans[22:0] && ans[22]) $display( "ans=qutNaN "); + if(&ans[30:23] & |ans[22:0] & ~ans[22] ) $display( "ans=sigNaN "); + if(&ans[30:23] & |ans[22:0] & ans[22]) $display( "ans=qutNaN "); errors = errors + 1; if (errors == 10) $stop; diff --git a/pipelined/regression/fpga-wave.do b/pipelined/regression/fpga-wave.do index 638fa43d5..14185e707 100644 --- a/pipelined/regression/fpga-wave.do +++ b/pipelined/regression/fpga-wave.do @@ -98,7 +98,7 @@ add wave -noupdate -group Bpred -expand -group {bp wrong} /testbench/dut/wallypi add wave -noupdate -group Bpred -expand -group {bp wrong} /testbench/dut/wallypipelinedsoc/core/ifu/bpred/bpred/BPPredWrongE add wave -noupdate -group Bpred /testbench/dut/wallypipelinedsoc/core/ifu/bpred/bpred/BPPredWrongE add wave -noupdate -group {instruction pipeline} /testbench/InstrFName -add wave -noupdate -group {instruction pipeline} /testbench/dut/wallypipelinedsoc/core/ifu/icache/FinalInstrRawF +add wave -noupdate -group {instruction pipeline} /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/FinalInstrRawF add wave -noupdate -group {instruction pipeline} /testbench/dut/wallypipelinedsoc/core/ifu/InstrD add wave -noupdate -group {instruction pipeline} /testbench/dut/wallypipelinedsoc/core/ifu/InstrE add wave -noupdate -group {instruction pipeline} /testbench/dut/wallypipelinedsoc/core/ifu/InstrM @@ -172,86 +172,86 @@ add wave -noupdate -group muldiv /testbench/dut/wallypipelinedsoc/core/mdu/Flush add wave -noupdate -group muldiv /testbench/dut/wallypipelinedsoc/core/mdu/FlushW add wave -noupdate -group muldiv /testbench/dut/wallypipelinedsoc/core/mdu/MulDivResultW add wave -noupdate -group muldiv /testbench/dut/wallypipelinedsoc/core/mdu/DivBusyE -add wave -noupdate -group icache -color Gold /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/CurrState -add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/icache/BasePAdrF -add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/icache/WayHit -add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/icache/genblk1/cachereplacementpolicy/BlockReplacementBits -add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/icache/genblk1/cachereplacementpolicy/EncVicWay -add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/icache/VictimWay -add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[0]/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[0]/SetValid} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -label TAG {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[0]/CacheTagMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[0]/ValidBits} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[0]/word[0]/CacheDataMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[0]/word[0]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[0]/word[1]/CacheDataMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[0]/word[1]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[0]/word[2]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[0]/word[2]/CacheDataMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[0]/word[3]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[0]/word[3]/CacheDataMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[1]/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[1]/WriteWordEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -label TAG {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[1]/CacheTagMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[1]/ValidBits} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -expand -group Way1Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[1]/word[0]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -expand -group Way1Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[1]/word[0]/CacheDataMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[1]/word[1]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[1]/word[1]/CacheDataMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[1]/word[2]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[1]/word[2]/CacheDataMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[1]/word[3]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[1]/word[3]/CacheDataMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[2]/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[2]/SetValid} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -label TAG {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[2]/CacheTagMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[2]/ValidBits} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -expand -group Way2Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[2]/word[0]/CacheDataMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -expand -group Way2Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[2]/word[0]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[2]/word[1]/CacheDataMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[2]/word[1]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[2]/word[2]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[2]/word[2]/CacheDataMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[2]/word[3]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[2]/word[3]/CacheDataMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[3]/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[3]/SetValid} -add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -label TAG {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[3]/CacheTagMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[3]/DirtyBits} -add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[3]/ValidBits} -add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[3]/word[0]/CacheDataMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[3]/word[0]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[3]/word[1]/CacheDataMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[3]/word[1]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[3]/word[2]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[3]/word[2]/CacheDataMem/StoredData} -add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[3]/word[3]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/icache/MemWay[3]/word[3]/CacheDataMem/StoredData} -add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/NextState +add wave -noupdate -group icache -color Gold /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/CurrState +add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/BasePAdrF +add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/WayHit +add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/genblk1/cachereplacementpolicy/BlockReplacementBits +add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/genblk1/cachereplacementpolicy/EncVicWay +add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/VictimWay +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[0]/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[0]/SetValid} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -label TAG {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[0]/CacheTagMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[0]/ValidBits} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[0]/word[0]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[0]/word[0]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[0]/word[1]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[0]/word[1]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[0]/word[2]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[0]/word[2]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[0]/word[3]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[0]/word[3]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[1]/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[1]/WriteWordEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -label TAG {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[1]/CacheTagMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[1]/ValidBits} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -expand -group Way1Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[1]/word[0]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -expand -group Way1Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[1]/word[0]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[1]/word[1]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[1]/word[1]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[1]/word[2]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[1]/word[2]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[1]/word[3]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[1]/word[3]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[2]/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[2]/SetValid} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -label TAG {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[2]/CacheTagMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[2]/ValidBits} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -expand -group Way2Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[2]/word[0]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -expand -group Way2Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[2]/word[0]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[2]/word[1]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[2]/word[1]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[2]/word[2]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[2]/word[2]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[2]/word[3]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[2]/word[3]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[3]/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[3]/SetValid} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -label TAG {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[3]/CacheTagMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[3]/DirtyBits} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[3]/ValidBits} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[3]/word[0]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[3]/word[0]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[3]/word[1]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word1 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[3]/word[1]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[3]/word[2]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word2 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[3]/word[2]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[3]/word[3]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word3 {/testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/MemWay[3]/word[3]/CacheDataMem/StoredData} +add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/NextState add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/ITLBMissF -add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/icache/ITLBWriteF -add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/icache/ReadLineF -add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/icache/PCNextIndexF -add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/icache/ReadLineF -add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/icache/BasePAdrF -add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/hit -add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/spill -add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/ICacheStallF -add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/SavePC -add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/spillSave -add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/UnalignedSelect -add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/spillSave -add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/CntReset -add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/PreCntEn -add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/CntEn -add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/icache/InstrPAdrF -add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/icache/InstrInF -add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/FetchCountFlag -add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/icache/FetchCount -add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/InstrReadF -add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/InstrAckF -add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/icache/controller/ICacheMemWriteEnable -add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/icache/ICacheMemWriteData +add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/ITLBWriteF +add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/ReadLineF +add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/PCNextIndexF +add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/ReadLineF +add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/BasePAdrF +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/hit +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/spill +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/ICacheStallF +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/SavePC +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/spillSave +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/UnalignedSelect +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/spillSave +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/CntReset +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/PreCntEn +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/CntEn +add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/InstrPAdrF +add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/InstrInF +add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/FetchCountFlag +add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/FetchCount +add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/InstrReadF +add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/InstrAckF +add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/ICacheMemWriteEnable +add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/ICacheMemWriteData add wave -noupdate -group AHB -color Gold /testbench/dut/wallypipelinedsoc/core/ebu/BusState add wave -noupdate -group AHB /testbench/dut/wallypipelinedsoc/core/ebu/NextBusState add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/wallypipelinedsoc/core/ebu/AtomicMaskedM diff --git a/pipelined/regression/linux-wave.do b/pipelined/regression/linux-wave.do index b2cb90145..a9f9e3b2e 100644 --- a/pipelined/regression/linux-wave.do +++ b/pipelined/regression/linux-wave.do @@ -23,7 +23,7 @@ add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/StoreAmoMisalignedFaultM add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InstrPageFaultM add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/LoadPageFaultM -add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/StorePageFaultM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/StoreAmoPageFaultM add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/BreakpointFaultM add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/EcallFaultM add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/LoadMisalignedFaultM @@ -168,15 +168,15 @@ add wave -noupdate -group {alu execution stage} /testbench/dut/core/ieu/dp/Write add wave -noupdate -group {alu execution stage} /testbench/dut/core/ieu/dp/ALUResultE add wave -noupdate -group {alu execution stage} /testbench/dut/core/ieu/dp/SrcAE add wave -noupdate -group {alu execution stage} /testbench/dut/core/ieu/dp/SrcBE -add wave -noupdate -group icache -color Gold /testbench/dut/core/ifu/icache/icache/cachefsm/CurrState -add wave -noupdate -group icache /testbench/dut/core/ifu/icache/icache/ReadDataWord -add wave -noupdate -group icache /testbench/dut/core/ifu/icache/icache/SelAdr -add wave -noupdate -group icache /testbench/dut/core/ifu/icache/icache/RAdr -add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/icache/icache/CacheHit -add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/icache/icache/CacheStall -add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/icache/icache/ReadDataLineSets -add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/icache/icache/CacheMemWriteData -add wave -noupdate -group icache /testbench/dut/core/ifu/SpillSupport/SpillDataLine0 +add wave -noupdate -group icache -color Gold /testbench/dut/core/ifu/bus/icache/icache/cachefsm/CurrState +add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/icache/ReadDataWord +add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/icache/SelAdr +add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/icache/RAdr +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/bus/icache/icache/CacheHit +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/bus/icache/icache/CacheStall +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/bus/icache/icache/ReadDataLineSets +add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/icache/CacheMemWriteData +add wave -noupdate -group icache /testbench/dut/core/ifu/SpillSupport/spillsupport/SpillDataLine0 add wave -noupdate -group AHB -color Gold /testbench/dut/core/ebu/BusState add wave -noupdate -group AHB /testbench/dut/core/ebu/NextBusState add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/core/ebu/AtomicMaskedM @@ -196,12 +196,12 @@ add wave -noupdate -group AHB /testbench/dut/core/ebu/HMASTLOCK add wave -noupdate -group AHB /testbench/dut/core/ebu/HADDRD add wave -noupdate -group AHB /testbench/dut/core/ebu/HSIZED add wave -noupdate -group AHB /testbench/dut/core/ebu/HWRITED -add wave -noupdate -group AMO_ALU /testbench/dut/core/lsu/amo/amoalu/funct -add wave -noupdate -group AMO_ALU /testbench/dut/core/lsu/amo/amoalu/result -add wave -noupdate -group AMO_ALU /testbench/dut/core/lsu/amo/amoalu/srca -add wave -noupdate -group AMO_ALU /testbench/dut/core/lsu/amo/amoalu/srcb -add wave -noupdate -group AMO_ALU /testbench/dut/core/lsu/amo/amoalu/width -add wave -noupdate -expand -group lsu -color Gold /testbench/dut/core/lsu/MEM_VIRTMEM/interlockfsm/InterlockCurrState +add wave -noupdate -group AMO_ALU /testbench/dut/core/lsu/atomic/atomic/amoalu/funct +add wave -noupdate -group AMO_ALU /testbench/dut/core/lsu/atomic/atomic/amoalu/result +add wave -noupdate -group AMO_ALU /testbench/dut/core/lsu/atomic/atomic/amoalu/srca +add wave -noupdate -group AMO_ALU /testbench/dut/core/lsu/atomic/atomic/amoalu/srcb +add wave -noupdate -group AMO_ALU /testbench/dut/core/lsu/atomic/atomic/amoalu/width +add wave -noupdate -expand -group lsu -color Gold /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/interlockfsm/InterlockCurrState add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/SelHPTW add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/InterlockStall add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/LSUStallM @@ -212,7 +212,7 @@ add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/ add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/dcache/SRAMWayWriteEnable add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/dcache/SRAMWordEnable add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/dcache/SelAdr -add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/MEM_VIRTMEM/SelReplayCPURequest +add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/SelReplayCPURequest add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/IEUAdrE add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/IEUAdrM add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/dcache/RAdr @@ -220,8 +220,8 @@ add wave -noupdate -expand -group lsu -expand -group dcache -expand -group flush add wave -noupdate -expand -group lsu -expand -group dcache -expand -group flush /testbench/dut/core/lsu.bus.dcache/dcache/VictimDirtyWay add wave -noupdate -expand -group lsu -expand -group dcache -expand -group flush /testbench/dut/core/lsu.bus.dcache/dcache/VictimTag add wave -noupdate -expand -group lsu -expand -group dcache -expand -group flush /testbench/dut/core/lsu.bus.dcache/dcache/CacheBusAdr -add wave -noupdate -expand -group lsu -expand -group dcache -expand -group flush /testbench/dut/core/lsu/WordCount -add wave -noupdate -expand -group lsu -expand -group dcache -expand -group flush /testbench/dut/core/lsu.bus.dcache/dcache/FlushAdr +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group flush /testbench/dut/core/lsu/bus/busdp/WordCount +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group flush /testbench/dut/core/lsu/bus/dcache/dcache/FlushAdr add wave -noupdate -expand -group lsu -expand -group dcache -expand -group flush /testbench/dut/core/lsu.bus.dcache/dcache/FlushWay add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/dcache/CacheMemWriteData add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/dcache/WayHit @@ -319,7 +319,7 @@ add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/core/lsu.bus.dcache/dcache/CacheStall add wave -noupdate -expand -group lsu -expand -group dcache -group status /testbench/dut/core/lsu.bus.dcache/dcache/WayHit add wave -noupdate -expand -group lsu -expand -group dcache -group status -color {Medium Orchid} /testbench/dut/core/lsu.bus.dcache/dcache/CacheHit -add wave -noupdate -expand -group lsu -expand -group dcache -group status /testbench/dut/core/lsu/WordCount +add wave -noupdate -expand -group lsu -expand -group dcache -group status /testbench/dut/core/lsu/bus/busdp/WordCount add wave -noupdate -expand -group lsu -expand -group dcache -group {Memory Side} /testbench/dut/core/lsu.bus.dcache/dcache/CacheBusAdr add wave -noupdate -expand -group lsu -expand -group dcache -group {Memory Side} /testbench/dut/core/lsu.bus.dcache/dcache/CacheFetchLine add wave -noupdate -expand -group lsu -expand -group dcache -group {Memory Side} /testbench/dut/core/lsu.bus.dcache/dcache/CacheWriteLine @@ -360,20 +360,20 @@ add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dm add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/pmpchecker/pmpchecker/W add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/pmpchecker/pmpchecker/X add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/pmpchecker/pmpchecker/L -add wave -noupdate -expand -group lsu -group ptwalker -color Gold /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/WalkerState -add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/PCF -add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/HPTWAdr -add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/HPTWReadPTE -add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/HPTWAdr -add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/PTE -add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/ITLBMissF -add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/DTLBMissM -add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/ITLBWriteF -add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/DTLBWriteM -add wave -noupdate -group itlb /testbench/dut/core/ifu/immu/TLBWrite +add wave -noupdate -expand -group lsu -group ptwalker -color Gold /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/WalkerState +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/PCF +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/HPTWAdr +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/HPTWReadPTE +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/HPTWAdr +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/PTE +add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/ITLBMissF +add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/DTLBMissM +add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/ITLBWriteF +add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/DTLBWriteM +add wave -noupdate -group itlb /testbench/dut/core/ifu/immu/immu//TLBWrite add wave -noupdate -group itlb /testbench/dut/core/ifu/ITLBMissF -add wave -noupdate -group itlb /testbench/dut/core/ifu/immu/PhysicalAddress -add wave -noupdate -group itlb /testbench/dut/core/ifu/immu/PMAInstrAccessFaultF +add wave -noupdate -group itlb /testbench/dut/core/ifu/immu/immu/PhysicalAddress +add wave -noupdate -group itlb /testbench/dut/core/ifu/immu/immu/PMAInstrAccessFaultF add wave -noupdate -group plic /testbench/dut/uncore/plic/plic/HCLK add wave -noupdate -group plic /testbench/dut/uncore/plic/plic/HSELPLIC add wave -noupdate -group plic /testbench/dut/uncore/plic/plic/HADDR @@ -470,10 +470,10 @@ add wave -noupdate /testbench/dut/core/ifu/BPPredWrongM add wave -noupdate /testbench/dut/core/ifu/InvalidateICacheM add wave -noupdate -expand -group ifu /testbench/dut/core/ifu/PCF add wave -noupdate -expand -group ifu /testbench/dut/core/ifu/PostSpillInstrRawF -add wave -noupdate -expand -group ifu -expand -group {Bus FSM} -color Gold /testbench/dut/core/ifu/busfsm/BusCurrState +add wave -noupdate -expand -group ifu -expand -group {Bus FSM} -color Gold /testbench/dut/core/ifu/bus/busfsm/BusCurrState add wave -noupdate -expand -group ifu -expand -group {Bus FSM} /testbench/dut/core/ifu/BusStall -add wave -noupdate -expand -group ifu -expand -group Spills /testbench/dut/core/ifu/SpillSupport/Spill -add wave -noupdate -expand -group ifu -expand -group Spills -color Gold /testbench/dut/core/ifu/SpillSupport/CurrState +add wave -noupdate -expand -group ifu -expand -group Spills /testbench/dut/core/ifu/SpillSupport/spillsupport/SpillF +add wave -noupdate -expand -group ifu -expand -group Spills -color Gold /testbench/dut/core/ifu/SpillSupport/spillsupport/CurrState add wave -noupdate /testbench/dut/core/lsu.bus.dcache/dcache/VictimTag TreeUpdate [SetDefaultTree] WaveRestoreCursors {{Cursor 6} {5187387 ns} 1} {{Cursor 5} {88705641 ns} 0} diff --git a/pipelined/regression/wave-coremark.do b/pipelined/regression/wave-coremark.do index f1a38e989..4c1a77472 100644 --- a/pipelined/regression/wave-coremark.do +++ b/pipelined/regression/wave-coremark.do @@ -98,7 +98,7 @@ add wave -noupdate -group Bpred -expand -group {bp wrong} /testbench/dut/core/if add wave -noupdate -group Bpred -expand -group {bp wrong} /testbench/dut/core/ifu/bpred/bpred/BPPredWrongE add wave -noupdate -group Bpred /testbench/dut/core/ifu/bpred/bpred/BPPredWrongE add wave -noupdate -group {instruction pipeline} /testbench/InstrFName -add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/icache/FinalInstrRawF +add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/bus/icache/FinalInstrRawF add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/InstrD add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/InstrE add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/InstrM @@ -174,44 +174,44 @@ add wave -noupdate -group muldiv /testbench/dut/core/mdu/FlushM add wave -noupdate -group muldiv /testbench/dut/core/mdu/FlushW add wave -noupdate -group muldiv /testbench/dut/core/mdu/MulDivResultW add wave -noupdate -group muldiv /testbench/dut/core/mdu/DivBusyE -add wave -noupdate -group icache -color Gold /testbench/dut/core/ifu/icache/controller/CurrState -add wave -noupdate -group icache /testbench/dut/core/ifu/icache/BasePAdrF -add wave -noupdate -group icache /testbench/dut/core/ifu/icache/WayHit -add wave -noupdate -group icache /testbench/dut/core/ifu/icache/VictimWay -add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 {/testbench/dut/core/ifu/icache/MemWay[0]/WriteEnable} -add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 {/testbench/dut/core/ifu/icache/MemWay[0]/SetValid} -add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -label TAG {/testbench/dut/core/ifu/icache/MemWay[0]/CacheTagMem/StoredData} -add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 {/testbench/dut/core/ifu/icache/MemWay[0]/ValidBits} -add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/core/ifu/icache/MemWay[0]/word[0]/CacheDataMem/StoredData} -add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/core/ifu/icache/MemWay[0]/word[0]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -group Way0Word1 {/testbench/dut/core/ifu/icache/MemWay[0]/word[1]/CacheDataMem/StoredData} -add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -group Way0Word1 {/testbench/dut/core/ifu/icache/MemWay[0]/word[1]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -group Way0Word2 {/testbench/dut/core/ifu/icache/MemWay[0]/word[2]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -group Way0Word2 {/testbench/dut/core/ifu/icache/MemWay[0]/word[2]/CacheDataMem/StoredData} -add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -group Way0Word3 {/testbench/dut/core/ifu/icache/MemWay[0]/word[3]/CacheDataMem/WriteEnable} -add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -group Way0Word3 {/testbench/dut/core/ifu/icache/MemWay[0]/word[3]/CacheDataMem/StoredData} -add wave -noupdate -group icache /testbench/dut/core/ifu/icache/controller/NextState +add wave -noupdate -group icache -color Gold /testbench/dut/core/ifu/bus/icache/controller/CurrState +add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/BasePAdrF +add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/WayHit +add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/VictimWay +add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 {/testbench/dut/core/ifu/bus/icache/MemWay[0]/WriteEnable} +add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 {/testbench/dut/core/ifu/bus/icache/MemWay[0]/SetValid} +add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -label TAG {/testbench/dut/core/ifu/bus/icache/MemWay[0]/CacheTagMem/StoredData} +add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 {/testbench/dut/core/ifu/bus/icache/MemWay[0]/ValidBits} +add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/core/ifu/bus/icache/MemWay[0]/word[0]/CacheDataMem/StoredData} +add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/core/ifu/bus/icache/MemWay[0]/word[0]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -group Way0Word1 {/testbench/dut/core/ifu/bus/icache/MemWay[0]/word[1]/CacheDataMem/StoredData} +add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -group Way0Word1 {/testbench/dut/core/ifu/bus/icache/MemWay[0]/word[1]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -group Way0Word2 {/testbench/dut/core/ifu/bus/icache/MemWay[0]/word[2]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -group Way0Word2 {/testbench/dut/core/ifu/bus/icache/MemWay[0]/word[2]/CacheDataMem/StoredData} +add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -group Way0Word3 {/testbench/dut/core/ifu/bus/icache/MemWay[0]/word[3]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 -group Way0Word3 {/testbench/dut/core/ifu/bus/icache/MemWay[0]/word[3]/CacheDataMem/StoredData} +add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/controller/NextState add wave -noupdate -group icache /testbench/dut/core/ifu/ITLBMissF -add wave -noupdate -group icache /testbench/dut/core/ifu/icache/ITLBWriteF -add wave -noupdate -group icache /testbench/dut/core/ifu/icache/ReadLineF -add wave -noupdate -group icache /testbench/dut/core/ifu/icache/ReadLineF -add wave -noupdate -group icache /testbench/dut/core/ifu/icache/BasePAdrF -add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/icache/controller/hit -add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/icache/controller/spill -add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/icache/controller/ICacheStallF -add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/icache/controller/spillSave -add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/icache/controller/spillSave -add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/icache/controller/CntReset -add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/icache/controller/PreCntEn -add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/icache/controller/CntEn -add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/icache/InstrPAdrF -add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/icache/InstrInF -add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/icache/controller/FetchCountFlag -add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/icache/FetchCount -add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/icache/controller/InstrReadF -add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/icache/controller/InstrAckF -add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/icache/controller/ICacheMemWriteEnable -add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/icache/ICacheMemWriteData +add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/ITLBWriteF +add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/ReadLineF +add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/ReadLineF +add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/BasePAdrF +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/bus/icache/controller/hit +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/bus/icache/controller/spill +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/bus/icache/controller/ICacheStallF +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/bus/icache/controller/spillSave +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/bus/icache/controller/spillSave +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/bus/icache/controller/CntReset +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/bus/icache/controller/PreCntEn +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/bus/icache/controller/CntEn +add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/InstrPAdrF +add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/InstrInF +add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/controller/FetchCountFlag +add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/FetchCount +add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/controller/InstrReadF +add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/controller/InstrAckF +add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/controller/ICacheMemWriteEnable +add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/ICacheMemWriteData add wave -noupdate -group AHB -color Gold /testbench/dut/core/ebu/BusState add wave -noupdate -group AHB /testbench/dut/core/ebu/NextBusState add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/core/ebu/AtomicMaskedM diff --git a/pipelined/regression/wave.do b/pipelined/regression/wave.do index 6c198e484..743148967 100644 --- a/pipelined/regression/wave.do +++ b/pipelined/regression/wave.do @@ -25,7 +25,7 @@ add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/EcallFaultM add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InstrPageFaultM add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/LoadPageFaultM -add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/StorePageFaultM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/StoreAmoPageFaultM add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InterruptM add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/PendingInterruptM add wave -noupdate -group HDU -group Flush -color Yellow /testbench/dut/core/hzu/FlushF @@ -177,15 +177,15 @@ add wave -noupdate -group AHB /testbench/dut/core/ebu/HMASTLOCK add wave -noupdate -group AHB /testbench/dut/core/ebu/HADDRD add wave -noupdate -group AHB /testbench/dut/core/ebu/HSIZED add wave -noupdate -group AHB /testbench/dut/core/ebu/HWRITED -add wave -noupdate -group lsu -color Gold /testbench/dut/core/lsu/MEM_VIRTMEM/interlockfsm/InterlockCurrState +add wave -noupdate -group lsu -color Gold /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/interlockfsm/InterlockCurrState add wave -noupdate -group lsu /testbench/dut/core/lsu/SelHPTW add wave -noupdate -group lsu /testbench/dut/core/lsu/InterlockStall add wave -noupdate -group lsu /testbench/dut/core/lsu/LSUStallM add wave -noupdate -group lsu /testbench/dut/core/lsu/ReadDataWordMuxM add wave -noupdate -group lsu /testbench/dut/core/lsu/ReadDataM add wave -noupdate -group lsu /testbench/dut/core/lsu/WriteDataM -add wave -noupdate -group lsu /testbench/dut/core/lsu/SelUncachedAdr -add wave -noupdate -group lsu -group bus -color Gold /testbench/dut/core/lsu/busfsm/BusCurrState +add wave -noupdate -group lsu /testbench/dut/core/lsu/bus/busdp/SelUncachedAdr +add wave -noupdate -group lsu -group bus -color Gold /testbench/dut/core/lsu/bus/busdp/busfsm/BusCurrState add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/BusStall add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/LSUBusRead add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/LSUBusWrite @@ -201,7 +201,7 @@ add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus. add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/dcache/SRAMWordEnable add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/dcache/SRAMLineWayWriteEnable add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/dcache/SelAdr -add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu/MEM_VIRTMEM/SelReplayCPURequest +add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/SelReplayCPURequest add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu/IEUAdrE add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu/IEUAdrM add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/dcache/RAdr @@ -349,15 +349,15 @@ add wave -noupdate -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/pmpch add wave -noupdate -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPInstrAccessFaultF add wave -noupdate -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPLoadAccessFaultM add wave -noupdate -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPStoreAmoAccessFaultM -add wave -noupdate -group lsu -group ptwalker -color Gold /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/WalkerState -add wave -noupdate -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/PCF -add wave -noupdate -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/HPTWReadPTE -add wave -noupdate -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/HPTWAdr -add wave -noupdate -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/PTE -add wave -noupdate -group lsu -group ptwalker -group types /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/ITLBMissF -add wave -noupdate -group lsu -group ptwalker -group types /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/DTLBMissM -add wave -noupdate -group lsu -group ptwalker -group types /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/ITLBWriteF -add wave -noupdate -group lsu -group ptwalker -group types /testbench/dut/core/lsu/MEM_VIRTMEM/hptw/DTLBWriteM +add wave -noupdate -group lsu -group ptwalker -color Gold /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/WalkerState +add wave -noupdate -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/PCF +add wave -noupdate -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/HPTWReadPTE +add wave -noupdate -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/HPTWAdr +add wave -noupdate -group lsu -group ptwalker /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/PTE +add wave -noupdate -group lsu -group ptwalker -group types /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/ITLBMissF +add wave -noupdate -group lsu -group ptwalker -group types /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/DTLBMissM +add wave -noupdate -group lsu -group ptwalker -group types /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/ITLBWriteF +add wave -noupdate -group lsu -group ptwalker -group types /testbench/dut/core/lsu/MEM_VIRTMEM/lsuvirtmem/hptw/DTLBWriteM add wave -noupdate -group plic /testbench/dut/uncore/plic/plic/HCLK add wave -noupdate -group plic /testbench/dut/uncore/plic/plic/HSELPLIC add wave -noupdate -group plic /testbench/dut/uncore/plic/plic/HADDR @@ -434,35 +434,34 @@ add wave -noupdate -group {pc selection} /testbench/dut/core/ifu/PCNext2F add wave -noupdate -group {pc selection} /testbench/dut/core/ifu/PrivilegedNextPCM add wave -noupdate -group {pc selection} /testbench/dut/core/ifu/PrivilegedChangePCM add wave -noupdate /testbench/dut/core/priv/priv/csr/MEPC_REGW -add wave -noupdate /testbench/dut/core/lsu/LocalLSUBusAdr -add wave -noupdate /testbench/dut/core/lsu/busfsm/BusNextState -add wave -noupdate /testbench/dut/core/lsu/busfsm/DCacheFetchLine -add wave -noupdate /testbench/dut/core/lsu/busfsm/DCacheWriteLine -add wave -noupdate -expand -group ifu -color Gold /testbench/dut/core/ifu/busfsm/BusCurrState +add wave -noupdate /testbench/dut/core/lsu/bus/busdp/LocalLSUBusAdr +add wave -noupdate /testbench/dut/core/lsu/bus/busdp/busfsm/DCacheFetchLine +add wave -noupdate /testbench/dut/core/lsu/bus/busdp/busfsm/DCacheWriteLine +add wave -noupdate -expand -group ifu -color Gold /testbench/dut/core/lsu/bus/busdp/busfsm/BusCurrState add wave -noupdate -expand -group ifu /testbench/dut/core/ifu/IFUBusRead add wave -noupdate -expand -group ifu /testbench/dut/core/ifu/IFUBusAdr -add wave -noupdate -expand -group ifu /testbench/dut/core/ifu/busfsm/LSUBusAck +add wave -noupdate -expand -group ifu /testbench/dut/core/ifu/IFUBusAck add wave -noupdate -expand -group ifu /testbench/dut/core/ifu/IFUBusHRDATA -add wave -noupdate -expand -group ifu -expand -group spill /testbench/dut/core/ifu/SpillSupport/Spill -add wave -noupdate -expand -group ifu -expand -group spill /testbench/dut/core/ifu/SpillSupport/CurrState -add wave -noupdate -expand -group ifu -expand -group spill /testbench/dut/core/ifu/SpillSupport/SpillDataLine0 -add wave -noupdate -expand -group ifu -expand -group spill /testbench/dut/core/ifu/SpillSupport/SelSpill -add wave -noupdate -expand -group ifu -expand -group icache -color Gold /testbench/dut/core/ifu/icache/icache/cachefsm/CurrState +add wave -noupdate -expand -group ifu -expand -group spill /testbench/dut/core/ifu/SpillSupport/spillsupport/SpillF +add wave -noupdate -expand -group ifu -expand -group spill /testbench/dut/core/ifu/SpillSupport/spillsupport/CurrState +add wave -noupdate -expand -group ifu -expand -group spill /testbench/dut/core/ifu/SpillSupport/spillsupport/SpillDataLine0 +add wave -noupdate -expand -group ifu -expand -group spill /testbench/dut/core/ifu/SpillSupport/spillsupport/SelSpillF +add wave -noupdate -expand -group ifu -expand -group icache -color Gold /testbench/dut/core/ifu/bus/icache/icache/cachefsm/CurrState add wave -noupdate -expand -group ifu -expand -group icache /testbench/dut/core/ifu/ITLBMissF -add wave -noupdate -expand -group ifu -expand -group icache /testbench/dut/core/ifu/icache/icache/SelAdr +add wave -noupdate -expand -group ifu -expand -group icache /testbench/dut/core/ifu/bus/icache/icache/SelAdr add wave -noupdate -expand -group ifu -expand -group icache /testbench/dut/core/ifu/PCNextF add wave -noupdate -expand -group ifu -expand -group icache /testbench/dut/core/ifu/PCPF -add wave -noupdate -expand -group ifu -expand -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/icache/icache/WayHit +add wave -noupdate -expand -group ifu -expand -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/bus/icache/icache/WayHit add wave -noupdate -expand -group ifu -expand -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/ICacheStallF add wave -noupdate -expand -group ifu -expand -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/FinalInstrRawF -add wave -noupdate -expand -group ifu -expand -group icache -expand -group memory /testbench/dut/core/ifu/icache/icache/CacheBusAdr -add wave -noupdate -expand -group ifu -expand -group icache -expand -group memory /testbench/dut/core/ifu/icache/icache/cachefsm/CacheBusAck -add wave -noupdate -expand -group ifu -expand -group icache -expand -group memory /testbench/dut/core/ifu/icache/icache/CacheMemWriteData -add wave -noupdate -expand -group ifu -group itlb /testbench/dut/core/ifu/immu/TLBWrite +add wave -noupdate -expand -group ifu -expand -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/icache/CacheBusAdr +add wave -noupdate -expand -group ifu -expand -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/icache/cachefsm/CacheBusAck +add wave -noupdate -expand -group ifu -expand -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/icache/CacheMemWriteData +add wave -noupdate -expand -group ifu -group itlb /testbench/dut/core/ifu/immu/immu/TLBWrite add wave -noupdate -expand -group ifu -group itlb /testbench/dut/core/ifu/ITLBMissF -add wave -noupdate -expand -group ifu -group itlb /testbench/dut/core/ifu/immu/PhysicalAddress +add wave -noupdate -expand -group ifu -group itlb /testbench/dut/core/ifu/immu/immu/PhysicalAddress add wave -noupdate /testbench/dut/core/ifu/IFUBusRead -add wave -noupdate /testbench/dut/core/ifu/icache/icache/CacheFetchLine +add wave -noupdate /testbench/dut/core/ifu/bus/icache/icache/CacheFetchLine add wave -noupdate -radix unsigned -childformat {{{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[31]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[30]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[29]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[28]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[27]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[26]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[25]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[24]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[23]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[22]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[21]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[20]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[19]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[18]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[17]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[16]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[15]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[14]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[13]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[12]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[11]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[10]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[9]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[8]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[7]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[6]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[5]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[4]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[3]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[2]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[1]} -radix unsigned} {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[0]} -radix unsigned}} -subitemconfig {{/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[31]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[30]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[29]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[28]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[27]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[26]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[25]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[24]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[23]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[22]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[21]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[20]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[19]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[18]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[17]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[16]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[15]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[14]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[13]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[12]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[11]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[10]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[9]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[8]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[7]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[6]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[5]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[4]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[3]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[2]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[1]} {-height 16 -radix unsigned} {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[0]} {-height 16 -radix unsigned}} /testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW add wave -noupdate -expand -group {Performance Counters} -label MCYCLE -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[0]} add wave -noupdate -expand -group {Performance Counters} -label MINSTRET -radix unsigned {/testbench/dut/core/priv/priv/csr/counters/counters/HPMCOUNTER_REGW[2]} diff --git a/pipelined/src/fpu/cvtfp.sv b/pipelined/src/fpu/cvtfp.sv index 0b91b82e4..95c0d1799 100644 --- a/pipelined/src/fpu/cvtfp.sv +++ b/pipelined/src/fpu/cvtfp.sv @@ -40,7 +40,7 @@ module cvtfp ( logic [8:0] i,NormCnt; always_comb begin i = 0; - while (~XManE[52-i] && i <= 52) i = i+1; // search for leading one + while (~XManE[52-i] & i <= 52) i = i+1; // search for leading one NormCnt = i; end diff --git a/pipelined/src/fpu/faddcvt.sv b/pipelined/src/fpu/faddcvt.sv index 5737b463d..e5dddb7e9 100755 --- a/pipelined/src/fpu/faddcvt.sv +++ b/pipelined/src/fpu/faddcvt.sv @@ -187,12 +187,12 @@ module fpuaddcvt1 ( logic [8:0] j; always_comb begin i = 0; - while (~mantissaA[52-i] && $unsigned(i) <= $unsigned(52)) i = i+1; // search for leading one + while (~mantissaA[52-i] & $unsigned(i) <= $unsigned(52)) i = i+1; // search for leading one ZP_mantissaA = i; end always_comb begin j = 0; - while (~mantissaB[52-j] && $unsigned(j) <= $unsigned(52)) j = j+1; // search for leading one + while (~mantissaB[52-j] & $unsigned(j) <= $unsigned(52)) j = j+1; // search for leading one ZP_mantissaB = j; end diff --git a/pipelined/src/fpu/fcvt.sv b/pipelined/src/fpu/fcvt.sv index e238560ff..3e89afde2 100644 --- a/pipelined/src/fpu/fcvt.sv +++ b/pipelined/src/fpu/fcvt.sv @@ -85,7 +85,7 @@ module fcvt ( logic [8:0] i; always_comb begin i = 0; - while (~PosInt[64-1-i] && i < `XLEN) i = i+1; // search for leading one + while (~PosInt[64-1-i] & i < `XLEN) i = i+1; // search for leading one LZResP = i[5:0]+1; // compute shift count end diff --git a/pipelined/src/fpu/fma.sv b/pipelined/src/fpu/fma.sv index 368d02c47..3ce4495ce 100644 --- a/pipelined/src/fpu/fma.sv +++ b/pipelined/src/fpu/fma.sv @@ -396,7 +396,7 @@ module lzc( logic [8:0] i; always_comb begin i = 0; - while (~f[3*`NF+6-i] && $unsigned(i) <= $unsigned(9'd3*9'd`NF+9'd6)) i = i+1; // search for leading one + while (~f[3*`NF+6-i] & $unsigned(i) <= $unsigned(9'd3*9'd`NF+9'd6)) i = i+1; // search for leading one NormCntE = i; end endmodule @@ -768,7 +768,7 @@ module fmaflags( // 3) 0 * Inf assign SigNaN = XSNaNM | YSNaNM | ZSNaNM; - assign Invalid = SigNaN | ((XInfM || YInfM) & ZInfM & (PSgnM ^ ZSgnEffM) & ~XNaNM & ~YNaNM) | (XZeroM & YInfM) | (YZeroM & XInfM); + assign Invalid = SigNaN | ((XInfM | YInfM) & ZInfM & (PSgnM ^ ZSgnEffM) & ~XNaNM & ~YNaNM) | (XZeroM & YInfM) | (YZeroM & XInfM); // Set Overflow flag if the number is too big to be represented // - Don't set the overflow flag if an overflowed result isn't outputed diff --git a/pipelined/src/fpu/fsm_fpdiv_pipe.sv b/pipelined/src/fpu/fsm_fpdiv_pipe.sv index afef96be9..33d270b89 100755 --- a/pipelined/src/fpu/fsm_fpdiv_pipe.sv +++ b/pipelined/src/fpu/fsm_fpdiv_pipe.sv @@ -129,7 +129,7 @@ module fsm_fpdiv_pipe ( end // if (start==1'b0) S65: begin - if (op_type==1'b0 && P==1'b0) + if (op_type==1'b0 & P==1'b0) begin done = 1'b0; divBusy = 1'b1; @@ -146,7 +146,7 @@ module fsm_fpdiv_pipe ( sel_muxr = 1'b0; next_state = S1; end - else if (op_type==1'b0 && P==1'b1) + else if (op_type==1'b0 & P==1'b1) begin done = 1'b0; divBusy = 1'b1; @@ -163,7 +163,7 @@ module fsm_fpdiv_pipe ( sel_muxr = 1'b0; next_state = S36; end - else if (op_type==1'b1 && P==1'b0) + else if (op_type==1'b1 & P==1'b0) begin done = 1'b0; divBusy = 1'b1; @@ -180,7 +180,7 @@ module fsm_fpdiv_pipe ( sel_muxr = 1'b0; next_state = S15; end - else if (op_type==1'b1 && P==1'b1) + else if (op_type==1'b1 & P==1'b1) begin done = 1'b0; divBusy = 1'b1; diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index 165057829..7cee766bb 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -85,13 +85,15 @@ module ifu ( ); (* mark_debug = "true" *) logic [`XLEN-1:0] PCCorrectE, UnalignedPCNextF, PCNextF; - logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM; + logic BranchMisalignedFaultE; logic PrivilegedChangePCM; logic IllegalCompInstrD; logic [`XLEN-1:0] PCPlus2or4F, PCLinkD; logic [`XLEN-3:0] PCPlusUpperF; logic CompressedF; - logic [31:0] InstrRawD, FinalInstrRawF, InstrRawF; + logic [31:0] InstrRawD, InstrRawF; + logic [`XLEN-1:0] FinalInstrRawF; + logic [31:0] InstrE; logic [`XLEN-1:0] PCD; @@ -114,202 +116,127 @@ module ifu ( logic CPUBusy; (* mark_debug = "true" *) logic [31:0] PostSpillInstrRawF; - localparam integer SPILLTHRESHOLD = `MEM_ICACHE ? `ICACHE_LINELENINBITS/32 : 1; - - //////////////////////////////////////////////////////////////////////////////////////////////// - // Spill Support *** add other banners - //////////////////////////////////////////////////////////////////////////////////////////////// - - if(`C_SUPPORTED) begin : SpillSupport - logic [`XLEN-1:0] PCPlus2F; - logic TakeSpillF; - logic SpillF; - logic SelSpillF, SpillSaveF; - logic [15:0] SpillDataLine0; - - // *** PLACE ALL THIS IN A MODULE - // this exists only if there are compressed instructions. - // reuse PC+2/4 circuitry to avoid needing a second CPA to add 2 - mux2 #(`XLEN) pcplus2mux(.d0({PCF[`XLEN-1:2], 2'b10}), .d1({PCPlusUpperF, 2'b00}), .s(PCF[1]), .y(PCPlus2F)); - mux2 #(`XLEN) pcnextspillmux(.d0(PCNextF), .d1(PCPlus2F), .s(SelNextSpillF), .y(PCNextFSpill)); - mux2 #(`XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCFSpill)); - - assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1]; - - typedef enum {STATE_SPILL_READY, STATE_SPILL_SPILL} statetype; - (* mark_debug = "true" *) statetype CurrState, NextState; - - always_ff @(posedge clk) - if (reset) CurrState <= #1 STATE_SPILL_READY; - else CurrState <= #1 NextState; - - assign TakeSpillF = SpillF & ~IFUCacheBusStallF; - - always_comb begin - case (CurrState) - STATE_SPILL_READY: if (TakeSpillF) NextState = STATE_SPILL_SPILL; - else NextState = STATE_SPILL_READY; - STATE_SPILL_SPILL: if(IFUCacheBusStallF | StallF) NextState = STATE_SPILL_SPILL; - else NextState = STATE_SPILL_READY; - default: NextState = STATE_SPILL_READY; - endcase - end - - assign SelSpillF = (CurrState == STATE_SPILL_SPILL); - assign SelNextSpillF = (CurrState == STATE_SPILL_READY & TakeSpillF) | - (CurrState == STATE_SPILL_SPILL & IFUCacheBusStallF); - assign SpillSaveF = (CurrState == STATE_SPILL_READY) & TakeSpillF; - - flopenr #(16) SpillInstrReg(.clk(clk), - .en(SpillSaveF), - .reset(reset), - .d(`MEM_ICACHE ? InstrRawF[15:0] : InstrRawF[31:16]), - .q(SpillDataLine0)); - - assign PostSpillInstrRawF = SpillF ? {InstrRawF[15:0], SpillDataLine0} : InstrRawF; - assign CompressedF = PostSpillInstrRawF[1:0] != 2'b11; - - // end of spill support - end else begin : NoSpillSupport // line: SpillSupport - assign PCNextFSpill = PCNextF; - assign PCFSpill = PCF; - assign SelNextSpillF = 0; - assign PostSpillInstrRawF = InstrRawF; - end - - assign PCFExt = {2'b00, PCFSpill}; - mmu #(.TLB_ENTRIES(`ITLB_ENTRIES), .IMMU(1)) - immu(.PAdr(PCFExt[`PA_BITS-1:0]), - .VAdr(PCFSpill), - .Size(2'b10), - .PTE(PTE), - .PageTypeWriteVal(PageType), - .TLBWrite(ITLBWriteF), - .TLBFlush(ITLBFlushF), - .PhysicalAddress(PCPF), - .TLBMiss(ITLBMissF), - .InstrPageFaultF, - .ExecuteAccessF(1'b1), - .AtomicAccessM(1'b0), - .ReadAccessM(1'b0), - .WriteAccessM(1'b0), - .LoadAccessFaultM(), - .StoreAmoAccessFaultM(), - .LoadPageFaultM(), .StoreAmoPageFaultM(), - .LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(), - .DisableTranslation(1'b0), // *** is there a better name - .Cacheable(CacheableF), .Idempotent(), .AtomicAllowed(), + ///////////////////////////////////////////////////////////////////////////////////////////// + // Spill Support *** add other banners + ///////////////////////////////////////////////////////////////////////////////////////////// - .clk, .reset, - .SATP_REGW, - .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, - .STATUS_MPP, - .PrivilegeModeW, - .InstrAccessFaultF, - .PMPCFG_ARRAY_REGW, - .PMPADDR_ARRAY_REGW - ); + if(`C_SUPPORTED) begin : SpillSupport - // conditional - // 1. ram // controlled by `MEM_IROM - // 2. cache // `MEM_ICACHE - // 3. wire pass-through + spillsupport spillsupport(.clk, .reset, .StallF, .PCF, .PCPlusUpperF, .PCNextF, .InstrRawF, + .IFUCacheBusStallF, .PCNextFSpill, .PCFSpill, .SelNextSpillF, + .PostSpillInstrRawF, .CompressedF); + end else begin : NoSpillSupport + assign PCNextFSpill = PCNextF; + assign PCFSpill = PCF; + assign PostSpillInstrRawF = InstrRawF; + assign {SelNextSpillF, CompressedF} = 0; + end - // If we have `MEM_IROM we don't have the bus controller - // otherwise we have the bus controller and either a cache or a passthrough. + //////////////////////////////////////////////////////////////////////////////////////////////// + // Memory management + //////////////////////////////////////////////////////////////////////////////////////////////// + if(`ZICSR_SUPPORTED == 1) begin : immu + mmu #(.TLB_ENTRIES(`ITLB_ENTRIES), .IMMU(1)) + immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, + .PrivilegeModeW, .DisableTranslation(1'b0), + .PAdr(PCFExt[`PA_BITS-1:0]), + .VAdr(PCFSpill), + .Size(2'b10), + .PTE(PTE), + .PageTypeWriteVal(PageType), + .TLBWrite(ITLBWriteF), + .TLBFlush(ITLBFlushF), + .PhysicalAddress(PCPF), + .TLBMiss(ITLBMissF), + .Cacheable(CacheableF), .Idempotent(), .AtomicAllowed(), + .InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(), + .InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(), + .LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(), + .AtomicAccessM(1'b0),.ExecuteAccessF(1'b1), .WriteAccessM(1'b0), .ReadAccessM(1'b0), + .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW); - // *** make this area look like LSU, including moving I$. Hide localparams in submodules when feasible + end else begin + assign {ITLBMissF, InstrAccessFaultF} = '0; + assign InstrPageFaultF = '0; + assign PCPF = PCF; + assign CacheableF = '1; + end - localparam integer WORDSPERLINE = `MEM_ICACHE ? `ICACHE_LINELENINBITS/`XLEN : 1; - localparam integer LOGWPL = `MEM_ICACHE ? $clog2(WORDSPERLINE) : 1; - localparam integer LINELEN = `MEM_ICACHE ? `ICACHE_LINELENINBITS : `XLEN; - localparam integer WordCountThreshold = `MEM_ICACHE ? WORDSPERLINE - 1 : 0; + //////////////////////////////////////////////////////////////////////////////////////////////// + // Memory + //////////////////////////////////////////////////////////////////////////////////////////////// - localparam integer LINEBYTELEN = LINELEN/8; - localparam integer OFFSETLEN = $clog2(LINEBYTELEN); + logic [`XLEN-1:0] AllInstrRawF; + assign InstrRawF = AllInstrRawF[31:0]; - logic [LOGWPL-1:0] WordCount; - logic [LINELEN-1:0] ICacheMemWriteData; - logic ICacheBusAck; - logic [`PA_BITS-1:0] LocalIFUBusAdr; - logic [`PA_BITS-1:0] ICacheBusAdr; - logic SelUncachedAdr; if (`MEM_IROM) begin : irom - logic [`XLEN-1:0] FinalInstrRawF_FIXME; - - simpleram #( - .BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram ( - .clk, - .a(CPUBusy | reset ? PCPF[31:0] : PCNextFSpill[31:0]), // mux is also inside $, have to replay address if CPU is stalled. - .we(1'b0), - .wd(0), .rd(FinalInstrRawF_FIXME)); - assign FinalInstrRawF = FinalInstrRawF_FIXME[31:0]; - assign BusStall = 0; - assign IFUBusRead = 0; - assign ICacheBusAck = 0; - assign SelUncachedAdr = 0; - assign IFUBusAdr = 0; + dtim irom(.clk, .reset, .CPUBusy, .LSURWM(2'b10), .IEUAdrM(PCPF), .IEUAdrE(PCNextFSpill), + .TrapM(1'b0), .FinalWriteDataM(), + .ReadDataWordM(AllInstrRawF), .BusStall, .LSUBusWrite(), .LSUBusRead(IFUBusRead), + .BusCommittedM(), .ReadDataWordMuxM(), .DCacheStallM(ICacheStallF), + .DCacheCommittedM(), .DCacheMiss(ICacheMiss), .DCacheAccess(ICacheAccess)); + end else begin : bus - genvar index; - for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer - flopen #(`XLEN) fb(.clk(clk), - .en(IFUBusAck & IFUBusRead & (index == WordCount)), - .d(IFUBusHRDATA), - .q(ICacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN])); - end + localparam integer WORDSPERLINE = `MEM_ICACHE ? `ICACHE_LINELENINBITS/`XLEN : 1; + localparam integer LOGWPL = `MEM_ICACHE ? $clog2(WORDSPERLINE) : 1; + localparam integer LINELEN = `MEM_ICACHE ? `ICACHE_LINELENINBITS : `XLEN; + localparam integer WordCountThreshold = `MEM_ICACHE ? WORDSPERLINE - 1 : 0; - assign LocalIFUBusAdr = SelUncachedAdr ? PCPF : ICacheBusAdr; - assign IFUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalIFUBusAdr; + localparam integer LINEBYTELEN = LINELEN/8; + localparam integer OFFSETLEN = $clog2(LINEBYTELEN); - busfsm #(WordCountThreshold, LOGWPL, `MEM_ICACHE) - busfsm(.clk, .reset, .IgnoreRequest(ITLBMissF), - .LSURWM(2'b10), .DCacheFetchLine(ICacheFetchLine), .DCacheWriteLine(1'b0), - .LSUBusAck(IFUBusAck), - .CPUBusy, .CacheableM(CacheableF), - .BusStall, .LSUBusWrite(), .LSUBusRead(IFUBusRead), .DCacheBusAck(ICacheBusAck), - .BusCommittedM(), .SelUncachedAdr(SelUncachedAdr), .WordCount); + logic [LOGWPL-1:0] WordCount; + logic SelUncachedAdr; + logic [LINELEN-1:0] ICacheMemWriteData; + logic [`PA_BITS-1:0] LocalIFUBusAdr; + logic [`PA_BITS-1:0] ICacheBusAdr; + logic ICacheBusAck; + genvar index; + + + busdp #(WORDSPERLINE, LINELEN) + busdp(.clk, .reset, + .LSUBusHRDATA(IFUBusHRDATA), .LSUBusAck(IFUBusAck), .LSUBusWrite(), + .LSUBusRead(IFUBusRead), .LSUBusHWDATA(), .LSUBusSize(), + .LSUFunct3M(3'b010), .LSUBusAdr(IFUBusAdr), .DCacheBusAdr(ICacheBusAdr), + .ReadDataLineSetsM(), .DCacheFetchLine(ICacheFetchLine), + .DCacheWriteLine(1'b0), .DCacheBusAck(ICacheBusAck), + .DCacheMemWriteData(ICacheMemWriteData), .LSUPAdrM(PCPF), + .FinalAMOWriteDataM(), .ReadDataWordM(FinalInstrRawF), .ReadDataWordMuxM(AllInstrRawF), + .IgnoreRequest(ITLBMissF), .LSURWM(2'b10), .CPUBusy, .CacheableM(CacheableF), + .BusStall, .BusCommittedM()); + + if(`MEM_ICACHE) begin : icache + logic [1:0] IFURWF; + assign IFURWF = CacheableF ? 2'b10 : 2'b00; + + cache #(.LINELEN(`ICACHE_LINELENINBITS), + .NUMLINES(`ICACHE_WAYSIZEINBYTES*8/`ICACHE_LINELENINBITS), + .NUMWAYS(`ICACHE_NUMWAYS), .DCACHE(0)) + icache(.clk, .reset, .CPUBusy, .IgnoreRequest(ITLBMissF), + .CacheMemWriteData(ICacheMemWriteData), .CacheBusAck(ICacheBusAck), + .CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF), + .ReadDataWord(FinalInstrRawF), .CacheFetchLine(ICacheFetchLine), + .CacheWriteLine(), .ReadDataLineSets(), + .CacheMiss(ICacheMiss), .CacheAccess(ICacheAccess), + .FinalWriteData('0), + .RW(IFURWF), + .Atomic(2'b00), .FlushCache(1'b0), + .NextAdr(PCNextFSpill[11:0]), + .PAdr(PCPF), + .CacheCommitted(), .InvalidateCacheM(InvalidateICacheM)); + + end else begin : passthrough + assign {ICacheFetchLine, ICacheBusAdr, ICacheStallF, FinalInstrRawF} = '0; + assign ICacheAccess = CacheableF; assign ICacheMiss = CacheableF; + end end - // *** in same generate with bus - if(`MEM_ICACHE) begin : icache - logic [1:0] IFURWF; - assign IFURWF = CacheableF ? 2'b10 : 2'b00; - - logic [`XLEN-1:0] FinalInstrRawF_FIXME; - - cache #(.LINELEN(`ICACHE_LINELENINBITS), - .NUMLINES(`ICACHE_WAYSIZEINBYTES*8/`ICACHE_LINELENINBITS), - .NUMWAYS(`ICACHE_NUMWAYS), .DCACHE(0)) - icache(.clk, .reset, .CPUBusy, .IgnoreRequest(ITLBMissF), .CacheMemWriteData(ICacheMemWriteData) , .CacheBusAck(ICacheBusAck), - .CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF), .ReadDataWord(FinalInstrRawF_FIXME), - .CacheFetchLine(ICacheFetchLine), - .CacheWriteLine(), - .ReadDataLineSets(), - .CacheMiss(ICacheMiss), - .CacheAccess(ICacheAccess), - .FinalWriteData('0), - .RW(IFURWF), - .Atomic(2'b00), - .FlushCache(1'b0), - .NextAdr(PCNextFSpill[11:0]), - .PAdr(PCPF), - .CacheCommitted(), - .InvalidateCacheM(InvalidateICacheM)); - - assign FinalInstrRawF = FinalInstrRawF_FIXME[31:0]; - end else begin - assign ICacheFetchLine = 0; - assign ICacheBusAdr = 0; - assign ICacheStallF = 0; - if(!`MEM_IROM) assign FinalInstrRawF = 0; // *** move - assign ICacheAccess = CacheableF; - assign ICacheMiss = CacheableF; - end // branch predictor signal logic SelBPPredF; @@ -317,9 +244,6 @@ module ifu ( logic [4:0] InstrClassD, InstrClassE; - // select between dcache and direct from the BUS. Always selected if no dcache. - // handled in the busfsm. - mux2 #(32) UnCachedInstrMux(.d0(FinalInstrRawF), .d1(ICacheMemWriteData[31:0]), .s(SelUncachedAdr), .y(InstrRawF)); assign IFUCacheBusStallF = ICacheStallF | BusStall; assign IFUStallF = IFUCacheBusStallF | SelNextSpillF; @@ -401,22 +325,19 @@ module ifu ( // Misaligned PC logic + // Instruction address misalignement only from br/jal(r) instructions. // instruction address misalignment is generated by the target of control flow instructions, not // the fetch itself. - assign misaligned = PCNextF[0] | (PCNextF[1] & ~`C_SUPPORTED); - // do we really need to have check if the instruction is control flow? Yes - // Branches are updated in the execution stage but traps are updated in the memory stage. - - // pipeline misaligned faults to M stage - assign BranchMisalignedFaultE = misaligned & PCSrcE; // E-stage (Branch/Jump) misaligned - flopenr #(1) InstrMisalginedReg(clk, reset, ~StallM, BranchMisalignedFaultE, BranchMisalignedFaultM); + // xret and Traps both cannot produce instruction misaligned. + // xret: mepc is an MXLEN-bit read/write register formatted as shown in Figure 3.21. + // The low bit of mepc (mepc[0]) is always zero. On implementations that support + // only IALIGN=32, the two low bits (mepc[1:0]) are always zero. + // Spec 3.1.14 + // Traps: Can’t happen. The bottom two bits of MTVEC are ignored so the trap always is to a multiple of 4. See 3.1.7 of the privileged spec. + assign BranchMisalignedFaultE = (IEUAdrE[1] & ~`C_SUPPORTED) & PCSrcE; + flopenr #(1) InstrMisalginedReg(clk, reset, ~StallM, BranchMisalignedFaultE, InstrMisalignedFaultM); // *** Ross Thompson. Check InstrMisalignedAdrM as I believe it is the same as PCF. Should be able to remove. flopenr #(`XLEN) InstrMisalignedAdrReg(clk, reset, ~StallM, PCNextF, InstrMisalignedAdrM); - assign TrapMisalignedFaultM = misaligned & PrivilegedChangePCM; - assign InstrMisalignedFaultM = BranchMisalignedFaultM; // | TrapMisalignedFaultM; *** put this back in without causing a cyclic path - // *** likely leave TrapMisalignedFaultM out of here. Don't implement full spec because - // *** it seems silly to have a misaligned trap handler and it adds to the critical path. - // ***later revisit more detail // Instruction and PC/PCLink pipeline registers flopenr #(32) InstrEReg(clk, reset, ~StallE, FlushE ? nop : InstrD, InstrE); diff --git a/pipelined/src/ifu/spillsupport.sv b/pipelined/src/ifu/spillsupport.sv new file mode 100644 index 000000000..86c82cd75 --- /dev/null +++ b/pipelined/src/ifu/spillsupport.sv @@ -0,0 +1,100 @@ +/////////////////////////////////////////// +// spillsupport.sv +// +// Written: Ross Thompson ross1728@gmail.com January 28, 2022 +// Modified: +// +// Purpose: allows the IFU to make extra memory request if instruction address crosses +// cache line boundaries or if instruction address without a cache crosses +// XLEN/8 boundary. +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "wally-config.vh" + +module spillsupport ( + input logic clk, + input logic reset, + input logic StallF, + input logic [`XLEN-1:0] PCF, + input logic [`XLEN-3:0] PCPlusUpperF, + input logic [`XLEN-1:0] PCNextF, + logic [31:0] InstrRawF, + input logic IFUCacheBusStallF, + output logic [`XLEN-1:0] PCNextFSpill, + output logic [`XLEN-1:0] PCFSpill, + output logic SelNextSpillF, + output logic [31:0] PostSpillInstrRawF, + output logic CompressedF); + + + localparam integer SPILLTHRESHOLD = `MEM_ICACHE ? `ICACHE_LINELENINBITS/32 : 1; + logic [`XLEN-1:0] PCPlus2F; + logic TakeSpillF; + logic SpillF; + logic SelSpillF, SpillSaveF; + logic [15:0] SpillDataLine0; + + // *** PLACE ALL THIS IN A MODULE + // this exists only if there are compressed instructions. + // reuse PC+2/4 circuitry to avoid needing a second CPA to add 2 + mux2 #(`XLEN) pcplus2mux(.d0({PCF[`XLEN-1:2], 2'b10}), .d1({PCPlusUpperF, 2'b00}), .s(PCF[1]), .y(PCPlus2F)); + mux2 #(`XLEN) pcnextspillmux(.d0(PCNextF), .d1(PCPlus2F), .s(SelNextSpillF), .y(PCNextFSpill)); + mux2 #(`XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCFSpill)); + + assign SpillF = &PCF[$clog2(SPILLTHRESHOLD)+1:1]; + + typedef enum {STATE_SPILL_READY, STATE_SPILL_SPILL} statetype; + (* mark_debug = "true" *) statetype CurrState, NextState; + + always_ff @(posedge clk) + if (reset) CurrState <= #1 STATE_SPILL_READY; + else CurrState <= #1 NextState; + + assign TakeSpillF = SpillF & ~IFUCacheBusStallF; + + always_comb begin + case (CurrState) + STATE_SPILL_READY: if (TakeSpillF) NextState = STATE_SPILL_SPILL; + else NextState = STATE_SPILL_READY; + STATE_SPILL_SPILL: if(IFUCacheBusStallF | StallF) NextState = STATE_SPILL_SPILL; + else NextState = STATE_SPILL_READY; + default: NextState = STATE_SPILL_READY; + endcase + end + + assign SelSpillF = (CurrState == STATE_SPILL_SPILL); + assign SelNextSpillF = (CurrState == STATE_SPILL_READY & TakeSpillF) | + (CurrState == STATE_SPILL_SPILL & IFUCacheBusStallF); + assign SpillSaveF = (CurrState == STATE_SPILL_READY) & TakeSpillF; + + flopenr #(16) SpillInstrReg(.clk(clk), + .en(SpillSaveF), + .reset(reset), + .d(`MEM_ICACHE ? InstrRawF[15:0] : InstrRawF[31:16]), + .q(SpillDataLine0)); + + assign PostSpillInstrRawF = SpillF ? {InstrRawF[15:0], SpillDataLine0} : InstrRawF; + assign CompressedF = PostSpillInstrRawF[1:0] != 2'b11; + +endmodule diff --git a/pipelined/src/lsu/atomic.sv b/pipelined/src/lsu/atomic.sv new file mode 100644 index 000000000..77db25e1c --- /dev/null +++ b/pipelined/src/lsu/atomic.sv @@ -0,0 +1,59 @@ +/////////////////////////////////////////// +// atomic.sv +// +// Written: Ross Thompson ross1728@gmail.com January 31, 2022 +// Modified: +// +// Purpose: atomic data path. +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "wally-config.vh" + +module atomic ( + input logic clk, + input logic reset, FlushW, CPUBusy, + input logic [`XLEN-1:0] ReadDataM, + input logic [`XLEN-1:0] WriteDataM, + input logic [`PA_BITS-1:0] LSUPAdrM, + input logic [6:0] LSUFunct7M, + input logic [2:0] LSUFunct3M, + input logic [1:0] LSUAtomicM, + input logic [1:0] PreLSURWM, + input logic IgnoreRequest, + input logic DTLBMissM, + output logic [`XLEN-1:0] FinalAMOWriteDataM, + output logic SquashSCW, + output logic [1:0] LSURWM); + + logic [`XLEN-1:0] AMOResult; + logic MemReadM; + + amoalu amoalu(.srca(ReadDataM), .srcb(WriteDataM), .funct(LSUFunct7M), .width(LSUFunct3M[1:0]), + .result(AMOResult)); + mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, LSUAtomicM[1], FinalAMOWriteDataM); + assign MemReadM = PreLSURWM[1] & ~(IgnoreRequest) & ~DTLBMissM; + lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .PreLSURWM, .LSUAtomicM, .LSUPAdrM, + .SquashSCW, .LSURWM); + +endmodule diff --git a/pipelined/src/lsu/busdp.sv b/pipelined/src/lsu/busdp.sv new file mode 100644 index 000000000..dbed6f445 --- /dev/null +++ b/pipelined/src/lsu/busdp.sv @@ -0,0 +1,101 @@ +/////////////////////////////////////////// +// busdp.sv +// +// Written: Ross Thompson ross1728@gmail.com January 30, 2022 +// Modified: +// +// Purpose: Bus data path. +// Bus Side logic +// register the fetch data from the next level of memory. +// This register should be necessary for timing. There is no register in the uncore or +// ahblite controller between the memories and this cache. +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "wally-config.vh" + +module busdp #(parameter WORDSPERLINE, parameter LINELEN) + ( + input logic clk, reset, + // bus interface + input logic [`XLEN-1:0] LSUBusHRDATA, + input logic LSUBusAck, + output logic LSUBusWrite, + output logic LSUBusRead, + output logic [`XLEN-1:0] LSUBusHWDATA, + output logic [2:0] LSUBusSize, + input logic [2:0] LSUFunct3M, + output logic [`PA_BITS-1:0] LSUBusAdr, + + // cache interface. + input logic [`PA_BITS-1:0] DCacheBusAdr, + input var logic [`XLEN-1:0] ReadDataLineSetsM [WORDSPERLINE-1:0], + input logic DCacheFetchLine, + input logic DCacheWriteLine, + output logic DCacheBusAck, + output logic [LINELEN-1:0] DCacheMemWriteData, + + // lsu interface + input logic [`PA_BITS-1:0] LSUPAdrM, + input logic [`XLEN-1:0] FinalAMOWriteDataM, + input logic [`XLEN-1:0] ReadDataWordM, + output logic [`XLEN-1:0] ReadDataWordMuxM, + input logic IgnoreRequest, + input logic [1:0] LSURWM, + input logic CPUBusy, + input logic CacheableM, + output logic BusStall, + output logic BusCommittedM); + + + localparam integer WordCountThreshold = `MEM_DCACHE ? WORDSPERLINE - 1 : 0; + localparam integer LOGWPL = `MEM_DCACHE ? $clog2(WORDSPERLINE) : 1; + + logic SelUncachedAdr; + logic [`XLEN-1:0] PreLSUBusHWDATA; + logic [`PA_BITS-1:0] LocalLSUBusAdr; + logic [LOGWPL-1:0] WordCount; + genvar index; + + for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer + flopen #(`XLEN) fb(.clk, .en(LSUBusAck & LSUBusRead & (index == WordCount)), + .d(LSUBusHRDATA), .q(DCacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN])); + end + + + mux2 #(`PA_BITS) localadrmux(DCacheBusAdr, LSUPAdrM, SelUncachedAdr, LocalLSUBusAdr); + assign LSUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLSUBusAdr; + assign PreLSUBusHWDATA = ReadDataLineSetsM[WordCount]; // only in lsu, not ifu + mux2 #(`XLEN) lsubushwdatamux(.d0(PreLSUBusHWDATA), .d1(FinalAMOWriteDataM), + .s(SelUncachedAdr), .y(LSUBusHWDATA)); + mux2 #(3) lsubussizemux(.d0(`XLEN == 32 ? 3'b010 : 3'b011), .d1(LSUFunct3M), + .s(SelUncachedAdr), .y(LSUBusSize)); + mux2 #(`XLEN) UnCachedDataMux(.d0(ReadDataWordM), .d1(DCacheMemWriteData[`XLEN-1:0]), + .s(SelUncachedAdr), .y(ReadDataWordMuxM)); + + busfsm #(WordCountThreshold, LOGWPL, `MEM_DCACHE) + busfsm(.clk, .reset, .IgnoreRequest, .LSURWM, .DCacheFetchLine, .DCacheWriteLine, + .LSUBusAck, .CPUBusy, .CacheableM, .BusStall, .LSUBusWrite, .LSUBusRead, + .DCacheBusAck, .BusCommittedM, .SelUncachedAdr, .WordCount); + +endmodule diff --git a/pipelined/src/lsu/busfsm.sv b/pipelined/src/lsu/busfsm.sv index ae85fa870..9eb6b386a 100644 --- a/pipelined/src/lsu/busfsm.sv +++ b/pipelined/src/lsu/busfsm.sv @@ -33,23 +33,23 @@ module busfsm #(parameter integer WordCountThreshold, parameter integer LOGWPL, parameter logic CacheEnabled ) - (input logic clk, - input logic reset, + (input logic clk, + input logic reset, - input logic IgnoreRequest, - input logic [1:0] LSURWM, - input logic DCacheFetchLine, - input logic DCacheWriteLine, - input logic LSUBusAck, - input logic CPUBusy, - input logic CacheableM, + input logic IgnoreRequest, + input logic [1:0] LSURWM, + input logic DCacheFetchLine, + input logic DCacheWriteLine, + input logic LSUBusAck, + input logic CPUBusy, + input logic CacheableM, - output logic BusStall, - output logic LSUBusWrite, - output logic LSUBusRead, - output logic DCacheBusAck, - output logic BusCommittedM, - output logic SelUncachedAdr, + output logic BusStall, + output logic LSUBusWrite, + output logic LSUBusRead, + output logic DCacheBusAck, + output logic BusCommittedM, + output logic SelUncachedAdr, output logic [LOGWPL-1:0] WordCount); diff --git a/pipelined/src/lsu/dtim.sv b/pipelined/src/lsu/dtim.sv new file mode 100644 index 000000000..7ebb0e8c6 --- /dev/null +++ b/pipelined/src/lsu/dtim.sv @@ -0,0 +1,65 @@ +/////////////////////////////////////////// +// dtim.sv +// +// Written: Ross Thompson ross1728@gmail.com January 30, 2022 +// Modified: +// +// Purpose: simple memory with bus or cache. +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "wally-config.vh" + +module dtim( + input logic clk, reset, + input logic CPUBusy, + input logic [1:0] LSURWM, + input logic [`XLEN-1:0] IEUAdrM, + input logic [`XLEN-1:0] IEUAdrE, + input logic TrapM, + input logic [`XLEN-1:0] FinalWriteDataM, + output logic [`XLEN-1:0] ReadDataWordM, + output logic BusStall, + output logic LSUBusWrite, + output logic LSUBusRead, + output logic BusCommittedM, + output logic [`XLEN-1:0] ReadDataWordMuxM, + output logic DCacheStallM, + output logic DCacheCommittedM, + output logic DCacheMiss, + output logic DCacheAccess); + + simpleram #(.BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram ( + .clk, + .a(CPUBusy | LSURWM[0] | reset ? IEUAdrM[31:0] : IEUAdrE[31:0]), + .we(LSURWM[0] & ~TrapM), // have to ignore write if Trap. + .wd(FinalWriteDataM), .rd(ReadDataWordM)); + + // since we have a local memory the bus connections are all disabled. + // There are no peripherals supported. + assign {BusStall, LSUBusWrite, LSUBusRead, BusCommittedM} = '0; + assign ReadDataWordMuxM = ReadDataWordM; + assign {DCacheStallM, DCacheCommittedM} = '0; + assign {DCacheMiss, DCacheAccess} = '0; + +endmodule + diff --git a/pipelined/src/lsu/lsu.sv b/pipelined/src/lsu/lsu.sv index c2c8c1e65..25397be28 100644 --- a/pipelined/src/lsu/lsu.sv +++ b/pipelined/src/lsu/lsu.sv @@ -33,129 +33,99 @@ `include "wally-config.vh" module lsu ( - input logic clk, reset, - input logic StallM, FlushM, StallW, FlushW, - output logic LSUStallM, + input logic clk, reset, + input logic StallM, FlushM, StallW, FlushW, + output logic LSUStallM, // connected to cpu (controls) - input logic [1:0] MemRWM, - input logic [2:0] Funct3M, - input logic [6:0] Funct7M, - input logic [1:0] AtomicM, - input logic TrapM, - input logic FlushDCacheM, - output logic CommittedM, - output logic SquashSCW, - output logic DCacheMiss, - output logic DCacheAccess, + input logic [1:0] MemRWM, + input logic [2:0] Funct3M, + input logic [6:0] Funct7M, + input logic [1:0] AtomicM, + input logic TrapM, + input logic FlushDCacheM, + output logic CommittedM, + output logic SquashSCW, + output logic DCacheMiss, + output logic DCacheAccess, // address and write data - input logic [`XLEN-1:0] IEUAdrE, - (* mark_debug = "true" *)output logic [`XLEN-1:0] IEUAdrM, - input logic [`XLEN-1:0] WriteDataM, - output logic [`XLEN-1:0] ReadDataM, + input logic [`XLEN-1:0] IEUAdrE, + (* mark_debug = "true" *)output logic [`XLEN-1:0] IEUAdrM, + input logic [`XLEN-1:0] WriteDataM, + output logic [`XLEN-1:0] ReadDataM, // cpu privilege - input logic [1:0] PrivilegeModeW, - input logic DTLBFlushM, + input logic [1:0] PrivilegeModeW, + input logic DTLBFlushM, // faults - output logic LoadPageFaultM, StoreAmoPageFaultM, - output logic LoadMisalignedFaultM, LoadAccessFaultM, + output logic LoadPageFaultM, StoreAmoPageFaultM, + output logic LoadMisalignedFaultM, LoadAccessFaultM, // cpu hazard unit (trap) - output logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM, - // connect to ahb -(* mark_debug = "true" *) output logic [`PA_BITS-1:0] LSUBusAdr, -(* mark_debug = "true" *) output logic LSUBusRead, -(* mark_debug = "true" *) output logic LSUBusWrite, -(* mark_debug = "true" *) input logic LSUBusAck, -(* mark_debug = "true" *) input logic [`XLEN-1:0] LSUBusHRDATA, -(* mark_debug = "true" *) output logic [`XLEN-1:0] LSUBusHWDATA, -(* mark_debug = "true" *) output logic [2:0] LSUBusSize, - // page table walker - input logic [`XLEN-1:0] SATP_REGW, // from csr - input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, - input logic [1:0] STATUS_MPP, - input logic [`XLEN-1:0] PCF, - input logic ITLBMissF, - output logic [`XLEN-1:0] PTE, - output logic [1:0] PageType, - output logic ITLBWriteF, - input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], - input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0] // *** this one especially has a large note attached to it in pmpchecker. + output logic StoreAmoMisalignedFaultM, StoreAmoAccessFaultM, + // connect to ahb + (* mark_debug = "true" *) output logic [`PA_BITS-1:0] LSUBusAdr, + (* mark_debug = "true" *) output logic LSUBusRead, + (* mark_debug = "true" *) output logic LSUBusWrite, + (* mark_debug = "true" *) input logic LSUBusAck, + (* mark_debug = "true" *) input logic [`XLEN-1:0] LSUBusHRDATA, + (* mark_debug = "true" *) output logic [`XLEN-1:0] LSUBusHWDATA, + (* mark_debug = "true" *) output logic [2:0] LSUBusSize, + // page table walker + input logic [`XLEN-1:0] SATP_REGW, // from csr + input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, + input logic [1:0] STATUS_MPP, + input logic [`XLEN-1:0] PCF, + input logic ITLBMissF, + output logic [`XLEN-1:0] PTE, + output logic [1:0] PageType, + output logic ITLBWriteF, + input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], + input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0] // *** this one especially has a large note attached to it in pmpchecker. ); - logic [`PA_BITS-1:0] LSUPAdrM; // from mmu to dcache - logic [`XLEN+1:0] IEUAdrExtM; - logic DTLBMissM; - logic DTLBWriteM; - logic [1:0] LSURWM; - logic [1:0] PreLSURWM; - logic [2:0] LSUFunct3M; - logic [6:0] LSUFunct7M; - logic [1:0] LSUAtomicM; -(* mark_debug = "true" *) logic [`PA_BITS-1:0] PreLSUPAdrM, LocalLSUBusAdr; - logic [11:0] PreLSUAdrE, LSUAdrE; - logic CPUBusy; - logic MemReadM; - logic DCacheStallM; - logic CacheableM; - logic SelHPTW; - logic BusStall; - logic InterlockStall; - logic IgnoreRequest; - logic BusCommittedM, DCacheCommittedM; - - //////////////////////////////////////////////////////////////////////////////////////////////// - // HPTW and Interlock FSM (only needed if VM supported) - // MMU include PMP and is needed if any privileged supported - //////////////////////////////////////////////////////////////////////////////////////////////// + logic [`XLEN+1:0] IEUAdrExtM; + logic [`PA_BITS-1:0] LSUPAdrM; + logic DTLBMissM; + logic DTLBWriteM; + logic [1:0] LSURWM; + logic [1:0] PreLSURWM; + logic [2:0] LSUFunct3M; + logic [6:0] LSUFunct7M; + logic [1:0] LSUAtomicM; + (* mark_debug = "true" *) logic [`PA_BITS-1:0] PreLSUPAdrM; + logic [11:0] PreLSUAdrE, LSUAdrE; + logic CPUBusy; + logic DCacheStallM; + logic CacheableM; + logic SelHPTW; + logic BusStall; + logic InterlockStall; + logic IgnoreRequest; + logic BusCommittedM, DCacheCommittedM; flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM); assign IEUAdrExtM = {2'b00, IEUAdrM}; - + assign LSUStallM = DCacheStallM | InterlockStall | BusStall; + + ///////////////////////////////////////////////////////////////////////////////////////////// + // HPTW and Interlock FSM (only needed if VM supported) + // MMU include PMP and is needed if any privileged supported + ///////////////////////////////////////////////////////////////////////////////////////////// + if(`MEM_VIRTMEM) begin : MEM_VIRTMEM - // *** encapsulate as lsuvirtmem - logic AnyCPUReqM; - logic [`PA_BITS-1:0] HPTWAdr; - logic HPTWRead; - logic [2:0] HPTWSize; - logic SelReplayCPURequest; + lsuvirtmem lsuvirtmem(.clk, .reset, .StallW, .MemRWM, .AtomicM, .ITLBMissF, .ITLBWriteF, + .DTLBMissM, .DTLBWriteM, .TrapM, .DCacheStallM, .SATP_REGW, .PCF, + .ReadDataM, .Funct3M, .LSUFunct3M, .Funct7M, .LSUFunct7M, .IEUAdrM, + .IEUAdrExtM, .PTE, .PageType, .PreLSURWM, .LSUAtomicM, .IEUAdrE, + .LSUAdrE, .PreLSUPAdrM, .CPUBusy, .InterlockStall, .SelHPTW, + .IgnoreRequest); - assign AnyCPUReqM = (|MemRWM) | (|AtomicM); - - interlockfsm interlockfsm (.clk, .reset, .AnyCPUReqM, .ITLBMissF, .ITLBWriteF, - .DTLBMissM, .DTLBWriteM, .TrapM, .DCacheStallM, - .InterlockStall, .SelReplayCPURequest, .SelHPTW, - .IgnoreRequest); - - hptw hptw(.clk, .reset, .SATP_REGW, .PCF, .IEUAdrM, - .ITLBMissF(ITLBMissF & ~TrapM), - .DTLBMissM(DTLBMissM & ~TrapM), - .PTE, .PageType, .ITLBWriteF, .DTLBWriteM, - .HPTWReadPTE(ReadDataM), - .DCacheStallM, .HPTWAdr, .HPTWRead, .HPTWSize); - - // arbiter between IEU and hptw - - // multiplex the outputs to LSU - mux2 #(2) rwmux(MemRWM, {HPTWRead, 1'b0}, SelHPTW, PreLSURWM); - mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LSUFunct3M); - mux2 #(7) funct7mux(Funct7M, 7'b0, SelHPTW, LSUFunct7M); - mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LSUAtomicM); - mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLSUAdrE); - mux2 #(12) replaymux(PreLSUAdrE, IEUAdrM[11:0], SelReplayCPURequest, LSUAdrE); // replay cpu request after hptw. - mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, PreLSUPAdrM); - - // always block interrupts when using the hardware page table walker. - assign CPUBusy = StallW & ~SelHPTW; - - end // if (`MEM_VIRTMEM) - else begin + end else begin assign {InterlockStall, SelHPTW, PTE, PageType, DTLBWriteM, ITLBWriteF} = '0; - assign IgnoreRequest = TrapM; - assign CPUBusy = StallW; - assign LSUAdrE = PreLSUAdrE; assign LSUFunct3M = Funct3M; assign LSUFunct7M = Funct7M; assign LSUAtomicM = AtomicM; - assign PreLSURWM = MemRWM; assign PreLSUAdrE = IEUAdrE[11:0]; assign PreLSUPAdrM = IEUAdrExtM; + assign IgnoreRequest = TrapM; assign CPUBusy = StallW; assign PreLSURWM = MemRWM; + assign LSUAdrE = PreLSUAdrE; assign PreLSUAdrE = IEUAdrE[11:0]; + assign PreLSUPAdrM = IEUAdrExtM[`PA_BITS-1:0]; + assign LSUFunct3M = Funct3M; assign LSUFunct7M = Funct7M; assign LSUAtomicM = AtomicM; end - // **** look into this confusing signal. // This signal is confusing. CommittedM tells the CPU's trap unit the current instruction // in the memory stage is a memory operaton and that memory operation is either completed @@ -181,168 +151,91 @@ module lsu ( .TLBFlush(DTLBFlushM), .PhysicalAddress(LSUPAdrM), .TLBMiss(DTLBMissM), - .Cacheable(CacheableM), - .Idempotent(), .AtomicAllowed(), + .Cacheable(CacheableM), .Idempotent(), .AtomicAllowed(), .InstrAccessFaultF(), .LoadAccessFaultM, .StoreAmoAccessFaultM, .InstrPageFaultF(),.LoadPageFaultM, .StoreAmoPageFaultM, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, .AtomicAccessM(|LSUAtomicM), .ExecuteAccessF(1'b0), // **** change this to just use PreLSURWM .WriteAccessM(PreLSURWM[0]), .ReadAccessM(PreLSURWM[1]), - .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW - ); - - // *** lsumisaligned lsumisaligned(Funct3M, IEUAdrM, MemRW, LoadMisalignedFaultM, StoreAmoMisalignedFaultM); - // *** lump into lsumislaigned module - // Determine if an Unaligned access is taking place - // hptw guarantees alignment, only check inputs from IEU. - - // *** modify MMU to put out LoadMisalignedFault and StoreMisalignedFault rather than DataMisalignedM - + .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW); end else begin assign {DTLBMissM, LoadAccessFaultM, StoreAmoAccessFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM} = '0; - assign LSUPAdrM = PreLSUPAdrM; - assign CacheableM = 1; assign {LoadPageFaultM, StoreAmoPageFaultM} = '0; + assign LSUPAdrM = PreLSUPAdrM; + assign CacheableM = '1; end - assign LSUStallM = DCacheStallM | InterlockStall | BusStall; - //////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////// // Hart Memory System // Either Data Cache or Data Tightly Integrated Memory or just bus interface - //////////////////////////////////////////////////////////////////////////////////////////////// - - localparam integer WORDSPERLINE = `MEM_DCACHE ? `DCACHE_LINELENINBITS/`XLEN : 1; - localparam integer LOGWPL = `MEM_DCACHE ? $clog2(WORDSPERLINE) : 1; - localparam integer LINELEN = `MEM_DCACHE ? `DCACHE_LINELENINBITS : `XLEN; - localparam integer WordCountThreshold = `MEM_DCACHE ? WORDSPERLINE - 1 : 0; - - localparam integer LINEBYTELEN = LINELEN/8; - localparam integer OFFSETLEN = $clog2(LINEBYTELEN); - + ///////////////////////////////////////////////////////////////////////////////////////////// logic [`XLEN-1:0] FinalAMOWriteDataM, FinalWriteDataM; - (* mark_debug = "true" *) logic [`XLEN-1:0] PreLSUBusHWDATA; logic [`XLEN-1:0] ReadDataWordM; - logic [LINELEN-1:0] DCacheMemWriteData; logic [`XLEN-1:0] ReadDataWordMuxM; - logic [`PA_BITS-1:0] DCacheBusAdr; - logic [`XLEN-1:0] ReadDataLineSetsM [WORDSPERLINE-1:0]; - logic DCacheWriteLine; - logic DCacheFetchLine; - logic DCacheBusAck; - logic SelUncachedAdr; if (`MEM_DTIM) begin : dtim -/* Consider restructuring with higher level blocks. Try drawing block diagrams with several pages of schematics, - one for top level, one for each sublevel, alternate with either dtim or bus. If this looks more satisfactory, - restructure code accordingly. + dtim dtim(.clk, .reset, .CPUBusy, .LSURWM, .IEUAdrM, .IEUAdrE, .TrapM, .FinalWriteDataM, + .ReadDataWordM, .BusStall, .LSUBusWrite,.LSUBusRead, .BusCommittedM, + .ReadDataWordMuxM, .DCacheStallM, .DCacheCommittedM, + .DCacheMiss, .DCacheAccess); - dtim dtim (.clk, .CPUBusy, .LSURWM, .IEUAdrM, .IEUAdrE, .TrapM, .FinalWriteDataM, .ReadDataWordM, - .BusStallM, .LSUBusWrite, .LSUBusRead, .DCacheBusAck, .BusCommittedM, .SelUncachedAdr, - .ReadDataWordMuxM, .DCacheStallM, .DCacheCommittedM, .DCacheWriteLine, .DCacheFetchLine, .DCacheBusAdr, - .ReadDataLineSetsM, .DCacheMiss, .DCacheAccess); */ - - // *** adjust interface so write address doesn't need delaying; switch to standard RAM? - simpleram #(.BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram ( - .clk, - .a(CPUBusy | LSURWM[0] ? IEUAdrM[31:0] : IEUAdrE[31:0]), - .we(LSURWM[0] & ~TrapM), // have to ignore write if Trap. - .wd(FinalWriteDataM), .rd(ReadDataWordM)); - - // since we have a local memory the bus connections are all disabled. - // There are no peripherals supported. - assign {BusStall, LSUBusWrite, LSUBusRead, DCacheBusAck, BusCommittedM, SelUncachedAdr} = '0; - assign ReadDataWordMuxM = ReadDataWordM; - assign {DCacheStallM, DCacheCommittedM, DCacheWriteLine, DCacheFetchLine, DCacheBusAdr} = '0; - assign ReadDataLineSetsM[0] = 0; - assign DCacheMiss = 1'b0; assign DCacheAccess = 1'b0; end else begin : bus - // replace from here up to if (`MEM_DCACHE) with busdp *** - // Bus Side logic - // register the fetch data from the next level of memory. - // This register should be necessary for timing. There is no register in the uncore or - // ahblite controller between the memories and this cache. - logic [LOGWPL-1:0] WordCount; - - genvar index; - for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer - flopen #(`XLEN) fb(.clk, .en(LSUBusAck & LSUBusRead & (index == WordCount)), - .d(LSUBusHRDATA), .q(DCacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN])); - end - - assign LocalLSUBusAdr = SelUncachedAdr ? LSUPAdrM : DCacheBusAdr ; - assign LSUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLSUBusAdr; - assign PreLSUBusHWDATA = ReadDataLineSetsM[WordCount]; - // exclude the subword write for uncached. We don't read the data first so we cannot - // select the subword by masking. Subword write also exists inside the uncore to - // suport subword masking for i/o. I'm not sure if this is necessary. - assign LSUBusHWDATA = SelUncachedAdr ? FinalAMOWriteDataM : PreLSUBusHWDATA; - - assign LSUBusSize = SelUncachedAdr ? LSUFunct3M : (`XLEN == 32 ? 3'b010 : 3'b011); - - // select between dcache and direct from the BUS. Always selected if no dcache. - mux2 #(`XLEN) UnCachedDataMux(.d0(ReadDataWordM), - .d1(DCacheMemWriteData[`XLEN-1:0]), - .s(SelUncachedAdr), - .y(ReadDataWordMuxM)); - - busfsm #(WordCountThreshold, LOGWPL, `MEM_DCACHE) - busfsm(.clk, .reset, .IgnoreRequest, .LSURWM, .DCacheFetchLine, .DCacheWriteLine, - .LSUBusAck, .CPUBusy, .CacheableM, .BusStall, .LSUBusWrite, .LSUBusRead, - .DCacheBusAck, .BusCommittedM, .SelUncachedAdr, .WordCount); + localparam integer WORDSPERLINE = `MEM_DCACHE ? `DCACHE_LINELENINBITS/`XLEN : 1; + localparam integer LINELEN = `MEM_DCACHE ? `DCACHE_LINELENINBITS : `XLEN; + logic [`XLEN-1:0] ReadDataLineSetsM [WORDSPERLINE-1:0]; + logic [LINELEN-1:0] DCacheMemWriteData; + logic [`PA_BITS-1:0] DCacheBusAdr; + logic DCacheWriteLine; + logic DCacheFetchLine; + logic DCacheBusAck; + busdp #(WORDSPERLINE, LINELEN) + busdp(.clk, .reset, + .LSUBusHRDATA, .LSUBusAck, .LSUBusWrite, .LSUBusRead, .LSUBusHWDATA, .LSUBusSize, + .LSUFunct3M, .LSUBusAdr, .DCacheBusAdr, .ReadDataLineSetsM, .DCacheFetchLine, + .DCacheWriteLine, .DCacheBusAck, .DCacheMemWriteData, .LSUPAdrM, .FinalAMOWriteDataM, + .ReadDataWordM, .ReadDataWordMuxM, .IgnoreRequest, .LSURWM, .CPUBusy, .CacheableM, + .BusStall, .BusCommittedM); + if(`MEM_DCACHE) begin : dcache cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN), - .NUMWAYS(`DCACHE_NUMWAYS), .DCACHE(1)) + .NUMWAYS(`DCACHE_NUMWAYS), .DCACHE(1)) dcache(.clk, .reset, .CPUBusy, - .RW(CacheableM ? LSURWM : 2'b00), .FlushCache(FlushDCacheM), .Atomic(CacheableM ? LSUAtomicM : 2'b00), - .NextAdr(LSUAdrE), .PAdr(LSUPAdrM), - .FinalWriteData(FinalWriteDataM), .ReadDataWord(ReadDataWordM), .CacheStall(DCacheStallM), - .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess), - .IgnoreRequest, .CacheCommitted(DCacheCommittedM), - .CacheBusAdr(DCacheBusAdr), .ReadDataLineSets(ReadDataLineSetsM), .CacheMemWriteData(DCacheMemWriteData), - .CacheFetchLine(DCacheFetchLine), .CacheWriteLine(DCacheWriteLine), .CacheBusAck(DCacheBusAck), .InvalidateCacheM(1'b0)); + .RW(CacheableM ? LSURWM : 2'b00), .FlushCache(FlushDCacheM), + .Atomic(CacheableM ? LSUAtomicM : 2'b00), .NextAdr(LSUAdrE), .PAdr(LSUPAdrM), + .FinalWriteData(FinalWriteDataM), .ReadDataWord(ReadDataWordM), + .CacheStall(DCacheStallM), .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess), + .IgnoreRequest, .CacheCommitted(DCacheCommittedM), .CacheBusAdr(DCacheBusAdr), + .ReadDataLineSets(ReadDataLineSetsM), .CacheMemWriteData(DCacheMemWriteData), + .CacheFetchLine(DCacheFetchLine), .CacheWriteLine(DCacheWriteLine), + .CacheBusAck(DCacheBusAck), .InvalidateCacheM(1'b0)); end else begin : passthrough - assign {ReadDataWordM, DCacheStallM, DCacheCommittedM, DCacheWriteLine, DCacheFetchLine, DCacheBusAdr} = '0; - assign ReadDataLineSetsM[0] = 0; + assign {ReadDataWordM, DCacheStallM, DCacheCommittedM, DCacheFetchLine, DCacheWriteLine} = '0; assign DCacheMiss = CacheableM; assign DCacheAccess = CacheableM; end end - // sub word selection for read and writes and optional amo alu. - subwordread subwordread(.ReadDataWordMuxM, - .LSUPAdrM(LSUPAdrM[2:0]), - .Funct3M(LSUFunct3M), - .ReadDataM); + subwordread subwordread(.ReadDataWordMuxM, .LSUPAdrM(LSUPAdrM[2:0]), + .Funct3M(LSUFunct3M), .ReadDataM); // this might only get instantiated if there is a dcache or dtim. // There is a copy in the ebu. *** is it needed there, or can data come in from ebu, get muxed here and sent back out // Explore changing feedback path from output of AMOALU to subword write *** - subwordwrite subwordwrite(.HRDATA(ReadDataWordM), - .HADDRD(LSUPAdrM[2:0]), + subwordwrite subwordwrite(.HRDATA(ReadDataWordM), .HADDRD(LSUPAdrM[2:0]), .HSIZED({LSUFunct3M[2], 1'b0, LSUFunct3M[1:0]}), - .HWDATAIN(FinalAMOWriteDataM), - .HWDATA(FinalWriteDataM)); + .HWDATAIN(FinalAMOWriteDataM), .HWDATA(FinalWriteDataM)); - //////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////// // Atomic operations - //////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////////////////////// - if (`A_SUPPORTED) begin:lrsc - /*atomic atomic(.clk, .reset, .FlushW, .CPUBusy, .MemRead, .PreLSURWM, .LSUAtomicM, .LSUPAdrM, - .SquashSCM, .LSURWM, ... ); *** */ - logic [`XLEN-1:0] AMOResult; - amoalu amoalu(.srca(ReadDataM), .srcb(WriteDataM), .funct(LSUFunct7M), .width(LSUFunct3M[1:0]), - .result(AMOResult)); - mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, LSUAtomicM[1], FinalAMOWriteDataM); - assign MemReadM = PreLSURWM[1] & ~(IgnoreRequest) & ~DTLBMissM; - lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .PreLSURWM, .LSUAtomicM, .LSUPAdrM, - .SquashSCW, .LSURWM); + if (`A_SUPPORTED) begin:atomic + atomic atomic(.clk, .reset, .FlushW, .CPUBusy, .ReadDataM, .WriteDataM, .LSUPAdrM, + .LSUFunct7M, .LSUFunct3M, .LSUAtomicM, .PreLSURWM, .IgnoreRequest, + .DTLBMissM, .FinalAMOWriteDataM, .SquashSCW, .LSURWM); end else begin:lrsc - assign SquashSCW = 0; - assign LSURWM = PreLSURWM; - assign FinalAMOWriteDataM = WriteDataM; + assign SquashSCW = 0; assign LSURWM = PreLSURWM; assign FinalAMOWriteDataM = WriteDataM; end endmodule - diff --git a/pipelined/src/lsu/lsuvirtmen.sv b/pipelined/src/lsu/lsuvirtmen.sv new file mode 100644 index 000000000..60e76f7fe --- /dev/null +++ b/pipelined/src/lsu/lsuvirtmen.sv @@ -0,0 +1,102 @@ +/////////////////////////////////////////// +// lsuvirtmem.sv +// +// Written: Ross Thompson ross1728@gmail.com January 30, 2022 +// Modified: +// +// Purpose: Encapsulates the hptw and muxes required to support virtual memory. +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "wally-config.vh" + +module lsuvirtmem( + input logic clk, reset, StallW, + input logic [1:0] MemRWM, + input logic [1:0] AtomicM, + input logic ITLBMissF, + output logic ITLBWriteF, + input logic DTLBMissM, + output logic DTLBWriteM, + input logic TrapM, + input logic DCacheStallM, + input logic [`XLEN-1:0] SATP_REGW, // from csr + input logic [`XLEN-1:0] PCF, + input logic [`XLEN-1:0] ReadDataM, + input logic [2:0] Funct3M, + output logic [2:0] LSUFunct3M, + input logic [6:0] Funct7M, + output logic [6:0] LSUFunct7M, + input logic [`XLEN-1:0] IEUAdrE, + input logic [`XLEN-1:0] IEUAdrM, + output logic [`XLEN-1:0] PTE, + output logic [1:0] PageType, + output logic [1:0] PreLSURWM, + output logic [1:0] LSUAtomicM, + output logic [11:0] LSUAdrE, + output logic [`PA_BITS-1:0] PreLSUPAdrM, + input logic [`XLEN+1:0] IEUAdrExtM, + + output logic InterlockStall, + output logic CPUBusy, + output logic SelHPTW, + output logic IgnoreRequest); + + + logic AnyCPUReqM; + logic [`PA_BITS-1:0] HPTWAdr; + logic HPTWRead; + logic [2:0] HPTWSize; + logic SelReplayCPURequest; + logic [11:0] PreLSUAdrE; + + + + assign AnyCPUReqM = (|MemRWM) | (|AtomicM); + + interlockfsm interlockfsm (.clk, .reset, .AnyCPUReqM, .ITLBMissF, .ITLBWriteF, + .DTLBMissM, .DTLBWriteM, .TrapM, .DCacheStallM, + .InterlockStall, .SelReplayCPURequest, .SelHPTW, + .IgnoreRequest); + + hptw hptw(.clk, .reset, .SATP_REGW, .PCF, .IEUAdrM, + .ITLBMissF(ITLBMissF & ~TrapM), + .DTLBMissM(DTLBMissM & ~TrapM), + .PTE, .PageType, .ITLBWriteF, .DTLBWriteM, + .HPTWReadPTE(ReadDataM), + .DCacheStallM, .HPTWAdr, .HPTWRead, .HPTWSize); + + // arbiter between IEU and hptw + + // multiplex the outputs to LSU + mux2 #(2) rwmux(MemRWM, {HPTWRead, 1'b0}, SelHPTW, PreLSURWM); + mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LSUFunct3M); + mux2 #(7) funct7mux(Funct7M, 7'b0, SelHPTW, LSUFunct7M); + mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LSUAtomicM); + mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLSUAdrE); + mux2 #(12) replaymux(PreLSUAdrE, IEUAdrM[11:0], SelReplayCPURequest, LSUAdrE); // replay cpu request after hptw. + mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, PreLSUPAdrM); + + // always block interrupts when using the hardware page table walker. + assign CPUBusy = StallW & ~SelHPTW; + +endmodule; // lsuvirtmem diff --git a/pipelined/src/privileged/csrc.sv b/pipelined/src/privileged/csrc.sv index 7fde50036..c48e3d2e7 100644 --- a/pipelined/src/privileged/csrc.sv +++ b/pipelined/src/privileged/csrc.sv @@ -86,7 +86,7 @@ module csrc #(parameter // Determine when to increment each counter assign CounterEvent[0] = 1'b1; // MCYCLE always increments - assign CounterEvent[1] = 1'b0; // Counter 0 doesn't exist + assign CounterEvent[1] = 1'b0; // Counter 1 doesn't exist assign CounterEvent[2] = InstrValidNotFlushedM; if(`QEMU) begin: cevent // No other performance counters in QEMU assign CounterEvent[`COUNTERS-1:3] = 0; diff --git a/pipelined/src/privileged/trap.sv b/pipelined/src/privileged/trap.sv index d38769155..be38baafa 100644 --- a/pipelined/src/privileged/trap.sv +++ b/pipelined/src/privileged/trap.sv @@ -72,25 +72,16 @@ module trap ( assign PendingIntsM = ((MIP_REGW & MIE_REGW) & ({12{MIntGlobalEnM}} & 12'h888)) | ((SIP_REGW & SIE_REGW) & ({12{SIntGlobalEnM}} & 12'h222)); assign PendingInterruptM = (|PendingIntsM) & InstrValidM; assign InterruptM = PendingInterruptM & ~(CommittedM); // *** RT. temporary hack to prevent integer division from having an interrupt during divide. - // ideally this should be disabled for all but the first cycle. However I'm not familar with the internals of the integer divider. This should (could) be an issue for - // floating point and integer multiply. - //assign ExceptionM = TrapM; - assign ExceptionM = Exception1M; - // *** as of 7/17/21, the system passes with this definition of ExceptionM as being all traps and fails if ExceptionM = Exception1M - // with no interrupts. However, Ross intended the datacache to use Exception without interrupts, so there is something subtle - // to sort out here. - // *** as of 8/13/21, switching to Exception1M does not seem to cause any failures. It's possible the bug was - // fixed inadvertantly as the dcache was debugged. - + // Trigger Traps and RET // According to RISC-V Spec Section 1.6, exceptions are caused by instructions. Interrupts are external asynchronous. // Traps are the union of exceptions and interrupts. - assign Exception1M = InstrMisalignedFaultM | InstrAccessFaultM | IllegalInstrFaultM | + assign ExceptionM = InstrMisalignedFaultM | InstrAccessFaultM | IllegalInstrFaultM | LoadMisalignedFaultM | StoreAmoMisalignedFaultM | InstrPageFaultM | LoadPageFaultM | StoreAmoPageFaultM | BreakpointFaultM | EcallFaultM | LoadAccessFaultM | StoreAmoAccessFaultM; - assign TrapM = Exception1M | InterruptM; // *** clean this up later DH + assign TrapM = ExceptionM | InterruptM; // *** clean this up later DH assign MTrapM = TrapM & (NextPrivilegeModeM == `M_MODE); assign STrapM = TrapM & (NextPrivilegeModeM == `S_MODE) & `S_SUPPORTED; assign UTrapM = TrapM & (NextPrivilegeModeM == `U_MODE) & `N_SUPPORTED; diff --git a/pipelined/testbench/sdc/sdModel.sv b/pipelined/testbench/sdc/sdModel.sv index 1e36c23e2..f2a5127d8 100644 --- a/pipelined/testbench/sdc/sdModel.sv +++ b/pipelined/testbench/sdc/sdModel.sv @@ -361,7 +361,7 @@ module sdModel next_state = READ_CMD; end ANALYZE_CMD: begin - if ((ValidCmd ) && (outDelayCnt >= `outDelay )) // outDelayCnt >= 4 (NCR) + if ((ValidCmd ) & (outDelayCnt >= `outDelay )) // outDelayCnt >= 4 (NCR) next_state = SEND_CMD; else if (inValidCmd) next_state = IDLE; @@ -387,7 +387,7 @@ module sdModel DATA_IDLE: begin if ((CardStatus[12:9]==`RCV) | (mult_write == 1'b1) ) next_datastate = READ_WAITS; - else if ((CardStatus[12:9]==`DATAS )|| (mult_read == 1'b1) ) + else if ((CardStatus[12:9]==`DATAS )| (mult_read == 1'b1) ) next_datastate = WRITE_DATA; else next_datastate = DATA_IDLE; @@ -551,7 +551,7 @@ module sdModel ResetCard; end 2 : begin //ALL_SEND_CARD_ID (CID) - if (lastCMD != 41 && outDelayCnt==0) begin + if (lastCMD != 41 & outDelayCnt==0) begin $fdisplay(sdModel_file_desc, "**Error in sequence, ACMD 41 should precede 2 in Start-up state") ; //$display(sdModel_file_desc, "**Error in sequence, ACMD 41 should precede 2 in Start-up state") ; CardStatus[3]<=1; // AKE_SEQ_ERROR = ERROR in sequence of authentication process @@ -561,7 +561,7 @@ module sdModel CardStatus[12:9] <=2; end 3 : begin //SEND_RELATIVE_CARD_ADDRESS (RCA) - if (lastCMD != 2 && outDelayCnt==0 ) begin + if (lastCMD != 2 & outDelayCnt==0 ) begin $fdisplay(sdModel_file_desc, "**Error in sequence, CMD 2 should precede 3 in Start-up state") ; //$display(sdModel_file_desc, "**Error in sequence, CMD 2 should precede 3 in Start-up state") ; CardStatus[3]<=1; // AKE_SEQ_ERROR = ERROR in sequence of authentication process @@ -573,7 +573,7 @@ module sdModel cardIdentificationState<=0; end 6 : begin - if (lastCMD == 55 && outDelayCnt==0) begin //ACMD6 - SET_BUS_WIDTH + if (lastCMD == 55 & outDelayCnt==0) begin //ACMD6 - SET_BUS_WIDTH if (inCmd[9:8] == 2'b10) begin BusWidth <=4; $display(sdModel_file_desc, "**BUS WIDTH 4 ") ; @@ -627,7 +627,7 @@ module sdModel end 9 : begin // SEND_CARD_SPECIFIC_DATA (CSD) - if (lastCMD != 41 && outDelayCnt==0) begin + if (lastCMD != 41 & outDelayCnt==0) begin $fdisplay(sdModel_file_desc, "**Error in sequence, ACMD 41 should precede 9 in Start-up state") ; //$display(sdModel_file_desc, "**Error in sequence, ACMD 41 should precede 9 in Start-up state") ; CardStatus[3]<=1; // AKE_SEQ_ERROR = ERROR in sequence of authentication process @@ -743,7 +743,7 @@ module sdModel 41 : // CMD41 - SD_SEND_OCR begin if (cardIdentificationState) begin - if (lastCMD != 55 && outDelayCnt==0) begin // CMD41 - Reserved/Invalid + if (lastCMD != 55 & outDelayCnt==0) begin // CMD41 - Reserved/Invalid $fdisplay(sdModel_file_desc, "**Error in sequence, CMD 55 should precede 41 in Start-up state") ; $display( "**Error in sequence, CMD 55 should precede 41 in Start-up state") ; CardStatus[3]<=1; // AKE_SEQ_ERROR = ERROR in sequence of authentication process @@ -755,7 +755,7 @@ module sdModel CardStatus[5] <=0; // not expecting next command to be ACMD if (Busy==1) CardStatus[12:9] <=1; // READY - end // else: !if(lastCMD != 55 && outDelayCnt==0) + end // else: !if(lastCMD != 55 & outDelayCnt==0) end // if (cardIdentificationState) end // case: 41 endcase // case (inCmd[45:40]) @@ -799,7 +799,7 @@ module sdModel else cmdOut<=1; - if ((cmdWrite>0) && (cmdWrite < response_S-8)) begin + if ((cmdWrite>0) & (cmdWrite < response_S-8)) begin cmdOut<=response_CMD[135-cmdWrite]; crcIn<=response_CMD[134-cmdWrite]; if (cmdWrite >= response_S-9) @@ -948,7 +948,7 @@ module sdModel data_send_index<=1; // Next nibble is lower nibble end - else if ( (transf_cnt>=2) && (transf_cnt<=BLOCK_WIDTH -`CRC_OFF )) begin // if (2 <= transf_cnt <= 1025) + else if ( (transf_cnt>=2) & (transf_cnt<=BLOCK_WIDTH -`CRC_OFF )) begin // if (2 <= transf_cnt <= 1025) data_send_index<=~data_send_index; //toggle if (!data_send_index) begin //upper nibble if (BLOCK_WIDTH == 11'd1044) begin @@ -987,7 +987,7 @@ module sdModel if ( transf_cnt >=BLOCK_WIDTH-`CRC_OFF ) begin // if (trans_cnt >= 1025) crcDat_en<=0; // Disable CRC16 Generators end - end // if ( (transf_cnt>=2) && (transf_cnt<=`BIT_BLOCK-`CRC_OFF )) + end // if ( (transf_cnt>=2) & (transf_cnt<=`BIT_BLOCK-`CRC_OFF )) else if (transf_cnt>BLOCK_WIDTH-`CRC_OFF & crc_c!=0) begin // if ((transf_cnt > 1025) and (crc_c /= 0)) datOut<= last_din; // if sent all data bitsbut not crc16 bits yet @@ -1004,7 +1004,7 @@ module sdModel else if (transf_cnt==BLOCK_WIDTH-2) begin // if (transf_cnt = 1042) Last CRC16 bit is 1041 datOut<=4'b1111; // send end bits end - else if ((transf_cnt !=0) && (crc_c == 0 ))begin // if sent data bits and crc_c points past last bit of CRC + else if ((transf_cnt !=0) & (crc_c == 0 ))begin // if sent data bits and crc_c points past last bit of CRC oeDat<=0; // disable output on DAT bus CardStatus[12:9] <= `TRAN; // put card in transfer state end @@ -1026,14 +1026,14 @@ module sdModel else if(flash_write_cnt == 2) datOut[0]<=0; - else if ((flash_write_cnt > 2) && (flash_write_cnt < 7)) begin + else if ((flash_write_cnt > 2) & (flash_write_cnt < 7)) begin if (crc_ok) datOut[0] <=okcrctoken[6-flash_write_cnt]; else datOut[0] <= invalidcrctoken[6-flash_write_cnt]; end - else if ((flash_write_cnt >= 7) && (flash_write_cnt < 264)) begin + else if ((flash_write_cnt >= 7) & (flash_write_cnt < 264)) begin datOut[0]<=0; flash_blockwrite_cnt<=flash_blockwrite_cnt+2; @@ -1045,7 +1045,7 @@ module sdModel datOut<=1; InbuffStatus<=0; CardStatus[12:9] <= `TRAN; - end // else: !if((flash_write_cnt >= 7) && (flash_write_cnt < 264)) + end // else: !if((flash_write_cnt >= 7) & (flash_write_cnt < 264)) end // case: WRITE_FLASH endcase // case (dataState) end // always @ (negedge sdClk) diff --git a/pipelined/testbench/testbench-linux.sv b/pipelined/testbench/testbench-linux.sv index b31140dd9..06f2cf2e9 100644 --- a/pipelined/testbench/testbench-linux.sv +++ b/pipelined/testbench/testbench-linux.sv @@ -82,7 +82,7 @@ module testbench; .HRDATAEXT, .HREADYEXT, .HREADY, .HSELEXT, .HRESPEXT, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, - .TIMECLK(0), .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, + .TIMECLK('0), .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .SDCCLK, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn); @@ -379,7 +379,7 @@ module testbench; //$display("len = %d", line``STAGE.len()); \ for(index``STAGE = 0; index``STAGE < line``STAGE.len(); index``STAGE++) begin \ //$display("char = %s", line``STAGE[index]); \ - if (line``STAGE[index``STAGE] == " " || line``STAGE[index``STAGE] == "\n") begin \ + if (line``STAGE[index``STAGE] == " " | line``STAGE[index``STAGE] == "\n") begin \ EndIndex``STAGE = index``STAGE; \ ExpectedTokens``STAGE[TokenIndex``STAGE] = line``STAGE.substr(StartIndex``STAGE, EndIndex``STAGE-1); \ //$display("In Tokenizer %s", line``STAGE.substr(StartIndex, EndIndex-1)); \ @@ -412,7 +412,7 @@ module testbench; // parse CSRs, because there are 1 or more CSRs after the CSR token \ // we check if the CSR token or the number of CSRs is greater than 0. \ // if so then we want to parse for a CSR. \ - end else if(ExpectedTokens``STAGE[MarkerIndex``STAGE] == "CSR" || NumCSR``STAGE > 0) begin \ + end else if(ExpectedTokens``STAGE[MarkerIndex``STAGE] == "CSR" | NumCSR``STAGE > 0) begin \ if(ExpectedTokens``STAGE[MarkerIndex``STAGE] == "CSR") begin \ // all additional CSR's won't have this token. \ MarkerIndex``STAGE++; \ @@ -467,7 +467,7 @@ module testbench; // $display("%tns: ExpectedPCM %x",$time,ExpectedPCM); // $display("%tns: ExpectedPCE %x",$time,ExpectedPCE); // $display("%tns: ExpectedPCW %x",$time,ExpectedPCW); - if((ExpectedPCE != MepcExpected) & ((MepcExpected - ExpectedPCE) * (MepcExpected - ExpectedPCE) <= 200) || ~dut.core.ieu.c.InstrValidM) begin + if((ExpectedPCE != MepcExpected) & ((MepcExpected - ExpectedPCE) * (MepcExpected - ExpectedPCE) <= 200) | ~dut.core.ieu.c.InstrValidM) begin RequestDelayedMIP <= 1; $display("%tns: Requesting Delayed MIP. Current MEPC value is %x",$time,MepcExpected); end else begin // update MIP immediately @@ -584,10 +584,10 @@ module testbench; if (MemOpW.substr(0,2) == "Mem") begin if(`DEBUG_TRACE >= 4) $display("\tIEUAdrW: %016x ? expected: %016x", IEUAdrW, ExpectedIEUAdrW); `checkEQ("IEUAdrW",IEUAdrW,ExpectedIEUAdrW) - if(MemOpW == "MemR" || MemOpW == "MemRW") begin + if(MemOpW == "MemR" | MemOpW == "MemRW") begin if(`DEBUG_TRACE >= 4) $display("\tReadDataW: %016x ? expected: %016x", dut.core.ieu.dp.ReadDataW, ExpectedMemReadDataW); `checkEQ("ReadDataW",dut.core.ieu.dp.ReadDataW,ExpectedMemReadDataW) - end else if(MemOpW == "MemW" || MemOpW == "MemRW") begin + end else if(MemOpW == "MemW" | MemOpW == "MemRW") begin if(`DEBUG_TRACE >= 4) $display("\tWriteDataW: %016x ? expected: %016x", WriteDataW, ExpectedMemWriteDataW); `checkEQ("WriteDataW",ExpectedMemWriteDataW,ExpectedMemWriteDataW) end @@ -636,7 +636,7 @@ module testbench; // For waveview convenience string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE, - dut.core.ifu.FinalInstrRawF, + dut.core.ifu.FinalInstrRawF[31:0], dut.core.ifu.InstrD, dut.core.ifu.InstrE, dut.core.ifu.InstrM, InstrW, InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); @@ -680,7 +680,7 @@ module testbench; PTE = dut.uncore.ram.ram.RAM[PAdr >> 3]; PTE_R = PTE[1]; PTE_X = PTE[3]; - if (PTE_R || PTE_X) begin + if (PTE_R | PTE_X) begin // Leaf page found break; end else begin diff --git a/pipelined/testbench/testbench-tim.sv b/pipelined/testbench/testbench-tim.sv index d694377c1..64d989292 100644 --- a/pipelined/testbench/testbench-tim.sv +++ b/pipelined/testbench/testbench-tim.sv @@ -196,7 +196,7 @@ logic [3:0] dummy; else pathname = tvpaths[1]; */ memfilename = {pathname, tests[test], ".elf.memfile"}; //$readmemh(memfilename, dut.uncore.ram.ram.RAM); - $readmemh(memfilename, dut.core.lsu.dtim.ram.RAM); + $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); // if(`MEM_DTIM == 1) $readmemh(memfilename, dut.core.lsu.dtim.ram.RAM); //`ifdef `MEM_IROM // $display("here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); @@ -204,7 +204,7 @@ logic [3:0] dummy; //`endif // if(`MEM_IROM == 1) begin // $display("here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); - $readmemh(memfilename, dut.core.ifu.irom.ram.RAM); + $readmemh(memfilename, dut.core.ifu.irom.irom.ram.RAM); // end ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; @@ -258,7 +258,7 @@ logic [3:0] dummy; while (signature[i] !== 'bx) begin //$display("signature[%h] = %h", i, signature[i]); // *** have to figure out how to exclude shadowram when not using a dcache. - if (signature[i] !== dut.core.lsu.dtim.ram.RAM[testadr+i] & + if (signature[i] !== dut.core.lsu.dtim.dtim.ram.RAM[testadr+i] & (signature[i] !== DCacheFlushFSM.ShadowRAM[testadr+i])) begin if (signature[i+4] !== 'bx | signature[i] !== 32'hFFFFFFFF) begin // report errors unless they are garbage at the end of the sim @@ -266,7 +266,7 @@ logic [3:0] dummy; errors = errors+1; $display(" Error on test %s result %d: adr = %h sim (D$) %h sim (TIM) = %h, signature = %h", //tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], dut.uncore.ram.ram.RAM[testadr+i], signature[i]); - tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], dut.core.lsu.dtim.ram.RAM[testadr+i], signature[i]); + tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], dut.core.lsu.dtim.dtim.ram.RAM[testadr+i], signature[i]); $stop;//***debug end end @@ -290,7 +290,7 @@ logic [3:0] dummy; //pathname = tvpaths[tests[0]]; memfilename = {pathname, tests[test], ".elf.memfile"}; //$readmemh(memfilename, dut.uncore.ram.ram.RAM); - $readmemh(memfilename, dut.core.lsu.dtim.ram.RAM); + $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); //if(`MEM_DTIM == 1) $readmemh(memfilename, dut.core.lsu.dtim.ram.RAM); /* -----\/----- EXCLUDED -----\/----- `ifdef `MEM_IROM @@ -298,7 +298,7 @@ logic [3:0] dummy; $readmemh(memfilename, dut.core.ifu.irom.ram.RAM); `endif -----/\----- EXCLUDED -----/\----- */ - $readmemh(memfilename, dut.core.ifu.irom.ram.RAM); + $readmemh(memfilename, dut.core.ifu.irom.irom.ram.RAM); //if(`MEM_IROM == 1) $readmemh(memfilename, dut.core.ifu.irom.ram.RAM); ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; diff --git a/pipelined/testbench/tests.vh b/pipelined/testbench/tests.vh index 6f4362bf5..424f2282b 100644 --- a/pipelined/testbench/tests.vh +++ b/pipelined/testbench/tests.vh @@ -1479,7 +1479,8 @@ string imperas32f[] = '{ "rv64i_m/privilege/WALLY-MMU-SV39", "30A0", "rv64i_m/privilege/WALLY-MMU-SV48", "30A0", "rv64i_m/privilege/WALLY-PMP", "30A0", - "rv64i_m/privilege/WALLY-PMA", "30A0" + "rv64i_m/privilege/WALLY-PMA", "30A0", + "rv64i_m/privilege/WALLY-minfo-01", "30A0" }; string wally64periph[] = '{ diff --git a/synthDC/.synopsys_dc.setup b/synthDC/.synopsys_dc.setup new file mode 100755 index 000000000..e4441ef36 --- /dev/null +++ b/synthDC/.synopsys_dc.setup @@ -0,0 +1,78 @@ + +# Search Paths +set CURRENT_DIR [exec pwd] +set search_path [list "./" ] + +set s8lib ../addins/sky130_osu_sc_t18/18T_ms/lib +lappend search_path $s8lib + +# Synthetic libraries +set synthetic_library [list dw_foundation.sldb] + +# Set OKSTATE standard cell libraries +set target_library [list] + +lappend target_library sky130_osu_sc_18T_ms_TT_1P8_25C.ccs.db + +# Set Link Library +set link_library "$target_library $synthetic_library" + +# Set up DesignWare cache read and write directories to speed up compile. +set cache_write ~ +set cache_read $cache_write + +# Tell DC where to look for files +lappend search_path ./scripts +lappend search_path ./hdl +lappend search_path ./mapped + +# Set up User Information +set company "Oklahoma State University" +set user "James E. Stine" + +# Alias +alias ra report_area +alias rt report_timing +alias rc {report_constraint -all_violators} + +alias sf set_flatten +alias ss set_structure +alias rco report_compile_options +alias cs compile -scan +alias csi compile -scan -incr -map high + +alias h history +history keep 100 +alias all_gone {remove_design -designs} + +alias page_on {set sh_enable_page_mode true} +alias page_off {set sh_enable_page_mode false} + +# specify directory for intermediate files from analyze +define_design_lib DEFAULT -path ./analyzed + +# suppress Driving cell warning +suppress_message {UID-401} + +########### Source Useful Tcl Procedures ########### + +foreach _file [glob -nocomplain ./tcl_procs/*.tcl] { + source $_file +} + +############# Enable line editing in 2004.12 ########### + +set sh_enable_line_editing true + +############# Setup the view utility ########### + +proc view {args} { + redirect tmpfile1212 {uplevel $args} + # Without redirect, exec echos the PID of the new process to the screen + redirect /dev/null {exec ./tcl_procs/view.tk tmpfile1212 "$args" &} +} + +alias vrt {view report_timing -nosplit} +alias vrtm {view report_timing -nosplit -delay min} +alias vman {view man} + diff --git a/synthDC/Makefile b/synthDC/Makefile new file mode 100755 index 000000000..35caad119 --- /dev/null +++ b/synthDC/Makefile @@ -0,0 +1,34 @@ +# +# Makefile for synthesis +# +NAME := synth + +VARIANT := 18T_ms + +default: + @echo "Basic synthesis procedure for OSU/HMC/UNLV:" + @echo " adapt Makefile to your liking..." + @echo + +synth: + @sed -i 's/18T_ms/${VARIANT}/g' scripts/synth.tcl + @sed -i 's/18T_ms/${VARIANT}/g' .synopsys_dc.setup + @echo "DC Synthesis" + @mkdir -p reports + @mkdir -p mapped + dc_shell-xg-t -64bit -f scripts/$(NAME).tcl | tee $(NAME).out +# @cp mapped/*.sdc ../../outputs/ +# @cp mapped/*.vh ../../outputs/ +# @sed -i 's/${VARIANT}/18T_ms/g' scripts/synth.tcl +# @sed -i 's/${VARIANT}/18T_ms/g' .synopsys_dc.setup + +clean: + rm -rf alib-52 WORK mapped unmapped reports analyzed $(NAME).out + mkdir mapped unmapped reports + rm -f hdl/* + rm -f default.svf + rm -f command.log + rm -f filenames*.log + + + diff --git a/synthDC/README.md b/synthDC/README.md new file mode 100644 index 000000000..12db0a524 --- /dev/null +++ b/synthDC/README.md @@ -0,0 +1,34 @@ +This subdirectory contains synthesis scripts for use with Synopsys +Design Compiler (DC). The scripts are separated into two distinct +sections: user and technology setups. The technology setup is found +in .synopsys_dc.setup file. Key items within this technology setup +are the location of the PDK and standard cell libraries. + +We are using the Skywater Technology 130nm process for the synthesis. +The Oklahoma State University standard-cell libraries for this process +are located via the target_library keyword. There are currently three +versions of the standard-cell libraries available (see +http://stineje.github.io) for dowload locations. Currently, the TT 18 +track OSU standard-cell library is utilized. + +There are other useful elements within the technology setup file, as +well. These include user information as well as search path +information. Good tool flows usually rely on finding the right files +correctly and having a search path set correctly is importantly. + +The user setup is found in two main areas. The scripts/ and hdl/ +directories. The scripts directory contains a basic DC synthesis Tcl +script that is involved when synthesis is run. Please modify this +synth.tcl file to add information about PPA and information about your +design (e.g., top-level name, SV files). The SV is found within the +hdl/ subdirectory. Just put all your synthesis-friendly files in this +directory or allude to the correct location in the synthesis Tcl +script. + +After synthesis completes, always check your synthesis log file that +will be called synth.log. Good tool flow starts and ends with +understanding what is happening during a specific part of the flow. +This can only be done through interpreting what the Electronic Design +Automation (EDA) tool is doing. So, always check this file for any +possible warnings or errors after completion. All output of synthesis +is found in the reports/ subdirectory. \ No newline at end of file diff --git a/synthDC/scripts/synth.tcl b/synthDC/scripts/synth.tcl new file mode 100755 index 000000000..a52abaa91 --- /dev/null +++ b/synthDC/scripts/synth.tcl @@ -0,0 +1,184 @@ +# +# Main Synopsys Flow +# james.stine@okstate.edu 26 Jan 2022 +# + +# Config +set hdl_src "../pipelined/src" + +eval file copy ${hdl_src}/../config/rv64gc/wally-config.vh {hdl/} +eval file copy ${hdl_src}/../config/rv64gc/wally-config.vh {reports/} +eval file copy [glob ${hdl_src}/../config/shared/*.vh] {hdl/} +eval file copy [glob ${hdl_src}/*/*.sv] {hdl/} +eval file copy [glob ${hdl_src}/*/flop/*.sv] {hdl/} + +# Verilog files +set my_verilog_files [glob hdl/*] + +# Set toplevel +set my_toplevel wallypipelinedcore + +# Set number of significant digits +set report_default_significant_digits 6 + +# V(HDL) Unconnectoed Pins Output +set verilogout_show_unconnected_pins "true" +set vhdlout_show_unconnected_pins "true" + +# +# Due to parameterized Verilog must use analyze/elaborate and not +# read_verilog/vhdl (change to pull in Verilog and/or VHDL) +# +define_design_lib WORK -path ./WORK +analyze -f sverilog -lib WORK $my_verilog_files + +# +# Added if you had any VHDL +# analyze -f vhdl -lib WORK $my_vhdl_files +# +elaborate $my_toplevel -lib WORK + +# Set the current_design +current_design $my_toplevel +link + +# Reset all constraints +reset_design + +# Set Frequency in [MHz] or [ps] +set my_clock_pin clk +set my_clk_freq_MHz 10 +set my_period [expr 1000 / $my_clk_freq_MHz] +set my_uncertainty [expr .1 * $my_period] + +# Create clock object +set find_clock [ find port [list $my_clock_pin] ] +if { $find_clock != [list] } { + echo "Found clock!" + set my_clk $my_clock_pin + create_clock -period $my_period $my_clk + set_clock_uncertainty $my_uncertainty [get_clocks $my_clk] +} else { + echo "Did not find clock! Design is probably combinational!" + set my_clk vclk + create_clock -period $my_period -name $my_clk +} + +# Partitioning - flatten or hierarchically synthesize +#ungroup -flatten -simple_names { dp* } +#ungroup -flatten -simple_names { c* } +#ungroup -all -flatten -simple_names + +# Set input pins except clock +set all_in_ex_clk [remove_from_collection [all_inputs] [get_ports $my_clk]] + +# Specifies delays be propagated through the clock network +set_propagated_clock [get_clocks $my_clk] + +# Setting constraints on input ports +set_driving_cell -lib_cell sky130_osu_sc_18T_ms__dff_1 -pin Q $all_in_ex_clk + +# Set input/output delay +set_input_delay 0.0 -max -clock $my_clk $all_in_ex_clk +set_output_delay 0.0 -max -clock $my_clk [all_outputs] + +# Setting load constraint on output ports +set_load [expr [load_of sky130_osu_sc_18T_ms_TT_1P8_25C.ccs/sky130_osu_sc_18T_ms__dff_1/D] * 1] [all_outputs] + +# Set the wire load model +set_wire_load_mode "top" + +# Attempt Area Recovery - if looking for minimal area +# set_max_area 2000 + +# Set fanout +set_max_fanout 6 $all_in_ex_clk + +# Fix hold time violations +set_fix_hold [all_clocks] + +# Deal with constants and buffers to isolate ports +set_fix_multiple_port_nets -all -buffer_constants + +# setting up the group paths to find out the required timings +#group_path -name OUTPUTS -to [all_outputs] +#group_path -name INPUTS -from [all_inputs] +#group_path -name COMBO -from [all_inputs] -to [all_outputs] + +# Save Unmapped Design +set filename [format "%s%s%s" "unmapped/" $my_toplevel ".ddc"] +write_file -format ddc -hierarchy -o $filename + +# Compile statements - either compile or compile_ultra +# compile -scan -incr -map_effort low +# compile_ultra -no_seq_output_inversion -no_boundary_optimization + +# Eliminate need for assign statements (yuck!) +set verilogout_no_tri true +set verilogout_equation false + +# setting to generate output files +set write_v 1 ;# generates structual netlist +set write_sdc 1 ;# generates synopsys design constraint file for p&r +set write_ddc 1 ;# compiler file in ddc format +set write_sdf 1 ;# sdf file for backannotated timing sim +set write_pow 1 ;# genrates estimated power report +set write_rep 1 ;# generates estimated area and timing report +set write_cst 1 ;# generate report of constraints +set write_hier 1 ;# generate hierarchy report + +# Report Constraint Violators +set filename [format "%s%s%s" "reports/" $my_toplevel "_constraint_all_violators.rpt"] +redirect $filename {report_constraint -all_violators} + +# Check design +redirect reports/check_design.rpt { check_design } + +# Report Final Netlist (Hierarchical) +set filename [format "%s%s%s" "mapped/" $my_toplevel ".vh"] +write_file -f verilog -hierarchy -output $filename + +set filename [format "%s%s%s" "mapped/" $my_toplevel ".sdc"] +write_sdc $filename + +set filename [format "%s%s%s" "mapped/" $my_toplevel ".ddc"] +write_file -format ddc -hierarchy -o $filename + +set filename [format "%s%s%s" "mapped/" $my_toplevel ".sdf"] +write_sdf $filename + +# QoR +set filename [format "%s%s%s" "reports/" $my_toplevel "_qor.rep"] +redirect $filename { report_qor } + +# Report Timing +set filename [format "%s%s%s" "reports/" $my_toplevel "_reportpath.rep"] +redirect $filename { report_path_group } + +set filename [format "%s%s%s" "reports/" $my_toplevel "_report_clock.rep"] +redirect $filename { report_clock } + +set filename [format "%s%s%s" "reports/" $my_toplevel "_timing.rep"] +redirect $filename { report_timing -capacitance -transition_time -nets -nworst 1 } + +set filename [format "%s%s%s" "reports/" $my_toplevel "_min_timing.rep"] +redirect $filename { report_timing -delay min } + +set filename [format "%s%s%s" "reports/" $my_toplevel "_area.rep"] +redirect $filename { report_area -hierarchy -nosplit -physical -designware} + +set filename [format "%s%s%s" "reports/" $my_toplevel "_cell.rep"] +redirect $filename { report_cell [get_cells -hier *] } + +set filename [format "%s%s%s" "reports/" $my_toplevel "_power.rep"] +redirect $filename { report_power } + +set filename [format "%s%s%s" "reports/" $my_toplevel "_constraint.rep"] +redirect $filename { report_constraint } + +set filename [format "%s%s%s" "reports/" $my_toplevel "_hier.rep"] +redirect $filename { report_hierarchy } + +# Quit +quit + diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-MMU-SV32.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-MMU-SV32.S index f1733f8fe..91681f81d 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-MMU-SV32.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-MMU-SV32.S @@ -21,7 +21,7 @@ // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /////////////////////////////////////////// -#include "WALLY-TEST-LIB-32.S" +#include "WALLY-TEST-LIB-32.h" // Test library includes and handler for each type of test, a trap handler, imperas compliance instructions // Ideally this should mean that a test can be written by simply adding .8byte statements as below. @@ -44,52 +44,52 @@ # test 12.3.1.1.1 write page tables / entries to phyiscal memory # sv32 Page table (See Figure 12.12***): # Level 1 page table, situated at 0x8000D000 -.4byte 0x8000D000, 0x20004C01, 0x0 # points to level 0 page table A -.4byte 0x8000D004, 0x200000CB, 0x0 # Vaddr 0x400000 Paddr 0x80000000: aligned megapage, W=0, used for execute tests -.4byte 0x8000D008, 0x20005401, 0x0 # points to level 0 page table B -.4byte 0x8000D00C, 0x000800C7, 0x0 # Vaddr 0xC00000: misaligned megapage -.4byte 0x8000D800, 0x200000CF, 0x0 # Vaddr 0x80000000 Paddr 0x80000000: aligned megapage (program and data memory) -.4byte 0x8000D804, 0x200000DF, 0x0 # Vaddr 0x80400000 Paddr 0x80000000: aligned megapage, U=1 (aliased with program and data memory) +.4byte 0x8000D000, 0x20004C01, write32_test # points to level 0 page table A +.4byte 0x8000D004, 0x200000CB, write32_test # Vaddr 0x400000 Paddr 0x80000000: aligned megapage, W=0, used for execute tests +.4byte 0x8000D008, 0x20005401, write32_test # points to level 0 page table B +.4byte 0x8000D00C, 0x000800C7, write32_test # Vaddr 0xC00000: misaligned megapage +.4byte 0x8000D800, 0x200000CF, write32_test # Vaddr 0x80000000 Paddr 0x80000000: aligned megapage (program and data memory) +.4byte 0x8000D804, 0x200000DF, write32_test # Vaddr 0x80400000 Paddr 0x80000000: aligned megapage, U=1 (aliased with program and data memory) # Level 0 page table A -.4byte 0x80013000, 0x20007001, 0x0 # Vaddr 0x0000: bad PTE points to level -1 table -.4byte 0x80013004, 0x202000DF, 0x0 # Vaddr 0x1000 Paddr 0x80800000: aligned kilopage, U=1 -.4byte 0x80013008, 0x202010D5, 0x0 # Vaddr 0x2000: pad PTE has W but not R -.4byte 0x8001300C, 0x20200817, 0x0 # Vaddr 0x3000: A=0, should cause read fault -.4byte 0x80013010, 0x20200C57, 0x0 # Vaddr 0x4000: D=0, should cause write fault -.4byte 0x80013014, 0x202014C9, 0x0 # Vaddr 0x5000 Paddr 80805000: aligned kilopage, W=R=0 -.4byte 0x80013018, 0x0, 0x0 # Vaddr 0x6000: invalid page +.4byte 0x80013000, 0x20007001, write32_test # Vaddr 0x0000: bad PTE points to level -1 table +.4byte 0x80013004, 0x202000DF, write32_test # Vaddr 0x1000 Paddr 0x80800000: aligned kilopage, U=1 +.4byte 0x80013008, 0x202010D5, write32_test # Vaddr 0x2000: pad PTE has W but not R +.4byte 0x8001300C, 0x20200817, write32_test # Vaddr 0x3000: A=0, should cause read fault +.4byte 0x80013010, 0x20200C57, write32_test # Vaddr 0x4000: D=0, should cause write fault +.4byte 0x80013014, 0x202014C9, write32_test # Vaddr 0x5000 Paddr 80805000: aligned kilopage, W=R=0 +.4byte 0x80013018, 0x0, write32_test # Vaddr 0x6000: invalid page # Level 0 page table B -.4byte 0x80015FFC, 0x202004C7, 0x0 # Vaddr 0xBFF000 Paddr 0x80801000: aligned kilopage with X=0, U=0 +.4byte 0x80015FFC, 0x202004C7, write32_test # Vaddr 0xBFF000 Paddr 0x80801000: aligned kilopage with X=0, U=0 # test 12.3.1.1.2 write values to Paddrs in each page # each of these values is used for 12.3.1.1.3 and some other tests, specified in the comments. # when a test is supposed to fault, nothing is written into where it'll be reading/executing since it should fault before getting there. -.4byte 0x800AAAA8, 0xBEEF0055, 0x0 # 12.3.1.1.4 megapage -.4byte 0x800FFAC0, 0xBEEF0033, 0x0 # 12.3.1.3.2 -.4byte 0x800E3130, 0xBEEF0077, 0x0 # 12.3.1.3.2 -.4byte 0x808017E0, 0xBEEF0099, 0x0 # 12.3.1.1.4 kilopage -.4byte 0x80805EA0, 0xBEEF0440, 0x0 # 12.3.1.3.3 -.4byte 0x80803AA0, 0xBEEF0BB0, 0x0 # 12.3.1.3.7 -.4byte 0x8000FFA0, 0x11100393, 0x0 # write executable code for "li x7, 0x111; ret" to executable region. -.4byte 0x8000FFA4, 0x00008067, 0x0 # Used for 12.3.1.3.1, 12.3.1.3.2 +.4byte 0x800AAAA8, 0xBEEF0055, write32_test # 12.3.1.1.4 megapage +.4byte 0x800FFAC0, 0xBEEF0033, write32_test # 12.3.1.3.2 +.4byte 0x800E3130, 0xBEEF0077, write32_test # 12.3.1.3.2 +.4byte 0x808017E0, 0xBEEF0099, write32_test # 12.3.1.1.4 kilopage +.4byte 0x80805EA0, 0xBEEF0440, write32_test # 12.3.1.3.3 +.4byte 0x80803AA0, 0xBEEF0BB0, write32_test # 12.3.1.3.7 +.4byte 0x8000FFA0, 0x11100393, write32_test # write executable code for "li x7, 0x111; ret" to executable region. +.4byte 0x8000FFA4, 0x00008067, write32_test # Used for 12.3.1.3.1, 12.3.1.3.2 # test 12.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test) -.4byte 0x0, 0x0, 0x4 # satp.MODE = baremetal / no translation. -.4byte 0x0, 0x0, 0x9 # change to S mode, 0xb written to output -.4byte 0x800AAAA8, 0xBEEF0055, 0x1 -.4byte 0x800FFAC0, 0xBEEF0033, 0x1 -.4byte 0x800E3130, 0xBEEF0077, 0x1 -.4byte 0x808017E0, 0xBEEF0099, 0x1 -.4byte 0x80805EA0, 0xBEEF0440, 0x1 -.4byte 0x80803AA0, 0xBEEF0BB0, 0x1 -.4byte 0x8000FFA0, 0x11100393, 0x1 -.4byte 0x8000FFA4, 0x00008067, 0x1 +.4byte 0x0, 0x0, goto_baremetal # satp.MODE = baremetal / no translation. +.4byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output +.4byte 0x800AAAA8, 0xBEEF0055, read32_test +.4byte 0x800FFAC0, 0xBEEF0033, read32_test +.4byte 0x800E3130, 0xBEEF0077, read32_test +.4byte 0x808017E0, 0xBEEF0099, read32_test +.4byte 0x80805EA0, 0xBEEF0440, read32_test +.4byte 0x80803AA0, 0xBEEF0BB0, read32_test +.4byte 0x8000FFA0, 0x11100393, read32_test +.4byte 0x8000FFA4, 0x00008067, read32_test # test 12.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs -.4byte 0x0, 0x0, 0x5 # satp.MODE = sv32, Nothing written to output -.4byte 0x4AAAA8, 0xBEEF0055, 0x1 # megapage at Vaddr 0x400000, Paddr 0x80000000 -.4byte 0xBFF7E0, 0xBEEF0099, 0x1 # kilopage at Vaddr 0xBFF000, Paddr 0x80201000 +.4byte 0x0, 0x0, goto_sv32 # satp.MODE = sv32, Nothing written to output +.4byte 0x4AAAA8, 0xBEEF0055, read32_test # megapage at Vaddr 0x400000, Paddr 0x80000000 +.4byte 0xBFF7E0, 0xBEEF0099, read32_test # kilopage at Vaddr 0xBFF000, Paddr 0x80201000 # =========== test 12.3.1.2 page fault tests =========== @@ -97,59 +97,59 @@ # Not tested in rv32/sv32 # test 12.3.1.2.2 load page fault when reading an address where the valid flag is zero -.4byte 0x6000, 0x0, 0x1 +.4byte 0x6000, 0x0, read32_test # test 12.3.1.2.3 store page fault if PTE has W and ~R flags set -.4byte 0x2000, 0x0, 0x0 +.4byte 0x2000, 0x0, write32_test # test 12.3.1.2.4 Fault if last level PTE is a pointer -.4byte 0x0200, 0x0, 0x1 +.4byte 0x0200, 0x0, read32_test # test 12.3.1.2.5 load page fault on misaligned pages -.4byte 0xC00000, 0x0, 0x1 # misaligned megapage +.4byte 0xC00000, 0x0, read32_test # misaligned megapage # =========== test 12.3.1.3 PTE Protection flags =========== # test 12.3.1.3.1 User flag == 0 # *** reads on pages with U=0 already tested in 12.3.1.1.4 -.4byte 0x40FFA0, 0x111, 0x2 # fetch success when U=0, priv=S -.4byte 0x80400000, 0x1, 0xA # go to U mode, return to VPN 0x80400000 where PTE.U = 1. 0x9 written to output -.4byte 0xBFFC80, 0xBEEF0550, 0x1 # load page fault when U=0, priv=U -.4byte 0x40FFA0, 0xbad, 0x2 # instr page fault when U=0, priv=U +.4byte 0x40FFA0, 0x111, executable_test # fetch success when U=0, priv=S +.4byte 0x80400000, 0x1, goto_u_mode # go to U mode, return to VPN 0x80400000 where PTE.U = 1. 0x9 written to output +.4byte 0xBFFC80, 0xBEEF0550, read32_test # load page fault when U=0, priv=U +.4byte 0x40FFA0, 0xbad, executable_test # instr page fault when U=0, priv=U # test 12.3.1.3.2 User flag == 1 -.4byte 0x804FFAC0, 0xBEEF0033, 0x1 # read success when U=1, priv=U -.4byte 0x80000000, 0x1, 0x9 # go back to S mode, return to VPN 0x80000000 where PTE.U = 0. 0x8 written to output -.4byte 0x0, 0x3, 0x7 # set sstatus.[MXR, SUM] = 11 -.4byte 0x804E3130, 0xBEEF0077, 0x1 # read success when U=1, priv=S, sstatus.SUM=1 -.4byte 0x8040FFA0, 0xbad, 0x2 # instr page fault when U=1, priv=S (with any sstatus.SUM) -.4byte 0x0, 0x2, 0x7 # set sstatus.[MXR, SUM] = 10. -.4byte 0x804FFAC0, 0xBEEF0033, 0x1 # load page fault when U-1, priv=S, sstatus.SUM=0 +.4byte 0x804FFAC0, 0xBEEF0033, read32_test # read success when U=1, priv=U +.4byte 0x80000000, 0x1, goto_s_mode # go back to S mode, return to VPN 0x80000000 where PTE.U = 0. 0x8 written to output +.4byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11 +.4byte 0x804E3130, 0xBEEF0077, read32_test # read success when U=1, priv=S, sstatus.SUM=1 +.4byte 0x8040FFA0, 0xbad, executable_test # instr page fault when U=1, priv=S (with any sstatus.SUM) +.4byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10. +.4byte 0x804FFAC0, 0xBEEF0033, read32_test # load page fault when U-1, priv=S, sstatus.SUM=0 # test 12.3.1.3.3 Read flag # *** reads on pages with R=1 already tested in 12.3.1.1.4 -.4byte 0x0, 0x1, 0x7 # set sstatus.[MXR, SUM] = 01. -.4byte 0x5EA0, 0xBEEF0440, 0x1 # load page fault when R=0, sstatus.MXR=0 -.4byte 0x0, 0x3, 0x7 # set sstatus.[MXR, SUM] = 11. -.4byte 0x5EA0, 0xBEEF0440, 0x1 # read success when R=0, MXR=1, X=1 +.4byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01. +.4byte 0x5EA0, 0xBEEF0440, read32_test # load page fault when R=0, sstatus.MXR=0 +.4byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11. +.4byte 0x5EA0, 0xBEEF0440, read32_test # read success when R=0, MXR=1, X=1 # test 12.3.1.3.4 Write flag -.4byte 0xBFF290, 0xBEEF0110, 0x0 # write success when W=1 -.4byte 0xBFF290, 0xBEEF0110, 0x1 # check write success by reading -.4byte 0x5B78, 0xBEEF0CC0, 0x0 # store page fault when W=0 +.4byte 0xBFF290, 0xBEEF0110, write32_test # write success when W=1 +.4byte 0xBFF290, 0xBEEF0110, read32_test # check write success by reading +.4byte 0x5B78, 0xBEEF0CC0, write32_test # store page fault when W=0 # test 12.3.1.3.5 eXecute flag # *** fetches on pages with X = 1 already tested in 12.3.1.3.1 -.4byte 0xBFFDE0, 0xbad, 0x2 # instr page fault when X=0 +.4byte 0xBFFDE0, 0xbad, executable_test # instr page fault when X=0 # test 12.3.1.3.6 Accessed flag == 0 -.4byte 0x3020, 0xBEEF0770, 0x0 # store page fault when A=0 -.4byte 0x3808, 0xBEEF0990, 0x1 # load page fault when A=0 +.4byte 0x3020, 0xBEEF0770, write32_test # store page fault when A=0 +.4byte 0x3808, 0xBEEF0990, read32_test # load page fault when A=0 # test 12.3.1.3.7 Dirty flag == 0 -.4byte 0x4658, 0xBEEF0AA0, 0x0 # store page fault when D=0 -.4byte 0x4AA0, 0xBEEF0BB0, 0x1 # read success when D=0 +.4byte 0x4658, 0xBEEF0AA0, write32_test # store page fault when D=0 +.4byte 0x4AA0, 0xBEEF0BB0, read32_test # read success when D=0 # terminate tests -.4byte 0x0, 0x0, 0x3 # brings us back into machine mode with a final ecall, writing 0x9 to the output. +.4byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output. diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-PMA.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-PMA.S index 6188b2ac3..80d6d504f 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-PMA.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-PMA.S @@ -34,7 +34,7 @@ #define PLIC_BASE 0x0C000000 #define PLIC_RANGE 0x03FFFFFF -#include "WALLY-TEST-LIB-32.S" +#include "WALLY-TEST-LIB-32.h" // Test library includes and handler for each type of test, a trap handler, imperas compliance instructions // Ideally this should mean that a test can be written by simply adding .4byte statements as below. @@ -71,49 +71,49 @@ # ----------------- CLINT --------------------- # Use timecmp register as readable and writable section of the CLINT -.4byte CLINT_BASE + 0x4000, 0xBEEF00B5, 0x0 # 32-bit write: success -.4byte CLINT_BASE + 0x4000, 0xBEEF00B5, 0x1 # 32-bit read: success -.4byte CLINT_BASE + 0x4000, 0xBEEF00B6, 0x12 # 16-bit write: success -.4byte CLINT_BASE + 0x4000, 0xBEEF00B6, 0x15 # 16-bit read: success -.4byte CLINT_BASE + 0x4000, 0xBEEF00B7, 0x13 # 08-bit write: success -.4byte CLINT_BASE + 0x4000, 0xBEEF00B7, 0x16 # 08-bit read: success +.4byte CLINT_BASE + 0x4000, 0xBEEF00B5, write32_test # 32-bit write: success +.4byte CLINT_BASE + 0x4000, 0xBEEF00B5, read32_test # 32-bit read: success +.4byte CLINT_BASE + 0x4000, 0xBEEF00B6, write16_test# 16-bit write: success +.4byte CLINT_BASE + 0x4000, 0xBEEF00B6, read16_test# 16-bit read: success +.4byte CLINT_BASE + 0x4000, 0xBEEF00B7, write08_test# 08-bit write: success +.4byte CLINT_BASE + 0x4000, 0xBEEF00B7, read08_test# 08-bit read: success -.4byte CLINT_BASE, 0xbad, 0x2 # execute: instruction access fault +.4byte CLINT_BASE, 0xbad, executable_test# execute: instruction access fault # ----------------- PLIC --------------------- # Write 0x2 instead of wider value to plic address because the register width might change. -.4byte PLIC_BASE + 0x2000, 0x2, 0x0 # 32-bit write: success -.4byte PLIC_BASE + 0x2000, 0x2, 0x1 # 32-bit read: success -.4byte PLIC_BASE, 0xBEEF00BA, 0x12 # 16-bit write: store access fault -.4byte PLIC_BASE, 0xBEEF00BA, 0x15 # 16-bit read: load access fault -.4byte PLIC_BASE, 0xBEEF00BB, 0x13 # 08-bit write: store access fault -.4byte PLIC_BASE, 0xBEEF00BB, 0x16 # 08-bit read: load access fault +.4byte PLIC_BASE + 0x2000, 0x2, write32_test # 32-bit write: success +.4byte PLIC_BASE + 0x2000, 0x2, read32_test # 32-bit read: success +.4byte PLIC_BASE, 0xBEEF00BA, write16_test # 16-bit write: store access fault +.4byte PLIC_BASE, 0xBEEF00BA, read16_test # 16-bit read: load access fault +.4byte PLIC_BASE, 0xBEEF00BB, write08_test # 08-bit write: store access fault +.4byte PLIC_BASE, 0xBEEF00BB, read08_test # 08-bit read: load access fault -.4byte PLIC_BASE, 0xbad, 0x2 # execute: instruction access fault +.4byte PLIC_BASE, 0xbad, executable_test# execute: instruction access fault # ----------------- UART0 --------------------- -.4byte UART_BASE, 0xBEEF00BD, 0x0 # 32-bit write: store access fault -.4byte UART_BASE, 0xBEEF00BD, 0x1 # 32-bit read: load access fault -.4byte UART_BASE, 0xBEEF00BE, 0x12 # 16-bit write: store access fault -.4byte UART_BASE, 0xBEEF00BE, 0x15 # 16-bit read: load access fault +.4byte UART_BASE, 0xBEEF00BD, write32_test # 32-bit write: store access fault +.4byte UART_BASE, 0xBEEF00BD, read32_test # 32-bit read: load access fault +.4byte UART_BASE, 0xBEEF00BE, write16_test# 16-bit write: store access fault +.4byte UART_BASE, 0xBEEF00BE, read16_test# 16-bit read: load access fault # Different address for this test so that we write into a writable register in the uart. -.4byte UART_BASE + 0x3, 0xBEEF00BF, 0x13 # 08-bit write: success -.4byte UART_BASE + 0x3, 0xBEEF00BF, 0x16 # 08-bit read: success +.4byte UART_BASE + 0x3, 0xBEEF00BF, write08_test# 08-bit write: success +.4byte UART_BASE + 0x3, 0xBEEF00BF, read08_test# 08-bit read: success -.4byte UART_BASE, 0xbad, 0x2 # execute: instruction access fault +.4byte UART_BASE, 0xbad, executable_test# execute: instruction access fault # ----------------- GPIO --------------------- -.4byte GPIO_BASE + 0x8, 0xBEEF00C1, 0x0 # 32-bit write: success -.4byte GPIO_BASE + 0x8, 0xBEEF00C1, 0x1 # 32-bit read: success -.4byte GPIO_BASE, 0xBEEF00C2, 0x12 # 16-bit write: store access fault -.4byte GPIO_BASE, 0xBEEF00C2, 0x15 # 16-bit read: load access fault -.4byte GPIO_BASE, 0xBEEF00C3, 0x13 # 08-bit write: store access fault -.4byte GPIO_BASE, 0xBEEF00C3, 0x16 # 08-bit read: load access fault +.4byte GPIO_BASE + 0x8, 0xBEEF00C1, write32_test # 32-bit write: success +.4byte GPIO_BASE + 0x8, 0xBEEF00C1, read32_test# 32-bit read: success +.4byte GPIO_BASE, 0xBEEF00C2, write16_test # 16-bit write: store access fault +.4byte GPIO_BASE, 0xBEEF00C2, read16_test # 16-bit read: load access fault +.4byte GPIO_BASE, 0xBEEF00C3, write08_test # 08-bit write: store access fault +.4byte GPIO_BASE, 0xBEEF00C3, read08_test # 08-bit read: load access fault -.4byte GPIO_BASE, 0xbad, 0x2 # execute: instruction access fault +.4byte GPIO_BASE, 0xbad, executable_test# execute: instruction access fault # ----------------- Inaccessible --------------------- @@ -121,32 +121,32 @@ # show that load, store, and jalr cause faults in a region not defined by PMAs. # Tests 'random' place in unimplemented memory -.4byte 0x40000000, 0xBEEF00C7, 0x0 # 32-bit write: store access fault -.4byte 0x40000000, 0xBEEF00C7, 0x1 # 32-bit read: load access fault -.4byte 0x40000000, 0x111, 0x2 # execute: instruction access fault +.4byte 0x40000000, 0xBEEF00C7, write32_test # 32-bit write: store access fault +.4byte 0x40000000, 0xBEEF00C7, read32_test # 32-bit read: load access fault +.4byte 0x40000000, 0x111, executable_test # execute: instruction access fault # Tests just past the end of each peripheral -.4byte (BOOTROM_BASE+BOOTROM_RANGE+1), 0xBEEF00C8, 0x0 # 32-bit write: store access fault -.4byte (BOOTROM_BASE+BOOTROM_RANGE+1), 0xBEEF00C8, 0x1 # 32-bit read: load access fault -.4byte (BOOTROM_BASE+BOOTROM_RANGE+1), 0x111, 0x2 # execute: instruction access fault +.4byte (BOOTROM_BASE+BOOTROM_RANGE+1), 0xBEEF00C8, write32_test # 32-bit write: store access fault +.4byte (BOOTROM_BASE+BOOTROM_RANGE+1), 0xBEEF00C8, read32_test # 32-bit read: load access fault +.4byte (BOOTROM_BASE+BOOTROM_RANGE+1), 0x111, executable_test # execute: instruction access fault -.4byte (CLINT_BASE+CLINT_RANGE+1), 0xBEEF00C9, 0x0 # 32-bit write: store access fault -.4byte (CLINT_BASE+CLINT_RANGE+1), 0xBEEF00C9, 0x1 # 32-bit read: load access fault -.4byte (CLINT_BASE+CLINT_RANGE+1), 0x111, 0x2 # execute: instruction access fault +.4byte (CLINT_BASE+CLINT_RANGE+1), 0xBEEF00C9, write32_test # 32-bit write: store access fault +.4byte (CLINT_BASE+CLINT_RANGE+1), 0xBEEF00C9, read32_test # 32-bit read: load access fault +.4byte (CLINT_BASE+CLINT_RANGE+1), 0x111, executable_test # execute: instruction access fault -.4byte (PLIC_BASE+PLIC_RANGE+1), 0xBEEF00CA, 0x0 # 32-bit write: store access fault -.4byte (PLIC_BASE+PLIC_RANGE+1), 0xBEEF00CA, 0x1 # 32-bit read: load access fault -.4byte (PLIC_BASE+PLIC_RANGE+1), 0x111, 0x2 # execute: instruction access fault +.4byte (PLIC_BASE+PLIC_RANGE+1), 0xBEEF00CA, write32_test # 32-bit write: store access fault +.4byte (PLIC_BASE+PLIC_RANGE+1), 0xBEEF00CA, read32_test # 32-bit read: load access fault +.4byte (PLIC_BASE+PLIC_RANGE+1), 0x111, executable_test # execute: instruction access fault -.4byte (UART_BASE+UART_RANGE+1), 0xBEEF00CB, 0x13 # 08-bit write: store access fault -.4byte (UART_BASE+UART_RANGE+1), 0xBEEF00CB, 0x16 # 08-bit read: load access fault -.4byte (UART_BASE+UART_RANGE+1), 0x111, 0x2 # execute: instruction access fault +.4byte (UART_BASE+UART_RANGE+1), 0xBEEF00CB, write08_test # 08-bit write: store access fault +.4byte (UART_BASE+UART_RANGE+1), 0xBEEF00CB, read08_test # 08-bit read: load access fault +.4byte (UART_BASE+UART_RANGE+1), 0x111, executable_test # execute: instruction access fault -.4byte (GPIO_BASE+GPIO_RANGE+1), 0xBEEF00CC, 0x0 # 32-bit write: store access fault -.4byte (GPIO_BASE+GPIO_RANGE+1), 0xBEEF00CC, 0x1 # 32-bit read: load access fault -.4byte (GPIO_BASE+GPIO_RANGE+1), 0x111, 0x2 # execute: instruction access fault +.4byte (GPIO_BASE+GPIO_RANGE+1), 0xBEEF00CC, write32_test # 32-bit write: store access fault +.4byte (GPIO_BASE+GPIO_RANGE+1), 0xBEEF00CC, read32_test # 32-bit read: load access fault +.4byte (GPIO_BASE+GPIO_RANGE+1), 0x111, executable_test # execute: instruction access fault -.4byte 0x0, 0x0, 0x3 # terminate tests +.4byte 0x0, 0x0, terminate_test # terminate tests diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-PMP.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-PMP.S index f963b09b9..887bfd97f 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-PMP.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-PMP.S @@ -21,7 +21,7 @@ // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /////////////////////////////////////////// -#include "WALLY-TEST-LIB-32.S" +#include "WALLY-TEST-LIB-32.h" // Test library includes and handler for each type of test, a trap handler, imperas compliance instructions // Ideally this should mean that a test can be written by simply adding .4byte statements as below. @@ -45,70 +45,70 @@ # Test 12.3.2.2.1 Config: Write known values and set PMP config according to table 12.4 in the *** riscv book, copied below # write pmpaddr regs - # | Reg | pmpaddr | pmpcfg | L | A | X | W | R | Comments | -.4byte 0x0, 0x0FFFFFFF, 0xE # | 0 | 0x0FFFFFFF | 1F | 0 | NAPOT | 0 | 1 | 1 | I/O 00000000-7FFFFFFF RW | -.4byte 0x1, 0x20040000, 0xE # | 1 | 0x20040000 | 00 | 0 | OFF | 0 | 0 | 0 | | -.4byte 0x2, 0x2004003F, 0xE # | 2 | 0x2004003F | 09 | 0 | TOR | 0 | 0 | 1 | 80100000-801000FF R | -.4byte 0x3, 0x20040080, 0xE # | 3 | 0x20040080 | 00 | 0 | OFF | 0 | 0 | 0 | | -.4byte 0x4, 0x20040084, 0xE # | 4 | 0x20040084 | 0C | 0 | TOR | 1 | 0 | 0 | 80100200-80100210 X | -.4byte 0x5, 0x200400C0, 0xE # | 5 | 0x200400C0 | 90 | 1 | NA4 | 0 | 0 | 0 | 80100300-80100303 locked out | -.4byte 0x6, 0x2004013F, 0xE # | 6 | 0x2004013F | 18 | 0 | NAPOT | 0 | 0 | 0 | 80100400-801004FF no access | + # | Reg | pmpaddr | pmpcfg | L | A | X | W | R | Comments | +.4byte 0x0, 0x0FFFFFFF, write_pmpaddr_0 # | 0 | 0x0FFFFFFF | 1F | 0 | NAPOT | 0 | 1 | 1 | I/O 00000000-7FFFFFFF RW | +.4byte 0x1, 0x20040000, write_pmpaddr_0 # | 1 | 0x20040000 | 00 | 0 | OFF | 0 | 0 | 0 | | +.4byte 0x2, 0x2004003F, write_pmpaddr_0 # | 2 | 0x2004003F | 09 | 0 | TOR | 0 | 0 | 1 | 80100000-801000FF R | +.4byte 0x3, 0x20040080, write_pmpaddr_0 # | 3 | 0x20040080 | 00 | 0 | OFF | 0 | 0 | 0 | | +.4byte 0x4, 0x20040084, write_pmpaddr_0 # | 4 | 0x20040084 | 0C | 0 | TOR | 1 | 0 | 0 | 80100200-80100210 X | +.4byte 0x5, 0x200400C0, write_pmpaddr_0 # | 5 | 0x200400C0 | 90 | 1 | NA4 | 0 | 0 | 0 | 80100300-80100303 locked out | +.4byte 0x6, 0x2004013F, write_pmpaddr_0 # | 6 | 0x2004013F | 18 | 0 | NAPOT | 0 | 0 | 0 | 80100400-801004FF no access | # Pmpaddr 7-14 are all zeroed out in this test, so they don't need writes. -.4byte 0xF, 0x2FFFFFFF, 0xE # | 15 | 0x2FFFFFFF | 1F | 0 | NAPOT | 1 | 1 | 1 | Main mem 80000000-FFFFFFFF RWX| +.4byte 0xF, 0x2FFFFFFF, write_pmpaddr_0 # | 15 | 0x2FFFFFFF | 1F | 0 | NAPOT | 1 | 1 | 1 | Main mem 80000000-FFFFFFFF RWX| # write pmpcfg regs with the information in the table above. this should also write the value of these registers to the output. -.4byte 0x0, 0x0009001F, 0xD # write pmpcfg0, output 0x0009001F -.4byte 0x1, 0x0018900C, 0xD # write pmpcfg1, output 0x0018900C +.4byte 0x0, 0x0009001F, write_pmpcfg_0 # write pmpcfg0, output 0x0009001F +.4byte 0x1, 0x0018900C, write_pmpcfg_0 # write pmpcfg1, output 0x0018900C # pmpcfg2 is zeroed out, so it doesn't need a write -.4byte 0x3, 0x1F000000, 0xD # write pmpcfg3, output 0x1F000000 +.4byte 0x3, 0x1F000000, write_pmpcfg_0 # write pmpcfg3, output 0x1F000000 # write known values to memory where W=0. This should be possible since we're in machine mode. -.4byte 0x80100010, 0x600DAA, 0x0 # write to pmpaddr 1-2 range -.4byte 0x80100400, 0x600DBB, 0x0 # write to pmpaddr 6 range +.4byte 0x80100010, 0x600DAA, write32_test # write to pmpaddr 1-2 range +.4byte 0x80100400, 0x600DBB, write32_test # write to pmpaddr 6 range # Write executable code to regions where X = 0, 1 in main memory -.4byte 0x80100200, 0x11100393, 0x0 # write executable code for "li x7, 0x111; ret" to region with X=1 (PMP4) -.4byte 0x80100204, 0x00008067, 0x0 -.4byte 0x80100020, 0x11100393, 0x0 # write same executable code to region with X=0 (PMP2) -.4byte 0x80100024, 0x00008067, 0x0 +.4byte 0x80100200, 0x11100393, write32_test # write executable code for "li x7, 0x111; ret" to region with X=1 (PMP4) +.4byte 0x80100204, 0x00008067, write32_test +.4byte 0x80100020, 0x11100393, write32_test # write same executable code to region with X=0 (PMP2) +.4byte 0x80100024, 0x00008067, write32_test # attempt to write to pmpaddr5 and pmp5cfg after lockout -.4byte 0x1, 0x0018FF0C, 0xD # attempt to edit only pmp5cfg (pmpcfg1[8:15]) after lockout. +.4byte 0x1, 0x0018FF0C, write_pmpcfg_0 # attempt to edit only pmp5cfg (pmpcfg1[8:15]) after lockout. # instruction ignored, output is 0x0018900C, NOT 0x0018FF0C -.4byte 0x5, 0xFFFFFFFF, 0xE # attempt to edit pmpaddr5 after lockout. +.4byte 0x5, 0xFFFFFFFF, write_pmpaddr_0 # attempt to edit pmpaddr5 after lockout. # instruction ignored, output is 0x200400C0, NOT 0xFFFFFFFF # Test 12.3.2.2.2 Machine mode access -.4byte 0x80100300, 0x0, 0x1 # access fault to region with L=1, R=0. This one writes 0x5 as the mcause, not 0xd. -.4byte 0x80100400, 0x0, 0x1 # successful access to region with L=X=W=R=0 +.4byte 0x80100300, 0x0, read32_test # access fault to region with L=1, R=0. This one writes 0x5 as the mcause, not 0xd. +.4byte 0x80100400, 0x0, read32_test # successful access to region with L=X=W=R=0 # Test 12.3.2.2.3 System mode access -.4byte 0x0, 0x0, 0x9 # go to S mode. 0xb written to output +.4byte 0x0, 0x0, goto_s_mode # go to S mode. 0xb written to output # test a write followed by a read to each region with R=W=1 -.4byte 0x80200000, 0x600D15, 0x0 # Write "good value" to RW range (PMP15) -.4byte 0x80200000, 0x600D15, 0x1 # confirm write with read +.4byte 0x80200000, 0x600D15, write32_test # Write "good value" to RW range (PMP15) +.4byte 0x80200000, 0x600D15, read32_test # confirm write with read # test a write followed by a read on the edges of a read-only range -.4byte 0x800FFFF8, 0x600D02, 0x0 # Write "good value" just below read-only range (PMP2) -.4byte 0x800FFFF8, 0x600D02, 0x1 # confirm write with read -.4byte 0x80100100, 0x600D12, 0x0 # Write "good value" just above read-only range (PMP2) -.4byte 0x80100100, 0x600D12, 0x1 # confirm write with read +.4byte 0x800FFFF8, 0x600D02, write32_test # Write "good value" just below read-only range (PMP2) +.4byte 0x800FFFF8, 0x600D02, read32_test # confirm write with read +.4byte 0x80100100, 0x600D12, write32_test # Write "good value" just above read-only range (PMP2) +.4byte 0x80100100, 0x600D12, read32_test # confirm write with read # test a read from each read only range verify a write causes an access fault -.4byte 0x80100010, 0xBAD, 0x0 # Write fault in read-only range (PMP2) -.4byte 0x80100010, 0x600DAA, 0x1 # read correct value out +.4byte 0x80100010, 0xBAD, write32_test # Write fault in read-only range (PMP2) +.4byte 0x80100010, 0x600DAA, read32_test # read correct value out # test read and write fault on region with no access -.4byte 0x80100208, 0x600D15, 0x0 # Write fault on no-access range (PMP6) -.4byte 0x80100208, 0x600D15, 0x1 # read fault on no-access range (PMP6) +.4byte 0x80100208, 0x600D15, write32_test # Write fault on no-access range (PMP6) +.4byte 0x80100208, 0x600D15, read32_test # read fault on no-access range (PMP6) # test jalr to region with X=0 causes access fault -.4byte 0x80100020, 0xbad, 0x2 # execute fault on no-execute range (PMP2) +.4byte 0x80100020, 0xbad, executable_test # execute fault on no-execute range (PMP2) # test jalr to region with X=1 returns successfully -.4byte 0x80100200, 0x111, 0x2 # execute success when X=1 +.4byte 0x80100200, 0x111, executable_test # execute success when X=1 -.4byte 0x0, 0x0, 0x3 // terminate tests +.4byte 0x0, 0x0, terminate_test // terminate tests diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-TEST-LIB-32.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-TEST-LIB-32.S deleted file mode 100644 index f2b6d06a9..000000000 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-TEST-LIB-32.S +++ /dev/null @@ -1,609 +0,0 @@ -/////////////////////////////////////////// -// -// WALLY-TEST-LIB-32.S -// -// Author: Kip Macsai-Goren -// -// Created 2021-07-20 -// -// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, -// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -/////////////////////////////////////////// - -#include "model_test.h" -#include "arch_test.h" -RVTEST_ISA("RV32I") - -.section .text.init -.globl rvtest_entry_point -rvtest_entry_point: -RVMODEL_BOOT -RVTEST_CODE_BEGIN - - # --------------------------------------------------------------------------------------------- - # Initialization Overview: - # - # Initialize x6 as a virtual pointer to the test results - # Initialize x16 as a physical pointer to the test results - # Set up stack pointer (sp = x2) - # Set up the exception Handler, keeping the original handler in x4. - # - # --------------------------------------------------------------------------------------------- - - # address for test results - la x6, test_1_res - la x16, test_1_res # x16 reserved for the physical address equivalent of x6 to be used in trap handlers - # any time either is used, both must be updated. - - # address for stack - la sp, top_of_stack - - # trap handler setup - la x1, machine_trap_handler - csrrw x4, mtvec, x1 # x4 reserved for "default" trap handler address that needs to be restored before halting this test. - li a0, 0 - li a1, 0 - li a2, 0 # reset trap handler inputs to zero - - # go to first test! - j test_setup - - - # --------------------------------------------------------------------------------------------- - # General traps Handler - # - # Handles traps by branching to different behaviors based on mcause. - # - # Note that allowing the exception handler to change mode for a program is a huge security - # hole, but this is an expedient way of writing tests that need different modes - # - # input parameters: - # - # a0 (x10): - # 0: halt program with no failures - # 1: halt program with failure in x11 = a1 - # 2: go to machine mode - # 3: go to supervisor mode - # 4: go to user mode - # others: do nothing - # - # a1 (x11): - # VPN for return address after changing privilege mode. - # This should be the base VPN with no offset. - # 0x0 : defaults to next instruction on the same page the trap was called on. - # - # a2 (x12): - # Pagetype of the current address VPN before changing privilge mode - # Used so that we can know how many bits of the adress are the offset. - # Ignored if a1 == 0x0 - # 0: Kilopage - # 1: Megapage - # - # -------------------------------------------------------------------------------------------- - - -machine_trap_handler: - # The processor is always in machine mode when a trap takes us here - # save registers on stack before using - sw x1, -4(sp) - sw x5, -8(sp) - - # Record trap - csrr x1, mcause # record the mcause - sw x1, 0(x16) - addi x6, x6, 4 - addi x16, x16, 4 # update pointers for logging results - - # Respond to trap based on cause - # All interrupts should return after being logged - li x5, 0x8000000000000000 # if msb is set, it is an interrupt - and x5, x5, x1 - bnez x5, trapreturn # return from interrupt - # Other trap handling is specified in the vector Table - slli x1, x1, 2 # multiply cause by 4 to get offset in vector Table - la x5, trap_handler_vector_table - add x5, x5, x1 # compute address of vector in Table - lw x5, 0(x5) # fectch address of handler from vector Table - jr x5 # and jump to the handler - -segfault: - lw x5, -8(sp) # restore registers from stack before faulting - lw x1, -4(sp) - j terminate_test # halt program. - -trapreturn: - # look at the instruction to figure out whether to add 2 or 4 bytes to PC, or go to address specified in a1 - csrr x1, mepc # get the mepc - addi x1, x1, 4 # *** should be 2 for compressed instructions, see note. - - -# ****** KMG: the following is no longer as easy to determine. mepc gets the virtual address of the trapped instruction, -# ******** but in the handler, we work in M mode with physical addresses -# This means the address in mepc is suddenly pointing somewhere else. -# to get this to work, We could either retranslate the vaddr back into a paddr (probably on the scale of difficult to intractible) -# or we could come up with some other ingenious way to stay in M mode and see if the instruction was compressed. - -# lw x5, 0(x1) # read the faulting instruction -# li x1, 3 # check bottom 2 bits of instruction to see if compressed -# and x5, x5, x1 # mask the other bits -# beq x5, x1, trapreturn_uncompressed # if 11, the instruction is return_uncompressed - -# trapreturn_compressed: -# csrr x1, mepc # get the mepc again -# addi x1, x1, 2 # add 2 to find the next instruction -# j trapreturn_specified # and return - -# trapreturn_uncompressed: -# csrr x1, mepc # get the mepc again -# addi x1, x1, 4 # add 4 to find the next instruction - -trapreturn_specified: - # reset the necessary pointers and registers (x1, x5, x6, and the return address going to mepc) - # so that when we return to a new virtual address, they're all in the right spot as well. - - beqz a1, trapreturn_finished # either update values, of go to default return address. - - la x5, trap_return_pagetype_table - slli a2, a2, 2 - add x5, x5, a2 - lw a2, 0(x5) # a2 = number of offset bits in current page type - - li x5, 1 - sll x5, x5, a2 - addi x5, x5, -1 # x5 = mask bits for offset into current pagetype - - # reset the top of the stack, x1 - lw x7, -4(sp) - and x7, x5, x7 # x7 = offset for x1 - add x7, x7, a1 # x7 = new address for x1 - sw x7, -4(sp) - - # reset the second spot in the stack, x5 - lw x7, -8(sp) - and x7, x5, x7 # x7 = offset for x5 - add x7, x7, a1 # x7 = new address for x5 - sw x7, -8(sp) - - # reset x6, the pointer for the virtual address of the output of the tests - and x7, x5, x6 # x7 = offset for x6 - add x6, x7, a1 # x6 = new address for the result pointer - - # set return address, stored temporarily in x1, to the next instruction, but in the new virtual page. - and x1, x5, x1 # x1 = offset for the return address - add x1, x1, a1 # x1 = new return address. - - li a1, 0 - li a2, 0 # reset trapreturn inputs to the trap handler - -trapreturn_finished: - csrw mepc, x1 # update the mepc with address of next instruction - lw x5, -8(sp) # restore registers from stack before returning - lw x1, -4(sp) - mret # return from trap - -ecallhandler: - # Check input parameter a0. encoding above. - # *** ASSUMES: that this trap is being handled in machine mode. in other words, that nothing odd has been written to the medeleg or mideleg csrs. - li x5, 2 # case 2: change to machine mode - beq a0, x5, ecallhandler_changetomachinemode - li x5, 3 # case 3: change to supervisor mode - beq a0, x5, ecallhandler_changetosupervisormode - li x5, 4 # case 4: change to user mode - beq a0, x5, ecallhandler_changetousermode - # unsupported ecalls should segfault - j segfault - -ecallhandler_changetomachinemode: - # Force mstatus.MPP (bits 12:11) to 11 to enter machine mode after mret - li x1, 0b1100000000000 - csrs mstatus, x1 - j trapreturn - -ecallhandler_changetosupervisormode: - # Force mstatus.MPP (bits 12:11) to 01 to enter supervisor mode after mret - li x1, 0b1100000000000 - csrc mstatus, x1 - li x1, 0b0100000000000 - csrs mstatus, x1 - j trapreturn - -ecallhandler_changetousermode: - # Force mstatus.MPP (bits 12:11) to 00 to enter user mode after mret - li x1, 0b1100000000000 - csrc mstatus, x1 - j trapreturn - -instrfault: - lw x1, -4(sp) # load return address int x1 (the address after the jal into faulting page) - j trapreturn_finished # puts x1 into mepc, restores stack and returns to program (outside of faulting page) - -accessfault: - # *** What do I have to do here? - j trapreturn - # Table of trap behavior - # lists what to do on each exception (not interrupts) - # unexpected exceptions should cause segfaults for easy detection - # Expected exceptions should increment the EPC to the next instruction and return - - .align 2 # aligns this data table to an 4 byte boundary -trap_handler_vector_table: - .4byte segfault # 0: instruction address misaligned - .4byte instrfault # 1: instruction access fault - .4byte segfault # 2: illegal instruction - .4byte segfault # 3: breakpoint - .4byte segfault # 4: load address misaligned - .4byte accessfault # 5: load access fault - .4byte segfault # 6: store address misaligned - .4byte accessfault # 7: store access fault - .4byte ecallhandler # 8: ecall from U-mode - .4byte ecallhandler # 9: ecall from S-mode - .4byte segfault # 10: reserved - .4byte ecallhandler # 11: ecall from M-mode - .4byte instrfault # 12: instruction page fault - .4byte trapreturn # 13: load page fault - .4byte segfault # 14: reserved - .4byte trapreturn # 15: store page fault - -.align 2 -trap_return_pagetype_table: - .4byte 0xC # 0: kilopage has 12 offset bits - .4byte 0x16 # 1: megapage has 22 offset bits - - # --------------------------------------------------------------------------------------------- - # Test Handler - # - # This test handler works in a similar wy to the trap handler. It takes in a few things by reading from a table in memory - # (see test_cases) and performing certain behavior based on them. - # - # Input parameters: - # - # x28: - # Address input for the test taking place (think address to read/write, new address to return to, etc...) - # - # x29: - # Value input for the test taking place (think value to write, any other extra info needed) - # - # x30: - # Test type input that determines which kind of test will take place. Encoding for this input is in the table/case statements below - # - # ------------------------------------------------------------------------------------------------------------------------------------ - -test_setup: - la x5, test_cases - -test_loop: - lw x28, 0(x5) # fetch test case address - lw x29, 4(x5) # fetch test case value - lw x30, 8(x5) # fetch test case flag - addi x5, x5, 12 # set x5 to next test case - - slli x30, x30, 2 # multiply test type by 4 to index into jump table - la x7, test_jump_table # load base address of jump table - add x7, x7, x30 # get address of jump table entry - jr x7 # jump to relevant test - -test_jump_table: - # x30 Value : Function : Fault output value : Normal output values - # ----------:---------------------------------------:------------------------:------------------------------------------------------ - j write32_test # 0x0 : Write 32 bits to address : 0xf : None - j read32_test # 0x1 : Read 32 bits from address : 0xd, 0xbad : readvalue in hex - j executable_test # 0x2 : test executable at address : 0xc, 0xbad : leading 12 bits of the li instr written to address. In general this is 0x111. (be sure to also write a return instruction) - j terminate_test # 0x3 : terminate tests : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 - j goto_baremetal # 0x4 : satp.MODE = bare metal : None : None - j goto_sv32 # 0x5 : satp.MODE = sv32 : None : None - j segfault # 0x6 : Segfault, undefined test - j write_mxr_sum # 0x7 : write sstatus.[19:18] = MXR, SUM bits : None : None - j goto_m_mode # 0x8 : go to mahcine mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 - j goto_s_mode # 0x9 : go to supervisor mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 - j goto_u_mode # 0xA : go to user mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 - j segfault # 0xB : Segfault, undefined test - j segfault # 0xC : Segfault, undefined test - j write_pmpcfg_0 # 0xD : Write one of the pmpcfg csr's : mstatuses?, 0xD : readback of pmpcfg value - j write_pmpaddr_0 # 0xE : Write one of the pmpaddr csr's : None : readback of pmpaddr value - j segfault # 0xF : Segfault, undefined test - j segfault # 0x10 : Segfault, undefined test - j segfault # 0x11 : Segfault, undefined test - j write16_test # 0x12 : Write 16 bits to address : 0xf : None - j write08_test # 0x13 : Write 8 bits to address : 0xf : None - j segfault # 0x14 : Segfault, undefined test - j read16_test # 0x15 : Read 16 bits from address : 0xd, 0xbad : readvalue in hex - j read08_test # 0x16 : Read 8 bits from address : 0xd, 0xbad : readvalue in hex - -write32_test: - # address to write in x28, word value in x29 - sw x29, 0(x28) - j test_loop # go to next test case - -write16_test: - # address to write in x28, halfword value in x29 - sh x29, 0(x28) - j test_loop # go to next test case - -write08_test: - # address to write in x28, value in x29 - sb x29, 0(x28) - j test_loop # go to next test case - -read32_test: - # address to read in x28, expected 32 bit value in x29 (unused, but there for your perusal). - li x7, 0xBAD # bad value that will be overwritten on good reads. - lw x7, 0(x28) - sw x7, 0(x6) - addi x6, x6, 4 - addi x16, x16, 4 - j test_loop # go to next test case - -read16_test: - # address to read in x28, expected 16 bit value in x29 (unused, but there for your perusal). - li x7, 0xBAD # bad value that will be overwritten on good reads. - lh x7, 0(x28) - sw x7, 0(x6) - addi x6, x6, 4 - addi x16, x16, 4 - j test_loop # go to next test case - -read08_test: - # address to read in x28, expected 8 bit value in x29 (unused, but there for your perusal). - li x7, 0xBAD # bad value that will be overwritten on good reads. - lb x7, 0(x28) - sw x7, 0(x6) - addi x6, x6, 4 - addi x16, x16, 4 - j test_loop # go to next test case - - -goto_s_mode: - li a0, 3 # Trap handler behavior (go to machine mode) - mv a1, x28 # return VPN - mv a2, x29 # return page types - ecall # writes mcause to the output. - # now in S mode - j test_loop - -goto_m_mode: - li a0, 2 # Trap handler behavior (go to machine mode) - mv a1, x28 # return VPN - mv a2, x29 # return page types - ecall # writes mcause to the output. - j test_loop - -goto_u_mode: - li a0, 4 # Trap handler behavior (go to user mode) - mv a1, x28 # return VPN - mv a2, x29 # return page types - ecall # writes mcause to the output. - j test_loop - -goto_baremetal: - # Turn translation off - li x7, 0 # satp.MODE value for bare metal (0) - slli x7, x7, 31 - li x28, 0x8000D # Base Pagetable physical page number, satp.PPN field. - add x7, x7, x28 - csrw satp, x7 - sfence.vma x0, x0 # *** flushes global pte's as well. Be careful - j test_loop # go to next test case - -goto_sv32: - li x7, 1 # satp.MODE value for Sv39 (1) - slli x7, x7, 31 - li x28, 0x8000D # Base Pagetable physical page number, satp.PPN field. - add x7, x7, x28 - csrw satp, x7 - sfence.vma x0, x0 # *** flushes global pte's as well. Be careful - j test_loop # go to next test case - -write_mxr_sum: - # writes sstatus.[mxr, sum] with the (assumed to be) 2 bit value in x29. also assumes we're in S. M mode - li x30, 0xC0000 # mask bits for MXR, SUM - not x7, x29 - slli x7, x7, 18 - and x7, x7, x30 - slli x29, x29, 18 - csrc sstatus, x7 - csrs sstatus, x29 - j test_loop - -write_pmpcfg_0: - # writes the value in x29 to the pmpcfg register specified in x28. - li x7, 0x0 - bne x7, x28, write_pmpcfg_1 - csrw pmpcfg0, x29 - csrr x30, pmpcfg0 -write_pmpcfg_1: - li x7, 0x1 - bne x7, x28, write_pmpcfg_2 - csrw pmpcfg1, x29 - csrr x30, pmpcfg1 -write_pmpcfg_2: - li x7, 0x2 - bne x7, x28, write_pmpcfg_3 - csrw pmpcfg2, x29 - csrr x30, pmpcfg2 -write_pmpcfg_3: - li x7, 0x3 - bne x7, x28, write_pmpcfg_end - csrw pmpcfg3, x29 - csrr x30, pmpcfg3 -write_pmpcfg_end: - sw x30, 0(x6) - addi x6, x6, 4 - addi x16, x16, 4 - j test_loop - -write_pmpaddr_0: - # writes the value in x29 to the pmpaddr register specified in x28. - # then writes the final value of pmpaddrX to the output. - li x7, 0x0 - bne x7, x28, write_pmpaddr_1 - csrw pmpaddr0, x29 - csrr x30, pmpaddr0 - j write_pmpaddr_end -write_pmpaddr_1: - li x7, 0x1 - bne x7, x28, write_pmpaddr_2 - csrw pmpaddr1, x29 - csrr x30, pmpaddr1 - j write_pmpaddr_end -write_pmpaddr_2: - li x7, 0x2 - bne x7, x28, write_pmpaddr_3 - csrw pmpaddr2, x29 - csrr x30, pmpaddr2 - j write_pmpaddr_end -write_pmpaddr_3: - li x7, 0x3 - bne x7, x28, write_pmpaddr_4 - csrw pmpaddr3, x29 - csrr x30, pmpaddr3 - j write_pmpaddr_end -write_pmpaddr_4: - li x7, 0x4 - bne x7, x28, write_pmpaddr_5 - csrw pmpaddr4, x29 - csrr x30, pmpaddr4 - j write_pmpaddr_end -write_pmpaddr_5: - li x7, 0x5 - bne x7, x28, write_pmpaddr_6 - csrw pmpaddr5, x29 - csrr x30, pmpaddr5 - j write_pmpaddr_end -write_pmpaddr_6: - li x7, 0x6 - bne x7, x28, write_pmpaddr_7 - csrw pmpaddr6, x29 - csrr x30, pmpaddr6 - j write_pmpaddr_end -write_pmpaddr_7: - li x7, 0x7 - bne x7, x28, write_pmpaddr_8 - csrw pmpaddr7, x29 - csrr x30, pmpaddr7 - j write_pmpaddr_end -write_pmpaddr_8: - li x7, 0x8 - bne x7, x28, write_pmpaddr_9 - csrw pmpaddr8, x29 - csrr x30, pmpaddr8 - j write_pmpaddr_end -write_pmpaddr_9: - li x7, 0x9 - bne x7, x28, write_pmpaddr_10 - csrw pmpaddr9, x29 - csrr x30, pmpaddr9 - j write_pmpaddr_end -write_pmpaddr_10: - li x7, 0xA - bne x7, x28, write_pmpaddr_11 - csrw pmpaddr10, x29 - csrr x30, pmpaddr10 - j write_pmpaddr_end -write_pmpaddr_11: - li x7, 0xB - bne x7, x28, write_pmpaddr_12 - csrw pmpaddr11, x29 - csrr x30, pmpaddr11 - j write_pmpaddr_end -write_pmpaddr_12: - li x7, 0xC - bne x7, x28, write_pmpaddr_13 - csrw pmpaddr12, x29 - csrr x30, pmpaddr12 - j write_pmpaddr_end -write_pmpaddr_13: - li x7, 0xD - bne x7, x28, write_pmpaddr_14 - csrw pmpaddr13, x29 - csrr x30, pmpaddr13 - j write_pmpaddr_end -write_pmpaddr_14: - li x7, 0xE - bne x7, x28, write_pmpaddr_15 - csrw pmpaddr14, x29 - csrr x30, pmpaddr14 - j write_pmpaddr_end -write_pmpaddr_15: - li x7, 0xF - bne x7, x28, write_pmpaddr_end - csrw pmpaddr15, x29 - csrr x30, pmpaddr15 - j write_pmpaddr_end -write_pmpaddr_end: - sw x30, 0(x6) - addi x6, x6, 4 - addi x16, x16, 4 - j test_loop - -executable_test: - # Execute the code at the address in x28, returning the value in x7. - # Assumes the code modifies x7, to become the value stored in x29 for this test. - fence.i # forces cache and main memory to sync so execution code written by the program can run. - li x7, 0xBAD - jalr x28 - sw x7, 0(x6) - addi x6, x6, 4 - addi x16, x16, 4 - j test_loop - - - -terminate_test: - - li a0, 2 # Trap handler behavior (go to machine mode) - ecall # writes mcause to the output. - csrw mtvec, x4 # restore original trap handler to halt program - - -RVTEST_CODE_END -RVMODEL_HALT - -RVTEST_DATA_BEGIN -.align 4 -rvtest_data: -.word 0xbabecafe -RVTEST_DATA_END - -.align 2 # align stack to 4 byte boundary -bottom_of_stack: - .fill 1024, 4, 0xdeadbeef -top_of_stack: - - - -RVMODEL_DATA_BEGIN - -// next lines through test cases copied over from old framework -test_1_res: - .fill 1024, 4, 0xdeadbeef - -RVMODEL_DATA_END - -#ifdef rvtest_mtrap_routine - -mtrap_sigptr: - .fill 64*(XLEN/32),4,0xdeadbeef - -#endif - -#ifdef rvtest_gpr_save - -gpr_save: - .fill 32*(XLEN/32),4,0xdeadbeef - -#endif - -.align 2 -test_cases: - diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-TEST-LIB-32.h b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-TEST-LIB-32.h new file mode 100644 index 000000000..31bd11940 --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-TEST-LIB-32.h @@ -0,0 +1,607 @@ +/////////////////////////////////////////// +// +// WALLY-TEST-LIB-32.S +// +// Author: Kip Macsai-Goren +// +// Created 2021-07-20 +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV32I") + +.section .text.init +.globl rvtest_entry_point +rvtest_entry_point: +RVMODEL_BOOT +RVTEST_CODE_BEGIN + + // --------------------------------------------------------------------------------------------- + // Initialization Overview: + // + // Initialize x6 as a virtual pointer to the test results + // Initialize x16 as a physical pointer to the test results + // Set up stack pointer (sp = x2) + // Set up the exception Handler, keeping the original handler in x4. + // + // --------------------------------------------------------------------------------------------- + + // address for test results + la x6, test_1_res + la x16, test_1_res // x16 reserved for the physical address equivalent of x6 to be used in trap handlers + // any time either is used, both must be updated. + + // address for stack + la sp, top_of_stack + + // trap handler setup + la x1, machine_trap_handler + csrrw x4, mtvec, x1 // x4 reserved for "default" trap handler address that needs to be restored before halting this test. + li a0, 0 + li a1, 0 + li a2, 0 // reset trap handler inputs to zero + + // go to first test! + j test_setup + + + // --------------------------------------------------------------------------------------------- + // General traps Handler + // + // Handles traps by branching to different behaviors based on mcause. + // + // Note that allowing the exception handler to change mode for a program is a huge security + // hole, but this is an expedient way of writing tests that need different modes + // + // input parameters: + // + // a0 (x10): + // 0: halt program with no failures + // 1: halt program with failure in x11 = a1 + // 2: go to machine mode + // 3: go to supervisor mode + // 4: go to user mode + // others: do nothing + // + // a1 (x11): + // VPN for return address after changing privilege mode. + // This should be the base VPN with no offset. + // 0x0 : defaults to next instruction on the same page the trap was called on. + // + // a2 (x12): + // Pagetype of the current address VPN before changing privilge mode + // Used so that we can know how many bits of the adress are the offset. + // Ignored if a1 == 0x0 + // 0: Kilopage + // 1: Megapage + // + // -------------------------------------------------------------------------------------------- + + +machine_trap_handler: + // The processor is always in machine mode when a trap takes us here + // save registers on stack before using + sw x1, -4(sp) + sw x5, -8(sp) + + // Record trap + csrr x1, mcause // record the mcause + sw x1, 0(x16) + addi x6, x6, 4 + addi x16, x16, 4 // update pointers for logging results + + // Respond to trap based on cause + // All interrupts should return after being logged + li x5, 0x8000000000000000 // if msb is set, it is an interrupt + and x5, x5, x1 + bnez x5, trapreturn // return from interrupt + // Other trap handling is specified in the vector Table + slli x1, x1, 2 // multiply cause by 4 to get offset in vector Table + la x5, trap_handler_vector_table + add x5, x5, x1 // compute address of vector in Table + lw x5, 0(x5) // fectch address of handler from vector Table + jr x5 // and jump to the handler + +segfault: + lw x5, -8(sp) // restore registers from stack before faulting + lw x1, -4(sp) + j terminate_test // halt program. + +trapreturn: + // look at the instruction to figure out whether to add 2 or 4 bytes to PC, or go to address specified in a1 + csrr x1, mepc // get the mepc + addi x1, x1, 4 // *** should be 2 for compressed instructions, see note. + + +// ****** KMG: the following is no longer as easy to determine. mepc gets the virtual address of the trapped instruction, +// ******** but in the handler, we work in M mode with physical addresses +// This means the address in mepc is suddenly pointing somewhere else. +// to get this to work, We could either retranslate the vaddr back into a paddr (probably on the scale of difficult to intractible) +// or we could come up with some other ingenious way to stay in M mode and see if the instruction was compressed. + +// lw x5, 0(x1) // read the faulting instruction +// li x1, 3 // check bottom 2 bits of instruction to see if compressed +// and x5, x5, x1 // mask the other bits +// beq x5, x1, trapreturn_uncompressed // if 11, the instruction is return_uncompressed + +// trapreturn_compressed: +// csrr x1, mepc // get the mepc again +// addi x1, x1, 2 // add 2 to find the next instruction +// j trapreturn_specified // and return + +// trapreturn_uncompressed: +// csrr x1, mepc // get the mepc again +// addi x1, x1, 4 // add 4 to find the next instruction + +trapreturn_specified: + // reset the necessary pointers and registers (x1, x5, x6, and the return address going to mepc) + // so that when we return to a new virtual address, they're all in the right spot as well. + + beqz a1, trapreturn_finished // either update values, of go to default return address. + + la x5, trap_return_pagetype_table + slli a2, a2, 2 + add x5, x5, a2 + lw a2, 0(x5) // a2 = number of offset bits in current page type + + li x5, 1 + sll x5, x5, a2 + addi x5, x5, -1 // x5 = mask bits for offset into current pagetype + + // reset the top of the stack, x1 + lw x7, -4(sp) + and x7, x5, x7 // x7 = offset for x1 + add x7, x7, a1 // x7 = new address for x1 + sw x7, -4(sp) + + // reset the second spot in the stack, x5 + lw x7, -8(sp) + and x7, x5, x7 // x7 = offset for x5 + add x7, x7, a1 // x7 = new address for x5 + sw x7, -8(sp) + + // reset x6, the pointer for the virtual address of the output of the tests + and x7, x5, x6 // x7 = offset for x6 + add x6, x7, a1 // x6 = new address for the result pointer + + // set return address, stored temporarily in x1, to the next instruction, but in the new virtual page. + and x1, x5, x1 // x1 = offset for the return address + add x1, x1, a1 // x1 = new return address. + + li a1, 0 + li a2, 0 // reset trapreturn inputs to the trap handler + +trapreturn_finished: + csrw mepc, x1 // update the mepc with address of next instruction + lw x5, -8(sp) // restore registers from stack before returning + lw x1, -4(sp) + mret // return from trap + +ecallhandler: + // Check input parameter a0. encoding above. + // *** ASSUMES: that this trap is being handled in machine mode. in other words, that nothing odd has been written to the medeleg or mideleg csrs. + li x5, 2 // case 2: change to machine mode + beq a0, x5, ecallhandler_changetomachinemode + li x5, 3 // case 3: change to supervisor mode + beq a0, x5, ecallhandler_changetosupervisormode + li x5, 4 // case 4: change to user mode + beq a0, x5, ecallhandler_changetousermode + // unsupported ecalls should segfault + j segfault + +ecallhandler_changetomachinemode: + // Force mstatus.MPP (bits 12:11) to 11 to enter machine mode after mret + li x1, 0b1100000000000 + csrs mstatus, x1 + j trapreturn + +ecallhandler_changetosupervisormode: + // Force mstatus.MPP (bits 12:11) to 01 to enter supervisor mode after mret + li x1, 0b1100000000000 + csrc mstatus, x1 + li x1, 0b0100000000000 + csrs mstatus, x1 + j trapreturn + +ecallhandler_changetousermode: + // Force mstatus.MPP (bits 12:11) to 00 to enter user mode after mret + li x1, 0b1100000000000 + csrc mstatus, x1 + j trapreturn + +instrfault: + lw x1, -4(sp) // load return address int x1 (the address after the jal into faulting page) + j trapreturn_finished // puts x1 into mepc, restores stack and returns to program (outside of faulting page) + +accessfault: + // *** What do I have to do here? + j trapreturn + // Table of trap behavior + // lists what to do on each exception (not interrupts) + // unexpected exceptions should cause segfaults for easy detection + // Expected exceptions should increment the EPC to the next instruction and return + + .align 2 // aligns this data table to an 4 byte boundary +trap_handler_vector_table: + .4byte segfault // 0: instruction address misaligned + .4byte instrfault // 1: instruction access fault + .4byte segfault // 2: illegal instruction + .4byte segfault // 3: breakpoint + .4byte segfault // 4: load address misaligned + .4byte accessfault // 5: load access fault + .4byte segfault // 6: store address misaligned + .4byte accessfault // 7: store access fault + .4byte ecallhandler // 8: ecall from U-mode + .4byte ecallhandler // 9: ecall from S-mode + .4byte segfault // 10: reserved + .4byte ecallhandler // 11: ecall from M-mode + .4byte instrfault // 12: instruction page fault + .4byte trapreturn // 13: load page fault + .4byte segfault // 14: reserved + .4byte trapreturn // 15: store page fault + +.align 2 +trap_return_pagetype_table: + .4byte 0xC // 0: kilopage has 12 offset bits + .4byte 0x16 // 1: megapage has 22 offset bits + + // --------------------------------------------------------------------------------------------- + // Test Handler + // + // This test handler works in a similar wy to the trap handler. It takes in a few things by reading from a table in memory + // (see test_cases) and performing certain behavior based on them. + // + // Input parameters: + // + // x28: + // Address input for the test taking place (think address to read/write, new address to return to, etc...) + // + // x29: + // Value input for the test taking place (think value to write, any other extra info needed) + // + // x30: + // Test type input that determines which kind of test will take place. Encoding for this input is in the table/case statements below + // + // ------------------------------------------------------------------------------------------------------------------------------------ + +test_setup: + la x5, test_cases + +test_loop: + lw x28, 0(x5) // fetch test case address + lw x29, 4(x5) // fetch test case value + lw x30, 8(x5) // fetch test case flag + addi x5, x5, 12 // set x5 to next test case + + // x5 has the symbol for a test's location in the assembly + li x7, 0x3FFFFF + and x30, x30, x7 // This program is always on at least a megapage, so this masks out the megapage offset. + auipc x7, 0x0 + srli x7, x7, 22 + slli x7, x7, 22 // zero out the bottom 22 bits so the megapage offset of the symbol can be placed there + or x30, x7, x30 // x30 = virtual address of the symbol for this type of test. + + jr x30 + +// Test Name : Description : Fault output value : Normal output values +// ----------------------:---------------------------------------:------------------------:------------------------------------------------------ +// write32_test : Write 32 bits to address : 0xf : None +// write16_test : Write 16 bits to address : 0xf : None +// write08_test : Write 8 bits to address : 0xf : None +// read32_test : Read 32 bits from address : 0xd, 0xbad : readvalue in hex +// read16_test : Read 16 bits from address : 0xd, 0xbad : readvalue in hex +// read08_test : Read 8 bits from address : 0xd, 0xbad : readvalue in hex +// executable_test : test executable at address : 0xc, 0xbad : leading 12 bits of the li instr written to address. In general this is 0x111. (be sure to also write a return instruction) +// terminate_test : terminate tests : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 +// goto_baremetal : satp.MODE = bare metal : None : None +// goto_sv32 : satp.MODE = sv32 : None : None +// write_mxr_sum : write sstatus.[19:18] = MXR, SUM bits : None : None +// goto_m_mode : go to mahcine mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 +// goto_s_mode : go to supervisor mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 +// goto_u_mode : go to user mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 +// write_pmpcfg_x : Write one of the pmpcfg csr's : mstatuses?, 0xD : readback of pmpcfg value +// write_pmpaddr_x : Write one of the pmpaddr csr's : None : readback of pmpaddr value + + +write32_test: + // address to write in x28, word value in x29 + sw x29, 0(x28) + j test_loop // go to next test case + +write16_test: + // address to write in x28, halfword value in x29 + sh x29, 0(x28) + j test_loop // go to next test case + +write08_test: + // address to write in x28, value in x29 + sb x29, 0(x28) + j test_loop // go to next test case + +read32_test: + // address to read in x28, expected 32 bit value in x29 (unused, but there for your perusal). + li x7, 0xBAD // bad value that will be overwritten on good reads. + lw x7, 0(x28) + sw x7, 0(x6) + addi x6, x6, 4 + addi x16, x16, 4 + j test_loop // go to next test case + +read16_test: + // address to read in x28, expected 16 bit value in x29 (unused, but there for your perusal). + li x7, 0xBAD // bad value that will be overwritten on good reads. + lh x7, 0(x28) + sw x7, 0(x6) + addi x6, x6, 4 + addi x16, x16, 4 + j test_loop // go to next test case + +read08_test: + // address to read in x28, expected 8 bit value in x29 (unused, but there for your perusal). + li x7, 0xBAD // bad value that will be overwritten on good reads. + lb x7, 0(x28) + sw x7, 0(x6) + addi x6, x6, 4 + addi x16, x16, 4 + j test_loop // go to next test case + + +goto_s_mode: + li a0, 3 // Trap handler behavior (go to machine mode) + mv a1, x28 // return VPN + mv a2, x29 // return page types + ecall // writes mcause to the output. + // now in S mode + j test_loop + +goto_m_mode: + li a0, 2 // Trap handler behavior (go to machine mode) + mv a1, x28 // return VPN + mv a2, x29 // return page types + ecall // writes mcause to the output. + j test_loop + +goto_u_mode: + li a0, 4 // Trap handler behavior (go to user mode) + mv a1, x28 // return VPN + mv a2, x29 // return page types + ecall // writes mcause to the output. + j test_loop + +goto_baremetal: + // Turn translation off + li x7, 0 // satp.MODE value for bare metal (0) + slli x7, x7, 31 + li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. + add x7, x7, x28 + csrw satp, x7 + sfence.vma x0, x0 // *** flushes global pte's as well. Be careful + j test_loop // go to next test case + +goto_sv32: + li x7, 1 // satp.MODE value for Sv39 (1) + slli x7, x7, 31 + li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. + add x7, x7, x28 + csrw satp, x7 + sfence.vma x0, x0 // *** flushes global pte's as well. Be careful + j test_loop // go to next test case + +write_mxr_sum: + // writes sstatus.[mxr, sum] with the (assumed to be) 2 bit value in x29. also assumes we're in S. M mode + li x30, 0xC0000 // mask bits for MXR, SUM + not x7, x29 + slli x7, x7, 18 + and x7, x7, x30 + slli x29, x29, 18 + csrc sstatus, x7 + csrs sstatus, x29 + j test_loop + +write_pmpcfg_0: + // writes the value in x29 to the pmpcfg register specified in x28. + li x7, 0x0 + bne x7, x28, write_pmpcfg_1 + csrw pmpcfg0, x29 + csrr x30, pmpcfg0 +write_pmpcfg_1: + li x7, 0x1 + bne x7, x28, write_pmpcfg_2 + csrw pmpcfg1, x29 + csrr x30, pmpcfg1 +write_pmpcfg_2: + li x7, 0x2 + bne x7, x28, write_pmpcfg_3 + csrw pmpcfg2, x29 + csrr x30, pmpcfg2 +write_pmpcfg_3: + li x7, 0x3 + bne x7, x28, write_pmpcfg_end + csrw pmpcfg3, x29 + csrr x30, pmpcfg3 +write_pmpcfg_end: + sw x30, 0(x6) + addi x6, x6, 4 + addi x16, x16, 4 + j test_loop + +write_pmpaddr_0: + // writes the value in x29 to the pmpaddr register specified in x28. + // then writes the final value of pmpaddrX to the output. + li x7, 0x0 + bne x7, x28, write_pmpaddr_1 + csrw pmpaddr0, x29 + csrr x30, pmpaddr0 + j write_pmpaddr_end +write_pmpaddr_1: + li x7, 0x1 + bne x7, x28, write_pmpaddr_2 + csrw pmpaddr1, x29 + csrr x30, pmpaddr1 + j write_pmpaddr_end +write_pmpaddr_2: + li x7, 0x2 + bne x7, x28, write_pmpaddr_3 + csrw pmpaddr2, x29 + csrr x30, pmpaddr2 + j write_pmpaddr_end +write_pmpaddr_3: + li x7, 0x3 + bne x7, x28, write_pmpaddr_4 + csrw pmpaddr3, x29 + csrr x30, pmpaddr3 + j write_pmpaddr_end +write_pmpaddr_4: + li x7, 0x4 + bne x7, x28, write_pmpaddr_5 + csrw pmpaddr4, x29 + csrr x30, pmpaddr4 + j write_pmpaddr_end +write_pmpaddr_5: + li x7, 0x5 + bne x7, x28, write_pmpaddr_6 + csrw pmpaddr5, x29 + csrr x30, pmpaddr5 + j write_pmpaddr_end +write_pmpaddr_6: + li x7, 0x6 + bne x7, x28, write_pmpaddr_7 + csrw pmpaddr6, x29 + csrr x30, pmpaddr6 + j write_pmpaddr_end +write_pmpaddr_7: + li x7, 0x7 + bne x7, x28, write_pmpaddr_8 + csrw pmpaddr7, x29 + csrr x30, pmpaddr7 + j write_pmpaddr_end +write_pmpaddr_8: + li x7, 0x8 + bne x7, x28, write_pmpaddr_9 + csrw pmpaddr8, x29 + csrr x30, pmpaddr8 + j write_pmpaddr_end +write_pmpaddr_9: + li x7, 0x9 + bne x7, x28, write_pmpaddr_10 + csrw pmpaddr9, x29 + csrr x30, pmpaddr9 + j write_pmpaddr_end +write_pmpaddr_10: + li x7, 0xA + bne x7, x28, write_pmpaddr_11 + csrw pmpaddr10, x29 + csrr x30, pmpaddr10 + j write_pmpaddr_end +write_pmpaddr_11: + li x7, 0xB + bne x7, x28, write_pmpaddr_12 + csrw pmpaddr11, x29 + csrr x30, pmpaddr11 + j write_pmpaddr_end +write_pmpaddr_12: + li x7, 0xC + bne x7, x28, write_pmpaddr_13 + csrw pmpaddr12, x29 + csrr x30, pmpaddr12 + j write_pmpaddr_end +write_pmpaddr_13: + li x7, 0xD + bne x7, x28, write_pmpaddr_14 + csrw pmpaddr13, x29 + csrr x30, pmpaddr13 + j write_pmpaddr_end +write_pmpaddr_14: + li x7, 0xE + bne x7, x28, write_pmpaddr_15 + csrw pmpaddr14, x29 + csrr x30, pmpaddr14 + j write_pmpaddr_end +write_pmpaddr_15: + li x7, 0xF + bne x7, x28, write_pmpaddr_end + csrw pmpaddr15, x29 + csrr x30, pmpaddr15 + j write_pmpaddr_end +write_pmpaddr_end: + sw x30, 0(x6) + addi x6, x6, 4 + addi x16, x16, 4 + j test_loop + +executable_test: + // Execute the code at the address in x28, returning the value in x7. + // Assumes the code modifies x7, to become the value stored in x29 for this test. + fence.i // forces cache and main memory to sync so execution code written by the program can run. + li x7, 0xBAD + jalr x28 + sw x7, 0(x6) + addi x6, x6, 4 + addi x16, x16, 4 + j test_loop + + + +terminate_test: + + li a0, 2 // Trap handler behavior (go to machine mode) + ecall // writes mcause to the output. + csrw mtvec, x4 // restore original trap handler to halt program + + +RVTEST_CODE_END +RVMODEL_HALT + +RVTEST_DATA_BEGIN +.align 4 +rvtest_data: +.word 0xbabecafe +RVTEST_DATA_END + +.align 2 // align stack to 4 byte boundary +bottom_of_stack: + .fill 1024, 4, 0xdeadbeef +top_of_stack: + + + +RVMODEL_DATA_BEGIN + +// next lines through test cases copied over from old framework +test_1_res: + .fill 1024, 4, 0xdeadbeef + +RVMODEL_DATA_END + +#ifdef rvtest_mtrap_routine + +mtrap_sigptr: + .fill 64*(XLEN/32),4,0xdeadbeef + +#endif + +#ifdef rvtest_gpr_save + +gpr_save: + .fill 32*(XLEN/32),4,0xdeadbeef + +#endif + +.align 2 +test_cases: + diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/Makefrag b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/Makefrag index 224e9dbbb..aa30cdc79 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/Makefrag +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/Makefrag @@ -30,7 +30,8 @@ rv64i_sc_tests = \ WALLY-MMU-SV39 \ WALLY-MMU-SV48 \ - WALLY-PMP + WALLY-PMP \ + WALLY-minfo-01 target_tests_nosim = WALLY-PMA \ diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-minfo-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-minfo-01.reference_output new file mode 100644 index 000000000..880d5dc82 --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-minfo-01.reference_output @@ -0,0 +1,1024 @@ +00000002 +00000000 +00000011 +00000000 +00000002 +00000000 +00000011 +00000000 +00000002 +00000000 +00000011 +00000000 +00000002 +00000000 +00000011 +00000000 +0000000b +00000000 +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef +deadbeef diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-MMU-SV39.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-MMU-SV39.S index f42afc690..39ca0a257 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-MMU-SV39.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-MMU-SV39.S @@ -21,7 +21,7 @@ // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /////////////////////////////////////////// -#include "WALLY-TEST-LIB-64.S" +#include "WALLY-TEST-LIB-64.h" // Test library includes and handler for each type of test, a trap handler, imperas compliance instructions // Ideally this should mean that a test can be written by simply adding .8byte statements as below. @@ -44,126 +44,126 @@ # test 12.3.1.1.1 write page tables / entries to phyiscal memory # sv39 page table (See Figure 12.12***): # Level 2 page table, situated at 0x8000D000 -.8byte 0x000000008000D000, 0x0000000020004C01, 0x0 # points to level 1 page table A -.8byte 0x000000008000D008, 0x0000000020005001, 0x0 # points to level 1 page table B #*** replacing all the pointers DAU bits with 0. -.8byte 0x000000008000D010, 0x00000000200000CF, 0x0 # Vaddr 0x8000_0000, Paddr 0x80000000: aligned gigapage (program and data memory) -.8byte 0x000000008000D018, 0x00004000004000C7, 0x0 # Vaddr 0xC000_0000: misaligned gigapage -.8byte 0x000000008000DFF8, 0x0000000020005401, 0x0 # points to level 1 page table C +.8byte 0x000000008000D000, 0x0000000020004C01, write64_test# points to level 1 page table A +.8byte 0x000000008000D008, 0x0000000020005001, write64_test# points to level 1 page table B #*** replacing all the pointers DAU bits with 0. +.8byte 0x000000008000D010, 0x00000000200000CF, write64_test# Vaddr 0x8000_0000, Paddr 0x80000000: aligned gigapage (program and data memory) +.8byte 0x000000008000D018, 0x00004000004000C7, write64_test# Vaddr 0xC000_0000: misaligned gigapage +.8byte 0x000000008000DFF8, 0x0000000020005401, write64_test # points to level 1 page table C # Level 1 page table A -.8byte 0x0000000080013000, 0x0000000020006001, 0x0 # points to level 0 page table A +.8byte 0x0000000080013000, 0x0000000020006001, write64_test# points to level 0 page table A # Level 1 page table B -.8byte 0x0000000080014000, 0x00000000200000CB, 0x0 # Vaddr 0x4000_0000, Paddr 0x80000000: aligned megapage, W=0, used for execution tests -.8byte 0x0000000080014008, 0x00000400000080C3, 0x0 # Vaddr 0x4020_0000: misaligned megapage -.8byte 0x0000000080014010, 0x00000000200000DF, 0x0 # Vaddr 0x4040_0000, Paddr 0x80000000: aligned megapage, aliased with program, U=1 -.8byte 0x0000000080014018, 0x00000000210800C9, 0x0 # Vaddr 0x4060_0000, Paddr 0x84200000: R=0, reads should fault +.8byte 0x0000000080014000, 0x00000000200000CB, write64_test# Vaddr 0x4000_0000, Paddr 0x80000000: aligned megapage, W=0, used for execution tests +.8byte 0x0000000080014008, 0x00000400000080C3, write64_test# Vaddr 0x4020_0000: misaligned megapage +.8byte 0x0000000080014010, 0x00000000200000DF, write64_test# Vaddr 0x4040_0000, Paddr 0x80000000: aligned megapage, aliased with program, U=1 +.8byte 0x0000000080014018, 0x00000000210800C9, write64_test# Vaddr 0x4060_0000, Paddr 0x84200000: R=0, reads should fault # Level 1 page table C -.8byte 0x0000000080015FF8, 0x0000000020005801, 0x0 # points to level 0 page table B +.8byte 0x0000000080015FF8, 0x0000000020005801, write64_test# points to level 0 page table B # Level 0 page table A -.8byte 0x0000000080018000, 0x00000000200070D1, 0x0 # Vaddr 0x0000: bad PTE points to level -1 table -.8byte 0x0000000080018008, 0x00000000200800DF, 0x0 # Vaddr 0x1000, Paddr = 0x80200000: aligned kilopage -.8byte 0x0000000080018010, 0x00000000200810D5, 0x0 # Vaddr 0x2000: bad PTE has W but not R -.8byte 0x0000000080018018, 0x0000000020080817, 0x0 # Vaddr 0x3000 Paddr 0x80202000: A=0, should cause read fault -.8byte 0x0000000080018020, 0x0000000020080C57, 0x0 # Vaddr 0x4000 Paddr 0x80203000: D=0, should cause write fault -.8byte 0x0000000080018028, 0x00000000200814C7, 0x0 # Vaddr 0x5000 Paddr 0x80205000: X=0, fetches should fault -.8byte 0x0000000080018030, 0x00000000200814C0, 0x0 # Vaddr 0x6000: invalid page +.8byte 0x0000000080018000, 0x00000000200070D1, write64_test# Vaddr 0x0000: bad PTE points to level -1 table +.8byte 0x0000000080018008, 0x00000000200800DF, write64_test# Vaddr 0x1000, Paddr = 0x80200000: aligned kilopage +.8byte 0x0000000080018010, 0x00000000200810D5, write64_test# Vaddr 0x2000: bad PTE has W but not R +.8byte 0x0000000080018018, 0x0000000020080817, write64_test# Vaddr 0x3000 Paddr 0x80202000: A=0, should cause read fault +.8byte 0x0000000080018020, 0x0000000020080C57, write64_test# Vaddr 0x4000 Paddr 0x80203000: D=0, should cause write fault +.8byte 0x0000000080018028, 0x00000000200814C7, write64_test# Vaddr 0x5000 Paddr 0x80205000: X=0, fetches should fault +.8byte 0x0000000080018030, 0x00000000200814C0, write64_test# Vaddr 0x6000: invalid page # Level 0 page table B -.8byte 0x0000000080016FF8, 0x00000000200804CF, 0x0 # Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000 aligned kilopage +.8byte 0x0000000080016FF8, 0x00000000200804CF, write64_test# Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000 aligned kilopage # test 12.3.1.1.2 write values to Paddrs in each page # each of these values is used for 12.3.1.1.3 and some other tests, specified in the comments. # when a test is supposed to fault, nothing is written into where it'll be reading/executing since it shuold fault before getting there. -.8byte 0x80200AB0, 0x0000DEADBEEF0000, 0x0 # 12.3.1.1.4 -.8byte 0x800FFAB8, 0x0880DEADBEEF0055, 0x0 # 12.3.1.1.4 -.8byte 0x80200AC0, 0x0990DEADBEEF0033, 0x0 # 12.3.1.3.2 -.8byte 0x80203130, 0x0110DEADBEEF0077, 0x0 # 12.3.1.3.2 -.8byte 0x80099000, 0x0000806711100393, 0x0 # 12.3.1.3.1 and 12.3.1.3.2 write executable code for "li x7, 0x111; ret" -.8byte 0x80205AA0, 0x0000806711100393, 0x0 # 12.3.1.3.5 write same executable code -.8byte 0x80201888, 0x0220DEADBEEF0099, 0x0 # 12.3.1.1.4 -.8byte 0x84212348, 0x0330DEADBEEF0440, 0x0 # 12.3.1.3.3 -.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, 0x0 # 12.3.1.3.7 +.8byte 0x80200AB0, 0x0000DEADBEEF0000, write64_test# 12.3.1.1.4 +.8byte 0x800FFAB8, 0x0880DEADBEEF0055, write64_test# 12.3.1.1.4 +.8byte 0x80200AC0, 0x0990DEADBEEF0033, write64_test# 12.3.1.3.2 +.8byte 0x80203130, 0x0110DEADBEEF0077, write64_test# 12.3.1.3.2 +.8byte 0x80099000, 0x0000806711100393, write64_test# 12.3.1.3.1 and 12.3.1.3.2 write executable code for "li x7, 0x111; ret" +.8byte 0x80205AA0, 0x0000806711100393, write64_test# 12.3.1.3.5 write same executable code +.8byte 0x80201888, 0x0220DEADBEEF0099, write64_test# 12.3.1.1.4 +.8byte 0x84212348, 0x0330DEADBEEF0440, write64_test# 12.3.1.3.3 +.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, write64_test# 12.3.1.3.7 # test 12.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test) -.8byte 0x0, 0x0, 0x4 # satp.MODE = baremetal / no translation. -.8byte 0x0, 0x0, 0x9 # change to S mode, 0xb written to output -.8byte 0x80200AB0, 0x0000DEADBEEF0000, 0x1 -.8byte 0x800FFAB8, 0x0880DEADBEEF0055, 0x1 -.8byte 0x80200AC0, 0x0990DEADBEEF0033, 0x1 -.8byte 0x80203130, 0x0110DEADBEEF0077, 0x1 -.8byte 0x80201888, 0x0220DEADBEEF0099, 0x1 -.8byte 0x84212348, 0x0330DEADBEEF0440, 0x1 -.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, 0x1 +.8byte 0x0, 0x0, goto_baremetal# satp.MODE = baremetal / no translation. +.8byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output +.8byte 0x80200AB0, 0x0000DEADBEEF0000, read64_test +.8byte 0x800FFAB8, 0x0880DEADBEEF0055, read64_test +.8byte 0x80200AC0, 0x0990DEADBEEF0033, read64_test +.8byte 0x80203130, 0x0110DEADBEEF0077, read64_test +.8byte 0x80201888, 0x0220DEADBEEF0099, read64_test +.8byte 0x84212348, 0x0330DEADBEEF0440, read64_test +.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, read64_test # test 12.3.1.1.4 check translation works in sv39, read the same values from previous tests, this time with Vaddrs -.8byte 0x0, 0x0, 0x5 # satp.MODE = sv39, current VPN: gigapage at 0x80000000. Nothing written to output -.8byte 0x80200AB0, 0x0000DEADBEEF0000, 0x1 # gigapage at Vaddr 0x80000000, Paddr 0x80000000 -.8byte 0x400FFAB8, 0x0880DEADBEEF0055, 0x1 # megapage at Vaddr 0x40400000, Paddr 0x80000000 -.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, 0x1 # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000 +.8byte 0x0, 0x0, goto_sv39 # satp.MODE = sv39, current VPN: gigapage at 0x80000000. Nothing written to output +.8byte 0x80200AB0, 0x0000DEADBEEF0000, read64_test # gigapage at Vaddr 0x80000000, Paddr 0x80000000 +.8byte 0x400FFAB8, 0x0880DEADBEEF0055, read64_test # megapage at Vaddr 0x40400000, Paddr 0x80000000 +.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000 # =========== test 12.3.1.2 page fault tests =========== # test 12.3.1.2.1 load page fault if upper bits of Vaddr are not the same -.8byte 0x0010000080000AB0, 0x0, 0x1 # gigapage at Vaddr 0x80000000, Paddr 0x80000000, bad 1 in upper bits -.8byte 0xFF0FFFFFFFFFF888, 0x0, 0x1 # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000, bad 0000 in upper bits +.8byte 0x0010000080000AB0, 0x0, read64_test# gigapage at Vaddr 0x80000000, Paddr 0x80000000, bad 1 in upper bits +.8byte 0xFF0FFFFFFFFFF888, 0x0, read64_test# kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000, bad 0000 in upper bits # test 12.3.1.2.2 load page fault when reading an address where the valid flag is zero -.8byte 0x6000, 0x0, 0x1 +.8byte 0x6000, 0x0, read64_test # test 12.3.1.2.3 store page fault if PTE has W and ~R flags set -.8byte 0x2000, 0x0, 0x0 +.8byte 0x2000, 0x0, write64_test # test 12.3.1.2.4 Fault if last level PTE is a pointer -.8byte 0x0020, 0x0, 0x1 +.8byte 0x0020, 0x0, read64_test # test 12.3.1.2.5 load page fault on misaligned pages -.8byte 0xC0000000, 0x0, 0x1 # misaligned gigapage -.8byte 0x40200000, 0x0, 0x1 # misaligned megapage +.8byte 0xC0000000, 0x0, read64_test# misaligned gigapage +.8byte 0x40200000, 0x0, read64_test# misaligned megapage # =========== test 12.3.1.3 PTE Protection flags =========== # test 12.3.1.3.1 User flag == 0 # *** reads on pages with U=0 already tested in 12.3.1.1.4 -.8byte 0x40099000, 0x111, 0x2 # execute success when U=0, priv=S -.8byte 0x40400000, 0x2, 0xA # go to U mode, return to megapage at 0x40400000 where U = 1. 0x9 written to output -.8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, 0x1 # load page fault when U=0, priv=U -.8byte 0x40099000, 0xbad, 0x2 # execute fault when U=0, priv=U +.8byte 0x40099000, 0x111, executable_test # execute success when U=0, priv=S +.8byte 0x40400000, 0x2, goto_u_mode # go to U mode, return to megapage at 0x40400000 where U = 1. 0x9 written to output +.8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, read64_test # load page fault when U=0, priv=U +.8byte 0x40099000, 0xbad, executable_test # execute fault when U=0, priv=U # test 12.3.1.3.2 User flag == 1 -.8byte 0x1AC0, 0x0990DEADBEEF0033, 0x1 # read success when U=1, priv=U -.8byte 0x80000000, 0x1, 0x9 # go back to S mode, return to gigapage at 0x80000000 where U = 0. 0x8 written to output -.8byte 0x0, 0x3, 0x7 # set sstatus.[MXR, SUM] = 11 -.8byte 0x4130, 0x0110DEADBEEF0077, 0x1 # read success when U=1, priv=S, sstatus.SUM=1 -.8byte 0x40499000, 0xbad, 0x2 # instr page fault when U=1, priv=S (with any sstatus.SUM) -.8byte 0x0, 0x2, 0x7 # set sstatus.[MXR, SUM] = 10. -.8byte 0x1AC0, 0x0990DEADBEEF0033, 0x1 # load page fault when U-1, priv=S, sstatus.SUM=0 +.8byte 0x1AC0, 0x0990DEADBEEF0033, read64_test # read success when U=1, priv=U +.8byte 0x80000000, 0x1, goto_s_mode # go back to S mode, return to gigapage at 0x80000000 where U = 0. 0x8 written to output +.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11 +.8byte 0x4130, 0x0110DEADBEEF0077, read64_test # read success when U=1, priv=S, sstatus.SUM=1 +.8byte 0x40499000, 0xbad, executable_test # instr page fault when U=1, priv=S (with any sstatus.SUM) +.8byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10. +.8byte 0x1AC0, 0x0990DEADBEEF0033, read64_test # load page fault when U-1, priv=S, sstatus.SUM=0 # test 12.3.1.3.3 Read flag # *** reads on pages with R=1 already tested in 12.3.1.1.4 -.8byte 0x0, 0x1, 0x7 # set sstatus.[MXR, SUM] = 01. -.8byte 0x40612348, 0x0330DEADBEEF0440, 0x1 # load page fault when R=0, sstatus.MXR=0 -.8byte 0x0, 0x3, 0x7 # set sstatus.[MXR, SUM] = 11. -.8byte 0x40612348, 0x0330DEADBEEF0440, 0x1 # read success when MXR=1, X=1 +.8byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01. +.8byte 0x40612348, 0x0330DEADBEEF0440, read64_test # load page fault when R=0, sstatus.MXR=0 +.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11. +.8byte 0x40612348, 0x0330DEADBEEF0440, read64_test # read success when MXR=1, X=1 # test 12.3.1.3.4 Write flag -.8byte 0x80AAAAA0, 0x0440DEADBEEF0110, 0x0 # write success when W=1 -.8byte 0x80AAAAA0, 0x0440DEADBEEF0110, 0x1 # check write success by reading the same address -.8byte 0x40000000, 0x0220DEADBEEF0BB0, 0x0 # store page fault when W=0 +.8byte 0x80AAAAA0, 0x0440DEADBEEF0110, write64_test# write success when W=1 +.8byte 0x80AAAAA0, 0x0440DEADBEEF0110, read64_test# check write success by reading the same address +.8byte 0x40000000, 0x0220DEADBEEF0BB0, write64_test# store page fault when W=0 # test 12.3.1.3.5 eXecute flag # *** fetches on pages with X = 1 already tested in 12.3.1.3.1 -.8byte 0x5AA0, 0x1, 0x2 # instr page fault when X=0 +.8byte 0x5AA0, 0x1, executable_test # instr page fault when X=0 # test 12.3.1.3.6 Accessed flag == 0 -.8byte 0x36D0, 0x0990DEADBEEF0770, 0x0 # store page fault when A=0 -.8byte 0x3AB8, 0x0990DEADBEEF0990, 0x1 # load page fault when A=0 +.8byte 0x36D0, 0x0990DEADBEEF0770, write64_test# store page fault when A=0 +.8byte 0x3AB8, 0x0990DEADBEEF0990, read64_test# load page fault when A=0 # test 12.3.1.3.7 Dirty flag == 0 -.8byte 0x4658, 0x0440DEADBEEF0AA0, 0x0 # store page fault when D=0 -.8byte 0x4AA0, 0x0440DEADBEEF0BB0, 0x1 # read success when D=0 +.8byte 0x4658, 0x0440DEADBEEF0AA0, write64_test# store page fault when D=0 +.8byte 0x4AA0, 0x0440DEADBEEF0BB0, read64_test# read success when D=0 # terminate tests -.8byte 0x0, 0x0, 0x3 # brings us back into machine mode with a final ecall, writing 0x9 to the output. +.8byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output. diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-MMU-SV48.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-MMU-SV48.S index 299bedff7..260a40fe9 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-MMU-SV48.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-MMU-SV48.S @@ -21,7 +21,7 @@ // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /////////////////////////////////////////// -#include "WALLY-TEST-LIB-64.S" +#include "WALLY-TEST-LIB-64.h" // Test library includes and handler for each type of test, a trap handler, imperas compliance instructions // Ideally this should mean that a test can be written by simply adding .8byte statements as below. @@ -46,136 +46,136 @@ # test 12.3.1.1.1 write page tables / entries to phyiscal memory # sv48 page table (See Figure 12.12***): # Level 3 page table, situated at 0x8000D000 -.8byte 0x000000008000D000, 0x0000000020004C01, 0x0 # points to level 2 page table A -.8byte 0x000000008000D008, 0x0000000020005001, 0x0 # points to level 2 page table B # Changing DAU bits of each pointer to zero -.8byte 0x000000008000D010, 0x00000000000000C7, 0x0 # Vaddr 0x010000000000, Paddr 0x00000000: aligned terapage -.8byte 0x000000008000D018, 0x00004000004000C7, 0x0 # Vaddr 0x018000000000, misaligned terapage -.8byte 0x000000008000DFF8, 0x0000000020005401, 0x0 # points to level 2 page table C +.8byte 0x000000008000D000, 0x0000000020004C01, write64_test # points to level 2 page table A +.8byte 0x000000008000D008, 0x0000000020005001, write64_test # points to level 2 page table B # Changing DAU bits of each pointer to zero +.8byte 0x000000008000D010, 0x00000000000000C7, write64_test # Vaddr 0x010000000000, Paddr 0x00000000: aligned terapage +.8byte 0x000000008000D018, 0x00004000004000C7, write64_test # Vaddr 0x018000000000, misaligned terapage +.8byte 0x000000008000DFF8, 0x0000000020005401, write64_test # points to level 2 page table C # Level 2 page table A -.8byte 0x0000000080013010, 0x0000000020006001, 0x0 # points to level 1 page table A +.8byte 0x0000000080013010, 0x0000000020006001, write64_test # points to level 1 page table A # Level 2 page table B -.8byte 0x0000000080014000, 0x00000000200000CB, 0x0 # Vaddr 0x008000000000, Paddr 0x80000000: aligned gigapage used for execution tests -.8byte 0x0000000080014008, 0x00000000200000DF, 0x0 # Vaddr 0x008040000000, Paddr 0x80000000: aligned gigapage (aliased with data and instr memory) U bit set. -.8byte 0x0000000080014010, 0x00000400080000C3, 0x0 # Vaddr 0x008080000000, misaligned gigapage +.8byte 0x0000000080014000, 0x00000000200000CB, write64_test # Vaddr 0x008000000000, Paddr 0x80000000: aligned gigapage used for execution tests +.8byte 0x0000000080014008, 0x00000000200000DF, write64_test # Vaddr 0x008040000000, Paddr 0x80000000: aligned gigapage (aliased with data and instr memory) U bit set. +.8byte 0x0000000080014010, 0x00000400080000C3, write64_test # Vaddr 0x008080000000, misaligned gigapage # Level 2 page table C -.8byte 0x0000000080015FF8, 0x0000000020005801, 0x0 # points to level 1 page table B +.8byte 0x0000000080015FF8, 0x0000000020005801, write64_test # points to level 1 page table B # Level 1 page table A -.8byte 0x0000000080018000, 0x00000000200000CF, 0x0 # Vaddr 0x80000000, Paddr 0x80000000: aligned megapage (data and instr memory) -.8byte 0x0000000080018008, 0x0000000020006401, 0x0 # points to level 0 page table A -.8byte 0x0000000080018010, 0x000000C0000400CF, 0x0 # Vaddr 0x80400000, misaligned megapage -.8byte 0x0000000080018018, 0x00000000214800C9, 0x0 # Vaddr 0x80600000, Paddr 0x85200000: aligned megapage, R=0 +.8byte 0x0000000080018000, 0x00000000200000CF, write64_test # Vaddr 0x80000000, Paddr 0x80000000: aligned megapage (data and instr memory) +.8byte 0x0000000080018008, 0x0000000020006401, write64_test # points to level 0 page table A +.8byte 0x0000000080018010, 0x000000C0000400CF, write64_test # Vaddr 0x80400000, misaligned megapage +.8byte 0x0000000080018018, 0x00000000214800C9, write64_test # Vaddr 0x80600000, Paddr 0x85200000: aligned megapage, R=0 # Level 1 page table B -.8byte 0x0000000080016FF8, 0x0000000020006801, 0x0 # points to level 0 page table B +.8byte 0x0000000080016FF8, 0x0000000020006801, write64_test # points to level 0 page table B # Level 0 page table A -.8byte 0x0000000080019000, 0x00000000200070D1, 0x0 # Vaddr 0x80200000, Paddr 0x8001C000: bad PTE points to level -1 table -.8byte 0x0000000080019008, 0x00000000200800DF, 0x0 # Vaddr 0x80201000, Paddr 0x80200000: aligned kilopage -.8byte 0x0000000080019010, 0x00000000200810DF, 0x0 # Vaddr 0x80202000, Paddr 0x80204000: bad PTE has W but not R -.8byte 0x0000000080019018, 0x0000000020080817, 0x0 # Vaddr 0x80203000, Paddr 0x80202000: A=0, should cause read fault -.8byte 0x0000000080019020, 0x0000000020080C57, 0x0 # Vaddr 0x80204000, Paddr 0x80203000: D=0, should cause write fault -.8byte 0x0000000080019028, 0x0000000020333000, 0x0 # Vaddr 0x80205000, Paddr 0x80CCC000, invalid page. +.8byte 0x0000000080019000, 0x00000000200070D1, write64_test # Vaddr 0x80200000, Paddr 0x8001C000: bad PTE points to level -1 table +.8byte 0x0000000080019008, 0x00000000200800DF, write64_test # Vaddr 0x80201000, Paddr 0x80200000: aligned kilopage +.8byte 0x0000000080019010, 0x00000000200810DF, write64_test # Vaddr 0x80202000, Paddr 0x80204000: bad PTE has W but not R +.8byte 0x0000000080019018, 0x0000000020080817, write64_test # Vaddr 0x80203000, Paddr 0x80202000: A=0, should cause read fault +.8byte 0x0000000080019020, 0x0000000020080C57, write64_test # Vaddr 0x80204000, Paddr 0x80203000: D=0, should cause write fault +.8byte 0x0000000080019028, 0x0000000020333000, write64_test # Vaddr 0x80205000, Paddr 0x80CCC000, invalid page. # Level 0 page table B -.8byte 0x000000008001AFF8, 0x00000000200804CF, 0x0 # Vaddr 0xFFFFFFFFF000, Paddr 0x80201000: aligned kilopage +.8byte 0x000000008001AFF8, 0x00000000200804CF, write64_test # Vaddr 0xFFFFFFFFF000, Paddr 0x80201000: aligned kilopage # test 12.3.1.1.2 write values to Paddrs in each page # each of these values is used for 12.3.1.1.3 and some other tests, specified in the comments. # when a test is supposed to fault, nothing is written into where it'll be reading/executing since it should fault before getting there. -.8byte 0x82777778, 0x0EE0DEADBEEF0CC0, 0x0 # 12.3.1.1.4 terapage -.8byte 0x85BC0AB0, 0x0000DEADBEEF0000, 0x0 # 12.3.1.1.4 gigapage -.8byte 0x800F0AB8, 0x0880DEADBEEF0055, 0x0 # 12.3.1.1.4 megapage -.8byte 0x80201888, 0x0220DEADBEEF0099, 0x0 # 12.3.1.1.4 kilopage -.8byte 0x80099000, 0x0000806711100393, 0x0 # 12.3.1.3.1 write executable code for "li x7, 0x111; ret" -.8byte 0x80200400, 0x0000806711100393, 0x0 # 12.3.1.3.2 write same executable code -.8byte 0x80200AC0, 0x0990DEADBEEF0033, 0x0 # 12.3.1.3.2 -.8byte 0x80200130, 0x0110DEADBEEF0077, 0x0 # 12.3.1.3.2 -.8byte 0x85212348, 0x0330DEADBEEF0440, 0x0 # 12.3.1.3.3 -.8byte 0x88888000, 0x0000806711100393, 0x0 # 12.3.1.3.5 write same executable code -.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, 0x0 # 12.3.1.3.7 +.8byte 0x82777778, 0x0EE0DEADBEEF0CC0, write64_test # 12.3.1.1.4 terapage +.8byte 0x85BC0AB0, 0x0000DEADBEEF0000, write64_test # 12.3.1.1.4 gigapage +.8byte 0x800F0AB8, 0x0880DEADBEEF0055, write64_test # 12.3.1.1.4 megapage +.8byte 0x80201888, 0x0220DEADBEEF0099, write64_test # 12.3.1.1.4 kilopage +.8byte 0x80099000, 0x0000806711100393, write64_test # 12.3.1.3.1 write executable code for "li x7, 0x111; ret" +.8byte 0x80200400, 0x0000806711100393, write64_test # 12.3.1.3.2 write same executable code +.8byte 0x80200AC0, 0x0990DEADBEEF0033, write64_test # 12.3.1.3.2 +.8byte 0x80200130, 0x0110DEADBEEF0077, write64_test # 12.3.1.3.2 +.8byte 0x85212348, 0x0330DEADBEEF0440, write64_test # 12.3.1.3.3 +.8byte 0x88888000, 0x0000806711100393, write64_test # 12.3.1.3.5 write same executable code +.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, write64_test # 12.3.1.3.7 # test 12.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test) -.8byte 0x0, 0x0, 0x4 # satp.MODE = baremetal / no translation. -.8byte 0x0, 0x0, 0x9 # change to S mode, 0xb written to output -.8byte 0x82777778, 0x0EE0DEADBEEF0CC0, 0x1 -.8byte 0x85BC0AB0, 0x0000DEADBEEF0000, 0x1 -.8byte 0x800F0AB8, 0x0880DEADBEEF0055, 0x1 -.8byte 0x80200AC0, 0x0990DEADBEEF0033, 0x1 -.8byte 0x80200130, 0x0110DEADBEEF0077, 0x1 -.8byte 0x80201888, 0x0220DEADBEEF0099, 0x1 -.8byte 0x85212348, 0x0330DEADBEEF0440, 0x1 -.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, 0x1 +.8byte 0x0, 0x0, goto_baremetal # satp.MODE = baremetal / no translation. +.8byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output +.8byte 0x82777778, 0x0EE0DEADBEEF0CC0, read64_test +.8byte 0x85BC0AB0, 0x0000DEADBEEF0000, read64_test +.8byte 0x800F0AB8, 0x0880DEADBEEF0055, read64_test +.8byte 0x80200AC0, 0x0990DEADBEEF0033, read64_test +.8byte 0x80200130, 0x0110DEADBEEF0077, read64_test +.8byte 0x80201888, 0x0220DEADBEEF0099, read64_test +.8byte 0x85212348, 0x0330DEADBEEF0440, read64_test +.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, read64_test # test 12.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs -.8byte 0x0, 0x0, 0x6 # satp.MODE = sv48, current VPN: megapage at 0x80000000. Nothing written to output -.8byte 0x10082777778, 0x0EE0DEADBEEF0CC0, 0x1 # terapage at Vaddr 0x010000000000, Paddr 0x0 -.8byte 0x8005BC0AB0, 0x0000DEADBEEF0000, 0x1 # gigapage at Vaddr 0x008000000000, Paddr 0x80000000 -.8byte 0x800F0AB8, 0x0880DEADBEEF0055, 0x1 # megapage at Vaddr 0x80000000, Paddr 0x80000000 -.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, 0x1 # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000 +.8byte 0x0, 0x0, goto_sv48 # satp.MODE = sv48, current VPN: megapage at 0x80000000. Nothing written to output +.8byte 0x10082777778, 0x0EE0DEADBEEF0CC0, read64_test # terapage at Vaddr 0x010000000000, Paddr 0x0 +.8byte 0x8005BC0AB0, 0x0000DEADBEEF0000, read64_test # gigapage at Vaddr 0x008000000000, Paddr 0x80000000 +.8byte 0x800F0AB8, 0x0880DEADBEEF0055, read64_test # megapage at Vaddr 0x80000000, Paddr 0x80000000 +.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000 # =========== test 12.3.1.2 page fault tests =========== # test 12.3.1.2.1 page fault if upper bits of Vaddr are not the same -.8byte 0x001000800ABC0AB0, 0x0, 0x1 # gigapage at Vaddr 0x008000000000, Paddr 0x80000000, bad 1 in upper bits -.8byte 0xFF0FFFFFFFFFF888, 0x0, 0x1 # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000, bad 0000 in upper bits +.8byte 0x001000800ABC0AB0, 0x0, read64_test# gigapage at Vaddr 0x008000000000, Paddr 0x80000000, bad 1 in upper bits +.8byte 0xFF0FFFFFFFFFF888, 0x0, read64_test# kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000, bad 0000 in upper bits # test 12.3.1.2.2 read fault when reading an address where the valid flag is zero -.8byte 0x80205000, 0x0, 0x1 +.8byte 0x80205000, 0x0, read64_test # test 12.3.1.2.3 write fault if PTE has W and ~R flags set -.8byte 0x80202000, 0x0, 0x0 +.8byte 0x80202000, 0x0, write64_test # test 12.3.1.2.4 Fault if last level PTE is a pointer -.8byte 0x80200000, 0x0, 0x1 +.8byte 0x80200000, 0x0, read64_test # test 12.3.1.2.5 read fault on misaligned pages -.8byte 0x18000000000, 0x0, 0x1 # misaligned terapage -.8byte 0x8080000000, 0x0, 0x1 # misaligned gigapage -.8byte 0x80400000, 0x0, 0x1 # misaligned megapage +.8byte 0x18000000000, 0x0, read64_test # misaligned terapage +.8byte 0x8080000000, 0x0, read64_test # misaligned gigapage +.8byte 0x80400000, 0x0, read64_test # misaligned megapage # =========== test 12.3.1.3 PTE Protection flags =========== # test 12.3.1.3.1 User flag == 0 # reads on pages with U=0 already tested in 12.3.1.1.4 -.8byte 0x008000099000, 0x111, 0x2 # execute success when U=0, priv=S -.8byte 0x008040000000, 0x1, 0xA # go to U mode, return to gigapage at 0x008040000000 where PTE.U = 1. 0x9 written to output -.8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, 0x1 # read fault when U=0, priv=U -.8byte 0x008000099000, 0xbad, 0x2 # execute fault when U=0, priv=U +.8byte 0x008000099000, 0x111, executable_test # execute success when U=0, priv=S +.8byte 0x008040000000, 0x1, goto_u_mode # go to U mode, return to gigapage at 0x008040000000 where PTE.U = 1. 0x9 written to output +.8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, read64_test # read fault when U=0, priv=U +.8byte 0x008000099000, 0xbad, executable_test # execute fault when U=0, priv=U # test 12.3.1.3.2 User flag == 1 -.8byte 0x80201AC0, 0x0990DEADBEEF0033, 0x1 # read success when U=1, priv=U -.8byte 0x80000000, 0x2, 0x9 # go back to S mode, return to megapage at 0x80000000 where PTE.U = 0. 0x8 written to output -.8byte 0x0, 0x3, 0x7 # set sstatus.[MXR, SUM] = 11 -.8byte 0x80201130, 0x0110DEADBEEF0077, 0x1 # read success when U=1, priv=S, sstatus.SUM=1 -.8byte 0x80201400, 0xbad, 0x2 # execute fault when U=1, priv=S (with any sstatus.SUM) -.8byte 0x0, 0x2, 0x7 # set sstatus.[MXR, SUM] = 10. -.8byte 0x80201AC0, 0x0990DEADBEEF0033, 0x1 # read fault when U=1, priv=S, sstatus.SUM=0 +.8byte 0x80201AC0, 0x0990DEADBEEF0033, read64_test # read success when U=1, priv=U +.8byte 0x80000000, 0x2, goto_s_mode +.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11 +.8byte 0x80201130, 0x0110DEADBEEF0077, read64_test # read success when U=1, priv=S, sstatus.SUM=1 +.8byte 0x80201400, 0xbad, executable_test # execute fault when U=1, priv=S (with any sstatus.SUM) +.8byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10. +.8byte 0x80201AC0, 0x0990DEADBEEF0033, read64_test # read fault when U=1, priv=S, sstatus.SUM=0 # test 12.3.1.3.3 Read flag # reads on pages with R=1 already tested in 12.3.1.1.4 -.8byte 0x0, 0x1, 0x7 # set sstatus.[MXR, SUM] = 01. -.8byte 0x80612348, 0x0330DEADBEEF0440, 0x1 # read fault when R=0, sstatus.MXR=0 -.8byte 0x0, 0x3, 0x7 # set sstatus.[MXR, SUM] = 11. -.8byte 0x80612348, 0x0330DEADBEEF0440, 0x1 # read success when MXR=1, X=1 +.8byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01. +.8byte 0x80612348, 0x0330DEADBEEF0440, read64_test # read fault when R=0, sstatus.MXR=0 +.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11. +.8byte 0x80612348, 0x0330DEADBEEF0440, read64_test # read success when MXR=1, X=1 # test 12.3.1.3.4 Write flag -.8byte 0x10080BCDED8, 0x0440DEADBEEF0110, 0x0 # write success when W=1 (corresponding Paddr = 0x80BCDED8) -.8byte 0x10080BCDED8, 0x0440DEADBEEF0110, 0x1 # check write success by reading value back -.8byte 0x8000009E88, 0x0220DEADBEEF0BB0, 0x0 # write fault when W=0 +.8byte 0x10080BCDED8, 0x0440DEADBEEF0110, write64_test # write success when W=1 (corresponding Paddr = 0x80BCDED8) +.8byte 0x10080BCDED8, 0x0440DEADBEEF0110, read64_test # check write success by reading value back +.8byte 0x8000009E88, 0x0220DEADBEEF0BB0, write64_test # write fault when W=0 # test 12.3.1.3.5 eXecute flag # executes on pages with X = 1 already tested in 12.3.1.3.1 -.8byte 0x010088888000, 0x2, 0x2 # execute fault when X=0 +.8byte 0x010088888000, 0x2, executable_test # execute fault when X=0 # test 12.3.1.3.6 Accessed flag == 0 -.8byte 0x802036D0, 0x0990DEADBEEF0770, 0x0 # write fault when A=0 -.8byte 0x80203AB8, 0x0990DEADBEEF0990, 0x1 # read fault when A=0 +.8byte 0x802036D0, 0x0990DEADBEEF0770, write64_test # write fault when A=0 +.8byte 0x80203AB8, 0x0990DEADBEEF0990, read64_test# read fault when A=0 # test 12.3.1.3.7 Dirty flag == 0 -.8byte 0x80204658, 0x0440DEADBEEF0AA0, 0x0 # write fault when D=0 -.8byte 0x80204AA0, 0x0440DEADBEEF0BB0, 0x1 # read success when D=0 +.8byte 0x80204658, 0x0440DEADBEEF0AA0, write64_test # write fault when D=0 +.8byte 0x80204AA0, 0x0440DEADBEEF0BB0, read64_test# read success when D=0 # terminate tests -.8byte 0x0, 0x0, 0x3 # brings us back into machine mode with a final ecall, writing 0x9 to the output. +.8byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output. diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-PMA.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-PMA.S index 51b9d3388..a4a50a3da 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-PMA.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-PMA.S @@ -34,7 +34,7 @@ #define PLIC_BASE 0x0C000000 #define PLIC_RANGE 0x03FFFFFF -#include "WALLY-TEST-LIB-64.S" +#include "WALLY-TEST-LIB-64.h" // Test library includes and handler for each type of test, a trap handler, imperas compliance instructions // Ideally this should mean that a test can be written by simply adding .8byte statements as below. @@ -71,89 +71,89 @@ # ----------------- CLINT --------------------- # Use timecmp register as readable and writable section of the CLINT -.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B4, 0x0 # 64-bit write: success -.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B4, 0x1 # 64-bit read: success -.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B5, 0x11 # 32-bit write: success -.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B5, 0x14 # 32-bit read: success -.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B6, 0x12 # 16-bit write: success -.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B6, 0x15 # 16-bit read: success -.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B7, 0x13 # 08-bit write: success -.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B7, 0x16 # 08-bit read: success +.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B4, write64_test # 64-bit write: success +.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B4, read64_test # 64-bit read: success +.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B5, write32_test # 32-bit write: success +.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B5, read32_test # 32-bit read: success +.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B6, write16_test # 16-bit write: success +.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B6, read16_test # 16-bit read: success +.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B7, write08_test # 08-bit write: success +.8byte CLINT_BASE + 0x4000, 0x0000DEADBEEF00B7, read08_test # 08-bit read: success -.8byte CLINT_BASE, 0xbad, 0x2 # execute: instruction access fault +.8byte CLINT_BASE, 0xbad, executable_test# execute: instruction access fault # ----------------- PLIC --------------------- -.8byte PLIC_BASE, 0x0000DEADBEEF00B8, 0x0 # 64-bit write: store access fault -.8byte PLIC_BASE, 0x0000DEADBEEF00B8, 0x1 # 64-bit read: load access fault +.8byte PLIC_BASE, 0x0000DEADBEEF00B8, write64_test # 64-bit write: store access fault +.8byte PLIC_BASE, 0x0000DEADBEEF00B8, read64_test # 64-bit read: load access fault # Write 0x2 instead of wider value to plic address because the register width might change. -.8byte PLIC_BASE + 0x2000, 0x2, 0x11 # 32-bit write: success -.8byte PLIC_BASE + 0x2000, 0x2, 0x14 # 32-bit read: success -.8byte PLIC_BASE, 0x0000DEADBEEF00BA, 0x12 # 16-bit write: store access fault -.8byte PLIC_BASE, 0x0000DEADBEEF00BA, 0x15 # 16-bit read: load access fault -.8byte PLIC_BASE, 0x0000DEADBEEF00BB, 0x13 # 08-bit write: store access fault -.8byte PLIC_BASE, 0x0000DEADBEEF00BB, 0x16 # 08-bit read: load access fault +.8byte PLIC_BASE + 0x2000, 0x2, write32_test # 32-bit write: success +.8byte PLIC_BASE + 0x2000, 0x2, read32_test # 32-bit read: success +.8byte PLIC_BASE, 0x0000DEADBEEF00BA, write16_test # 16-bit write: store access fault +.8byte PLIC_BASE, 0x0000DEADBEEF00BA, read16_test # 16-bit read: load access fault +.8byte PLIC_BASE, 0x0000DEADBEEF00BB, write08_test # 08-bit write: store access fault +.8byte PLIC_BASE, 0x0000DEADBEEF00BB, read08_test # 08-bit read: load access fault -.8byte PLIC_BASE, 0xbad, 0x2 # execute: instruction access fault +.8byte PLIC_BASE, 0xbad, executable_test# execute: instruction access fault # ----------------- UART0 --------------------- -.8byte UART_BASE, 0x0000DEADBEEF00BC, 0x0 # 64-bit write: store access fault -.8byte UART_BASE, 0x0000DEADBEEF00BC, 0x1 # 64-bit read: load access fault -.8byte UART_BASE, 0x0000DEADBEEF00BD, 0x11 # 32-bit write: store access fault -.8byte UART_BASE, 0x0000DEADBEEF00BD, 0x14 # 32-bit read: load access fault -.8byte UART_BASE, 0x0000DEADBEEF00BE, 0x12 # 16-bit write: store access fault -.8byte UART_BASE, 0x0000DEADBEEF00BE, 0x15 # 16-bit read: load access fault +.8byte UART_BASE, 0x0000DEADBEEF00BC, write64_test # 64-bit write: store access fault +.8byte UART_BASE, 0x0000DEADBEEF00BC, read64_test # 64-bit read: load access fault +.8byte UART_BASE, 0x0000DEADBEEF00BD, write32_test # 32-bit write: store access fault +.8byte UART_BASE, 0x0000DEADBEEF00BD, read32_test # 32-bit read: load access fault +.8byte UART_BASE, 0x0000DEADBEEF00BE, write16_test # 16-bit write: store access fault +.8byte UART_BASE, 0x0000DEADBEEF00BE, read16_test # 16-bit read: load access fault # Different address for this test so that we write into a writable register in the uart. -.8byte UART_BASE + 0x3, 0x0000DEADBEEF00BF, 0x13 # 08-bit write: success -.8byte UART_BASE + 0x3, 0x0000DEADBEEF00BF, 0x16 # 08-bit read: success +.8byte UART_BASE + 0x3, 0x0000DEADBEEF00BF, write08_test # 08-bit write: success +.8byte UART_BASE + 0x3, 0x0000DEADBEEF00BF, read08_test # 08-bit read: success -.8byte UART_BASE, 0xbad, 0x2 # execute: instruction access fault +.8byte UART_BASE, 0xbad, executable_test# execute: instruction access fault # ----------------- GPIO --------------------- -.8byte GPIO_BASE, 0x0000DEADBEEF00C0, 0x0 # 64-bit write: store access fault -.8byte GPIO_BASE, 0x0000DEADBEEF00C0, 0x1 # 64-bit read: load access fault -.8byte GPIO_BASE + 0x8, 0x0000DEADBEEF00C1, 0x11 # 32-bit write: success -.8byte GPIO_BASE + 0x8, 0x0000DEADBEEF00C1, 0x14 # 32-bit read: success -.8byte GPIO_BASE, 0x0000DEADBEEF00C2, 0x12 # 16-bit write: store access fault -.8byte GPIO_BASE, 0x0000DEADBEEF00C2, 0x15 # 16-bit read: load access fault -.8byte GPIO_BASE, 0x0000DEADBEEF00C3, 0x13 # 08-bit write: store access fault -.8byte GPIO_BASE, 0x0000DEADBEEF00C3, 0x16 # 08-bit read: load access fault +.8byte GPIO_BASE, 0x0000DEADBEEF00C0, write64_test # 64-bit write: store access fault +.8byte GPIO_BASE, 0x0000DEADBEEF00C0, read64_test # 64-bit read: load access fault +.8byte GPIO_BASE + 0x8, 0x0000DEADBEEF00C1, write32_test # 32-bit write: success +.8byte GPIO_BASE + 0x8, 0x0000DEADBEEF00C1, read32_test # 32-bit read: success +.8byte GPIO_BASE, 0x0000DEADBEEF00C2, write16_test # 16-bit write: store access fault +.8byte GPIO_BASE, 0x0000DEADBEEF00C2, read16_test # 16-bit read: load access fault +.8byte GPIO_BASE, 0x0000DEADBEEF00C3, write08_test # 08-bit write: store access fault +.8byte GPIO_BASE, 0x0000DEADBEEF00C3, read08_test # 08-bit read: load access fault -.8byte GPIO_BASE, 0xbad, 0x2 # execute: instruction access fault +.8byte GPIO_BASE, 0xbad, executable_test# execute: instruction access fault # ----------------- Inaccessible --------------------- # show that load, store, and jalr cause faults in regions not defined by PMAs. # Tests 'random' place in unimplemented memory -.8byte 0x40000000, 0x0000DEADBEEF00C7, 0x0 # 64-bit write: store access fault -.8byte 0x40000000, 0x0000DEADBEEF00C7, 0x1 # 64-bit read: load access fault -.8byte 0x40000000, 0x111, 0x2 # execute: instruction access fault +.8byte 0x40000000, 0x0000DEADBEEF00C7, write64_test # 64-bit write: store access fault +.8byte 0x40000000, 0x0000DEADBEEF00C7, read64_test # 64-bit read: load access fault +.8byte 0x40000000, 0x111, executable_test # execute: instruction access fault # Tests just past the end of each peripheral -.8byte (BOOTROM_BASE+BOOTROM_RANGE+1), 0x0000DEADBEEF00C8, 0x0 # 64-bit write: store access fault -.8byte (BOOTROM_BASE+BOOTROM_RANGE+1), 0x0000DEADBEEF00C8, 0x1 # 64-bit read: load access fault -.8byte (BOOTROM_BASE+BOOTROM_RANGE+1), 0x111, 0x2 # execute: instruction access fault +.8byte (BOOTROM_BASE+BOOTROM_RANGE+1), 0x0000DEADBEEF00C8, write64_test # 64-bit write: store access fault +.8byte (BOOTROM_BASE+BOOTROM_RANGE+1), 0x0000DEADBEEF00C8, read64_test # 64-bit read: load access fault +.8byte (BOOTROM_BASE+BOOTROM_RANGE+1), 0x111, executable_test # execute: instruction access fault -.8byte (CLINT_BASE+CLINT_RANGE+1), 0x0000DEADBEEF00C9, 0x0 # 64-bit write: store access fault -.8byte (CLINT_BASE+CLINT_RANGE+1), 0x0000DEADBEEF00C9, 0x1 # 64-bit read: load access fault -.8byte (CLINT_BASE+CLINT_RANGE+1), 0x111, 0x2 # execute: instruction access fault +.8byte (CLINT_BASE+CLINT_RANGE+1), 0x0000DEADBEEF00C9, write64_test # 64-bit write: store access fault +.8byte (CLINT_BASE+CLINT_RANGE+1), 0x0000DEADBEEF00C9, read64_test # 64-bit read: load access fault +.8byte (CLINT_BASE+CLINT_RANGE+1), 0x111, executable_test # execute: instruction access fault -.8byte (PLIC_BASE+PLIC_RANGE+1), 0x0000DEADBEEF00CA, 0x11 # 32-bit write: store access fault -.8byte (PLIC_BASE+PLIC_RANGE+1), 0x0000DEADBEEF00CA, 0x14 # 32-bit read: load access fault -.8byte (PLIC_BASE+PLIC_RANGE+1), 0x111, 0x2 # execute: instruction access fault +.8byte (PLIC_BASE+PLIC_RANGE+1), 0x0000DEADBEEF00CA, write32_test # 32-bit write: store access fault +.8byte (PLIC_BASE+PLIC_RANGE+1), 0x0000DEADBEEF00CA, read32_test # 32-bit read: load access fault +.8byte (PLIC_BASE+PLIC_RANGE+1), 0x111, executable_test # execute: instruction access fault -.8byte (UART_BASE+UART_RANGE+1), 0x0000DEADBEEF00CB, 0x13 # 08-bit write: store access fault -.8byte (UART_BASE+UART_RANGE+1), 0x0000DEADBEEF00CB, 0x16 # 08-bit read: load access fault -.8byte (UART_BASE+UART_RANGE+1), 0x111, 0x2 # execute: instruction access fault +.8byte (UART_BASE+UART_RANGE+1), 0x0000DEADBEEF00CB, write08_test # 08-bit write: store access fault +.8byte (UART_BASE+UART_RANGE+1), 0x0000DEADBEEF00CB, read08_test # 08-bit read: load access fault +.8byte (UART_BASE+UART_RANGE+1), 0x111, executable_test # execute: instruction access fault -.8byte (GPIO_BASE+GPIO_RANGE+1), 0x0000DEADBEEF00CC, 0x11 # 32-bit write: store access fault -.8byte (GPIO_BASE+GPIO_RANGE+1), 0x0000DEADBEEF00CC, 0x14 # 32-bit read: load access fault -.8byte (GPIO_BASE+GPIO_RANGE+1), 0x111, 0x2 # execute: instruction access fault +.8byte (GPIO_BASE+GPIO_RANGE+1), 0x0000DEADBEEF00CC, write32_test # 32-bit write: store access fault +.8byte (GPIO_BASE+GPIO_RANGE+1), 0x0000DEADBEEF00CC, read32_test # 32-bit read: load access fault +.8byte (GPIO_BASE+GPIO_RANGE+1), 0x111, executable_test # execute: instruction access fault -.8byte 0x0, 0x0, 0x3 # terminate tests +.8byte 0x0, 0x0, terminate_test# terminate tests diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-PMP.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-PMP.S index 1bc866b0d..226c93984 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-PMP.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-PMP.S @@ -21,7 +21,7 @@ // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /////////////////////////////////////////// -#include "WALLY-TEST-LIB-64.S" +#include "WALLY-TEST-LIB-64.h" // Test library includes and handler for each type of test, a trap handler, imperas compliance instructions // Ideally this should mean that a test can be written by simply adding .8byte statements as below. @@ -45,65 +45,65 @@ # Test 12.3.2.2.1 Config: Write known values and set PMP config according to table 12.4 in the *** riscv book, copied below # write pmpaddr regs. Each of these should output the value of the pmpaddr after being written. - # | Reg | pmpaddr | pmpcfg | L | A | X | W | R | Comments | -.8byte 0x0, 0x0FFFFFFF, 0xE # | 0 | 0x0FFFFFFF | 1F | 0 | NAPOT | 0 | 1 | 1 | I/O 00000000-7FFFFFFF RW | -.8byte 0x1, 0x20040000, 0xE # | 1 | 0x20040000 | 00 | 0 | OFF | 0 | 0 | 0 | | -.8byte 0x2, 0x2004003F, 0xE # | 2 | 0x2004003F | 09 | 0 | TOR | 0 | 0 | 1 | 80100000-801000FF R | -.8byte 0x3, 0x20040080, 0xE # | 3 | 0x20040080 | 00 | 0 | OFF | 0 | 0 | 0 | | -.8byte 0x4, 0x20040084, 0xE # | 4 | 0x20040084 | 0C | 0 | TOR | 1 | 0 | 0 | 80100200-80100210 X | -.8byte 0x5, 0x200400C0, 0xE # | 5 | 0x200400C0 | 90 | 1 | NA4 | 0 | 0 | 0 | 80100300-80100303 locked out | -.8byte 0x6, 0x2004013F, 0xE # | 6 | 0x2004013F | 18 | 0 | NAPOT | 0 | 0 | 0 | 80100400-801004FF no access | + # *** change the pmpcfg and addr commands to the right number # | Reg | pmpaddr | pmpcfg | L | A | X | W | R | Comments | +.8byte 0x0, 0x0FFFFFFF, write_pmpaddr_0 # | 0 | 0x0FFFFFFF | 1F | 0 | NAPOT | 0 | 1 | 1 | I/O 00000000-7FFFFFFF RW | +.8byte 0x1, 0x20040000, write_pmpaddr_1 # | 1 | 0x20040000 | 00 | 0 | OFF | 0 | 0 | 0 | | +.8byte 0x2, 0x2004003F, write_pmpaddr_2 # | 2 | 0x2004003F | 09 | 0 | TOR | 0 | 0 | 1 | 80100000-801000FF R | +.8byte 0x3, 0x20040080, write_pmpaddr_3 # | 3 | 0x20040080 | 00 | 0 | OFF | 0 | 0 | 0 | | +.8byte 0x4, 0x20040084, write_pmpaddr_4 # | 4 | 0x20040084 | 0C | 0 | TOR | 1 | 0 | 0 | 80100200-80100210 X | +.8byte 0x5, 0x200400C0, write_pmpaddr_5 # | 5 | 0x200400C0 | 90 | 1 | NA4 | 0 | 0 | 0 | 80100300-80100303 locked out | +.8byte 0x6, 0x2004013F, write_pmpaddr_6 # | 6 | 0x2004013F | 18 | 0 | NAPOT | 0 | 0 | 0 | 80100400-801004FF no access | # Pmpaddr 7-14 are all zeroed out in this test, so they don't need writes. -.8byte 0xF, 0x2FFFFFFF, 0xE # | 15 | 0x2FFFFFFF | 1F | 0 | NAPOT | 1 | 1 | 1 | Main mem 80000000-FFFFFFFF RWX| +.8byte 0xF, 0x2FFFFFFF, write_pmpaddr_15 # | 15 | 0x2FFFFFFF | 1F | 0 | NAPOT | 1 | 1 | 1 | Main mem 80000000-FFFFFFFF RWX| # write pmpcfg regs with the information in the table above. this should also write the value of these registers to the output. -.8byte 0x0, 0x0018900C0009001F, 0xD # write pmpcfg0, output 0x0018900C0009001F -.8byte 0x2, 0x1F00000000000000, 0xD # write pmpcfg2, output 0x1F00000000000000 +.8byte 0x0, 0x0018900C0009001F, write_pmpcfg_0 # write pmpcfg0, output 0x0018900C0009001F +.8byte 0x2, 0x1F00000000000000, write_pmpcfg_2 # write pmpcfg2, output 0x1F00000000000000 # write known values to memory where W=0. This should be possible since we're in machine mode. -.8byte 0x80100010, 0x600DAA, 0x0 # write to pmpaddr 1-2 range -.8byte 0x80100400, 0x600DBB, 0x0 # write to pmpaddr 6 range +.8byte 0x80100010, 0x600DAA, write64_test # write to pmpaddr 1-2 range +.8byte 0x80100400, 0x600DBB, write64_test # write to pmpaddr 6 range # Write executable code to regions where X = 0, 1 in main memory -.8byte 0x80100200, 0x0000806711100393, 0x0 # write executable code for "li x7, 0x111; ret" to region with X=1 (PMP4) -.8byte 0x80100020, 0x0000806711100393, 0x0 # Write same executable code to region with X=0 (PMP2) +.8byte 0x80100200, 0x0000806711100393, write64_test # write executable code for "li x7, 0x111; ret" to region with X=1 (PMP4) +.8byte 0x80100020, 0x0000806711100393, write64_test # Write same executable code to region with X=0 (PMP2) # attempt to write to pmpaddr5 and pmp5cfg after lockout -.8byte 0x0, 0x0018FF0C0009001F, 0xD # attempt to edit only pmp5cfg (pmpcfg0[47:40]) after lockout. +.8byte 0x0, 0x0018FF0C0009001F, write_pmpcfg_0 # attempt to edit only pmp5cfg (pmpcfg0[47:40]) after lockout. # instruction ignored, output is 0x0018900C0009001F, NOT 0x0018FF0C0009001F -.8byte 0x5, 0xFFFFFFFF, 0xE # attempt to edit pmpaddr5 after lockout. +.8byte 0x5, 0xFFFFFFFF, write_pmpaddr_5 # attempt to edit pmpaddr5 after lockout. # instruction ignored, output is 0x80100300, NOT 0xFFFFFFFF # Test 12.3.2.2.2 Machine mode access -.8byte 0x80100300, 0x0, 0x1 # access fault to region with L=1, R=0 -.8byte 0x80100400, 0x0, 0x1 # successful access to region with L=X=W=R=0 +.8byte 0x80100300, 0x0, read64_test # access fault to region with L=1, R=0 +.8byte 0x80100400, 0x0, read64_test # successful access to region with L=X=W=R=0 # Test 12.3.2.2.3 System mode access -.8byte 0x0, 0x0, 0x9 # go to S mode. 0xb written to output +.8byte 0x0, 0x0, goto_s_mode # go to S mode. 0xb written to output # test a write followed by a read to each region with R=W=1 -.8byte 0x80200000, 0x600D15, 0x0 # Write "good value" to RW range (PMP15) -.8byte 0x80200000, 0x600D15, 0x1 # confirm write with read +.8byte 0x80200000, 0x600D15, write64_test # Write "good value" to RW range (PMP15) +.8byte 0x80200000, 0x600D15, read64_test # confirm write with read # test a write followed by a read on the edges of a read-only range -.8byte 0x800FFFF8, 0x600D02, 0x0 # Write "good value" just below read-only range (PMP2) -.8byte 0x800FFFF8, 0x600D02, 0x1 # confirm write with read -.8byte 0x80100100, 0x600D12, 0x0 # Write "good value" just above read-only range (PMP2) -.8byte 0x80100100, 0x600D12, 0x1 # confirm write with read +.8byte 0x800FFFF8, 0x600D02, write64_test # Write "good value" just below read-only range (PMP2) +.8byte 0x800FFFF8, 0x600D02, read64_test # confirm write with read +.8byte 0x80100100, 0x600D12, write64_test # Write "good value" just above read-only range (PMP2) +.8byte 0x80100100, 0x600D12, read64_test # confirm write with read # test a read from each read only range verify a write causes an access fault -.8byte 0x80100010, 0xBAD, 0x0 # Write fault in read-only range (PMP2) -.8byte 0x80100010, 0x600DAA, 0x1 # read correct value out +.8byte 0x80100010, 0xBAD, write64_test # Write fault in read-only range (PMP2) +.8byte 0x80100010, 0x600DAA, read64_test # read correct value out # test read and write fault on region with no access -.8byte 0x80100208, 0x600D15, 0x0 # Write fault on no-access range (PMP6) -.8byte 0x80100208, 0x600D15, 0x1 # read fault on no-access range (PMP6) +.8byte 0x80100208, 0x600D15, write64_test # Write fault on no-access range (PMP6) +.8byte 0x80100208, 0x600D15, read64_test # read fault on no-access range (PMP6) # test jalr to region with X=0 causes access fault -.8byte 0x80100020, 0xbad, 0x2 # execute fault on no-execute range (PMP2) +.8byte 0x80100020, 0xbad, executable_test # execute fault on no-execute range (PMP2) # test jalr to region with X=1 returns successfully -.8byte 0x80100200, 0x111, 0x2 # execute success when X=1 +.8byte 0x80100200, 0x111, executable_test # execute success when X=1 -.8byte 0x0, 0x0, 0x3 // terminate tests +.8byte 0x0, 0x0, terminate_test // terminate tests diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-LIB-64.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-LIB-64.S deleted file mode 100644 index 0007db6cb..000000000 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-LIB-64.S +++ /dev/null @@ -1,623 +0,0 @@ -/////////////////////////////////////////// -// -// WALLY-TEST-LIB-64.S -// -// Author: Kip Macsai-Goren -// -// Created 2021-07-19 -// -// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, -// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software -// is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -/////////////////////////////////////////// - -#include "model_test.h" -#include "arch_test.h" -RVTEST_ISA("RV64I") - -.section .text.init -.globl rvtest_entry_point -rvtest_entry_point: -RVMODEL_BOOT -RVTEST_CODE_BEGIN - - # --------------------------------------------------------------------------------------------- - # Initialization Overview: - # - # Initialize x6 as a virtual pointer to the test results - # Initialize x16 as a physical pointer to the test results - # Set up stack pointer (sp = x2) - # Set up the exception Handler, keeping the original handler in x4. - # - # --------------------------------------------------------------------------------------------- - - # address for test results - la x6, test_1_res - la x16, test_1_res # x16 reserved for the physical address equivalent of x6 to be used in trap handlers - # any time either is used, both must be updated. - - # address for stack - la sp, top_of_stack - - # trap handler setup - la x1, machine_trap_handler - csrrw x4, mtvec, x1 # x4 reserved for "default" trap handler address that needs to be restored before halting this test. - li a0, 0 - li a1, 0 - li a2, 0 # reset trap handler inputs to zero - - # go to first test! - j test_setup - - - # --------------------------------------------------------------------------------------------- - # General traps Handler - # - # Handles traps by branching to different behaviors based on mcause. - # - # Note that allowing the exception handler to change mode for a program is a huge security - # hole, but this is an expedient way of writing tests that need different modes - # - # input parameters: - # - # a0 (x10): - # 0: halt program with no failures - # 1: halt program with failure in x11 = a1 - # 2: go to machine mode - # 3: go to supervisor mode - # 4: go to user mode - # others: do nothing - # - # a1 (x11): - # VPN for return address after changing privilege mode. - # This should be the base VPN with no offset. - # 0x0 : defaults to next instruction on the same page the trap was called on. - # - # a2 (x12): - # Pagetype of the current address VPN before changing privilge mode - # Used so that we can know how many bits of the adress are the offset. - # Ignored if a1 == 0x0 - # 0: Kilopage - # 1: Megapage - # 2: Gigapage - # 3: Terapage - # - # -------------------------------------------------------------------------------------------- - - -machine_trap_handler: - # The processor is always in machine mode when a trap takes us here - # save registers on stack before using - sd x1, -8(sp) - sd x5, -16(sp) - - # Record trap - csrr x1, mcause # record the mcause - sd x1, 0(x16) - addi x6, x6, 8 - addi x16, x16, 8 # update pointers for logging results - - # Respond to trap based on cause - # All interrupts should return after being logged - li x5, 0x8000000000000000 # if msb is set, it is an interrupt - and x5, x5, x1 - bnez x5, trapreturn # return from interrupt - # Other trap handling is specified in the vector Table - slli x1, x1, 3 # multiply cause by 8 to get offset in vector Table - la x5, trap_handler_vector_table - add x5, x5, x1 # compute address of vector in Table - ld x5, 0(x5) # fectch address of handler from vector Table - jr x5 # and jump to the handler - -segfault: - ld x5, -16(sp) # restore registers from stack before faulting - ld x1, -8(sp) - j terminate_test # halt program. - -trapreturn: - # look at the instruction to figure out whether to add 2 or 4 bytes to PC, or go to address specified in a1 - csrr x1, mepc # get the mepc - addi x1, x1, 4 # *** should be 2 for compressed instructions, see note. - - -# ****** KMG: the following is no longer as easy to determine. mepc gets the virtual address of the trapped instruction, -# ******** but in the handler, we work in M mode with physical addresses -# This means the address in mepc is suddenly pointing somewhere else. -# to get this to work, We could either retranslate the vaddr back into a paddr (probably on the scale of difficult to intractible) -# or we could come up with some other ingenious way to stay in M mode and see if the instruction was compressed. - -# lw x5, 0(x1) # read the faulting instruction -# li x1, 3 # check bottom 2 bits of instruction to see if compressed -# and x5, x5, x1 # mask the other bits -# beq x5, x1, trapreturn_uncompressed # if 11, the instruction is return_uncompressed - -# trapreturn_compressed: -# csrr x1, mepc # get the mepc again -# addi x1, x1, 2 # add 2 to find the next instruction -# j trapreturn_specified # and return - -# trapreturn_uncompressed: -# csrr x1, mepc # get the mepc again -# addi x1, x1, 4 # add 4 to find the next instruction - -trapreturn_specified: - # reset the necessary pointers and registers (x1, x5, x6, and the return address going to mepc) - # so that when we return to a new virtual address, they're all in the right spot as well. - - beqz a1, trapreturn_finished # either update values, of go to default return address. - - la x5, trap_return_pagetype_table - slli a2, a2, 3 - add x5, x5, a2 - ld a2, 0(x5) # a2 = number of offset bits in current page type - - li x5, 1 - sll x5, x5, a2 - addi x5, x5, -1 # x5 = mask bits for offset into current pagetype - - # reset the top of the stack, x1 - ld x7, -8(sp) - and x7, x5, x7 # x7 = offset for x1 - add x7, x7, a1 # x7 = new address for x1 - sd x7, -8(sp) - - # reset the second spot in the stack, x5 - ld x7, -16(sp) - and x7, x5, x7 # x7 = offset for x5 - add x7, x7, a1 # x7 = new address for x5 - sd x7, -16(sp) - - # reset x6, the pointer for the virtual address of the output of the tests - and x7, x5, x6 # x7 = offset for x6 - add x6, x7, a1 # x6 = new address for the result pointer - - # set return address, stored temporarily in x1, to the next instruction, but in the new virtual page. - and x1, x5, x1 # x1 = offset for the return address - add x1, x1, a1 # x1 = new return address. - - li a1, 0 - li a2, 0 # reset trapreturn inputs to the trap handler - -trapreturn_finished: - csrw mepc, x1 # update the mepc with address of next instruction - ld x5, -16(sp) # restore registers from stack before returning - ld x1, -8(sp) - mret # return from trap - -ecallhandler: - # Check input parameter a0. encoding above. - # *** ASSUMES: that this trap is being handled in machine mode. in other words, that nothing odd has been written to the medeleg or mideleg csrs. - li x5, 2 # case 2: change to machine mode - beq a0, x5, ecallhandler_changetomachinemode - li x5, 3 # case 3: change to supervisor mode - beq a0, x5, ecallhandler_changetosupervisormode - li x5, 4 # case 4: change to user mode - beq a0, x5, ecallhandler_changetousermode - # unsupported ecalls should segfault - j segfault - -ecallhandler_changetomachinemode: - # Force mstatus.MPP (bits 12:11) to 11 to enter machine mode after mret - li x1, 0b1100000000000 - csrs mstatus, x1 - j trapreturn - -ecallhandler_changetosupervisormode: - # Force mstatus.MPP (bits 12:11) to 01 to enter supervisor mode after mret - li x1, 0b1100000000000 - csrc mstatus, x1 - li x1, 0b0100000000000 - csrs mstatus, x1 - j trapreturn - -ecallhandler_changetousermode: - # Force mstatus.MPP (bits 12:11) to 00 to enter user mode after mret - li x1, 0b1100000000000 - csrc mstatus, x1 - j trapreturn - -instrfault: - ld x1, -8(sp) # load return address int x1 (the address AFTER the jal into faulting page) - j trapreturn_finished # puts x1 into mepc, restores stack and returns to program (outside of faulting page) - -accessfault: - # *** What do I have to do here? - j trapreturn - - # Table of trap behavior - # lists what to do on each exception (not interrupts) - # unexpected exceptions should cause segfaults for easy detection - # Expected exceptions should increment the EPC to the next instruction and return - - .align 3 # aligns this data table to an 8 byte boundary -trap_handler_vector_table: - .8byte segfault # 0: instruction address misaligned - .8byte instrfault # 1: instruction access fault - .8byte segfault # 2: illegal instruction - .8byte segfault # 3: breakpoint - .8byte segfault # 4: load address misaligned - .8byte accessfault # 5: load access fault - .8byte segfault # 6: store address misaligned - .8byte accessfault # 7: store access fault - .8byte ecallhandler # 8: ecall from U-mode - .8byte ecallhandler # 9: ecall from S-mode - .8byte segfault # 10: reserved - .8byte ecallhandler # 11: ecall from M-mode - .8byte instrfault # 12: instruction page fault - .8byte trapreturn # 13: load page fault - .8byte segfault # 14: reserved - .8byte trapreturn # 15: store page fault - -.align 3 -trap_return_pagetype_table: - .8byte 0xC # 0: kilopage has 12 offset bits - .8byte 0x15 # 1: megapage has 21 offset bits - .8byte 0x1E # 2: gigapage has 30 offset bits - .8byte 0x27 # 3: terapage has 39 offset bits - - # --------------------------------------------------------------------------------------------- - # Test Handler - # - # This test handler works in a similar wy to the trap handler. It takes in a few things by reading from a table in memory - # (see test_cases) and performing certain behavior based on them. - # - # Input parameters: - # - # x28: - # Address input for the test taking place (think address to read/write, new address to return to, etc...) - # - # x29: - # Value input for the test taking place (think value to write, any other extra info needed) - # - # x30: - # Test type input that determines which kind of test will take place. Encoding for this input is in the table/case statements below - # - # ------------------------------------------------------------------------------------------------------------------------------------ - -test_setup: - la x5, test_cases - -test_loop: - ld x28, 0(x5) # fetch test case address - ld x29, 8(x5) # fetch test case value - ld x30, 16(x5) # fetch test case flag - addi x5, x5, 24 # set x5 to next test case - - slli x30, x30, 2 # multiply test type by 4 to index into jump table - la x7, test_jump_table # load base address of jump table - add x7, x7, x30 # get address of jump table entry - jr x7 # jump to relevant test - -test_jump_table: - # x30 Value : Function : Fault output value : Normal output values - # ----------:---------------------------------------:------------------------:------------------------------------------------------ - j write64_test # 0x0 : Write 64 bits to address : 0xf : None - j read64_test # 0x1 : Read 64 bits from address : 0xd, 0xbad : readvalue in hex - j executable_test # 0x2 : test executable on virtual page : 0xc, 0xbad : value of x7 modified by exectuion code (usually 0x111) - j terminate_test # 0x3 : terminate tests : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 - j goto_baremetal # 0x4 : satp.MODE = bare metal : None : None - j goto_sv39 # 0x5 : satp.MODE = sv39 : None : None - j goto_sv48 # 0x6 : satp.MODE = sv48 : None : None - j write_mxr_sum # 0x7 : write sstatus.[19:18] = MXR, SUM bits : None : None - j goto_m_mode # 0x8 : go to mahcine mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 - j goto_s_mode # 0x9 : go to supervisor mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 - j goto_u_mode # 0xA : go to user mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 - j segfault # 0xB : Segfault, undefined test - j segfault # 0xC : Segfault, undefined test - j write_pmpcfg_0 # 0xD : Write one of the pmpcfg csr's : mstatuses?, 0xD : readback of pmpcfg value - j write_pmpaddr_0 # 0xE : Write one of the pmpaddr csr's : None : None - j segfault # 0xF : Segfault, undefined test - j segfault # 0x10 : Segfault, undefined test - j write32_test # 0x11 : Write 32 bits to address : 0xf : None - j write16_test # 0x12 : Write 16 bits to address : 0xf : None - j write08_test # 0x13 : Write 8 bits to address : 0xf : None - j read32_test # 0x14 : Read 32 bitsfrom address : 0xd, 0xbad : readvalue in hex - j read16_test # 0x15 : Read 16 bitsfrom address : 0xd, 0xbad : readvalue in hex - j read08_test # 0x16 : Read 8 bitsfrom address : 0xd, 0xbad : readvalue in hex - -write64_test: - # address to write in x28, double value in x29 - sd x29, 0(x28) - j test_loop # go to next test case - -write32_test: - # address to write in x28, word value in x29 - sw x29, 0(x28) - j test_loop # go to next test case - -write16_test: - # address to write in x28, halfword value in x29 - sh x29, 0(x28) - j test_loop # go to next test case - -write08_test: - # address to write in x28, value in x29 - sb x29, 0(x28) - j test_loop # go to next test case - -read64_test: - # address to read in x28, expected 64 bit value in x29 (unused, but there for your perusal). - li x7, 0xBAD # bad value that will be overwritten on good reads. - ld x7, 0(x28) - sd x7, 0(x6) - addi x6, x6, 8 - addi x16, x16, 8 - j test_loop # go to next test case - -read32_test: - # address to read in x28, expected 32 bit value in x29 (unused, but there for your perusal). - li x7, 0xBAD # bad value that will be overwritten on good reads. - lw x7, 0(x28) - sd x7, 0(x6) - addi x6, x6, 8 - addi x16, x16, 8 - j test_loop # go to next test case - -read16_test: - # address to read in x28, expected 16 bit value in x29 (unused, but there for your perusal). - li x7, 0xBAD # bad value that will be overwritten on good reads. - lh x7, 0(x28) - sd x7, 0(x6) - addi x6, x6, 8 - addi x16, x16, 8 - j test_loop # go to next test case - -read08_test: - # address to read in x28, expected 8 bit value in x29 (unused, but there for your perusal). - li x7, 0xBAD # bad value that will be overwritten on good reads. - lb x7, 0(x28) - sd x7, 0(x6) - addi x6, x6, 8 - addi x16, x16, 8 - j test_loop # go to next test case - -goto_s_mode: - # return to address in x28, - li a0, 3 # Trap handler behavior (go to supervisor mode) - mv a1, x28 # return VPN - mv a2, x29 # return page types - ecall # writes mcause to the output. - # now in S mode - j test_loop - -goto_m_mode: - li a0, 2 # Trap handler behavior (go to machine mode) - mv a1, x28 # return VPN - mv a2, x29 # return page types - ecall # writes mcause to the output. - j test_loop - -goto_u_mode: - li a0, 4 # Trap handler behavior (go to user mode) - mv a1, x28 # return VPN - mv a2, x29 # return page types - ecall # writes mcause to the output. - j test_loop - -goto_baremetal: - # Turn translation off - li x7, 0 # satp.MODE value for bare metal (0) - slli x7, x7, 60 - li x28, 0x8000D # Base Pagetable physical page number, satp.PPN field. - add x7, x7, x28 - csrw satp, x7 - sfence.vma x0, x0 # *** flushes global pte's as well - j test_loop # go to next test case - -goto_sv39: - li x7, 8 # satp.MODE value for Sv39 (8) - slli x7, x7, 60 - li x28, 0x8000D # Base Pagetable physical page number, satp.PPN field. - add x7, x7, x28 - csrw satp, x7 - sfence.vma x0, x0 # *** flushes global pte's as well - j test_loop # go to next test case - -goto_sv48: - li x7, 9 # satp.MODE value for Sv48 - slli x7, x7, 60 - li x28, 0x8000D # Base Pagetable physical page number, satp.PPN field. - add x7, x7, x28 - csrw satp, x7 - sfence.vma x0, x0 # *** flushes global pte's as well - j test_loop # go to next test case - -write_mxr_sum: - # writes sstatus.[mxr, sum] with the (assumed to be) 2 bit value in x29. also assumes we're in S. M mode - li x30, 0xC0000 # mask bits for MXR, SUM - not x7, x29 - slli x7, x7, 18 - and x7, x7, x30 - slli x29, x29, 18 - csrc sstatus, x7 - csrs sstatus, x29 - j test_loop - -write_pmpcfg_0: - # writes the value in x29 to the pmpcfg register specified in x28. - # then writes the final value of pmpcfgX to the output. - li x7, 0x0 - bne x7, x28, write_pmpcfg_2 - csrw pmpcfg0, x29 - csrr x30, pmpcfg0 -write_pmpcfg_2: - li x7, 0x2 - bne x7, x28, write_pmpcfg_end - csrw pmpcfg2, x29 - csrr x30, pmpcfg2 # I would use csrrw but we need the value AFTER the csr has been written -write_pmpcfg_end: - sd x30, 0(x6) - addi x6, x6, 8 - addi x16, x16, 8 - j test_loop - -write_pmpaddr_0: - # writes the value in x29 to the pmpaddr register specified in x28. - # then writes the final value of pmpaddrX to the output. - li x7, 0x0 - bne x7, x28, write_pmpaddr_1 - csrw pmpaddr0, x29 - csrr x30, pmpaddr0 - j write_pmpaddr_end -write_pmpaddr_1: - li x7, 0x1 - bne x7, x28, write_pmpaddr_2 - csrw pmpaddr1, x29 - csrr x30, pmpaddr1 - j write_pmpaddr_end -write_pmpaddr_2: - li x7, 0x2 - bne x7, x28, write_pmpaddr_3 - csrw pmpaddr2, x29 - csrr x30, pmpaddr2 - j write_pmpaddr_end -write_pmpaddr_3: - li x7, 0x3 - bne x7, x28, write_pmpaddr_4 - csrw pmpaddr3, x29 - csrr x30, pmpaddr3 - j write_pmpaddr_end -write_pmpaddr_4: - li x7, 0x4 - bne x7, x28, write_pmpaddr_5 - csrw pmpaddr4, x29 - csrr x30, pmpaddr4 - j write_pmpaddr_end -write_pmpaddr_5: - li x7, 0x5 - bne x7, x28, write_pmpaddr_6 - csrw pmpaddr5, x29 - csrr x30, pmpaddr5 - j write_pmpaddr_end -write_pmpaddr_6: - li x7, 0x6 - bne x7, x28, write_pmpaddr_7 - csrw pmpaddr6, x29 - csrr x30, pmpaddr6 - j write_pmpaddr_end -write_pmpaddr_7: - li x7, 0x7 - bne x7, x28, write_pmpaddr_8 - csrw pmpaddr7, x29 - csrr x30, pmpaddr7 - j write_pmpaddr_end -write_pmpaddr_8: - li x7, 0x8 - bne x7, x28, write_pmpaddr_9 - csrw pmpaddr8, x29 - csrr x30, pmpaddr8 - j write_pmpaddr_end -write_pmpaddr_9: - li x7, 0x9 - bne x7, x28, write_pmpaddr_10 - csrw pmpaddr9, x29 - csrr x30, pmpaddr9 - j write_pmpaddr_end -write_pmpaddr_10: - li x7, 0xA - bne x7, x28, write_pmpaddr_11 - csrw pmpaddr10, x29 - csrr x30, pmpaddr10 - j write_pmpaddr_end -write_pmpaddr_11: - li x7, 0xB - bne x7, x28, write_pmpaddr_12 - csrw pmpaddr11, x29 - csrr x30, pmpaddr11 - j write_pmpaddr_end -write_pmpaddr_12: - li x7, 0xC - bne x7, x28, write_pmpaddr_13 - csrw pmpaddr12, x29 - csrr x30, pmpaddr12 - j write_pmpaddr_end -write_pmpaddr_13: - li x7, 0xD - bne x7, x28, write_pmpaddr_14 - csrw pmpaddr13, x29 - csrr x30, pmpaddr13 - j write_pmpaddr_end -write_pmpaddr_14: - li x7, 0xE - bne x7, x28, write_pmpaddr_15 - csrw pmpaddr14, x29 - csrr x30, pmpaddr14 - j write_pmpaddr_end -write_pmpaddr_15: - li x7, 0xF - bne x7, x28, write_pmpaddr_end - csrw pmpaddr15, x29 - csrr x30, pmpaddr15 - j write_pmpaddr_end -write_pmpaddr_end: - sd x30, 0(x6) - addi x6, x6, 8 - addi x16, x16, 8 - j test_loop - -executable_test: - # Execute the code at the address in x28, returning the value in x7. - # Assumes the code modifies x7, to become the value stored in x29 for this test. - fence.i # forces cache and main memory to sync so execution code written by the program can run. - li x7, 0xBAD - jalr x28 - sd x7, 0(x6) - addi x6, x6, 8 - addi x16, x16, 8 - j test_loop - -terminate_test: - - li a0, 2 # Trap handler behavior (go to machine mode) - ecall # writes mcause to the output. - csrw mtvec, x4 # restore original trap handler to halt program - -RVTEST_CODE_END -RVMODEL_HALT - -RVTEST_DATA_BEGIN -.align 4 -rvtest_data: -.word 0xbabecafe -RVTEST_DATA_END - -.align 3 # align stack to 8 byte boundary -bottom_of_stack: - .fill 1024, 4, 0xdeadbeef -top_of_stack: - - -RVMODEL_DATA_BEGIN - -test_1_res: - .fill 1024, 4, 0xdeadbeef - -RVMODEL_DATA_END - -#ifdef rvtest_mtrap_routine - -mtrap_sigptr: - .fill 64*(XLEN/32),4,0xdeadbeef - -#endif - -#ifdef rvtest_gpr_save - -gpr_save: - .fill 32*(XLEN/32),4,0xdeadbeef - -#endif - -.align 3 -test_cases: - diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-LIB-64.h b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-LIB-64.h new file mode 100644 index 000000000..5e946618e --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-LIB-64.h @@ -0,0 +1,624 @@ +/////////////////////////////////////////// +// +// WALLY-TEST-LIB-64.S +// +// Author: Kip Macsai-Goren +// +// Created 2021-07-19 +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I") + +.section .text.init +.globl rvtest_entry_point +rvtest_entry_point: +RVMODEL_BOOT +RVTEST_CODE_BEGIN + + // --------------------------------------------------------------------------------------------- + // Initialization Overview: + // + // Initialize x6 as a virtual pointer to the test results + // Initialize x16 as a physical pointer to the test results + // Set up stack pointer (sp = x2) + // Set up the exception Handler, keeping the original handler in x4. + // + // --------------------------------------------------------------------------------------------- + + // address for test results + la x6, test_1_res + la x16, test_1_res // x16 reserved for the physical address equivalent of x6 to be used in trap handlers + // any time either is used, both must be updated. + + // address for stack + la sp, top_of_stack + + // trap handler setup + la x1, machine_trap_handler + csrrw x4, mtvec, x1 // x4 reserved for "default" trap handler address that needs to be restored before halting this test. + li a0, 0 + li a1, 0 + li a2, 0 // reset trap handler inputs to zero + + // go to first test! + j test_setup + + + // --------------------------------------------------------------------------------------------- + // General traps Handler + // + // Handles traps by branching to different behaviors based on mcause. + // + // Note that allowing the exception handler to change mode for a program is a huge security + // hole, but this is an expedient way of writing tests that need different modes + // + // input parameters: + // + // a0 (x10): + // 0: halt program with no failures + // 1: halt program with failure in x11 = a1 + // 2: go to machine mode + // 3: go to supervisor mode + // 4: go to user mode + // others: do nothing + // + // a1 (x11): + // VPN for return address after changing privilege mode. + // This should be the base VPN with no offset. + // 0x0 : defaults to next instruction on the same page the trap was called on. + // + // a2 (x12): + // Pagetype of the current address VPN before changing privilge mode + // Used so that we can know how many bits of the adress are the offset. + // Ignored if a1 == 0x0 + // 0: Kilopage + // 1: Megapage + // 2: Gigapage + // 3: Terapage + // + // -------------------------------------------------------------------------------------------- + + +machine_trap_handler: + // The processor is always in machine mode when a trap takes us here + // save registers on stack before using + sd x1, -8(sp) + sd x5, -16(sp) + + // Record trap + csrr x1, mcause // record the mcause + sd x1, 0(x16) + addi x6, x6, 8 + addi x16, x16, 8 // update pointers for logging results + + // Respond to trap based on cause + // All interrupts should return after being logged + li x5, 0x8000000000000000 // if msb is set, it is an interrupt + and x5, x5, x1 + bnez x5, trapreturn // return from interrupt + // Other trap handling is specified in the vector Table + slli x1, x1, 3 // multiply cause by 8 to get offset in vector Table + la x5, trap_handler_vector_table + add x5, x5, x1 // compute address of vector in Table + ld x5, 0(x5) // fectch address of handler from vector Table + jr x5 // and jump to the handler + +segfault: + ld x5, -16(sp) // restore registers from stack before faulting + ld x1, -8(sp) + j terminate_test // halt program. + +trapreturn: + // look at the instruction to figure out whether to add 2 or 4 bytes to PC, or go to address specified in a1 + csrr x1, mepc // get the mepc + addi x1, x1, 4 // *** should be 2 for compressed instructions, see note. + + +// ****** KMG: the following is no longer as easy to determine. mepc gets the virtual address of the trapped instruction, +// ******** but in the handler, we work in M mode with physical addresses +// This means the address in mepc is suddenly pointing somewhere else. +// to get this to work, We could either retranslate the vaddr back into a paddr (probably on the scale of difficult to intractible) +// or we could come up with some other ingenious way to stay in M mode and see if the instruction was compressed. + +// lw x5, 0(x1) // read the faulting instruction +// li x1, 3 // check bottom 2 bits of instruction to see if compressed +// and x5, x5, x1 // mask the other bits +// beq x5, x1, trapreturn_uncompressed // if 11, the instruction is return_uncompressed + +// trapreturn_compressed: +// csrr x1, mepc // get the mepc again +// addi x1, x1, 2 // add 2 to find the next instruction +// j trapreturn_specified // and return + +// trapreturn_uncompressed: +// csrr x1, mepc // get the mepc again +// addi x1, x1, 4 // add 4 to find the next instruction + +trapreturn_specified: + // reset the necessary pointers and registers (x1, x5, x6, and the return address going to mepc) + // so that when we return to a new virtual address, they're all in the right spot as well. + + beqz a1, trapreturn_finished // either update values, of go to default return address. + + la x5, trap_return_pagetype_table + slli a2, a2, 3 + add x5, x5, a2 + ld a2, 0(x5) // a2 = number of offset bits in current page type + + li x5, 1 + sll x5, x5, a2 + addi x5, x5, -1 // x5 = mask bits for offset into current pagetype + + // reset the top of the stack, x1 + ld x7, -8(sp) + and x7, x5, x7 // x7 = offset for x1 + add x7, x7, a1 // x7 = new address for x1 + sd x7, -8(sp) + + // reset the second spot in the stack, x5 + ld x7, -16(sp) + and x7, x5, x7 // x7 = offset for x5 + add x7, x7, a1 // x7 = new address for x5 + sd x7, -16(sp) + + // reset x6, the pointer for the virtual address of the output of the tests + and x7, x5, x6 // x7 = offset for x6 + add x6, x7, a1 // x6 = new address for the result pointer + + // set return address, stored temporarily in x1, to the next instruction, but in the new virtual page. + and x1, x5, x1 // x1 = offset for the return address + add x1, x1, a1 // x1 = new return address. + + li a1, 0 + li a2, 0 // reset trapreturn inputs to the trap handler + +trapreturn_finished: + csrw mepc, x1 // update the mepc with address of next instruction + ld x5, -16(sp) // restore registers from stack before returning + ld x1, -8(sp) + mret // return from trap + +ecallhandler: + // Check input parameter a0. encoding above. + // *** ASSUMES: that this trap is being handled in machine mode. in other words, that nothing odd has been written to the medeleg or mideleg csrs. + li x5, 2 // case 2: change to machine mode + beq a0, x5, ecallhandler_changetomachinemode + li x5, 3 // case 3: change to supervisor mode + beq a0, x5, ecallhandler_changetosupervisormode + li x5, 4 // case 4: change to user mode + beq a0, x5, ecallhandler_changetousermode + // unsupported ecalls should segfault + j segfault + +ecallhandler_changetomachinemode: + // Force mstatus.MPP (bits 12:11) to 11 to enter machine mode after mret + li x1, 0b1100000000000 + csrs mstatus, x1 + j trapreturn + +ecallhandler_changetosupervisormode: + // Force mstatus.MPP (bits 12:11) to 01 to enter supervisor mode after mret + li x1, 0b1100000000000 + csrc mstatus, x1 + li x1, 0b0100000000000 + csrs mstatus, x1 + j trapreturn + +ecallhandler_changetousermode: + // Force mstatus.MPP (bits 12:11) to 00 to enter user mode after mret + li x1, 0b1100000000000 + csrc mstatus, x1 + j trapreturn + +instrfault: + ld x1, -8(sp) // load return address int x1 (the address AFTER the jal into faulting page) + j trapreturn_finished // puts x1 into mepc, restores stack and returns to program (outside of faulting page) + +accessfault: + // *** What do I have to do here? + j trapreturn + + // Table of trap behavior + // lists what to do on each exception (not interrupts) + // unexpected exceptions should cause segfaults for easy detection + // Expected exceptions should increment the EPC to the next instruction and return + + .align 3 // aligns this data table to an 8 byte boundary +trap_handler_vector_table: + .8byte segfault // 0: instruction address misaligned + .8byte instrfault // 1: instruction access fault + .8byte segfault // 2: illegal instruction + .8byte segfault // 3: breakpoint + .8byte segfault // 4: load address misaligned + .8byte accessfault // 5: load access fault + .8byte segfault // 6: store address misaligned + .8byte accessfault // 7: store access fault + .8byte ecallhandler // 8: ecall from U-mode + .8byte ecallhandler // 9: ecall from S-mode + .8byte segfault // 10: reserved + .8byte ecallhandler // 11: ecall from M-mode + .8byte instrfault // 12: instruction page fault + .8byte trapreturn // 13: load page fault + .8byte segfault // 14: reserved + .8byte trapreturn // 15: store page fault + +.align 3 +trap_return_pagetype_table: + .8byte 0xC // 0: kilopage has 12 offset bits + .8byte 0x15 // 1: megapage has 21 offset bits + .8byte 0x1E // 2: gigapage has 30 offset bits + .8byte 0x27 // 3: terapage has 39 offset bits + + // --------------------------------------------------------------------------------------------- + // Test Handler + // + // This test handler works in a similar wy to the trap handler. It takes in a few things by reading from a table in memory + // (see test_cases) and performing certain behavior based on them. + // + // Input parameters: + // + // x28: + // Address input for the test taking place (think address to read/write, new address to return to, etc...) + // + // x29: + // Value input for the test taking place (think value to write, any other extra info needed) + // + // x30: + // Test type input that determines which kind of test will take place. Encoding for this input is in the table/case statements below + // + // ------------------------------------------------------------------------------------------------------------------------------------ + +test_setup: + la x5, test_cases + +test_loop: + ld x28, 0(x5) // fetch test case address + ld x29, 8(x5) // fetch test case value + ld x30, 16(x5) // fetch test case flag + addi x5, x5, 24 // set x5 to next test case + + // x5 has the symbol for a test's location in the assembly + li x7, 0x1FFFFF + and x30, x30, x7 // This program is always on at least a megapage, so this masks out the megapage offset. + auipc x7, 0x0 + srli x7, x7, 21 + slli x7, x7, 21 // zero out the bottom 21 bits so the megapage offset of the symbol can be placed there + or x30, x7, x30 // x30 = virtual address of the symbol for this type of test. + + jr x30 + +// Test Name : Description : Fault output value : Normal output values +// ----------------------:-------------------------------------------:------------------------:------------------------------------------------------ +// write64_test : Write 64 bits to address : 0xf : None +// write32_test : Write 32 bits to address : 0xf : None +// write16_test : Write 16 bits to address : 0xf : None +// write08_test : Write 8 bits to address : 0xf : None +// read64_test : Read 64 bits from address : 0xd, 0xbad : readvalue in hex +// read32_test : Read 32 bitsfrom address : 0xd, 0xbad : readvalue in hex +// read16_test : Read 16 bitsfrom address : 0xd, 0xbad : readvalue in hex +// read08_test : Read 8 bitsfrom address : 0xd, 0xbad : readvalue in hex +// executable_test : test executable on virtual page : 0xc, 0xbad : value of x7 modified by exectuion code (usually 0x111) +// terminate_test : terminate tests : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 +// goto_baremetal : satp.MODE = bare metal : None : None +// goto_sv39 : satp.MODE = sv39 : None : None +// goto_sv48 : satp.MODE = sv48 : None : None +// write_mxr_sum : write sstatus.[19:18] = MXR, SUM bits : None : None +// goto_m_mode : go to mahcine mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 +// goto_s_mode : go to supervisor mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 +// goto_u_mode : go to user mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 +// write_pmpcfg_x : Write one of the pmpcfg csr's : mstatuses?, 0xD : readback of pmpcfg value +// write_pmpaddr_x : Write one of the pmpaddr csr's : None : readback of pmpaddr value + + +write64_test: + // address to write in x28, double value in x29 + sd x29, 0(x28) + j test_loop // go to next test case + +write32_test: + // address to write in x28, word value in x29 + sw x29, 0(x28) + j test_loop // go to next test case + +write16_test: + // address to write in x28, halfword value in x29 + sh x29, 0(x28) + j test_loop // go to next test case + +write08_test: + // address to write in x28, value in x29 + sb x29, 0(x28) + j test_loop // go to next test case + +read64_test: + // address to read in x28, expected 64 bit value in x29 (unused, but there for your perusal). + li x7, 0xBAD // bad value that will be overwritten on good reads. + ld x7, 0(x28) + sd x7, 0(x6) + addi x6, x6, 8 + addi x16, x16, 8 + j test_loop // go to next test case + +read32_test: + // address to read in x28, expected 32 bit value in x29 (unused, but there for your perusal). + li x7, 0xBAD // bad value that will be overwritten on good reads. + lw x7, 0(x28) + sd x7, 0(x6) + addi x6, x6, 8 + addi x16, x16, 8 + j test_loop // go to next test case + +read16_test: + // address to read in x28, expected 16 bit value in x29 (unused, but there for your perusal). + li x7, 0xBAD // bad value that will be overwritten on good reads. + lh x7, 0(x28) + sd x7, 0(x6) + addi x6, x6, 8 + addi x16, x16, 8 + j test_loop // go to next test case + +read08_test: + // address to read in x28, expected 8 bit value in x29 (unused, but there for your perusal). + li x7, 0xBAD // bad value that will be overwritten on good reads. + lb x7, 0(x28) + sd x7, 0(x6) + addi x6, x6, 8 + addi x16, x16, 8 + j test_loop // go to next test case + +goto_s_mode: + // return to address in x28, + li a0, 3 // Trap handler behavior (go to supervisor mode) + mv a1, x28 // return VPN + mv a2, x29 // return page types + ecall // writes mcause to the output. + // now in S mode + j test_loop + +goto_m_mode: + li a0, 2 // Trap handler behavior (go to machine mode) + mv a1, x28 // return VPN + mv a2, x29 // return page types + ecall // writes mcause to the output. + j test_loop + +goto_u_mode: + li a0, 4 // Trap handler behavior (go to user mode) + mv a1, x28 // return VPN + mv a2, x29 // return page types + ecall // writes mcause to the output. + j test_loop + +goto_baremetal: + // Turn translation off + li x7, 0 // satp.MODE value for bare metal (0) + slli x7, x7, 60 + li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. + add x7, x7, x28 + csrw satp, x7 + sfence.vma x0, x0 // *** flushes global pte's as well + j test_loop // go to next test case + +goto_sv39: + li x7, 8 // satp.MODE value for Sv39 (8) + slli x7, x7, 60 + li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. + add x7, x7, x28 + csrw satp, x7 + sfence.vma x0, x0 // *** flushes global pte's as well + j test_loop // go to next test case + +goto_sv48: + li x7, 9 // satp.MODE value for Sv48 + slli x7, x7, 60 + li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. + add x7, x7, x28 + csrw satp, x7 + sfence.vma x0, x0 // *** flushes global pte's as well + j test_loop // go to next test case + +write_mxr_sum: + // writes sstatus.[mxr, sum] with the (assumed to be) 2 bit value in x29. also assumes we're in S. M mode + li x30, 0xC0000 // mask bits for MXR, SUM + not x7, x29 + slli x7, x7, 18 + and x7, x7, x30 + slli x29, x29, 18 + csrc sstatus, x7 + csrs sstatus, x29 + j test_loop + +write_pmpcfg_0: + // writes the value in x29 to the pmpcfg register specified in x28. + // then writes the final value of pmpcfgX to the output. + li x7, 0x0 + bne x7, x28, write_pmpcfg_2 + csrw pmpcfg0, x29 + csrr x30, pmpcfg0 +write_pmpcfg_2: + li x7, 0x2 + bne x7, x28, write_pmpcfg_end + csrw pmpcfg2, x29 + csrr x30, pmpcfg2 // I would use csrrw but we need the value AFTER the csr has been written +write_pmpcfg_end: + sd x30, 0(x6) + addi x6, x6, 8 + addi x16, x16, 8 + j test_loop + +write_pmpaddr_0: + // writes the value in x29 to the pmpaddr register specified in x28. + // then writes the final value of pmpaddrX to the output. + li x7, 0x0 + bne x7, x28, write_pmpaddr_1 + csrw pmpaddr0, x29 + csrr x30, pmpaddr0 + j write_pmpaddr_end +write_pmpaddr_1: + li x7, 0x1 + bne x7, x28, write_pmpaddr_2 + csrw pmpaddr1, x29 + csrr x30, pmpaddr1 + j write_pmpaddr_end +write_pmpaddr_2: + li x7, 0x2 + bne x7, x28, write_pmpaddr_3 + csrw pmpaddr2, x29 + csrr x30, pmpaddr2 + j write_pmpaddr_end +write_pmpaddr_3: + li x7, 0x3 + bne x7, x28, write_pmpaddr_4 + csrw pmpaddr3, x29 + csrr x30, pmpaddr3 + j write_pmpaddr_end +write_pmpaddr_4: + li x7, 0x4 + bne x7, x28, write_pmpaddr_5 + csrw pmpaddr4, x29 + csrr x30, pmpaddr4 + j write_pmpaddr_end +write_pmpaddr_5: + li x7, 0x5 + bne x7, x28, write_pmpaddr_6 + csrw pmpaddr5, x29 + csrr x30, pmpaddr5 + j write_pmpaddr_end +write_pmpaddr_6: + li x7, 0x6 + bne x7, x28, write_pmpaddr_7 + csrw pmpaddr6, x29 + csrr x30, pmpaddr6 + j write_pmpaddr_end +write_pmpaddr_7: + li x7, 0x7 + bne x7, x28, write_pmpaddr_8 + csrw pmpaddr7, x29 + csrr x30, pmpaddr7 + j write_pmpaddr_end +write_pmpaddr_8: + li x7, 0x8 + bne x7, x28, write_pmpaddr_9 + csrw pmpaddr8, x29 + csrr x30, pmpaddr8 + j write_pmpaddr_end +write_pmpaddr_9: + li x7, 0x9 + bne x7, x28, write_pmpaddr_10 + csrw pmpaddr9, x29 + csrr x30, pmpaddr9 + j write_pmpaddr_end +write_pmpaddr_10: + li x7, 0xA + bne x7, x28, write_pmpaddr_11 + csrw pmpaddr10, x29 + csrr x30, pmpaddr10 + j write_pmpaddr_end +write_pmpaddr_11: + li x7, 0xB + bne x7, x28, write_pmpaddr_12 + csrw pmpaddr11, x29 + csrr x30, pmpaddr11 + j write_pmpaddr_end +write_pmpaddr_12: + li x7, 0xC + bne x7, x28, write_pmpaddr_13 + csrw pmpaddr12, x29 + csrr x30, pmpaddr12 + j write_pmpaddr_end +write_pmpaddr_13: + li x7, 0xD + bne x7, x28, write_pmpaddr_14 + csrw pmpaddr13, x29 + csrr x30, pmpaddr13 + j write_pmpaddr_end +write_pmpaddr_14: + li x7, 0xE + bne x7, x28, write_pmpaddr_15 + csrw pmpaddr14, x29 + csrr x30, pmpaddr14 + j write_pmpaddr_end +write_pmpaddr_15: + li x7, 0xF + bne x7, x28, write_pmpaddr_end + csrw pmpaddr15, x29 + csrr x30, pmpaddr15 + j write_pmpaddr_end +write_pmpaddr_end: + sd x30, 0(x6) + addi x6, x6, 8 + addi x16, x16, 8 + j test_loop + +executable_test: + // Execute the code at the address in x28, returning the value in x7. + // Assumes the code modifies x7, to become the value stored in x29 for this test. + fence.i // forces cache and main memory to sync so execution code written by the program can run. + li x7, 0xBAD + jalr x28 + sd x7, 0(x6) + addi x6, x6, 8 + addi x16, x16, 8 + j test_loop + +terminate_test: + + li a0, 2 // Trap handler behavior (go to machine mode) + ecall // writes mcause to the output. + csrw mtvec, x4 // restore original trap handler to halt program + +RVTEST_CODE_END +RVMODEL_HALT + +RVTEST_DATA_BEGIN +.align 4 +rvtest_data: +.word 0xbabecafe +RVTEST_DATA_END + +.align 3 // align stack to 8 byte boundary +bottom_of_stack: + .fill 1024, 4, 0xdeadbeef +top_of_stack: + + +RVMODEL_DATA_BEGIN + +test_1_res: + .fill 1024, 4, 0xdeadbeef + +RVMODEL_DATA_END + +#ifdef rvtest_mtrap_routine + +mtrap_sigptr: + .fill 64*(XLEN/32),4,0xdeadbeef + +#endif + +#ifdef rvtest_gpr_save + +gpr_save: + .fill 32*(XLEN/32),4,0xdeadbeef + +#endif + +.align 3 +test_cases: + diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-MACROS-64.h b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-MACROS-64.h new file mode 100644 index 000000000..a044f737c --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-MACROS-64.h @@ -0,0 +1,560 @@ +/////////////////////////////////////////// +// +// WALLY-TEST-LIB-64.h +// +// Author: Kip Macsai-Goren +// +// Created 2022-01-30 +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + + +.macro INIT_TESTS + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I") + +.section .text.init +.globl rvtest_entry_point +rvtest_entry_point: +RVMODEL_BOOT +RVTEST_CODE_BEGIN + + + // --------------------------------------------------------------------------------------------- + // Initialization Overview: + // + // Initialize x6 as a virtual pointer to the test results + // Initialize x16 as a physical pointer to the test results + // Set up stack pointer (sp = x2) + // Set up the exception Handler, keeping the original handler in x4. + // + // --------------------------------------------------------------------------------------------- + + // address for test results + la x6, test_1_res + la x16, test_1_res // x16 reserved for the physical address equivalent of x6 to be used in trap handlers + // any time either is used, both must be updated. + + // address for stack + la sp, top_of_stack + + // trap handler setup + la x1, machine_trap_handler + csrrw x4, mtvec, x1 // x4 reserved for "default" trap handler address that needs to be restored before halting this test. + li a0, 0 + li a1, 0 + li a2, 0 // reset trap handler inputs to zero + + // go to first test! + j begin_test + + + // --------------------------------------------------------------------------------------------- + // General traps Handler + // + // Handles traps by branching to different behaviors based on mcause. + // + // Note that allowing the exception handler to change mode for a program is a huge security + // hole, but this is an expedient way of writing tests that need different modes + // + // input parameters: + // + // a0 (x10): + // 0: halt program with no failures + // 1: halt program with failure in x11 = a1 + // 2: go to machine mode + // 3: go to supervisor mode + // 4: go to user mode + // others: do nothing + // + // a1 (x11): + // VPN for return address after changing privilege mode. + // This should be the base VPN with no offset. + // 0x0 : defaults to next instruction on the same page the trap was called on. + // + // a2 (x12): + // Pagetype of the current address VPN before changing privilge mode + // Used so that we can know how many bits of the adress are the offset. + // Ignored if a1 == 0x0 + // 0: Kilopage + // 1: Megapage + // 2: Gigapage + // 3: Terapage + // + // -------------------------------------------------------------------------------------------- + + +machine_trap_handler: + // The processor is always in machine mode when a trap takes us here + // save registers on stack before using + sd x1, -8(sp) + sd x5, -16(sp) + + // Record trap + csrr x1, mcause // record the mcause + sd x1, 0(x16) + addi x6, x6, 8 + addi x16, x16, 8 // update pointers for logging results + + // Respond to trap based on cause + // All interrupts should return after being logged + li x5, 0x8000000000000000 // if msb is set, it is an interrupt + and x5, x5, x1 + bnez x5, trapreturn // return from interrupt + // Other trap handling is specified in the vector Table + slli x1, x1, 3 // multiply cause by 8 to get offset in vector Table + la x5, trap_handler_vector_table + add x5, x5, x1 // compute address of vector in Table + ld x5, 0(x5) // fectch address of handler from vector Table + jr x5 // and jump to the handler + +segfault: + ld x5, -16(sp) // restore registers from stack before faulting + ld x1, -8(sp) + j terminate_test // halt program. + +trapreturn: + // look at the instruction to figure out whether to add 2 or 4 bytes to PC, or go to address specified in a1 + csrr x1, mepc // get the mepc + addi x1, x1, 4 // *** should be 2 for compressed instructions, see note. + + +// ****** KMG: the following is no longer as easy to determine. mepc gets the virtual address of the trapped instruction, +// ******** but in the handler, we work in M mode with physical addresses +// This means the address in mepc is suddenly pointing somewhere else. +// to get this to work, We could either retranslate the vaddr back into a paddr (probably on the scale of difficult to intractible) +// or we could come up with some other ingenious way to stay in M mode and see if the instruction was compressed. + +// lw x5, 0(x1) // read the faulting instruction +// li x1, 3 // check bottom 2 bits of instruction to see if compressed +// and x5, x5, x1 // mask the other bits +// beq x5, x1, trapreturn_uncompressed // if 11, the instruction is return_uncompressed + +// trapreturn_compressed: +// csrr x1, mepc // get the mepc again +// addi x1, x1, 2 // add 2 to find the next instruction +// j trapreturn_specified // and return + +// trapreturn_uncompressed: +// csrr x1, mepc // get the mepc again +// addi x1, x1, 4 // add 4 to find the next instruction + +trapreturn_specified: + // reset the necessary pointers and registers (x1, x5, x6, and the return address going to mepc) + // so that when we return to a new virtual address, they're all in the right spot as well. + + beqz a1, trapreturn_finished // either update values, of go to default return address. + + la x5, trap_return_pagetype_table + slli a2, a2, 3 + add x5, x5, a2 + ld a2, 0(x5) // a2 = number of offset bits in current page type + + li x5, 1 + sll x5, x5, a2 + addi x5, x5, -1 // x5 = mask bits for offset into current pagetype + + // reset the top of the stack, x1 + ld x7, -8(sp) + and x7, x5, x7 // x7 = offset for x1 + add x7, x7, a1 // x7 = new address for x1 + sd x7, -8(sp) + + // reset the second spot in the stack, x5 + ld x7, -16(sp) + and x7, x5, x7 // x7 = offset for x5 + add x7, x7, a1 // x7 = new address for x5 + sd x7, -16(sp) + + // reset x6, the pointer for the virtual address of the output of the tests + and x7, x5, x6 // x7 = offset for x6 + add x6, x7, a1 // x6 = new address for the result pointer + + // set return address, stored temporarily in x1, to the next instruction, but in the new virtual page. + and x1, x5, x1 // x1 = offset for the return address + add x1, x1, a1 // x1 = new return address. + + li a1, 0 + li a2, 0 // reset trapreturn inputs to the trap handler + +trapreturn_finished: + csrw mepc, x1 // update the mepc with address of next instruction + ld x5, -16(sp) // restore registers from stack before returning + ld x1, -8(sp) + mret // return from trap + +ecallhandler: + // Check input parameter a0. encoding above. + // *** ASSUMES: that this trap is being handled in machine mode. in other words, that nothing odd has been written to the medeleg or mideleg csrs. + li x5, 2 // case 2: change to machine mode + beq a0, x5, ecallhandler_changetomachinemode + li x5, 3 // case 3: change to supervisor mode + beq a0, x5, ecallhandler_changetosupervisormode + li x5, 4 // case 4: change to user mode + beq a0, x5, ecallhandler_changetousermode + // unsupported ecalls should segfault + j segfault + +ecallhandler_changetomachinemode: + // Force mstatus.MPP (bits 12:11) to 11 to enter machine mode after mret + li x1, 0b1100000000000 + csrs mstatus, x1 + j trapreturn + +ecallhandler_changetosupervisormode: + // Force mstatus.MPP (bits 12:11) to 01 to enter supervisor mode after mret + li x1, 0b1100000000000 + csrc mstatus, x1 + li x1, 0b0100000000000 + csrs mstatus, x1 + j trapreturn + +ecallhandler_changetousermode: + // Force mstatus.MPP (bits 12:11) to 00 to enter user mode after mret + li x1, 0b1100000000000 + csrc mstatus, x1 + j trapreturn + +instrfault: + ld x1, -8(sp) // load return address int x1 (the address AFTER the jal into faulting page) + j trapreturn_finished // puts x1 into mepc, restores stack and returns to program (outside of faulting page) + +illegalinstr: + j trapreturn // return to the code after recording the mcause + +accessfault: + // *** What do I have to do here? + j trapreturn + + // Table of trap behavior + // lists what to do on each exception (not interrupts) + // unexpected exceptions should cause segfaults for easy detection + // Expected exceptions should increment the EPC to the next instruction and return + + .align 3 // aligns this data table to an 8 byte boundary +trap_handler_vector_table: + .8byte segfault // 0: instruction address misaligned + .8byte instrfault // 1: instruction access fault + .8byte illegalinstr // 2: illegal instruction + .8byte segfault // 3: breakpoint + .8byte segfault // 4: load address misaligned + .8byte accessfault // 5: load access fault + .8byte segfault // 6: store address misaligned + .8byte accessfault // 7: store access fault + .8byte ecallhandler // 8: ecall from U-mode + .8byte ecallhandler // 9: ecall from S-mode + .8byte segfault // 10: reserved + .8byte ecallhandler // 11: ecall from M-mode + .8byte instrfault // 12: instruction page fault + .8byte trapreturn // 13: load page fault + .8byte segfault // 14: reserved + .8byte trapreturn // 15: store page fault + +.align 3 +trap_return_pagetype_table: + .8byte 0xC // 0: kilopage has 12 offset bits + .8byte 0x15 // 1: megapage has 21 offset bits + .8byte 0x1E // 2: gigapage has 30 offset bits + .8byte 0x27 // 3: terapage has 39 offset bits + +begin_test: // label here to jump to so we dont go through the trap handler before starting the test + +.endm // Ends the initialization macro that set up the begginnning of the tests and the trap handler. + + +// Test Summary table! + +// Test Name : Description : Fault output value : Normal output values +// ---------------------:-------------------------------------------:-------------------------------:------------------------------------------------------ +// write64_test : Write 64 bits to address : 0x6, 0x7, or 0xf : None +// write32_test : Write 32 bits to address : 0x6, 0x7, or 0xf : None +// write16_test : Write 16 bits to address : 0x6, 0x7, or 0xf : None +// write08_test : Write 8 bits to address : 0x6, 0x7, or 0xf : None +// read64_test : Read 64 bits from address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex +// read32_test : Read 32 bitsfrom address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex +// read16_test : Read 16 bitsfrom address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex +// read08_test : Read 8 bitsfrom address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex +// executable_test : test executable on virtual page : 0x0, 0x1, or 0xc, then 0xbad : value of x7 modified by exectuion code (usually 0x111) +// terminate_test : terminate tests : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 +// goto_baremetal : satp.MODE = bare metal : None : None +// goto_sv39 : satp.MODE = sv39 : None : None +// goto_sv48 : satp.MODE = sv48 : None : None +// goto_m_mode : go to mahcine mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 +// goto_s_mode : go to supervisor mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 +// goto_u_mode : go to user mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 +// write_csr : write to specified CSR : CSR value before test attempt : value written to CSR +// read_csr : read from specified CSR : *** None? Mcause or fault? : value read back from CSR + + +// *** TESTS TO ADD: execute inline, read unknown value out, read CSR unknown value + +.macro write64_test ADDR VAL + // attempt to write VAL to ADDR + // Success outputs: + // None + // Fault outputs: + // 0x6: misaligned address + // 0x7: access fault + // 0xf: page fault + li x29, \VAL + li x30, \ADDR + sd x29, 0(x30) +.endm + +.macro write32_test ADDR VAL + // all write tests have the same description/outputs as write64 + li x29, \VAL + li x30, \ADDR + sw x29, 0(x30) +.endm + +.macro write16_test ADDR VAL + // all write tests have the same description/outputs as write64 + li x29, \VAL + li x30, \ADDR + sh x29, 0(x30) +.endm + +.macro write08_test ADDR VAL + // all write tests have the same description/outputs as write64 + li x29, \VAL + li x30, \ADDR + sb x29, 0(x30) +.endm + +.macro read64_test ADDR + // Attempt read at ADDR. Write the value read out to the output *** Consider adding specific test for reading a non known value + // Success outputs: + // value read out from ADDR + // Fault outputs: + // One of the following followed by 0xBAD + // 0x4: misaligned address + // 0x5: access fault + // 0xD: page fault + li x7, 0xBAD // bad value that will be overwritten on good reads. + li x29, \ADDR + ld x7, 0(x29) + sd x7, 0(x6) + addi x6, x6, 8 + addi x16, x16, 8 +.endm + +.macro read32_test ADDR + // All reads have the same description/outputs as read64. + // They will store the sign extended value of what was read out at ADDR + li x7, 0xBAD // bad value that will be overwritten on good reads. + li x29, \ADDR + lw x7, 0(x29) + sd x7, 0(x6) + addi x6, x6, 8 + addi x16, x16, 8 +.endm + +.macro read16_test ADDR + // All reads have the same description/outputs as read64. + // They will store the sign extended value of what was read out at ADDR + li x7, 0xBAD // bad value that will be overwritten on good reads. + li x29, \ADDR + lh x7, 0(x29) + sd x7, 0(x6) + addi x6, x6, 8 + addi x16, x16, 8 +.endm + +.macro read08_test ADDR + // All reads have the same description/outputs as read64. + // They will store the sign extended value of what was read out at ADDR + li x7, 0xBAD // bad value that will be overwritten on good reads. + li x29, \ADDR + lb x7, 0(x29) + sd x7, 0(x6) + addi x6, x6, 8 + addi x16, x16, 8 +.endm + +// These goto_x_mode tests all involve invoking the trap handler, +// So their outputs are inevitably: +// 0x8: test called from U mode +// 0x9: test called from S mode +// 0xB: test called from M mode +// they generally do not fault or cause issues as long as these modes are enabled +// *** add functionality to check if modes are enabled before jumping? maybe cause a fault if not? + +.macro goto_m_mode RETURN_VPN RETURN_PAGETYPE + li a0, 2 // determine trap handler behavior (go to supervisor mode) + li a1, \RETURN_VPN // return VPN + li a2, \RETURN_PAGETYPE // return page types + ecall // writes mcause to the output. + // now in S mode +.endm + +.macro goto_s_mode RETURN_VPN RETURN_PAGETYPE + li a0, 3 // determine trap handler behavior (go to supervisor mode) + li a1, \RETURN_VPN // return VPN + li a2, \RETURN_PAGETYPE // return page types + ecall // writes mcause to the output. + // now in S mode +.endm + +.macro goto_u_mode RETURN_VPN RETURN_PAGETYPE + li a0, 4 // determine trap handler behavior (go to supervisor mode) + li a1, \RETURN_VPN // return VPN + li a2, \RETURN_PAGETYPE // return page types + ecall // writes mcause to the output. + // now in S mode +.endm + +// These tests change virtual memory settings, turning it on/off and changing between types. +// They don't have outputs as any error with turning on virtual memory should reveal itself in the tests *** Consider changing this policy? + +.macro goto_baremetal + // Turn translation off + li x7, 0 // satp.MODE value for bare metal (0) + slli x7, x7, 60 + li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. *** add option for different pagetable location + add x7, x7, x28 + csrw satp, x7 + sfence.vma x0, x0 // *** flushes global pte's as well +.endm + +.macro goto_sv39 + // Turn on sv39 virtual memory + li x7, 8 // satp.MODE value for Sv39 (8) + slli x7, x7, 60 + li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. *** add option for different pagetable location + add x7, x7, x28 + csrw satp, x7 + sfence.vma x0, x0 // *** flushes global pte's as well +.endm + +.macro goto_sv48 + // Turn on sv48 virtual memory + li x7, 9 // satp.MODE value for Sv39 (8) + slli x7, x7, 60 + li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. *** add option for different pagetable location + add x7, x7, x28 + csrw satp, x7 + sfence.vma x0, x0 // *** flushes global pte's as well +.endm + +.macro write_csr CSR VAL + // attempt to write CSR with VAL *** ASSUMES RW access to CSR in whatever privilege mode is running + // Success outputs: + // value read back out from CSR after writing + // Fault outputs: + // The previous CSR value before write attempt + // *** Is there an associated mstatus? maybe 0x2??? + li x29, \VAL + csrw \CSR\(), x29 + csrr x30, \CSR + sd x30, 0(x6) + addi x6, x6, 8 + addi x16, x16, 8 +.endm + +.macro csr_r_access CSR + // verify that a csr is accessible to read but not to write + // Success outputs: + // 0x2, then + // 0x11 *** consider changing to something more meaningful + // Fault outputs: + // 0xBAD *** consider changing this one as well. in general, do we need the branching if it hould cause an illegal instruction fault? + csrr x29, \CSR + csrwi \CSR\(), 0xA // Attempt to write a 'random' value to the CSR + csrr x30, \CSR + bne x30, x29, 1f // 1f represents write_access + li x30, 0x11 // Write succeeded, violating read only permissions. + j 2f // j r_access_end +1: // w_access (test failed) + li x30, 0xBAD +2: // r_access end + sd x30, 0(x6) + addi x6, x6, 8 + addi x16, x16, 8 +.endm + +.macro execute_at_address ADDR + // Execute the code already written to ADDR, returning the value in x7. + // *** Note: this test itself doesn't write the code to ADDR because it might be callled at a point where we dont have write access to ADDR + // Assumes the code modifies x7, usually to become 0x111. + // Sample code: 0x11100393 (li x7, 0x111), 0x00008067 (ret) + // Success outputs: + // modified value of x7. (0x111 if you use the sample code) + // Fault outputs: + // One of the following followed by 0xBAD + // 0x0: misaligned address + // 0x1: access fault + // 0xC: page fault + fence.i // forces caches and main memory to sync so execution code written to ADDR can run. + li x7, 0xBAD + li x28, \ADDR + jalr x28 // jump to executable test code + sd x7, 0(x6) + addi x6, x6, 8 + addi x16, x16, 8 +.endm + +.macro END_TESTS +// invokes one final ecall to return to machine mode then terminates this program, so the output is +// 0x8: termination called from U mode +// 0x9: termination called from S mode +// 0xB: termination called from M mode + +terminate_test: + + li a0, 2 // Trap handler behavior (go to machine mode) + ecall // writes mcause to the output. + csrw mtvec, x4 // restore original trap handler to halt program + +RVTEST_CODE_END +RVMODEL_HALT + +RVTEST_DATA_BEGIN +.align 4 +rvtest_data: +.word 0xbabecafe +RVTEST_DATA_END + +.align 3 // align stack to 8 byte boundary +bottom_of_stack: + .fill 1024, 4, 0xdeadbeef +top_of_stack: + + +RVMODEL_DATA_BEGIN + +test_1_res: + .fill 1024, 4, 0xdeadbeef + +RVMODEL_DATA_END + +#ifdef rvtest_mtrap_routine + +mtrap_sigptr: + .fill 64*(XLEN/32),4,0xdeadbeef + +#endif + +#ifdef rvtest_gpr_save + +gpr_save: + .fill 32*(XLEN/32),4,0xdeadbeef + +#endif + +.endm // ends the macro that terminates this test program. \ No newline at end of file diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-minfo-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-minfo-01.S new file mode 100644 index 000000000..2367a32bb --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-minfo-01.S @@ -0,0 +1,37 @@ +/////////////////////////////////////////// +// +// WALLY-MMU +// +// Author: Kip Macsai-Goren +// +// Created 2022-01-25 +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +#include "WALLY-TEST-MACROS-64.h" + +INIT_TESTS + +// Test 5.2.3.1: tersting Read-only access to Machine info CSRs + +csr_r_access mvendorid +csr_r_access marchid +csr_r_access mimpid +csr_r_access mhartid +# csr_r_access mconfigptr # Unimplemented in spike as of 31 Jan 22 + + +END_TESTS \ No newline at end of file