Made timing graph more gate-level. Changed edges to be defined by inputs/ouputs and name based.

This commit is contained in:
Hunter Nichols
2019-05-07 00:52:27 -07:00
parent 5bfc42fdbb
commit d54074d68e
20 changed files with 205 additions and 151 deletions
+4 -7
View File
@@ -13,6 +13,7 @@ class bitcell(design.design):
"""
pin_names = ["bl", "br", "wl", "vdd", "gnd"]
type_list = ["OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"]
(width,height) = utils.get_libcell_size("cell_6t", GDS["unit"], layer["boundary"])
pin_map = utils.get_libcell_pins(pin_names, "cell_6t", GDS["unit"])
@@ -24,6 +25,7 @@ class bitcell(design.design):
self.width = bitcell.width
self.height = bitcell.height
self.pin_map = bitcell.pin_map
self.add_pin_types(self.type_list)
def analytical_delay(self, corner, slew, load=0, swing = 0.5):
parasitic_delay = 1
@@ -76,10 +78,5 @@ class bitcell(design.design):
return 2*access_tx_cin
def build_graph(self, graph, inst_name, port_nets):
"""Adds edges to graph. Handmade cells must implement this manually."""
#The bitcell has 5 net ports hard-coded in self.pin_names. The edges
#are based on the hard-coded name positions.
# The edges added are: wl->bl, wl->br.
# Internal nodes of the handmade cell not considered, only ports. vdd/gnd ignored for graph.
graph.add_edge(port_nets[2],port_nets[0])
graph.add_edge(port_nets[2],port_nets[1])
"""Adds edges based on inputs/outputs. Overrides base class function."""
self.add_graph_edges(graph, port_nets)
+13 -11
View File
@@ -13,6 +13,7 @@ class bitcell_1rw_1r(design.design):
"""
pin_names = ["bl0", "br0", "bl1", "br1", "wl0", "wl1", "vdd", "gnd"]
type_list = ["OUTPUT", "OUTPUT", "OUTPUT", "OUTPUT", "INPUT", "INPUT", "POWER", "GROUND"]
(width,height) = utils.get_libcell_size("cell_1rw_1r", GDS["unit"], layer["boundary"])
pin_map = utils.get_libcell_pins(pin_names, "cell_1rw_1r", GDS["unit"])
@@ -24,7 +25,8 @@ class bitcell_1rw_1r(design.design):
self.width = bitcell_1rw_1r.width
self.height = bitcell_1rw_1r.height
self.pin_map = bitcell_1rw_1r.pin_map
self.add_pin_types(self.type_list)
def analytical_delay(self, corner, slew, load=0, swing = 0.5):
parasitic_delay = 1
size = 0.5 #This accounts for bitline being drained thought the access TX and internal node
@@ -101,13 +103,13 @@ class bitcell_1rw_1r(design.design):
return 2*access_tx_cin
def build_graph(self, graph, inst_name, port_nets):
"""Adds edges to graph. Handmade cells must implement this manually."""
#The bitcell has 8 net ports hard-coded in self.pin_names. The edges
#are based on the hard-coded name positions.
# The edges added are: wl0->bl0, wl0->br0, wl1->bl1, wl1->br1.
# Internal nodes of the handmade cell not considered, only ports. vdd/gnd ignored for graph.
graph.add_edge(port_nets[4],port_nets[0])
graph.add_edge(port_nets[4],port_nets[1])
graph.add_edge(port_nets[5],port_nets[2])
graph.add_edge(port_nets[5],port_nets[3])
"""Adds edges to graph. Multiport bitcell timing graph is too complex
to use the add_graph_edges function."""
pin_dict = {pin:port for pin,port in zip(self.pins, port_nets)}
#Edges hardcoded here. Essentially wl->bl/br for both ports.
# Port 0 edges
graph.add_edge(pin_dict["wl0"], pin_dict["bl0"])
graph.add_edge(pin_dict["wl0"], pin_dict["br0"])
# Port 1 edges
graph.add_edge(pin_dict["wl1"], pin_dict["bl1"])
graph.add_edge(pin_dict["wl1"], pin_dict["br1"])
+10 -9
View File
@@ -13,6 +13,7 @@ class bitcell_1w_1r(design.design):
"""
pin_names = ["bl0", "br0", "bl1", "br1", "wl0", "wl1", "vdd", "gnd"]
type_list = ["OUTPUT", "OUTPUT", "INPUT", "INPUT", "INPUT", "INPUT", "POWER", "GROUND"]
(width,height) = utils.get_libcell_size("cell_1w_1r", GDS["unit"], layer["boundary"])
pin_map = utils.get_libcell_pins(pin_names, "cell_1w_1r", GDS["unit"])
@@ -24,6 +25,7 @@ class bitcell_1w_1r(design.design):
self.width = bitcell_1w_1r.width
self.height = bitcell_1w_1r.height
self.pin_map = bitcell_1w_1r.pin_map
self.add_pin_types(self.type_list)
def analytical_delay(self, corner, slew, load=0, swing = 0.5):
parasitic_delay = 1
@@ -101,12 +103,11 @@ class bitcell_1w_1r(design.design):
return 2*access_tx_cin
def build_graph(self, graph, inst_name, port_nets):
"""Adds edges to graph. Handmade cells must implement this manually."""
#The bitcell has 8 net ports hard-coded in self.pin_names. The edges
#are based on the hard-coded name positions.
# The edges added are: wl0->bl0, wl0->br0, wl1->bl1, wl1->br1.
# Internal nodes of the handmade cell not considered, only ports. vdd/gnd ignored for graph.
graph.add_edge(port_nets[4],port_nets[0])
graph.add_edge(port_nets[4],port_nets[1])
graph.add_edge(port_nets[5],port_nets[2])
graph.add_edge(port_nets[5],port_nets[3])
"""Adds edges to graph. Multiport bitcell timing graph is too complex
to use the add_graph_edges function."""
pin_dict = {pin:port for pin,port in zip(self.pins, port_nets)}
#Edges hardcoded here. Essentially wl->bl/br for both ports.
# Port 0 edges
graph.add_edge(pin_dict["wl0"], pin_dict["bl0"])
graph.add_edge(pin_dict["wl0"], pin_dict["br0"])
# Port 1 is a write port, so its timing is not considered here.
+21 -22
View File
@@ -91,40 +91,40 @@ class pbitcell(design.design):
port = 0
for k in range(self.num_rw_ports):
self.add_pin("bl{}".format(port))
self.add_pin("br{}".format(port))
self.add_pin("bl{}".format(port), "OUTPUT")
self.add_pin("br{}".format(port), "OUTPUT")
self.rw_bl_names.append("bl{}".format(port))
self.rw_br_names.append("br{}".format(port))
port += 1
for k in range(self.num_w_ports):
self.add_pin("bl{}".format(port))
self.add_pin("br{}".format(port))
self.add_pin("bl{}".format(port), "INPUT")
self.add_pin("br{}".format(port), "INPUT")
self.w_bl_names.append("bl{}".format(port))
self.w_br_names.append("br{}".format(port))
port += 1
for k in range(self.num_r_ports):
self.add_pin("bl{}".format(port))
self.add_pin("br{}".format(port))
self.add_pin("bl{}".format(port), "OUTPUT")
self.add_pin("br{}".format(port), "OUTPUT")
self.r_bl_names.append("bl{}".format(port))
self.r_br_names.append("br{}".format(port))
port += 1
port = 0
for k in range(self.num_rw_ports):
self.add_pin("wl{}".format(port))
self.add_pin("wl{}".format(port), "INPUT")
self.rw_wl_names.append("wl{}".format(port))
port += 1
for k in range(self.num_w_ports):
self.add_pin("wl{}".format(port))
self.add_pin("wl{}".format(port), "INPUT")
self.w_wl_names.append("wl{}".format(port))
port += 1
for k in range(self.num_r_ports):
self.add_pin("wl{}".format(port))
self.add_pin("wl{}".format(port), "INPUT")
self.r_wl_names.append("wl{}".format(port))
port += 1
self.add_pin("vdd")
self.add_pin("gnd")
self.add_pin("vdd", "POWER")
self.add_pin("gnd", "GROUND")
# if this is a replica bitcell, replace the instances of Q_bar with vdd
if self.replica_bitcell:
@@ -894,14 +894,13 @@ class pbitcell(design.design):
return 2*access_tx_cin
def build_graph(self, graph, inst_name, port_nets):
"""Adds edges to graph. Done manually to make the graph acyclic."""
#The base graph function can make this but it would contain loops and path
#searches would essentially be useless.
# Edges added wl->bl, wl->br for every port
num_wl = len(self.rw_wl_names) + len(self.w_wl_names) + len(self.r_wl_names)
wl_pos = 2*num_wl #there are this many bitlines nets before the wls in the port list
for i in range(num_wl):
bl_pos = i*2
graph.add_edge(port_nets[wl_pos+i],port_nets[bl_pos])
graph.add_edge(port_nets[wl_pos+i],port_nets[bl_pos+1])
"""Adds edges to graph for pbitcell. Only readwrite and read ports."""
pin_dict = {pin:port for pin,port in zip(self.pins, port_nets)}
# Edges added wl->bl, wl->br for every port except write ports
rw_pin_names = zip(self.r_wl_names, self.r_bl_names, self.r_br_names)
r_pin_names = zip(self.rw_wl_names, self.rw_bl_names, self.rw_br_names)
for pin_zip in zip(rw_pin_names, r_pin_names):
for wl,bl,br in pin_zip:
graph.add_edge(pin_dict[wl],pin_dict[bl])
graph.add_edge(pin_dict[wl],pin_dict[br])
+4 -7
View File
@@ -11,6 +11,7 @@ class replica_bitcell(design.design):
the technology library. """
pin_names = ["bl", "br", "wl", "vdd", "gnd"]
type_list = ["OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"]
(width,height) = utils.get_libcell_size("replica_cell_6t", GDS["unit"], layer["boundary"])
pin_map = utils.get_libcell_pins(pin_names, "replica_cell_6t", GDS["unit"])
@@ -22,6 +23,7 @@ class replica_bitcell(design.design):
self.width = replica_bitcell.width
self.height = replica_bitcell.height
self.pin_map = replica_bitcell.pin_map
self.add_pin_types(self.type_list)
def get_wl_cin(self):
"""Return the relative capacitance of the access transistor gates"""
@@ -31,10 +33,5 @@ class replica_bitcell(design.design):
return 2*access_tx_cin
def build_graph(self, graph, inst_name, port_nets):
"""Adds edges to graph. Handmade cells must implement this manually."""
#The bitcell has 5 net ports hard-coded in self.pin_names. The edges
#are based on the hard-coded name positions.
# The edges added are: wl->bl, wl->br.
# Internal nodes of the handmade cell not considered, only ports. vdd/gnd ignored for graph.
graph.add_edge(port_nets[2],port_nets[0])
graph.add_edge(port_nets[2],port_nets[1])
"""Adds edges based on inputs/outputs. Overrides base class function."""
self.add_graph_edges(graph, port_nets)
+12 -9
View File
@@ -11,6 +11,7 @@ class replica_bitcell_1rw_1r(design.design):
the technology library. """
pin_names = ["bl0", "br0", "bl1", "br1", "wl0", "wl1", "vdd", "gnd"]
type_list = ["OUTPUT", "OUTPUT", "OUTPUT", "OUTPUT", "INPUT", "INPUT", "POWER", "GROUND"]
(width,height) = utils.get_libcell_size("replica_cell_1rw_1r", GDS["unit"], layer["boundary"])
pin_map = utils.get_libcell_pins(pin_names, "replica_cell_1rw_1r", GDS["unit"])
@@ -22,6 +23,7 @@ class replica_bitcell_1rw_1r(design.design):
self.width = replica_bitcell_1rw_1r.width
self.height = replica_bitcell_1rw_1r.height
self.pin_map = replica_bitcell_1rw_1r.pin_map
self.add_pin_types(self.type_list)
def get_wl_cin(self):
"""Return the relative capacitance of the access transistor gates"""
@@ -32,12 +34,13 @@ class replica_bitcell_1rw_1r(design.design):
return 2*access_tx_cin
def build_graph(self, graph, inst_name, port_nets):
"""Adds edges to graph. Handmade cells must implement this manually."""
#The bitcell has 8 net ports hard-coded in self.pin_names. The edges
#are based on the hard-coded name positions.
# The edges added are: wl0->bl0, wl0->br0, wl1->bl1, wl1->br1.
# Internal nodes of the handmade cell not considered, only ports. vdd/gnd ignored for graph.
graph.add_edge(port_nets[4],port_nets[0])
graph.add_edge(port_nets[4],port_nets[1])
graph.add_edge(port_nets[5],port_nets[2])
graph.add_edge(port_nets[5],port_nets[3])
"""Adds edges to graph. Multiport bitcell timing graph is too complex
to use the add_graph_edges function."""
pin_dict = {pin:port for pin,port in zip(self.pins, port_nets)}
#Edges hardcoded here. Essentially wl->bl/br for both ports.
# Port 0 edges
graph.add_edge(pin_dict["wl0"], pin_dict["bl0"])
graph.add_edge(pin_dict["wl0"], pin_dict["br0"])
# Port 1 edges
graph.add_edge(pin_dict["wl1"], pin_dict["bl1"])
graph.add_edge(pin_dict["wl1"], pin_dict["br1"])
+10 -9
View File
@@ -11,6 +11,7 @@ class replica_bitcell_1w_1r(design.design):
the technology library. """
pin_names = ["bl0", "br0", "bl1", "br1", "wl0", "wl1", "vdd", "gnd"]
type_list = ["OUTPUT", "OUTPUT", "INPUT", "INPUT", "INPUT", "INPUT", "POWER", "GROUND"]
(width,height) = utils.get_libcell_size("replica_cell_1w_1r", GDS["unit"], layer["boundary"])
pin_map = utils.get_libcell_pins(pin_names, "replica_cell_1w_1r", GDS["unit"])
@@ -22,6 +23,7 @@ class replica_bitcell_1w_1r(design.design):
self.width = replica_bitcell_1w_1r.width
self.height = replica_bitcell_1w_1r.height
self.pin_map = replica_bitcell_1w_1r.pin_map
self.add_pin_types(self.type_list)
def get_wl_cin(self):
"""Return the relative capacitance of the access transistor gates"""
@@ -32,12 +34,11 @@ class replica_bitcell_1w_1r(design.design):
return 2*access_tx_cin
def build_graph(self, graph, inst_name, port_nets):
"""Adds edges to graph. Handmade cells must implement this manually."""
#The bitcell has 8 net ports hard-coded in self.pin_names. The edges
#are based on the hard-coded name positions.
# The edges added are: wl0->bl0, wl0->br0, wl1->bl1, wl1->br1.
# Internal nodes of the handmade cell not considered, only ports. vdd/gnd ignored for graph.
graph.add_edge(port_nets[4],port_nets[0])
graph.add_edge(port_nets[4],port_nets[1])
graph.add_edge(port_nets[5],port_nets[2])
graph.add_edge(port_nets[5],port_nets[3])
"""Adds edges to graph. Multiport bitcell timing graph is too complex
to use the add_graph_edges function."""
pin_dict = {pin:port for pin,port in zip(self.pins, port_nets)}
#Edges hardcoded here. Essentially wl->bl/br for both ports.
# Port 0 edges
graph.add_edge(pin_dict["wl0"], pin_dict["bl0"])
graph.add_edge(pin_dict["wl0"], pin_dict["br0"])
# Port 1 is a write port, so its timing is not considered here.