From 6d0c247926f7dfb0a5d64da37360e13c9c1b208d Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Mon, 28 Aug 2023 09:32:59 -0700 Subject: [PATCH 1/9] added configurability for wrapper --- synthDC/Makefile | 12 +- synthDC/scripts/synth.tcl | 5 +- synthDC/scripts/synthWrapper.tcl | 407 +++++++++++++++++++++++++++++++ 3 files changed, 420 insertions(+), 4 deletions(-) create mode 100755 synthDC/scripts/synthWrapper.tcl diff --git a/synthDC/Makefile b/synthDC/Makefile index 881abd406..58f54cb88 100755 --- a/synthDC/Makefile +++ b/synthDC/Makefile @@ -2,7 +2,6 @@ # Makefile for synthesis # Shreya Sanghai (ssanghai@hmc.edu) 2/28/2022 # Madeleine Masser-Frye (mmasserfrye@hmc.edu) 1/27/2023 -NAME := synth # defaults export DESIGN ?= wallypipelinedcore @@ -18,9 +17,18 @@ 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 + +ifeq ($(WRAPPER),1) + rm $(WALLY)/synthDC/wrappers/* + NAME := synthWrapper +else + NAME := synth +endif time := $(shell date +%F-%H-%M) hash := $(shell git rev-parse --short HEAD) @@ -120,7 +128,9 @@ endif mkwrapper: +ifeq ($(WRAPPER),1) python3 $(WALLY)/synthDC/scripts/wrapperGen.py $(DESIGN) +endif mkdirecs: @echo "DC Synthesis" @mkdir -p $(OUTPUTDIR) diff --git a/synthDC/scripts/synth.tcl b/synthDC/scripts/synth.tcl index bcf07902f..7de696da2 100755 --- a/synthDC/scripts/synth.tcl +++ b/synthDC/scripts/synth.tcl @@ -29,7 +29,6 @@ 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/} -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/} @@ -43,7 +42,7 @@ if { $saifpower == 1 } { set my_verilog_files [glob $outputDir/hdl/cvw.sv $outputDir/hdl/*.sv] # Set toplevel -set my_toplevel $::env(DESIGN)wrapper +set my_toplevel $::env(DESIGN) # Set number of significant digits set report_default_significant_digits 6 @@ -404,4 +403,4 @@ set t2 [clock seconds] set t [expr $t2 - $t1] echo [expr $t/60] -quit +quit \ No newline at end of file diff --git a/synthDC/scripts/synthWrapper.tcl b/synthDC/scripts/synthWrapper.tcl new file mode 100755 index 000000000..d15234692 --- /dev/null +++ b/synthDC/scripts/synthWrapper.tcl @@ -0,0 +1,407 @@ +# +# Synthesis Synopsys Flow +# james.stine@okstate.edu 27 Sep 2015 +# kekim@hmc.edu + +# start run clock +set t1 [clock seconds] + +# Ignore unnecessary warnings: +# intraassignment delays for nonblocking assignments are ignored +suppress_message {VER-130} +# statements in initial blocks are ignored +suppress_message {VER-281} +suppress_message {VER-173} + +# Enable Multicore +set_host_options -max_cores $::env(MAXCORES) + +# get outputDir and configDir from environment (Makefile) +set outputDir $::env(OUTPUTDIR) +set cfg $::env(CONFIGDIR) +set hdl_src "../src" +set saifpower $::env(SAIFPOWER) +set maxopt $::env(MAXOPT) +set drive $::env(DRIVE) + +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/} +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/} + +# Enables name mapping +if { $saifpower == 1 } { + saif_map -start +} + +# Verilog files +set my_verilog_files [glob $outputDir/hdl/cvw.sv $outputDir/hdl/*.sv] + +# Set toplevel +set my_toplevel $::env(DESIGN)wrapper + +# Set number of significant digits +set report_default_significant_digits 6 + +# V(HDL) Unconnectoed Pins Output +set verilogout_show_unconnected_pins "true" +set vhdlout_show_unconnected_pins "true" + +# Set up MW List +set MY_LIB_NAME $my_toplevel +# Create MW +if { [shell_is_in_topographical_mode] } { + echo "In Topographical Mode...processing\n" + create_mw_lib -technology $MW_REFERENCE_LIBRARY/$MW_TECH_FILE.tf \ + -mw_reference_library $mw_reference_library $outputDir/$MY_LIB_NAME + # Open MW + open_mw_lib $outputDir/$MY_LIB_NAME + + # TLU+ + set_tlu_plus_files -max_tluplus $MAX_TLU_FILE -min_tluplus $MIN_TLU_FILE \ + -tech2itf_map $PRS_MAP_FILE + +} else { + echo "In normal DC mode...processing\n" +} + +# Due to parameterized Verilog must use analyze/elaborate and not +# read_verilog/vhdl (change to pull in Verilog and/or VHDL) +# +#set alib_library_analysis_path ./$outputDir +define_design_lib WORK -path ./$outputDir/WORK +analyze -f sverilog -lib WORK $my_verilog_files +elaborate $my_toplevel -lib WORK + +# Set the current_design +current_design $my_toplevel +link + +# Reset all constraints +reset_design + +# Power Dissipation Analysis +######### OPTIONAL !!!!!!!!!!!!!!!! +if { $saifpower == 1 } { + read_saif -input power.saif -instance_name testbench/dut/core -auto_map_names -verbose +} + +# Set reset false path +if {$drive != "INV"} { + set_false_path -from [get_ports reset] +} +if {(($::env(DESIGN) == "ppa_mux2d_1") || ($::env(DESIGN) == "ppa_mux4d_1") || ($::env(DESIGN) == "ppa_mux8d_1"))} { + set_false_path -from {s} +} + +# Set Frequency in [MHz] or period in [ns] +set my_clock_pin clk +set my_uncertainty 0.0 +set my_clk_freq_MHz $::env(FREQ) +set my_period [expr 1000.0 / $my_clk_freq_MHz] + +# Create clock object +set find_clock [ find port [list $my_clock_pin] ] +if { $find_clock != [list] } { + echo "Found clock!" + set my_clk $my_clock_pin + create_clock -period $my_period $my_clk + set_clock_uncertainty $my_uncertainty [get_clocks $my_clk] +} else { + echo "Did not find clock! Design is probably combinational!" + set my_clk vclk + create_clock -period $my_period -name $my_clk +} + +# Optimize paths that are close to critical +set_critical_range 0.05 $current_design + +# Partitioning - flatten or hierarchically synthesize +if { $maxopt == 1 } { + ungroup -all -simple_names -flatten +} + +# Set input pins except clock +set all_in_ex_clk [remove_from_collection [all_inputs] [get_ports $my_clk]] + +# Specifies delays be propagated through the clock network +# This is getting optimized poorly in the current flow, causing a lot of clock skew +# and unrealistic bad timing results. +# set_propagated_clock [get_clocks $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 +} elseif {$tech == "sky90"} { + if {$drive == "INV"} { + 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 + } +} elseif {$tech == "tsmc28" || $tech=="tsmc28psyn"} { + if {$drive == "INV"} { + 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 input/output delay +if {$drive == "FLOP"} { + set_input_delay 0.0 -max -clock $my_clk $all_in_ex_clk + set_output_delay 0.0 -max -clock $my_clk [all_outputs] +} else { + set_input_delay 0.0 -max -clock $my_clk $all_in_ex_clk + set_output_delay 0.0 -max -clock $my_clk [all_outputs] +} + +# Setting load constraint on output ports +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] + } 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] + } elseif {$drive == "FLOP"} { + set_load [expr [load_of tcbn28hpcplusbwp30p140tt0p9v25c/DFQD1BWP30P140/D] * 1] [all_outputs] + } +} + +if {$tech != "tsmc28psyn"} { + # Set the wire load model + set_wire_load_mode "top" +} + +# Set switching activities +# default activity factors are 1 for clocks, 0.1 for others +# static probability of 0.5 is used for leakage + +# Attempt Area Recovery - if looking for minimal area +# set_max_area 2000 + +# Set fanout +set_max_fanout 6 $all_in_ex_clk + +# Fix hold time violations (DH: this doesn't seem to be working right now) +#set_fix_hold [all_clocks] + +# Deal with constants and buffers to isolate ports +set_fix_multiple_port_nets -all -buffer_constants + +# setting up the group paths to find out the required timings +# group_path -name OUTPUTS -to [all_outputs] +# group_path -name INPUTS -from [all_inputs] +# group_path -name COMBO -from [all_inputs] -to [all_outputs] + +# Save Unmapped Design +# set filename [format "%s%s%s%s" $outputDir "/unmapped/" $my_toplevel ".ddc"] +# write_file -format ddc -hierarchy -o $filename + +# Compile statements +if { $maxopt == 1 } { + compile_ultra -retime + optimize_registers +} else { + compile_ultra -no_seq_output_inversion -no_boundary_optimization +} + +# Eliminate need for assign statements (yuck!) +set verilogout_no_tri true +set verilogout_equation false + +# setting to generate output files +set write_v 1 ;# generates structual netlist +set write_sdc 1 ;# generates synopsys design constraint file for p&r +set write_ddc 1 ;# compiler file in ddc format +set write_sdf 1 ;# sdf file for backannotated timing sim +set write_pow 1 ;# genrates estimated power report +set write_rep 1 ;# generates estimated area and timing report +set write_cst 1 ;# generate report of constraints +set write_hier 1 ;# generate hierarchy report + +# Report Constraint Violators +set filename [format "%s%s" $outputDir "/reports/constraint_all_violators.rpt"] +redirect $filename {report_constraint -all_violators} + +# Check design +redirect $outputDir/reports/check_design.rpt { check_design } + +# Report Final Netlist (Hierarchical) +set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".sv"] +write_file -f verilog -hierarchy -output $filename + +set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".sdc"] +write_sdc $filename + +set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".ddc"] +write_file -format ddc -hierarchy -o $filename + +set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".sdf"] +write_sdf $filename + +# QoR +set filename [format "%s%s" $outputDir "/reports/qor.rep"] +redirect $filename { report_qor } + +# Report Timing +set filename [format "%s%s" $outputDir "/reports/reportpath.rep"] +#redirect $filename { report_path_group } + +set filename [format "%s%s" $outputDir "/reports/report_clock.rep"] +# redirect $filename { report_clock } + +set filename [format "%s%s" $outputDir "/reports/timing.rep"] +redirect $filename { report_timing -capacitance -transition_time -nets -nworst 1 } + +set filename [format "%s%s" $outputDir "/reports/mindelay.rep"] +redirect $filename { report_timing -capacitance -transition_time -nets -delay_type min -nworst 1 } + +set filename [format "%s%s" $outputDir "/reports/per_module_timing.rep"] +redirect -append $filename { echo "\n\n\n//// Critical paths through ifu ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ifu/*} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical paths through ieu ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/*} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical paths through lsu ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {lsu/*} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical paths through ebu (ahblite) ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ebu/*} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical paths through mdu ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/*} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical paths through hzu ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {hzu/*} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical paths through priv ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {priv/*} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical paths through fpu ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {fpu/*} -nworst 1 } + +set filename [format "%s%s" $outputDir "/reports/mdu_timing.rep"] +redirect -append $filename { echo "\n\n\n//// Critical paths through entire mdu ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/*} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical paths through multiply unit ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.mul/*} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical paths through redundant multiplier ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.mul/bigmul/*} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical path through ProdM (mul output) ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.ProdM} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical path through PP0E (mul partial product) ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.mul/PP0E} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical paths through divide unit ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.div/*} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical path through QuotM (div output) ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.QuotM} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical path through RemM (div output) ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.RemM} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical path through div/WNextE ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.div/WNextE} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical path through div/XQNextE ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.div/XQNextE} -nworst 1 } +redirect -append $filename { echo "\n\n\n//// Critical path through div/DAbsBE ////\n\n\n" } +redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.div/DAbsBE} -nworst 1 } + +# set filename [format "%s%s%s%s" $outputDir "/reports/fpu_timing.rep"] +# redirect $filename { echo "\n\n\n//// Critical paths through fma ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {fpu/fpu.fma/*} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical paths through fpdiv ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {fpu/fpu.fdivsqrt/*} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical paths through faddcvt ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {fpu/fpu.faddcvt/*} -nworst 1 } + +# set filename [format "%s%s%s%s" $outputDir "/reports/ifu_timing.rep"] +# redirect -append $filename { echo "\n\n\n//// Critical path through PCF ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ifu/PCF} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical path through PCNextF ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ifu/PCNextF} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical path through FinalInstrRawF ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ifu/FinalInstrRawF} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical path through InstrD ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ifu/decomp/InstrD} -nworst 1 } + +# set filename [format "%s%s%s%s" $outputDir "/reports/stall_flush_timing.rep"] +# redirect -append $filename { echo "\n\n\n//// Critical path through StallD ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/StallD} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical path through StallE ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/StallE} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical path through StallM ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/StallM} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical path through StallW ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/StallW} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical path through FlushD ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/FlushD} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical path through FlushE ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/FlushE} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical path through FlushM ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/FlushM} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical path through FlushW ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/FlushW} -nworst 1 } + +# set filename [format "%s%s%s%s" $outputDir "/reports/ieu_timing.rep"] +# redirect -append $filename { echo "\n\n\n//// Critical path through datapath/R1D ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/R1D} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical path through datapath/R2D ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/R2D} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical path through datapath/SrcAE ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/SrcAE} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical path through datapath/ALUResultE ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/ALUResultE} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical path through datapath/WriteDataW ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/WriteDataW} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical path through datapath/ReadDataM ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/ReadDataM} -nworst 1 } + +# set filename [format "%s%s%s%s" $outputDir "/reports/fpu_timing.rep"] +# redirect -append $filename { echo "\n\n\n//// Critical paths through fma ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {fma/*} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical paths through fma1 ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {fma/fma1/*} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical paths through fma2 ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {postprocess/*} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical paths through fpdiv ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {divsqrt/*} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical paths through fcvt ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {fcvt/*} -nworst 1 } + +# set filename [format "%s%s%s%s" $outputDir "/reports/mmu_timing.rep"] +# redirect -append $filename { echo "\n\n\n//// Critical paths through immu/physicaladdress ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ifu/immu/PhysicalAddress} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical paths through dmmu/physicaladdress ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {lsu/dmmu/PhysicalAddress} -nworst 1 } + +# set filename [format "%s%s%s%s" $outputDir "/reports/priv_timing.rep"] +# redirect -append $filename { echo "\n\n\n//// Critical paths through priv/TrapM ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {priv/TrapM} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical paths through priv/CSRReadValM ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {priv/csr/CSRReadValM} -nworst 1 } +# redirect -append $filename { echo "\n\n\n//// Critical paths through priv/CSRReadValW ////\n\n\n" } +# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {priv/CSRReadValW} -nworst 1 } + +set filename [format "%s%s" $outputDir "/reports/area.rep"] +redirect $filename { report_area -hierarchy -nosplit -physical -designware} + +set filename [format "%s%s" $outputDir "/reports/cell.rep"] +#redirect $filename { report_cell [get_cells -hier *] } # not too useful + +set filename [format "%s%s" $outputDir "/reports/power.rep"] +redirect $filename { report_power -hierarchy -levels 1 } + +set filename [format "%s%s" $outputDir "/reports/constraint.rep"] +redirect $filename { report_constraint } + +set filename [format "%s%s" $outputDir "/reports/hier.rep"] +# redirect $filename { report_hierarchy } + +# end run clock and echo run time in minutes +set t2 [clock seconds] +set t [expr $t2 - $t1] +echo [expr $t/60] + +quit From 098111ea8506b12d73de4d18befd8d6a301ac080 Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Mon, 28 Aug 2023 09:43:04 -0700 Subject: [PATCH 2/9] makefile bug fix --- synthDC/Makefile | 3 +-- synthDC/scripts/wrapperGen.py | 2 +- synthDC/wrappers/wallypipelinedcorewrapper.sv | 24 ------------------- 3 files changed, 2 insertions(+), 27 deletions(-) delete mode 100644 synthDC/wrappers/wallypipelinedcorewrapper.sv diff --git a/synthDC/Makefile b/synthDC/Makefile index 58f54cb88..44b938d34 100755 --- a/synthDC/Makefile +++ b/synthDC/Makefile @@ -24,7 +24,6 @@ export USESRAM ?= 0 export WRAPPER ?= 0 ifeq ($(WRAPPER),1) - rm $(WALLY)/synthDC/wrappers/* NAME := synthWrapper else NAME := synth @@ -160,4 +159,4 @@ clean: rm -f power.saif rm -f Synopsys_stack_trace_*.txt rm -f crte_*.txt - rm $(WALLY)/synthDC/wrappers/* + rm $(WALLY)/synthDC/wrappers/* \ No newline at end of file diff --git a/synthDC/scripts/wrapperGen.py b/synthDC/scripts/wrapperGen.py index d406dd6d3..aacdb0634 100755 --- a/synthDC/scripts/wrapperGen.py +++ b/synthDC/scripts/wrapperGen.py @@ -63,7 +63,7 @@ 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')}/src/wrappers/*") +os.system(f"rm {os.getenv('WALLY')}/synthDC/wrappers/*") fout = open(wrapperPath, "w") diff --git a/synthDC/wrappers/wallypipelinedcorewrapper.sv b/synthDC/wrappers/wallypipelinedcorewrapper.sv deleted file mode 100644 index 9b44d7377..000000000 --- a/synthDC/wrappers/wallypipelinedcorewrapper.sv +++ /dev/null @@ -1,24 +0,0 @@ -import cvw::*; -`include "config.vh" -`include "parameter-defs.vh" -module wallypipelinedcorewrapper ( - input logic clk, reset, - // Privileged - input logic MTimerInt, MExtInt, SExtInt, MSwInt, - input logic [63:0] MTIME_CLINT, - // Bus Interface - input logic [P.AHBW-1:0] HRDATA, - input logic HREADY, HRESP, - output logic HCLK, HRESETn, - output logic [P.PA_BITS-1:0] HADDR, - output logic [P.AHBW-1:0] HWDATA, - output logic [P.XLEN/8-1:0] HWSTRB, - output logic HWRITE, - output logic [2:0] HSIZE, - output logic [2:0] HBURST, - output logic [3:0] HPROT, - output logic [1:0] HTRANS, - output logic HMASTLOCK -); - wallypipelinedcore #(P) dut(.*); -endmodule \ No newline at end of file From 53fc6e1ca7a69f90b4618518c6f9193ef1763c44 Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Tue, 29 Aug 2023 08:25:31 -0700 Subject: [PATCH 3/9] removed duplicate synth scripts --- synthDC/Makefile | 7 +------ synthDC/scripts/synth.tcl | 12 +++++++++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/synthDC/Makefile b/synthDC/Makefile index 44b938d34..57b478795 100755 --- a/synthDC/Makefile +++ b/synthDC/Makefile @@ -2,7 +2,7 @@ # Makefile for synthesis # Shreya Sanghai (ssanghai@hmc.edu) 2/28/2022 # Madeleine Masser-Frye (mmasserfrye@hmc.edu) 1/27/2023 - +NAME := synth # defaults export DESIGN ?= wallypipelinedcore export FREQ ?= 10000 @@ -23,11 +23,6 @@ export DRIVE ?= FLOP export USESRAM ?= 0 export WRAPPER ?= 0 -ifeq ($(WRAPPER),1) - NAME := synthWrapper -else - NAME := synth -endif time := $(shell date +%F-%H-%M) hash := $(shell git rev-parse --short HEAD) diff --git a/synthDC/scripts/synth.tcl b/synthDC/scripts/synth.tcl index 7de696da2..075bb5db9 100755 --- a/synthDC/scripts/synth.tcl +++ b/synthDC/scripts/synth.tcl @@ -16,6 +16,7 @@ suppress_message {VER-173} # Enable Multicore set_host_options -max_cores $::env(MAXCORES) + # get outputDir and configDir from environment (Makefile) set outputDir $::env(OUTPUTDIR) set cfg $::env(CONFIGDIR) @@ -23,12 +24,17 @@ 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 } { + 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/} @@ -42,7 +48,11 @@ if { $saifpower == 1 } { set my_verilog_files [glob $outputDir/hdl/cvw.sv $outputDir/hdl/*.sv] # Set toplevel -set my_toplevel $::env(DESIGN) +if { $wrapper == 1 } { + set my_toplevel $::env(DESIGN)wrapper +} else { + set my_toplevel $::env(DESIGN) +} # Set number of significant digits set report_default_significant_digits 6 From b45c8efad3476d2f21f4a0524d2f2da99bbc338e Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Tue, 29 Aug 2023 08:31:23 -0700 Subject: [PATCH 4/9] del old --- synthDC/scripts/synthWrapper.tcl | 407 ------------------------------- 1 file changed, 407 deletions(-) delete mode 100755 synthDC/scripts/synthWrapper.tcl diff --git a/synthDC/scripts/synthWrapper.tcl b/synthDC/scripts/synthWrapper.tcl deleted file mode 100755 index d15234692..000000000 --- a/synthDC/scripts/synthWrapper.tcl +++ /dev/null @@ -1,407 +0,0 @@ -# -# Synthesis Synopsys Flow -# james.stine@okstate.edu 27 Sep 2015 -# kekim@hmc.edu - -# start run clock -set t1 [clock seconds] - -# Ignore unnecessary warnings: -# intraassignment delays for nonblocking assignments are ignored -suppress_message {VER-130} -# statements in initial blocks are ignored -suppress_message {VER-281} -suppress_message {VER-173} - -# Enable Multicore -set_host_options -max_cores $::env(MAXCORES) - -# get outputDir and configDir from environment (Makefile) -set outputDir $::env(OUTPUTDIR) -set cfg $::env(CONFIGDIR) -set hdl_src "../src" -set saifpower $::env(SAIFPOWER) -set maxopt $::env(MAXOPT) -set drive $::env(DRIVE) - -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/} -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/} - -# Enables name mapping -if { $saifpower == 1 } { - saif_map -start -} - -# Verilog files -set my_verilog_files [glob $outputDir/hdl/cvw.sv $outputDir/hdl/*.sv] - -# Set toplevel -set my_toplevel $::env(DESIGN)wrapper - -# Set number of significant digits -set report_default_significant_digits 6 - -# V(HDL) Unconnectoed Pins Output -set verilogout_show_unconnected_pins "true" -set vhdlout_show_unconnected_pins "true" - -# Set up MW List -set MY_LIB_NAME $my_toplevel -# Create MW -if { [shell_is_in_topographical_mode] } { - echo "In Topographical Mode...processing\n" - create_mw_lib -technology $MW_REFERENCE_LIBRARY/$MW_TECH_FILE.tf \ - -mw_reference_library $mw_reference_library $outputDir/$MY_LIB_NAME - # Open MW - open_mw_lib $outputDir/$MY_LIB_NAME - - # TLU+ - set_tlu_plus_files -max_tluplus $MAX_TLU_FILE -min_tluplus $MIN_TLU_FILE \ - -tech2itf_map $PRS_MAP_FILE - -} else { - echo "In normal DC mode...processing\n" -} - -# Due to parameterized Verilog must use analyze/elaborate and not -# read_verilog/vhdl (change to pull in Verilog and/or VHDL) -# -#set alib_library_analysis_path ./$outputDir -define_design_lib WORK -path ./$outputDir/WORK -analyze -f sverilog -lib WORK $my_verilog_files -elaborate $my_toplevel -lib WORK - -# Set the current_design -current_design $my_toplevel -link - -# Reset all constraints -reset_design - -# Power Dissipation Analysis -######### OPTIONAL !!!!!!!!!!!!!!!! -if { $saifpower == 1 } { - read_saif -input power.saif -instance_name testbench/dut/core -auto_map_names -verbose -} - -# Set reset false path -if {$drive != "INV"} { - set_false_path -from [get_ports reset] -} -if {(($::env(DESIGN) == "ppa_mux2d_1") || ($::env(DESIGN) == "ppa_mux4d_1") || ($::env(DESIGN) == "ppa_mux8d_1"))} { - set_false_path -from {s} -} - -# Set Frequency in [MHz] or period in [ns] -set my_clock_pin clk -set my_uncertainty 0.0 -set my_clk_freq_MHz $::env(FREQ) -set my_period [expr 1000.0 / $my_clk_freq_MHz] - -# Create clock object -set find_clock [ find port [list $my_clock_pin] ] -if { $find_clock != [list] } { - echo "Found clock!" - set my_clk $my_clock_pin - create_clock -period $my_period $my_clk - set_clock_uncertainty $my_uncertainty [get_clocks $my_clk] -} else { - echo "Did not find clock! Design is probably combinational!" - set my_clk vclk - create_clock -period $my_period -name $my_clk -} - -# Optimize paths that are close to critical -set_critical_range 0.05 $current_design - -# Partitioning - flatten or hierarchically synthesize -if { $maxopt == 1 } { - ungroup -all -simple_names -flatten -} - -# Set input pins except clock -set all_in_ex_clk [remove_from_collection [all_inputs] [get_ports $my_clk]] - -# Specifies delays be propagated through the clock network -# This is getting optimized poorly in the current flow, causing a lot of clock skew -# and unrealistic bad timing results. -# set_propagated_clock [get_clocks $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 -} elseif {$tech == "sky90"} { - if {$drive == "INV"} { - 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 - } -} elseif {$tech == "tsmc28" || $tech=="tsmc28psyn"} { - if {$drive == "INV"} { - 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 input/output delay -if {$drive == "FLOP"} { - set_input_delay 0.0 -max -clock $my_clk $all_in_ex_clk - set_output_delay 0.0 -max -clock $my_clk [all_outputs] -} else { - set_input_delay 0.0 -max -clock $my_clk $all_in_ex_clk - set_output_delay 0.0 -max -clock $my_clk [all_outputs] -} - -# Setting load constraint on output ports -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] - } 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] - } elseif {$drive == "FLOP"} { - set_load [expr [load_of tcbn28hpcplusbwp30p140tt0p9v25c/DFQD1BWP30P140/D] * 1] [all_outputs] - } -} - -if {$tech != "tsmc28psyn"} { - # Set the wire load model - set_wire_load_mode "top" -} - -# Set switching activities -# default activity factors are 1 for clocks, 0.1 for others -# static probability of 0.5 is used for leakage - -# Attempt Area Recovery - if looking for minimal area -# set_max_area 2000 - -# Set fanout -set_max_fanout 6 $all_in_ex_clk - -# Fix hold time violations (DH: this doesn't seem to be working right now) -#set_fix_hold [all_clocks] - -# Deal with constants and buffers to isolate ports -set_fix_multiple_port_nets -all -buffer_constants - -# setting up the group paths to find out the required timings -# group_path -name OUTPUTS -to [all_outputs] -# group_path -name INPUTS -from [all_inputs] -# group_path -name COMBO -from [all_inputs] -to [all_outputs] - -# Save Unmapped Design -# set filename [format "%s%s%s%s" $outputDir "/unmapped/" $my_toplevel ".ddc"] -# write_file -format ddc -hierarchy -o $filename - -# Compile statements -if { $maxopt == 1 } { - compile_ultra -retime - optimize_registers -} else { - compile_ultra -no_seq_output_inversion -no_boundary_optimization -} - -# Eliminate need for assign statements (yuck!) -set verilogout_no_tri true -set verilogout_equation false - -# setting to generate output files -set write_v 1 ;# generates structual netlist -set write_sdc 1 ;# generates synopsys design constraint file for p&r -set write_ddc 1 ;# compiler file in ddc format -set write_sdf 1 ;# sdf file for backannotated timing sim -set write_pow 1 ;# genrates estimated power report -set write_rep 1 ;# generates estimated area and timing report -set write_cst 1 ;# generate report of constraints -set write_hier 1 ;# generate hierarchy report - -# Report Constraint Violators -set filename [format "%s%s" $outputDir "/reports/constraint_all_violators.rpt"] -redirect $filename {report_constraint -all_violators} - -# Check design -redirect $outputDir/reports/check_design.rpt { check_design } - -# Report Final Netlist (Hierarchical) -set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".sv"] -write_file -f verilog -hierarchy -output $filename - -set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".sdc"] -write_sdc $filename - -set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".ddc"] -write_file -format ddc -hierarchy -o $filename - -set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".sdf"] -write_sdf $filename - -# QoR -set filename [format "%s%s" $outputDir "/reports/qor.rep"] -redirect $filename { report_qor } - -# Report Timing -set filename [format "%s%s" $outputDir "/reports/reportpath.rep"] -#redirect $filename { report_path_group } - -set filename [format "%s%s" $outputDir "/reports/report_clock.rep"] -# redirect $filename { report_clock } - -set filename [format "%s%s" $outputDir "/reports/timing.rep"] -redirect $filename { report_timing -capacitance -transition_time -nets -nworst 1 } - -set filename [format "%s%s" $outputDir "/reports/mindelay.rep"] -redirect $filename { report_timing -capacitance -transition_time -nets -delay_type min -nworst 1 } - -set filename [format "%s%s" $outputDir "/reports/per_module_timing.rep"] -redirect -append $filename { echo "\n\n\n//// Critical paths through ifu ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ifu/*} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical paths through ieu ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/*} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical paths through lsu ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {lsu/*} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical paths through ebu (ahblite) ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ebu/*} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical paths through mdu ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/*} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical paths through hzu ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {hzu/*} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical paths through priv ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {priv/*} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical paths through fpu ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {fpu/*} -nworst 1 } - -set filename [format "%s%s" $outputDir "/reports/mdu_timing.rep"] -redirect -append $filename { echo "\n\n\n//// Critical paths through entire mdu ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/*} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical paths through multiply unit ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.mul/*} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical paths through redundant multiplier ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.mul/bigmul/*} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical path through ProdM (mul output) ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.ProdM} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical path through PP0E (mul partial product) ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.mul/PP0E} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical paths through divide unit ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.div/*} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical path through QuotM (div output) ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.QuotM} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical path through RemM (div output) ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.RemM} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical path through div/WNextE ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.div/WNextE} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical path through div/XQNextE ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.div/XQNextE} -nworst 1 } -redirect -append $filename { echo "\n\n\n//// Critical path through div/DAbsBE ////\n\n\n" } -redirect -append $filename { report_timing -capacitance -transition_time -nets -through {mdu/genblk1.div/DAbsBE} -nworst 1 } - -# set filename [format "%s%s%s%s" $outputDir "/reports/fpu_timing.rep"] -# redirect $filename { echo "\n\n\n//// Critical paths through fma ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {fpu/fpu.fma/*} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical paths through fpdiv ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {fpu/fpu.fdivsqrt/*} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical paths through faddcvt ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {fpu/fpu.faddcvt/*} -nworst 1 } - -# set filename [format "%s%s%s%s" $outputDir "/reports/ifu_timing.rep"] -# redirect -append $filename { echo "\n\n\n//// Critical path through PCF ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ifu/PCF} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical path through PCNextF ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ifu/PCNextF} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical path through FinalInstrRawF ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ifu/FinalInstrRawF} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical path through InstrD ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ifu/decomp/InstrD} -nworst 1 } - -# set filename [format "%s%s%s%s" $outputDir "/reports/stall_flush_timing.rep"] -# redirect -append $filename { echo "\n\n\n//// Critical path through StallD ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/StallD} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical path through StallE ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/StallE} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical path through StallM ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/StallM} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical path through StallW ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/StallW} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical path through FlushD ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/FlushD} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical path through FlushE ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/FlushE} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical path through FlushM ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/FlushM} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical path through FlushW ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/FlushW} -nworst 1 } - -# set filename [format "%s%s%s%s" $outputDir "/reports/ieu_timing.rep"] -# redirect -append $filename { echo "\n\n\n//// Critical path through datapath/R1D ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/R1D} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical path through datapath/R2D ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/R2D} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical path through datapath/SrcAE ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/SrcAE} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical path through datapath/ALUResultE ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/ALUResultE} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical path through datapath/WriteDataW ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/WriteDataW} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical path through datapath/ReadDataM ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/ReadDataM} -nworst 1 } - -# set filename [format "%s%s%s%s" $outputDir "/reports/fpu_timing.rep"] -# redirect -append $filename { echo "\n\n\n//// Critical paths through fma ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {fma/*} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical paths through fma1 ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {fma/fma1/*} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical paths through fma2 ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {postprocess/*} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical paths through fpdiv ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {divsqrt/*} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical paths through fcvt ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {fcvt/*} -nworst 1 } - -# set filename [format "%s%s%s%s" $outputDir "/reports/mmu_timing.rep"] -# redirect -append $filename { echo "\n\n\n//// Critical paths through immu/physicaladdress ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ifu/immu/PhysicalAddress} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical paths through dmmu/physicaladdress ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {lsu/dmmu/PhysicalAddress} -nworst 1 } - -# set filename [format "%s%s%s%s" $outputDir "/reports/priv_timing.rep"] -# redirect -append $filename { echo "\n\n\n//// Critical paths through priv/TrapM ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {priv/TrapM} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical paths through priv/CSRReadValM ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {priv/csr/CSRReadValM} -nworst 1 } -# redirect -append $filename { echo "\n\n\n//// Critical paths through priv/CSRReadValW ////\n\n\n" } -# redirect -append $filename { report_timing -capacitance -transition_time -nets -through {priv/CSRReadValW} -nworst 1 } - -set filename [format "%s%s" $outputDir "/reports/area.rep"] -redirect $filename { report_area -hierarchy -nosplit -physical -designware} - -set filename [format "%s%s" $outputDir "/reports/cell.rep"] -#redirect $filename { report_cell [get_cells -hier *] } # not too useful - -set filename [format "%s%s" $outputDir "/reports/power.rep"] -redirect $filename { report_power -hierarchy -levels 1 } - -set filename [format "%s%s" $outputDir "/reports/constraint.rep"] -redirect $filename { report_constraint } - -set filename [format "%s%s" $outputDir "/reports/hier.rep"] -# redirect $filename { report_hierarchy } - -# end run clock and echo run time in minutes -set t2 [clock seconds] -set t [expr $t2 - $t1] -echo [expr $t/60] - -quit From 91429f3f0273dbb9e6e3514e575d03fb2ea55788 Mon Sep 17 00:00:00 2001 From: David Harris Date: Tue, 29 Aug 2023 12:39:24 -0700 Subject: [PATCH 5/9] Initial TLB NAPOT tests --- testbench/tests.vh | 1 + tests/coverage/tlbNAPOT.S | 184 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 tests/coverage/tlbNAPOT.S diff --git a/testbench/tests.vh b/testbench/tests.vh index 3229a6de7..8ba4ce8d1 100644 --- a/testbench/tests.vh +++ b/testbench/tests.vh @@ -44,6 +44,7 @@ string tvpaths[] = '{ string coverage64gc[] = '{ `COVERAGE, + "tlbNAPOT", "priv", "ieu", "ebu", diff --git a/tests/coverage/tlbNAPOT.S b/tests/coverage/tlbNAPOT.S new file mode 100644 index 000000000..e136f864a --- /dev/null +++ b/tests/coverage/tlbNAPOT.S @@ -0,0 +1,184 @@ +/////////////////////////////////////////// +// tlbNAPOT.S +// +// Written: mmendozamanriquez@hmc.edu 4 April 2023 +// nlimpert@hmc.edu +// Adapted David_Harris@hmc.edu 8/29/23 to exercise NAPOT huge pages +// +// Purpose: Test coverage for LSU NAPOT +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +// load code to initalize stack, handle interrupts, terminate + +#include "WALLY-init-lib.h" + +# run-elf.bash find this in project description +main: + # Page table root address at 0x80010000; SV48 + li t5, 0x9000000000080010 + csrw satp, t5 + + # sfence.vma x0, x0 + + # switch to supervisor mode + li a0, 1 + ecall + + li t0, 0x80215240 + + li t2, 0 # i = 0 + li t3, 33 # Max amount of Loops = 32 + li t4, 0x200000 + li t5, 0x8082 # return instruction opcode + +loop: bge t2, t3, finished # exit loop if i >= loops + sw t5, 0(t0) # store a return at this address to exercise DTLB + lw t1, 0(t0) # read it back + fence.i # synchronize with I$ + jalr ra, t0 # jump to the return statement to exercise the ITLB + add t0, t0, t4 + addi t2, t2, 1 + j loop + +finished: + j done + +.data + +.align 16 +# root Page table situated at 0x80010000 +pagetable: + .8byte 0x200044C1 // old page table was 200040 which just pointed to itself! wrong + +# next page table at 0x80011000 +.align 12 + .8byte 0x0000000000000000 + .8byte 0x00000000200048C1 + .8byte 0x00000000200048C1 + + +# Next page table at 0x80012000 +.align 12 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + +# Leaf page table at 0x80013000 +.align 12 + #80000000 + .8byte 0x80000000200020CF + .8byte 0x80000000200020CF + .8byte 0x80000000200020CF + .8byte 0x80000000200020CF + + .8byte 0x80000000200020CF + .8byte 0x80000000200020CF + .8byte 0x80000000200020CF + .8byte 0x80000000200020CF + + .8byte 0x80000000200020CF + .8byte 0x80000000200020CF + .8byte 0x80000000200020CF + .8byte 0x80000000200020CF + + .8byte 0x80000000200020CF + .8byte 0x80000000200020CF + .8byte 0x80000000200020CF + .8byte 0x80000000200020CF + + .8byte 0x80000000200060CF + .8byte 0x80000000200060CF + .8byte 0x80000000200060CF + .8byte 0x80000000200060CF + + .8byte 0x80000000200060CF + .8byte 0x80000000200060CF + .8byte 0x80000000200060CF + .8byte 0x80000000200060CF + + .8byte 0x80000000200060CF + .8byte 0x80000000200060CF + .8byte 0x80000000200060CF + .8byte 0x80000000200060CF + + .8byte 0x80000000200060CF + .8byte 0x80000000200060CF + .8byte 0x80000000200060CF + .8byte 0x80000000200060CF + + .8byte 0x800000002000A0CF + .8byte 0x800000002000A0CF + .8byte 0x800000002000A0CF + .8byte 0x800000002000A0CF + + .8byte 0x800000002000A0CF + .8byte 0x800000002000A0CF + .8byte 0x800000002000A0CF + .8byte 0x800000002000A0CF + + .8byte 0x800000002000A0CF + .8byte 0x800000002000A0CF + .8byte 0x800000002000A0CF + .8byte 0x800000002000A0CF + + .8byte 0x800000002000A0CF + .8byte 0x800000002000A0CF + .8byte 0x800000002000A0CF + .8byte 0x800000002000A0CF + + .8byte 0x800000002000E0CF + .8byte 0x800000002000E0CF + .8byte 0x800000002000E0CF + .8byte 0x800000002000E0CF + + .8byte 0x800000002000E0CF + .8byte 0x800000002000E0CF From 1642ad2badd6cc8fb109870b74b4c62149e2b436 Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 30 Aug 2023 21:04:36 -0700 Subject: [PATCH 6/9] Improved NAPOT test coverage --- sim/wave.do | 6 + tests/coverage/WALLY-init-lib.h | 3 + tests/coverage/tlbNAPOT.S | 201 +++++++++++++++++++++++++++++++- 3 files changed, 204 insertions(+), 6 deletions(-) diff --git a/sim/wave.do b/sim/wave.do index 6fd560251..047a0b163 100644 --- a/sim/wave.do +++ b/sim/wave.do @@ -65,14 +65,20 @@ add wave -noupdate -group {Execution Stage} /testbench/dut/core/ifu/PCE add wave -noupdate -group {Execution Stage} /testbench/dut/core/ifu/InstrE add wave -noupdate -group {Execution Stage} /testbench/InstrEName add wave -noupdate -group {Execution Stage} /testbench/dut/core/ieu/c/InstrValidE +add wave -noupdate -group {Execution Stage} /testbench/dut/core/ieu/dp/SrcAE +add wave -noupdate -group {Execution Stage} /testbench/dut/core/ieu/dp/SrcBE +add wave -noupdate -group {Execution Stage} /testbench/dut/core/ieu/dp/ALUResultE add wave -noupdate -expand -group {Memory Stage} /testbench/FunctionName/FunctionName/FunctionName add wave -noupdate -expand -group {Memory Stage} /testbench/dut/core/InstrValidM add wave -noupdate -expand -group {Memory Stage} /testbench/dut/core/PCM add wave -noupdate -expand -group {Memory Stage} /testbench/dut/core/InstrM add wave -noupdate -expand -group {Memory Stage} /testbench/InstrMName add wave -noupdate -expand -group {Memory Stage} /testbench/dut/core/lsu/IEUAdrM +add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/ReadDataM +add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/WriteDataM add wave -noupdate -group {WriteBack stage} /testbench/InstrW add wave -noupdate -group {WriteBack stage} /testbench/InstrWName +add wave -noupdate -group {Execution Stage} /testbench/dut/core/ieu/dp/ResultW add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/csrm/MCAUSE_REGW add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/MCOUNTEREN_REGW add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/MCOUNTINHIBIT_REGW diff --git a/tests/coverage/WALLY-init-lib.h b/tests/coverage/WALLY-init-lib.h index b0f5a9654..55bfcf4e5 100644 --- a/tests/coverage/WALLY-init-lib.h +++ b/tests/coverage/WALLY-init-lib.h @@ -92,7 +92,10 @@ changeprivilege: trap_return: # return from trap handler csrr t0, mepc # get address of instruction that caused exception + li t1, 0x20000 + csrs mstatus, t1 # set mprv bit to fetch instruction with permission of code that trapped lh t0, 0(t0) # get instruction that caused exception + csrc mstatus, t1 # clear mprv bit to restore normal operation li t1, 3 and t0, t0, t1 # mask off upper bits beq t0, t1, instr32 # if lower 2 bits are 11, instruction is uncompresssed diff --git a/tests/coverage/tlbNAPOT.S b/tests/coverage/tlbNAPOT.S index e136f864a..f827d503b 100644 --- a/tests/coverage/tlbNAPOT.S +++ b/tests/coverage/tlbNAPOT.S @@ -41,8 +41,21 @@ main: li a0, 1 ecall - li t0, 0x80215240 + li t0, 0x80215240 # Test NAPOT pages + jal a1, looptest + li t0, 0x80215240 # Test NAPOT pages + jal a1, looptest + li t0, 0xC0215240 # Test ill-formed NAPOT pages + jal a1, looptest + li t0, 0xC0215240 # Test ill-formed NAPOT pages + jal a1, looptest + li t0, 0x40215240 # Test properly formed pages with 1 in PPN[3] that are not NAPOT + jal a1, looptest + li t0, 0x40215240 # Test properly formed pages with 1 in PPN[3] that are not NAPOT + jal a1, looptest + j done +looptest: li t2, 0 # i = 0 li t3, 33 # Max amount of Loops = 32 li t4, 0x200000 @@ -58,7 +71,7 @@ loop: bge t2, t3, finished # exit loop if i >= loops j loop finished: - j done + jr a1 .data @@ -69,9 +82,10 @@ pagetable: # next page table at 0x80011000 .align 12 - .8byte 0x0000000000000000 - .8byte 0x00000000200048C1 - .8byte 0x00000000200048C1 + .8byte 0x0000000000000000 # gigapage at 0x00000000 + .8byte 0x00000000200058C1 # gigapage at 0x40000000 used for non-NAPOT with PPN bit 3 set + .8byte 0x00000000200048C1 # gigapage at 0x80000000 used for testing NAPOT huge pages + .8byte 0x00000000200050C1 # gigapage at 0xC0000000 mapped to ill-formed NAPOT with wrong PPN # Next page table at 0x80012000 @@ -112,7 +126,7 @@ pagetable: .8byte 0x0000000020004CC1 .8byte 0x0000000020004CC1 -# Leaf page table at 0x80013000 +# Leaf page table at 0x80013000 with NAPOT pages .align 12 #80000000 .8byte 0x80000000200020CF @@ -182,3 +196,178 @@ pagetable: .8byte 0x800000002000E0CF .8byte 0x800000002000E0CF + +# Next page table at 0x80014000: mega-sized, pointing to malformed NAPOT +.align 12 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + +# Leaf page table at 0x80015000 with malformed NAPOT pages (wrong PPN) starting at 0xC0000000 +.align 12 + #80000000 + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + .8byte 0x80000000200000CF + + +# Next page table at 0x80016000: mega-sized, pointing to properly formed PTE with 1 in PPN bit 3 +.align 12 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + +# Leaf page table at 0x80017000 with properly formed PTE with bit 4 of PPN set but no NAPOT +.align 12 + #80000000 + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + .8byte 0x00000000200020CF + + \ No newline at end of file From e75ceb044fdb6b670a2395522168df63fcbfcdc1 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 31 Aug 2023 00:27:47 -0700 Subject: [PATCH 7/9] Improved tlb and controller coverage; fixed exclusions on broken lines --- src/cache/cachefsm.sv | 3 +- src/ieu/controller.sv | 1 - src/mmu/pmachecker.sv | 4 +-- tests/coverage/Makefile | 2 +- tests/coverage/ieu.S | 35 ++++++++++++++++++ tests/coverage/tlbNAPOT.S | 76 ++++++++++++++++++++++----------------- 6 files changed, 82 insertions(+), 39 deletions(-) diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index 124b92678..770579b67 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -106,8 +106,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P, assign FlushFlag = FlushAdrFlag & FlushWayFlag; // outputs for the performance counters. - assign CacheAccess = (|CacheRW) & ((CurrState == STATE_READY & ~Stall & ~FlushStage) | - (CurrState == STATE_READ_HOLD & ~Stall & ~FlushStage)); // exclusion-tag: icache CacheW + assign CacheAccess = (|CacheRW) & ((CurrState == STATE_READY & ~Stall & ~FlushStage) | (CurrState == STATE_READ_HOLD & ~Stall & ~FlushStage)); // exclusion-tag: icache CacheW assign CacheMiss = CacheAccess & ~CacheHit; // special case on reset. When the fsm first exists reset the diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index e923f1e3f..32fdba23e 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -182,7 +182,6 @@ module controller import cvw::*; #(parameter cvw_t P) ( ((P.ZICBOZ_SUPPORTED & InstrD[31:20] == 12'd4 & ENVCFG_CBE[3]) | (P.ZICBOM_SUPPORTED & ((InstrD[31:20] == 12'd0 & (ENVCFG_CBE[1:0] != 2'b00))) | (InstrD[31:20] == 12'd1 | InstrD[31:20] == 12'd2) & ENVCFG_CBE[2])); - // *** need to get with enable bits such as MENVCFG_CBZE assign AFunctD = (Funct3D == 3'b010) | (P.XLEN == 64 & Funct3D == 3'b011); assign AMOFunctD = (InstrD[31:27] == 5'b00001) | (InstrD[31:27] == 5'b00000) | diff --git a/src/mmu/pmachecker.sv b/src/mmu/pmachecker.sv index ce129af51..587f54dbd 100644 --- a/src/mmu/pmachecker.sv +++ b/src/mmu/pmachecker.sv @@ -57,8 +57,8 @@ module pmachecker import cvw::*; #(parameter cvw_t P) ( adrdecs #(P) adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWX, Size, SelRegions); // Only non-core RAM/ROM memory regions are cacheable. PBMT can override cachable; NC and IO are uncachable - assign CacheableRegion = SelRegions[8] | SelRegions[7] | SelRegions[6]; - assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 0; // exclusion-tag: unused-cachable + assign CacheableRegion = SelRegions[8] | SelRegions[7] | SelRegions[6]; // exclusion-tag: unused-cachable + assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 0; // Nonidemdempotent means access could have side effect and must not be done speculatively or redundantly // I/O is nonidempotent. PBMT can override PMA; NC is idempotent and IO is non-idempotent diff --git a/tests/coverage/Makefile b/tests/coverage/Makefile index b2a2544d3..2f6002efc 100644 --- a/tests/coverage/Makefile +++ b/tests/coverage/Makefile @@ -17,7 +17,7 @@ all: $(OBJECTS) # Change many things if bit width isn't 64 %.elf: $(SRCDIR)/%.$(SEXT) WALLY-init-lib.h Makefile - riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zba_zbb_zbc_zbs_zfh -mabi=lp64 -mcmodel=medany \ + riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zba_zbb_zbc_zbs_zfh_zicboz_zicbop_zicbom -mabi=lp64 -mcmodel=medany \ -nostartfiles -T../../examples/link/link.ld $< riscv64-unknown-elf-objdump -S $@ > $@.objdump riscv64-unknown-elf-elf2hex --bit-width 64 --input $@ --output $@.memfile diff --git a/tests/coverage/ieu.S b/tests/coverage/ieu.S index cb0dae877..1e32a24ab 100644 --- a/tests/coverage/ieu.S +++ b/tests/coverage/ieu.S @@ -47,6 +47,13 @@ main: sc.w t0, a1, 0(a0) addi t0, t0, 1 + # test prefetch Hints (ori with destination x0) + ori x0, x0, 0 + ori x0, x0, 1 + ori x0, x0, 2 + ori x0, x0, 3 + + # Test illegal instructions are detected .word 0x80000033 // illegal R-type instruction .word 0x00007003 // illegal Load instruction @@ -66,6 +73,34 @@ main: .word 0x60F0101B // Illegal BMU similar to count word .word 0x6080101B // Illegal BMU similar to count word .word 0x6030101B // Illegal BMU similar to count word + .word 0x0000202F // Illegal similar to LR + .word 0x1010202F // Illegal similar to LR + .word 0x00402003 // illegal similar to CMO + .word 0x00202003 // illegal similar to CMO + .word 0xFF00302F // illegal Atomic instruction + .word 0xFF00402F // illegal Atomic instruction + .word 0x00000873 // illegal CSR instruction + + # Illegal CMO instructions because envcfg is 0 and system is in user Mode + li a0, 0 + ecall # switch to user mode + cbo.inval (x1) + cbo.clean (x1) + cbo.flush (x1) + cbo.zero (x1) + + li a0, 3 + ecall # switch back to machine mode + li x1, 0x50 + csrw menvcfg, x1 + csrw senvcfg, x1 + li a0, 0 + ecall # swtich to user mode + cbo.inval (x2) + cbo.clean (x3) + cbo.flush (x1) + + j done diff --git a/tests/coverage/tlbNAPOT.S b/tests/coverage/tlbNAPOT.S index f827d503b..282420be9 100644 --- a/tests/coverage/tlbNAPOT.S +++ b/tests/coverage/tlbNAPOT.S @@ -41,6 +41,7 @@ main: li a0, 1 ecall + li t4, 0x200000 # address step size li t0, 0x80215240 # Test NAPOT pages jal a1, looptest li t0, 0x80215240 # Test NAPOT pages @@ -53,12 +54,14 @@ main: jal a1, looptest li t0, 0x40215240 # Test properly formed pages with 1 in PPN[3] that are not NAPOT jal a1, looptest + li t4, 0x1000 # address step size + li t0, 0x80216000 # Test NAPOT pages + jal a1, looptest j done looptest: li t2, 0 # i = 0 - li t3, 33 # Max amount of Loops = 32 - li t4, 0x200000 + li t3, 35 # Max amount of Loops = 34 li t5, 0x8082 # return instruction opcode loop: bge t2, t3, finished # exit loop if i >= loops @@ -88,7 +91,7 @@ pagetable: .8byte 0x00000000200050C1 # gigapage at 0xC0000000 mapped to ill-formed NAPOT with wrong PPN -# Next page table at 0x80012000 +# Next page table at 0x80012000 for gigapage at 0x80000000 .align 12 .8byte 0x0000000020004CC1 .8byte 0x0000000020004CC1 @@ -125,6 +128,9 @@ pagetable: .8byte 0x0000000020004CC1 .8byte 0x0000000020004CC1 .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 + .8byte 0x0000000020004CC1 # Leaf page table at 0x80013000 with NAPOT pages .align 12 @@ -197,7 +203,7 @@ pagetable: .8byte 0x800000002000E0CF .8byte 0x800000002000E0CF -# Next page table at 0x80014000: mega-sized, pointing to malformed NAPOT +# Next page table at 0x80014000: mega-sized, pointing to malformed NAPOT for gigapage at 0xC9000000 .align 12 .8byte 0x00000000200054C1 .8byte 0x00000000200054C1 @@ -234,6 +240,9 @@ pagetable: .8byte 0x00000000200054C1 .8byte 0x00000000200054C1 .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 + .8byte 0x00000000200054C1 # Leaf page table at 0x80015000 with malformed NAPOT pages (wrong PPN) starting at 0xC0000000 .align 12 @@ -284,7 +293,7 @@ pagetable: .8byte 0x80000000200000CF -# Next page table at 0x80016000: mega-sized, pointing to properly formed PTE with 1 in PPN bit 3 +# Next page table at 0x80016000: mega-sized, pointing to properly formed PTE with 1 in PPN bit 3 for gigapage at 0x40000000 .align 12 .8byte 0x0000000020005CC1 .8byte 0x0000000020005CC1 @@ -321,53 +330,54 @@ pagetable: .8byte 0x0000000020005CC1 .8byte 0x0000000020005CC1 .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 + .8byte 0x0000000020005CC1 # Leaf page table at 0x80017000 with properly formed PTE with bit 4 of PPN set but no NAPOT .align 12 #80000000 .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF - .8byte 0x00000000200020CF + .8byte 0x00000000200060CF + .8byte 0x000000002000A0CF + .8byte 0x000000002000E0CF - \ No newline at end of file From 6c789426852577d0cea41cf42f436c9827f5fc4c Mon Sep 17 00:00:00 2001 From: Limnanthes Serafini Date: Fri, 1 Sep 2023 23:31:02 -0700 Subject: [PATCH 8/9] Properly gate LRUWriteEn with ~FlushStage --- src/cache/cachefsm.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cache/cachefsm.sv b/src/cache/cachefsm.sv index 124b92678..54715e3fe 100644 --- a/src/cache/cachefsm.sv +++ b/src/cache/cachefsm.sv @@ -172,9 +172,9 @@ module cachefsm import cvw::*; #(parameter cvw_t P, assign ClearValid = P.ZICBOM_SUPPORTED & ((CurrState == STATE_READY & CMOp[0] & CacheHit) | (CurrState == STATE_CMO_WRITEBACK & CMOp[2] & CacheBusAck)); // coverage off -item e 1 -fecexprrow 8 - assign LRUWriteEn = (CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) | + assign LRUWriteEn = ((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) | (P.ZICBOZ_SUPPORTED & CurrState == STATE_WRITEBACK & CMOp[3] & CacheBusAck) | - (CurrState == STATE_WRITE_LINE) & ~FlushStage; + (CurrState == STATE_WRITE_LINE)) & ~FlushStage; // exclusion-tag-start: icache flushdirtycontrols assign SetDirty = (CurrState == STATE_READY & (AnyUpdateHit | CMOZeroNoEviction)) | // exclusion-tag: icache SetDirty (CurrState == STATE_WRITE_LINE & (CacheRW[0])) | From 9747d122d2e056a8639902e4a0e3061e618f3caf Mon Sep 17 00:00:00 2001 From: David Harris Date: Sat, 2 Sep 2023 12:56:36 -0700 Subject: [PATCH 9/9] tlbNAPOT hangs due to PBMT making instruction memory uncacheable, and spill logic not working there. Fixed TLBLRU to update recently used on TLBHit rather than CAMHit. Moved coverage exclusions to proper line in pmachecker --- sim/coverage | 2 ++ src/mmu/pmachecker.sv | 4 +-- src/mmu/tlb/tlb.sv | 2 +- src/mmu/tlb/tlblru.sv | 4 +-- tests/coverage/tlbNAPOT.S | 68 ++++++++++++++++++++++----------------- 5 files changed, 46 insertions(+), 34 deletions(-) create mode 100755 sim/coverage diff --git a/sim/coverage b/sim/coverage new file mode 100755 index 000000000..038253911 --- /dev/null +++ b/sim/coverage @@ -0,0 +1,2 @@ +# recompile coverage tests and run coverage including them +pushd $WALLY/tests/coverage; make; popd; ./regression-wally -coverage diff --git a/src/mmu/pmachecker.sv b/src/mmu/pmachecker.sv index 587f54dbd..119e88d8c 100644 --- a/src/mmu/pmachecker.sv +++ b/src/mmu/pmachecker.sv @@ -62,8 +62,8 @@ module pmachecker import cvw::*; #(parameter cvw_t P) ( // Nonidemdempotent means access could have side effect and must not be done speculatively or redundantly // I/O is nonidempotent. PBMT can override PMA; NC is idempotent and IO is non-idempotent - assign IdempotentRegion = SelRegions[10] | SelRegions[9] | SelRegions[8] | SelRegions[7] | SelRegions[6]; - assign Idempotent = (PBMemoryType == 2'b00) ? IdempotentRegion : (PBMemoryType == 2'b01); // exclusion-tag: unused-idempotent + assign IdempotentRegion = SelRegions[10] | SelRegions[9] | SelRegions[8] | SelRegions[7] | SelRegions[6]; // exclusion-tag: unused-idempotent + assign Idempotent = (PBMemoryType == 2'b00) ? IdempotentRegion : (PBMemoryType == 2'b01); // Atomic operations are only allowed on RAM assign AtomicAllowed = SelRegions[10] | SelRegions[8] | SelRegions[6]; // exclusion-tag: unused-atomic diff --git a/src/mmu/tlb/tlb.sv b/src/mmu/tlb/tlb.sv index 8910f7d53..9619c958d 100644 --- a/src/mmu/tlb/tlb.sv +++ b/src/mmu/tlb/tlb.sv @@ -110,7 +110,7 @@ module tlb import cvw::*; #(parameter cvw_t P, .TLBMiss, .TLBHit, .TLBPageFault, .UpdateDA, .SV39Mode, .Translate, .PTE_N, .PBMemoryType); - tlblru #(TLB_ENTRIES) lru(.clk, .reset, .TLBWrite, .TLBFlush, .Matches, .CAMHit, .WriteEnables); + tlblru #(TLB_ENTRIES) lru(.clk, .reset, .TLBWrite, .TLBFlush, .Matches, .TLBHit, .WriteEnables); tlbcam #(P, TLB_ENTRIES, P.VPN_BITS + P.ASID_BITS, P.VPN_SEGMENT_BITS) tlbcam(.clk, .reset, .VPN, .PageTypeWriteVal, .SV39Mode, .TLBFlush, .WriteEnables, .PTE_Gs, .PTE_NAPOTs, .SATP_ASID, .Matches, .HitPageType, .CAMHit); diff --git a/src/mmu/tlb/tlblru.sv b/src/mmu/tlb/tlblru.sv index 4cabb33ab..18014155a 100644 --- a/src/mmu/tlb/tlblru.sv +++ b/src/mmu/tlb/tlblru.sv @@ -32,7 +32,7 @@ module tlblru #(parameter TLB_ENTRIES = 8) ( input logic TLBWrite, input logic TLBFlush, input logic [TLB_ENTRIES-1:0] Matches, - input logic CAMHit, + input logic TLBHit, output logic [TLB_ENTRIES-1:0] WriteEnables ); @@ -50,5 +50,5 @@ module tlblru #(parameter TLB_ENTRIES = 8) ( assign RUBitsAccessed = AccessLines | RUBits; assign AllUsed = &RUBitsAccessed; // if all recently used, then clear to none assign RUBitsNext = AllUsed ? 0 : RUBitsAccessed; - flopenr #(TLB_ENTRIES) lrustate(clk, reset, (CAMHit | TLBWrite), RUBitsNext, RUBits); + flopenr #(TLB_ENTRIES) lrustate(clk, reset, (TLBHit | TLBWrite), RUBitsNext, RUBits); endmodule diff --git a/tests/coverage/tlbNAPOT.S b/tests/coverage/tlbNAPOT.S index 282420be9..09dc2abcd 100644 --- a/tests/coverage/tlbNAPOT.S +++ b/tests/coverage/tlbNAPOT.S @@ -31,6 +31,9 @@ # run-elf.bash find this in project description main: + li t5, 0x1 + slli t5, t5, 62 + csrs menvcfg, t5 # Page table root address at 0x80010000; SV48 li t5, 0x9000000000080010 csrw satp, t5 @@ -42,29 +45,24 @@ main: ecall li t4, 0x200000 # address step size - li t0, 0x80215240 # Test NAPOT pages + li a2, 0x80215240 # Test NAPOT pages jal a1, looptest - li t0, 0x80215240 # Test NAPOT pages + li a2, 0xC0215240 # Test ill-formed NAPOT pages jal a1, looptest - li t0, 0xC0215240 # Test ill-formed NAPOT pages - jal a1, looptest - li t0, 0xC0215240 # Test ill-formed NAPOT pages - jal a1, looptest - li t0, 0x40215240 # Test properly formed pages with 1 in PPN[3] that are not NAPOT - jal a1, looptest - li t0, 0x40215240 # Test properly formed pages with 1 in PPN[3] that are not NAPOT - jal a1, looptest - li t4, 0x1000 # address step size - li t0, 0x80216000 # Test NAPOT pages + li a2, 0x40215240 # Test properly formed pages with 1 in PPN[3] that are not NAPOT jal a1, looptest +# li t4, 0x1000 # address step size +# li a2, 0x80216000 # Test NAPOT pages +# jal a1, looptest j done looptest: + mv t0, a2 # base address li t2, 0 # i = 0 li t3, 35 # Max amount of Loops = 34 li t5, 0x8082 # return instruction opcode -loop: bge t2, t3, finished # exit loop if i >= loops +loop: bge t2, t3, looptesti # exit loop if i >= loops sw t5, 0(t0) # store a return at this address to exercise DTLB lw t1, 0(t0) # read it back fence.i # synchronize with I$ @@ -73,6 +71,18 @@ loop: bge t2, t3, finished # exit loop if i >= loops addi t2, t2, 1 j loop +looptesti: + mv t0, a2 # base address + li t2, 0 # i = 0 + fence.i # synchronize with I$ + +# Exercise itlb by jumping to each of the return statements +loopi: bge t2, t3, finished # exit loop if i >= loops + jalr ra, t0 # jump to the return statement to exercise the ITLB + add t0, t0, t4 + addi t2, t2, 1 + j loopi + finished: jr a1 @@ -135,25 +145,25 @@ pagetable: # Leaf page table at 0x80013000 with NAPOT pages .align 12 #80000000 - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF - .8byte 0x80000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF + .8byte 0xA0000000200020CF .8byte 0x80000000200060CF .8byte 0x80000000200060CF