mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
fixed synth scraping, best delay plotting
This commit is contained in:
parent
b13c3d5385
commit
e76986b31e
@ -24,60 +24,69 @@ def synthsfromcsv(filename):
|
|||||||
except: pass
|
except: pass
|
||||||
allSynths[i] = Synth(*allSynths[i])
|
allSynths[i] = Synth(*allSynths[i])
|
||||||
|
|
||||||
def synthsintocsv(mod=None, width=None):
|
def synthsintocsv():
|
||||||
''' writes a CSV with one line for every available synthesis
|
''' writes a CSV with one line for every available synthesis
|
||||||
each line contains the module, tech, width, target freq, and resulting metrics
|
each line contains the module, tech, width, target freq, and resulting metrics
|
||||||
'''
|
'''
|
||||||
specStr = ''
|
|
||||||
if mod != None:
|
|
||||||
specStr = mod
|
|
||||||
if width != None:
|
|
||||||
specStr += ('_'+str(width))
|
|
||||||
specStr += '*'
|
|
||||||
|
|
||||||
bashCommand = "grep 'Critical Path Length' runs/ppa_{}/reports/*qor*".format(specStr)
|
bashCommand = "find . -path '*runs/ppa*rv32e*' -prune"
|
||||||
outputCPL = subprocess.check_output(['bash','-c', bashCommand])
|
output = subprocess.check_output(['bash','-c', bashCommand])
|
||||||
linesCPL = outputCPL.decode("utf-8").split('\n')[:-1]
|
allSynths = output.decode("utf-8").split('\n')[:-1]
|
||||||
|
|
||||||
bashCommand = "grep 'Design Area' runs/ppa_{}/reports/*qor*".format(specStr)
|
specReg = re.compile('[a-zA-Z0-9]+')
|
||||||
outputDA = subprocess.check_output(['bash','-c', bashCommand])
|
metricReg = re.compile('\d+\.\d+[e]?[-+]?\d*')
|
||||||
linesDA = outputDA.decode("utf-8").split('\n')[:-1]
|
|
||||||
|
|
||||||
bashCommand = "grep '100' runs/ppa_{}/reports/*power*".format(specStr)
|
|
||||||
outputP = subprocess.check_output(['bash','-c', bashCommand])
|
|
||||||
linesP = outputP.decode("utf-8").split('\n')[:-1]
|
|
||||||
|
|
||||||
cpl = re.compile('\d{1}\.\d{6}')
|
|
||||||
f = re.compile('_\d*_MHz')
|
|
||||||
wm = re.compile('ppa_\w*_\d*_qor')
|
|
||||||
da = re.compile('\d*\.\d{6}')
|
|
||||||
p = re.compile('\d+\.\d+[e-]*\d+')
|
|
||||||
t = re.compile('[a-zA-Z0-9]+nm')
|
|
||||||
|
|
||||||
file = open("ppaData.csv", "w")
|
file = open("ppaData.csv", "w")
|
||||||
writer = csv.writer(file)
|
writer = csv.writer(file)
|
||||||
writer.writerow(['Module', 'Tech', 'Width', 'Target Freq', 'Delay', 'Area', 'L Power (nW)', 'D energy (mJ)'])
|
writer.writerow(['Module', 'Tech', 'Width', 'Target Freq', 'Delay', 'Area', 'L Power (nW)', 'D energy (mJ)'])
|
||||||
|
|
||||||
for i in range(len(linesCPL)):
|
for oneSynth in allSynths:
|
||||||
line = linesCPL[i]
|
module, width, risc, tech, freq = specReg.findall(oneSynth)[2:7]
|
||||||
mwm = wm.findall(line)[0][4:-4].split('_')
|
tech = tech[:-2]
|
||||||
freq = int(f.findall(line)[0][1:-4])
|
metrics = []
|
||||||
delay = float(cpl.findall(line)[0])
|
for phrase in [['Path Length', 'qor'], ['Design Area', 'qor'], ['100', 'power']]:
|
||||||
area = float(da.findall(linesDA[i])[0])
|
bashCommand = 'grep "{}" '+ oneSynth[2:]+'/reports/*{}*'
|
||||||
mod = mwm[0]
|
bashCommand = bashCommand.format(*phrase)
|
||||||
width = int(mwm[1])
|
try: output = subprocess.check_output(['bash','-c', bashCommand])
|
||||||
tech = t.findall(line)[0][:-2]
|
except: print("At least one synth run doesn't have reports, try cleanup() first")
|
||||||
try: #fix
|
nums = metricReg.findall(str(output))
|
||||||
power = p.findall(linesP[i])
|
nums = [float(m) for m in nums]
|
||||||
lpower = float(power[2])
|
metrics += nums
|
||||||
denergy = float(power[1])*delay
|
delay = metrics[0]
|
||||||
except:
|
area = metrics[1]
|
||||||
lpower = 0
|
lpower = metrics[4]
|
||||||
denergy = 0
|
denergy = (metrics[2] + metrics[3])*delay # (switching + internal powers)*delay
|
||||||
|
|
||||||
writer.writerow([mod, tech, width, freq, delay, area, lpower, denergy])
|
writer.writerow([module, tech, width, freq, delay, area, lpower, denergy])
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
|
def cleanup():
|
||||||
|
''' removes runs that didn't work
|
||||||
|
'''
|
||||||
|
bashCommand = 'grep -r "Error" runs/ppa*/reports/*qor*'
|
||||||
|
try:
|
||||||
|
output = subprocess.check_output(['bash','-c', bashCommand])
|
||||||
|
allSynths = output.decode("utf-8").split('\n')[:-1]
|
||||||
|
for run in allSynths:
|
||||||
|
run = run.split('MHz')[0]
|
||||||
|
bc = 'rm -r '+ run + '*'
|
||||||
|
output = subprocess.check_output(['bash','-c', bc])
|
||||||
|
except: pass
|
||||||
|
|
||||||
|
bashCommand = "find . -path '*runs/ppa*rv32e*' -prune"
|
||||||
|
output = subprocess.check_output(['bash','-c', bashCommand])
|
||||||
|
allSynths = output.decode("utf-8").split('\n')[:-1]
|
||||||
|
for oneSynth in allSynths:
|
||||||
|
for phrase in [['Path Length', 'qor'], ['Design Area', 'qor'], ['100', 'power']]:
|
||||||
|
bashCommand = 'grep "{}" '+ oneSynth[2:]+'/reports/*{}*'
|
||||||
|
bashCommand = bashCommand.format(*phrase)
|
||||||
|
try: output = subprocess.check_output(['bash','-c', bashCommand])
|
||||||
|
except:
|
||||||
|
bc = 'rm -r '+ oneSynth[2:]
|
||||||
|
try: output = subprocess.check_output(['bash','-c', bc])
|
||||||
|
except: pass
|
||||||
|
print("All cleaned up!")
|
||||||
|
|
||||||
def getVals(tech, module, var, freq=None):
|
def getVals(tech, module, var, freq=None):
|
||||||
''' for a specified tech, module, and variable/metric
|
''' for a specified tech, module, and variable/metric
|
||||||
returns a list of values for that metric in ascending width order with the appropriate units
|
returns a list of values for that metric in ascending width order with the appropriate units
|
||||||
@ -112,7 +121,8 @@ def getVals(tech, module, var, freq=None):
|
|||||||
m = oneSynth.delay
|
m = oneSynth.delay
|
||||||
osdict = oneSynth._asdict()
|
osdict = oneSynth._asdict()
|
||||||
met = osdict[var]
|
met = osdict[var]
|
||||||
metric += [met]
|
try: metric += [met]
|
||||||
|
except: pass
|
||||||
|
|
||||||
if ('flop' in module) & (var == 'area'):
|
if ('flop' in module) & (var == 'area'):
|
||||||
metric = [m/2 for m in metric] # since two flops in each module
|
metric = [m/2 for m in metric] # since two flops in each module
|
||||||
@ -144,9 +154,9 @@ def genLegend(fits, coefs, r2, techcolor):
|
|||||||
eq += " + " + coefsr[ind] + "*Nlog2(N)"
|
eq += " + " + coefsr[ind] + "*Nlog2(N)"
|
||||||
ind += 1
|
ind += 1
|
||||||
|
|
||||||
tech, c = techcolor
|
tech, c, m = techcolor
|
||||||
legend_elements = [lines.Line2D([0], [0], color=c, label=eq),
|
legend_elements = [lines.Line2D([0], [0], color=c, label=eq),
|
||||||
lines.Line2D([0], [0], color=c, ls='', marker='o', label=tech +' $R^2$='+ str(round(r2, 4)))]
|
lines.Line2D([0], [0], color=c, ls='', marker=m, label=tech +' $R^2$='+ str(round(r2, 4)))]
|
||||||
return legend_elements
|
return legend_elements
|
||||||
|
|
||||||
def oneMetricPlot(module, var, freq=None, ax=None, fits='clsgn'):
|
def oneMetricPlot(module, var, freq=None, ax=None, fits='clsgn'):
|
||||||
@ -167,13 +177,13 @@ def oneMetricPlot(module, var, freq=None, ax=None, fits='clsgn'):
|
|||||||
global techcolors
|
global techcolors
|
||||||
global widths
|
global widths
|
||||||
for combo in techcolors:
|
for combo in techcolors:
|
||||||
tech, c = combo
|
tech, c, m = combo
|
||||||
metric, units = getVals(tech, module, var, freq=freq)
|
metric, units = getVals(tech, module, var, freq=freq)
|
||||||
if len(metric) == 5:
|
if len(metric) == 5:
|
||||||
xp, pred, leg = regress(widths, metric, combo, fits)
|
xp, pred, leg = regress(widths, metric, combo, fits)
|
||||||
fullLeg += leg
|
fullLeg += leg
|
||||||
|
|
||||||
ax.scatter(widths, metric, color=c)
|
ax.scatter(widths, metric, color=c, marker=m)
|
||||||
ax.plot(xp, pred, color=c)
|
ax.plot(xp, pred, color=c)
|
||||||
|
|
||||||
ax.legend(handles=fullLeg)
|
ax.legend(handles=fullLeg)
|
||||||
@ -183,7 +193,7 @@ def oneMetricPlot(module, var, freq=None, ax=None, fits='clsgn'):
|
|||||||
ax.set_ylabel(str.title(var) + units)
|
ax.set_ylabel(str.title(var) + units)
|
||||||
|
|
||||||
if singlePlot:
|
if singlePlot:
|
||||||
titleStr = " (target " + str(freq)+ "MHz)" if freq != None else " (min delay)"
|
titleStr = " (target " + str(freq)+ "MHz)" if freq != None else " (best delay)"
|
||||||
ax.set_title(module + titleStr)
|
ax.set_title(module + titleStr)
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
@ -266,8 +276,6 @@ def noOutliers(freqs, delays, areas):
|
|||||||
f=[]
|
f=[]
|
||||||
d=[]
|
d=[]
|
||||||
a=[]
|
a=[]
|
||||||
|
|
||||||
try:
|
|
||||||
ind = delays.index(min(delays))
|
ind = delays.index(min(delays))
|
||||||
med = freqs[ind]
|
med = freqs[ind]
|
||||||
for i in range(len(freqs)):
|
for i in range(len(freqs)):
|
||||||
@ -276,7 +284,6 @@ def noOutliers(freqs, delays, areas):
|
|||||||
f += [freqs[i]]
|
f += [freqs[i]]
|
||||||
d += [delays[i]]
|
d += [delays[i]]
|
||||||
a += [areas[i]]
|
a += [areas[i]]
|
||||||
except: pass
|
|
||||||
|
|
||||||
return f, d, a
|
return f, d, a
|
||||||
|
|
||||||
@ -292,7 +299,7 @@ def freqPlot(tech, mod, width):
|
|||||||
delaysL[ind] += [oneSynth.delay]
|
delaysL[ind] += [oneSynth.delay]
|
||||||
areasL[ind] += [oneSynth.area]
|
areasL[ind] += [oneSynth.area]
|
||||||
|
|
||||||
f, (ax1, ax2, ax3, ax4, ax5) = plt.subplots(5, 1, sharex=True)
|
f, (ax1, ax2, ax3, ax4) = plt.subplots(4, 1, sharex=True)
|
||||||
|
|
||||||
for ind in [0,1]:
|
for ind in [0,1]:
|
||||||
areas = areasL[ind]
|
areas = areasL[ind]
|
||||||
@ -300,17 +307,15 @@ def freqPlot(tech, mod, width):
|
|||||||
freqs = freqsL[ind]
|
freqs = freqsL[ind]
|
||||||
|
|
||||||
if ('flop' in mod): areas = [m/2 for m in areas] # since two flops in each module
|
if ('flop' in mod): areas = [m/2 for m in areas] # since two flops in each module
|
||||||
freqs, delays, areas = noOutliers(freqs, delays, areas)
|
freqs, delays, areas = noOutliers(freqs, delays, areas) # comment out to see all syntheses
|
||||||
|
|
||||||
c = 'blue' if ind else 'green'
|
c = 'blue' if ind else 'green'
|
||||||
adprod = adprodpow(areas, delays, 2)
|
adprod = adprodpow(areas, delays, 1)
|
||||||
adpow = adprodpow(areas, delays, 3)
|
adpow = adprodpow(areas, delays, 2)
|
||||||
adpow2 = adprodpow(areas, delays, 4)
|
|
||||||
ax1.scatter(freqs, delays, color=c)
|
ax1.scatter(freqs, delays, color=c)
|
||||||
ax2.scatter(freqs, areas, color=c)
|
ax2.scatter(freqs, areas, color=c)
|
||||||
ax3.scatter(freqs, adprod, color=c)
|
ax3.scatter(freqs, adprod, color=c)
|
||||||
ax4.scatter(freqs, adpow, color=c)
|
ax4.scatter(freqs, adpow, color=c)
|
||||||
ax5.scatter(freqs, adpow2, color=c)
|
|
||||||
|
|
||||||
legend_elements = [lines.Line2D([0], [0], color='green', ls='', marker='o', label='timing achieved'),
|
legend_elements = [lines.Line2D([0], [0], color='green', ls='', marker='o', label='timing achieved'),
|
||||||
lines.Line2D([0], [0], color='blue', ls='', marker='o', label='slack violated')]
|
lines.Line2D([0], [0], color='blue', ls='', marker='o', label='slack violated')]
|
||||||
@ -341,22 +346,26 @@ def plotPPA(mod, freq=None):
|
|||||||
overlays data from both techs
|
overlays data from both techs
|
||||||
'''
|
'''
|
||||||
fig, axs = plt.subplots(2, 2)
|
fig, axs = plt.subplots(2, 2)
|
||||||
oneMetricPlot(mod, 'delay', ax=axs[0,0], fits='clg', freq=freq)
|
oneMetricPlot(mod, 'delay', ax=axs[0,0], fits='cg', freq=freq)
|
||||||
oneMetricPlot(mod, 'area', ax=axs[0,1], fits='s', freq=freq)
|
oneMetricPlot(mod, 'area', ax=axs[0,1], fits='s', freq=freq)
|
||||||
oneMetricPlot(mod, 'lpower', ax=axs[1,0], fits='c', freq=freq)
|
oneMetricPlot(mod, 'lpower', ax=axs[1,0], fits='s', freq=freq)
|
||||||
oneMetricPlot(mod, 'denergy', ax=axs[1,1], fits='s', freq=freq)
|
oneMetricPlot(mod, 'denergy', ax=axs[1,1], fits='s', freq=freq)
|
||||||
titleStr = " (target " + str(freq)+ "MHz)" if freq != None else " (min delay)"
|
titleStr = " (target " + str(freq)+ "MHz)" if freq != None else " (best delay)"
|
||||||
plt.suptitle(mod + titleStr)
|
plt.suptitle(mod + titleStr)
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
Synth = namedtuple("Synth", "module tech width freq delay area lpower denergy")
|
if __name__ == '__main__':
|
||||||
techcolors = [['sky90', 'green'], ['tsmc28', 'blue']]
|
|
||||||
widths = [8, 16, 32, 64, 128]
|
|
||||||
synthsintocsv()
|
|
||||||
|
|
||||||
synthsfromcsv('ppaData.csv') # your csv here!
|
# set up stuff, global variables
|
||||||
|
Synth = namedtuple("Synth", "module tech width freq delay area lpower denergy")
|
||||||
|
techcolors = [['sky90', 'green', 'o'], ['tsmc28', 'blue', '^']] # add another list here for gf32
|
||||||
|
widths = [8, 16, 32, 64, 128]
|
||||||
|
|
||||||
### examples
|
# synthsintocsv() # slow, run only when new synth runs to add to csv
|
||||||
# oneMetricPlot('add', 'delay')
|
|
||||||
#freqPlot('sky90', 'add', 8)
|
synthsfromcsv('ppaData.csv') # your csv here!
|
||||||
#plotPPA('add')
|
|
||||||
|
### examples
|
||||||
|
oneMetricPlot('add', 'delay')
|
||||||
|
freqPlot('sky90', 'comparator', 16)
|
||||||
|
plotPPA('add')
|
2429
synthDC/ppaData.csv
2429
synthDC/ppaData.csv
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user