adapted shifter in ppa.sv for widths beside 32 and 64

modified plotting and regression in ppaAnalyze.py
This commit is contained in:
mmasserfrye 2022-05-18 16:08:40 +00:00
parent 5c22bec023
commit 12c42cd507
4 changed files with 118 additions and 44 deletions

View File

@ -281,20 +281,21 @@ module ppa_shifter #(parameter WIDTH=32) (
// For RV64, 32 and 64-bit shifts are needed, with sign extension. // For RV64, 32 and 64-bit shifts are needed, with sign extension.
// funnel shifter input (see CMOS VLSI Design 4e Section 11.8.1, note Table 11.11 shift types wrong) // funnel shifter input (see CMOS VLSI Design 4e Section 11.8.1, note Table 11.11 shift types wrong)
if (WIDTH == 64) begin:shifter // RV64 fix what about 128 if (WIDTH == 64 | WIDTH ==128) begin:shifter // RV64 or 128
always_comb // funnel mux always_comb // funnel mux
if (W64) begin // 32-bit shifts if (W64) begin // 32-bit shifts
if (Right) if (Right)
if (Arith) z = {64'b0, {31{A[31]}}, A[31:0]}; if (Arith) z = {{WIDTH{1'b0}}, {WIDTH/2 -1{A[WIDTH/2 -1]}}, A[WIDTH/2 -1:0]};
else z = {95'b0, A[31:0]}; else z = {{WIDTH*3/2-1{1'b0}}, A[WIDTH/2 -1:0]};
else z = {32'b0, A[31:0], 63'b0}; else z = {{WIDTH/2{1'b0}}, A[WIDTH/2 -1:0], {WIDTH-1{1'b0}}};
end else begin end else begin
if (Right) if (Right)
if (Arith) z = {{63{A[63]}}, A}; if (Arith) z = {{WIDTH-1{A[WIDTH-1]}}, A};
else z = {63'b0, A}; else z = {{WIDTH-1{1'b0}}, A};
else z = {A, 63'b0}; else z = {A, {WIDTH-1{1'b0}}};
end end
end else begin:shifter // RV32, assign amttrunc = W64 ? {1'b0, Amt[$clog2(WIDTH)-2:0]} : Amt; // 32 or 64-bit shift
end else begin:shifter // RV32 or less
always_comb // funnel mux always_comb // funnel mux
if (Right) if (Right)
if (Arith) z = {{WIDTH-1{A[WIDTH-1]}}, A}; if (Arith) z = {{WIDTH-1{A[WIDTH-1]}}, A};
@ -302,7 +303,7 @@ module ppa_shifter #(parameter WIDTH=32) (
else z = {A, {WIDTH-1{1'b0}}}; else z = {A, {WIDTH-1{1'b0}}};
assign amttrunc = Amt; // shift amount assign amttrunc = Amt; // shift amount
end end
assign amttrunc = (W64 & WIDTH==64) ? {1'b0, Amt[4:0]} : Amt; // 32 or 64-bit shift fix
// opposite offset for right shfits // opposite offset for right shfits
assign offset = Right ? amttrunc : ~amttrunc; assign offset = Right ? amttrunc : ~amttrunc;

View File

@ -3,6 +3,7 @@ import subprocess
import csv import csv
import re import re
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import matplotlib.lines as lines
import numpy as np import numpy as np
def getData(): def getData():
@ -32,6 +33,23 @@ def getData():
return allSynths return allSynths
def getVals(module, freq, var):
global allSynths
if (var == 'delay'):
ind = 3
units = " (ps)"
else:
ind = 4
units = " (square microns)"
widths = []
ivar = []
for oneSynth in allSynths:
if (oneSynth[0] == module) & (oneSynth[2] == freq):
widths += [oneSynth[1]]
ivar += [oneSynth[ind]]
return widths, ivar, units
def writeCSV(allSynths): def writeCSV(allSynths):
file = open("ppaData.csv", "w") file = open("ppaData.csv", "w")
writer = csv.writer(file) writer = csv.writer(file)
@ -42,6 +60,17 @@ def writeCSV(allSynths):
file.close() file.close()
def polyfitR2(x, y, deg):
''' from internet, check math'''
z = np.polyfit(x, y, deg)
p = np.poly1d(z)
yhat = p(x) # or [p(z) for z in x]
ybar = np.sum(y)/len(y) # or sum(y)/len(y)
ssreg = np.sum((yhat-ybar)**2) # or sum([ (yihat - ybar)**2 for yihat in yhat])
sstot = np.sum((y - ybar)**2) # or sum([ (yi - ybar)**2 for yi in y])
r2 = ssreg / sstot
return p, r2
def plotPPA(module, freq, var): def plotPPA(module, freq, var):
''' '''
module: string module name module: string module name
@ -49,47 +78,82 @@ def plotPPA(module, freq, var):
var: string 'delay' or 'area' var: string 'delay' or 'area'
plots chosen variable vs width for all matching syntheses with regression plots chosen variable vs width for all matching syntheses with regression
''' '''
global allSynths
ind = 3 if (var == 'delay') else 4
widths = []
ivar = []
for oneSynth in allSynths:
if (oneSynth[0] == module) & (oneSynth[2] == freq):
widths += [oneSynth[1]]
ivar += [oneSynth[ind]]
x = np.array(widths, dtype=np.int) # A = np.vstack([x, np.ones(len(x))]).T
y = np.array(ivar, dtype=np.float) # mcresid = np.linalg.lstsq(A, y, rcond=None)
# m, c = mcresid[0]
# resid = mcresid[1]
# r2 = 1 - resid / (y.size * y.var())
# p, r2p = polyfitR2(x, y, 2)
# zlog = np.polyfit(np.log(x), y, 1)
# plog = np.poly1d(zlog)
# xplog = np.log(xp)
# _ = plt.plot(x, m*x + c, 'r', label='Linear fit R^2='+ str(r2)[1:7])
# _ = plt.plot(xp, p(xp), label='Quadratic fit R^2='+ str(r2p)[:6])
# _ = plt.plot(xp, plog(xplog), label = 'Log fit')
A = np.vstack([x, np.ones(len(x))]).T widths, ivar, units = getVals(module, freq, var)
m, c = np.linalg.lstsq(A, y, rcond=None)[0] coefs, r2 = regress(widths, ivar)
z = np.polyfit(x, y, 2) xp = np.linspace(8, 140, 200)
p = np.poly1d(z) pred = [coefs[0] + x*coefs[1] + np.log(x)*coefs[2] + x*np.log(x)*coefs[3] for x in xp]
zlog = np.polyfit(np.log(x), y, 1) r2p = round(r2[0], 4)
plog = np.poly1d(zlog) rcoefs = [round(c, 3) for c in coefs]
xp = np.linspace(0, 140, 200) l = "{} + {}*N + {}*log(N) + {}*Nlog(N)".format(*rcoefs)
xplog = np.log(xp) legend_elements = [lines.Line2D([0], [0], color='steelblue', label=module),
lines.Line2D([0], [0], color='orange', label=l),
lines.Line2D([0], [0], ls='', label=' R^2='+ str(r2p))]
_ = plt.plot(x, y, 'o', label=module, markersize=10) _ = plt.plot(widths, ivar, 'o', label=module, markersize=10)
_ = plt.plot(x, m*x + c, 'r', label='Linear fit') _ = plt.plot(xp, pred)
_ = plt.plot(xp, p(xp), label='Quadratic fit') _ = plt.legend(handles=legend_elements)
_ = plt.plot(xp, plog(xplog), label = 'Log fit')
_ = plt.legend()
_ = plt.xlabel("Width (bits)") _ = plt.xlabel("Width (bits)")
_ = plt.ylabel(str.title(var)) _ = plt.ylabel(str.title(var) + units)
_ = plt.title("Target frequency " + str(freq)) _ = plt.title("Target frequency " + str(freq) + "MHz")
plt.show() plt.show()
#fix square microns, picosec, end plots at 8 to stop negs, add equation to plots and R2
# try linear term with delay as well (w and wo) def makePlots(mod):
plotPPA(mod, 5000, 'delay')
plotPPA(mod, 5000, 'area')
plotPPA(mod, 10, 'area')
def regress(widths, var):
mat = []
for w in widths:
row = [1, w, np.log(w), w*np.log(w)]
mat += [row]
y = np.array(var, dtype=np.float)
coefsResid = np.linalg.lstsq(mat, y, rcond=None)
coefs = coefsResid[0]
resid = coefsResid[1]
r2 = 1 - resid / (y.size * y.var())
return coefs, r2
def makeCoefTable():
file = open("ppaFitting.csv", "w")
writer = csv.writer(file)
writer.writerow(['Module', 'Variable', 'Freq', '1', 'N', 'log(N)', 'Nlog(N)', 'R^2'])
for mod in ['add', 'mult', 'comparator']:
for comb in [['delay', 5000], ['area', 5000], ['area', 10]]:
var = comb[0]
freq = comb[1]
widths, ivar, units = getVals(mod, freq, var)
coefs, r2 = regress(widths, ivar)
row = [mod] + comb + np.ndarray.tolist(coefs) + [r2[0]]
writer.writerow(row)
file.close()
allSynths = getData() allSynths = getData()
writeCSV(allSynths) writeCSV(allSynths)
plotPPA('mult', 5000, 'delay') makePlots('shifter')
plotPPA('mult', 5000, 'area')
plotPPA('mult', 10, 'area') # makeCoefTable()

10
synthDC/ppaFitting.csv Normal file
View File

@ -0,0 +1,10 @@
Module,Variable,Freq,1,N,log(N),Nlog(N),R^2
add,delay,5000,0.23935453005464438,0.015973094945355207,-0.058207695467226296,-0.002593789781151714,0.9902532112478974
add,area,5000,-1032.1274349672115,64.4386855922132,374.6678949053879,-3.2579193244904823,0.9999180068922152
add,area,10,-13.720004131149423,14.699999256147343,3.6067390521177815e-06,9.312480709428003e-08,1.0
mult,delay,5000,-0.21755360109289562,-0.00033127390710363004,0.36865114245083547,0.0004100845872014472,0.9999815499619515
mult,area,5000,-29928.193338752997,-11370.538120558254,39122.3984379376,2592.313970431163,0.9998454828501703
mult,area,10,-24112.991162714883,-8735.874000034026,30452.017533199683,1892.3032427172166,0.9999575675635335
comparator,delay,5000,0.18302939890710385,-0.001793523907103751,0.00950014684425352,0.0004195522734073458,0.9999387049502957
comparator,area,5000,1831.2076391201958,303.59984869227907,-1617.4342555852443,-44.475154143873425,0.9990603962758624
comparator,area,10,-0.23027509289593326,18.299023530396347,-8.48304611908023,-0.4881808064440773,0.9999674500675539
1 Module Variable Freq 1 N log(N) Nlog(N) R^2
2 add delay 5000 0.23935453005464438 0.015973094945355207 -0.058207695467226296 -0.002593789781151714 0.9902532112478974
3 add area 5000 -1032.1274349672115 64.4386855922132 374.6678949053879 -3.2579193244904823 0.9999180068922152
4 add area 10 -13.720004131149423 14.699999256147343 3.6067390521177815e-06 9.312480709428003e-08 1.0
5 mult delay 5000 -0.21755360109289562 -0.00033127390710363004 0.36865114245083547 0.0004100845872014472 0.9999815499619515
6 mult area 5000 -29928.193338752997 -11370.538120558254 39122.3984379376 2592.313970431163 0.9998454828501703
7 mult area 10 -24112.991162714883 -8735.874000034026 30452.017533199683 1892.3032427172166 0.9999575675635335
8 comparator delay 5000 0.18302939890710385 -0.001793523907103751 0.00950014684425352 0.0004195522734073458 0.9999387049502957
9 comparator area 5000 1831.2076391201958 303.59984869227907 -1617.4342555852443 -44.475154143873425 0.9990603962758624
10 comparator area 10 -0.23027509289593326 18.299023530396347 -8.48304611908023 -0.4881808064440773 0.9999674500675539

View File

@ -14,12 +14,11 @@ def deleteRedundant(LoT):
bashCommand = synthStr.format(*synth) bashCommand = synthStr.format(*synth)
outputCPL = subprocess.check_output(['bash','-c', bashCommand]) outputCPL = subprocess.check_output(['bash','-c', bashCommand])
widths = ['128'] widths = ['8', '16', '32', '64', '128']
modules = ['mult'] modules = ['shifter']
freqs = ['5000'] freqs = ['10', '5000']
tech = 'sky90' tech = 'sky90'
#to run: add 8 10, shifter 8 16 (check .sv!)
LoT = [] LoT = []
for module in modules: for module in modules: