This commit is contained in:
Katherine Parry 2022-07-11 18:30:29 -07:00
commit 7815b81716
21 changed files with 357 additions and 335 deletions

View File

@ -4,37 +4,60 @@ cmbase=../../addins/coremark
work_dir= ../../benchmarks/coremark/work
XLEN ?=64
sources=$(cmbase)/core_main.c $(cmbase)/core_list_join.c $(cmbase)/coremark.h \
$(cmbase)/core_matrix.c $(cmbase)/core_state.c $(cmbase)/core_util.c \
$(PORT_DIR)/core_portme.h $(PORT_DIR)/core_portme.c $(PORT_DIR)/core_portme.mak \
$(PORT_DIR)/crt.S $(PORT_DIR)/encoding.h $(PORT_DIR)/util.h $(PORT_DIR)/syscalls.c
ABI = lp64
#$(if $(findstring 64, $(XLEN)), lp64, ilp32)
PORT_CFLAGS = -g -march=$(XLEN)im -mabi=$(ABI) -static -mcmodel=medlow -mtune=sifive-3-series \
-O3 -falign-functions=16 -funroll-all-loops \
-finline-functions -falign-jumps=4 \
-nostdlib -nostartfiles -ffreestanding -mstrict-align \
-DTOTAL_DATA_SIZE=2000 -DMAIN_HAS_NOARGC=1 \
-DPERFORMANCE_RUN=1
$(cmbase)/core_matrix.c $(cmbase)/core_state.c $(cmbase)/core_util.c \
$(PORT_DIR)/core_portme.h $(PORT_DIR)/core_portme.c $(PORT_DIR)/core_portme.mak \
$(PORT_DIR)/crt.S $(PORT_DIR)/encoding.h $(PORT_DIR)/util.h $(PORT_DIR)/syscalls.c
ABI := $(if $(findstring "64","$(XLEN)"),lp64,ilp32)
ARCH := rv$(XLEN)im
PORT_CFLAGS = -g -march=rv$(XLEN)im -mabi=$(ABI) -march=$(ARCH) -static -falign-functions=16 \
-mbranch-cost=1 -DSKIP_DEFAULT_MEMSET -mtune=sifive-3-series -O3 -funroll-all-loops -finline-functions -falign-jumps=4 \
-fno-delete-null-pointer-checks -fno-rename-registers --param=loop-max-datarefs-for-datadeps=0 \
-funroll-all-loops --param=uninlined-function-insns=8 -fno-tree-vrp -fwrapv -fipa-pta \
-nostdlib -nostartfiles -ffreestanding -mstrict-align \
-DTOTAL_DATA_SIZE=2000 -DMAIN_HAS_NOARGC=1 -DPERFORMANCE_RUN=1 -DXLEN=$(XLEN)
# flags that cause build errors mcmodel=medlow
# -static -mcmodel=medlow -mtune=sifive-7-series \
# -O3 -falign-functions=16 -funroll-all-loops -mbranch-cost=1 -DSKIP_DEFAULT_MEMSET
# -finline-functions -falign-jumps=4 \
# -nostdlib -nostartfiles -ffreestanding -mstrict-align \
# -DTOTAL_DATA_SIZE=2000 -DMAIN_HAS_NOARGC=1 \
# -DPERFORMANCE_RUN=1
# "-march=rv$(XLEN)im -mabi=$(ABI) -mbranch-cost=1 -DSKIP_DEFAULT_MEMSET -mtune=sifive-7-series -Ofast -funroll-all-loops -fno-delete-null-pointer-checks -fno-rename-registers --param=loop-max-datarefs-for-datadeps=0 -funroll-all-loops --param=uninlined-function-insns=8 -fno-tree-vrp -fwrapv -fipa-pta "
all: $(work_dir)/coremark.bare.riscv.elf.memfile
run:
(cd ../../pipelined/regression && (time vsim -c -do "do wally-pipelined-batch.do rv$(XLEN)gc coremark" 2>&1 | tee $(work_dir)/coremark.sim.log))
cd ../../benchmarks/coremark/
$(work_dir)/coremark.bare.riscv.elf.memfile: $(work_dir)/coremark.bare.riscv
riscv64-unknown-elf-objdump -D $< > $<.elf.objdump
riscv64-unknown-elf-elf2hex --bit-width $(XLEN) --input $< --output $@
extractFunctionRadix.sh $<.elf.objdump
(cd ../../pipelined/regression && (vsim -c -do "do wally-pipelined-batch.do rv$(XLEN)gc coremark" 2>&1 | tee $(work_dir)/coremark.sim.log))
cd ../../benchmarks/coremark/
$(work_dir)/coremark.bare.riscv: $(sources) Makefile
# make -C $(cmbase) PORT_DIR=$(PORT_DIR) compile RISCV=/opt/riscv/riscv-gnu-toolchain XCFLAGS="-march=rv64imd -mabi=lp64d -mbranch-cost=1 -DSKIP_DEFAULT_MEMSET -mtune=sifive-7-series -Ofast -funroll-all-loops -fno-delete-null-pointer-checks -fno-rename-registers --param=loop-max-datarefs-for-datadeps=0 -funroll-all-loops --param=uninlined-function-insns=8 -fno-tree-vrp -fwrapv -fno-toplevel-reorder --param=max-inline-insns-size=128 -fipa-pta"
# These flags were used by WD on CoreMark
# make -C $(cmbase) PORT_DIR=$(PORT_DIR) compile RISCV=$(RISCV)/riscv-gnu-toolchain XCFLAGS="-march=rv64imd -mabi=lp64d -mbranch-cost=1 -DSKIP_DEFAULT_MEMSET -mtune=sifive-7-series -Ofast -funroll-all-loops -fno-delete-null-pointer-checks -fno-rename-registers --param=loop-max-datarefs-for-datadeps=0 -funroll-all-loops --param=uninlined-function-insns=8 -fno-tree-vrp -fwrapv -fipa-pta "
make -C $(cmbase) PORT_DIR=$(PORT_DIR) compile RISCV=$(RISCV)/riscv-gnu-toolchain XCFLAGS="-march=rv$(XLEN)im -mabi=$(ABI) -mbranch-cost=1 -DSKIP_DEFAULT_MEMSET -mtune=sifive-7-series -Ofast -funroll-all-loops -fno-delete-null-pointer-checks -fno-rename-registers --param=loop-max-datarefs-for-datadeps=0 -funroll-all-loops --param=uninlined-function-insns=8 -fno-tree-vrp -fwrapv -fipa-pta "
make -C $(cmbase) PORT_DIR=$(PORT_DIR) compile RISCV=$(RISCV)/riscv-gnu-toolchain XCFLAGS="$(PORT_CFLAGS)"
# -fno-toplevel-reorder --param=max-inline-insns-size=128 " # adding this bit caused a compiler error
mkdir -p $(work_dir)
mv $(cmbase)/coremark.bare.riscv $(work_dir)
.PHONY: clean
clean:
rm -f $(work_dir)/*
# # PORT_CFLAGS = -g -march=$(XLEN)im -mabi=$(ABI) -static -mcmodel=medlow -mtune=sifive-3-series \
# # -O3 -falign-functions=16 -funroll-all-loops \
# # -finline-functions -falign-jumps=4 \
# # -nostdlib -nostartfiles -ffreestanding -mstrict-align \
# # -DTOTAL_DATA_SIZE=2000 -DMAIN_HAS_NOARGC=1 \
# # -DPERFORMANCE_RUN=1
# make -C $(cmbase) PORT_DIR=$(PORT_DIR) compile RISCV=$(RISCV)/riscv-gnu-toolchain XCFLAGS="-march=rv$(XLEN)im -mabi=$(ABI) -mbranch-cost=1 -DSKIP_DEFAULT_MEMSET -mtune=sifive-7-series -Ofast -funroll-all-loops -fno-delete-null-pointer-checks -fno-rename-registers --param=loop-max-datarefs-for-datadeps=0 -funroll-all-loops --param=uninlined-function-insns=8 -fno-tree-vrp -fwrapv -fipa-pta "
# make -C $(cmbase) PORT_DIR=$(PORT_DIR) compile RISCV=/opt/riscv/riscv-gnu-toolchain XCFLAGS="-march=rv64imd -mabi=lp64d -mbranch-cost=1 -DSKIP_DEFAULT_MEMSET -mtune=sifive-7-series -Ofast -funroll-all-loops -fno-delete-null-pointer-checks -fno-rename-registers --param=loop-max-datarefs-for-datadeps=0 -funroll-all-loops --param=uninlined-function-insns=8 -fno-tree-vrp -fwrapv -fno-toplevel-reorder --param=max-inline-insns-size=128 -fipa-pta"
# make -C $(cmbase) PORT_DIR=$(PORT_DIR) compile RISCV=$(RISCV)/riscv-gnu-toolchain XCFLAGS="-march=rv64imd -mabi=lp64d -mbranch-cost=1 -DSKIP_DEFAULT_MEMSET -mtune=sifive-7-series -Ofast -funroll-all-loops -fno-delete-null-pointer-checks -fno-rename-registers --param=loop-max-datarefs-for-datadeps=0 -funroll-all-loops --param=uninlined-function-insns=8 -fno-tree-vrp -fwrapv -fipa-pta "

View File

@ -196,10 +196,13 @@ void stop_time(void) {
CORE_TICKS get_time(void) {
CORE_TICKS elapsed=(CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
unsigned long instructions = minstretDiff();
ee_printf(" Called get_time\n");
long long cm100 = 1000000000 / elapsed; // coremark score * 100
long long cpi100 = elapsed*100/instructions; // CPI * 100
ee_printf(" WALLY CoreMark Results (from get_time)\n");
ee_printf(" Elapsed MTIME: %u\n", elapsed);
ee_printf(" Elapsed MINSTRET: %lu\n", instructions);
ee_printf(" CPI: %lu / %lu\n", elapsed, instructions);
ee_printf(" COREMARK/MHz Score: 10,000,000 / %lu = %d.%02d \n", elapsed, cm100/100, cm100%100);
ee_printf(" CPI: %lu / %lu = %d.%02d\n", elapsed, instructions, cpi100/100, cpi100%100);
return elapsed;
}
/* Function: time_in_secs

View File

@ -66,6 +66,9 @@ typedef size_t CORE_TICKS;
#elif HAS_TIME_H
#include <time.h>
typedef clock_t CORE_TICKS;
// #elif (XLEN==32)
// #include <sys/types.h>
// typedef ee_u32 CORE_TICKS;
#else
/* Configuration: size_t and clock_t
Note these need to match the size of the clock output and the xLen the processor supports
@ -105,11 +108,16 @@ typedef signed int ee_s32;
typedef double ee_f32;
typedef unsigned char ee_u8;
typedef unsigned int ee_u32;
typedef unsigned long long ee_ptr_int;
#if (XLEN==64)
typedef unsigned long long ee_ptr_int;
#else
typedef ee_u32 ee_ptr_int;
#endif
typedef size_t ee_size_t;
/* align an offset to point to a 32b value */
#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x) - 1) & ~3))
/* Configuration: SEED_METHOD
Defines method to get seed values that cannot be computed at compile time.

View File

@ -33,13 +33,13 @@ CC = $(RISCVTOOLS)/bin/$(RISCVTYPE)-gcc
# Flag: CFLAGS
# Use this flag to define compiler options. Note, you can add compiler options from the command line using XCFLAGS="other flags"
#PORT_CFLAGS = -O2 -static -std=gnu99
PORT_CFLAGS = -O2 -mcmodel=medany -static -fno-tree-loop-distribute-patterns -std=gnu99 -fno-common -nostartfiles -lm -lgcc -T $(PORT_DIR)/link.ld
PORT_CFLAGS = -mcmodel=medany -fno-tree-loop-distribute-patterns -fno-common -lm -lgcc -T $(PORT_DIR)/link.ld
FLAGS_STR = "$(PORT_CFLAGS) $(XCFLAGS) $(XLFLAGS) $(LFLAGS_END)"
CFLAGS = $(PORT_CFLAGS) -I$(PORT_DIR) -I. -DFLAGS_STR=\"$(FLAGS_STR)\"
#Flag: LFLAGS_END
# Define any libraries needed for linking or other flags that should come at the end of the link line (e.g. linker scripts).
# Note: On certain platforms, the default clock_gettime implementation is supported but requires linking of librt.
LFLAGS_END +=
LFLAGS_END += -static-libgcc -lgcc
# Flag: PORT_SRCS
# Port specific source files can be added here
PORT_SRCS = $(PORT_DIR)/core_portme.c $(PORT_DIR)/syscalls.c $(PORT_DIR)/crt.S

View File

@ -105,6 +105,7 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
// Data Array
/////////////////////////////////////////////////////////////////////////////////////////////
// *** instantiate one larger RAM, not one per RAM. Expand byte mask
genvar words;
for(words = 0; words < LINELEN/`XLEN; words++) begin: word
sram1p1rw #(.DEPTH(NUMLINES), .WIDTH(`XLEN)) CacheDataMem(.clk, .Adr(RAdr),

View File

@ -53,6 +53,7 @@ module sram1p1rw #(parameter DEPTH=128, WIDTH=256) (
if (`USE_SRAM == 1) begin
// 64 x 128-bit SRAM
// check if the size is ok, complain if not***
logic [WIDTH-1:0] BitWriteMask;
for (index=0; index < WIDTH; index++)
assign BitWriteMask[index] = ByteMask[index/8];

View File

@ -93,11 +93,7 @@ module srt (
otfc2 #(`DIVLEN) otfc2(clk, Start, qp, qz, qm, Quot);
<<<<<<< Updated upstream
expcalc expcalc(.XExp, .YExp, .calcExp);
=======
expcalc expcalc(.XExp, .YExp, .calcExp, .Sqrt);
>>>>>>> Stashed changes
signcalc signcalc(.XSign, .YSign, .calcSign);
endmodule
@ -187,6 +183,26 @@ module qsel2 ( // *** eventually just change to 4 bits
assign #1 qm = magnitude & sign;
endmodule
////////////////////////////////////
// Adder Input Selection, Radix 2 //
////////////////////////////////////
module fsel2 (
input logic sp, sn,
input logic [`DIVLEN+3:0] C, S, SM,
output logic [`DIVLEN+3:0] F
);
logic [`DIVLEN+3:0] FP, FN;
// Generate for both positive and negative bits
assign FP = ~S & C;
assign FN = SM | (C & (~C << 2));
// Choose which adder input will be used
assign F = sp ? FP : (sn ? FN : (`DIVLEN+4){1'b0});
endmodule
///////////////////////////////////
// On-The-Fly Converter, Radix 2 //
///////////////////////////////////
@ -234,6 +250,17 @@ module otfc2 #(parameter N=64) (
endmodule
///////////////////////////////
// Square Root OTFC, Radix 2 //
///////////////////////////////
module softc2(
input logic clk,
input logic Start,
input logic sp, sn,
output logic S,
);
endmodule
/////////////
// counter //
/////////////
@ -301,13 +328,6 @@ endmodule
// expcalc //
//////////////
module expcalc(
<<<<<<< Updated upstream
input logic [`NE-1:0] XExp, YExp,
output logic [`NE-1:0] calcExp
);
assign calcExp = XExp - YExp + (`NE)'(`BIAS);
=======
input logic [`NE-1:0] XExp, YExp,
input logic Sqrt,
output logic [`NE-1:0] calcExp
@ -317,7 +337,6 @@ module expcalc(
assign SExp = {1'b0, SXExp[`NE-1:1]} + (`NE)'(`BIAS);
assign DExp = XExp - YExp + (`NE)'(`BIAS);
assign calcExp = Sqrt ? SExp : DExp;
>>>>>>> Stashed changes
endmodule

View File

@ -62,11 +62,6 @@ module testbench;
// `define mema 255:192
// FLOAT TEST SIZES
<<<<<<< Updated upstream
`define memr 63:0
`define memb 127:64
`define mema 191:128
=======
// `define memr 63:0
// `define memb 127:64
// `define mema 191:128
@ -75,7 +70,6 @@ module testbench;
`define memr 63:0
`define mema 127:64
`define memb 191:128
>>>>>>> Stashed changes
// Test logicisters
logic [MEM_WIDTH-1:0] Tests [0:MEM_SIZE]; // Space for input file
@ -86,13 +80,9 @@ module testbench;
logic rsign;
integer testnum, errors;
<<<<<<< Updated upstream
assign Int = 1'b0;
=======
// Equip Int test or Sqrt test
assign Int = 1'b0;
assign Sqrt = 1'b1;
>>>>>>> Stashed changes
// Divider
srt srt(.clk, .Start(req),
@ -101,11 +91,7 @@ module testbench;
.XSign(asign), .YSign(bsign), .rsign,
.SrcXFrac(afrac), .SrcYFrac(bfrac),
.SrcA(a), .SrcB(b), .Fmt(2'b00),
<<<<<<< Updated upstream
.W64(1'b1), .Signed(1'b0), .Int, .Sqrt(1'b0),
=======
.W64(1'b1), .Signed(1'b0), .Int, .Sqrt,
>>>>>>> Stashed changes
.Quot, .Rem(), .Flags(), .done);
// Counter
@ -125,11 +111,7 @@ module testbench;
begin
testnum = 0;
errors = 0;
<<<<<<< Updated upstream
$readmemh ("testvectors", Tests);
=======
$readmemh ("sqrttestvectors", Tests);
>>>>>>> Stashed changes
Vec = Tests[testnum];
a = Vec[`mema];
{asign, aExp, afrac} = a;
@ -183,17 +165,10 @@ module testbench;
req <= #5 1;
diffp = correctr[51:0] - r;
diffn = r - correctr[51:0];
<<<<<<< Updated upstream
if (($signed(diffn) > 1) | ($signed(diffp) > 1) | (diffn === 64'bx) | (diffp === 64'bx)) // check if accurate to 1 ulp
begin
errors = errors + 1;
$display("result was %h, should be %h %h %h\n", rSqrt, correctr, diffn, diffp);
=======
if (rExp !== correctr[62:52]) // check if accurate to 1 ulp
begin
errors = errors + 1;
$display("result was %h, should be %h %h %h\n", r, correctr, diffn, diffp);
>>>>>>> Stashed changes
$display("failed\n");
$stop;
end

View File

@ -123,6 +123,7 @@ logic [3:0] dummy;
"wally32priv": tests = wally32priv;
"wally32periph": tests = wally32periph;
"embench": tests = embench;
"coremark": tests = coremark;
endcase
end
if (tests.size() == 0) begin

View File

@ -36,7 +36,7 @@ string tvpaths[] = '{
"../../tests/riscof/work/riscv-arch-test/",
"../../tests/wally-riscv-arch-test/work/", //"../../tests/riscof/work/wally-riscv-arch-test/",
"../../tests/imperas-riscv-tests/work/",
"../../benchmarks/coremark/work/", //"../../benchmarks/coremark/work/",
"../../benchmarks/coremark/work/",
"../../addins/embench-iot/"
};

View File

@ -1,14 +1,15 @@
#
# Makefile for synthesis
# Makefile for synthesis
# Shreya Sanghai (ssanghai@hmc.edu) 2/28/2022
# Madeleine Masser-Frye (mmasserfrye@hmc.edu) 7/8/2022
NAME := synth
# defaults
export DESIGN ?= wallypipelinedcore
export FREQ ?= 3000
export CONFIG ?= rv32e
# title to add a note in the synth's directory name
TITLE =
# tsmc28, sky130, and sky90 presently supported
export TECH ?= sky90
# MAXCORES allows parallel compilation, which is faster but less CPU-efficient
@ -21,20 +22,14 @@ export DRIVE ?= FLOP
time := $(shell date +%F-%H-%M)
hash := $(shell git rev-parse --short HEAD)
export OUTPUTDIR := newRuns/$(DESIGN)_$(CONFIG)_$(TECH)nm_$(FREQ)_MHz_$(time)_$(TITLE)_$(hash)
export OUTPUTDIR := runs/$(DESIGN)_$(CONFIG)_$(TECH)nm_$(FREQ)_MHz_$(time)_$(TITLE)_$(hash)
export SAIFPOWER ?= 0
CONFIGDIR ?= ${WALLY}/pipelined/config
CONFIGFILES ?= $(shell find $(CONFIGDIR) -name rv*_*)
CONFIGFILESTRIM = $(notdir $(CONFIGFILES))
# FREQS = 25 50 100 150 200 250 300 350 400
k = 3 6
ifeq ($(TECH), sky130)
FREQS = 25 50 100 150 200 250 300 350 400
else ifeq ($(TECH), sky90)
FREQS = 500 550 600 650 700 750 800 850 900 950 1000
endif
# k = 3 6
print:
@echo $(FREQS)
@ -42,14 +37,9 @@ print:
default:
@echo "Basic synthesis procedure for Wally:"
@echo " Invoke with make synth"
test: rv%
echo "Running test on $<"
rv%.log: rv%
echo $<
@echo " Basic synthesis procedure for Wally:"
@echo " Invoke with make synth"
@echo "Use wallySynth.py to run a concurrent sweep "
DIRS32 = rv32e rv32gc rv32ic
@ -62,22 +52,22 @@ DIRS = $(DIRS32) $(DIRS64)
# @$(foreach kval, $(k), sed -i 's/BPRED_SIZE.*/BPRED_SIZE $(kval)/g' $(CONFIGDIR)/rv64gc_bpred_$(kval)/wally-config.vh;)
# @$(foreach kval, $(k), make synth DESIGN=wallypipelinedcore CONFIG=rv64gc_bpred_$(kval) TECH=sky90 FREQ=500 MAXCORES=4 --jobs;)
copy:
# remove old config files
rm -rf $(CONFIGDIR)/*_*
@$(foreach dir, $(DIRS), rm -rf $(CONFIGDIR)/$(dir)_orig;)
@$(foreach dir, $(DIRS), cp -r $(CONFIGDIR)/$(dir) $(CONFIGDIR)/$(dir)_orig;)
@$(foreach dir, $(DIRS), sed -i 's/WAYSIZEINBYTES.*/WAYSIZEINBYTES 512/g' $(CONFIGDIR)/$(dir)_orig/wally-config.vh;)
@$(foreach dir, $(DIRS), sed -i 's/NUMWAYS.*/NUMWAYS 1/g' $(CONFIGDIR)/$(dir)_orig/wally-config.vh;)
@$(foreach dir, $(DIRS), sed -i 's/BPRED_SIZE.*/BPRED_SIZE 5/g' $(CONFIGDIR)/$(dir)_orig/wally-config.vh;)
@$(foreach dir, $(DIRS), sed -i 's/BPRED_SIZE.*/BPRED_SIZE 4/g' $(CONFIGDIR)/$(dir)_orig/wally-config.vh;)
@$(foreach dir, $(DIRS32), sed -i "s/RAM_RANGE.*/RAM_RANGE 34\'h01FF/g" $(CONFIGDIR)/$(dir)_orig/wally-config.vh ;)
@$(foreach dir, $(DIRS64), sed -i "s/RAM_RANGE.*/RAM_RANGE 56\'h01FF/g" $(CONFIGDIR)/$(dir)_orig/wally-config.vh ;)
del:
rm -rf $(CONFIGDIR)/*_*
configs: $(DIRS)
$(DIRS):
#turn off FPU
# turn off FPU
rm -rf $(CONFIGDIR)/$@_FPUoff
cp -r $(CONFIGDIR)/$@_orig $(CONFIGDIR)/$@_FPUoff
sed -i 's/1 *<< *3/0 << 3/' $(CONFIGDIR)/$@_FPUoff/wally-config.vh
@ -93,12 +83,12 @@ $(DIRS):
cp -r $(CONFIGDIR)/$@_FPUoff $(CONFIGDIR)/$@_PMP0
sed -i 's/PMP_ENTRIES \(64\|16\|0\)/PMP_ENTRIES 0/' $(CONFIGDIR)/$@_PMP0/wally-config.vh
#no muldiv
# no muldiv
rm -rf $(CONFIGDIR)/$@_noMulDiv
cp -r $(CONFIGDIR)/$@_PMP0 $(CONFIGDIR)/$@_noMulDiv
sed -i 's/1 *<< *12/0 << 12/' $(CONFIGDIR)/$@_noMulDiv/wally-config.vh
#no priv
# no priv
rm -rf $(CONFIGDIR)/$@_noPriv
cp -r $(CONFIGDIR)/$@_noMulDiv $(CONFIGDIR)/$@_noPriv
sed -i 's/ZICSR_SUPPORTED *1/ZICSR_SUPPORTED 0/' $(CONFIGDIR)/$@_noPriv/wally-config.vh
@ -106,18 +96,10 @@ $(DIRS):
freqs:
@$(foreach freq, $(FREQS), make synth DESIGN=wallypipelinedcore CONFIG=rv32e FREQ=$(freq) MAXCORES=1;)
allsynth: $(CONFIGFILESTRIM)
$(CONFIGFILESTRIM):
make synth DESIGN=wallypipelinedcore CONFIG=$@ TECH=sky90 FREQ=3000 MAXCORES=1
synth:
rm -f hdl/*
rm -rf WORK
@echo "DC Synthesis"
@mkdir -p hdl/
@mkdir -p $(OUTPUTDIR)
@mkdir -p $(OUTPUTDIR)/hdl
@mkdir -p $(OUTPUTDIR)/reports
@mkdir -p $(OUTPUTDIR)/mapped
@mkdir -p $(OUTPUTDIR)/unmapped
@ -125,11 +107,11 @@ ifeq ($(SAIFPOWER), 1)
cp -f ../pipelined/regression/power.saif .
endif
dc_shell-xg-t -64bit -f scripts/$(NAME).tcl | tee $(OUTPUTDIR)/$(NAME).out
rm -rf $(OUTPUTDIR)/hdl
rm -rf $(OUTPUTDIR)/WORK
rm -rf $(OUTPUTDIR)/alib-52
clean:
# fix should make del be here
rm -rf alib-52 WORK analyzed $(NAME).out
rm -f hdl/*
rm -f default.svf
rm -f command.log
rm -f filenames*.log
@ -137,6 +119,5 @@ clean:
rm -f Synopsys_stack_trace_*.txt
rm -f crte_*.txt
fresh: clean copy configs
@echo "synth directory cleaned and fresh config files written"

View File

@ -7,10 +7,10 @@ import subprocess
from matplotlib.cbook import flatten
import matplotlib.pyplot as plt
import matplotlib.lines as lines
from wallySynth import testFreq
import numpy as np
from ppa.ppaAnalyze import noOutliers
from matplotlib import ticker
import argparse
def synthsintocsv():
@ -74,14 +74,13 @@ def synthsfromcsv(filename):
allSynths[i] = Synth(*allSynths[i])
return allSynths
def freqPlot(tech, width, config):
''' plots delay, area for syntheses with specified tech, module, width
'''
freqsL, delaysL, areasL = ([[], []] for i in range(3))
for oneSynth in allSynths:
if (width == oneSynth.width) & (config == oneSynth.config) & (tech == oneSynth.tech) & (oneSynth.special == ''):
if (width == oneSynth.width) & (config == oneSynth.config) & (tech == oneSynth.tech) & ('' == oneSynth.special):
ind = (1000/oneSynth.delay < oneSynth.freq) # when delay is within target clock period
freqsL[ind] += [oneSynth.freq]
delaysL[ind] += [oneSynth.delay]
@ -124,74 +123,93 @@ def freqPlot(tech, width, config):
addFO4axis(fig, ax1, tech)
plt.savefig('./plots/wally/freqSweep_' + tech + '_' + width + config + '.png')
# plt.show()
def areaDelay(tech, delays, areas, labels, fig, ax, norm=False):
def areaDelay(tech, fig=None, ax=None, freq=None, width=None, config=None, norm=False):
delays, areas, labels = ([] for i in range(3))
plt.subplots_adjust(left=0.18)
for oneSynth in allSynths:
if (width==None) or (width == oneSynth.width):
if (tech == oneSynth.tech) & (freq == oneSynth.freq):
if (config == None) & (oneSynth.special == 'FPUoff'): #fix
delays += [oneSynth.delay]
areas += [oneSynth.area]
labels += [oneSynth.width + oneSynth.config]
elif (config != None) & (oneSynth.config == config):
delays += [oneSynth.delay]
areas += [oneSynth.area]
labels += [oneSynth.special]
if width == None:
width = ''
if (fig == None) or (ax == None):
fig, (ax) = plt.subplots(1, 1)
ax.ticklabel_format(useOffset=False, style='plain')
plt.subplots_adjust(left=0.18)
fo4 = techdict[tech].fo4
add32area = techdict[tech].add32area
marker = techdict[tech].shape
color = techdict[tech].color
if norm:
delays = [d/techdict[tech][0] for d in delays]
areas = [a/techdict[tech][1] for a in areas]
delays = [d/fo4 for d in delays]
areas = [a/add32area for a in areas]
plt.scatter(delays, areas)
plt.scatter(delays, areas, marker=marker, color=color)
plt.xlabel('Cycle time (ns)')
plt.ylabel('Area (sq microns)')
ytop = ax.get_ylim()[1]
plt.ylim(ymin=0, ymax=1.1*ytop)
titleStr = tech + ' ' + width
saveStr = tech + '_' + width
if config:
titleStr += config
saveStr = saveStr + config + '_versions_'
if (config == None):
saveStr = saveStr + '_origConfigs_'
saveStr += str(freq)
titleStr = titleStr
plt.title(titleStr)
ax.yaxis.set_major_formatter(ticker.StrMethodFormatter('{x:,.0f}'))
for i in range(len(labels)):
plt.annotate(labels[i], (delays[i], areas[i]), textcoords="offset points", xytext=(0,10), ha='center')
# addFO4axis(fig, ax1, tech)
plt.savefig('./plots/wally/areaDelay_' + saveStr + '.png')
return fig
def plotFeatures(tech, width, config):
delays, areas, labels = ([] for i in range(3))
freq = techdict[tech].targfreq
for oneSynth in allSynths:
if (tech == oneSynth.tech) & (freq == oneSynth.freq):
if (oneSynth.config == config) & (width == oneSynth.width):
delays += [oneSynth.delay]
areas += [oneSynth.area]
labels += [oneSynth.special]
fig, (ax) = plt.subplots(1, 1)
fig = areaDelay(tech, delays, areas, labels, fig, ax)
titlestr = tech+'_'+width+config
plt.title(titlestr)
plt.savefig('./plots/wally/features_'+titlestr+'.png')
def plotConfigs(tech, special=''):
delays, areas, labels = ([] for i in range(3))
freq = techdict[tech].targfreq
for oneSynth in allSynths:
if (tech == oneSynth.tech) & (freq == oneSynth.freq) & (oneSynth.special == special):
delays += [oneSynth.delay]
areas += [oneSynth.area]
labels += [oneSynth.width + oneSynth.config]
fig, (ax) = plt.subplots(1, 1)
fig = areaDelay(tech, delays, areas, labels, fig, ax)
titleStr = tech+'_'+special
plt.title(titleStr)
plt.savefig('./plots/wally/configs_' + titleStr + '.png')
def normAreaDelay(special=''):
fig, (ax) = plt.subplots(1, 1)
fullLeg = []
for tech in list(techdict.keys()):
delays, areas, labels = ([] for i in range(3))
spec = techdict[tech]
freq = spec.targfreq
for oneSynth in allSynths:
if (tech == oneSynth.tech) & (freq == oneSynth.freq) & (oneSynth.special == special):
delays += [oneSynth.delay]
areas += [oneSynth.area]
labels += [oneSynth.width + oneSynth.config]
areaDelay(tech, delays, areas, labels, fig, ax, norm=True)
fullLeg += [lines.Line2D([0], [0], markerfacecolor=spec.color, label=tech, marker=spec.shape, markersize=10, color='w')]
def normAreaDelay():
fig2, (ax) = plt.subplots(1, 1)
areaDelay('sky90', fig=fig2, ax=ax, freq=testFreq[0], norm=True)
areaDelay('tsmc28', fig=fig2, ax=ax, freq=testFreq[1], norm=True)
ax.set_title('Normalized Area & Cycle Time by Configuration')
ax.set_xlabel('Cycle Time (FO4)')
ax.set_ylabel('Area (add32)')
fullLeg = [lines.Line2D([0], [0], color='royalblue', label='tsmc28')]
fullLeg += [lines.Line2D([0], [0], color='orange', label='sky90')]
ax.set_ylabel('Area (add32)')
ax.legend(handles = fullLeg, loc='upper left')
plt.savefig('./plots/wally/normAreaDelay.png')
def addFO4axis(fig, ax, tech):
fo4 = techdict[tech][0]
fo4 = techdict[tech].fo4
ax3 = fig.add_axes((0.125,0.14,0.775,0.0))
ax3.yaxis.set_visible(False) # hide the yaxis
@ -215,15 +233,22 @@ def addFO4axis(fig, ax, tech):
if __name__ == '__main__':
techdict = {'sky90': [43.2e-3, 1440.600027], 'tsmc28': [12.2e-3, 209.286002]}
parser = argparse.ArgumentParser()
parser.add_argument("-s", "--skyfreq", type=int, default=3000, help = "Target frequency used for sky90 syntheses")
parser.add_argument("-t", "--tsmcfreq", type=int, default=10000, help = "Target frequency used for tsmc28 syntheses")
args = parser.parse_args()
# synthsintocsv()
TechSpec = namedtuple("TechSpec", "color shape targfreq fo4 add32area add32lpower add32denergy")
techdict = {}
techdict['sky90'] = TechSpec('green', 'o', args.skyfreq, 43.2e-3, 1440.600027, 714.057, 0.658023)
techdict['tsmc28'] = TechSpec('blue', 's', args.tsmcfreq, 12.2e-3, 209.286002, 1060.0, .081533)
synthsintocsv()
synthsfromcsv('Summary.csv')
freqPlot('tsmc28', 'rv32', 'e')
freqPlot('sky90', 'rv32', 'e')
areaDelay('tsmc28', freq=testFreq[1], width= 'rv64', config='gc')
areaDelay('sky90', freq=testFreq[0], width='rv64', config='gc')
areaDelay('tsmc28', freq=testFreq[1])
areaDelay('sky90', freq=testFreq[0])
# normAreaDelay()
plotFeatures('sky90', 'rv64', 'gc')
plotFeatures('tsmc28', 'rv64', 'gc')
plotConfigs('sky90', special='orig')
plotConfigs('tsmc28', special='orig')
normAreaDelay(special='orig')

32
synthDC/ppa/README Normal file
View File

@ -0,0 +1,32 @@
Wally PPA Study
July 8, 2022
Madeleine Masser-Frye
mmasserfrye@hmc.edu
___________________
Apologies for issues in this folder, code was written originally for individual use and documentation was compiled in haste. Please feel free to contact the author with questions.
-------------------
ppaSynth.py
Run to synthesize datapath modules from src/ppa.
To run a specific combination of widths, modules, techs, and freqs,
modify those lists and use allCombos() to generate synthsToRun (comment out freqSweep).
To run a sweep of frequencies around the best delay found in existing syntheses (according to bestSynths.csv), modify the parameters and use freqSweep to generate synthsToRun.
To remove synths to be run that already exist in /runs from synthsToRun, use filterRedundant().
Syntheses run in parallel but you may encounter issues doing more than a dozen or so at once.
-------------------
ppaAnalyze.py
Run to plot results of PPA syntheses. See docstrings for individual function info.
-------------------
bestSynths.csv
Results of the synthesis for each combination of module, width, and tech with the best achievable delay. Generated by csvOfBest() in ppaAnalyze.py
-------------------
ppaFitting.csv & ppaEquations.csv
Representations of the regression fit for each module and metric. Generated in ppaAnalyze.py by makeCoefTable() and makeEqTable().
-------------------
ppaData.csv
Results from all synthesis runs. Generated by synthsintocsv() and used by synthsfromcsv in ppaAnalyze.py.

View File

@ -8,9 +8,11 @@ import re
from matplotlib.cbook import flatten
import matplotlib.pyplot as plt
import matplotlib.lines as lines
import matplotlib as mpl
import numpy as np
from collections import namedtuple
import sklearn.metrics as skm
import os
def synthsfromcsv(filename):
Synth = namedtuple("Synth", "module tech width freq delay area lpower denergy")
@ -518,8 +520,8 @@ def plotPPA(mod, freq=None, norm=True, aleOpt=False):
if no freq specified, uses the synthesis with best achievable delay for each width
overlays data from both techs
'''
plt.rcParams["figure.figsize"] = (7,3.46)
fig, axs = plt.subplots(2, 2)
with mpl.rc_context({"figure.figsize": (7,3.46)}):
fig, axs = plt.subplots(2, 2)
arr = [['delay', 'area'], ['lpower', 'denergy']]
@ -555,6 +557,8 @@ def plotPPA(mod, freq=None, norm=True, aleOpt=False):
# plt.show()
def makeLineLegend():
''' generates legend to accompany normalized plots
'''
plt.rcParams["figure.figsize"] = (5.5,0.3)
fig = plt.figure()
fullLeg = [lines.Line2D([0], [0], color='black', label='fastest', linestyle='-')]
@ -619,6 +623,8 @@ def muxPlot(fits='clsgn', norm=True):
plt.savefig('./plots/mux.png')
def stdDevError():
''' calculates std deviation and error for paper-writing purposes
'''
for var in ['delay', 'area', 'lpower', 'denergy']:
errlist = []
for module in modules:
@ -668,6 +674,30 @@ def stdDevError():
print(var, ' ', avgErr, ' ', stdv)
def makePlotDirectory():
''' creates plots directory in same level as this script to store plots in
'''
current_directory = os.getcwd()
final_directory = os.path.join(current_directory, 'plots')
if not os.path.exists(final_directory):
os.makedirs(final_directory)
os.chdir(final_directory)
for folder in ['freqBuckshot', 'normalized', 'unnormalized']:
new_directory = os.path.join(final_directory, folder)
if not os.path.exists(new_directory):
os.makedirs(new_directory)
os.chdir(new_directory)
if 'freq' in folder:
for tech in ['sky90', 'tsmc28']:
for mod in modules:
tech_directory = os.path.join(new_directory, tech)
mod_directory = os.path.join(tech_directory, mod)
if not os.path.exists(mod_directory):
os.makedirs(mod_directory)
os.chdir('..')
os.chdir(current_directory)
if __name__ == '__main__':
##############################
@ -686,26 +716,22 @@ if __name__ == '__main__':
##############################
# cleanup() # run to remove garbage synth runs
# synthsintocsv() # slow, run only when new synth runs to add to csv
synthsintocsv() # slow, run only when new synth runs to add to csv
allSynths = synthsfromcsv('ppaData.csv') # your csv here!
bestSynths = csvOfBest('bestSynths.csv')
makePlotDirectory()
# ### function examples
# squareAreaDelay('sky90', 'add', 32)
# oneMetricPlot('mult', 'lpower')
# freqPlot('sky90', 'mux4', 16)
# plotBestAreas('add')
# ### other functions
# makeCoefTable()
# makeEqTable()
# makeLineLegend()
# muxPlot()
# stdDevError()
for mod in modules:
plotPPA(mod, norm=False)
plotPPA(mod, aleOpt=True)
for w in widths:
freqPlot('sky90', mod, w)
freqPlot('tsmc28', mod, w)
plotPPA(mod, norm=False)
plotPPA(mod, aleOpt=True)
plt.close('all')

View File

@ -10,47 +10,64 @@ def runCommand(module, width, tech, freq):
command = "make synth DESIGN=ppa_{}_{} TECH={} DRIVE=INV FREQ={} MAXOPT=1 MAXCORES=1".format(module, width, tech, freq)
subprocess.Popen(command, shell=True)
def deleteRedundant(LoT):
def deleteRedundant(synthsToRun):
'''removes any previous runs for the current synthesis specifications'''
synthStr = "rm -rf runs/ppa_{}_{}_rv32e_{}nm_{}_*"
for synth in LoT:
for synth in synthsToRun:
bashCommand = synthStr.format(*synth)
outputCPL = subprocess.check_output(['bash','-c', bashCommand])
if __name__ == '__main__':
LoT = []
def freqSweep(module, width, tech):
synthsToRun = []
##### Run specific syntheses
# widths = [8]
# modules = ['mult', 'add', 'shiftleft', 'flop', 'comparator', 'priorityencoder', 'add', 'csa', 'mux2', 'mux4', 'mux8']
# techs = ['sky90']
# freqs = [5000]
# for w in widths:
# for module in modules:
# for tech in techs:
# for freq in freqs:
# LoT += [[module, str(w), tech, str(freq)]]
##### Run a sweep based on best delay found in existing syntheses
arr = [-8, -6, -4, -2, 0, 2, 4, 6, 8]
allSynths = synthsfromcsv('bestSynths.csv')
for synth in allSynths:
f = 1000/synth.delay
for freq in [round(f+f*x/100) for x in arr]:
LoT += [[synth.module, str(synth.width), synth.tech, str(freq)]]
##### Only do syntheses for which a run doesn't already exist
if (synth.module == module) & (synth.tech == tech) & (synth.width == width):
f = 1000/synth.delay
for freq in [round(f+f*x/100) for x in arr]:
synthsToRun += [[synth.module, str(synth.width), synth.tech, str(freq)]]
return synthsToRun
def filterRedundant(synthsToRun):
bashCommand = "find . -path '*runs/ppa*rv32e*' -prune"
output = subprocess.check_output(['bash','-c', bashCommand])
specReg = re.compile('[a-zA-Z0-9]+')
allSynths = output.decode("utf-8").split('\n')[:-1]
allSynths = [specReg.findall(oneSynth)[2:7] for oneSynth in allSynths]
allSynths = [oneSynth[0:2] + [oneSynth[3][:-2]] + [oneSynth[4]] for oneSynth in allSynths]
for synth in LoT:
output = []
for synth in synthsToRun:
if (synth not in allSynths):
synthsToRun += [synth]
output += [synth]
return output
def allCombos(widths, modules, techs, freqs):
synthsToRun = []
for w in widths:
for module in modules:
for tech in techs:
for freq in freqs:
synthsToRun += [[module, str(w), tech, str(freq)]]
return synthsToRun
if __name__ == '__main__':
##### Run specific syntheses
widths = [8, 16, 32, 64, 128]
modules = ['mult', 'add', 'shiftleft', 'flop', 'comparator', 'priorityencoder', 'add', 'csa', 'mux2', 'mux4', 'mux8']
techs = ['sky90', 'tsmc28']
freqs = [5000]
synthsToRun = allCombos(widths, modules, techs, freqs)
##### Run a sweep based on best delay found in existing syntheses
module = 'add'
width = 32
tech = 'sky90'
synthsToRun = freqSweep(module, width, tech)
##### Only do syntheses for which a run doesn't already exist
synthsToRun = filterRedundant(synthsToRun)
pool = Pool(processes=25)
pool.starmap(runCommand, synthsToRun)
pool.starmap(print, synthsToRun)

View File

@ -1,29 +0,0 @@
#!/usr/bin/bash
# Madeleine Masser-Frye mmasserfrye@hmc.edu July 2022
helpFunction()
{ echo ""
echo "Usage: $0 "
echo -e "\t--configs Synthesizes wally with configurations 32e, 32ic, 64ic, 32gc, and 64gc"
echo -e "\t--freqs NUM Synthesizes rv32e with target frequencies at NUM MHz and +/- 2, 4, 6, 8 %"
echo -e "\t--features Synthesizes rv64gc versions FPUoff, noMulDiv, noPriv, PMP0, PMP16"
exit 1 # Exit script after printing help
}
VALID_ARGS=$(getopt -o cft: --long configs,features,freqs: -- "$@")
eval set -- "$VALID_ARGS"
unset VALID_ARGS
if [[ $1 == "--" ]];
then helpFunction
elif [[ $1 == "--freqs" ]] && [[ ! $2 =~ ^[[:digit:]]+$ ]]
then echo "Argument must be an integer, target frequnecy is in MHz"
else
make clean
make del
make copy
make configs
./wallySynth.py $1 $2
./extractSummary.py
fi

View File

@ -1,64 +0,0 @@
#!/usr/bin/python3
# Shreya Sanghai (ssanghai@hmc.edu) 2/28/2022
import glob
import re
import csv
import linecache
import os
# field_names = [ 'Name', 'Critical Path Length', 'Cell Area', 'Synth Time']
# data = []
# for name in glob.glob("/home/ssanghai/riscv-wally/synthDC/runs/*/reports/wallypipelinedcore_qor.rep"):
# f = open(name, 'r')
# # trimName = re.search("runs\/(.*?)\/reports", name).group(1)
# trimName = re.search("wallypipelinedcore_(.*?)_sky9",name).group(1)
# for line in f:
# if "Critical Path Length" in line:
# pathLen = re.search("Length: *(.*?)\\n", line).group(1)
# if "Cell Area" in line:
# area = re.search("Area: *(.*?)\\n", line).group(1)
# if "Overall Compile Time" in line:
# time = re.search("Time: *(.*?)\\n", line).group(1)
# data += [{'Name' : trimName, 'Critical Path Length': pathLen, 'Cell Area' : area, 'Synth Time' :time}]
def main():
data = []
curr_dir = os.path.dirname(os.path.abspath(__file__))
output_file = os.path.join(curr_dir,"..","Summary.csv")
runs_dir = os.path.join(curr_dir,"..","runs/*/reports/wallypipelinedcore_qor.rep")
# cruns_dir = "/home/ssanghai/Desktop/cleanRun/*/reports/wallypipelinedcore_qor.rep"
search_strings = [
"Critical Path Length:", "Cell Area:", "Overall Compile Time:",
"Critical Path Clk Period:", "Critical Path Slack:"
]
for name in glob.glob(runs_dir):
f = open(name, 'r')
trimName = re.search("wallypipelinedcore_(.*?)_sky",name).group(1)
output = {'Name':trimName}
num_lines = len(f.readlines())
curr_line_index = 0
while curr_line_index < num_lines:
line = linecache.getline(name, curr_line_index)
for search_string in search_strings:
if search_string in line:
val = getVal(name,search_string,line,curr_line_index)
output[search_string] = val
curr_line_index +=1
data += [output]
with open(output_file, 'w') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=['Name'] + search_strings)
writer.writeheader()
writer.writerows(data)
def getVal(filename, search_string, line, line_index):
data = re.search(f"{search_string} *(.*?)\\n", line).group(1)
if data == '': #sometimes data is stored in two line
data = linecache.getline(filename, line_index+1).strip()
return data
if __name__=="__main__":
main()

