From 12c42cd5078cbfe76beb81bf8c990ba0483d3ed1 Mon Sep 17 00:00:00 2001 From: mmasserfrye Date: Wed, 18 May 2022 16:08:40 +0000 Subject: [PATCH] adapted shifter in ppa.sv for widths beside 32 and 64 modified plotting and regression in ppaAnalyze.py --- pipelined/src/ppa/ppa.sv | 19 +++--- synthDC/ppaAnalyze.py | 126 +++++++++++++++++++++++++++++---------- synthDC/ppaFitting.csv | 10 ++++ synthDC/ppaSynth.py | 7 +-- 4 files changed, 118 insertions(+), 44 deletions(-) create mode 100644 synthDC/ppaFitting.csv diff --git a/pipelined/src/ppa/ppa.sv b/pipelined/src/ppa/ppa.sv index 03b004f6..96b2581b 100644 --- a/pipelined/src/ppa/ppa.sv +++ b/pipelined/src/ppa/ppa.sv @@ -281,20 +281,21 @@ module ppa_shifter #(parameter WIDTH=32) ( // 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) - if (WIDTH == 64) begin:shifter // RV64 fix what about 128 + if (WIDTH == 64 | WIDTH ==128) begin:shifter // RV64 or 128 always_comb // funnel mux if (W64) begin // 32-bit shifts if (Right) - if (Arith) z = {64'b0, {31{A[31]}}, A[31:0]}; - else z = {95'b0, A[31:0]}; - else z = {32'b0, A[31:0], 63'b0}; + if (Arith) z = {{WIDTH{1'b0}}, {WIDTH/2 -1{A[WIDTH/2 -1]}}, A[WIDTH/2 -1:0]}; + else z = {{WIDTH*3/2-1{1'b0}}, A[WIDTH/2 -1:0]}; + else z = {{WIDTH/2{1'b0}}, A[WIDTH/2 -1:0], {WIDTH-1{1'b0}}}; end else begin if (Right) - if (Arith) z = {{63{A[63]}}, A}; - else z = {63'b0, A}; - else z = {A, 63'b0}; + if (Arith) z = {{WIDTH-1{A[WIDTH-1]}}, A}; + else z = {{WIDTH-1{1'b0}}, A}; + else z = {A, {WIDTH-1{1'b0}}}; 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 if (Right) 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}}}; assign amttrunc = Amt; // shift amount end - assign amttrunc = (W64 & WIDTH==64) ? {1'b0, Amt[4:0]} : Amt; // 32 or 64-bit shift fix + // opposite offset for right shfits assign offset = Right ? amttrunc : ~amttrunc; diff --git a/synthDC/ppaAnalyze.py b/synthDC/ppaAnalyze.py index fef78921..9dc7399f 100755 --- a/synthDC/ppaAnalyze.py +++ b/synthDC/ppaAnalyze.py @@ -3,6 +3,7 @@ import subprocess import csv import re import matplotlib.pyplot as plt +import matplotlib.lines as lines import numpy as np def getData(): @@ -32,6 +33,23 @@ def getData(): 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): file = open("ppaData.csv", "w") writer = csv.writer(file) @@ -42,6 +60,17 @@ def writeCSV(allSynths): 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): ''' module: string module name @@ -49,47 +78,82 @@ def plotPPA(module, freq, var): var: string 'delay' or 'area' 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) - y = np.array(ivar, dtype=np.float) + # A = np.vstack([x, np.ones(len(x))]).T + # 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 - m, c = np.linalg.lstsq(A, y, rcond=None)[0] + widths, ivar, units = getVals(module, freq, var) + coefs, r2 = regress(widths, ivar) - z = np.polyfit(x, y, 2) - p = np.poly1d(z) + xp = np.linspace(8, 140, 200) + 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) - plog = np.poly1d(zlog) + r2p = round(r2[0], 4) + rcoefs = [round(c, 3) for c in coefs] - xp = np.linspace(0, 140, 200) - xplog = np.log(xp) + l = "{} + {}*N + {}*log(N) + {}*Nlog(N)".format(*rcoefs) + 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(x, m*x + c, 'r', label='Linear fit') - _ = plt.plot(xp, p(xp), label='Quadratic fit') - _ = plt.plot(xp, plog(xplog), label = 'Log fit') - _ = plt.legend() + _ = plt.plot(widths, ivar, 'o', label=module, markersize=10) + _ = plt.plot(xp, pred) + _ = plt.legend(handles=legend_elements) _ = plt.xlabel("Width (bits)") - _ = plt.ylabel(str.title(var)) - _ = plt.title("Target frequency " + str(freq)) + _ = plt.ylabel(str.title(var) + units) + _ = plt.title("Target frequency " + str(freq) + "MHz") 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() writeCSV(allSynths) -plotPPA('mult', 5000, 'delay') -plotPPA('mult', 5000, 'area') -plotPPA('mult', 10, 'area') \ No newline at end of file +makePlots('shifter') + +# makeCoefTable() + diff --git a/synthDC/ppaFitting.csv b/synthDC/ppaFitting.csv new file mode 100644 index 00000000..58a3d036 --- /dev/null +++ b/synthDC/ppaFitting.csv @@ -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 diff --git a/synthDC/ppaSynth.py b/synthDC/ppaSynth.py index 654d7739..b2479fed 100755 --- a/synthDC/ppaSynth.py +++ b/synthDC/ppaSynth.py @@ -14,12 +14,11 @@ def deleteRedundant(LoT): bashCommand = synthStr.format(*synth) outputCPL = subprocess.check_output(['bash','-c', bashCommand]) -widths = ['128'] -modules = ['mult'] -freqs = ['5000'] +widths = ['8', '16', '32', '64', '128'] +modules = ['shifter'] +freqs = ['10', '5000'] tech = 'sky90' -#to run: add 8 10, shifter 8 16 (check .sv!) LoT = [] for module in modules: