mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	adapted shifter in ppa.sv for widths beside 32 and 64
modified plotting and regression in ppaAnalyze.py
This commit is contained in:
		
							parent
							
								
									5c22bec023
								
							
						
					
					
						commit
						12c42cd507
					
				| @ -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; | ||||||
|  | |||||||
| @ -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]] |     # A = np.vstack([x, np.ones(len(x))]).T | ||||||
|             ivar += [oneSynth[ind]] |     # 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') | ||||||
| 
 | 
 | ||||||
|     x = np.array(widths, dtype=np.int) |     widths, ivar, units = getVals(module, freq, var) | ||||||
|     y = np.array(ivar, dtype=np.float) |     coefs, r2 = regress(widths, ivar) | ||||||
| 
 | 
 | ||||||
|     A = np.vstack([x, np.ones(len(x))]).T |     xp = np.linspace(8, 140, 200) | ||||||
|     m, c = np.linalg.lstsq(A, y, rcond=None)[0] |     pred = [coefs[0] + x*coefs[1] + np.log(x)*coefs[2] + x*np.log(x)*coefs[3] for x in xp] | ||||||
| 
 | 
 | ||||||
|     z = np.polyfit(x, y, 2) |     r2p = round(r2[0], 4) | ||||||
|     p = np.poly1d(z) |     rcoefs = [round(c, 3) for c in coefs] | ||||||
| 
 | 
 | ||||||
|     zlog = np.polyfit(np.log(x), y, 1) |     l = "{} + {}*N + {}*log(N) + {}*Nlog(N)".format(*rcoefs)  | ||||||
|     plog = np.poly1d(zlog) |     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))] | ||||||
| 
 | 
 | ||||||
|     xp = np.linspace(0, 140, 200) |     _ = plt.plot(widths, ivar, 'o', label=module, markersize=10) | ||||||
|     xplog = np.log(xp) |     _ = plt.plot(xp, pred) | ||||||
| 
 |     _ = plt.legend(handles=legend_elements) | ||||||
|     _ = 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.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
									
								
							
							
						
						
									
										10
									
								
								synthDC/ppaFitting.csv
									
									
									
									
									
										Normal 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 | ||||||
| 
 | 
| @ -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: | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user