From dce6d335311bb4edbea1188b6df0fd41b10fdbc2 Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 7 Mar 2023 06:31:40 -0800 Subject: [PATCH 01/25] editorconfig to specify tabs/spaces. Fixed some tabs. Turn off coverage to speed up simulation --- .editorconfig | 5 +++++ sim/wally-batch.do | 12 +++++++++++- src/fpu/fdivsqrt/fdivsqrtexpcalc.sv | 2 +- src/fpu/fdivsqrt/fdivsqrtpreproc.sv | 2 +- src/mdu/mdu.sv | 10 +++++----- 5 files changed, 23 insertions(+), 8 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..2a9c5c8c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +root = true + +[src/**.sv] +indent_style = space +indent_size = 2 \ No newline at end of file diff --git a/sim/wally-batch.do b/sim/wally-batch.do index 7e63de8a..53ea2e00 100644 --- a/sim/wally-batch.do +++ b/sim/wally-batch.do @@ -32,6 +32,9 @@ if {$2 eq "ahb"} { } vlib wkdir/work_${1}_${2} } +# Create directory for coverage data +mkdir -p cov + # compile source files # suppress spurious warnngs about # "Extra checking for conflicts with always_comb done at vopt time" @@ -80,7 +83,8 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals - vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt + vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt +cover=sbectf +# vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 -coverage vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 # Adding coverage increases runtime from 2:00 to 4:29. Can't run it all the time #vopt work_$2.testbench -work work_$2 -o workopt_$2 +cover=sbectf @@ -91,6 +95,12 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { # power off -r /dut/core/* } +coverage save -instance /testbench/dut cov/${1}_${2}.ucdb +#vcover merge -out cov/cov.ucdb cov/rv*.ucdb +#vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb -logfile cov/log + +#vcover merge -out cov/cov.ucdb cov +#vcover report cov/cov.ucdb > cov/rpt #coverage report -file wally-coverage.txt # These aren't doing anything helpful #coverage report -memory diff --git a/src/fpu/fdivsqrt/fdivsqrtexpcalc.sv b/src/fpu/fdivsqrt/fdivsqrtexpcalc.sv index 07cffa26..b5b2ba33 100644 --- a/src/fpu/fdivsqrt/fdivsqrtexpcalc.sv +++ b/src/fpu/fdivsqrt/fdivsqrtexpcalc.sv @@ -69,6 +69,6 @@ module fdivsqrtexpcalc( assign SExp = {SXExp[`NE+1], SXExp[`NE+1:1]} + {2'b0, Bias}; // correct exponent for subnormal input's normalization shifts - assign DExp = ({2'b0, Xe} - {{(`NE+1-`DIVBLEN){1'b0}}, ell} - {2'b0, Ye} + {{(`NE+1-`DIVBLEN){1'b0}}, m} + {3'b0, Bias}) & {`NE+2{~XZero}}; + assign DExp = ({2'b0, Xe} - {{(`NE+1-`DIVBLEN){1'b0}}, ell} - {2'b0, Ye} + {{(`NE+1-`DIVBLEN){1'b0}}, m} + {3'b0, Bias}) & {`NE+2{~XZero}}; // *** why Xzero? Is this a hack for postprocessor? assign Qe = Sqrt ? SExp : DExp; endmodule diff --git a/src/fpu/fdivsqrt/fdivsqrtpreproc.sv b/src/fpu/fdivsqrt/fdivsqrtpreproc.sv index 0a96e1b1..c5485c26 100644 --- a/src/fpu/fdivsqrt/fdivsqrtpreproc.sv +++ b/src/fpu/fdivsqrt/fdivsqrtpreproc.sv @@ -151,7 +151,7 @@ module fdivsqrtpreproc ( lzc #(`DIVb) lzcY (IFNormLenD, mE); // Normalization shift - assign XPreproc = IFNormLenX << (ell + {{`DIVBLEN{1'b0}}, 1'b1}); + assign XPreproc = IFNormLenX << (ell + {{`DIVBLEN{1'b0}}, 1'b1}); // *** try to remove this +1 assign DPreproc = IFNormLenD << (mE + {{`DIVBLEN{1'b0}}, 1'b1}); // append leading 1 (for normal inputs) diff --git a/src/mdu/mdu.sv b/src/mdu/mdu.sv index b62add60..21d4dd4b 100644 --- a/src/mdu/mdu.sv +++ b/src/mdu/mdu.sv @@ -32,11 +32,11 @@ module mdu( input logic clk, reset, input logic StallM, StallW, input logic FlushE, FlushM, FlushW, - input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // inputs A and B from IEU forwarding mux output - input logic [2:0] Funct3E, Funct3M, // type of MDU operation - input logic IntDivE, W64E, // Integer division/remainder, and W-type instrutions - output logic [`XLEN-1:0] MDUResultW, // multiply/divide result - output logic DivBusyE // busy signal to stall pipeline in Execute stage + input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // inputs A and B from IEU forwarding mux output + input logic [2:0] Funct3E, Funct3M, // type of MDU operation + input logic IntDivE, W64E, // Integer division/remainder, and W-type instrutions + output logic [`XLEN-1:0] MDUResultW, // multiply/divide result + output logic DivBusyE // busy signal to stall pipeline in Execute stage ); logic [`XLEN*2-1:0] ProdM; // double-width product from mul From 6d2d7d181eabf6068ec0a16c91a69769d84bfa72 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 8 Mar 2023 17:11:27 -0600 Subject: [PATCH 02/25] Updated testbench to record coremark performance counters. Added comment about mtval probably not being correct for compressed instructions. --- sim/wave.do | 9 ++++----- src/privileged/csr.sv | 2 +- testbench/testbench.sv | 11 +++++++++++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/sim/wave.do b/sim/wave.do index fd95f6f1..5aa5deb0 100644 --- a/sim/wave.do +++ b/sim/wave.do @@ -366,11 +366,9 @@ add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VI add wave -noupdate -group lsu -expand -group ptwalker -color Gold /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/WalkerState add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/HPTWAdr add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/PTE -add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/PCFSpill add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/NextPageType add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/PageType add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/ValidNonLeafPTE -add wave -noupdate -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/PCFSpill add wave -noupdate -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/ITLBMissF add wave -noupdate -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/DTLBMissM add wave -noupdate -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/hptw/ITLBWriteF @@ -467,7 +465,6 @@ add wave -noupdate -group ifu -group Spill -expand -group takespill /testbench/d add wave -noupdate -group ifu -group Spill -expand -group takespill /testbench/dut/core/ifu/Spill/spill/IFUCacheBusStallD add wave -noupdate -group ifu -group Spill -expand -group takespill /testbench/dut/core/ifu/Spill/spill/ITLBMissF add wave -noupdate -group ifu -group Spill -expand -group takespill /testbench/dut/core/ifu/Spill/spill/TakeSpillF -add wave -noupdate -group ifu -group Spill /testbench/dut/core/ifu/SelNextSpillF add wave -noupdate -group ifu -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HSIZE add wave -noupdate -group ifu -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HBURST add wave -noupdate -group ifu -group bus /testbench/dut/core/ifu/bus/icache/ahbcacheinterface/HTRANS @@ -635,8 +632,10 @@ add wave -noupdate /testbench/dut/core/priv/priv/csr/counters/counters/DCacheMis add wave -noupdate /testbench/dut/core/priv/priv/csr/counters/counters/InstrValidNotFlushedM add wave -noupdate /testbench/clk add wave -noupdate /testbench/HPMCSample/InitialHPMCOUNTERH +add wave -noupdate /testbench/HPMCSample/EndSample +add wave -noupdate /testbench/HPMCSample/StartSample TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 2} {314596 ns} 1} {{Cursor 3} {314460 ns} 1} {{Cursor 4} {391801 ns} 1} {{Cursor 4} {49231900 ns} 0} {{Cursor 5} {394987 ns} 1} +WaveRestoreCursors {{Cursor 2} {314596 ns} 1} {{Cursor 3} {314460 ns} 1} {{Cursor 4} {391801 ns} 1} {{Cursor 4} {23 ns} 0} {{Cursor 5} {394987 ns} 1} quietly wave cursor active 4 configure wave -namecolwidth 250 configure wave -valuecolwidth 194 @@ -652,4 +651,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update -WaveRestoreZoom {49231842 ns} {49231960 ns} +WaveRestoreZoom {0 ns} {52 ns} diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index d97be53f..0764e6c6 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -133,7 +133,7 @@ module csr #(parameter if (InterruptM) NextFaultMtvalM = 0; else case (CauseM) 12, 1, 3: NextFaultMtvalM = PCM; // Instruction page/access faults, breakpoint - 2: NextFaultMtvalM = {{(`XLEN-32){1'b0}}, InstrM}; // Illegal instruction fault + 2: NextFaultMtvalM = {{(`XLEN-32){1'b0}}, InstrM}; // Illegal instruction fault // *** this should probably set to the uncompressed instruction 0, 4, 6, 13, 15, 5, 7: NextFaultMtvalM = IEUAdrM; // Instruction misaligned, Load/Store Misaligned/page/access faults default: NextFaultMtvalM = 0; // Ecall, interrupts endcase diff --git a/testbench/testbench.sv b/testbench/testbench.sv index c4581fa8..b0af190a 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -447,6 +447,17 @@ logic [3:0] dummy; flopr #(1) EndSampleReg(clk, reset, EndSampleFirst, EndSampleDelayed); assign EndSample = EndSampleFirst & ~ EndSampleDelayed; + end else if(TEST == "coremark") begin + // embench runs warmup then runs start_trigger + // embench end with stop_trigger. + assign StartSampleFirst = FunctionName.FunctionName.FunctionName == "start_time"; + flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed); + assign StartSample = StartSampleFirst & ~ StartSampleDelayed; + + assign EndSampleFirst = FunctionName.FunctionName.FunctionName == "stop_time"; + flopr #(1) EndSampleReg(clk, reset, EndSampleFirst, EndSampleDelayed); + assign EndSample = EndSampleFirst & ~ EndSampleDelayed; + end else begin // default start condiction is reset // default end condiction is end of test (DCacheFlushDone) From 26144482184dbdd279c14eaf6915831c847c6aac Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 9 Mar 2023 15:14:52 -0800 Subject: [PATCH 03/25] Simplified SLT and SLTU code in ALU --- src/ieu/alu.sv | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index ccd55779..4725d632 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -38,7 +38,7 @@ module alu #(parameter WIDTH=32) ( // CondInvB = ~B when subtracting, B otherwise. Shift = shift result. SLT/U = result of a slt/u instruction. // FullResult = ALU result before adjusting for a RV64 w-suffix instruction. - logic [WIDTH-1:0] CondInvB, Shift, SLT, SLTU, FullResult; // Intermediate results + logic [WIDTH-1:0] CondInvB, Shift, FullResult; // Intermediate results logic Carry, Neg; // Flags: carry out, negative logic LT, LTU; // Less than, Less than unsigned logic W64; // RV64 W-type instruction @@ -66,21 +66,17 @@ module alu #(parameter WIDTH=32) ( assign LT = Asign & ~Bsign | Asign & Neg | ~Bsign & Neg; assign LTU = ~Carry; - // SLT - assign SLT = {{(WIDTH-1){1'b0}}, LT}; - assign SLTU = {{(WIDTH-1){1'b0}}, LTU}; - // Select appropriate ALU Result always_comb - if (~ALUOp) FullResult = Sum; // Always add for ALUOp = 0 (address generation) - else casez (Funct3) // Otherwise check Funct3 - 3'b000: FullResult = Sum; // add or sub - 3'b?01: FullResult = Shift; // sll, sra, or srl - 3'b010: FullResult = SLT; // slt - 3'b011: FullResult = SLTU; // sltu - 3'b100: FullResult = A ^ B; // xor - 3'b110: FullResult = A | B; // or - 3'b111: FullResult = A & B; // and + if (~ALUOp) FullResult = Sum; // Always add for ALUOp = 0 (address generation) + else casez (Funct3) // Otherwise check Funct3 + 3'b000: FullResult = Sum; // add or sub + 3'b?01: FullResult = Shift; // sll, sra, or srl + 3'b010: FullResult = {{(WIDTH-1){1'b0}}, LT}; // slt + 3'b011: FullResult = {{(WIDTH-1){1'b0}}, LTU}; // sltu + 3'b100: FullResult = A ^ B; // xor + 3'b110: FullResult = A | B; // or + 3'b111: FullResult = A & B; // and endcase // Support RV64I W-type addw/subw/addiw/shifts that discard upper 32 bits and sign-extend 32-bit result to 64 bits From 06b99035d4bc1d849bbf948e976a4a0c5ac17e46 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 9 Mar 2023 15:59:28 -0800 Subject: [PATCH 04/25] Modified setup to add Imperas/scripts/cvw to path --- setup.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/setup.sh b/setup.sh index f6cbac6b..126059df 100755 --- a/setup.sh +++ b/setup.sh @@ -48,8 +48,10 @@ if [ -e "$IDV" ]; then export IMPERAS_HOME=$IDV/Imperas export IMPERAS_PERSONALITY=CPUMAN_DV_ASYNC export ROOTDIR=~/ - source ${IDV}/Imperas/bin/setup.sh - setupImperas ${IDV}/Imperas + source ${IMPERAS_HOME}/bin/setup.sh + setupImperas ${IMPERAS_HOME} + export PATH=$IDV/scripts/cvw:$PATH + echo $PATH fi From a3691cc5f7831c62343f53a4f456b5a628b60b18 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 9 Mar 2023 15:59:57 -0800 Subject: [PATCH 05/25] Modified regression and wally-batch.do to support -coverage --- sim/regression-wally | 36 +++++++++++++++++++++++++++--------- sim/wally-batch.do | 25 ++++++++++++------------- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/sim/regression-wally b/sim/regression-wally index 07603120..ce9387b6 100755 --- a/sim/regression-wally +++ b/sim/regression-wally @@ -27,6 +27,8 @@ from collections import namedtuple regressionDir = os.path.dirname(os.path.abspath(__file__)) os.chdir(regressionDir) +coverage = '-coverage' in sys.argv + TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr']) # name: the name of this test configuration (used in printing human-readable # output and picking logfile names) @@ -66,14 +68,6 @@ tc = TestCase( configs.append(tc) tests64gcimperas = ["imperas64i", "imperas64f", "imperas64d", "imperas64m", "imperas64c"] # unused -tests64gc = ["arch64f", "arch64d", "arch64i", "arch64priv", "arch64c", "arch64m", "arch64zi", "wally64a", "wally64periph", "wally64priv"] -for test in tests64gc: - tc = TestCase( - name=test, - variant="rv64gc", - cmd="vsim > {} -c < {} -c < {} -c < cov/rv64gc_coverage.rpt') # Count the number of failures if num_fail: print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail) diff --git a/sim/wally-batch.do b/sim/wally-batch.do index 718f3d5a..2adc917e 100644 --- a/sim/wally-batch.do +++ b/sim/wally-batch.do @@ -115,27 +115,26 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals - vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt +cover=sbectf -# vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 -coverage - vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 - # Adding coverage increases runtime from 2:00 to 4:29. Can't run it all the time - #vopt work_$2.testbench -work work_$2 -o workopt_$2 +cover=sbectf - #vsim -coverage -lib work_$2 workopt_$2 + if {$3 eq "-coverage"} { + vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt +cover=sbectf + vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 -coverage + } else { + vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt + vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 + } +# vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 # power add generates the logging necessary for said generation. # power add -r /dut/core/* run -all # power off -r /dut/core/* } -coverage save -instance /testbench/dut cov/${1}_${2}.ucdb -#vcover merge -out cov/cov.ucdb cov/rv*.ucdb -#vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb -logfile cov/log +if {$3 eq "-coverage"} { + do coverage-exclusions.do + coverage save -instance /testbench/dut cov/${1}_${2}.ucdb +} -#vcover merge -out cov/cov.ucdb cov -#vcover report cov/cov.ucdb > cov/rpt -#coverage report -file wally-coverage.txt # These aren't doing anything helpful -#coverage report -memory #profile report -calltree -file wally-calltree.rpt -cutoff 2 #power report -all -bsaif power.saif quit From 8e657c335e5ebaaae14bf86d33497745c85d606e Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Fri, 10 Mar 2023 14:09:22 +0000 Subject: [PATCH 06/25] Enhancements to support the PMA ranges --- sim/imperas.ic | 50 +++++++++++++++++++++------------- sim/wally-imperas.do | 2 ++ testbench/testbench_imperas.sv | 27 ++++-------------- 3 files changed, 38 insertions(+), 41 deletions(-) diff --git a/sim/imperas.ic b/sim/imperas.ic index 8b4ef2d4..6a34466f 100644 --- a/sim/imperas.ic +++ b/sim/imperas.ic @@ -1,42 +1,54 @@ #--showoverrides -#--help --helpall +#--showcommands ---override cpu/show_c_prefix=T +# Core settings --override cpu/unaligned=F --override cpu/ignore_non_leaf_DAU=1 --override cpu/wfi_is_nop=T +--override cpu/mimpid=0x100 -# this should be 16 not 0 +# THIS NEEDS FIXING to 16 --override cpu/PMP_registers=0 +# PMA Settings +# 'r': read access allowed +# 'w': write access allowed +# 'x': execute access allowed +# 'a': aligned access required +# 'A': atomic instructions NOT allowed (actually USER1 privilege needed) +# 'P': push/pop instructions NOT allowed (actually USER2 privilege needed) +# '1': 1-byte accesses allowed +# '2': 2-byte accesses allowed +# '4': 4-byte accesses allowed +# '8': 8-byte accesses allowed +# '-', space: ignored (use for input string formatting). +# +# SV39 Memory 0x0000000000 0x7FFFFFFFFF +# +--callcommand refRoot/cpu/setPMA -lo 0x0000000000 -hi 0x7FFFFFFFFF -attributes " ------ ---- "; # INITIAL +--callcommand refRoot/cpu/setPMA -lo 0x0000001000 -hi 0x0000001FFF -attributes " r-x-A- 1248 "; # BOOTROM +--callcommand refRoot/cpu/setPMA -lo 0x0000012100 -hi 0x000001211F -attributes " rw--A- --48 "; # SDC +--callcommand refRoot/cpu/setPMA -lo 0x0002000000 -hi 0x000200FFFF -attributes " rw--A- 1248 "; # CLINT +--callcommand refRoot/cpu/setPMA -lo 0x000C000000 -hi 0x000FFFFFFF -attributes " rw--A- --4- "; # PLIC +--callcommand refRoot/cpu/setPMA -lo 0x0010000000 -hi 0x0010000007 -attributes " rw--A- 1--- "; # UART0 error - 0x10000000 - 0x100000FF +--callcommand refRoot/cpu/setPMA -lo 0x0010060000 -hi 0x00100600FF -attributes " rw--A- --4- "; # GPIO error - 0x10006000 - 0x100060FF +--callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwx--- 1248 "; # UNCORE_RAM + # Enable the Imperas instruction coverage #-extlib refRoot/cpu/cv=imperas.com/intercept/riscvInstructionCoverage/1.0 #-override refRoot/cpu/cv/cover=basic #-override refRoot/cpu/cv/extensions=RV32I # Add Imperas simulator application instruction tracing ---trace ---tracechange ---traceshowicount ---tracemode ---tracemem ASX ---monitornetschange +--override cpu/show_c_prefix=T +--trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange # Exceptions and pagetables debug --override cpu/debugflags=6 -# Turn on verbose output for Imperas simulator +# Turn on verbose output for Imperas simulator and Model --verbose - -# Turn on verbose output for RISCV model --override cpu/verbose=1 # Store simulator output to logfile --output imperas.log - - -# ignore settings of bits DAU for non leaf page table walks ---override cpu/ignore_non_leaf_DAU=1 - -# mimpid = 0x100 ---override cpu/mimpid=0x100 diff --git a/sim/wally-imperas.do b/sim/wally-imperas.do index 985739cb..2de97be2 100644 --- a/sim/wally-imperas.do +++ b/sim/wally-imperas.do @@ -24,6 +24,7 @@ vlib work # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals # *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings. + vlog +incdir+../config/$1 \ +incdir+../config/shared \ +define+USE_IMPERAS_DV \ @@ -42,6 +43,7 @@ vlog +incdir+../config/$1 \ ../src/*/*/*.sv \ -suppress 2583 \ -suppress 7063 + vopt +acc work.testbench -G DEBUG=1 -o workopt vsim workopt +nowarn3829 -fatal 7 \ -sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \ diff --git a/testbench/testbench_imperas.sv b/testbench/testbench_imperas.sv index f5ad63bc..27bd1246 100644 --- a/testbench/testbench_imperas.sv +++ b/testbench/testbench_imperas.sv @@ -138,11 +138,6 @@ module testbench; .CMP_CSR (1) ) idv_trace2api(rvvi); - int PRIV_RWX = RVVI_MEMORY_PRIVILEGE_READ | RVVI_MEMORY_PRIVILEGE_WRITE | RVVI_MEMORY_PRIVILEGE_EXEC; - int PRIV_RW = RVVI_MEMORY_PRIVILEGE_READ | RVVI_MEMORY_PRIVILEGE_WRITE; - int PRIV_RX = RVVI_MEMORY_PRIVILEGE_READ | RVVI_MEMORY_PRIVILEGE_EXEC; - int PRIV_X = RVVI_MEMORY_PRIVILEGE_EXEC; - initial begin MAX_ERRS = 3; @@ -173,37 +168,25 @@ module testbench; void'(rvviRefCsrSetVolatile(0, 32'h344)); // MIP void'(rvviRefCsrSetVolatile(0, 32'h144)); // SIP -/* - // Memory lo, hi, priv (RVVI_MEMORY_PRIVILEGE_{READ,WRITE,EXEC}) - void'(rvviRefMemorySetPrivilege(56'h0, 56'h7fffffffff, 0)); - if (`BOOTROM_SUPPORTED) - void'(rvviRefMemorySetPrivilege(`BOOTROM_BASE, (`BOOTROM_BASE + `BOOTROM_RANGE), PRIV_RX)); - if (`UNCORE_RAM_SUPPORTED) - void'(rvviRefMemorySetPrivilege(`UNCORE_RAM_BASE, (`UNCORE_RAM_BASE + `UNCORE_RAM_RANGE), PRIV_RWX)); - if (`EXT_MEM_SUPPORTED) - void'(rvviRefMemorySetPrivilege(`EXT_MEM_BASE, (`EXT_MEM_BASE + `EXT_MEM_RANGE), PRIV_RWX)); - + // Privileges for PMA are set in the imperas.ic + // volatile (IO) regions are defined here + // only real ROM/RAM areas are BOOTROM and UNCORE_RAM if (`CLINT_SUPPORTED) begin - void'(rvviRefMemorySetPrivilege(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE), PRIV_RW)); void'(rvviRefMemorySetVolatile(`CLINT_BASE, (`CLINT_BASE + `CLINT_RANGE))); end if (`GPIO_SUPPORTED) begin - void'(rvviRefMemorySetPrivilege(`GPIO_BASE, (`GPIO_BASE + `GPIO_RANGE), PRIV_RW)); void'(rvviRefMemorySetVolatile(`GPIO_BASE, (`GPIO_BASE + `GPIO_RANGE))); end if (`UART_SUPPORTED) begin - void'(rvviRefMemorySetPrivilege(`UART_BASE, (`UART_BASE + `UART_RANGE), PRIV_RW)); - void'(rvviRefMemorySetVolatile(`UART_BASE, (`UART_BASE + `UART_RANGE))); + //void'(rvviRefMemorySetVolatile(`UART_BASE, (`UART_BASE + `UART_RANGE))); + void'(rvviRefMemorySetVolatile(`UART_BASE, (`UART_BASE + 7))); // BUG end if (`PLIC_SUPPORTED) begin - void'(rvviRefMemorySetPrivilege(`PLIC_BASE, (`PLIC_BASE + `PLIC_RANGE), PRIV_RW)); void'(rvviRefMemorySetVolatile(`PLIC_BASE, (`PLIC_BASE + `PLIC_RANGE))); end if (`SDC_SUPPORTED) begin - void'(rvviRefMemorySetPrivilege(`SDC_BASE, (`SDC_BASE + `SDC_RANGE), PRIV_RW)); void'(rvviRefMemorySetVolatile(`SDC_BASE, (`SDC_BASE + `SDC_RANGE))); end -*/ if(`XLEN==32) begin void'(rvviRefCsrSetVolatile(0, 32'hC80)); // CYCLEH From 2db97d20fa5d329ebd594a15cdaf03791a9b17a0 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 10 Mar 2023 12:08:24 -0800 Subject: [PATCH 07/25] Removed unneeded echo from setup --- setup.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.sh b/setup.sh index 126059df..2115a0d7 100755 --- a/setup.sh +++ b/setup.sh @@ -51,7 +51,6 @@ if [ -e "$IDV" ]; then source ${IMPERAS_HOME}/bin/setup.sh setupImperas ${IMPERAS_HOME} export PATH=$IDV/scripts/cvw:$PATH - echo $PATH fi From 8107f585c8d6f02582dca98e001e4ed4a9af06f7 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 10 Mar 2023 13:10:28 -0800 Subject: [PATCH 08/25] Fixed crash with wrong number of arguments for coverage in regression-wally --- sim/regression-wally | 1 + sim/wally-batch.do | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sim/regression-wally b/sim/regression-wally index ce9387b6..e7ce0d30 100755 --- a/sim/regression-wally +++ b/sim/regression-wally @@ -219,6 +219,7 @@ def main(): print('Generating coverage report') os.system('vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb -logfile cov/log') os.system('vcover report -details cov/cov.ucdb > cov/rv64gc_coverage.rpt') + os.system('vcover report -html cov/cov.ucdb') # Count the number of failures if num_fail: print(f"{bcolors.FAIL}Regression failed with %s failed configurations{bcolors.ENDC}" % num_fail) diff --git a/sim/wally-batch.do b/sim/wally-batch.do index 2adc917e..19951de9 100644 --- a/sim/wally-batch.do +++ b/sim/wally-batch.do @@ -115,7 +115,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals - if {$3 eq "-coverage"} { + if {$argc >= 3} { vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt +cover=sbectf vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 -coverage } else { @@ -129,9 +129,11 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { # power off -r /dut/core/* } -if {$3 eq "-coverage"} { - do coverage-exclusions.do - coverage save -instance /testbench/dut cov/${1}_${2}.ucdb +if {$argc >= 3) {} + if ($3 eq "-coverage"} { + do coverage-exclusions.do + coverage save -instance /testbench/dut cov/${1}_${2}.ucdb + } } # These aren't doing anything helpful From a1ffff57ba1bb292f8355af85cfc4834be9583e4 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 10 Mar 2023 13:33:32 -0800 Subject: [PATCH 09/25] Fixes to wally-batch for coverage --- sim/wally-batch.do | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/sim/wally-batch.do b/sim/wally-batch.do index 19951de9..83053899 100644 --- a/sim/wally-batch.do +++ b/sim/wally-batch.do @@ -43,6 +43,14 @@ if {$2 eq "ahb"} { # Create directory for coverage data mkdir -p cov +# Check if measuring coverage + set coverage 0 +if {$argc >= 3} { + if {$3 eq "-coverage"} { + set coverage 1 + } +} + # compile source files # suppress spurious warnngs about # "Extra checking for conflicts with always_comb done at vopt time" @@ -115,7 +123,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { vlog -lint -work wkdir/work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals - if {$argc >= 3} { + if {$coverage} { vopt wkdir/work_${1}_${2}.testbench -work wkdir/work_${1}_${2} -G TEST=$2 -o testbenchopt +cover=sbectf vsim -lib wkdir/work_${1}_${2} testbenchopt -fatal 7 -suppress 3829 -coverage } else { @@ -129,11 +137,9 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} { # power off -r /dut/core/* } -if {$argc >= 3) {} - if ($3 eq "-coverage"} { - do coverage-exclusions.do - coverage save -instance /testbench/dut cov/${1}_${2}.ucdb - } +if {$coverage} { + do coverage-exclusions.do + coverage save -instance /testbench/dut cov/${1}_${2}.ucdb } # These aren't doing anything helpful From e233b63752a55ac41ecbd932576f24808c9f2995 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Sun, 12 Mar 2023 13:21:22 -0500 Subject: [PATCH 10/25] Replaced DCACHE parameter with READ_ONLY_CACHE as the name was confusing in chapter 10. --- sim/regression-wally | 3 +-- src/cache/cache.sv | 8 ++++---- src/cache/cacheway.sv | 4 ++-- src/ifu/ifu.sv | 2 +- src/lsu/lsu.sv | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/sim/regression-wally b/sim/regression-wally index e7ce0d30..560f7795 100755 --- a/sim/regression-wally +++ b/sim/regression-wally @@ -126,8 +126,7 @@ for test in ahbTests: grepstr="All tests ran without failures") configs.append(tc) -#tests64gc = ["arch64f", "arch64d", "arch64i", "arch64priv", "arch64c", "arch64m", "arch64zi", "wally64a", "wally64periph", "wally64priv"] -tests64gc = ["arch64i", "arch64c", "arch64m"] +tests64gc = ["arch64f", "arch64d", "arch64i", "arch64priv", "arch64c", "arch64m", "arch64zi", "wally64a", "wally64periph", "wally64priv"] if (coverage): # delete all but 64gc tests when running coverage configs = [] coverStr = '-coverage' diff --git a/src/cache/cache.sv b/src/cache/cache.sv index 72b97a31..ea119d00 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -29,7 +29,7 @@ `include "wally-config.vh" -module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTERVAL, DCACHE) ( +module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTERVAL, READ_ONLY_CACHE) ( input logic clk, input logic reset, input logic Stall, // Stall the cache, preventing new accesses. In-flight access finished but does not return to READY @@ -110,12 +110,12 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE // and FlushAdr when handling D$ flushes // The icache must update to the newest PCNextF on flush as it is probably a trap. Trap // sets PCNextF to XTVEC and the icache must start reading the instruction. - assign AdrSelMuxSel = {SelFlush, ((SelAdr | SelHPTW) & ~((DCACHE == 0) & FlushStage))}; + assign AdrSelMuxSel = {SelFlush, ((SelAdr | SelHPTW) & ~((READ_ONLY_CACHE == 1) & FlushStage))}; mux3 #(SETLEN) AdrSelMux(NextAdr[SETTOP-1:OFFSETLEN], PAdr[SETTOP-1:OFFSETLEN], FlushAdr, AdrSelMuxSel, CAdr); // Array of cache ways, along with victim, hit, dirty, and read merging logic - cacheway #(NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, DCACHE) CacheWays[NUMWAYS-1:0]( + cacheway #(NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0]( .clk, .reset, .CacheEn, .CAdr, .PAdr, .LineWriteData, .LineByteMask, .SetValid, .ClearValid, .SetDirty, .ClearDirty, .SelWriteback, .VictimWay, .FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache); @@ -138,7 +138,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE or_rows #(NUMWAYS, TAGLEN) TagAOMux(.a(TagWay), .y(Tag)); // Data cache needs to choose word offset from PAdr or BeatCount to writeback dirty lines - if(DCACHE) + if(!READ_ONLY_CACHE) mux2 #(LOGBWPL) WordAdrrMux(.d0(PAdr[$clog2(LINELEN/8) - 1 : $clog2(MUXINTERVAL/8)]), .d1(BeatCount), .s(SelBusBeat), .y(WordOffsetAddr)); diff --git a/src/cache/cacheway.sv b/src/cache/cacheway.sv index 671bbcaf..08f2b975 100644 --- a/src/cache/cacheway.sv +++ b/src/cache/cacheway.sv @@ -30,7 +30,7 @@ `include "wally-config.vh" module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26, - OFFSETLEN = 5, INDEXLEN = 9, DIRTY_BITS = 1) ( + OFFSETLEN = 5, INDEXLEN = 9, READ_ONLY_CACHE = 0) ( input logic clk, input logic reset, input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations) @@ -163,7 +163,7 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26, ///////////////////////////////////////////////////////////////////////////////////////////// // Dirty bits - if (DIRTY_BITS) begin:dirty + if (!READ_ONLY_CACHE) begin:dirty always_ff @(posedge clk) begin // reset is optional. Consider merging with TAG array in the future. //if (reset) DirtyBits <= #1 {NUMLINES{1'b0}}; diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index 41b0de00..d1d468ae 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -233,7 +233,7 @@ module ifu ( assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0; cache #(.LINELEN(`ICACHE_LINELENINBITS), .NUMLINES(`ICACHE_WAYSIZEINBYTES*8/`ICACHE_LINELENINBITS), - .NUMWAYS(`ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .DCACHE(0)) + .NUMWAYS(`ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .READ_ONLY_CACHE(1)) icache(.clk, .reset, .FlushStage(FlushD), .Stall(GatedStallD), .FetchBuffer, .CacheBusAck(ICacheBusAck), .CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF), diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index 91ad694e..4a53801b 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -264,7 +264,7 @@ module lsu ( assign FlushDCache = FlushDCacheM & ~(IgnoreRequestTLB | SelHPTW); cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN), - .NUMWAYS(`DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(`LLEN), .MUXINTERVAL(`LLEN), .DCACHE(1)) dcache( + .NUMWAYS(`DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(`LLEN), .MUXINTERVAL(`LLEN), .READ_ONLY_CACHE(0)) dcache( .clk, .reset, .Stall(GatedStallW), .SelBusBeat, .FlushStage(FlushW), .CacheRW(CacheRWM), .CacheAtomic(CacheAtomicM), .FlushCache(FlushDCache), .NextAdr(IEUAdrE[11:0]), .PAdr(PAdrM), .ByteMask(ByteMaskM), .BeatCount(BeatCount[AHBWLOGBWPL-1:AHBWLOGBWPL-LLENLOGBWPL]), From ede9d49ce42ae3ee81d33e74f319cb881e69c187 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Sun, 12 Mar 2023 14:36:46 -0500 Subject: [PATCH 11/25] Changes BTA to BPBTA. --- src/ifu/bpred/bpred.sv | 18 +++++++++--------- src/ifu/bpred/btb.sv | 28 ++++++++++++++-------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/ifu/bpred/bpred.sv b/src/ifu/bpred/bpred.sv index f2f16b51..97aec386 100644 --- a/src/ifu/bpred/bpred.sv +++ b/src/ifu/bpred/bpred.sv @@ -71,7 +71,7 @@ module bpred ( logic [1:0] BPDirPredF; - logic [`XLEN-1:0] BTAF, RASPCF; + logic [`XLEN-1:0] BPBTAF, RASPCF; logic BPPCWrongE; logic IClassWrongE; logic BPDirPredWrongE; @@ -85,7 +85,7 @@ module bpred ( logic BTBTargetWrongE; logic RASTargetWrongE; - logic [`XLEN-1:0] BTAD; + logic [`XLEN-1:0] BPBTAD; logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF; logic BPBranchF, BPJumpF, BPReturnF, BPCallF; @@ -95,7 +95,7 @@ module bpred ( logic BranchM, JumpM, ReturnM, CallM; logic BranchW, JumpW, ReturnW, CallW; logic BPReturnWrongD; - logic [`XLEN-1:0] BTAE; + logic [`XLEN-1:0] BPBTAE; @@ -150,7 +150,7 @@ module bpred ( btb #(`BTB_SIZE) TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .PCNextF, .PCF, .PCD, .PCE, .PCM, - .BTAF, .BTAD, .BTAE, + .BPBTAF, .BPBTAD, .BPBTAE, .BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}), .IClassWrongM, .IClassWrongE, .IEUAdrE, .IEUAdrM, @@ -181,7 +181,7 @@ module bpred ( // Output the predicted PC or corrected PC on miss-predict. assign BPPCSrcF = (BPBranchF & BPDirPredF[1]) | BPJumpF; - mux2 #(`XLEN) pcmuxbp(BTAF, RASPCF, BPReturnF, BPPCF); + mux2 #(`XLEN) pcmuxbp(BPBTAF, RASPCF, BPReturnF, BPPCF); // Selects the BP or PC+2/4. mux2 #(`XLEN) pcmux0(PCPlus2or4F, BPPCF, BPPCSrcF, PC0NextF); // If the prediction is wrong select the correct address. @@ -196,7 +196,7 @@ module bpred ( if(`ZICOUNTERS_SUPPORTED) begin logic [`XLEN-1:0] RASPCD, RASPCE; - logic BTBPredPCWrongE, RASPredPCWrongE; + logic BTAWrongE, RASPredPCWrongE; // performance counters // 1. class (class wrong / minstret) (IClassWrongM / csr) // Correct now // 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal) @@ -207,14 +207,14 @@ module bpred ( // could be wrong or the fall through address selected for branch predict not taken. // By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of // both without the above inaccuracies. - // **** use BTAWrongM from BTB. - assign BTBPredPCWrongE = (BTAE != IEUAdrE) & (BranchE | JumpE & ~ReturnE) & PCSrcE; + // **** use BPBTAWrongM from BTB. + assign BTAWrongE = (BPBTAE != IEUAdrE) & (BranchE | JumpE & ~ReturnE) & PCSrcE; assign RASPredPCWrongE = (RASPCE != IEUAdrE) & ReturnE & PCSrcE; flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD); flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE); flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM, - {BPDirPredWrongE, BTBPredPCWrongE, RASPredPCWrongE}, + {BPDirPredWrongE, BTAWrongE, RASPredPCWrongE}, {BPDirPredWrongM, BTAWrongM, RASPredPCWrongM}); end else begin diff --git a/src/ifu/bpred/btb.sv b/src/ifu/bpred/btb.sv index b1439970..ab11b48b 100644 --- a/src/ifu/bpred/btb.sv +++ b/src/ifu/bpred/btb.sv @@ -35,9 +35,9 @@ module btb #(parameter Depth = 10 ) ( input logic reset, input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW, input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM,// PC at various stages - output logic [`XLEN-1:0] BTAF, // BTB's guess at PC - output logic [`XLEN-1:0] BTAD, - output logic [`XLEN-1:0] BTAE, + output logic [`XLEN-1:0] BPBTAF, // BTB's guess at PC + output logic [`XLEN-1:0] BPBTAD, + output logic [`XLEN-1:0] BPBTAE, output logic [3:0] BTBIClassF, // BTB's guess at instruction class // update input logic IClassWrongM, // BTB's instruction class guess was wrong @@ -57,8 +57,8 @@ module btb #(parameter Depth = 10 ) ( logic [`XLEN+3:0] TableBTBPredF; logic [`XLEN-1:0] IEUAdrW; logic [`XLEN-1:0] PCW; - logic BTBWrongE, BTAWrongE; - logic BTBWrongM, BTAWrongM; + logic BTBWrongE, BPBTAWrongE; + logic BTBWrongM, BPBTAWrongM; // hashing function for indexing the PC @@ -84,12 +84,12 @@ module btb #(parameter Depth = 10 ) ( assign MatchW = PCFIndex == PCWIndex; assign MatchX = MatchD | MatchE | MatchM | MatchW; - assign ForwardBTBPredictionF = MatchD ? {InstrClassD, BTAD} : + assign ForwardBTBPredictionF = MatchD ? {InstrClassD, BPBTAD} : MatchE ? {InstrClassE, IEUAdrE} : MatchM ? {InstrClassM, IEUAdrM} : {InstrClassW, IEUAdrW} ; - assign {BTBIClassF, BTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredF}; + assign {BTBIClassF, BPBTAF} = MatchX ? ForwardBTBPredictionF : {TableBTBPredF}; // An optimization may be using a PC relative address. @@ -97,16 +97,16 @@ module btb #(parameter Depth = 10 ) ( .clk, .ce1(~StallF | reset), .ra1(PCNextFIndex), .rd1(TableBTBPredF), .ce2(~StallW & ~FlushW), .wa2(PCMIndex), .wd2({InstrClassM, IEUAdrM}), .we2(BTBWrongM), .bwe2('1)); - flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BTAF, BTAD); + flopenrc #(`XLEN) BTBD(clk, reset, FlushD, ~StallD, BPBTAF, BPBTAD); - // BTAE is not strickly necessary. However it is used by two parts of wally. + // BPBTAE is not strickly necessary. However it is used by two parts of wally. // 1. It gates updates to the BTB when the prediction does not change. This save power. - // 2. BTAWrongE is used by the performance counters to track when the BTB's BTA or instruction class is wrong. - flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BTAD, BTAE); - assign BTAWrongE = (BTAE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] & ~InstrClassE[2]); + // 2. BPBTAWrongE is used by the performance counters to track when the BTB's BPBTA or instruction class is wrong. + flopenrc #(`XLEN) BTBTargetEReg(clk, reset, FlushE, ~StallE, BPBTAD, BPBTAE); + assign BPBTAWrongE = (BPBTAE != IEUAdrE) & (InstrClassE[0] | InstrClassE[1] & ~InstrClassE[2]); - flopenrc #(1) BTAWrongMReg(clk, reset, FlushM, ~StallM, BTAWrongE, BTAWrongM); - assign BTBWrongM = BTAWrongM | IClassWrongM; + flopenrc #(1) BPBTAWrongMReg(clk, reset, FlushM, ~StallM, BPBTAWrongE, BPBTAWrongM); + assign BTBWrongM = BPBTAWrongM | IClassWrongM; flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW); From 568d0031d216ccdc0617045f6ae65ada11cc61b8 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Sun, 12 Mar 2023 17:15:56 -0500 Subject: [PATCH 12/25] Modified the branch log to include markers for the start and end of tests with exclusion of warmup period. --- testbench/testbench.sv | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testbench/testbench.sv b/testbench/testbench.sv index b0af190a..6c9315ee 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -69,6 +69,7 @@ logic [3:0] dummy; logic DCacheFlushDone, DCacheFlushStart; logic riscofTest; + logic StartSample, EndSample; flopenr #(`XLEN) PCWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.PCM, PCW); flopenr #(32) InstrWReg(clk, reset, ~dut.core.ieu.dp.StallW, dut.core.ifu.InstrM, InstrW); @@ -405,8 +406,7 @@ logic [3:0] dummy; integer HPMCindex; logic StartSampleFirst; logic StartSampleDelayed; - logic StartSample; - logic EndSample, EndSampleFirst, EndSampleDelayed; + logic EndSampleFirst, EndSampleDelayed; logic [`XLEN-1:0] InitialHPMCOUNTERH[`COUNTERS-1:0]; string HPMCnames[] = '{"Mcycle", @@ -549,10 +549,12 @@ logic [3:0] dummy; file = $fopen("branch.log", "w"); end always @(posedge clk) begin + if(StartSample) $fwrite(file, "BEGIN %s\n", memfilename); if(dut.core.ifu.InstrClassM[0] & ~dut.core.StallW & ~dut.core.FlushW & dut.core.InstrValidM) begin direction = PCSrcM ? "t" : "n"; $fwrite(file, "%h %s\n", dut.core.PCM, direction); end + if(EndSample) $fwrite(file, "END %s\n", memfilename); end end end From ae421505198a724df21657eb8c97fdb7e18a9eb6 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Sun, 12 Mar 2023 17:58:36 -0500 Subject: [PATCH 13/25] Added script to separate branch.log into separate logs for each benchmark. --- bin/separateBrnach.sh | 24 ++++++++++++++++++++++++ testbench/testbench.sv | 4 +++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100755 bin/separateBrnach.sh diff --git a/bin/separateBrnach.sh b/bin/separateBrnach.sh new file mode 100755 index 00000000..157046ca --- /dev/null +++ b/bin/separateBrnach.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +File="$1" +BeginLineNumbers=`cat $File | grep -n "BEGIN" | awk -NF ':' '{print $1}'` +Name=`cat $File | grep -n "BEGIN" | awk -NF '/' '{print $6}'` +EndLineNumbers=`cat $File | grep -n "END" | awk -NF ':' '{print $1}'` +echo $Name +echo $BeginLineNumbers +echo $EndLineNumbers + +NameArray=($Name) +BeginLineNumberArray=($BeginLineNumbers) +EndLineNumberArray=($EndLineNumbers) + +mkdir -p branch +Length=${#EndLineNumberArray[@]} +for i in $(seq 0 1 $((Length-1))) +do + CurrName=${NameArray[$i]} + CurrStart=$((${BeginLineNumberArray[$i]}+1)) + CurrEnd=$((${EndLineNumberArray[$i]}-1)) + echo $CurrName, $CurrStart, $CurrEnd + sed -n "${CurrStart},${CurrEnd}p" $File > branch/${CurrName}_branch.log +done diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 6c9315ee..e6b032f8 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -544,9 +544,11 @@ logic [3:0] dummy; string direction; int file; logic PCSrcM; + string LogFile; flopenrc #(1) PCSrcMReg(clk, reset, dut.core.FlushM, ~dut.core.StallM, dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PCSrcE, PCSrcM); initial begin - file = $fopen("branch.log", "w"); + LogFile = $psprintf("branch_%s%d.log", `BPRED_TYPE, `BPRED_SIZE); + file = $fopen(LogFile, "w"); end always @(posedge clk) begin if(StartSample) $fwrite(file, "BEGIN %s\n", memfilename); From 755b1bfe53a98362aed219abf0d2dba638c8d66c Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Sun, 12 Mar 2023 22:40:59 -0500 Subject: [PATCH 14/25] Renamed script to parse branch.log --- bin/CModelBranchAccuracy.sh | 56 +++++++++++++++++++++++++++++++++++++ bin/SeparateBranch.sh | 50 +++++++++++++++++++++++++++++++++ bin/separateBrnach.sh | 24 ---------------- 3 files changed, 106 insertions(+), 24 deletions(-) create mode 100644 bin/CModelBranchAccuracy.sh create mode 100755 bin/SeparateBranch.sh delete mode 100755 bin/separateBrnach.sh diff --git a/bin/CModelBranchAccuracy.sh b/bin/CModelBranchAccuracy.sh new file mode 100644 index 00000000..259a1552 --- /dev/null +++ b/bin/CModelBranchAccuracy.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +########################################### +## Written: ross1728@gmail.com +## Created: 12 March 2023 +## Modified: +## +## Purpose: Takes a directory of branch outcomes organized as 1 files per benchmark. +## Computes the geometric mean. +## +## A component of the CORE-V-WALLY configurable RISC-V project. +## +## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +## +## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +## +## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +## except in compliance with the License, or, at your option, the Apache License version 2.0. You +## may obtain a copy of the License at +## +## https:##solderpad.org/licenses/SHL-2.1/ +## +## Unless required by applicable law or agreed to in writing, any work distributed under the +## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. See the License for the specific language governing permissions +## and limitations under the License. +################################################################################################ + + +irectory="$1" +Predictor="$2" +Size="$3" + + +File="$1" +BeginLineNumbers=`cat $File | grep -n "BEGIN" | awk -NF ':' '{print $1}'` +Name=`cat $File | grep -n "BEGIN" | awk -NF '/' '{print $6_$4}'` +EndLineNumbers=`cat $File | grep -n "END" | awk -NF ':' '{print $1}'` +echo $Name +echo $BeginLineNumbers +echo $EndLineNumbers + +NameArray=($Name) +BeginLineNumberArray=($BeginLineNumbers) +EndLineNumberArray=($EndLineNumbers) + +mkdir -p branch +Length=${#EndLineNumberArray[@]} +for i in $(seq 0 1 $((Length-1))) +do + CurrName=${NameArray[$i]} + CurrStart=$((${BeginLineNumberArray[$i]}+1)) + CurrEnd=$((${EndLineNumberArray[$i]}-1)) + echo $CurrName, $CurrStart, $CurrEnd + sed -n "${CurrStart},${CurrEnd}p" $File > branch/${CurrName}_branch.log +done diff --git a/bin/SeparateBranch.sh b/bin/SeparateBranch.sh new file mode 100755 index 00000000..f72eaeb8 --- /dev/null +++ b/bin/SeparateBranch.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +########################################### +## Written: ross1728@gmail.com +## Created: 12 March 2023 +## Modified: +## +## Purpose: Converts a single branch.log containing multiple benchmark branch outcomes into +## separate files, one for each program.x4 +## +## A component of the CORE-V-WALLY configurable RISC-V project. +## +## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +## +## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +## +## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +## except in compliance with the License, or, at your option, the Apache License version 2.0. You +## may obtain a copy of the License at +## +## https:##solderpad.org/licenses/SHL-2.1/ +## +## Unless required by applicable law or agreed to in writing, any work distributed under the +## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +## either express or implied. See the License for the specific language governing permissions +## and limitations under the License. +################################################################################################ + +File="$1" +BeginLineNumbers=`cat $File | grep -n "BEGIN" | awk -NF ':' '{print $1}'` +Name=`cat $File | grep -n "BEGIN" | awk -NF '/' '{print $6_$4}'` +EndLineNumbers=`cat $File | grep -n "END" | awk -NF ':' '{print $1}'` +echo $Name +echo $BeginLineNumbers +echo $EndLineNumbers + +NameArray=($Name) +BeginLineNumberArray=($BeginLineNumbers) +EndLineNumberArray=($EndLineNumbers) + +mkdir -p branch +Length=${#EndLineNumberArray[@]} +for i in $(seq 0 1 $((Length-1))) +do + CurrName=${NameArray[$i]} + CurrStart=$((${BeginLineNumberArray[$i]}+1)) + CurrEnd=$((${EndLineNumberArray[$i]}-1)) + echo $CurrName, $CurrStart, $CurrEnd + sed -n "${CurrStart},${CurrEnd}p" $File > branch/${CurrName}_branch.log +done diff --git a/bin/separateBrnach.sh b/bin/separateBrnach.sh deleted file mode 100755 index 157046ca..00000000 --- a/bin/separateBrnach.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -File="$1" -BeginLineNumbers=`cat $File | grep -n "BEGIN" | awk -NF ':' '{print $1}'` -Name=`cat $File | grep -n "BEGIN" | awk -NF '/' '{print $6}'` -EndLineNumbers=`cat $File | grep -n "END" | awk -NF ':' '{print $1}'` -echo $Name -echo $BeginLineNumbers -echo $EndLineNumbers - -NameArray=($Name) -BeginLineNumberArray=($BeginLineNumbers) -EndLineNumberArray=($EndLineNumbers) - -mkdir -p branch -Length=${#EndLineNumberArray[@]} -for i in $(seq 0 1 $((Length-1))) -do - CurrName=${NameArray[$i]} - CurrStart=$((${BeginLineNumberArray[$i]}+1)) - CurrEnd=$((${EndLineNumberArray[$i]}-1)) - echo $CurrName, $CurrStart, $CurrEnd - sed -n "${CurrStart},${CurrEnd}p" $File > branch/${CurrName}_branch.log -done From 0441e3b736d6669e5333eca8cf5b8d39820a5684 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Sun, 12 Mar 2023 23:15:44 -0500 Subject: [PATCH 15/25] Created script to batch processes all the embench branch outcomes into C model branch prediction rate. --- bin/CModelBranchAccuracy.sh | 49 +++++++++++++++++++------------------ bin/sim_bp | 1 + 2 files changed, 26 insertions(+), 24 deletions(-) mode change 100644 => 100755 bin/CModelBranchAccuracy.sh create mode 120000 bin/sim_bp diff --git a/bin/CModelBranchAccuracy.sh b/bin/CModelBranchAccuracy.sh old mode 100644 new mode 100755 index 259a1552..1b94f7c9 --- a/bin/CModelBranchAccuracy.sh +++ b/bin/CModelBranchAccuracy.sh @@ -27,30 +27,31 @@ ################################################################################################ -irectory="$1" -Predictor="$2" -Size="$3" +Directory="$1" +Files="$1/*.log" - -File="$1" -BeginLineNumbers=`cat $File | grep -n "BEGIN" | awk -NF ':' '{print $1}'` -Name=`cat $File | grep -n "BEGIN" | awk -NF '/' '{print $6_$4}'` -EndLineNumbers=`cat $File | grep -n "END" | awk -NF ':' '{print $1}'` -echo $Name -echo $BeginLineNumbers -echo $EndLineNumbers - -NameArray=($Name) -BeginLineNumberArray=($BeginLineNumbers) -EndLineNumberArray=($EndLineNumbers) - -mkdir -p branch -Length=${#EndLineNumberArray[@]} -for i in $(seq 0 1 $((Length-1))) +for Pred in "bimodal" "gshare" do - CurrName=${NameArray[$i]} - CurrStart=$((${BeginLineNumberArray[$i]}+1)) - CurrEnd=$((${EndLineNumberArray[$i]}-1)) - echo $CurrName, $CurrStart, $CurrEnd - sed -n "${CurrStart},${CurrEnd}p" $File > branch/${CurrName}_branch.log + for Size in $(seq 6 2 16) + do + if [ $Pred = "gshare" ]; then + SizeString="$Size $Size 18 1" + elif [ $Pred = "bimodal" ]; then + SizeString="$Size 18 1" + fi + + Product=1.0 + Count=0 + for File in $Files + do + #echo "sim_bp $Pred $Size $Size 18 1 $File | tail -1 | awk '{print $4}'" + #echo "sim_bp $Pred $SizeString $File | tail -1 | awk '{print $4}'" + BMDR=`sim_bp $Pred $SizeString $File | tail -1 | awk '{print $4}'` + Product=`echo "$Product * $BMDR" | bc` + Count=$((Count+1)) + done + + GeoMean=`perl -E "say $Product**(1/$Count)"` + echo "$Pred$Size $GeoMean" + done done diff --git a/bin/sim_bp b/bin/sim_bp new file mode 120000 index 00000000..a85da990 --- /dev/null +++ b/bin/sim_bp @@ -0,0 +1 @@ +../addins/branch-predictor-simulator/src/sim_bp \ No newline at end of file From 0d260accb42af670f576151bab65ca2ddf095efa Mon Sep 17 00:00:00 2001 From: eroom1966 Date: Mon, 13 Mar 2023 11:07:19 +0000 Subject: [PATCH 16/25] Fix MISA RO and UART addresses It appears on inspection that the MISA register is read only in Wally In which case this has now also been set in the ImperasDV representation Also the Addresss for the UART R/W privileges are corrected --- sim/imperas.ic | 1 + testbench/testbench_imperas.sv | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sim/imperas.ic b/sim/imperas.ic index 6a34466f..3744a426 100644 --- a/sim/imperas.ic +++ b/sim/imperas.ic @@ -6,6 +6,7 @@ --override cpu/ignore_non_leaf_DAU=1 --override cpu/wfi_is_nop=T --override cpu/mimpid=0x100 +--override cpu/misa_Extensions_mask=0x0 # THIS NEEDS FIXING to 16 --override cpu/PMP_registers=0 diff --git a/testbench/testbench_imperas.sv b/testbench/testbench_imperas.sv index 27bd1246..6ac11bc2 100644 --- a/testbench/testbench_imperas.sv +++ b/testbench/testbench_imperas.sv @@ -178,8 +178,7 @@ module testbench; void'(rvviRefMemorySetVolatile(`GPIO_BASE, (`GPIO_BASE + `GPIO_RANGE))); end if (`UART_SUPPORTED) begin - //void'(rvviRefMemorySetVolatile(`UART_BASE, (`UART_BASE + `UART_RANGE))); - void'(rvviRefMemorySetVolatile(`UART_BASE, (`UART_BASE + 7))); // BUG + void'(rvviRefMemorySetVolatile(`UART_BASE, (`UART_BASE + `UART_RANGE))); end if (`PLIC_SUPPORTED) begin void'(rvviRefMemorySetVolatile(`PLIC_BASE, (`PLIC_BASE + `PLIC_RANGE))); From 2d49c4582cca32449e3019c4b7e6117cac6ae0c8 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 13 Mar 2023 13:26:27 -0500 Subject: [PATCH 17/25] Modified branch logger to indicate when the warmup period is done. The branch-predictor-simulator also changed to support this. --- bin/SeparateBranch.sh | 8 +++++--- testbench/testbench.sv | 6 +++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/bin/SeparateBranch.sh b/bin/SeparateBranch.sh index f72eaeb8..c5ebb5de 100755 --- a/bin/SeparateBranch.sh +++ b/bin/SeparateBranch.sh @@ -27,6 +27,7 @@ ################################################################################################ File="$1" +TrainLineNumbers=`cat $File | grep -n "TRAIN" | awk -NF ':' '{print $1}'` BeginLineNumbers=`cat $File | grep -n "BEGIN" | awk -NF ':' '{print $1}'` Name=`cat $File | grep -n "BEGIN" | awk -NF '/' '{print $6_$4}'` EndLineNumbers=`cat $File | grep -n "END" | awk -NF ':' '{print $1}'` @@ -35,6 +36,7 @@ echo $BeginLineNumbers echo $EndLineNumbers NameArray=($Name) +TrainLineNumberArray=($TrainLineNumbers) BeginLineNumberArray=($BeginLineNumbers) EndLineNumberArray=($EndLineNumbers) @@ -43,8 +45,8 @@ Length=${#EndLineNumberArray[@]} for i in $(seq 0 1 $((Length-1))) do CurrName=${NameArray[$i]} - CurrStart=$((${BeginLineNumberArray[$i]}+1)) + CurrTrain=$((${TrainLineNumberArray[$i]}+1)) CurrEnd=$((${EndLineNumberArray[$i]}-1)) - echo $CurrName, $CurrStart, $CurrEnd - sed -n "${CurrStart},${CurrEnd}p" $File > branch/${CurrName}_branch.log + echo $CurrName, $CurrTrain, $CurrEnd + sed -n "${CurrTrain},${CurrEnd}p" $File > branch/${CurrName}_branch.log done diff --git a/testbench/testbench.sv b/testbench/testbench.sv index e6b032f8..fe3875cb 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -545,12 +545,16 @@ logic [3:0] dummy; int file; logic PCSrcM; string LogFile; + logic resetD, resetEdge; flopenrc #(1) PCSrcMReg(clk, reset, dut.core.FlushM, ~dut.core.StallM, dut.core.ifu.bpred.bpred.Predictor.DirPredictor.PCSrcE, PCSrcM); + flop #(1) ResetDReg(clk, reset, resetD); + assign resetEdge = ~reset & resetD; initial begin - LogFile = $psprintf("branch_%s%d.log", `BPRED_TYPE, `BPRED_SIZE); + LogFile = $psprintf("branch_%s%0d.log", `BPRED_TYPE, `BPRED_SIZE); file = $fopen(LogFile, "w"); end always @(posedge clk) begin + if(resetEdge) $fwrite(file, "TRAIN\n"); if(StartSample) $fwrite(file, "BEGIN %s\n", memfilename); if(dut.core.ifu.InstrClassM[0] & ~dut.core.StallW & ~dut.core.FlushW & dut.core.InstrValidM) begin direction = PCSrcM ? "t" : "n"; From c57e2a2140a7823b245c4d0e31a8644b05bca967 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 13 Mar 2023 13:30:43 -0500 Subject: [PATCH 18/25] Added reference data. --- bin/parseHPMC.py | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/bin/parseHPMC.py b/bin/parseHPMC.py index 3229d1c7..9f654915 100755 --- a/bin/parseHPMC.py +++ b/bin/parseHPMC.py @@ -30,6 +30,20 @@ import sys import matplotlib.pyplot as plt import re +#RefData={'twobitCModel' :(['6', '8', '10', '12', '14', '16'], +# [11.0680836450622, 8.53864970807778, 7.59565430177984, 6.38741598498948, 5.83662961500838, 5.83662961500838]), +# 'gshareCModel' : (['6', '8', '10', '12', '14', '16'], +# [14.5859173702079, 12.3634674403619, 10.5806018170154, 8.38831266973592, 6.37097544620762, 3.52638362703015]) +#} + +RefData = [('twobitCModel6', 11.068), ('twobitCModel8', 8.53864970807778), ('twobitCModel10', 7.59565430177984), + ('twobitCModel12', 6.38741598498948), ('twobitCModel14', 5.83662961500838), ('twobitCModel16', 5.83662961500838), + ('gshareCModel6', 14.5859173702079), ('gshareCModel8', 12.3634674403619), ('gshareCModel10', 10.5806018170154), + ('gshareCModel12', 8.38831266973592), ('gshareCModel14', 6.37097544620762), ('gshareCModel16', 3.52638362703015)] + + + + def ComputeCPI(benchmark): 'Computes and inserts CPI into benchmark stats.' (nameString, opt, dataDict) = benchmark @@ -221,14 +235,15 @@ if(sys.argv[1] == '-b'): for benchmark in benchmarkAll: (name, opt, config, dataDict) = benchmark if name+'_'+opt in benchmarkDict: - benchmarkDict[name+'_'+opt].append((config, dataDict['BTMR'])) + benchmarkDict[name+'_'+opt].append((config, dataDict['BDMR'])) else: - benchmarkDict[name+'_'+opt] = [(config, dataDict['BTMR'])] + benchmarkDict[name+'_'+opt] = [(config, dataDict['BDMR'])] size = len(benchmarkDict) index = 1 if(summery == 0): #print('Number of plots', size) + for benchmarkName in benchmarkDict: currBenchmark = benchmarkDict[benchmarkName] (names, values) = FormatToPlot(currBenchmark) @@ -241,6 +256,12 @@ if(sys.argv[1] == '-b'): index += 1 else: combined = benchmarkDict['All_'] + # merge the reference data into rtl data + print('Doing stuff') + print(combined) + combined.extend(RefData) + print('Doing stuff') + print(combined) (name, value) = FormatToPlot(combined) lst = [] dct = {} @@ -264,8 +285,8 @@ if(sys.argv[1] == '-b'): dct[PredType] = (currSize, currPercent) print(dct) fig, axes = plt.subplots() - marker={'twobit' : '^', 'gshare' : 'o', 'global' : 's', 'gshareBasic' : '*', 'globalBasic' : 'x', 'btb': 'x'} - colors={'twobit' : 'black', 'gshare' : 'blue', 'global' : 'dodgerblue', 'gshareBasic' : 'turquoise', 'globalBasic' : 'lightsteelblue', 'btb' : 'blue'} + marker={'twobit' : '^', 'gshare' : 'o', 'global' : 's', 'gshareBasic' : '*', 'globalBasic' : 'x', 'btb': 'x', 'twobitCModel' : 'x', 'gshareCModel' : '*'} + colors={'twobit' : 'black', 'gshare' : 'blue', 'global' : 'dodgerblue', 'gshareBasic' : 'turquoise', 'globalBasic' : 'lightsteelblue', 'btb' : 'blue', 'twobitCModel' : 'gray', 'gshareCModel' : 'dodgerblue'} for cat in dct: (x, y) = dct[cat] x=[int(2**int(v)) for v in x] From ef2c5ce6a789de3c5b83362b2f02eae5ad4fade6 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 13 Mar 2023 13:32:09 -0500 Subject: [PATCH 19/25] On our way to finish the C reference data collection. --- bin/parseHPMC.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/bin/parseHPMC.py b/bin/parseHPMC.py index 9f654915..ee3f4115 100755 --- a/bin/parseHPMC.py +++ b/bin/parseHPMC.py @@ -257,11 +257,7 @@ if(sys.argv[1] == '-b'): else: combined = benchmarkDict['All_'] # merge the reference data into rtl data - print('Doing stuff') - print(combined) combined.extend(RefData) - print('Doing stuff') - print(combined) (name, value) = FormatToPlot(combined) lst = [] dct = {} From c18a626abea57e40ab1d03f9c81e3ca1a24a2eb0 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 13 Mar 2023 13:54:04 -0500 Subject: [PATCH 20/25] More accurate c model gshare results. --- bin/parseHPMC.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/bin/parseHPMC.py b/bin/parseHPMC.py index ee3f4115..5b5e0d98 100755 --- a/bin/parseHPMC.py +++ b/bin/parseHPMC.py @@ -36,12 +36,10 @@ import re # [14.5859173702079, 12.3634674403619, 10.5806018170154, 8.38831266973592, 6.37097544620762, 3.52638362703015]) #} -RefData = [('twobitCModel6', 11.068), ('twobitCModel8', 8.53864970807778), ('twobitCModel10', 7.59565430177984), - ('twobitCModel12', 6.38741598498948), ('twobitCModel14', 5.83662961500838), ('twobitCModel16', 5.83662961500838), - ('gshareCModel6', 14.5859173702079), ('gshareCModel8', 12.3634674403619), ('gshareCModel10', 10.5806018170154), - ('gshareCModel12', 8.38831266973592), ('gshareCModel14', 6.37097544620762), ('gshareCModel16', 3.52638362703015)] - - +RefData = [('twobitCModel6', 11.0501534891674), ('twobitCModel8', 8.51829052266352), ('twobitCModel10', 7.56775222626483), + ('twobitCModel12', 6.31366834586515), ('twobitCModel14', 5.72699936834177), ('twobitCModel16', 5.72699936834177), + ('gshareCModel6', 14.5731555979574), ('gshareCModel8', 12.3155658100497), ('gshareCModel10', 10.4589596630561), + ('gshareCModel12', 8.25796055444401), ('gshareCModel14', 6.23093702707613), ('gshareCModel16', 3.34001125650374)] def ComputeCPI(benchmark): From cb019f9aed5a0f9103d019177af7482042b58482 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 13 Mar 2023 14:53:00 -0500 Subject: [PATCH 21/25] Updated CAdr to CacheSet. --- src/cache/cache.sv | 10 +++++----- src/cache/cacheLRU.sv | 9 ++++----- src/cache/cacheway.sv | 14 +++++++------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/cache/cache.sv b/src/cache/cache.sv index ea119d00..bea04a4d 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -74,7 +74,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE logic SelAdr; logic [1:0] AdrSelMuxSel; - logic [SETLEN-1:0] CAdr; + logic [SETLEN-1:0] CacheSet; logic [LINELEN-1:0] LineWriteData; logic ClearValid, ClearDirty, SetDirty, SetValid; logic [LINELEN-1:0] ReadDataLineWay [NUMWAYS-1:0]; @@ -106,24 +106,24 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE // Read Path ///////////////////////////////////////////////////////////////////////////////////////////// - // Choose read address (CAdr). Normally use NextAdr, but use PAdr during stalls + // Choose read address (CacheSet). Normally use NextAdr, but use PAdr during stalls // and FlushAdr when handling D$ flushes // The icache must update to the newest PCNextF on flush as it is probably a trap. Trap // sets PCNextF to XTVEC and the icache must start reading the instruction. assign AdrSelMuxSel = {SelFlush, ((SelAdr | SelHPTW) & ~((READ_ONLY_CACHE == 1) & FlushStage))}; mux3 #(SETLEN) AdrSelMux(NextAdr[SETTOP-1:OFFSETLEN], PAdr[SETTOP-1:OFFSETLEN], FlushAdr, - AdrSelMuxSel, CAdr); + AdrSelMuxSel, CacheSet); // Array of cache ways, along with victim, hit, dirty, and read merging logic cacheway #(NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0]( - .clk, .reset, .CacheEn, .CAdr, .PAdr, .LineWriteData, .LineByteMask, + .clk, .reset, .CacheEn, .CacheSet, .PAdr, .LineWriteData, .LineByteMask, .SetValid, .ClearValid, .SetDirty, .ClearDirty, .SelWriteback, .VictimWay, .FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .TagWay, .FlushStage, .InvalidateCache); // Select victim way for associative caches if(NUMWAYS > 1) begin:vict cacheLRU #(NUMWAYS, SETLEN, OFFSETLEN, NUMLINES) cacheLRU( - .clk, .reset, .CacheEn, .FlushStage, .HitWay, .ValidWay, .VictimWay, .CAdr, .LRUWriteEn(LRUWriteEn & ~FlushStage), + .clk, .reset, .CacheEn, .FlushStage, .HitWay, .ValidWay, .VictimWay, .CacheSet, .LRUWriteEn(LRUWriteEn & ~FlushStage), .SetValid, .PAdr(PAdr[SETTOP-1:OFFSETLEN]), .InvalidateCache, .FlushCache); end else assign VictimWay = 1'b1; // one hot. diff --git a/src/cache/cacheLRU.sv b/src/cache/cacheLRU.sv index 2e3057f0..05e26f4b 100644 --- a/src/cache/cacheLRU.sv +++ b/src/cache/cacheLRU.sv @@ -37,7 +37,7 @@ module cacheLRU input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant input logic [NUMWAYS-1:0] HitWay, // Which way is valid and matches PAdr's tag input logic [NUMWAYS-1:0] ValidWay, // Which ways for a particular set are valid, ignores tag - input logic [SETLEN-1:0] CAdr, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr + input logic [SETLEN-1:0] CacheSet, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr input logic [SETLEN-1:0] PAdr, // Physical address input logic LRUWriteEn, // Update the LRU state input logic SetValid, // Set the dirty bit in the selected way and set @@ -124,8 +124,7 @@ module cacheLRU // LRU storage must be reset for modelsim to run. However the reset value does not actually matter in practice. // This is a two port memory. - // Every cycle must read from CAdr and each load/store must write the new LRU. - // this is still wrong.*************************** + // Every cycle must read from CacheSet and each load/store must write the new LRU. always_ff @(posedge clk) begin if (reset) for (int set = 0; set < NUMLINES; set++) LRUMemory[set] <= '0; if(CacheEn) begin @@ -133,10 +132,10 @@ module cacheLRU else if (LRUWriteEn & ~FlushStage) begin LRUMemory[PAdr] <= NextLRU; end - if(LRUWriteEn & ~FlushStage & (PAdr == CAdr)) + if(LRUWriteEn & ~FlushStage & (PAdr == CacheSet)) CurrLRU <= #1 NextLRU; else - CurrLRU <= #1 LRUMemory[CAdr]; + CurrLRU <= #1 LRUMemory[CacheSet]; end end diff --git a/src/cache/cacheway.sv b/src/cache/cacheway.sv index 08f2b975..da40ab70 100644 --- a/src/cache/cacheway.sv +++ b/src/cache/cacheway.sv @@ -35,7 +35,7 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26, input logic reset, input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations) input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant - input logic [$clog2(NUMLINES)-1:0] CAdr, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr + input logic [$clog2(NUMLINES)-1:0] CacheSet, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr input logic [`PA_BITS-1:0] PAdr, // Physical address input logic [LINELEN-1:0] LineWriteData, // Final data written to cache (D$ only) input logic SetValid, // Set the dirty bit in the selected way and set @@ -114,7 +114,7 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26, ///////////////////////////////////////////////////////////////////////////////////////////// ram1p1rwbe #(.DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, .ce(CacheEn), - .addr(CAdr), .dout(ReadTag), .bwe('1), + .addr(CacheSet), .dout(ReadTag), .bwe('1), .din(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN)); @@ -136,7 +136,7 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26, localparam LOGNUMSRAM = $clog2(NUMSRAM); for(words = 0; words < NUMSRAM; words++) begin: word - ram1p1rwbe #(.DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CAdr), + ram1p1rwbe #(.DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSet), .dout(ReadDataLine[SRAMLEN*(words+1)-1:SRAMLEN*words]), .din(LineWriteData[SRAMLEN*(words+1)-1:SRAMLEN*words]), .we(SelectedWriteWordEn), .bwe(FinalByteMask[SRAMLENINBYTES*(words+1)-1:SRAMLENINBYTES*words])); @@ -152,9 +152,9 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26, always_ff @(posedge clk) begin // Valid bit array, if (reset) ValidBits <= #1 '0; if(CacheEn) begin - ValidWay <= #1 ValidBits[CAdr]; + ValidWay <= #1 ValidBits[CacheSet]; if(InvalidateCache) ValidBits <= #1 '0; - else if (SetValidEN | (ClearValidWay & ~FlushStage)) ValidBits[CAdr] <= #1 SetValidWay; + else if (SetValidEN | (ClearValidWay & ~FlushStage)) ValidBits[CacheSet] <= #1 SetValidWay; end end @@ -168,8 +168,8 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26, // reset is optional. Consider merging with TAG array in the future. //if (reset) DirtyBits <= #1 {NUMLINES{1'b0}}; if(CacheEn) begin - Dirty <= #1 DirtyBits[CAdr]; - if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CAdr] <= #1 SetDirtyWay; + Dirty <= #1 DirtyBits[CacheSet]; + if((SetDirtyWay | ClearDirtyWay) & ~FlushStage) DirtyBits[CacheSet] <= #1 SetDirtyWay; end end end else assign Dirty = 1'b0; From a27051b8a8ea5994bb16760f2d2c3a3286104068 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 13 Mar 2023 14:54:13 -0500 Subject: [PATCH 22/25] Updated NextAdr to NextSet. --- src/cache/cache.sv | 8 ++++---- src/ifu/ifu.sv | 2 +- src/lsu/lsu.sv | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cache/cache.sv b/src/cache/cache.sv index bea04a4d..de3b8d71 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -39,7 +39,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE input logic [1:0] CacheAtomic, // Atomic operation input logic FlushCache, // Flush all dirty lines back to memory input logic InvalidateCache, // Clear all valid bits - input logic [11:0] NextAdr, // Virtual address, but we only use the lower 12 bits. + input logic [11:0] NextSet, // Virtual address, but we only use the lower 12 bits. input logic [`PA_BITS-1:0] PAdr, // Physical address input logic [(WORDLEN-1)/8:0] ByteMask, // Which bytes to write (D$ only) input logic [WORDLEN-1:0] CacheWriteData, // Data to write to cache (D$ only) @@ -50,7 +50,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE output logic CacheMiss, // Cache miss output logic CacheAccess, // Cache access // lsu control - input logic SelHPTW, // Use PAdr from Hardware Page Table Walker rather than NextAdr + input logic SelHPTW, // Use PAdr from Hardware Page Table Walker rather than NextSet // Bus fsm interface input logic CacheBusAck, // Bus operation completed input logic SelBusBeat, // Word in cache line comes from BeatCount @@ -106,12 +106,12 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE // Read Path ///////////////////////////////////////////////////////////////////////////////////////////// - // Choose read address (CacheSet). Normally use NextAdr, but use PAdr during stalls + // Choose read address (CacheSet). Normally use NextSet, but use PAdr during stalls // and FlushAdr when handling D$ flushes // The icache must update to the newest PCNextF on flush as it is probably a trap. Trap // sets PCNextF to XTVEC and the icache must start reading the instruction. assign AdrSelMuxSel = {SelFlush, ((SelAdr | SelHPTW) & ~((READ_ONLY_CACHE == 1) & FlushStage))}; - mux3 #(SETLEN) AdrSelMux(NextAdr[SETTOP-1:OFFSETLEN], PAdr[SETTOP-1:OFFSETLEN], FlushAdr, + mux3 #(SETLEN) AdrSelMux(NextSet[SETTOP-1:OFFSETLEN], PAdr[SETTOP-1:OFFSETLEN], FlushAdr, AdrSelMuxSel, CacheSet); // Array of cache ways, along with victim, hit, dirty, and read merging logic diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index d1d468ae..d8d48cbf 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -245,7 +245,7 @@ module ifu ( .CacheWriteData('0), .CacheRW(CacheRWF), .CacheAtomic('0), .FlushCache('0), - .NextAdr(PCSpillNextF[11:0]), + .NextSet(PCSpillNextF[11:0]), .PAdr(PCPF), .CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM)); ahbcacheinterface #(WORDSPERLINE, LOGBWPL, LINELEN, LLENPOVERAHBW) diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index 4a53801b..628c85bb 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -266,7 +266,7 @@ module lsu ( cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN), .NUMWAYS(`DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(`LLEN), .MUXINTERVAL(`LLEN), .READ_ONLY_CACHE(0)) dcache( .clk, .reset, .Stall(GatedStallW), .SelBusBeat, .FlushStage(FlushW), .CacheRW(CacheRWM), .CacheAtomic(CacheAtomicM), - .FlushCache(FlushDCache), .NextAdr(IEUAdrE[11:0]), .PAdr(PAdrM), + .FlushCache(FlushDCache), .NextSet(IEUAdrE[11:0]), .PAdr(PAdrM), .ByteMask(ByteMaskM), .BeatCount(BeatCount[AHBWLOGBWPL-1:AHBWLOGBWPL-LLENLOGBWPL]), .CacheWriteData(LSUWriteDataM), .SelHPTW, .CacheStall(DCacheStallM), .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess), From 407b3c488d13a3b23dd73593b15f76e2e3f5269e Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 14 Mar 2023 13:09:50 -0500 Subject: [PATCH 23/25] Book updates. --- src/hazard/hazard.sv | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index 85d23d37..cf3a22c1 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -43,7 +43,7 @@ module hazard ( ); logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause; - logic FirstUnstalledD, FirstUnstalledE, FirstUnstalledM, FirstUnstalledW; + logic LatestUnstalledD, LatestUnstalledE, LatestUnstalledM, LatestUnstalledW; logic FlushDCause, FlushECause, FlushMCause, FlushWCause; // stalls and flushes @@ -95,14 +95,14 @@ module hazard ( assign #1 StallW = StallWCause; // detect the first stage that is not stalled - assign FirstUnstalledD = ~StallD & StallF; - assign FirstUnstalledE = ~StallE & StallD; - assign FirstUnstalledM = ~StallM & StallE; - assign FirstUnstalledW = ~StallW & StallM; + assign LatestUnstalledD = ~StallD & StallF; + assign LatestUnstalledE = ~StallE & StallD; + assign LatestUnstalledM = ~StallM & StallE; + assign LatestUnstalledW = ~StallW & StallM; // Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush - assign #1 FlushD = FirstUnstalledD | FlushDCause; - assign #1 FlushE = FirstUnstalledE | FlushECause; - assign #1 FlushM = FirstUnstalledM | FlushMCause; - assign #1 FlushW = FirstUnstalledW | FlushWCause; + assign #1 FlushD = LatestUnstalledD | FlushDCause; + assign #1 FlushE = LatestUnstalledE | FlushECause; + assign #1 FlushM = LatestUnstalledM | FlushMCause; + assign #1 FlushW = LatestUnstalledW | FlushWCause; endmodule From b5fa5bb47a28544b2e0ba423c51a52003bda7571 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 17 Mar 2023 00:47:52 -0500 Subject: [PATCH 24/25] Added notes on how to run QEMU to generate linux image. --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 75778102..f7abf0ba 100644 --- a/README.md +++ b/README.md @@ -261,6 +261,22 @@ $ make all Note: When the make tasks complete, you’ll find source code in $RISCV/buildroot/output/build and the executables in $RISCV/buildroot/output/images. +### Generate load images for linux boot + +The Questa linux boot uses preloaded bootram and ram memory. We use QEMU to generate these preloaded memory files. Files output in $RISCV/linux-testvectors + + cd cvw/linux/testvector-generation + ./genInitMem.sh + +This may require changing file permissions to the linux-testvectors directory. + +### Generate QEMU linux trace + +The linux testbench can instruction by instruction compare Wally's committed instructions against QEMU. To do this QEMU outputs a log file consisting of all instructions executed. Interrupts are handled by forcing the testbench to generate an interrupt at the same cycle as in QEMU. Generating this trace will take more than 24 hours. + + cd cvw/linux/testvector-generation + ./genTrace.sh + ### Download Synthesis Libraries For logic synthesis, we need a synthesis tool (see Section 3.XREF) and a cell library. Clone the OSU 12-track cell library for the Skywater 130 nm process: From 69d9bde3588a4110409a7a83f39ca3e88b1709b8 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 20 Mar 2023 11:52:10 -0500 Subject: [PATCH 25/25] Fixed bug in the tool chain install script. --- bin/wally-tool-chain-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/wally-tool-chain-install.sh b/bin/wally-tool-chain-install.sh index 331ca13d..2c6d5851 100755 --- a/bin/wally-tool-chain-install.sh +++ b/bin/wally-tool-chain-install.sh @@ -62,7 +62,7 @@ make install # elf2hex cd $RISCV #export PATH=$RISCV/riscv-gnu-toolchain/bin:$PATH -gexport PATH=$RISCV/bin:$PATH +export PATH=$RISCV/bin:$PATH git clone https://github.com/sifive/elf2hex.git cd elf2hex autoreconf -i