View File

@ -1,9 +0,0 @@
#!/usr/bin/bash
# rm -r runs/*
make clean
make del
make copy
make configs
make allsynth
scripts/extractSummary.py
make del

View File

@ -1,7 +0,0 @@
#!/usr/bin/bash
# rm -r runs/*
make clean
make del
make freqs TECH=$1
scripts/extractSummary.py
make del

View File

@ -26,11 +26,11 @@ set saifpower $::env(SAIFPOWER)
set maxopt $::env(MAXOPT)
set drive $::env(DRIVE)
eval file copy -force ${cfg} {hdl/}
eval file copy -force ${cfg} {$outputDir/hdl/}
eval file copy -force ${cfg} $outputDir
eval file copy -force [glob ${hdl_src}/../config/shared/*.vh] {hdl/}
eval file copy -force [glob ${hdl_src}/*/*.sv] {hdl/}
eval file copy -force [glob ${hdl_src}/*/flop/*.sv] {hdl/}
eval file copy -force [glob ${hdl_src}/../config/shared/*.vh] {$outputDir/hdl/}
eval file copy -force [glob ${hdl_src}/*/*.sv] {$outputDir/hdl/}
eval file copy -force [glob ${hdl_src}/*/flop/*.sv] {$outputDir/hdl/}
# Only for FMA class project; comment out when done
# eval file copy -force [glob ${hdl_src}/fma/fma16.v] {hdl/}
@ -41,7 +41,7 @@ if { $saifpower == 1 } {
}
# Verilog files
set my_verilog_files [glob hdl/*]
set my_verilog_files [glob $outputDir/hdl/*]
# Set toplevel
set my_toplevel $::env(DESIGN)
@ -56,7 +56,8 @@ set vhdlout_show_unconnected_pins "true"
# Due to parameterized Verilog must use analyze/elaborate and not
# read_verilog/vhdl (change to pull in Verilog and/or VHDL)
#
define_design_lib WORK -path ./WORK
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
@ -184,8 +185,8 @@ set_fix_multiple_port_nets -all -buffer_constants
# 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
# set filename [format "%s%s%s%s" $outputDir "/unmapped/" $my_toplevel ".ddc"]
# write_file -format ddc -hierarchy -o $filename
# Compile statements
if { $maxopt == 1 } {

View File

@ -3,44 +3,62 @@
import subprocess
from multiprocessing import Pool
import time
import sys
import argparse
def runSynth(config, tech, freq):
def runSynth(config, tech, freq, maxopt):
global pool
command = "make synth DESIGN=wallypipelinedcore CONFIG={} TECH={} DRIVE=FLOP FREQ={} MAXOPT=1 MAXCORES=1".format(config, tech, freq)
command = "make synth DESIGN=wallypipelinedcore CONFIG={} TECH={} DRIVE=FLOP FREQ={} MAXOPT={} MAXCORES=1".format(config, tech, freq, maxopt)
pool.map(mask, [command])
def mask(command):
subprocess.Popen(command, shell=True)
testFreq = [3000, 10000]
def freshStart():
out = subprocess.check_output(['bash','-c', 'make fresh'])
for x in out.decode("utf-8").split('\n')[:-1]:
print(x)
return
if __name__ == '__main__':
i = 0
techs = ['sky90', 'tsmc28']
synthsToRun = []
tech = techs[i]
freq = testFreq[i]
arr = [-8, -6, -4, -2, 0, 2, 4, 6, 8]
allConfigs = ['rv32gc', 'rv32ic', 'rv64gc', 'rv64ic', 'rv32e', 'rv32i', 'rv64i']
freqVaryPct = [-20, -12, -8, -6, -4, -2, 0, 2, 4, 6, 8, 12, 20]
pool = Pool()
staggerPeriod = 60 #seconds
typeToRun = sys.argv[1]
parser = argparse.ArgumentParser()
if 'configs' in typeToRun:
parser.add_argument("-s", "--freqsweep", type=int, help = "Synthesize wally with target frequencies at given MHz and +/- 2, 4, 6, 8 %%")
parser.add_argument("-c", "--configsweep", action='store_true', help = "Synthesize wally with configurations 32e, 32ic, 64ic, 32gc, and 64gc")
parser.add_argument("-f", "--featuresweep", action='store_true', help = "Synthesize wally with features turned off progressively to visualize critical path")
parser.add_argument("-v", "--version", choices=allConfigs, help = "Configuration of wally")
parser.add_argument("-t", "--targetfreq", type=int, help = "Target frequncy")
parser.add_argument("-e", "--tech", choices=techs, help = "Technology")
parser.add_argument("-o", "--maxopt", action='store_true', help = "Turn on MAXOPT")
args = parser.parse_args()
freq = args.targetfreq if args.targetfreq else 3000
tech = args.tech if args.tech else 'sky90'
maxopt = int(args.maxopt)
if args.freqsweep:
sc = args.freqsweep
config = args.version if args.version else 'rv32e'
freshStart()
for freq in [round(sc+sc*x/100) for x in freqVaryPct]: # rv32e freq sweep
runSynth(config, tech, freq, maxopt)
if args.configsweep:
freshStart()
for config in ['rv32gc', 'rv32ic', 'rv64gc', 'rv64ic', 'rv32e']: # configs
config = config + '_orig' # until memory integrated
runSynth(config, tech, freq)
time.sleep(staggerPeriod)
elif 'features' in typeToRun:
runSynth(config, tech, freq, maxopt)
if args.featuresweep:
freshStart()
v = args.version if args.version else 'rv64gc'
for mod in ['FPUoff', 'noMulDiv', 'noPriv', 'PMP0', 'PMP16']: # rv64gc path variations
config = 'rv64gc_' + mod
runSynth(config, tech, freq)
time.sleep(staggerPeriod)
elif 'freqs' in typeToRun:
sc = int(sys.argv[2])
config = 'rv32e'
for freq in [round(sc+sc*x/100) for x in arr]: # rv32e freq sweep
runSynth(config, tech, freq)
config = v + '_' + mod
runSynth(config, tech, freq, maxopt)