From 55c156046705c94bfd526c95055669b1b1021972 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 17 Oct 2023 10:00:50 -0500 Subject: [PATCH 01/26] Reverted linux testbench to not check for match against QEMU. --- testbench/testbench-linux.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testbench/testbench-linux.sv b/testbench/testbench-linux.sv index 54cfc66e4..683f55952 100644 --- a/testbench/testbench-linux.sv +++ b/testbench/testbench-linux.sv @@ -27,7 +27,7 @@ `include "config.vh" import cvw::*; -`define DEBUG_TRACE 1 +`define DEBUG_TRACE 0 // Debug Levels // 0: don't check against QEMU // 1: print disagreements with QEMU, but only halt on PCW disagreements From b01e1604e0ea92b65c9538508539b5767a715666 Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 18 Oct 2023 05:38:36 -0700 Subject: [PATCH 02/26] Config file cleanup --- config/rv32i/config.vh | 2 +- config/rv64i/config.vh | 2 +- sim/lint-wally | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/rv32i/config.vh b/config/rv32i/config.vh index 008687007..5c34ae413 100644 --- a/config/rv32i/config.vh +++ b/config/rv32i/config.vh @@ -36,7 +36,7 @@ localparam XLEN = 32'd32; localparam IEEE754 = 0; // I -localparam MISA = (32'h00000104); +localparam MISA = (32'h00000100); localparam ZICSR_SUPPORTED = 0; localparam ZIFENCEI_SUPPORTED = 0; localparam COUNTERS = 0; diff --git a/config/rv64i/config.vh b/config/rv64i/config.vh index 35fc2bdfa..ea668a45e 100644 --- a/config/rv64i/config.vh +++ b/config/rv64i/config.vh @@ -36,7 +36,7 @@ localparam XLEN = 32'd64; localparam IEEE754 = 0; // MISA RISC-V configuration per specification -localparam MISA = (32'h00000104); +localparam MISA = (32'h00000100); localparam ZICSR_SUPPORTED = 0; localparam ZIFENCEI_SUPPORTED = 0; localparam COUNTERS = 0; diff --git a/sim/lint-wally b/sim/lint-wally index 97bd2a877..263fb864f 100755 --- a/sim/lint-wally +++ b/sim/lint-wally @@ -16,7 +16,7 @@ done echo "All lints run with no errors or warnings" # --lint-only just runs lint rather than trying to compile and simulate -# -I points to the include directory where files such as `include wally-config.vh are found +# -I points to the include directory where files such as `include config.vh are found # For more exhaustive (and sometimes spurious) warnings, add --Wall to the Verilator command # Unfortunately, this produces a bunch of UNUSED and UNDRIVEN signal warnings in blocks that are configured to not exist. From 09b3a494714e838881bdbb9b29c4d5728af86eab Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 18 Oct 2023 05:50:41 -0700 Subject: [PATCH 03/26] Removed unnecessary RV64 PWDATA muxing from AHB peripherals because LSU already replicates --- src/uncore/ahbapbbridge.sv | 1 - src/uncore/gpio_apb.sv | 11 +++-------- src/uncore/plic_apb.sv | 10 +++------- src/uncore/uart_apb.sv | 28 +++------------------------- 4 files changed, 9 insertions(+), 41 deletions(-) diff --git a/src/uncore/ahbapbbridge.sv b/src/uncore/ahbapbbridge.sv index 381297f00..454f4d5df 100644 --- a/src/uncore/ahbapbbridge.sv +++ b/src/uncore/ahbapbbridge.sv @@ -88,7 +88,6 @@ module ahbapbbridge import cvw::*; #(parameter cvw_t P, int i; always_comb begin // default: no peripheral selected: read 0, indicate ready during access phase so bus doesn't hang - // *** also could assert ready right away HRDATA = 0; PREADYOUT = 1'b1; for (i=0; i Date: Wed, 18 Oct 2023 14:29:46 -0700 Subject: [PATCH 04/26] wrapper bug fix --- synthDC/scripts/wrapperGen.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/synthDC/scripts/wrapperGen.py b/synthDC/scripts/wrapperGen.py index aacdb0634..e931d0a65 100755 --- a/synthDC/scripts/wrapperGen.py +++ b/synthDC/scripts/wrapperGen.py @@ -43,7 +43,7 @@ index=0 # string copy logic for l in lines: - if l.find("module") == 0: + if l.lstrip().find("module") == 0: lineModuleStart = index moduleName = l.split()[1] writeBuf = True @@ -51,7 +51,7 @@ for l in lines: continue if (writeBuf): buf += l - if l.find (");") == 0: + if l.lstrip().find (");") == 0: lineModuleEnd = index break index+=1 @@ -64,6 +64,7 @@ wrapperPath = f"{os.getenv('WALLY')}/synthDC/wrappers/{moduleName}wrapper.sv" # clear wrappers directory os.system(f"rm {os.getenv('WALLY')}/synthDC/wrappers/*") +os.system(f"mkdir {os.getenv('WALLY')}/synthDC/wrappers") fout = open(wrapperPath, "w") From 379337fee0c63fdb5af43fb7157a07d607d4d6a5 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 19 Oct 2023 06:16:52 -0700 Subject: [PATCH 05/26] Adjusted synthesis scripts to report on DESIGN even when a wrapper is used --- .gitignore | 1 + synthDC/scripts/synth.tcl | 15 +++++++++++---- synthDC/wallySynth.py | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 41ccba5f9..04ae44109 100644 --- a/.gitignore +++ b/.gitignore @@ -82,6 +82,7 @@ synthDC/ppa/plots synthDC/wallyplots/ synthDC/runArchive synthDC/hdl +synthDC/wrappers sim/power.saif tests/fp/vectors/*.tv synthDC/Summary.csv diff --git a/synthDC/scripts/synth.tcl b/synthDC/scripts/synth.tcl index 075bb5db9..00800a7ef 100755 --- a/synthDC/scripts/synth.tcl +++ b/synthDC/scripts/synth.tcl @@ -53,6 +53,7 @@ if { $wrapper == 1 } { } else { set my_toplevel $::env(DESIGN) } +set my_design $::env(DESIGN) # Set number of significant digits set report_default_significant_digits 6 @@ -238,6 +239,12 @@ 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 on DESIGN, not wrapper. However, design has a suffix for the parameters. +if { $wrapper == 1 } { + set designname [format "%s%s" $my_design "__*"] + current_design $designname +} + # Report Constraint Violators set filename [format "%s%s" $outputDir "/reports/constraint_all_violators.rpt"] redirect $filename {report_constraint -all_violators} @@ -246,16 +253,16 @@ redirect $filename {report_constraint -all_violators} redirect $outputDir/reports/check_design.rpt { check_design } # Report Final Netlist (Hierarchical) -set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".sv"] +set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_design ".sv"] write_file -f verilog -hierarchy -output $filename -set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".sdc"] +set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_design ".sdc"] write_sdc $filename -set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".ddc"] +set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_design ".ddc"] write_file -format ddc -hierarchy -o $filename -set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".sdf"] +set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_design ".sdf"] write_sdf $filename # QoR diff --git a/synthDC/wallySynth.py b/synthDC/wallySynth.py index 139bcdd60..141b6e8c5 100755 --- a/synthDC/wallySynth.py +++ b/synthDC/wallySynth.py @@ -7,7 +7,7 @@ import argparse def runSynth(config, mod, tech, freq, maxopt, usesram): global pool - command = "make synth DESIGN=wallypipelinedcore CONFIG={} MOD={} TECH={} DRIVE=FLOP FREQ={} MAXOPT={} USESRAM={} MAXCORES=1".format(config, mod, tech, freq, maxopt, usesram) + command = "make synth DESIGN=wallypipelinedcore CONFIG={} MOD={} TECH={} DRIVE=FLOP FREQ={} MAXOPT={} USESRAM={} MAXCORES=1 WRAPPER=1".format(config, mod, tech, freq, maxopt, usesram) pool.map(mask, [command]) def mask(command): From 8c6b17de6d2292e81b3dff616e8349ff3a282cd4 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 19 Oct 2023 10:44:03 -0700 Subject: [PATCH 06/26] Updated wrapper generation to be automatic without specifying WRAPPER=1; instead looks for cvw_t in the file. Also starting to add OSU 130 nm synthesis. --- bin/libppa.pl | 14 ++++++++++++-- bin/wally-tool-chain-install.sh | 4 ++++ synthDC/Makefile | 9 +-------- synthDC/scripts/synth.tcl | 10 ++++++---- synthDC/scripts/wrapperGen.py | 6 +++--- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/bin/libppa.pl b/bin/libppa.pl index 56b3702dd..ccf4f1548 100755 --- a/bin/libppa.pl +++ b/bin/libppa.pl @@ -41,6 +41,16 @@ my @cr; my @cf; my @rt; my @ft; # cell and corners to analyze my $libpath; my $libbase; my $cellname; my @corners; +# Sky130 +$libpath ="/opt/riscv/cad/lib/sky130_osu_sc_t12/12T_ms/lib"; +$libbase = "sky130_osu_sc_12T_ms_"; +$cellname = "sky130_osu_sc_12T_ms__inv_1"; +@corners = ("TT_1P8_25C.ccs", "tt_1P80_25C.ccs", "tt_1P62_25C.ccs", "tt_1P89_25C.ccs", "ss_1P60_-40C.ccs", "ss_1P60_100C.ccs", "ss_1P60_150C.ccs", "ff_1P95_-40C.ccs", "ff_1P95_100C.ccs", "ff_1P95_150C.ccs"); +printf("Library $libbase Cell $cellname\n"); +foreach my $corner (@corners) { + &analyzeCell($corner); +} + # Sky90 $libpath ="/opt/riscv/cad/lib/sky90/sky90_sc/V1.7.4/lib"; $libbase = "scc9gena_"; @@ -54,7 +64,7 @@ foreach my $corner (@corners) { # TSMC $libpath = "/proj/models/tsmc28/libraries/28nmtsmc/tcbn28hpcplusbwp30p140_190a/TSMCHOME/digital/Front_End/timing_power_noise/NLDM/tcbn28hpcplusbwp30p140_180a"; $libbase = "tcbn28hpcplusbwp30p140"; -$cellname = "INVD1..."; // replace this with the full name of the library cell +$cellname = "INVD1..."; # replace this with the full name of the library cell @corners = ("tt0p9v25c", "tt0p8v25c", "tt1v25c", "tt0p9v85c", "ssg0p9vm40c", "ssg0p9v125c", "ssg0p81vm40c", "ssg0p81v125c", "ffg0p88vm40c", "ffg0p88v125c", "ffg0p99vm40c", "ffg0p99v125c"); printf("\nLibrary $libbase Cell $cellname\n"); foreach my $corner (@corners) { @@ -129,7 +139,7 @@ sub analyzeCell { my $delay = &computeDelay($cap); my $cornerr = sprintf("%20s", $corner); my $delayr = sprintf("%2.1f", $delay*1000); - my $leakager = sprintf("%3.1f", $leakage); + my $leakager = sprintf("%3.3f", $leakage); print("$cornerr: Delay $delayr Leakage: $leakager capacitance: $cap\n"); #print("$cellname $corner: Area $area Leakage: $leakage capacitance: $cap delay $delay\n"); diff --git a/bin/wally-tool-chain-install.sh b/bin/wally-tool-chain-install.sh index 7ff470f17..26dd54c8d 100755 --- a/bin/wally-tool-chain-install.sh +++ b/bin/wally-tool-chain-install.sh @@ -167,3 +167,7 @@ sudo ln -sf $RISCV/sail-riscv/c_emulator/riscv_sim_RV32 /usr/bin/riscv_sim_RV32 sudo pip3 install testresources pip3 install git+https://github.com/riscv/riscof.git +# Download OSU Skywater 130 cell library +sudo mkdir -p $RISCV/cad/lib +cd $RISCV/cad/lib +sudo git clone https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t12 diff --git a/synthDC/Makefile b/synthDC/Makefile index 57b478795..8cbfb934e 100755 --- a/synthDC/Makefile +++ b/synthDC/Makefile @@ -17,11 +17,9 @@ export TECH ?= sky90 export MAXCORES ?= 1 # MAXOPT turns on flattening, boundary optimization, and retiming # The output netlist is hard to interpret, but significantly better PPA -# WRAPPER turns on wrapper generation export MAXOPT ?= 0 export DRIVE ?= FLOP export USESRAM ?= 0 -export WRAPPER ?= 0 time := $(shell date +%F-%H-%M) @@ -120,11 +118,6 @@ ifeq ($(SAIFPOWER), 1) cp -f ../sim/power.saif . endif - -mkwrapper: -ifeq ($(WRAPPER),1) - python3 $(WALLY)/synthDC/scripts/wrapperGen.py $(DESIGN) -endif mkdirecs: @echo "DC Synthesis" @mkdir -p $(OUTPUTDIR) @@ -134,7 +127,7 @@ mkdirecs: @mkdir -p $(OUTPUTDIR)/mapped @mkdir -p $(OUTPUTDIR)/unmapped -synth: mkwrapper mkdirecs configs rundc # clean +synth: mkdirecs configs rundc # clean rundc: ifeq ($(TECH), tsmc28psyn) diff --git a/synthDC/scripts/synth.tcl b/synthDC/scripts/synth.tcl index 00800a7ef..542cb8fc1 100755 --- a/synthDC/scripts/synth.tcl +++ b/synthDC/scripts/synth.tcl @@ -24,18 +24,20 @@ set hdl_src "../src" set saifpower $::env(SAIFPOWER) set maxopt $::env(MAXOPT) set drive $::env(DRIVE) -set wrapper $::env(WRAPPER) eval file copy -force [glob ${cfg}/*.vh] {$outputDir/hdl/} eval file copy -force [glob ${hdl_src}/cvw.sv] {$outputDir/hdl/} -#eval file copy -force [glob ${hdl_src}/../fpga/src/wallypipelinedsocwrapper.sv] {$outputDir/hdl/} eval file copy -force [glob ${hdl_src}/*/*.sv] {$outputDir/hdl/} eval file copy -force [glob ${hdl_src}/*/*/*.sv] {$outputDir/hdl/} -if {$wrapper ==1 } { + +# Check if a wrapper is needed (when cvw_t parameters are used) +set wrapper 0 +if {[eval exec grep "cvw_t" {$outputDir/hdl/$::env(DESIGN).sv}] ne ""} { + set wrapper 1 + exec python3 $::env(WALLY)/synthDC/scripts/wrapperGen.py $::env(DESIGN) eval file copy -force [glob ${hdl_src}/../synthDC/wrappers/$::env(DESIGN)wrapper.sv] {$outputDir/hdl/} } - # Only for FMA class project; comment out when done # eval file copy -force [glob ${hdl_src}/fma/fma16.v] {hdl/} diff --git a/synthDC/scripts/wrapperGen.py b/synthDC/scripts/wrapperGen.py index e931d0a65..d830f5155 100755 --- a/synthDC/scripts/wrapperGen.py +++ b/synthDC/scripts/wrapperGen.py @@ -63,8 +63,8 @@ buf += f"\t{moduleName} #(P) dut(.*);\nendmodule" wrapperPath = f"{os.getenv('WALLY')}/synthDC/wrappers/{moduleName}wrapper.sv" # clear wrappers directory -os.system(f"rm {os.getenv('WALLY')}/synthDC/wrappers/*") -os.system(f"mkdir {os.getenv('WALLY')}/synthDC/wrappers") +os.system(f"rm -f {os.getenv('WALLY')}/synthDC/wrappers/*") +os.system(f"mkdir -p {os.getenv('WALLY')}/synthDC/wrappers") fout = open(wrapperPath, "w") @@ -75,4 +75,4 @@ fout.close() -print(buf) \ No newline at end of file +#print(buf) \ No newline at end of file From b28777fae004a6f160f5f4e9259a3d35804e5193 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 19 Oct 2023 10:49:06 -0700 Subject: [PATCH 07/26] Removed wrapper from wallySynth because it is automatic now --- synthDC/wallySynth.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synthDC/wallySynth.py b/synthDC/wallySynth.py index 141b6e8c5..139bcdd60 100755 --- a/synthDC/wallySynth.py +++ b/synthDC/wallySynth.py @@ -7,7 +7,7 @@ import argparse def runSynth(config, mod, tech, freq, maxopt, usesram): global pool - command = "make synth DESIGN=wallypipelinedcore CONFIG={} MOD={} TECH={} DRIVE=FLOP FREQ={} MAXOPT={} USESRAM={} MAXCORES=1 WRAPPER=1".format(config, mod, tech, freq, maxopt, usesram) + command = "make synth DESIGN=wallypipelinedcore CONFIG={} MOD={} TECH={} DRIVE=FLOP FREQ={} MAXOPT={} USESRAM={} MAXCORES=1".format(config, mod, tech, freq, maxopt, usesram) pool.map(mask, [command]) def mask(command): From aa3bc1025952108dc2141ebea86d0d4e836754ed Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 19 Oct 2023 11:16:02 -0700 Subject: [PATCH 08/26] Modified log2 coding to avoid synthesis warning --- src/cache/cacheLRU.sv | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cache/cacheLRU.sv b/src/cache/cacheLRU.sv index 34ea59612..613dd6de7 100644 --- a/src/cache/cacheLRU.sv +++ b/src/cache/cacheLRU.sv @@ -70,8 +70,10 @@ module cacheLRU // coverage off // Excluded from coverage b/c it is untestable without varying NUMWAYS. function integer log2 (integer value); - for (log2=0; value>0; log2=log2+1) - value = value>>1; + int val; + val = value; + for (log2 = 0; val > 0; log2 = log2+1) + val = val >> 1; return log2; endfunction // log2 // coverage on From 46d16305a49d2db5d93c986ffaa9b698231ab46a Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 19 Oct 2023 13:46:30 -0700 Subject: [PATCH 09/26] Set drive for Sky130 --- synthDC/scripts/synth.tcl | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/synthDC/scripts/synth.tcl b/synthDC/scripts/synth.tcl index 542cb8fc1..bdd868dd1 100755 --- a/synthDC/scripts/synth.tcl +++ b/synthDC/scripts/synth.tcl @@ -148,18 +148,22 @@ set all_in_ex_clk [remove_from_collection [all_inputs] [get_ports $my_clk]] # Setting constraints on input ports if {$tech == "sky130"} { - set_driving_cell -lib_cell sky130_osu_sc_12T_ms__dff_1 -pin Q $all_in_ex_clk + if {$drive == "INV"} { + set_driving_cell -lib_cell inv -pin Y $all_in_ex_clk + } elseif {$drive == "FLOP"} { + set_driving_cell -lib_cell sky130_osu_sc_12T_ms__dff_1 -pin Q $all_in_ex_clk + } } elseif {$tech == "sky90"} { if {$drive == "INV"} { - set_driving_cell -lib_cell scc9gena_inv_1 -pin Y $all_in_ex_clk + set_driving_cell -lib_cell scc9gena_inv_1 -pin Y $all_in_ex_clk } elseif {$drive == "FLOP"} { - set_driving_cell -lib_cell scc9gena_dfxbp_1 -pin Q $all_in_ex_clk + set_driving_cell -lib_cell scc9gena_dfxbp_1 -pin Q $all_in_ex_clk } } elseif {$tech == "tsmc28" || $tech=="tsmc28psyn"} { if {$drive == "INV"} { - set_driving_cell -lib_cell INVD1BWP30P140 -pin ZN $all_in_ex_clk + set_driving_cell -lib_cell INVD1BWP30P140 -pin ZN $all_in_ex_clk } elseif {$drive == "FLOP"} { - set_driving_cell -lib_cell DFQD1BWP30P140 -pin Q $all_in_ex_clk + set_driving_cell -lib_cell DFQD1BWP30P140 -pin Q $all_in_ex_clk } } @@ -174,16 +178,20 @@ if {$drive == "FLOP"} { # Setting load constraint on output ports if {$tech == "sky130"} { - set_load [expr [load_of sky130_osu_sc_12T_ms_TT_1P8_25C.ccs/sky130_osu_sc_12T_ms__dff_1/D] * 1] [all_outputs] -} elseif {$tech == "sky90"} { if {$drive == "INV"} { - set_load [expr [load_of scc9gena_tt_1.2v_25C/scc9gena_inv_4/A] * 1] [all_outputs] + set_load [expr [load_of sky130_osu_sc_12T_ms_TT_1P8_25C.ccs/sky130_osu_sc_12T_ms__inv_4/A] * 1] [all_outputs] + } elseif {$drive == "FLOP"} { + set_load [expr [load_of sky130_osu_sc_12T_ms_TT_1P8_25C.ccs/sky130_osu_sc_12T_ms__dff_1/D] * 1] [all_outputs] + } + } elseif {$tech == "sky90"} { + if {$drive == "INV"} { + set_load [expr [load_of scc9gena_tt_1.2v_25C/scc9gena_inv_4/A] * 1] [all_outputs] } elseif {$drive == "FLOP"} { set_load [expr [load_of scc9gena_tt_1.2v_25C/scc9gena_dfxbp_1/D] * 1] [all_outputs] } } elseif {$tech == "tsmc28" || $tech == "tsmc28psyn"} { if {$drive == "INV"} { - set_load [expr [load_of tcbn28hpcplusbwp30p140tt0p9v25c/INVD4BWP30P140/I] * 1] [all_outputs] + set_load [expr [load_of tcbn28hpcplusbwp30p140tt0p9v25c/INVD4BWP30P140/I] * 1] [all_outputs] } elseif {$drive == "FLOP"} { set_load [expr [load_of tcbn28hpcplusbwp30p140tt0p9v25c/DFQD1BWP30P140/D] * 1] [all_outputs] } From badfc1e4bb03a20fdea6825040ed648b955f517a Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 20 Oct 2023 15:13:52 -0500 Subject: [PATCH 10/26] Updated comments for the cbom tests. --- .../riscv-test-suite/rv32i_m/privilege/src/WALLY-cbom-01.S | 2 +- .../riscv-test-suite/rv64i_m/privilege/src/WALLY-cbom-01.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-cbom-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-cbom-01.S index 3c129b998..b4d4bae3c 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-cbom-01.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-cbom-01.S @@ -13,7 +13,7 @@ # and does not write back. Clean: Writes back dirty cacheline if needed # and clears dirty bit. Does NOT clear valid bit. Flush: Cleans and then # Invalidates. These operations apply to all caches in the memory system. -# The tests are divided into three parts one for the data cache, instruction cache +# The tests are divided into three parts one for the data cache # and checks to verify the uncached regions of memory cause exceptions. # ----------- # Copyright (c) 2020. RISC-V International. All rights reserved. diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-cbom-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-cbom-01.S index edad0406a..74145955a 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-cbom-01.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-cbom-01.S @@ -13,7 +13,7 @@ # and does not write back. Clean: Writes back dirty cacheline if needed # and clears dirty bit. Does NOT clear valid bit. Flush: Cleans and then # Invalidates. These operations apply to all caches in the memory system. -# The tests are divided into three parts one for the data cache, instruction cache +# The tests are divided into three parts one for the data cache # and checks to verify the uncached regions of memory cause exceptions. # ----------- # Copyright (c) 2020. RISC-V International. All rights reserved. From e3154bb7a3741349791dd0ccd0d8d82ad0e05ebf Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 20 Oct 2023 15:15:47 -0500 Subject: [PATCH 11/26] Updated comments in the cboz tests. --- .../riscv-test-suite/rv32i_m/privilege/src/WALLY-cboz-01.S | 2 +- .../riscv-test-suite/rv64i_m/privilege/src/WALLY-cboz-01.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-cboz-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-cboz-01.S index 207c727ec..92e046bd1 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-cboz-01.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-cboz-01.S @@ -17,7 +17,7 @@ # SPDX-License-Identifier: BSD-3-Clause # ----------- # -# This assembly file tests the cbo.inval, cbo.clean, and cbo.flush instructions of the RISC-V Zicbom extension. +# This assembly file tests the cbo.zero instruction of the RISC-V Zicboz extension. # #include "model_test.h" diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-cboz-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-cboz-01.S index 22b076261..1fe3e120b 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-cboz-01.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-cboz-01.S @@ -17,7 +17,7 @@ # SPDX-License-Identifier: BSD-3-Clause # ----------- # -# This assembly file tests the cbo.inval, cbo.clean, and cbo.flush instructions of the RISC-V Zicbom extension. +# This assembly file tests the cbo.zero instruction of the RISC-V Zicboz extension. # #include "model_test.h" From 7347ed2527ecbb58110e7cdceb3f2cdea2335c4a Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 23 Oct 2023 15:29:50 -0500 Subject: [PATCH 12/26] Addeed script to sweep sim_bp for btb. --- bin/CModelBTBAccuracy.sh | 57 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100755 bin/CModelBTBAccuracy.sh diff --git a/bin/CModelBTBAccuracy.sh b/bin/CModelBTBAccuracy.sh new file mode 100755 index 000000000..5cde4238c --- /dev/null +++ b/bin/CModelBTBAccuracy.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +########################################### +## Written: ross1728@gmail.com +## Created: 23 October 2023 +## Modified: +## +## Purpose: Takes a directory of branch outcomes organized as 1 files per benchmark. +## Computes the geometric mean for btb accuracy +## +## 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. +################################################################################################ + + +Directory="$1" +Files="$1/*.log" + +for Size in $(seq 6 2 16) +do + Product=1.0 + Count=0 + BMDRArray=() + for File in $Files + do + lines=`sim_bp gshare 16 16 $Size 1 $File | tail -5` + Total=`echo "$lines" | head -1 | awk '{print $5}'` + Miss=`echo "$lines" | tail -2 | head -1 | awk '{print $8}'` + BMDR=`echo "$Miss / $Total" | bc -l` + BMDRArray+=("$BMDR") + if [ $Miss -eq 0 ]; then + Product=`echo "scale=200; $Product / $Total" | bc -l` + else + Product=`echo "scale=200; $Product * $Miss / $Total" | bc -l` + fi + Count=$((Count+1)) + done + # with such long precision bc outputs onto multiple lines + # must remove \n and \ from string + Product=`echo "$Product" | tr -d '\n' | tr -d '\\\'` + GeoMean=`perl -E "say $Product**(1/$Count)"` + echo "$Pred$Size $GeoMean" +done From 2b031ea44515288f70751ee97730b8a5969d9ff2 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 23 Oct 2023 15:30:43 -0500 Subject: [PATCH 13/26] Fixed issue 250. instruction classification was not correct for jalr ra (non zero). --- src/ifu/bpred/icpred.sv | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ifu/bpred/icpred.sv b/src/ifu/bpred/icpred.sv index 65e60c59c..70136bdaf 100644 --- a/src/ifu/bpred/icpred.sv +++ b/src/ifu/bpred/icpred.sv @@ -51,20 +51,20 @@ module icpred import cvw::*; #(parameter cvw_t P, // An alternative to using the BTB to store the instruction class is to partially decode // the instructions in the Fetch stage into, Call, Return, Jump, and Branch instructions. // This logic is not described in the text book as of 23 February 2023. - logic ccall, cj, cjr, ccallr, CJumpF, CBranchF; + logic cjal, cj, cjr, cjalr, CJumpF, CBranchF; logic NCJumpF, NCBranchF; if(P.C_SUPPORTED) begin logic [4:0] CompressedOpcF; assign CompressedOpcF = {PostSpillInstrRawF[1:0], PostSpillInstrRawF[15:13]}; - assign ccall = CompressedOpcF == 5'h09 & P.XLEN == 32; + assign cjal = CompressedOpcF == 5'h09 & P.XLEN == 32; assign cj = CompressedOpcF == 5'h0d; assign cjr = CompressedOpcF == 5'h14 & ~PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0; - assign ccallr = CompressedOpcF == 5'h14 & PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0; - assign CJumpF = ccall | cj | cjr | ccallr; + assign cjalr = CompressedOpcF == 5'h14 & PostSpillInstrRawF[12] & PostSpillInstrRawF[6:2] == 5'b0 & PostSpillInstrRawF[11:7] != 5'b0; + assign CJumpF = cjal | cj | cjr | cjalr; assign CBranchF = CompressedOpcF[4:1] == 4'h7; end else begin - assign {ccall, cj, cjr, ccallr, CJumpF, CBranchF} = '0; + assign {cjal, cj, cjr, cjalr, CJumpF, CBranchF} = '0; end assign NCJumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F; @@ -72,11 +72,11 @@ module icpred import cvw::*; #(parameter cvw_t P, assign BPBranchF = NCBranchF | (P.C_SUPPORTED & CBranchF); assign BPJumpF = NCJumpF | (P.C_SUPPORTED & (CJumpF)); - assign BPReturnF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // returnurn must returnurn to ra or r5 - (P.C_SUPPORTED & (ccallr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01)); + assign BPReturnF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01 & PostSpillInstrRawF[11:7] == 5'b0) | // return must return to ra or r5 + (P.C_SUPPORTED & cjr & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01)); assign BPCallF = (NCJumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // call(r) must link to ra or x5 - (P.C_SUPPORTED & (ccall | (ccallr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01))); + (P.C_SUPPORTED & (cjal | (cjalr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01))); end else begin // This section connects the BTB's instruction class prediction. From bce15ce3678971a945ef5732fdb877019310fb6e Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 23 Oct 2023 15:32:03 -0500 Subject: [PATCH 14/26] Added support for branch counters when there is no branch predictor. --- src/ifu/ifu.sv | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index af6f70898..5ecc0237c 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -340,8 +340,21 @@ module ifu import cvw::*; #(parameter cvw_t P) ( end else begin : bpred mux2 #(P.XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PC1NextF)); + logic BranchM, JumpM, BranchW, JumpW; + logic CallD, CallE, CallM, CallW; + logic ReturnD, ReturnE, ReturnM, ReturnW; assign BPWrongE = PCSrcE; - assign {InstrClassM, BPDirPredWrongM, BTAWrongM, RASPredPCWrongM, IClassWrongM} = '0; + icpred #(P, 0) icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, + .PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW, + .CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, + .BTBCallF(1'b0), .BTBReturnF(1'b0), .BTBJumpF(1'b0), + .BTBBranchF(1'b0), .BPCallF(), .BPReturnF(), .BPJumpF(), .BPBranchF(), .IClassWrongM, + .IClassWrongE(), .BPReturnWrongD()); + flopenrc #(1) PCSrcMReg(clk, reset, FlushM, ~StallM, PCSrcE, BPWrongM); + assign RASPredPCWrongM = '0; + assign BPDirPredWrongM = BPWrongM; + assign BTAWrongM = BPWrongM; + assign InstrClassM = {CallM, ReturnM, JumpM, BranchM}; assign NextValidPCE = PCE; end From c296bd3a02b2913784eee221596ec7517d1aff27 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 23 Oct 2023 16:09:40 -0500 Subject: [PATCH 15/26] Updated bpred-sim.py to take command line options to select between sweeping direction, target, class, or ras prediction. --- sim/bpred-sim.py | 117 ++++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 52 deletions(-) diff --git a/sim/bpred-sim.py b/sim/bpred-sim.py index 9a59e8866..9e7ec12a6 100755 --- a/sim/bpred-sim.py +++ b/sim/bpred-sim.py @@ -11,6 +11,7 @@ # ################################## import sys,os,shutil +import argparse class bcolors: HEADER = '\033[95m' @@ -46,55 +47,6 @@ configs = [ ) ] -# bpdSize = [6, 8, 10, 12, 14, 16] -# bpdType = ['twobit', 'gshare', 'global', 'gshare_basic', 'global_basic', 'local_basic'] -# for CurrBPType in bpdType: -# for CurrBPSize in bpdSize: -# name = CurrBPType+str(CurrBPSize) -# configOptions = "+define+INSTR_CLASS_PRED=0 +define+BPRED_OVERRIDE +define+BPRED_TYPE=" + str(bpdType.index(CurrBPType)) + "+define+BPRED_SIZE=" + str(CurrBPSize) -# tc = TestCase( -# name=name, -# variant="rv32gc", -# cmd="vsim > {} -c < {} -c < {} -c < {} -c < {} -c < {} -c < {} -c < {} -c < Date: Tue, 24 Oct 2023 10:29:02 -0500 Subject: [PATCH 16/26] Fixed bug in bpred-sim.py for btb and class size sweep. --- sim/bpred-sim.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sim/bpred-sim.py b/sim/bpred-sim.py index 9e7ec12a6..209e21fc4 100755 --- a/sim/bpred-sim.py +++ b/sim/bpred-sim.py @@ -119,7 +119,7 @@ def main(): bpdSize = [6, 8, 10, 12, 14, 16] for CurrBPSize in bpdSize: name = 'BTB'+str(CurrBPSize) - configOptions = "+define+INSTR_CLASS_PRED=1 +define+BPRED_OVERRIDE +define+BPRED_TYPE=\`BP_GSHARE" + "+define+BPRED_SIZE=16" + "+define+BTB_SIZE=" + str(CurrBPSize) + "+define+BTB_OVERRIDE" + configOptions = "+define+INSTR_CLASS_PRED=1 +define+BPRED_OVERRIDE +define+BPRED_TYPE=\`BP_GSHARE" + "+define+BPRED_SIZE=16" + "+define+RAS_SIZE=16+define+BTB_SIZE=" + str(CurrBPSize) + "+define+BTB_OVERRIDE" tc = TestCase( name=name, variant="rv32gc", From 7fc5268f47c92a863af1c001903e7d0175583ef2 Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 24 Oct 2023 10:45:41 -0700 Subject: [PATCH 17/26] Tested assembly language file for the pause example --- .gitignore | 1 + examples/asm/etc/Makefile | 11 +++++++++++ examples/asm/etc/pause.S | 25 +++++++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 examples/asm/etc/Makefile create mode 100644 examples/asm/etc/pause.S diff --git a/.gitignore b/.gitignore index 04ae44109..b4223b50e 100644 --- a/.gitignore +++ b/.gitignore @@ -62,6 +62,7 @@ examples/fp/fpcalc/fpcalc examples/C/inline/inline examples/C/sum_mixed/sum_mixed examples/asm/trap/trap +examples/asm/etc/pause src/fma/fma16_testgen linux/devicetree/debug/* !linux/devicetree/debug/dump-dts.sh diff --git a/examples/asm/etc/Makefile b/examples/asm/etc/Makefile new file mode 100644 index 000000000..72f99e975 --- /dev/null +++ b/examples/asm/etc/Makefile @@ -0,0 +1,11 @@ +TARGET = pause + +$(TARGET).objdump: $(TARGET) + riscv64-unknown-elf-objdump -D $(TARGET) > $(TARGET).objdump + +pause: pause.S Makefile + riscv64-unknown-elf-gcc -o pause -march=rv32ia_zihintpause -mabi=ilp32 -mcmodel=medany \ + -nostartfiles -T../../link/link.ld pause.S + +clean: + rm -f $(TARGET) $(TARGET).objdump diff --git a/examples/asm/etc/pause.S b/examples/asm/etc/pause.S new file mode 100644 index 000000000..4e0aacfb4 --- /dev/null +++ b/examples/asm/etc/pause.S @@ -0,0 +1,25 @@ +.section .text.init +.globl rvtest_entry_point +rvtest_entry_point: + + +la a0, lock + +spinlock: # address of lock is in a0 + lr.w t0, (a0) # read the lock + bnez t0, retry # spin until free + li t1, 1 + sc.w t0, t1, (a0) # try to write a 1 to take lock + bnez t0, retry # spin until successful + ret # got the lock! +retry: # no lock yet + pause # pause hint to reduce spin power + j spinlock # try again + + +self_loop: + j self_loop + +.data +lock: + .word 1 \ No newline at end of file From 17fd0c90dae133a37f4951f5dfa232d6757aac10 Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 24 Oct 2023 14:01:43 -0700 Subject: [PATCH 18/26] Fixed warnings of signed conversion and for Design Compiler --- src/ebu/ebufsmarb.sv | 2 +- src/ifu/ifu.sv | 2 +- src/lsu/swbytemask.sv | 2 +- synthDC/scripts/synth.tcl | 6 +++++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/ebu/ebufsmarb.sv b/src/ebu/ebufsmarb.sv index 91fa9e491..302c4752f 100644 --- a/src/ebu/ebufsmarb.sv +++ b/src/ebu/ebufsmarb.sv @@ -116,5 +116,5 @@ module ebufsmarb ( // 11 16 15 always_comb if (HBURST[2:1] == 2'b00) Threshold = 4'b0000; - else Threshold = (2 << HBURST[2:1]) - 1; + else Threshold = ('d2 << HBURST[2:1]) - 'd1; endmodule diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index af6f70898..bacff6b50 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -389,7 +389,7 @@ module ifu import cvw::*; #(parameter cvw_t P) ( flopenrc #(1) CompressedDReg(clk, reset, FlushD, ~StallD, CompressedF, CompressedD); flopenrc #(1) CompressedEReg(clk, reset, FlushE, ~StallE, CompressedD, CompressedE); - assign PCLinkE = PCE + (CompressedE ? 2 : 4); + assign PCLinkE = PCE + (CompressedE ? 'd2 : 'd4); // 'd4 means 4 but stops Design Compiler complaining about signed to unsigned conversion // pipeline original compressed instruction in case it is needed for MTVAL on an illegal instruction exception flopenrc #(16) InstrRawEReg(clk, reset, FlushE, ~StallE, InstrRawD[15:0], InstrRawE); diff --git a/src/lsu/swbytemask.sv b/src/lsu/swbytemask.sv index ad20a4414..d8c4ed167 100644 --- a/src/lsu/swbytemask.sv +++ b/src/lsu/swbytemask.sv @@ -33,7 +33,7 @@ module swbytemask #(parameter WORDLEN)( output logic [WORDLEN/8-1:0] ByteMask ); - assign ByteMask = ((2**(2**Size))-1) << Adr; + assign ByteMask =(('d2**('d2**Size))-'d1) << Adr; // 'd2 means 2, but stops Design Compiler from complaining about signed to unsigned conversion /* Equivalent to the following diff --git a/synthDC/scripts/synth.tcl b/synthDC/scripts/synth.tcl index bdd868dd1..997574312 100755 --- a/synthDC/scripts/synth.tcl +++ b/synthDC/scripts/synth.tcl @@ -12,6 +12,8 @@ suppress_message {VER-130} # statements in initial blocks are ignored suppress_message {VER-281} suppress_message {VER-173} + # Unsupported system task '$warn' +suppress_message {VER-274} # Enable Multicore set_host_options -max_cores $::env(MAXCORES) @@ -107,6 +109,7 @@ if { $saifpower == 1 } { if {$drive != "INV"} { set_false_path -from [get_ports reset] } +# for PPA multiplexer synthesis if {(($::env(DESIGN) == "ppa_mux2d_1") || ($::env(DESIGN) == "ppa_mux4d_1") || ($::env(DESIGN) == "ppa_mux8d_1"))} { set_false_path -from {s} } @@ -124,12 +127,13 @@ if { $find_clock != [list] } { set my_clk $my_clock_pin create_clock -period $my_period $my_clk set_clock_uncertainty $my_uncertainty [get_clocks $my_clk] -} else { + } else { echo "Did not find clock! Design is probably combinational!" set my_clk vclk create_clock -period $my_period -name $my_clk } + # Optimize paths that are close to critical set_critical_range 0.05 $current_design From bc877e9ca73d8e4028a8b8589344b1489d89f95a Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 24 Oct 2023 18:08:33 -0500 Subject: [PATCH 19/26] Possible fix for wfi. --- src/hazard/hazard.sv | 16 +++++++++++----- src/privileged/csr.sv | 6 +++++- src/wally/wallypipelinedcore.sv | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index 8efa454d9..b47ac410d 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -27,6 +27,7 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module hazard ( + input logic clk, reset, // Detect hazards input logic BPWrongE, CSRWriteFenceM, RetM, TrapM, input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD, @@ -45,10 +46,12 @@ module hazard ( logic FlushDCause, FlushECause, FlushMCause, FlushWCause; logic WFIStallM, WFIInterruptedM; + logic wfiW; // WFI logic - assign WFIStallM = wfiM & ~IntPendingM; // WFI waiting for an interrupt or timeout - assign WFIInterruptedM = wfiM & IntPendingM; // WFI detects a pending interrupt. Retire WFI; trap if interrupt is enabled. + flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); + assign WFIStallM = wfiW & ~IntPendingM; // WFI waiting for an interrupt or timeout + assign WFIInterruptedM = wfiW & IntPendingM; // WFI detects a pending interrupt. Retire WFI; trap if interrupt is enabled. // stalls and flushes // loads: stall for one cycle if the subsequent instruction depends on the load @@ -73,7 +76,8 @@ module hazard ( assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPWrongE; assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE)); assign FlushMCause = TrapM | RetM | CSRWriteFenceM; - assign FlushWCause = TrapM & ~WFIInterruptedM; + //assign FlushWCause = TrapM & ~WFIInterruptedM; + assign FlushWCause = TrapM; // Stall causes // Most data depenency stalls are identified in the decode stage @@ -86,11 +90,13 @@ module hazard ( assign StallFCause = '0; assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | FPUStallD) & ~FlushDCause; assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause; - assign StallMCause = WFIStallM & ~FlushMCause; + //assign StallMCause = WFIStallM & ~FlushMCause; + assign StallMCause = '0; // Need to gate IFUStallF when the equivalent FlushFCause = FlushDCause = 1. // assign StallWCause = ((IFUStallF & ~FlushDCause) | LSUStallM) & ~FlushWCause; // Because FlushWCause is a strict subset of FlushDCause, FlushWCause is factored out. - assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause); + //assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause); + assign StallWCause = (IFUStallF & ~FlushDCause) | ((LSUStallM | WFIStallM) & ~FlushWCause); // Stall each stage for cause or if the next stage is stalled // coverage off: StallFCause is always 0 diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 4cdce4989..38e8945d9 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -200,9 +200,13 @@ module csr import cvw::*; #(parameter cvw_t P) ( /////////////////////////////////////////// // CSR Write values /////////////////////////////////////////// + logic [P.XLEN-1:0] PCW; // *** can optimize out it's just PCM for all now. + logic wfiW; + flopenr #(P.XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); + flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); assign CSRAdrM = InstrM[31:20]; - assign UnalignedNextEPCM = TrapM ? ((wfiM & IntPendingM) ? PCM+4 : PCM) : CSRWriteValM; + assign UnalignedNextEPCM = TrapM ? ((wfiW & IntPendingM) ? PCW+4 : PCM) : CSRWriteValM; assign NextEPCM = P.C_SUPPORTED ? {UnalignedNextEPCM[P.XLEN-1:1], 1'b0} : {UnalignedNextEPCM[P.XLEN-1:2], 2'b00}; // 3.1.15 alignment assign NextCauseM = TrapM ? {InterruptM, CauseM}: {CSRWriteValM[P.XLEN-1], CSRWriteValM[3:0]}; assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM; diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index 00b348660..5df543903 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -264,7 +264,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( end // global stall and flush control - hazard hzu( + hazard hzu(.clk, .reset, .BPWrongE, .CSRWriteFenceM, .RetM, .TrapM, .LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD, .LSUStallM, .IFUStallF, From e4aebbaaa53e775136863a9fe1fa75723e33964e Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 24 Oct 2023 22:58:26 -0500 Subject: [PATCH 20/26] This version passes the regression test and solves issue #200. wfi's implemenation is changed so that wfi does not take an interrupt in the Memory stage. Instead it advances to the Writeback stage then traps. --- src/hazard/hazard.sv | 16 ++++++++-------- src/privileged/csr.sv | 6 ++---- src/privileged/privdec.sv | 4 +++- src/privileged/privileged.sv | 8 +++++--- src/privileged/trap.sv | 4 ++-- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index b47ac410d..94c967f32 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -50,8 +50,8 @@ module hazard ( // WFI logic flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); - assign WFIStallM = wfiW & ~IntPendingM; // WFI waiting for an interrupt or timeout - assign WFIInterruptedM = wfiW & IntPendingM; // WFI detects a pending interrupt. Retire WFI; trap if interrupt is enabled. + assign WFIStallM = wfiM & ~IntPendingM; // WFI waiting for an interrupt or timeout + assign WFIInterruptedM = wfiM & IntPendingM; // WFI detects a pending interrupt. Retire WFI; trap if interrupt is enabled. // stalls and flushes // loads: stall for one cycle if the subsequent instruction depends on the load @@ -76,8 +76,8 @@ module hazard ( assign FlushDCause = TrapM | RetM | CSRWriteFenceM | BPWrongE; assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE)); assign FlushMCause = TrapM | RetM | CSRWriteFenceM; - //assign FlushWCause = TrapM & ~WFIInterruptedM; - assign FlushWCause = TrapM; + assign FlushWCause = TrapM & ~WFIInterruptedM; + //assign FlushWCause = TrapM; // Stall causes // Most data depenency stalls are identified in the decode stage @@ -90,13 +90,13 @@ module hazard ( assign StallFCause = '0; assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | FPUStallD) & ~FlushDCause; assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause; - //assign StallMCause = WFIStallM & ~FlushMCause; - assign StallMCause = '0; + assign StallMCause = WFIStallM & ~FlushMCause; + //assign StallMCause = '0; // Need to gate IFUStallF when the equivalent FlushFCause = FlushDCause = 1. // assign StallWCause = ((IFUStallF & ~FlushDCause) | LSUStallM) & ~FlushWCause; // Because FlushWCause is a strict subset of FlushDCause, FlushWCause is factored out. - //assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause); - assign StallWCause = (IFUStallF & ~FlushDCause) | ((LSUStallM | WFIStallM) & ~FlushWCause); + assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause); + //assign StallWCause = (IFUStallF & ~FlushDCause) | ((LSUStallM | WFIStallM) & ~FlushWCause); // Stall each stage for cause or if the next stage is stalled // coverage off: StallFCause is always 0 diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index 38e8945d9..ccd06a1ea 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -39,6 +39,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( input logic CSRReadM, CSRWriteM, // read or write CSR input logic TrapM, // trap is occurring input logic mretM, sretM, wfiM, // return or WFI instruction + output logic wfiW, input logic IntPendingM, // at least one interrupt is pending and could occur if enabled input logic InterruptM, // interrupt is occurring input logic ExceptionM, // interrupt is occurring @@ -200,13 +201,10 @@ module csr import cvw::*; #(parameter cvw_t P) ( /////////////////////////////////////////// // CSR Write values /////////////////////////////////////////// - logic [P.XLEN-1:0] PCW; // *** can optimize out it's just PCM for all now. - logic wfiW; - flopenr #(P.XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); assign CSRAdrM = InstrM[31:20]; - assign UnalignedNextEPCM = TrapM ? ((wfiW & IntPendingM) ? PCW+4 : PCM) : CSRWriteValM; + assign UnalignedNextEPCM = TrapM ? PCM : CSRWriteValM; assign NextEPCM = P.C_SUPPORTED ? {UnalignedNextEPCM[P.XLEN-1:1], 1'b0} : {UnalignedNextEPCM[P.XLEN-1:2], 2'b00}; // 3.1.15 alignment assign NextCauseM = TrapM ? {InterruptM, CauseM}: {CSRWriteValM[P.XLEN-1], CSRWriteValM[3:0]}; assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM; diff --git a/src/privileged/privdec.sv b/src/privileged/privdec.sv index a0195f366..e6edbb086 100644 --- a/src/privileged/privdec.sv +++ b/src/privileged/privdec.sv @@ -29,7 +29,7 @@ module privdec import cvw::*; #(parameter cvw_t P) ( input logic clk, reset, - input logic StallM, + input logic StallM, StallW, FlushW, input logic [31:15] InstrM, // privileged instruction function field input logic PrivilegedM, // is this a privileged instruction (from IEU controller) input logic IllegalIEUFPUInstrM, // Not a legal IEU instruction @@ -75,6 +75,8 @@ module privdec import cvw::*; #(parameter cvw_t P) ( /////////////////////////////////////////// // WFI timeout Privileged Spec 3.1.6.5 /////////////////////////////////////////// + logic wfiW; // *** need to merge with others + flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); // *** remove if (P.U_SUPPORTED) begin:wfi logic [P.WFI_TIMEOUT_BIT:0] WFICount, WFICountPlus1; diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index fff4af8b8..c338d2475 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -115,12 +115,14 @@ module privileged import cvw::*; #(parameter cvw_t P) ( logic ExceptionM; // Memory stage instruction caused a fault logic HPTWInstrAccessFaultM; // Hardware page table access fault while fetching instruction PTE + logic wfiW; + // track the current privilege level privmode #(P) privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .DelegateM, .STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW); // decode privileged instructions - privdec #(P) pmd(.clk, .reset, .StallM, .InstrM(InstrM[31:15]), + privdec #(P) pmd(.clk, .reset, .StallM, .StallW, .FlushW, .InstrM(InstrM[31:15]), .PrivilegedM, .IllegalIEUFPUInstrM, .IllegalCSRAccessM, .PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .IllegalInstrFaultM, .EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .wfiM, .sfencevmaM); @@ -128,7 +130,7 @@ module privileged import cvw::*; #(parameter cvw_t P) ( // Control and Status Registers csr #(P) csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW, .InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrM, .PC2NextF, - .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .wfiM, .IntPendingM, .InterruptM, + .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .wfiM, .wfiW, .IntPendingM, .InterruptM, .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD, .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .BPWrongM, @@ -156,5 +158,5 @@ module privileged import cvw::*; #(parameter cvw_t P) ( .mretM, .sretM, .PrivilegeModeW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MEDELEG_REGW, .STATUS_MIE, .STATUS_SIE, .InstrValidM, .CommittedM, .CommittedF, - .TrapM, .RetM, .wfiM, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .CauseM); + .TrapM, .RetM, .wfiM, .wfiW, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .CauseM); endmodule diff --git a/src/privileged/trap.sv b/src/privileged/trap.sv index bcde634de..00ffc6617 100644 --- a/src/privileged/trap.sv +++ b/src/privileged/trap.sv @@ -33,7 +33,7 @@ module trap import cvw::*; #(parameter cvw_t P) ( input logic LoadAccessFaultM, StoreAmoAccessFaultM, EcallFaultM, InstrPageFaultM, input logic LoadPageFaultM, StoreAmoPageFaultM, // various trap sources input logic mretM, sretM, // return instructions - input logic wfiM, // wait for interrupt instruction + input logic wfiM, wfiW, // wait for interrupt instruction input logic [1:0] PrivilegeModeW, // current privilege mode input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, // interrupt pending, enabled, and delegate CSRs input logic [15:0] MEDELEG_REGW, // exception delegation SR @@ -68,7 +68,7 @@ module trap import cvw::*; #(parameter cvw_t P) ( assign Committed = CommittedM | CommittedF; assign EnabledIntsM = ({12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW); assign ValidIntsM = {12{~Committed}} & EnabledIntsM; - assign InterruptM = (|ValidIntsM) & InstrValidM; // suppress interrupt if the memory system has partially processed a request. + assign InterruptM = (|ValidIntsM) & InstrValidM & (~wfiM | wfiW); // suppress interrupt if the memory system has partially processed a request. assign DelegateM = P.S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM] : MEDELEG_REGW[CauseM]) & (PrivilegeModeW == P.U_MODE | PrivilegeModeW == P.S_MODE); From dd9059317f16685cc2130c6b52471b19b89d54e2 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 24 Oct 2023 23:05:12 -0500 Subject: [PATCH 21/26] Cleaned up the implementation changes for wfi. --- src/hazard/hazard.sv | 6 ------ src/privileged/csr.sv | 2 -- src/privileged/privdec.sv | 6 +++--- src/privileged/privileged.sv | 4 ++-- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index 94c967f32..cb70605c0 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -27,7 +27,6 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module hazard ( - input logic clk, reset, // Detect hazards input logic BPWrongE, CSRWriteFenceM, RetM, TrapM, input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD, @@ -46,10 +45,8 @@ module hazard ( logic FlushDCause, FlushECause, FlushMCause, FlushWCause; logic WFIStallM, WFIInterruptedM; - logic wfiW; // WFI logic - flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); assign WFIStallM = wfiM & ~IntPendingM; // WFI waiting for an interrupt or timeout assign WFIInterruptedM = wfiM & IntPendingM; // WFI detects a pending interrupt. Retire WFI; trap if interrupt is enabled. @@ -77,7 +74,6 @@ module hazard ( assign FlushECause = TrapM | RetM | CSRWriteFenceM |(BPWrongE & ~(DivBusyE | FDivBusyE)); assign FlushMCause = TrapM | RetM | CSRWriteFenceM; assign FlushWCause = TrapM & ~WFIInterruptedM; - //assign FlushWCause = TrapM; // Stall causes // Most data depenency stalls are identified in the decode stage @@ -91,12 +87,10 @@ module hazard ( assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | FPUStallD) & ~FlushDCause; assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause; assign StallMCause = WFIStallM & ~FlushMCause; - //assign StallMCause = '0; // Need to gate IFUStallF when the equivalent FlushFCause = FlushDCause = 1. // assign StallWCause = ((IFUStallF & ~FlushDCause) | LSUStallM) & ~FlushWCause; // Because FlushWCause is a strict subset of FlushDCause, FlushWCause is factored out. assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause); - //assign StallWCause = (IFUStallF & ~FlushDCause) | ((LSUStallM | WFIStallM) & ~FlushWCause); // Stall each stage for cause or if the next stage is stalled // coverage off: StallFCause is always 0 diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index ccd06a1ea..b25c3b905 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -39,7 +39,6 @@ module csr import cvw::*; #(parameter cvw_t P) ( input logic CSRReadM, CSRWriteM, // read or write CSR input logic TrapM, // trap is occurring input logic mretM, sretM, wfiM, // return or WFI instruction - output logic wfiW, input logic IntPendingM, // at least one interrupt is pending and could occur if enabled input logic InterruptM, // interrupt is occurring input logic ExceptionM, // interrupt is occurring @@ -201,7 +200,6 @@ module csr import cvw::*; #(parameter cvw_t P) ( /////////////////////////////////////////// // CSR Write values /////////////////////////////////////////// - flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); assign CSRAdrM = InstrM[31:20]; assign UnalignedNextEPCM = TrapM ? PCM : CSRWriteValM; diff --git a/src/privileged/privdec.sv b/src/privileged/privdec.sv index e6edbb086..eb17b8d04 100644 --- a/src/privileged/privdec.sv +++ b/src/privileged/privdec.sv @@ -39,7 +39,7 @@ module privdec import cvw::*; #(parameter cvw_t P) ( output logic IllegalInstrFaultM, // Illegal instruction output logic EcallFaultM, BreakpointFaultM, // Ecall or breakpoint; must retire, so don't flush it when the trap occurs output logic sretM, mretM, // return instructions - output logic wfiM, sfencevmaM // wfi / sfence.vma / sinval.vma instructions + output logic wfiM, wfiW, sfencevmaM // wfi / sfence.vma / sinval.vma instructions ); logic rs1zeroM; // rs1 field = 0 @@ -75,8 +75,6 @@ module privdec import cvw::*; #(parameter cvw_t P) ( /////////////////////////////////////////// // WFI timeout Privileged Spec 3.1.6.5 /////////////////////////////////////////// - logic wfiW; // *** need to merge with others - flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); // *** remove if (P.U_SUPPORTED) begin:wfi logic [P.WFI_TIMEOUT_BIT:0] WFICount, WFICountPlus1; @@ -88,6 +86,8 @@ module privdec import cvw::*; #(parameter cvw_t P) ( // coverage on end else assign WFITimeoutM = 0; + flopenrc #(1) wfiWReg(clk, reset, FlushW, ~StallW, wfiM, wfiW); + /////////////////////////////////////////// // Extract exceptions by name and handle them /////////////////////////////////////////// diff --git a/src/privileged/privileged.sv b/src/privileged/privileged.sv index c338d2475..d777e0bf9 100644 --- a/src/privileged/privileged.sv +++ b/src/privileged/privileged.sv @@ -125,12 +125,12 @@ module privileged import cvw::*; #(parameter cvw_t P) ( privdec #(P) pmd(.clk, .reset, .StallM, .StallW, .FlushW, .InstrM(InstrM[31:15]), .PrivilegedM, .IllegalIEUFPUInstrM, .IllegalCSRAccessM, .PrivilegeModeW, .STATUS_TSR, .STATUS_TVM, .STATUS_TW, .IllegalInstrFaultM, - .EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .wfiM, .sfencevmaM); + .EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .wfiM, .wfiW, .sfencevmaM); // Control and Status Registers csr #(P) csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW, .InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrM, .PC2NextF, - .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .wfiM, .wfiW, .IntPendingM, .InterruptM, + .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .wfiM, .IntPendingM, .InterruptM, .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD, .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .BPWrongM, From 63bcc7655ca99bf6bdfdfc2ce639b7393a0b4668 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Thu, 26 Oct 2023 12:20:42 -0500 Subject: [PATCH 22/26] Forgot to include this file in the last commit. --- src/wally/wallypipelinedcore.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index 5df543903..00b348660 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -264,7 +264,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( end // global stall and flush control - hazard hzu(.clk, .reset, + hazard hzu( .BPWrongE, .CSRWriteFenceM, .RetM, .TrapM, .LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD, .LSUStallM, .IFUStallF, From 9ca3bfc2c8dcbd570673c0166823e3ae0b87b01b Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Thu, 26 Oct 2023 12:24:36 -0500 Subject: [PATCH 23/26] Updated comments about Interrupt and wfi. --- src/privileged/trap.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/privileged/trap.sv b/src/privileged/trap.sv index 00ffc6617..bfbbeb65f 100644 --- a/src/privileged/trap.sv +++ b/src/privileged/trap.sv @@ -68,7 +68,8 @@ module trap import cvw::*; #(parameter cvw_t P) ( assign Committed = CommittedM | CommittedF; assign EnabledIntsM = ({12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW); assign ValidIntsM = {12{~Committed}} & EnabledIntsM; - assign InterruptM = (|ValidIntsM) & InstrValidM & (~wfiM | wfiW); // suppress interrupt if the memory system has partially processed a request. + assign InterruptM = (|ValidIntsM) & InstrValidM & (~wfiM | wfiW); // suppress interrupt if the memory system has partially processed a request. Delay interrupt until wfi is in the W stage. + // wfiW is to support possible but unlikely back to back wfi instructions. wfiM would be high in the M stage, while also in the W stage. assign DelegateM = P.S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM] : MEDELEG_REGW[CauseM]) & (PrivilegeModeW == P.U_MODE | PrivilegeModeW == P.S_MODE); From 5ca54438353183772a2dce6ee776482885d8f51d Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 26 Oct 2023 20:14:14 -0700 Subject: [PATCH 24/26] Fixed reporting of timing on modules with wrappers --- synthDC/scripts/synth.tcl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/synthDC/scripts/synth.tcl b/synthDC/scripts/synth.tcl index 997574312..3e616e130 100755 --- a/synthDC/scripts/synth.tcl +++ b/synthDC/scripts/synth.tcl @@ -257,6 +257,19 @@ set write_hier 1 ;# generate hierarchy report if { $wrapper == 1 } { set designname [format "%s%s" $my_design "__*"] current_design $designname + + # recreate clock below wrapper level or reporting doesn't work properly + 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 + } } # Report Constraint Violators From 12d1aed8a9360ab4d4a5c651c7cbacb57e716bf5 Mon Sep 17 00:00:00 2001 From: David Harris Date: Mon, 30 Oct 2023 07:06:34 -0700 Subject: [PATCH 25/26] Fix issue 444 by preventing delegation of misaligned instructions when compressed instructions are supported. --- src/privileged/csrm.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/privileged/csrm.sv b/src/privileged/csrm.sv index 6e5a49c80..ad489c208 100644 --- a/src/privileged/csrm.sv +++ b/src/privileged/csrm.sv @@ -94,7 +94,8 @@ module csrm import cvw::*; #(parameter cvw_t P) ( localparam DSCRATCH1 = 12'h7B3; // Constants localparam ZERO = {(P.XLEN){1'b0}}; - localparam MEDELEG_MASK = 16'hB3FF; + // when C is supported, there can't be misaligned instructions + localparam MEDELEG_MASK = P.C_SUPPORTED ? 16'hB3FE : 16'hB3FF; localparam MIDELEG_MASK = 12'h222; // we choose to not make machine interrupts delegable // There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop From 4d191e63cc2cfb4a6e120b66c89e9516972342bb Mon Sep 17 00:00:00 2001 From: David Harris Date: Mon, 30 Oct 2023 09:56:17 -0700 Subject: [PATCH 26/26] Fixed test cases for medeleg issue 444. Also added a COMPRESSED_SUPPORTED parameter true when C or Zca is supported, and use this to get compressed hardware such as the spill logic and the +2 adder. --- config/shared/config-shared.vh | 1 + config/shared/parameter-defs.vh | 1 + src/cvw.sv | 1 + src/ifu/bpred/icpred.sv | 10 +++++----- src/ifu/ifu.sv | 6 +++--- src/privileged/csr.sv | 2 +- src/privileged/csrm.sv | 4 ++-- .../references/WALLY-trap-01.reference_output | 2 +- .../references/WALLY-trap-s-01.reference_output | 2 +- .../references/WALLY-trap-u-01.reference_output | 2 +- .../references/WALLY-trap-01.reference_output | 2 +- .../references/WALLY-trap-s-01.reference_output | 2 +- .../references/WALLY-trap-u-01.reference_output | 2 +- 13 files changed, 20 insertions(+), 17 deletions(-) diff --git a/config/shared/config-shared.vh b/config/shared/config-shared.vh index 54a6675ee..48f02b848 100644 --- a/config/shared/config-shared.vh +++ b/config/shared/config-shared.vh @@ -24,6 +24,7 @@ localparam SV48 = 4'd9; localparam A_SUPPORTED = ((MISA >> 0) % 2 == 1); localparam B_SUPPORTED = ((ZBA_SUPPORTED | ZBB_SUPPORTED | ZBC_SUPPORTED | ZBS_SUPPORTED));// not based on MISA localparam C_SUPPORTED = ((MISA >> 2) % 2 == 1); +localparam COMPRESSED_SUPPORTED = C_SUPPORTED | ZCA_SUPPORTED; localparam D_SUPPORTED = ((MISA >> 3) % 2 == 1); localparam E_SUPPORTED = ((MISA >> 4) % 2 == 1); localparam F_SUPPORTED = ((MISA >> 5) % 2 == 1); diff --git a/config/shared/parameter-defs.vh b/config/shared/parameter-defs.vh index f3f216062..ee46001e1 100644 --- a/config/shared/parameter-defs.vh +++ b/config/shared/parameter-defs.vh @@ -118,6 +118,7 @@ localparam cvw_t P = '{ A_SUPPORTED : A_SUPPORTED, B_SUPPORTED : B_SUPPORTED, C_SUPPORTED : C_SUPPORTED, + COMPRESSED_SUPPORTED : COMPRESSED_SUPPORTED, D_SUPPORTED : D_SUPPORTED, E_SUPPORTED : E_SUPPORTED, F_SUPPORTED : F_SUPPORTED, diff --git a/src/cvw.sv b/src/cvw.sv index 01e0d6376..f4e0d941d 100644 --- a/src/cvw.sv +++ b/src/cvw.sv @@ -196,6 +196,7 @@ typedef struct packed { logic A_SUPPORTED; logic B_SUPPORTED; logic C_SUPPORTED; + logic COMPRESSED_SUPPORTED; // C or ZCA logic D_SUPPORTED; logic E_SUPPORTED; logic F_SUPPORTED; diff --git a/src/ifu/bpred/icpred.sv b/src/ifu/bpred/icpred.sv index 70136bdaf..e4895d4b7 100644 --- a/src/ifu/bpred/icpred.sv +++ b/src/ifu/bpred/icpred.sv @@ -54,7 +54,7 @@ module icpred import cvw::*; #(parameter cvw_t P, logic cjal, cj, cjr, cjalr, CJumpF, CBranchF; logic NCJumpF, NCBranchF; - if(P.C_SUPPORTED) begin + if(P.COMPRESSED_SUPPORTED) begin logic [4:0] CompressedOpcF; assign CompressedOpcF = {PostSpillInstrRawF[1:0], PostSpillInstrRawF[15:13]}; assign cjal = CompressedOpcF == 5'h09 & P.XLEN == 32; @@ -70,13 +70,13 @@ module icpred import cvw::*; #(parameter cvw_t P, assign NCJumpF = PostSpillInstrRawF[6:0] == 7'h67 | PostSpillInstrRawF[6:0] == 7'h6F; assign NCBranchF = PostSpillInstrRawF[6:0] == 7'h63; - assign BPBranchF = NCBranchF | (P.C_SUPPORTED & CBranchF); - assign BPJumpF = NCJumpF | (P.C_SUPPORTED & (CJumpF)); + assign BPBranchF = NCBranchF | (P.COMPRESSED_SUPPORTED & CBranchF); + assign BPJumpF = NCJumpF | (P.COMPRESSED_SUPPORTED & (CJumpF)); assign BPReturnF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01 & PostSpillInstrRawF[11:7] == 5'b0) | // return must return to ra or r5 - (P.C_SUPPORTED & cjr & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01)); + (P.COMPRESSED_SUPPORTED & cjr & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01)); assign BPCallF = (NCJumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // call(r) must link to ra or x5 - (P.C_SUPPORTED & (cjal | (cjalr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01))); + (P.COMPRESSED_SUPPORTED & (cjal | (cjalr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01))); end else begin // This section connects the BTB's instruction class prediction. diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index 80d146617..a93b24f9d 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -144,7 +144,7 @@ module ifu import cvw::*; #(parameter cvw_t P) ( // Spill Support ///////////////////////////////////////////////////////////////////////////////////////////// - if(P.C_SUPPORTED) begin : Spill + if(P.COMPRESSED_SUPPORTED) begin : Spill spill #(P) spill(.clk, .reset, .StallD, .FlushD, .PCF, .PCPlus4F, .PCNextF, .InstrRawF, .InstrUpdateDAF, .CacheableF, .IFUCacheBusStallF, .ITLBMissF, .PCSpillNextF, .PCSpillF, .SelSpillNextF, .PostSpillInstrRawF, .CompressedF); end else begin : NoSpill @@ -366,7 +366,7 @@ module ifu import cvw::*; #(parameter cvw_t P) ( flopenrc #(P.XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD); // expand 16-bit compressed instructions to 32 bits - if (P.C_SUPPORTED | P.ZCA_SUPPORTED) begin + if (P.COMPRESSED_SUPPORTED) begin logic IllegalCompInstrD; decompress #(P) decomp(.InstrRawD, .InstrD, .IllegalCompInstrD); assign IllegalIEUInstrD = IllegalBaseInstrD | IllegalCompInstrD; // illegal if bad 32 or 16-bit instr @@ -386,7 +386,7 @@ module ifu import cvw::*; #(parameter cvw_t P) ( // 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] & ~P.C_SUPPORTED) & PCSrcE; + assign BranchMisalignedFaultE = (IEUAdrE[1] & ~P.COMPRESSED_SUPPORTED) & PCSrcE; flopenr #(1) InstrMisalignedReg(clk, reset, ~StallM, BranchMisalignedFaultE, InstrMisalignedFaultM); // Instruction and PC/PCLink pipeline registers diff --git a/src/privileged/csr.sv b/src/privileged/csr.sv index b25c3b905..7b590c077 100644 --- a/src/privileged/csr.sv +++ b/src/privileged/csr.sv @@ -203,7 +203,7 @@ module csr import cvw::*; #(parameter cvw_t P) ( assign CSRAdrM = InstrM[31:20]; assign UnalignedNextEPCM = TrapM ? PCM : CSRWriteValM; - assign NextEPCM = P.C_SUPPORTED ? {UnalignedNextEPCM[P.XLEN-1:1], 1'b0} : {UnalignedNextEPCM[P.XLEN-1:2], 2'b00}; // 3.1.15 alignment + assign NextEPCM = P.COMPRESSED_SUPPORTED ? {UnalignedNextEPCM[P.XLEN-1:1], 1'b0} : {UnalignedNextEPCM[P.XLEN-1:2], 2'b00}; // 3.1.15 alignment assign NextCauseM = TrapM ? {InterruptM, CauseM}: {CSRWriteValM[P.XLEN-1], CSRWriteValM[3:0]}; assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM; assign UngatedCSRMWriteM = CSRWriteM & (PrivilegeModeW == P.M_MODE); diff --git a/src/privileged/csrm.sv b/src/privileged/csrm.sv index ad489c208..2d714bf6a 100644 --- a/src/privileged/csrm.sv +++ b/src/privileged/csrm.sv @@ -94,8 +94,8 @@ module csrm import cvw::*; #(parameter cvw_t P) ( localparam DSCRATCH1 = 12'h7B3; // Constants localparam ZERO = {(P.XLEN){1'b0}}; - // when C is supported, there can't be misaligned instructions - localparam MEDELEG_MASK = P.C_SUPPORTED ? 16'hB3FE : 16'hB3FF; + // when compressed instructions are supported, there can't be misaligned instructions + localparam MEDELEG_MASK = P.COMPRESSED_SUPPORTED ? 16'hB3FE : 16'hB3FF; localparam MIDELEG_MASK = 12'h222; // we choose to not make machine interrupts delegable // There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-01.reference_output index d5a114ab3..e45c4d947 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-01.reference_output @@ -55,7 +55,7 @@ FFFFFFFF # stimecmp readback 8000000b # mcause value from m ext interrupt 00000000 # mtval for mext interrupt (0x0) 00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 -0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable) +0000b3fe # medeleg after attempted write of all 1's (only some bits are writeable) 00000222 # mideleg after attempted write of all 1's (only some bits are writeable) # skipping instruction address fault since they're impossible with compressed instrs enabled 00000001 # mcause from an instruction access fault 00000000 # mtval of faulting instruction address (0x0) diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-s-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-s-01.reference_output index 575427b04..54d13773a 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-s-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-s-01.reference_output @@ -48,7 +48,7 @@ 00000009 # scause from S mode ecall 00000000 # stval of ecall (*** defined to be zero for now) 00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0 -0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable) +0000b3fe # medeleg after attempted write of all 1's (only some bits are writeable) 00000222 # mideleg after attempted write of all 1's (only some bits are writeable) 0000000b # scause from M mode ecall 00000000 # stval of ecall (*** defined to be zero for now) diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-u-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-u-01.reference_output index 8529cbe64..9492779df 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-u-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-trap-u-01.reference_output @@ -45,7 +45,7 @@ 00000008 # scause from U mode ecall 00000000 # stval of ecall (*** defined to be zero for now) 00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0 -0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable) +0000b3fe # medeleg after attempted write of all 1's (only some bits are writeable) 00000222 # mideleg after attempted write of all 1's (only some bits are writeable) 0000000b # scause from M mode ecall 00000000 # stval of ecall (*** defined to be zero for now) diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output index 5c9b816fb..557341ad4 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output @@ -112,7 +112,7 @@ FFFFFFFF # stimecmp low bits 00000000 00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 00000000 -0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable) +0000b3fe # medeleg after attempted write of all 1's (only some bits are writeable) 00000000 00000222 # mideleg after attempted write of all 1's (only some bits are writeable) 00000000 # skipping instruction address fault since they're impossible with compressed instrs enabled diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-s-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-s-01.reference_output index 9f3ddc647..bca764a76 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-s-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-s-01.reference_output @@ -98,7 +98,7 @@ 00000000 00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0 00000000 -0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable) +0000b3fe # medeleg after attempted write of all 1's (only some bits are writeable) 00000000 00000222 # mideleg after attempted write of all 1's (only some bits are writeable) 00000000 diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-u-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-u-01.reference_output index 36f08113a..1670f68d7 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-u-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-u-01.reference_output @@ -92,7 +92,7 @@ 00000000 00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0 00000000 -0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable) +0000b3fe # medeleg after attempted write of all 1's (only some bits are writeable) 00000000 00000222 # mideleg after attempted write of all 1's (only some bits are writeable) 00000000