2024-07-04 03:42:55 +00:00
#!/usr/bin/env python3
2023-11-08 20:00:36 +00:00
#
# Python regression test for DC
2022-05-21 09:53:26 +00:00
# Madeleine Masser-Frye mmasserfrye@hmc.edu 5/22
2023-11-08 20:00:36 +00:00
# James Stine james.stine@okstate.edu 15 October 2023
#
2022-05-21 09:53:26 +00:00
2022-06-03 21:23:04 +00:00
import scipy . optimize as opt
2022-05-17 18:29:38 +00:00
import subprocess
import csv
import re
2022-05-27 20:59:23 +00:00
from matplotlib . cbook import flatten
2022-05-17 18:29:38 +00:00
import matplotlib . pyplot as plt
2022-05-18 16:08:40 +00:00
import matplotlib . lines as lines
2022-07-09 03:24:47 +00:00
import matplotlib as mpl
2022-05-17 18:29:38 +00:00
import numpy as np
2022-05-25 20:37:54 +00:00
from collections import namedtuple
2023-03-23 16:31:17 +00:00
import sklearn . metrics as skm # depricated, will need to replace with scikit-learn
2022-07-09 03:24:47 +00:00
import os
2022-05-25 20:37:54 +00:00
2023-11-14 07:06:14 +00:00
2022-05-25 20:37:54 +00:00
def synthsfromcsv ( filename ) :
2022-05-28 04:57:18 +00:00
Synth = namedtuple ( " Synth " , " module tech width freq delay area lpower denergy " )
2023-11-14 07:06:14 +00:00
with open ( filename , newline = " " ) as csvfile :
2022-05-25 20:37:54 +00:00
csvreader = csv . reader ( csvfile )
global allSynths
2022-06-03 21:23:04 +00:00
allSynths = list ( csvreader ) [ 1 : ]
2022-05-25 20:37:54 +00:00
for i in range ( len ( allSynths ) ) :
for j in range ( len ( allSynths [ 0 ] ) ) :
2023-11-14 07:06:14 +00:00
try :
allSynths [ i ] [ j ] = int ( allSynths [ i ] [ j ] )
except :
try :
allSynths [ i ] [ j ] = float ( allSynths [ i ] [ j ] )
except :
pass
2022-05-25 20:37:54 +00:00
allSynths [ i ] = Synth ( * allSynths [ i ] )
2022-06-03 21:23:04 +00:00
return allSynths
2023-11-14 07:06:14 +00:00
2022-05-26 20:51:00 +00:00
def synthsintocsv ( ) :
2023-11-14 07:06:14 +00:00
""" writes a CSV with one line for every available synthesis
each line contains the module , tech , width , target freq , and resulting metrics
"""
2022-05-27 20:59:23 +00:00
print ( " This takes a moment... " )
2023-11-13 16:02:10 +00:00
bashCommand = " find . -path ' *runs/* ' -prune "
2023-11-14 07:06:14 +00:00
output = subprocess . check_output ( [ " bash " , " -c " , bashCommand ] )
allSynths = output . decode ( " utf-8 " ) . split ( " \n " ) [ : - 1 ]
2022-05-26 20:51:00 +00:00
2023-11-14 07:06:14 +00:00
specReg = re . compile ( " [a-zA-Z0-9]+ " )
metricReg = re . compile ( " -? \ d+ \ . \ d+[e]?[-+]? \ d* " )
2022-05-25 20:37:54 +00:00
file = open ( " ppaData.csv " , " w " )
writer = csv . writer ( file )
2023-11-14 07:06:14 +00:00
writer . writerow (
[
" Module " ,
" Tech " ,
" Width " ,
" Target Freq " ,
" Delay " ,
" Area " ,
" L Power (nW) " ,
" D energy (nJ) " ,
]
)
2022-05-17 18:29:38 +00:00
2022-05-26 20:51:00 +00:00
for oneSynth in allSynths :
2023-11-13 16:02:10 +00:00
module , width , risc , tech , freq = specReg . findall ( oneSynth ) [ 1 : 6 ]
2023-11-21 15:24:07 +00:00
tech = tech [ : - 2 ]
2022-05-26 20:51:00 +00:00
metrics = [ ]
2023-11-14 07:06:14 +00:00
for phrase in [ [ " Path Slack " , " qor " ] , [ " Design Area " , " qor " ] , [ " 100 " , " power " ] ] :
bashCommand = ' grep " {} " ' + oneSynth [ 2 : ] + " /reports/* {} * "
2022-05-26 20:51:00 +00:00
bashCommand = bashCommand . format ( * phrase )
2023-11-14 07:06:14 +00:00
try :
output = subprocess . check_output ( [ " bash " , " -c " , bashCommand ] )
except :
2022-06-03 21:23:04 +00:00
print ( module + width + tech + freq + " doesn ' t have reports " )
print ( " Consider running cleanup() first " )
2022-05-26 20:51:00 +00:00
nums = metricReg . findall ( str ( output ) )
nums = [ float ( m ) for m in nums ]
metrics + = nums
2023-11-14 07:06:14 +00:00
delay = 1000 / int ( freq ) - metrics [ 0 ]
2022-06-07 18:31:49 +00:00
area = metrics [ 1 ]
lpower = metrics [ 4 ]
2023-11-14 08:41:44 +00:00
tpower = ( metrics [ 2 ] + metrics [ 3 ] + metrics [ 4 ] * .000001 )
2023-11-14 07:06:14 +00:00
denergy = (
2023-11-14 08:41:44 +00:00
( tpower ) / int ( freq ) * 1000
2023-11-14 07:06:14 +00:00
) # (switching + internal powers)*delay, more practical units for regression coefs
2022-06-03 21:23:04 +00:00
2023-11-14 07:06:14 +00:00
if " flop " in module : # since two flops in each module
[ area , lpower , denergy ] = [ n / 2 for n in [ area , lpower , denergy ] ]
2022-05-26 20:51:00 +00:00
writer . writerow ( [ module , tech , width , freq , delay , area , lpower , denergy ] )
2022-05-25 20:37:54 +00:00
file . close ( )
2022-05-17 18:29:38 +00:00
2023-11-14 07:06:14 +00:00
2022-05-26 20:51:00 +00:00
def cleanup ( ) :
2023-11-14 07:06:14 +00:00
""" removes runs that didn ' t work """
2022-05-26 20:51:00 +00:00
bashCommand = ' grep -r " Error " runs/ppa*/reports/*qor* '
2023-11-14 07:06:14 +00:00
try :
output = subprocess . check_output ( [ " bash " , " -c " , bashCommand ] )
allSynths = output . decode ( " utf-8 " ) . split ( " \n " ) [ : - 1 ]
2022-05-26 20:51:00 +00:00
for run in allSynths :
2023-11-14 07:06:14 +00:00
run = run . split ( " MHz " ) [ 0 ]
bc = " rm -r " + run + " * "
output = subprocess . check_output ( [ " bash " , " -c " , bc ] )
except :
pass
2022-05-26 20:51:00 +00:00
2023-11-13 16:02:10 +00:00
bashCommand = " find . -path ' *runs/* ' -prune "
2023-11-14 07:06:14 +00:00
output = subprocess . check_output ( [ " bash " , " -c " , bashCommand ] )
allSynths = output . decode ( " utf-8 " ) . split ( " \n " ) [ : - 1 ]
2022-05-26 20:51:00 +00:00
for oneSynth in allSynths :
2023-11-14 07:06:14 +00:00
for phrase in [ [ " Path Length " , " qor " ] ] :
bashCommand = ' grep " {} " ' + oneSynth [ 2 : ] + " /reports/* {} * "
2022-05-26 20:51:00 +00:00
bashCommand = bashCommand . format ( * phrase )
2023-11-14 07:06:14 +00:00
try :
output = subprocess . check_output ( [ " bash " , " -c " , bashCommand ] )
except :
bc = " rm -r " + oneSynth [ 2 : ]
output = subprocess . check_output ( [ " bash " , " -c " , bc ] )
2022-05-26 20:51:00 +00:00
print ( " All cleaned up! " )
2023-11-14 07:06:14 +00:00
2022-06-15 18:28:36 +00:00
def getVals ( tech , module , var , freq = None , width = None ) :
2023-11-14 07:06:14 +00:00
""" for a specified tech, module, and variable/metric
returns a list of values for that metric in ascending width order
works at a specified target frequency or if none is given , uses the synthesis with the best achievable delay for each width
"""
2022-05-18 16:08:40 +00:00
2022-06-15 18:28:36 +00:00
if width != None :
widthsToGet = width
else :
widthsToGet = widths
2022-05-19 20:24:47 +00:00
metric = [ ]
2022-05-25 20:37:54 +00:00
widthL = [ ]
2022-05-27 20:59:23 +00:00
2023-11-14 07:06:14 +00:00
if freq != None :
2022-05-21 09:53:26 +00:00
for oneSynth in allSynths :
2023-11-14 07:06:14 +00:00
if (
( oneSynth . freq == freq )
& ( oneSynth . tech == tech )
& ( oneSynth . module == module )
& ( oneSynth . width != 1 )
) :
2022-05-25 20:37:54 +00:00
widthL + = [ oneSynth . width ]
osdict = oneSynth . _asdict ( )
metric + = [ osdict [ var ] ]
2023-11-14 07:06:14 +00:00
metric = [ x for _ , x in sorted ( zip ( widthL , metric ) ) ] # ordering
2022-05-21 09:53:26 +00:00
else :
2022-06-15 18:28:36 +00:00
for w in widthsToGet :
2022-06-07 18:31:49 +00:00
for oneSynth in bestSynths :
2023-11-14 07:06:14 +00:00
if (
( oneSynth . width == w )
& ( oneSynth . tech == tech )
& ( oneSynth . module == module )
) :
2022-06-07 18:31:49 +00:00
osdict = oneSynth . _asdict ( )
met = osdict [ var ]
metric + = [ met ]
2022-05-28 04:57:18 +00:00
return metric
2022-05-17 18:29:38 +00:00
2023-11-14 07:06:14 +00:00
2022-06-15 18:28:36 +00:00
def csvOfBest ( filename ) :
2022-06-03 21:23:04 +00:00
bestSynths = [ ]
for tech in [ x . tech for x in techSpecs ] :
for mod in modules :
for w in widths :
2023-11-14 07:06:14 +00:00
m = np . Inf # large number to start
2022-06-03 21:23:04 +00:00
best = None
2023-11-14 07:06:14 +00:00
for oneSynth in allSynths : # best achievable, rightmost green
if (
( oneSynth . width == w )
& ( oneSynth . tech == tech )
& ( oneSynth . module == mod )
) :
if ( oneSynth . delay < m ) & (
1000 / oneSynth . delay > oneSynth . freq
) :
2022-06-17 19:36:32 +00:00
m = oneSynth . delay
best = oneSynth
2022-06-15 18:28:36 +00:00
2022-06-03 21:23:04 +00:00
if ( best != None ) & ( best not in bestSynths ) :
bestSynths + = [ best ]
2023-11-14 07:06:14 +00:00
2022-06-15 18:28:36 +00:00
file = open ( filename , " w " )
2022-06-03 21:23:04 +00:00
writer = csv . writer ( file )
2023-11-14 07:06:14 +00:00
writer . writerow (
[
" Module " ,
" Tech " ,
" Width " ,
" Target Freq " ,
" Delay " ,
" Area " ,
" L Power (nW) " ,
" D energy (nJ) " ,
]
)
2022-06-03 21:23:04 +00:00
for synth in bestSynths :
writer . writerow ( list ( synth ) )
file . close ( )
2022-06-07 18:31:49 +00:00
return bestSynths
2023-11-14 07:06:14 +00:00
2022-06-10 21:11:39 +00:00
def genLegend ( fits , coefs , r2 = None , spec = None , ale = False ) :
2023-11-14 07:06:14 +00:00
""" generates a list of two legend elements (or just an equation if no r2 or spec)
labels line with fit equation and dots with r squared of the fit
"""
2022-05-19 20:24:47 +00:00
2022-06-10 21:11:39 +00:00
coefsr = [ str ( sigfig ( c , 2 ) ) for c in coefs ]
2022-06-03 23:51:34 +00:00
if ale :
2023-11-14 07:06:14 +00:00
if normAddWidth == 32 :
sub = " S "
2022-06-03 23:51:34 +00:00
elif normAddWidth != 1 :
2023-11-14 07:06:14 +00:00
print ( " Equations are wrong, check normAddWidth " )
2022-06-10 21:11:39 +00:00
else :
2023-11-14 07:06:14 +00:00
sub = " N "
eqDict = {
" c " : " " ,
" l " : sub ,
" s " : " $ " + sub + " ^2$ " ,
" g " : " $log_2$( " + sub + " ) " ,
" n " : " " + sub + " $log_2$( " + sub + " ) " ,
}
eq = " "
ind = 0
2022-06-03 21:23:04 +00:00
for k in eqDict . keys ( ) :
if k in fits :
2023-11-14 07:06:14 +00:00
if str ( coefsr [ ind ] ) != " 0 " :
eq + = " + " + coefsr [ ind ] + eqDict [ k ]
2022-06-03 21:23:04 +00:00
ind + = 1
2023-11-14 07:06:14 +00:00
eq = eq [ 3 : ] # chop off leading ' + '
2022-05-19 20:24:47 +00:00
2023-11-14 07:06:14 +00:00
if ( r2 == None ) or ( spec == None ) :
2022-06-10 21:11:39 +00:00
return eq
else :
legend_elements = [ lines . Line2D ( [ 0 ] , [ 0 ] , color = spec . color , label = eq ) ]
2023-11-14 07:06:14 +00:00
legend_elements + = [
lines . Line2D (
[ 0 ] ,
[ 0 ] ,
color = spec . color ,
ls = " " ,
marker = spec . shape ,
label = " $R^2$= " + str ( round ( r2 , 4 ) ) ,
)
]
2022-06-10 21:11:39 +00:00
return legend_elements
2022-05-19 20:24:47 +00:00
2023-11-14 07:06:14 +00:00
def oneMetricPlot (
module , widths , var , freq = None , ax = None , fits = " clsgn " , norm = True , color = None
) :
""" module: string module name
freq : int freq ( MHz )
var : string delay , area , lpower , or denergy
fits : constant , linear , square , log2 , Nlog2
plots given variable vs width for all matching syntheses with regression
"""
2022-06-07 18:31:49 +00:00
singlePlot = True
if ax or ( freq == 10 ) :
singlePlot = False
2022-05-19 20:24:47 +00:00
if ax is None :
ax = plt . gca ( )
2022-05-25 13:52:20 +00:00
fullLeg = [ ]
2022-06-03 22:53:03 +00:00
allWidths = [ ]
allMetrics = [ ]
2023-11-14 07:06:14 +00:00
ale = var != " delay " # if not delay, must be area, leakage, or energy
2022-06-10 21:11:39 +00:00
modFit = fitDict [ module ]
2022-06-09 00:07:51 +00:00
fits = modFit [ ale ]
2022-06-03 23:51:34 +00:00
2022-06-10 21:11:39 +00:00
if freq :
2023-11-14 07:06:14 +00:00
ls = " -- "
2022-06-10 21:11:39 +00:00
else :
2023-11-14 07:06:14 +00:00
ls = " - "
2022-06-10 21:11:39 +00:00
2022-05-28 04:57:18 +00:00
for spec in techSpecs :
2023-11-14 07:06:14 +00:00
# print(f"Searching for module of spec {spec} and module {module} and var {var}")
2022-05-28 04:57:18 +00:00
metric = getVals ( spec . tech , module , var , freq = freq )
2023-11-14 07:06:14 +00:00
# print(f"Found metric : {metric}")
2022-05-28 04:57:18 +00:00
if norm :
techdict = spec . _asdict ( )
norm = techdict [ var ]
2023-11-14 07:06:14 +00:00
metric = [ m / norm for m in metric ]
2022-05-27 20:59:23 +00:00
2023-11-14 07:06:14 +00:00
if len ( widths ) == len ( metric ) :
# don't include the spec if we don't have points for all widths
# print(f"Width \neq Metric")
2022-06-10 21:11:39 +00:00
xp , pred , coefs , r2 = regress ( widths , metric , fits , ale )
2022-06-09 00:07:51 +00:00
fullLeg + = genLegend ( fits , coefs , r2 , spec , ale = ale )
2022-05-30 18:54:02 +00:00
c = color if color else spec . color
ax . scatter ( widths , metric , color = c , marker = spec . shape )
2022-06-10 21:11:39 +00:00
ax . plot ( xp , pred , color = c , linestyle = ls )
2022-06-07 18:31:49 +00:00
allWidths + = widths
allMetrics + = metric
2022-05-19 20:24:47 +00:00
2023-11-14 07:06:14 +00:00
# print(f"Widths passed into regress : {allWidths}")
if len ( allWidths ) > 0 :
xp , pred , coefs , r2 = regress ( allWidths , allMetrics , fits )
ax . plot ( xp , pred , color = " orange " , linestyle = ls )
else :
xp , pred , coefs , r2 = regress ( widths , metric , fits )
ax . plot ( xp , pred , color = " orange " , linestyle = ls )
2022-06-03 22:53:03 +00:00
2022-05-28 04:57:18 +00:00
if norm :
2023-11-14 07:06:14 +00:00
ylabeldic = {
" lpower " : " Leakage Power (add32) " ,
" denergy " : " Energy/Op (add32) " ,
" area " : " Area (add32) " ,
" delay " : " Delay (FO4) " ,
}
2022-05-28 04:57:18 +00:00
else :
2023-11-14 07:06:14 +00:00
ylabeldic = {
" lpower " : " Leakage Power (nW) " ,
2023-11-14 08:41:44 +00:00
" denergy " : " Dynamic Energy (nJ) " ,
2023-11-14 07:06:14 +00:00
" area " : " Area (sq microns) " ,
" delay " : " Delay (ns) " ,
}
2022-05-27 20:59:23 +00:00
2022-05-28 04:57:18 +00:00
ax . set_ylabel ( ylabeldic [ var ] )
2022-06-15 18:28:36 +00:00
ax . set_xticks ( widths )
2022-05-19 20:24:47 +00:00
2023-11-14 07:06:14 +00:00
if singlePlot or ( var == " lpower " ) or ( var == " denergy " ) :
2022-06-15 18:28:36 +00:00
ax . set_xlabel ( " Width (bits) " )
2023-11-14 07:06:14 +00:00
if not singlePlot and ( ( var == " delay " ) or ( var == " area " ) ) :
ax . tick_params ( labelbottom = False )
2022-06-07 18:31:49 +00:00
2022-05-19 20:24:47 +00:00
if singlePlot :
2022-06-15 18:28:36 +00:00
fullLeg + = genLegend ( fits , coefs , r2 , combined , ale = ale )
2023-11-14 07:06:14 +00:00
legLoc = " upper left " if ale else " center right "
2022-06-15 18:28:36 +00:00
ax . add_artist ( ax . legend ( handles = fullLeg , loc = legLoc ) )
2023-11-14 07:06:14 +00:00
titleStr = (
" (target " + str ( freq ) + " MHz) "
if freq != None
else " (best achievable delay) "
)
2022-05-25 20:37:54 +00:00
ax . set_title ( module + titleStr )
2023-11-14 07:06:14 +00:00
plt . savefig ( " .plots/ " + module + " _ " + var + " .png " )
2022-06-07 18:31:49 +00:00
# plt.show()
2022-06-10 21:11:39 +00:00
return r2
2022-05-19 20:24:47 +00:00
2022-05-18 16:08:40 +00:00
2023-11-14 07:06:14 +00:00
def regress ( widths , var , fits = " clsgn " , ale = False ) :
""" fits a curve to the given points
returns lists of x and y values to plot that curve and coefs for the eq with r2
"""
if len ( var ) != len ( widths ) :
2023-11-14 08:41:44 +00:00
# print(
# f"There are not enough variables to match widths. Widths : {widths} Variables Found : {var}, padding to match may affect correctness (doing it anyways)\n"
# )
2023-11-14 07:06:14 +00:00
if len ( widths ) > len ( var ) :
while len ( widths ) > len ( var ) :
var . append ( 0.0 )
if len ( var ) > len ( widths ) :
while len ( var ) > len ( widths ) :
widths . append ( 0 )
# widths = [8, 16, 32, 64, 128]
# print(f"Regress var : {var}")
# print(f"Regress widths : {widths}")
2022-05-19 20:24:47 +00:00
funcArr = genFuncs ( fits )
2023-11-14 07:06:14 +00:00
xp = np . linspace ( min ( widths ) / 2 , max ( widths ) * 1.1 , 200 )
2022-06-10 21:11:39 +00:00
xpToCalc = xp
if ale :
2023-11-14 07:06:14 +00:00
widths = [ w / normAddWidth for w in widths ]
xpToCalc = [ x / normAddWidth for x in xp ]
2022-05-18 16:08:40 +00:00
mat = [ ]
for w in widths :
2022-05-19 20:24:47 +00:00
row = [ ]
for func in funcArr :
row + = [ func ( w ) ]
2022-05-18 16:08:40 +00:00
mat + = [ row ]
2023-11-14 07:06:14 +00:00
# var = [0, 1, 2, 3, 4]
y = np . array ( var , dtype = np . float64 )
2022-06-07 18:31:49 +00:00
coefs = opt . nnls ( mat , y ) [ 0 ]
2022-06-10 21:11:39 +00:00
2022-06-03 21:23:04 +00:00
yp = [ ]
for w in widths :
n = [ func ( w ) for func in funcArr ]
yp + = [ sum ( np . multiply ( coefs , n ) ) ]
r2 = skm . r2_score ( y , yp )
2022-06-07 18:31:49 +00:00
pred = [ ]
2022-06-10 21:11:39 +00:00
for x in xpToCalc :
n = [ func ( x ) for func in funcArr ]
2022-06-07 18:31:49 +00:00
pred + = [ sum ( np . multiply ( coefs , n ) ) ]
2022-05-25 13:52:20 +00:00
2022-06-09 00:07:51 +00:00
return xp , pred , coefs , r2
2022-05-25 13:52:20 +00:00
2023-11-14 07:06:14 +00:00
2022-06-09 00:07:51 +00:00
def makeCoefTable ( ) :
2023-11-14 07:06:14 +00:00
""" writes CSV with each line containing the coefficients for a regression fit
to a particular combination of module , metric ( including both techs , normalized )
"""
2022-05-18 16:08:40 +00:00
file = open ( " ppaFitting.csv " , " w " )
writer = csv . writer ( file )
2023-11-14 07:06:14 +00:00
writer . writerow (
[ " Module " , " Metric " , " Target " , " 1 " , " N " , " N^2 " , " log2(N) " , " Nlog2(N) " , " R^2 " ]
)
2022-06-09 00:07:51 +00:00
for module in modules :
2022-06-10 21:11:39 +00:00
for freq in [ 10 , None ] :
2023-11-14 07:06:14 +00:00
target = " easy " if freq else " hard "
for var in [ " delay " , " area " , " lpower " , " denergy " ] :
ale = var != " delay "
2022-06-10 21:11:39 +00:00
metL = [ ]
modFit = fitDict [ module ]
fits = modFit [ ale ]
for spec in techSpecs :
metric = getVals ( spec . tech , module , var , freq = freq )
techdict = spec . _asdict ( )
norm = techdict [ var ]
2023-11-14 07:06:14 +00:00
metL + = [ m / norm for m in metric ]
2022-06-10 21:11:39 +00:00
2023-11-14 07:06:14 +00:00
xp , pred , coefs , r2 = regress ( widths * 2 , metL , fits , ale )
2022-06-10 21:11:39 +00:00
coefs = np . ndarray . tolist ( coefs )
2023-11-14 07:06:14 +00:00
coefsToWrite = [ None ] * 5
fitTerms = " clsgn "
2022-06-10 21:11:39 +00:00
ind = 0
for i in range ( len ( fitTerms ) ) :
if fitTerms [ i ] in fits :
coefsToWrite [ i ] = coefs [ ind ]
ind + = 1
row = [ module , var , target ] + coefsToWrite + [ r2 ]
writer . writerow ( row )
file . close ( )
2023-11-14 07:06:14 +00:00
2022-06-10 21:11:39 +00:00
def sigfig ( num , figs ) :
2023-11-14 07:06:14 +00:00
return " {:g} " . format ( float ( " { :. {p} g} " . format ( num , p = figs ) ) )
2022-06-10 21:11:39 +00:00
def makeEqTable ( ) :
2023-11-14 07:06:14 +00:00
""" writes CSV with each line containing the equations for fits for each metric
to a particular module ( including both techs , normalized )
"""
2022-06-10 21:11:39 +00:00
file = open ( " ppaEquations.csv " , " w " )
writer = csv . writer ( file )
2023-11-14 07:06:14 +00:00
writer . writerow (
[
" Element " ,
" Best delay " ,
" Fast area " ,
" Fast leakage " ,
" Fast energy " ,
" Small area " ,
" Small leakage " ,
" Small energy " ,
]
)
2022-06-10 21:11:39 +00:00
for module in modules :
eqs = [ ]
for freq in [ None , 10 ] :
2023-11-14 07:06:14 +00:00
for var in [ " delay " , " area " , " lpower " , " denergy " ] :
if ( var == " delay " ) and ( freq == 10 ) :
2022-06-10 21:11:39 +00:00
pass
else :
2023-11-14 07:06:14 +00:00
ale = var != " delay "
2022-06-10 21:11:39 +00:00
metL = [ ]
modFit = fitDict [ module ]
fits = modFit [ ale ]
for spec in techSpecs :
metric = getVals ( spec . tech , module , var , freq = freq )
techdict = spec . _asdict ( )
norm = techdict [ var ]
2023-11-14 07:06:14 +00:00
metL + = [ m / norm for m in metric ]
2022-06-10 21:11:39 +00:00
2023-11-14 07:06:14 +00:00
xp , pred , coefs , r2 = regress ( widths * 2 , metL , fits , ale )
2022-06-10 21:11:39 +00:00
coefs = np . ndarray . tolist ( coefs )
eqs + = [ genLegend ( fits , coefs , ale = ale ) ]
row = [ module ] + eqs
writer . writerow ( row )
2022-05-17 18:29:38 +00:00
2022-05-18 16:08:40 +00:00
file . close ( )
2022-05-17 18:29:38 +00:00
2023-11-14 07:06:14 +00:00
def genFuncs ( fits = " clsgn " ) :
""" helper function for regress()
returns array of functions with one for each term desired in the regression fit
"""
2022-05-19 20:24:47 +00:00
funcArr = [ ]
2023-11-14 07:06:14 +00:00
if " c " in fits :
2022-05-19 20:24:47 +00:00
funcArr + = [ lambda x : 1 ]
2023-11-14 07:06:14 +00:00
if " l " in fits :
2022-05-19 20:24:47 +00:00
funcArr + = [ lambda x : x ]
2023-11-14 07:06:14 +00:00
if " s " in fits :
2022-05-19 20:24:47 +00:00
funcArr + = [ lambda x : x * * 2 ]
2023-11-14 07:06:14 +00:00
if " g " in fits :
2022-05-19 20:24:47 +00:00
funcArr + = [ lambda x : np . log2 ( x ) ]
2023-11-14 07:06:14 +00:00
if " n " in fits :
funcArr + = [ lambda x : x * np . log2 ( x ) ]
2022-05-19 20:24:47 +00:00
return funcArr
2023-11-14 07:06:14 +00:00
2022-06-07 18:31:49 +00:00
def noOutliers ( median , freqs , delays , areas ) :
2023-11-14 07:06:14 +00:00
""" returns a pared down list of freqs, delays, and areas
cuts out any syntheses in which target freq isn ' t within 75 % o f the min delay target to focus on interesting area
helper function to freqPlot ( )
"""
f = [ ]
d = [ ]
a = [ ]
2022-06-07 18:31:49 +00:00
for i in range ( len ( freqs ) ) :
2023-11-14 07:06:14 +00:00
norm = freqs [ i ] / median
if ( norm > 0.4 ) & ( norm < 1.4 ) :
2022-06-07 18:31:49 +00:00
f + = [ freqs [ i ] ]
d + = [ delays [ i ] ]
a + = [ areas [ i ] ]
2023-11-14 07:06:14 +00:00
2022-05-19 20:24:47 +00:00
return f , d , a
2023-11-14 07:06:14 +00:00
2022-05-25 13:52:20 +00:00
def freqPlot ( tech , mod , width ) :
2023-11-14 07:06:14 +00:00
""" plots delay, area, area*delay, and area*delay^2 for syntheses with specified tech, module, width """
2022-06-07 18:31:49 +00:00
2022-05-25 13:52:20 +00:00
freqsL , delaysL , areasL = ( [ [ ] , [ ] ] for i in range ( 3 ) )
2022-05-19 20:24:47 +00:00
for oneSynth in allSynths :
2023-11-14 07:06:14 +00:00
if (
( mod == oneSynth . module )
& ( width == oneSynth . width )
& ( tech == oneSynth . tech )
) :
ind = (
1000 / oneSynth . delay < oneSynth . freq
) # when delay is within target clock period
2022-05-25 20:37:54 +00:00
freqsL [ ind ] + = [ oneSynth . freq ]
delaysL [ ind ] + = [ oneSynth . delay ]
areasL [ ind ] + = [ oneSynth . area ]
2022-06-07 18:31:49 +00:00
median = np . median ( list ( flatten ( freqsL ) ) )
2023-11-14 07:06:14 +00:00
2022-06-09 00:07:51 +00:00
f , ( ax1 , ax2 ) = plt . subplots ( 2 , 1 , sharex = True )
2022-06-15 18:28:36 +00:00
for ax in ( ax1 , ax2 ) :
2023-11-14 07:06:14 +00:00
ax . ticklabel_format ( useOffset = False , style = " plain " )
2022-05-25 13:52:20 +00:00
2023-11-14 07:06:14 +00:00
for ind in [ 0 , 1 ] :
2022-05-25 13:52:20 +00:00
areas = areasL [ ind ]
delays = delaysL [ ind ]
freqs = freqsL [ ind ]
2023-11-14 07:06:14 +00:00
freqs , delays , areas = noOutliers (
median , freqs , delays , areas
) # comment out to see all syntheses
2022-05-25 13:52:20 +00:00
2023-11-14 07:06:14 +00:00
c = " blue " if ind else " green "
2022-05-25 13:52:20 +00:00
ax1 . scatter ( freqs , delays , color = c )
ax2 . scatter ( freqs , areas , color = c )
2022-05-21 09:53:26 +00:00
2023-11-14 07:06:14 +00:00
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 " ) ,
]
2022-05-19 20:24:47 +00:00
2022-05-21 09:53:26 +00:00
ax1 . legend ( handles = legend_elements )
2022-06-10 21:11:39 +00:00
width = str ( width )
2023-11-14 07:06:14 +00:00
2022-06-09 00:07:51 +00:00
ax2 . set_xlabel ( " Target Freq (MHz) " )
2023-11-14 07:06:14 +00:00
ax1 . set_ylabel ( " Delay (ns) " )
ax2 . set_ylabel ( " Area (sq microns) " )
ax1 . set_title ( mod + " _ " + width )
if ( " mux " in mod ) & ( " d " in mod ) :
2022-06-10 21:11:39 +00:00
width = mod
2023-11-14 07:06:14 +00:00
mod = " muxd "
plt . savefig ( " ./plots/freqBuckshot/ " + tech + " / " + mod + " / " + width + " .png " )
2022-05-30 19:56:47 +00:00
# plt.show()
2022-05-17 18:29:38 +00:00
2023-11-14 07:06:14 +00:00
2022-05-26 22:24:39 +00:00
def squareAreaDelay ( tech , mod , width ) :
2023-11-14 07:06:14 +00:00
""" plots delay, area, area*delay, and area*delay^2 for syntheses with specified tech, module, width """
2022-05-26 22:24:39 +00:00
global allSynths
freqsL , delaysL , areasL = ( [ [ ] , [ ] ] for i in range ( 3 ) )
for oneSynth in allSynths :
2023-11-14 07:06:14 +00:00
if (
( mod == oneSynth . module )
& ( width == oneSynth . width )
& ( tech == oneSynth . tech )
) :
ind = (
1000 / oneSynth . delay < oneSynth . freq
) # when delay is within target clock period
2022-05-26 22:24:39 +00:00
freqsL [ ind ] + = [ oneSynth . freq ]
delaysL [ ind ] + = [ oneSynth . delay ]
areasL [ ind ] + = [ oneSynth . area ]
2022-05-27 20:59:23 +00:00
f , ( ax1 ) = plt . subplots ( 1 , 1 )
ax2 = ax1 . twinx ( )
2022-05-26 22:24:39 +00:00
2023-11-14 07:06:14 +00:00
for ind in [ 0 , 1 ] :
2022-05-26 22:24:39 +00:00
areas = areasL [ ind ]
delays = delaysL [ ind ]
2022-05-27 20:59:23 +00:00
targets = freqsL [ ind ]
2023-11-14 07:06:14 +00:00
targets = [ 1000 / f for f in targets ]
targets , delays , areas = noOutliers (
targets , delays , areas
) # comment out to see all
2022-05-27 20:59:23 +00:00
if not ind :
achievedDelays = delays
2022-05-26 22:24:39 +00:00
2023-11-14 07:06:14 +00:00
c = " blue " if ind else " green "
ax1 . scatter ( targets , delays , marker = " ^ " , color = c )
ax2 . scatter ( targets , areas , marker = " s " , color = c )
2022-05-27 20:59:23 +00:00
bestAchieved = min ( achievedDelays )
2023-11-14 07:06:14 +00:00
legend_elements = [
lines . Line2D (
[ 0 ] , [ 0 ] , color = " green " , ls = " " , marker = " ^ " , label = " delay (timing achieved) "
) ,
lines . Line2D (
[ 0 ] , [ 0 ] , color = " green " , ls = " " , marker = " s " , label = " area (timing achieved) "
) ,
lines . Line2D (
[ 0 ] , [ 0 ] , color = " blue " , ls = " " , marker = " ^ " , label = " delay (timing violated) "
) ,
lines . Line2D (
[ 0 ] , [ 0 ] , color = " blue " , ls = " " , marker = " s " , label = " area (timing violated) "
) ,
]
ax2 . legend ( handles = legend_elements , loc = " upper left " )
2022-05-27 20:59:23 +00:00
ax1 . set_xlabel ( " Delay Targeted (ns) " )
ax1 . set_ylabel ( " Delay Achieved (ns) " )
2023-11-14 07:06:14 +00:00
ax2 . set_ylabel ( " Area (sq microns) " )
ax1 . set_title ( mod + " _ " + str ( width ) )
2022-05-26 22:24:39 +00:00
2022-05-27 20:59:23 +00:00
squarify ( f )
xvals = np . array ( ax1 . get_xlim ( ) )
2023-11-14 07:06:14 +00:00
frac = ( min ( flatten ( delaysL ) ) - xvals [ 0 ] ) / ( xvals [ 1 ] - xvals [ 0 ] )
areaLowerLim = min ( flatten ( areasL ) ) - 100
areaUpperLim = max ( flatten ( areasL ) ) / frac + areaLowerLim
2022-05-27 20:59:23 +00:00
ax2 . set_ylim ( [ areaLowerLim , areaUpperLim ] )
ax1 . plot ( xvals , xvals , ls = " -- " , c = " .3 " )
2023-11-14 07:06:14 +00:00
ax1 . hlines ( y = bestAchieved , xmin = xvals [ 0 ] , xmax = xvals [ 1 ] , color = " black " , ls = " -- " )
2022-05-26 22:24:39 +00:00
2023-11-14 07:06:14 +00:00
plt . savefig ( " ./plots/squareareadelay_ " + mod + " _ " + str ( width ) + " .png " )
2022-05-30 19:56:47 +00:00
# plt.show()
2022-05-26 22:24:39 +00:00
2023-11-14 07:06:14 +00:00
2022-05-27 20:59:23 +00:00
def squarify ( fig ) :
2023-11-14 07:06:14 +00:00
""" helper function for squareAreaDelay()
forces matplotlib figure to be a square
"""
2022-05-27 20:59:23 +00:00
w , h = fig . get_size_inches ( )
if w > h :
t = fig . subplotpars . top
b = fig . subplotpars . bottom
2023-11-14 07:06:14 +00:00
axs = h * ( t - b )
l = ( 1.0 - axs / w ) / 2
fig . subplots_adjust ( left = l , right = 1 - l )
2022-05-27 20:59:23 +00:00
else :
t = fig . subplotpars . right
b = fig . subplotpars . left
2023-11-14 07:06:14 +00:00
axs = w * ( t - b )
l = ( 1.0 - axs / h ) / 2
fig . subplots_adjust ( bottom = l , top = 1 - l )
def plotPPA ( mod , freq = None , norm = True , aleOpt = False ) :
""" for the module specified, plots width vs delay, area, leakage power, and dynamic energy with fits
if no freq specified , uses the synthesis with best achievable delay for each width
overlays data from both techs
"""
with mpl . rc_context ( { " figure.figsize " : ( 7 , 3.46 ) } ) :
2022-07-09 03:24:47 +00:00
fig , axs = plt . subplots ( 2 , 2 )
2022-06-10 21:11:39 +00:00
2023-11-14 07:06:14 +00:00
arr = [ [ " delay " , " area " ] , [ " lpower " , " denergy " ] ]
2022-06-10 21:11:39 +00:00
freqs = [ freq ]
2023-11-14 07:06:14 +00:00
if aleOpt :
freqs + = [ 10 ]
2022-06-10 21:11:39 +00:00
for i in [ 0 , 1 ] :
for j in [ 0 , 1 ] :
leg = [ ]
for f in freqs :
2023-11-14 07:06:14 +00:00
if ( arr [ i ] [ j ] == " delay " ) and ( f == 10 ) :
2022-06-10 21:11:39 +00:00
pass
else :
2023-11-14 07:06:14 +00:00
# print(f"Pasing in widths {widths}")
r2 = oneMetricPlot (
mod , widths , arr [ i ] [ j ] , ax = axs [ i , j ] , freq = f , norm = norm
)
ls = " -- " if f else " - "
leg + = [
lines . Line2D (
[ 0 ] ,
[ 0 ] ,
color = " orange " ,
label = " $R^2$= " + str ( round ( r2 , 4 ) ) ,
linestyle = ls ,
)
]
if ( mod in [ " flop " , " csa " ] ) & ( arr [ i ] [ j ] == " delay " ) :
2022-06-15 18:28:36 +00:00
axs [ i , j ] . set_ylim ( ymin = 0 )
ytop = axs [ i , j ] . get_ylim ( ) [ 1 ]
2023-11-14 07:06:14 +00:00
axs [ i , j ] . set_ylim ( ymax = 1.1 * ytop )
2022-06-15 18:28:36 +00:00
else :
axs [ i , j ] . legend ( handles = leg , handlelength = 1.5 )
2023-11-14 07:06:14 +00:00
titleStr = " (target " + str ( freq ) + " MHz) " if freq != None else " "
2022-05-21 09:53:26 +00:00
plt . suptitle ( mod + titleStr )
2023-11-14 07:06:14 +00:00
plt . tight_layout ( pad = 0.05 , w_pad = 1 , h_pad = 0.5 , rect = ( 0 , 0 , 1 , 0.97 ) )
2022-06-09 00:07:51 +00:00
2023-11-14 07:06:14 +00:00
if freq != 10 :
n = " normalized " if norm else " unnormalized "
saveStr = " ./plots/ " + n + " / " + mod + " _ " + " .png "
print ( f " Saving to { saveStr } " )
2022-06-10 21:11:39 +00:00
plt . savefig ( saveStr )
2022-05-30 19:56:47 +00:00
# plt.show()
2022-05-30 18:54:02 +00:00
2023-11-14 07:06:14 +00:00
2022-06-17 19:36:32 +00:00
def makeLineLegend ( ) :
2023-11-14 07:06:14 +00:00
""" generates legend to accompany normalized plots """
plt . rcParams [ " figure.figsize " ] = ( 5.5 , 0.3 )
2022-06-15 18:28:36 +00:00
fig = plt . figure ( )
2023-11-14 07:06:14 +00:00
fullLeg = [ lines . Line2D ( [ 0 ] , [ 0 ] , color = " black " , label = " fastest " , linestyle = " - " ) ]
fullLeg + = [ lines . Line2D ( [ 0 ] , [ 0 ] , color = " black " , label = " smallest " , linestyle = " -- " ) ]
fullLeg + = [ lines . Line2D ( [ 0 ] , [ 0 ] , color = " blue " , label = " tsmc28 " , marker = " ^ " ) ]
fullLeg + = [ lines . Line2D ( [ 0 ] , [ 0 ] , color = " blue " , label = " tsmc28psyn " , marker = " x " ) ]
fullLeg + = [ lines . Line2D ( [ 0 ] , [ 0 ] , color = " green " , label = " sky90 " , marker = " o " ) ]
fullLeg + = [ lines . Line2D ( [ 0 ] , [ 0 ] , color = " purple " , label = " sky130 " , marker = " + " ) ]
fullLeg + = [ lines . Line2D ( [ 0 ] , [ 0 ] , color = " orange " , label = " combined " , marker = " _ " ) ]
fig . legend ( handles = fullLeg , ncol = 5 , handlelength = 1.4 , loc = " center " )
saveStr = " ./plots/legend.png "
2022-06-15 18:28:36 +00:00
plt . savefig ( saveStr )
2023-11-14 07:06:14 +00:00
def muxPlot ( fits = " clsgn " , norm = True ) :
""" module: string module name
freq : int freq ( MHz )
var : string delay , area , lpower , or denergy
fits : constant , linear , square , log2 , Nlog2
plots given variable vs width for all matching syntheses with regression
"""
2022-06-15 18:28:36 +00:00
ax = plt . gca ( )
inputs = [ 2 , 4 , 8 ]
2023-11-14 07:06:14 +00:00
allInputs = inputs * 2
2022-06-15 18:28:36 +00:00
fullLeg = [ ]
2023-11-14 07:06:14 +00:00
for crit in [ " data " , " control " ] :
2022-06-15 18:28:36 +00:00
allMetrics = [ ]
2023-11-14 07:06:14 +00:00
muxes = [ " mux2 " , " mux4 " , " mux8 " ]
2022-06-15 18:28:36 +00:00
2023-11-14 07:06:14 +00:00
if crit == " data " :
ls = " -- "
muxes = [ m + " d " for m in muxes ]
elif crit == " control " :
ls = " - "
2022-06-15 18:28:36 +00:00
for spec in techSpecs :
metric = [ ]
for module in muxes :
2023-11-14 07:06:14 +00:00
metric + = getVals ( spec . tech , module , " delay " , width = [ 1 ] )
2022-06-15 18:28:36 +00:00
if norm :
techdict = spec . _asdict ( )
2023-11-14 07:06:14 +00:00
norm = techdict [ " delay " ]
metric = [ m / norm for m in metric ]
2022-06-17 19:36:32 +00:00
# print(spec.tech, ' ', metric)
2022-06-15 18:28:36 +00:00
2023-11-14 07:06:14 +00:00
if (
len ( metric ) == 3
) : # don't include the spec if we don't have points for all
2022-06-15 18:28:36 +00:00
xp , pred , coefs , r2 = regress ( inputs , metric , fits , ale = False )
ax . scatter ( inputs , metric , color = spec . color , marker = spec . shape )
ax . plot ( xp , pred , color = spec . color , linestyle = ls )
allMetrics + = metric
xp , pred , coefs , r2 = regress ( allInputs , allMetrics , fits )
2023-11-14 08:41:44 +00:00
ax . plot ( xp , pred , color = " red " , linestyle = ls )
fullLeg + = [ lines . Line2D ( [ 0 ] , [ 0 ] , color = " red " , label = crit , linestyle = ls ) ]
2023-11-14 07:06:14 +00:00
ax . set_ylabel ( " Delay (FO4) " )
2022-06-15 18:28:36 +00:00
ax . set_xticks ( inputs )
ax . set_xlabel ( " Number of inputs " )
2023-11-14 07:06:14 +00:00
ax . set_title ( " mux timing " )
ax . legend ( handles = fullLeg )
plt . savefig ( " ./plots/mux.png " )
2022-06-15 18:28:36 +00:00
2022-06-17 19:36:32 +00:00
def stdDevError ( ) :
2023-11-14 07:06:14 +00:00
""" calculates std deviation and error for paper-writing purposes """
for var in [ " delay " , " area " , " lpower " , " denergy " ] :
2022-06-17 19:36:32 +00:00
errlist = [ ]
for module in modules :
2023-11-14 07:06:14 +00:00
ale = var != " delay "
2022-06-17 19:36:32 +00:00
metL = [ ]
modFit = fitDict [ module ]
fits = modFit [ ale ]
funcArr = genFuncs ( fits )
for spec in techSpecs :
metric = getVals ( spec . tech , module , var )
techdict = spec . _asdict ( )
norm = techdict [ var ]
2023-11-14 07:06:14 +00:00
metL + = [ m / norm for m in metric ]
2022-06-17 19:36:32 +00:00
if ale :
2023-11-14 07:06:14 +00:00
ws = [ w / normAddWidth for w in widths ]
2022-06-17 19:36:32 +00:00
else :
ws = widths
2023-11-14 07:06:14 +00:00
ws = ws * 2
2022-06-17 19:36:32 +00:00
mat = [ ]
for w in ws :
row = [ ]
for func in funcArr :
row + = [ func ( w ) ]
mat + = [ row ]
2023-11-14 07:06:14 +00:00
2022-06-17 19:36:32 +00:00
y = np . array ( metL , dtype = np . float )
coefs = opt . nnls ( mat , y ) [ 0 ]
yp = [ ]
for w in ws :
n = [ func ( w ) for func in funcArr ]
yp + = [ sum ( np . multiply ( coefs , n ) ) ]
2023-11-14 07:06:14 +00:00
if ( var == " delay " ) & ( module == " flop " ) :
2022-06-17 19:36:32 +00:00
pass
2023-11-14 07:06:14 +00:00
elif ( module == " mult " ) & ale :
2022-06-17 19:36:32 +00:00
pass
else :
for i in range ( len ( y ) ) :
2023-11-14 07:06:14 +00:00
errlist + = [ abs ( y [ i ] / yp [ i ] - 1 ) ]
2022-06-17 19:36:32 +00:00
# print(module, ' ', var, ' ', np.mean(errlist[-10:]))
2023-11-14 07:06:14 +00:00
2022-06-17 19:36:32 +00:00
avgErr = np . mean ( errlist )
stdv = np . std ( errlist )
2023-11-14 07:06:14 +00:00
print ( var , " " , avgErr , " " , stdv )
2022-06-17 19:36:32 +00:00
2022-07-09 03:24:47 +00:00
def makePlotDirectory ( ) :
2023-11-14 07:06:14 +00:00
""" creates plots directory in same level as this script to store plots in """
2022-07-09 03:24:47 +00:00
current_directory = os . getcwd ( )
2023-11-14 07:06:14 +00:00
final_directory = os . path . join ( current_directory , " plots " )
2022-07-09 03:24:47 +00:00
if not os . path . exists ( final_directory ) :
os . makedirs ( final_directory )
os . chdir ( final_directory )
2023-11-14 07:06:14 +00:00
for folder in [ " freqBuckshot " , " normalized " , " unnormalized " ] :
2022-07-09 03:24:47 +00:00
new_directory = os . path . join ( final_directory , folder )
if not os . path . exists ( new_directory ) :
os . makedirs ( new_directory )
os . chdir ( new_directory )
2023-11-14 07:06:14 +00:00
if " freq " in folder :
for tech in [ " sky90 " , " sky130 " , " tsmc28 " , " tsmc28psyn " ] :
2022-07-09 03:24:47 +00:00
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 )
2023-11-14 07:06:14 +00:00
os . chdir ( " .. " )
2022-06-07 18:31:49 +00:00
2023-11-14 07:06:14 +00:00
os . chdir ( current_directory )
2022-06-07 18:31:49 +00:00
2023-11-13 08:39:25 +00:00
2023-11-14 07:06:14 +00:00
if __name__ == " __main__ " :
##############################
# set up stuff, global variables
widths = [ 8 , 16 , 32 , 64 , 128 ]
2023-11-14 08:41:44 +00:00
modules = [ " adder " ]
2023-11-14 07:06:14 +00:00
normAddWidth = 32 # divisor to use with N since normalizing to add_32
fitDict = {
" adder " : [ " cg " , " l " , " l " ] ,
" mul " : [ " cg " , " s " , " s " ] ,
" comparator " : [ " cg " , " l " , " l " ] ,
" csa " : [ " c " , " l " , " l " ] ,
" shifter " : [ " cg " , " l " , " ln " ] ,
" flop " : [ " c " , " l " , " l " ] ,
" binencoder " : [ " cg " , " l " , " l " ] ,
}
fitDict . update ( dict . fromkeys ( [ " mux2 " , " mux4 " , " mux8 " ] , [ " cg " , " l " , " l " ] ) )
TechSpec = namedtuple ( " TechSpec " , " tech color shape delay area lpower denergy " )
# FO4 delay information information
techSpecs = [
2023-11-14 08:41:44 +00:00
#["sky90", "green", "o", 43.2e-3, 1440.600027, 714.057, 0.658022690438],
2023-11-14 07:06:14 +00:00
# Area/Lpower/Denergy needs to be corrected here (jes)
[ " sky130 " , " orange " , " o " , 99.5e-3 , 1440.600027 , 714.057 , 0.658022690438 ] ,
# ["tsmc28", "blue", "^", 12.2e-3, 209.286002, 1060.0, 0.08153281695882594],
# ["tsmc28psyn", "blue", "^", 12.2e-3, 209.286002, 1060.0, 0.08153281695882594],
]
techSpecs = [ TechSpec ( * t ) for t in techSpecs ]
2023-11-14 08:41:44 +00:00
combined = TechSpec ( " combined fit " , " red " , " _ " , 0 , 0 , 0 , 0 )
2022-06-07 18:31:49 +00:00
##############################
2022-06-03 21:23:04 +00:00
2022-06-07 18:31:49 +00:00
# cleanup() # run to remove garbage synth runs
2023-11-14 07:06:14 +00:00
synthsintocsv ( ) # slow, run only when new synth runs to add to csv
allSynths = synthsfromcsv ( " ppaData.csv " ) # your csv here!
bestSynths = csvOfBest ( " bestSynths.csv " )
makePlotDirectory ( )
2022-05-18 16:08:40 +00:00
2022-07-09 03:24:47 +00:00
# ### other functions
2022-06-09 00:07:51 +00:00
# makeCoefTable()
2022-06-10 21:11:39 +00:00
# makeEqTable()
2022-06-15 18:28:36 +00:00
# muxPlot()
2022-06-17 19:36:32 +00:00
# stdDevError()
2023-11-14 07:06:14 +00:00
for mod in modules :
for w in widths :
2023-11-14 08:41:44 +00:00
#freqPlot('sky90', mod, w)
freqPlot ( " sky130 " , mod , w )
2023-11-14 07:06:14 +00:00
# freqPlot('tsmc28', mod, w)
# freqPlot('tsmc28psyn', mod, w)
plotPPA ( mod , norm = False )
2023-11-14 08:41:44 +00:00
plotPPA ( mod , aleOpt = True )
2023-11-14 07:06:14 +00:00
plt . close ( " all " )