diff --git a/compiler/base/graph_util.py b/compiler/base/graph_util.py index 4d07d54a..f91d3d6e 100644 --- a/compiler/base/graph_util.py +++ b/compiler/base/graph_util.py @@ -92,7 +92,7 @@ class timing_graph(): path.pop() visited.remove(cur_node) - def get_timing(self, path, corner, slew, load): + def get_timing(self, path, corner, slew, load, cacti_params): """Returns the analytical delays in the input path""" if len(path) == 0: @@ -108,13 +108,14 @@ class timing_graph(): cout = 0 for node in self.graph[path[i + 1]]: output_edge_mod = self.edge_mods[(path[i + 1], node)] - cout+=output_edge_mod.get_cin() + #cout+=output_edge_mod.get_cin() # logical effort based CIN + cout+=output_edge_mod.get_input_capacitance() # If at the last output, include the final output load if i == len(path) - 2: cout += load #delays.append(path_edge_mod.analytical_delay(corner, cur_slew, cout)) - delays.append(path_edge_mod.cacti_delay(corner, cur_slew, cout)) + delays.append(path_edge_mod.cacti_delay(corner, cur_slew, cout, cacti_params)) cur_slew = delays[-1].slew return delays diff --git a/compiler/base/hierarchy_spice.py b/compiler/base/hierarchy_spice.py index 4be721cb..98b94351 100644 --- a/compiler/base/hierarchy_spice.py +++ b/compiler/base/hierarchy_spice.py @@ -419,9 +419,9 @@ class spice(): del usedMODS spfile.close() - def cacti_delay(self, corner, inrisetime, c_load=0.0): + def cacti_delay(self, corner, inrisetime, c_load, cacti_params): """Generalization of how Cacti determines the delay of a gate""" - + self.cacti_params = cacti_params # Get the r_on the the tx rd = self.get_on_resistance() # Calculate the intrinsic capacitance @@ -471,6 +471,15 @@ class spice(): self.cell_name)) return 0 + def get_input_capacitance(self): + """Inform users undefined delay module while building new modules""" + debug.warning("Design Class {0} input capacitance function needs to be defined" + .format(self.__class__.__name__)) + debug.warning("Class {0} name {1}" + .format(self.__class__.__name__, + self.cell_name)) + return 0 + def get_intrinsic_capacitance(self): """Inform users undefined delay module while building new modules""" debug.warning("Design Class {0} intrinsic capacitance function needs to be defined" @@ -491,7 +500,7 @@ class spice(): def input_load(self): """Inform users undefined relative capacitance functions used for analytical delays.""" - debug.warning("Design Class {0} input capacitance function needs to be defined" + debug.warning("Design Class {0} input load function needs to be defined" .format(self.__class__.__name__)) debug.warning("Class {0} name {1}" .format(self.__class__.__name__, @@ -521,13 +530,13 @@ class spice(): def tr_r_on(self, width, is_nchannel, stack, _is_cell): - restrans = tech.spice["r_nch_on"] if is_nchannel else tech.spice["r_pch_on"] + restrans = self.cacti_params["r_nch_on"] if is_nchannel else self.cacti_params["r_pch_on"] return stack * restrans / width - def gate_c(self, width, wirelength, _is_cell): + def gate_c(self, width): return (tech.spice["c_g_ideal"] + tech.spice["c_overlap"] + 3*tech.spice["c_fringe"])*width +\ - tech.spice["l_phy"]*tech.spice["cpolywire"] + tech.drc["minlength_channel"]*tech.spice["cpolywire"] def drain_c_(self, width, diff --git a/compiler/bitcells/bitcell_base.py b/compiler/bitcells/bitcell_base.py index 2b27bee9..72cbc40b 100644 --- a/compiler/bitcells/bitcell_base.py +++ b/compiler/bitcells/bitcell_base.py @@ -207,4 +207,9 @@ class bitcell_base(design.design): is_nchannel = True stack = 2 # for access and inv tx is_cell = False - return self.tr_r_on(drc["minwidth_tx"], is_nchannel, stack, is_cell) \ No newline at end of file + return self.tr_r_on(drc["minwidth_tx"], is_nchannel, stack, is_cell) + + def get_input_capacitance(self): + """Input cap of input, passes width of gates to gate cap function""" + # Input cap of both access TX connected to the wordline + return self.gate_c(2*parameter["6T_access_size"]) \ No newline at end of file diff --git a/compiler/characterizer/cacti.py b/compiler/characterizer/cacti.py index 99fc795d..4a8dc671 100644 --- a/compiler/characterizer/cacti.py +++ b/compiler/characterizer/cacti.py @@ -32,6 +32,14 @@ class cacti(simulation): self.set_corner(corner) self.create_signal_names() self.add_graph_exclusions() + self.set_params() + + def set_params(self): + """Set parameters specific to the corner being simulated""" + self.params = {} + # Only parameter right now is r_on which is dependent on Vdd + self.params["r_nch_on"] = self.vdd_voltage / tech.spice["i_on_n"] + self.params["r_pch_on"] = self.vdd_voltage / tech.spice["i_on_p"] def get_lib_values(self, load_slews): """ @@ -39,7 +47,7 @@ class cacti(simulation): """ if OPTS.num_rw_ports > 1 or OPTS.num_w_ports > 0 and OPTS.num_r_ports > 0: debug.warning("In analytical mode, all ports have the timing of the first read port.") - + # Probe set to 0th bit, does not matter for analytical delay. self.set_probe('0' * self.addr_size, 0) self.create_graph() @@ -61,7 +69,7 @@ class cacti(simulation): max_delay = 0.0 for load,slew in load_slews: # Calculate delay based on slew and load - path_delays = self.graph.get_timing(bl_path, self.corner, slew, load) + path_delays = self.graph.get_timing(bl_path, self.corner, slew, load, self.params) total_delay = self.sum_delays(path_delays) max_delay = max(max_delay, total_delay.delay) diff --git a/compiler/custom/nand2_dec.py b/compiler/custom/nand2_dec.py index a1418062..cafc7c34 100644 --- a/compiler/custom/nand2_dec.py +++ b/compiler/custom/nand2_dec.py @@ -81,3 +81,7 @@ class nand2_dec(design.design): stack = 2 is_cell = False return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell) + + def get_input_capacitance(self): + """Input cap of input, passes width of gates to gate cap function""" + return self.gate_c(self.nmos_width+self.pmos_width) \ No newline at end of file diff --git a/compiler/custom/nand3_dec.py b/compiler/custom/nand3_dec.py index da745bd2..4be8e8ca 100644 --- a/compiler/custom/nand3_dec.py +++ b/compiler/custom/nand3_dec.py @@ -80,4 +80,8 @@ class nand3_dec(design.design): is_nchannel = True stack = 3 is_cell = False - return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell) \ No newline at end of file + return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell) + + def get_input_capacitance(self): + """Input cap of input, passes width of gates to gate cap function""" + return self.gate_c(self.nmos_width+self.pmos_width) \ No newline at end of file diff --git a/compiler/custom/nand4_dec.py b/compiler/custom/nand4_dec.py index 1ddefed4..a0e2621c 100644 --- a/compiler/custom/nand4_dec.py +++ b/compiler/custom/nand4_dec.py @@ -80,4 +80,8 @@ class nand4_dec(design.design): is_nchannel = True stack = 4 is_cell = False - return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell) \ No newline at end of file + return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell) + + def get_input_capacitance(self): + """Input cap of input, passes width of gates to gate cap function""" + return self.gate_c(self.nmos_width+self.pmos_width) \ No newline at end of file diff --git a/compiler/custom/sense_amp.py b/compiler/custom/sense_amp.py index 8446756d..d2a3ba49 100644 --- a/compiler/custom/sense_amp.py +++ b/compiler/custom/sense_amp.py @@ -86,3 +86,7 @@ class sense_amp(design.design): stack = 1 is_cell = False return self.tr_r_on(parameter["sa_inv_nmos_size"], is_nchannel, stack, is_cell) + + def get_input_capacitance(self): + """Input cap of input, passes width of gates to gate cap function""" + return self.gate_c(parameter["sa_inv_nmos_size"]) diff --git a/compiler/pgates/pinv.py b/compiler/pgates/pinv.py index 0d464ee6..01f9535f 100644 --- a/compiler/pgates/pinv.py +++ b/compiler/pgates/pinv.py @@ -312,7 +312,7 @@ class pinv(pgate.pgate): def input_load(self): """ - Return the capacitance of the gate connection in generic capacitive + Return the relative capacitance of the gate connection in generic capacitive units relative to the minimum width of a transistor """ return self.nmos_size + self.pmos_size @@ -349,3 +349,7 @@ class pinv(pgate.pgate): stack = 1 is_cell = False return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell) + + def get_input_capacitance(self): + """Input cap of input, passes width of gates to gate cap function""" + return self.gate_c(self.nmos_width+self.pmos_width) diff --git a/compiler/pgates/pnand2.py b/compiler/pgates/pnand2.py index e5619b1f..d06c37a4 100644 --- a/compiler/pgates/pnand2.py +++ b/compiler/pgates/pnand2.py @@ -326,4 +326,8 @@ class pnand2(pgate.pgate): stack = 2 is_cell = False return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell) + + def get_input_capacitance(self): + """Input cap of input, passes width of gates to gate cap function""" + return self.gate_c(self.nmos_width+self.pmos_width) \ No newline at end of file diff --git a/compiler/pgates/pnand3.py b/compiler/pgates/pnand3.py index acc20ec5..798be423 100644 --- a/compiler/pgates/pnand3.py +++ b/compiler/pgates/pnand3.py @@ -358,4 +358,8 @@ class pnand3(pgate.pgate): is_nchannel = True stack = 3 is_cell = False - return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell) \ No newline at end of file + return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell) + + def get_input_capacitance(self): + """Input cap of input, passes width of gates to gate cap function""" + return self.gate_c(self.nmos_width+self.pmos_width) \ No newline at end of file diff --git a/compiler/pgates/pnand4.py b/compiler/pgates/pnand4.py index eec42916..b7c7a823 100644 --- a/compiler/pgates/pnand4.py +++ b/compiler/pgates/pnand4.py @@ -376,3 +376,7 @@ class pnand4(pgate.pgate): stack = 4 is_cell = False return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell) + + def get_input_capacitance(self): + """Input cap of input, passes width of gates to gate cap function""" + return self.gate_c(self.nmos_width+self.pmos_width) \ No newline at end of file diff --git a/compiler/pgates/ptx.py b/compiler/pgates/ptx.py index 9bdf82a6..ffe82025 100644 --- a/compiler/pgates/ptx.py +++ b/compiler/pgates/ptx.py @@ -555,7 +555,11 @@ class ptx(design.design): def get_on_resistance(self): """On resistance of pinv, defined by single nmos""" - is_nchannel = True + is_nchannel = (self.tx_type == "nmos") stack = 1 is_cell = False - return self.tr_r_on(self.nmos_width, is_nchannel, stack, is_cell) \ No newline at end of file + return self.tr_r_on(self.tx_width, is_nchannel, stack, is_cell) + + def get_input_capacitance(self): + """Input cap of input, passes width of gates to gate cap function""" + return self.gate_c(self.tx_width) \ No newline at end of file