This commit is contained in:
David Harris 2022-07-10 03:18:30 +00:00
commit ad92d0876e
10 changed files with 224 additions and 222 deletions

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,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

@ -14,7 +14,7 @@ def mask(command):
subprocess.Popen(command, shell=True)
def freshStart():
out = subprocess.check_output(['bash','-c', 'make clean'])
out = subprocess.check_output(['bash','-c', 'make fresh'])
for x in out.decode("utf-8").split('\n')[:-1]:
print(x)
return