mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' into spi
This commit is contained in:
commit
3570468ef5
2
.gitignore
vendored
2
.gitignore
vendored
@ -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
|
||||
@ -82,6 +83,7 @@ synthDC/ppa/plots
|
||||
synthDC/wallyplots/
|
||||
synthDC/runArchive
|
||||
synthDC/hdl
|
||||
synthDC/wrappers
|
||||
sim/power.saif
|
||||
tests/fp/vectors/*.tv
|
||||
synthDC/Summary.csv
|
||||
|
57
bin/CModelBTBAccuracy.sh
Executable file
57
bin/CModelBTBAccuracy.sh
Executable file
@ -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
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -123,6 +123,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,
|
||||
|
11
examples/asm/etc/Makefile
Normal file
11
examples/asm/etc/Makefile
Normal file
@ -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
|
25
examples/asm/etc/pause.S
Normal file
25
examples/asm/etc/pause.S
Normal file
@ -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
|
117
sim/bpred-sim.py
117
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 <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
||||
# grepstr="")
|
||||
# configs.append(tc)
|
||||
|
||||
# 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"
|
||||
# tc = TestCase(
|
||||
# name=name,
|
||||
# variant="rv32gc",
|
||||
# cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
||||
# grepstr="")
|
||||
# configs.append(tc)
|
||||
|
||||
bpdSize = [2, 3, 4, 6, 10, 16]
|
||||
for CurrBPSize in bpdSize:
|
||||
name = 'RAS'+str(CurrBPSize)
|
||||
configOptions = "+define+INSTR_CLASS_PRED=0 +define+BPRED_OVERRIDE +define+BPRED_TYPE=\`BP_GSHARE" + "+define+BPRED_SIZE=16" + "+define+BTB_SIZE=16" + "+define+RAS_SIZE=" + str(CurrBPSize) + "+define+BTB_OVERRIDE+define+RAS_OVERRIDE"
|
||||
tc = TestCase(
|
||||
name=name,
|
||||
variant="rv32gc",
|
||||
cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
||||
grepstr="")
|
||||
configs.append(tc)
|
||||
|
||||
# bpdSize = [6, 8, 10, 12, 14, 16]
|
||||
# LHRSize = [4, 8, 10]
|
||||
# bpdType = ['local_repair']
|
||||
# for CurrBPType in bpdType:
|
||||
# for CurrBPSize in bpdSize:
|
||||
# for CurrLHRSize in LHRSize:
|
||||
# name = str(CurrLHRSize)+CurrBPType+str(CurrBPSize)
|
||||
# configOptions = "+define+INSTR_CLASS_PRED=0 +define+BPRED_TYPE=\"BP_" + CurrBPType.upper() + "\" +define+BPRED_SIZE=" + str(CurrBPSize) + " +define+BPRED_NUM_LHR=" + str(CurrLHRSize) + " "
|
||||
# tc = TestCase(
|
||||
# name=name,
|
||||
# variant="rv32gc",
|
||||
# cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
||||
# grepstr="")
|
||||
# configs.append(tc)
|
||||
|
||||
import os
|
||||
from multiprocessing import Pool, TimeoutError
|
||||
@ -138,9 +90,70 @@ def main():
|
||||
finally:
|
||||
os.mkdir("wkdir")
|
||||
|
||||
if '-makeTests' in sys.argv:
|
||||
os.chdir(regressionDir)
|
||||
os.system('./make-tests.sh | tee ./logs/make-tests.log')
|
||||
parser = argparse.ArgumentParser(description='Runs embench with sweeps of branch predictor sizes and types.')
|
||||
mode = parser.add_mutually_exclusive_group()
|
||||
mode.add_argument('-r', '--ras', action='store_const', help='Sweep size of return address stack (RAS).', default=False, const=True)
|
||||
mode.add_argument('-d', '--direction', action='store_const', help='Sweep size of direction prediction (2-bit, Gshare, local, etc).', default=False, const=True)
|
||||
mode.add_argument('-t', '--target', action='store_const', help='Sweep size of branch target buffer (BTB).', default=False, const=True)
|
||||
mode.add_argument('-c', '--iclass', action='store_const', help='Sweep size of classification (BTB) Same as -t.', default=False, const=True)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if(args.direction):
|
||||
# for direction predictor size sweep
|
||||
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 <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
||||
grepstr="")
|
||||
configs.append(tc)
|
||||
|
||||
if(args.target or args.iclass):
|
||||
# BTB and class size sweep
|
||||
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+RAS_SIZE=16+define+BTB_SIZE=" + str(CurrBPSize) + "+define+BTB_OVERRIDE"
|
||||
tc = TestCase(
|
||||
name=name,
|
||||
variant="rv32gc",
|
||||
cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
||||
grepstr="")
|
||||
configs.append(tc)
|
||||
|
||||
# ras size sweep
|
||||
if(args.ras):
|
||||
bpdSize = [2, 3, 4, 6, 10, 16]
|
||||
for CurrBPSize in bpdSize:
|
||||
name = 'RAS'+str(CurrBPSize)
|
||||
configOptions = "+define+INSTR_CLASS_PRED=0 +define+BPRED_OVERRIDE +define+BPRED_TYPE=\`BP_GSHARE" + "+define+BPRED_SIZE=16" + "+define+BTB_SIZE=16" + "+define+RAS_SIZE=" + str(CurrBPSize) + "+define+BTB_OVERRIDE+define+RAS_OVERRIDE"
|
||||
tc = TestCase(
|
||||
name=name,
|
||||
variant="rv32gc",
|
||||
cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
||||
grepstr="")
|
||||
configs.append(tc)
|
||||
|
||||
# bpdSize = [6, 8, 10, 12, 14, 16]
|
||||
# LHRSize = [4, 8, 10]
|
||||
# bpdType = ['local_repair']
|
||||
# for CurrBPType in bpdType:
|
||||
# for CurrBPSize in bpdSize:
|
||||
# for CurrLHRSize in LHRSize:
|
||||
# name = str(CurrLHRSize)+CurrBPType+str(CurrBPSize)
|
||||
# configOptions = "+define+INSTR_CLASS_PRED=0 +define+BPRED_TYPE=\"BP_" + CurrBPType.upper() + "\" +define+BPRED_SIZE=" + str(CurrBPSize) + " +define+BPRED_NUM_LHR=" + str(CurrLHRSize) + " "
|
||||
# tc = TestCase(
|
||||
# name=name,
|
||||
# variant="rv32gc",
|
||||
# cmd="vsim > {} -c <<!\ndo wally-batch.do rv32gc configOptions " + name + " embench " + configOptions,
|
||||
# grepstr="")
|
||||
# configs.append(tc)
|
||||
|
||||
# Scale the number of concurrent processes to the number of test cases, but
|
||||
# max out at a limited number of concurrent processes to not overwhelm the system
|
||||
|
@ -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.
|
||||
|
6
src/cache/cacheLRU.sv
vendored
6
src/cache/cacheLRU.sv
vendored
@ -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
|
||||
|
@ -201,6 +201,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;
|
||||
|
@ -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
|
||||
|
@ -51,32 +51,32 @@ 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
|
||||
if(P.COMPRESSED_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;
|
||||
assign NCBranchF = PostSpillInstrRawF[6:0] == 7'h63;
|
||||
|
||||
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 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.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 & (ccall | (ccallr & (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.
|
||||
|
@ -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
|
||||
@ -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
|
||||
|
||||
@ -353,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
|
||||
@ -373,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
|
||||
@ -389,7 +402,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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -202,8 +202,8 @@ module csr import cvw::*; #(parameter cvw_t P) (
|
||||
///////////////////////////////////////////
|
||||
|
||||
assign CSRAdrM = InstrM[31:20];
|
||||
assign UnalignedNextEPCM = TrapM ? ((wfiM & IntPendingM) ? PCM+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 UnalignedNextEPCM = TrapM ? PCM : CSRWriteValM;
|
||||
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);
|
||||
|
@ -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 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
|
||||
|
@ -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
|
||||
@ -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
|
||||
@ -86,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
|
||||
///////////////////////////////////////////
|
||||
|
@ -115,15 +115,17 @@ 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);
|
||||
.EcallFaultM, .BreakpointFaultM, .sretM, .mretM, .wfiM, .wfiW, .sfencevmaM);
|
||||
|
||||
// Control and Status Registers
|
||||
csr #(P) csr(.clk, .reset, .FlushM, .FlushW, .StallE, .StallM, .StallW,
|
||||
@ -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
|
||||
|
@ -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,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; // 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);
|
||||
|
||||
|
@ -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<PERIPHS; i++) begin
|
||||
|
@ -59,14 +59,9 @@ module gpio_apb import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
// account for subword read/write circuitry
|
||||
// -- Note GPIO registers are 32 bits no matter what; access them with LW SW.
|
||||
// (At least that's what I think when FE310 spec says "only naturally aligned 32-bit accesses are supported")
|
||||
if (P.XLEN == 64) begin
|
||||
assign Din = entry[2] ? PWDATA[63:32] : PWDATA[31:0];
|
||||
assign PRDATA = entry[2] ? {Dout,32'b0} : {32'b0,Dout};
|
||||
end else begin // 32-bit
|
||||
assign Din = PWDATA[31:0];
|
||||
assign PRDATA = Dout;
|
||||
end
|
||||
assign Din = PWDATA[31:0];
|
||||
if (P.XLEN == 64) assign PRDATA = {Dout, Dout};
|
||||
else assign PRDATA = Dout;
|
||||
|
||||
// register access
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
|
@ -94,13 +94,9 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
// account for subword read/write circuitry
|
||||
// -- Note PLIC registers are 32 bits no matter what; access them with LW SW.
|
||||
if (P.XLEN == 64) begin
|
||||
assign Din = entry[2] ? PWDATA[63:32] : PWDATA[31:0];
|
||||
assign PRDATA = entry[2] ? {Dout,32'b0} : {32'b0,Dout};
|
||||
end else begin // 32-bit
|
||||
assign PRDATA = Dout;
|
||||
assign Din = PWDATA[31:0];
|
||||
end
|
||||
assign Din = PWDATA[31:0];
|
||||
if (P.XLEN == 64) assign PRDATA = {Dout, Dout};
|
||||
else assign PRDATA = Dout;
|
||||
|
||||
// ==================
|
||||
// Register Interface
|
||||
|
@ -54,31 +54,9 @@ module uart_apb import cvw::*; #(parameter cvw_t P) (
|
||||
assign MEMRb = ~memread;
|
||||
assign MEMWb = ~memwrite;
|
||||
|
||||
if (P.XLEN == 64) begin:uart
|
||||
always_comb begin
|
||||
PRDATA = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout};
|
||||
case (entry)
|
||||
3'b000: Din = PWDATA[7:0];
|
||||
3'b001: Din = PWDATA[15:8];
|
||||
3'b010: Din = PWDATA[23:16];
|
||||
3'b011: Din = PWDATA[31:24];
|
||||
3'b100: Din = PWDATA[39:32];
|
||||
3'b101: Din = PWDATA[47:40];
|
||||
3'b110: Din = PWDATA[55:48];
|
||||
3'b111: Din = PWDATA[63:56];
|
||||
endcase
|
||||
end
|
||||
end else begin:uart // 32-bit
|
||||
always_comb begin
|
||||
PRDATA = {Dout, Dout, Dout, Dout};
|
||||
case (entry[1:0])
|
||||
2'b00: Din = PWDATA[7:0];
|
||||
2'b01: Din = PWDATA[15:8];
|
||||
2'b10: Din = PWDATA[23:16];
|
||||
2'b11: Din = PWDATA[31:24];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
assign Din = PWDATA[7:0];
|
||||
if (P.XLEN == 64) assign PRDATA = {Dout, Dout, Dout, Dout, Dout, Dout, Dout, Dout};
|
||||
else assign PRDATA = {Dout, Dout, Dout, Dout};
|
||||
|
||||
logic BAUDOUTb; // loop tx clock BAUDOUTb back to rx clock RCLK
|
||||
uartPC16550D #(P.UART_PRESCALE) u(
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
@ -24,18 +26,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/}
|
||||
|
||||
@ -53,6 +57,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
|
||||
@ -104,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}
|
||||
}
|
||||
@ -121,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
|
||||
|
||||
@ -145,18 +152,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
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,16 +182,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]
|
||||
}
|
||||
@ -238,6 +253,25 @@ 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
|
||||
|
||||
# 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
|
||||
set filename [format "%s%s" $outputDir "/reports/constraint_all_violators.rpt"]
|
||||
redirect $filename {report_constraint -all_violators}
|
||||
@ -246,16 +280,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
|
||||
|
@ -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
|
||||
@ -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)
|
||||
#print(buf)
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user