added support for tsmc28, fixed ff modules/analysis for timing

This commit is contained in:
Madeleine Masser-Frye 2022-05-25 06:44:22 +00:00
parent cd9f0cd6bd
commit 7d1448d2ad
5 changed files with 219 additions and 91 deletions

View File

@ -126,6 +126,16 @@ module ppa_mult_128 #(parameter WIDTH=128) (
assign y = a * b;
endmodule
module ppa_alu_8 #(parameter WIDTH=8) (
input logic [WIDTH-1:0] A, B,
input logic [2:0] ALUControl,
input logic [2:0] Funct3,
output logic [WIDTH-1:0] Result,
output logic [WIDTH-1:0] Sum);
ppa_alu #(WIDTH) alu (.*);
endmodule
module ppa_alu_16 #(parameter WIDTH=16) (
input logic [WIDTH-1:0] A, B,
input logic [2:0] ALUControl,
@ -133,7 +143,7 @@ module ppa_alu_16 #(parameter WIDTH=16) (
output logic [WIDTH-1:0] Result,
output logic [WIDTH-1:0] Sum);
ppa_alu #(WIDTH) alu_16 (.*);
ppa_alu #(WIDTH) alu (.*);
endmodule
module ppa_alu_32 #(parameter WIDTH=32) (
@ -143,7 +153,7 @@ module ppa_alu_32 #(parameter WIDTH=32) (
output logic [WIDTH-1:0] Result,
output logic [WIDTH-1:0] Sum);
ppa_alu #(WIDTH) alu_32 (.*);
ppa_alu #(WIDTH) alu (.*);
endmodule
module ppa_alu_64 #(parameter WIDTH=64) (
@ -153,7 +163,17 @@ module ppa_alu_64 #(parameter WIDTH=64) (
output logic [WIDTH-1:0] Result,
output logic [WIDTH-1:0] Sum);
ppa_alu #(WIDTH) alu_64 (.*);
ppa_alu #(WIDTH) alu (.*);
endmodule
module ppa_alu_128 #(parameter WIDTH=128) (
input logic [WIDTH-1:0] A, B,
input logic [2:0] ALUControl,
input logic [2:0] Funct3,
output logic [WIDTH-1:0] Result,
output logic [WIDTH-1:0] Sum);
ppa_alu #(WIDTH) alu (.*);
endmodule
module ppa_alu #(parameter WIDTH=32) (
@ -209,9 +229,11 @@ module ppa_alu #(parameter WIDTH=32) (
3'b111: FullResult = A & B; // and
endcase
// support W-type RV64I ADDW/SUBW/ADDIW/Shifts that sign-extend 32-bit result to 64 bits
if (WIDTH==64) assign Result = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult;
else assign Result = FullResult;
assign Result = FullResult;
// not using W64 so it has the same architecture regardless of width
// // support W-type RV64I ADDW/SUBW/ADDIW/Shifts that sign-extend 32-bit result to 64 bits
// if (WIDTH==64) assign Result = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult;
// else assign Result = FullResult;
endmodule
module ppa_shiftleft_8 #(parameter WIDTH=8) (
@ -313,29 +335,35 @@ 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 | WIDTH ==128) begin:shifter // RV64 or 128
always_comb // funnel mux
if (W64) begin // 32-bit shifts
if (Right)
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 = {{WIDTH-1{A[WIDTH-1]}}, A};
else z = {{WIDTH-1{1'b0}}, A};
else z = {A, {WIDTH-1{1'b0}}};
end
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 (WIDTH == 64 | WIDTH ==128) begin:shifter // RV64 or 128
// always_comb // funnel mux
// if (W64) begin // 32-bit shifts
// if (Right)
// 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 = {{WIDTH-1{A[WIDTH-1]}}, A};
// else z = {{WIDTH-1{1'b0}}, A};
// else z = {A, {WIDTH-1{1'b0}}};
// end
// 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};
// else z = {{WIDTH-1{1'b0}}, A};
// else z = {A, {WIDTH-1{1'b0}}};
// assign amttrunc = Amt; // shift amount
// end
always_comb // funnel mux
if (Right)
if (Arith) z = {{WIDTH-1{A[WIDTH-1]}}, A};
else z = {{WIDTH-1{1'b0}}, A};
else z = {A, {WIDTH-1{1'b0}}};
assign amttrunc = Amt; // shift amount
end
// opposite offset for right shfits
assign offset = Right ? amttrunc : ~amttrunc;
@ -538,7 +566,7 @@ endmodule
// *** some way to express data-critical inputs
module ppa_flop_8 #(parameter WIDTH = 8) (
module ppa_flop #(parameter WIDTH = 8) (
input logic clk,
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
@ -547,13 +575,26 @@ module ppa_flop_8 #(parameter WIDTH = 8) (
q <= #1 d;
endmodule
module ppa_flop_8 #(parameter WIDTH = 8) (
input logic clk,
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
logic [WIDTH-1:0] q1;
ppa_flop #(WIDTH) f1(clk, d, q1);
ppa_flop #(WIDTH) f2(clk, q1, q);
endmodule
module ppa_flop_16 #(parameter WIDTH = 16) (
input logic clk,
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_flop #(WIDTH) f1(clk, d, q1);
ppa_flop #(WIDTH) f2(clk, q1, q);
endmodule
module ppa_flop_32 #(parameter WIDTH = 32) (
@ -561,8 +602,10 @@ module ppa_flop_32 #(parameter WIDTH = 32) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_flop #(WIDTH) f1(clk, d, q1);
ppa_flop #(WIDTH) f2(clk, q1, q);
endmodule
module ppa_flop_64 #(parameter WIDTH = 64) (
@ -570,8 +613,10 @@ module ppa_flop_64 #(parameter WIDTH = 64) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_flop #(WIDTH) f1(clk, d, q1);
ppa_flop #(WIDTH) f2(clk, q1, q);
endmodule
module ppa_flop_128 #(parameter WIDTH = 128) (
@ -579,8 +624,20 @@ module ppa_flop_128 #(parameter WIDTH = 128) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
logic [WIDTH-1:0] q1;
ppa_flop #(WIDTH) f1(clk, d, q1);
ppa_flop #(WIDTH) f2(clk, q1, q);
endmodule
module ppa_flopr #(parameter WIDTH = 8) (
input logic clk, reset,
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
q <= #1 d;
if (reset) q <= #1 0;
else q <= #1 d;
endmodule
module ppa_flopr_8 #(parameter WIDTH = 8) (
@ -588,9 +645,10 @@ module ppa_flopr_8 #(parameter WIDTH = 8) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
if (reset) q <= #1 0;
else q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_flopr #(WIDTH) f1(clk, reset, d, q1);
ppa_flopr #(WIDTH) f2(clk, reset, q1, q);
endmodule
module ppa_flopr_16 #(parameter WIDTH = 16) (
@ -598,9 +656,10 @@ module ppa_flopr_16 #(parameter WIDTH = 16) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
if (reset) q <= #1 0;
else q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_flopr #(WIDTH) f1(clk, reset, d, q1);
ppa_flopr #(WIDTH) f2(clk, reset, q1, q);
endmodule
module ppa_flopr_32 #(parameter WIDTH = 32) (
@ -608,9 +667,10 @@ module ppa_flopr_32 #(parameter WIDTH = 32) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
if (reset) q <= #1 0;
else q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_flopr #(WIDTH) f1(clk, reset, d, q1);
ppa_flopr #(WIDTH) f2(clk, reset, q1, q);
endmodule
module ppa_flopr_64 #(parameter WIDTH = 64) (
@ -618,9 +678,10 @@ module ppa_flopr_64 #(parameter WIDTH = 64) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
if (reset) q <= #1 0;
else q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_flopr #(WIDTH) f1(clk, reset, d, q1);
ppa_flopr #(WIDTH) f2(clk, reset, q1, q);
endmodule
module ppa_flopr_128 #(parameter WIDTH = 128) (
@ -628,7 +689,18 @@ module ppa_flopr_128 #(parameter WIDTH = 128) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
logic [WIDTH-1:0] q1;
ppa_flopr #(WIDTH) f1(clk, reset, d, q1);
ppa_flopr #(WIDTH) f2(clk, reset, q1, q);
endmodule
module ppa_floprasync #(parameter WIDTH = 8) (
input logic clk, reset,
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk or posedge reset)
if (reset) q <= #1 0;
else q <= #1 d;
endmodule
@ -638,9 +710,10 @@ module ppa_floprasync_8 #(parameter WIDTH = 8) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk or posedge reset)
if (reset) q <= #1 0;
else q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_floprasync #(WIDTH) f1(clk, reset, d, q1);
ppa_floprasync #(WIDTH) f2(clk, reset, q1, q);
endmodule
module ppa_floprasync_16 #(parameter WIDTH = 16) (
@ -648,9 +721,10 @@ module ppa_floprasync_16 #(parameter WIDTH = 16) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk or posedge reset)
if (reset) q <= #1 0;
else q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_floprasync #(WIDTH) f1(clk, reset, d, q1);
ppa_floprasync #(WIDTH) f2(clk, reset, q1, q);
endmodule
module ppa_floprasync_32 #(parameter WIDTH = 32) (
@ -658,9 +732,10 @@ module ppa_floprasync_32 #(parameter WIDTH = 32) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk or posedge reset)
if (reset) q <= #1 0;
else q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_floprasync #(WIDTH) f1(clk, reset, d, q1);
ppa_floprasync #(WIDTH) f2(clk, reset, q1, q);
endmodule
module ppa_floprasync_64 #(parameter WIDTH = 64) (
@ -668,9 +743,10 @@ module ppa_floprasync_64 #(parameter WIDTH = 64) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk or posedge reset)
if (reset) q <= #1 0;
else q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_floprasync #(WIDTH) f1(clk, reset, d, q1);
ppa_floprasync #(WIDTH) f2(clk, reset, q1, q);
endmodule
module ppa_floprasync_128 #(parameter WIDTH = 128) (
@ -678,9 +754,20 @@ module ppa_floprasync_128 #(parameter WIDTH = 128) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk or posedge reset)
if (reset) q <= #1 0;
else q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_floprasync #(WIDTH) f1(clk, reset, d, q1);
ppa_floprasync #(WIDTH) f2(clk, reset, q1, q);
endmodule
module ppa_flopenr #(parameter WIDTH = 8) (
input logic clk, reset, en,
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
if (reset) q <= #1 0;
else if (en) q <= #1 d;
endmodule
module ppa_flopenr_8 #(parameter WIDTH = 8) (
@ -688,9 +775,10 @@ module ppa_flopenr_8 #(parameter WIDTH = 8) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
if (reset) q <= #1 0;
else if (en) q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_flopenr #(WIDTH) f1(clk, reset, en, d, q1);
ppa_flopenr #(WIDTH) f2(clk, reset, en, q1, q);
endmodule
module ppa_flopenr_16 #(parameter WIDTH = 16) (
@ -698,9 +786,10 @@ module ppa_flopenr_16 #(parameter WIDTH = 16) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
if (reset) q <= #1 0;
else if (en) q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_flopenr #(WIDTH) f1(clk, reset, en, d, q1);
ppa_flopenr #(WIDTH) f2(clk, reset, en, q1, q);
endmodule
module ppa_flopenr_32 #(parameter WIDTH = 32) (
@ -708,9 +797,10 @@ module ppa_flopenr_32 #(parameter WIDTH = 32) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
if (reset) q <= #1 0;
else if (en) q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_flopenr #(WIDTH) f1(clk, reset, en, d, q1);
ppa_flopenr #(WIDTH) f2(clk, reset, en, q1, q);
endmodule
module ppa_flopenr_64 #(parameter WIDTH = 64) (
@ -718,9 +808,10 @@ module ppa_flopenr_64 #(parameter WIDTH = 64) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
if (reset) q <= #1 0;
else if (en) q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_flopenr #(WIDTH) f1(clk, reset, en, d, q1);
ppa_flopenr #(WIDTH) f2(clk, reset, en, q1, q);
endmodule
module ppa_flopenr_128 #(parameter WIDTH = 128) (
@ -728,9 +819,10 @@ module ppa_flopenr_128 #(parameter WIDTH = 128) (
input logic [WIDTH-1:0] d,
output logic [WIDTH-1:0] q);
always_ff @(posedge clk)
if (reset) q <= #1 0;
else if (en) q <= #1 d;
logic [WIDTH-1:0] q1;
ppa_flopenr #(WIDTH) f1(clk, reset, en, d, q1);
ppa_flopenr #(WIDTH) f2(clk, reset, en, q1, q);
endmodule
module ppa_csa_8 #(parameter WIDTH = 8) (

View File

@ -17,6 +17,9 @@ if {$tech == "sky130"} {
} elseif {$tech == "sky90"} {
set s9lib $timing_lib/sky90/sky90_sc/V1.7.4/lib
lappend search_path $s9lib
} elseif {$tech == "tsmc28"} {
set s10lib /proj/models/tsmc28/libraries/28nmtsmc/tcbn28hpcplusbwp30p140_190a/TSMCHOME/digital/Front_End/timing_power_noise/NLDM/tcbn28hpcplusbwp30p140_180a
lappend search_path $s10lib
}
# Synthetic libraries
@ -30,6 +33,8 @@ if {$tech == "sky130"} {
lappend target_library $s8lib/sky130_osu_sc_12T_ms_TT_1P8_25C.ccs.db
} elseif {$tech == "sky90"} {
lappend target_library $s9lib/scc9gena_tt_1.2v_25C.db
} elseif {$tech == "tsmc28"} {
lappend target_library $s10lib/tcbn28hpcplusbwp30p140tt0p9v25c.db
}
# Set Link Library

View File

@ -66,6 +66,7 @@ def getVals(module, var, freq=None):
elif (var == 'area'):
ind = 4
units = " (sq microns)"
scale = 2
elif (var == 'lpower'):
ind = 5
units = " (nW)"
@ -92,6 +93,9 @@ def getVals(module, var, freq=None):
m = oneSynth[3]
met = oneSynth[ind]
metric += [met]
if ('flop' in module) & (var == 'area'):
metric = [m/2 for m in metric] # since two flops in each module
return widths, metric, units
def writeCSV():
@ -250,13 +254,16 @@ def freqPlot(mod, width):
delaysA += [oneSynth[3]]
areasA += [oneSynth[4]]
freqsV, delaysV, areasV = noOutliers(freqsV, delaysV, areasV)
freqsA, delaysA, areasA = noOutliers(freqsA, delaysA, areasA)
if ('flop' in mod): # since two flops in each module
areasA = [m/2 for m in areasA]
areasV = [m/2 for m in areasV]
freqsA, delaysA, areasA = noOutliers(freqsA, delaysA, areasA)
freqsV, delaysV, areasV = noOutliers(freqsV, delaysV, areasV)
adprodA, adprodV = adprodpow(areasA, delaysA, areasV, delaysV, 1)
adpowA, adpowV = adprodpow(areasA, delaysA, areasV, delaysV, 2)
adprodA = np.multiply(areasA, delaysA)
adsqA = np.multiply(adprodA, delaysA)
adprodV = np.multiply(areasV, delaysV)
adsqV = np.multiply(adprodV, delaysV)
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')]
@ -268,8 +275,8 @@ def freqPlot(mod, width):
ax2.scatter(freqsV, areasV, color='blue')
ax3.scatter(freqsA, adprodA, color='green')
ax3.scatter(freqsV, adprodV, color='blue')
ax4.scatter(freqsA, adsqA, color='green')
ax4.scatter(freqsV, adsqV, color='blue')
ax4.scatter(freqsA, adpowA, color='green')
ax4.scatter(freqsV, adpowV, color='blue')
ax1.legend(handles=legend_elements)
ax4.set_xlabel("Target Freq (MHz)")
ax1.set_ylabel('Delay (ns)')
@ -279,19 +286,35 @@ def freqPlot(mod, width):
ax1.set_title(mod + '_' + str(width))
plt.show()
def adprodpow(areasA, delaysA, areasV, delaysV, pow):
resultA = []
resultV = []
for i in range(len(areasA)):
resultA += [(areasA[i])*(delaysA[i])**pow]
for i in range(len(areasV)):
resultV += [(areasV[i])*(delaysV[i])**pow]
return resultA, resultV
def plotPPA(mod, freq=None):
fig, axs = plt.subplots(2, 2)
oneMetricPlot(mod, 'delay', ax=axs[0,0], fits='clg', 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, '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 " (min delay)"
plt.suptitle(mod + titleStr)
plt.show()
# plotPPA('alu')
# writeCSV()
# makeCoefTable()
# look at comparaotro 32
# for x in ['add', 'mult', 'comparator']:
# for y in [16, 32, 64, 128]:
# freqPlot(x, y)
freqPlot('flopr', 128)
freqPlot('flop', 8)
# plotPPA('add')
# plotPPA('alu')

View File

@ -44,13 +44,13 @@ def getData():
allSynths = getData()
arr = [-40, -20, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 14, 20, 40]
widths = [32, 64, 128]
modules = ['flopr']
widths = [32, 64]
modules = ['flop', 'flopr']
tech = 'sky90'
LoT = []
# # # initial sweep to get estimate of min delay
# freqs = ['7500']
# # # # initial sweep to get estimate of min delay
# freqs = ['10000', '15000', '20000']
# for module in modules:
# for width in widths:
# for freq in freqs:

View File

@ -117,6 +117,10 @@ if {$tech == "sky130"} {
} else {
set_driving_cell -lib_cell scc9gena_dfxbp_1 -pin Q $all_in_ex_clk
}
} elseif {$tech == "tsmc28"} {
if ($drive == "INV") {
set_driving_cell -lib_cell INVD1BWP30P140 -pin ZN $all_in_ex_clk
}
}
# Set input/output delay
@ -132,6 +136,10 @@ if {$tech == "sky130"} {
} else {
set_load [expr [load_of scc9gena_tt_1.2v_25C/scc9gena_dfxbp_1/D] * 1] [all_outputs]
}
} elseif {$tech == "tsmc28"} {
if ($drive == "INV") {
set_load [expr [load_of tcbn28hpcplusbwp30p140tt0p9v25c/INVD4BWP30P140/I] * 1] [all_outputs]
}
}
# Set the wire load model