mirror of https://github.com/VLSIDA/OpenRAM.git
Added graph creation and functions in base class and lower level modules.
This commit is contained in:
parent
4f28295e20
commit
e292767166
|
|
@ -24,7 +24,7 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
||||||
self.name = name
|
self.name = name
|
||||||
hierarchy_layout.layout.__init__(self, name)
|
hierarchy_layout.layout.__init__(self, name)
|
||||||
hierarchy_spice.spice.__init__(self, name)
|
hierarchy_spice.spice.__init__(self, name)
|
||||||
|
self.init_graph_params()
|
||||||
|
|
||||||
def get_layout_pins(self,inst):
|
def get_layout_pins(self,inst):
|
||||||
""" Return a map of pin locations of the instance offset """
|
""" Return a map of pin locations of the instance offset """
|
||||||
|
|
@ -100,6 +100,7 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
||||||
os.remove(tempgds)
|
os.remove(tempgds)
|
||||||
|
|
||||||
#Example graph run
|
#Example graph run
|
||||||
|
# import graph_util
|
||||||
# graph = graph_util.graph()
|
# graph = graph_util.graph()
|
||||||
# pins = ['A','Z','vdd','gnd']
|
# pins = ['A','Z','vdd','gnd']
|
||||||
# d.build_graph(graph,"Xpdriver",pins)
|
# d.build_graph(graph,"Xpdriver",pins)
|
||||||
|
|
@ -108,6 +109,11 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
||||||
# debug.info(1,"{}".format(graph))
|
# debug.info(1,"{}".format(graph))
|
||||||
# graph.printAllPaths('A', 'Z')
|
# graph.printAllPaths('A', 'Z')
|
||||||
|
|
||||||
|
def init_graph_params(self):
|
||||||
|
"""Initializes parameters relevant to the graph creation"""
|
||||||
|
#Only initializes a set for checking instances which should not be added
|
||||||
|
self.graph_inst_exclude = set()
|
||||||
|
|
||||||
def build_graph(self, graph, inst_name, port_nets):
|
def build_graph(self, graph, inst_name, port_nets):
|
||||||
"""Recursively create graph from instances in module."""
|
"""Recursively create graph from instances in module."""
|
||||||
|
|
||||||
|
|
@ -115,9 +121,10 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
||||||
if len(port_nets) != len(self.pins):
|
if len(port_nets) != len(self.pins):
|
||||||
debug.error("Port length mismatch:\nExt nets={}, Ports={}".format(port_nets,self.pins),1)
|
debug.error("Port length mismatch:\nExt nets={}, Ports={}".format(port_nets,self.pins),1)
|
||||||
port_dict = {i:j for i,j in zip(self.pins, port_nets)}
|
port_dict = {i:j for i,j in zip(self.pins, port_nets)}
|
||||||
debug.info(1, "Instance name={}".format(inst_name))
|
debug.info(3, "Instance name={}".format(inst_name))
|
||||||
for subinst, conns in zip(self.insts, self.conns):
|
for subinst, conns in zip(self.insts, self.conns):
|
||||||
debug.info(1, "Sub-Instance={}".format(subinst))
|
if subinst in self.graph_inst_exclude:
|
||||||
|
continue
|
||||||
subinst_name = inst_name+'.X'+subinst.name
|
subinst_name = inst_name+'.X'+subinst.name
|
||||||
subinst_ports = self.translate_nets(conns, port_dict, inst_name)
|
subinst_ports = self.translate_nets(conns, port_dict, inst_name)
|
||||||
subinst.mod.build_graph(graph, subinst_name, subinst_ports)
|
subinst.mod.build_graph(graph, subinst_name, subinst_ports)
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ class bitcell(design.design):
|
||||||
self.width = bitcell.width
|
self.width = bitcell.width
|
||||||
self.height = bitcell.height
|
self.height = bitcell.height
|
||||||
self.pin_map = bitcell.pin_map
|
self.pin_map = bitcell.pin_map
|
||||||
|
|
||||||
def analytical_delay(self, corner, slew, load=0, swing = 0.5):
|
def analytical_delay(self, corner, slew, load=0, swing = 0.5):
|
||||||
parasitic_delay = 1
|
parasitic_delay = 1
|
||||||
size = 0.5 #This accounts for bitline being drained thought the access TX and internal node
|
size = 0.5 #This accounts for bitline being drained thought the access TX and internal node
|
||||||
|
|
@ -74,3 +74,12 @@ class bitcell(design.design):
|
||||||
#Calculated in the tech file by summing the widths of all the related gates and dividing by the minimum width.
|
#Calculated in the tech file by summing the widths of all the related gates and dividing by the minimum width.
|
||||||
access_tx_cin = parameter["6T_access_size"]/drc["minwidth_tx"]
|
access_tx_cin = parameter["6T_access_size"]/drc["minwidth_tx"]
|
||||||
return 2*access_tx_cin
|
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])
|
||||||
|
|
@ -99,3 +99,15 @@ class bitcell_1rw_1r(design.design):
|
||||||
#FIXME: sizing is not accurate with the handmade cell. Change once cell widths are fixed.
|
#FIXME: sizing is not accurate with the handmade cell. Change once cell widths are fixed.
|
||||||
access_tx_cin = parameter["6T_access_size"]/drc["minwidth_tx"]
|
access_tx_cin = parameter["6T_access_size"]/drc["minwidth_tx"]
|
||||||
return 2*access_tx_cin
|
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])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,3 +99,14 @@ class bitcell_1w_1r(design.design):
|
||||||
#FIXME: sizing is not accurate with the handmade cell. Change once cell widths are fixed.
|
#FIXME: sizing is not accurate with the handmade cell. Change once cell widths are fixed.
|
||||||
access_tx_cin = parameter["6T_access_size"]/drc["minwidth_tx"]
|
access_tx_cin = parameter["6T_access_size"]/drc["minwidth_tx"]
|
||||||
return 2*access_tx_cin
|
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])
|
||||||
|
|
|
||||||
|
|
@ -893,3 +893,15 @@ class pbitcell(design.design):
|
||||||
access_tx_cin = self.readwrite_nmos.get_cin()
|
access_tx_cin = self.readwrite_nmos.get_cin()
|
||||||
return 2*access_tx_cin
|
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])
|
||||||
|
|
|
||||||
|
|
@ -29,3 +29,12 @@ class replica_bitcell(design.design):
|
||||||
#Calculated in the tech file by summing the widths of all the related gates and dividing by the minimum width.
|
#Calculated in the tech file by summing the widths of all the related gates and dividing by the minimum width.
|
||||||
access_tx_cin = parameter["6T_access_size"]/drc["minwidth_tx"]
|
access_tx_cin = parameter["6T_access_size"]/drc["minwidth_tx"]
|
||||||
return 2*access_tx_cin
|
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])
|
||||||
|
|
@ -30,3 +30,14 @@ class replica_bitcell_1rw_1r(design.design):
|
||||||
#FIXME: sizing is not accurate with the handmade cell. Change once cell widths are fixed.
|
#FIXME: sizing is not accurate with the handmade cell. Change once cell widths are fixed.
|
||||||
access_tx_cin = parameter["6T_access_size"]/drc["minwidth_tx"]
|
access_tx_cin = parameter["6T_access_size"]/drc["minwidth_tx"]
|
||||||
return 2*access_tx_cin
|
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])
|
||||||
|
|
@ -30,3 +30,14 @@ class replica_bitcell_1w_1r(design.design):
|
||||||
#FIXME: sizing is not accurate with the handmade cell. Change once cell widths are fixed.
|
#FIXME: sizing is not accurate with the handmade cell. Change once cell widths are fixed.
|
||||||
access_tx_cin = parameter["6T_access_size"]/drc["minwidth_tx"]
|
access_tx_cin = parameter["6T_access_size"]/drc["minwidth_tx"]
|
||||||
return 2*access_tx_cin
|
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])
|
||||||
|
|
@ -36,9 +36,11 @@ class graph():
|
||||||
|
|
||||||
# Create an array to store paths
|
# Create an array to store paths
|
||||||
path = []
|
path = []
|
||||||
|
self.path_count = 0
|
||||||
|
|
||||||
# Call the recursive helper function to print all paths
|
# Call the recursive helper function to print all paths
|
||||||
self.printAllPathsUtil(s, d,visited, path)
|
self.printAllPathsUtil(s, d,visited, path)
|
||||||
|
debug.info(1, "Paths found={}".format(self.path_count))
|
||||||
|
|
||||||
def printAllPathsUtil(self, u, d, visited, path):
|
def printAllPathsUtil(self, u, d, visited, path):
|
||||||
|
|
||||||
|
|
@ -50,6 +52,7 @@ class graph():
|
||||||
# current path[]
|
# current path[]
|
||||||
if u == d:
|
if u == d:
|
||||||
debug.info(1,"{}".format(path))
|
debug.info(1,"{}".format(path))
|
||||||
|
self.path_count+=1
|
||||||
else:
|
else:
|
||||||
# If current vertex is not destination
|
# If current vertex is not destination
|
||||||
#Recur for all the vertices adjacent to this vertex
|
#Recur for all the vertices adjacent to this vertex
|
||||||
|
|
@ -1279,3 +1279,9 @@ class bank(design.design):
|
||||||
"""Get the relative capacitance of all the sense amp enable connections in the bank"""
|
"""Get the relative capacitance of all the sense amp enable connections in the bank"""
|
||||||
#Current bank only uses sen as an enable for the sense amps.
|
#Current bank only uses sen as an enable for the sense amps.
|
||||||
return self.sense_amp_array.get_en_cin()
|
return self.sense_amp_array.get_en_cin()
|
||||||
|
|
||||||
|
def graph_exclude_precharge(self):
|
||||||
|
"""Precharge adds a loop between bitlines, can be excluded to reduce complexity"""
|
||||||
|
for inst in self.precharge_array_inst:
|
||||||
|
if inst != None:
|
||||||
|
self.graph_inst_exclude.add(inst)
|
||||||
|
|
@ -193,3 +193,13 @@ class bitcell_array(design.design):
|
||||||
bitcell_wl_cin = self.cell.get_wl_cin()
|
bitcell_wl_cin = self.cell.get_wl_cin()
|
||||||
total_cin = bitcell_wl_cin * self.column_size
|
total_cin = bitcell_wl_cin * self.column_size
|
||||||
return total_cin
|
return total_cin
|
||||||
|
|
||||||
|
def graph_exclude_bits(self, targ_row, targ_col):
|
||||||
|
"""Excludes bits in column from being added to graph except target"""
|
||||||
|
#Function is not robust with column mux configurations
|
||||||
|
for row in range(self.row_size):
|
||||||
|
if row == targ_row:
|
||||||
|
continue
|
||||||
|
self.graph_inst_exclude.add(self.cell_inst[row,targ_col])
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -50,3 +50,11 @@ class dff(design.design):
|
||||||
#Calculated in the tech file by summing the widths of all the gates and dividing by the minimum width.
|
#Calculated in the tech file by summing the widths of all the gates and dividing by the minimum width.
|
||||||
return parameter["dff_clk_cin"]
|
return parameter["dff_clk_cin"]
|
||||||
|
|
||||||
|
def build_graph(self, graph, inst_name, port_nets):
|
||||||
|
"""Adds edges to graph. Handmade cells must implement this manually."""
|
||||||
|
#The cell has 5 net ports hard-coded in self.pin_names. The edges
|
||||||
|
#are based on the hard-coded name positions.
|
||||||
|
# The edges added are: clk->Q.
|
||||||
|
# Internal nodes of the handmade cell not considered, only ports. vdd/gnd ignored for graph.
|
||||||
|
graph.add_edge(port_nets[2],port_nets[1])
|
||||||
|
|
||||||
|
|
@ -621,3 +621,4 @@ class hierarchical_decoder(design.design):
|
||||||
else:
|
else:
|
||||||
pre = self.pre3_8
|
pre = self.pre3_8
|
||||||
return pre.input_load()
|
return pre.input_load()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,3 +107,4 @@ class precharge_array(design.design):
|
||||||
#Assume single port
|
#Assume single port
|
||||||
precharge_en_cin = self.pc_cell.get_en_cin()
|
precharge_en_cin = self.pc_cell.get_en_cin()
|
||||||
return precharge_en_cin*self.columns
|
return precharge_en_cin*self.columns
|
||||||
|
|
||||||
|
|
@ -51,4 +51,15 @@ class sense_amp(design.design):
|
||||||
pmos_cin = parameter["sa_en_pmos_size"]/drc("minwidth_tx")
|
pmos_cin = parameter["sa_en_pmos_size"]/drc("minwidth_tx")
|
||||||
nmos_cin = parameter["sa_en_nmos_size"]/drc("minwidth_tx")
|
nmos_cin = parameter["sa_en_nmos_size"]/drc("minwidth_tx")
|
||||||
#sen is connected to 2 pmos isolation TX and 1 nmos per sense amp.
|
#sen is connected to 2 pmos isolation TX and 1 nmos per sense amp.
|
||||||
return 2*pmos_cin + nmos_cin
|
return 2*pmos_cin + nmos_cin
|
||||||
|
|
||||||
|
def build_graph(self, graph, inst_name, port_nets):
|
||||||
|
"""Adds edges to graph. Handmade cells must implement this manually."""
|
||||||
|
#The cell has 6 net ports hard-coded in self.pin_names. The edges
|
||||||
|
#are based on the hard-coded name positions.
|
||||||
|
# The edges added are: en->dout, bl->dout
|
||||||
|
# br->dout not included to reduce complexity
|
||||||
|
# Internal nodes of the handmade cell not considered, only ports. vdd/gnd ignored for graph.
|
||||||
|
graph.add_edge(port_nets[0],port_nets[2])
|
||||||
|
graph.add_edge(port_nets[3],port_nets[2])
|
||||||
|
|
||||||
|
|
@ -10,7 +10,7 @@ class tri_gate(design.design):
|
||||||
netlist should be available in the technology library.
|
netlist should be available in the technology library.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pin_names = ["in", "en", "en_bar", "out", "gnd", "vdd"]
|
pin_names = ["in", "out", "en", "en_bar", "gnd", "vdd"]
|
||||||
(width,height) = utils.get_libcell_size("tri_gate", GDS["unit"], layer["boundary"])
|
(width,height) = utils.get_libcell_size("tri_gate", GDS["unit"], layer["boundary"])
|
||||||
pin_map = utils.get_libcell_pins(pin_names, "tri_gate", GDS["unit"])
|
pin_map = utils.get_libcell_pins(pin_names, "tri_gate", GDS["unit"])
|
||||||
|
|
||||||
|
|
@ -42,3 +42,13 @@ class tri_gate(design.design):
|
||||||
def input_load(self):
|
def input_load(self):
|
||||||
return 9*spice["min_tx_gate_c"]
|
return 9*spice["min_tx_gate_c"]
|
||||||
|
|
||||||
|
def build_graph(self, graph, inst_name, port_nets):
|
||||||
|
"""Adds edges to graph. Handmade cells must implement this manually."""
|
||||||
|
#The cell has 6 net ports hard-coded in self.pin_names. The edges
|
||||||
|
#are based on the hard-coded name positions.
|
||||||
|
# The edges added are: en->out, en_bar->out, in->out.
|
||||||
|
# A liberal amount of edges were added, may be reduced later for complexity.
|
||||||
|
# Internal nodes of the handmade cell not considered, only ports. vdd/gnd ignored for graph.
|
||||||
|
graph.add_edge(port_nets[0],port_nets[1])
|
||||||
|
graph.add_edge(port_nets[2],port_nets[1])
|
||||||
|
graph.add_edge(port_nets[3],port_nets[1])
|
||||||
|
|
@ -28,3 +28,15 @@ class write_driver(design.design):
|
||||||
"""Get the relative capacitance of a single input"""
|
"""Get the relative capacitance of a single input"""
|
||||||
# This is approximated from SCMOS. It has roughly 5 3x transistor gates.
|
# This is approximated from SCMOS. It has roughly 5 3x transistor gates.
|
||||||
return 5*3
|
return 5*3
|
||||||
|
|
||||||
|
def build_graph(self, graph, inst_name, port_nets):
|
||||||
|
"""Adds edges to graph. Handmade cells must implement this manually."""
|
||||||
|
#The cell has 6 net ports hard-coded in self.pin_names. The edges
|
||||||
|
#are based on the hard-coded name positions.
|
||||||
|
# The edges added are: din->bl, din->br, en->bl, en->br
|
||||||
|
# A liberal amount of edges were added, may be reduced later for complexity.
|
||||||
|
# Internal nodes of the handmade cell not considered, only ports. vdd/gnd ignored for graph.
|
||||||
|
graph.add_edge(port_nets[0],port_nets[1])
|
||||||
|
graph.add_edge(port_nets[0],port_nets[2])
|
||||||
|
graph.add_edge(port_nets[3],port_nets[1])
|
||||||
|
graph.add_edge(port_nets[3],port_nets[2])
|
||||||
|
|
@ -32,6 +32,8 @@ class pnand2(pgate.pgate):
|
||||||
if not OPTS.netlist_only:
|
if not OPTS.netlist_only:
|
||||||
self.create_layout()
|
self.create_layout()
|
||||||
|
|
||||||
|
#For characterization purposes only
|
||||||
|
self.exclude_nmos_from_graph()
|
||||||
|
|
||||||
def create_netlist(self):
|
def create_netlist(self):
|
||||||
self.add_pins()
|
self.add_pins()
|
||||||
|
|
@ -259,3 +261,10 @@ class pnand2(pgate.pgate):
|
||||||
"""
|
"""
|
||||||
parasitic_delay = 2
|
parasitic_delay = 2
|
||||||
return logical_effort.logical_effort(self.name, self.size, self.get_cin(), cout, parasitic_delay, not inp_is_rise)
|
return logical_effort.logical_effort(self.name, self.size, self.get_cin(), cout, parasitic_delay, not inp_is_rise)
|
||||||
|
|
||||||
|
def exclude_nmos_from_graph(self):
|
||||||
|
"""Exclude the nmos TXs from the graph to reduce complexity"""
|
||||||
|
#The pull-down network has an internal net which causes 2 different in->out paths
|
||||||
|
#Removing them simplifies generic path searching.
|
||||||
|
self.graph_inst_exclude.add(self.nmos1_inst)
|
||||||
|
self.graph_inst_exclude.add(self.nmos2_inst)
|
||||||
|
|
|
||||||
|
|
@ -305,3 +305,19 @@ class sram_1bank(sram_base):
|
||||||
self.add_label(text=n,
|
self.add_label(text=n,
|
||||||
layer=pin.layer,
|
layer=pin.layer,
|
||||||
offset=pin.center())
|
offset=pin.center())
|
||||||
|
|
||||||
|
def graph_exclude_data_dff(self):
|
||||||
|
"""Removes data dff from search graph. """
|
||||||
|
#Data dffs are only for writing so are not useful for evaluating read delay.
|
||||||
|
for inst in self.data_dff_insts:
|
||||||
|
self.graph_inst_exclude.add(inst)
|
||||||
|
|
||||||
|
def graph_exclude_addr_dff(self):
|
||||||
|
"""Removes data dff from search graph. """
|
||||||
|
#Address is considered not part of the critical path, subjectively removed
|
||||||
|
for inst in self.row_addr_dff_insts:
|
||||||
|
self.graph_inst_exclude.add(inst)
|
||||||
|
|
||||||
|
if self.col_addr_dff:
|
||||||
|
for inst in self.col_addr_dff_insts:
|
||||||
|
self.graph_inst_exclude.add(inst)
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ class bitcell_1rw_1r_array_test(openram_test):
|
||||||
OPTS.num_w_ports = 0
|
OPTS.num_w_ports = 0
|
||||||
a = factory.create(module_type="bitcell_array", cols=4, rows=4)
|
a = factory.create(module_type="bitcell_array", cols=4, rows=4)
|
||||||
self.local_check(a)
|
self.local_check(a)
|
||||||
|
|
||||||
globals.end_openram()
|
globals.end_openram()
|
||||||
|
|
||||||
# run the test from the command line
|
# run the test from the command line
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ class array_test(openram_test):
|
||||||
debug.info(2, "Testing 4x4 array for 6t_cell")
|
debug.info(2, "Testing 4x4 array for 6t_cell")
|
||||||
a = factory.create(module_type="bitcell_array", cols=4, rows=4)
|
a = factory.create(module_type="bitcell_array", cols=4, rows=4)
|
||||||
self.local_check(a)
|
self.local_check(a)
|
||||||
|
|
||||||
globals.end_openram()
|
globals.end_openram()
|
||||||
|
|
||||||
# run the test from the command line
|
# run the test from the command line
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ class tri_gate_array_test(openram_test):
|
||||||
debug.info(1, "Testing tri_gate_array for columns=8, word_size=8")
|
debug.info(1, "Testing tri_gate_array for columns=8, word_size=8")
|
||||||
a = factory.create(module_type="tri_gate_array", columns=8, word_size=8)
|
a = factory.create(module_type="tri_gate_array", columns=8, word_size=8)
|
||||||
self.local_check(a)
|
self.local_check(a)
|
||||||
|
|
||||||
debug.info(1, "Testing tri_gate_array for columns=16, word_size=8")
|
debug.info(1, "Testing tri_gate_array for columns=16, word_size=8")
|
||||||
a = factory.create(module_type="tri_gate_array", columns=16, word_size=8)
|
a = factory.create(module_type="tri_gate_array", columns=16, word_size=8)
|
||||||
self.local_check(a)
|
self.local_check(a)
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,23 @@ class timing_sram_test(openram_test):
|
||||||
c.recompute_sizes()
|
c.recompute_sizes()
|
||||||
debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank")
|
debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank")
|
||||||
s = factory.create(module_type="sram", sram_config=c)
|
s = factory.create(module_type="sram", sram_config=c)
|
||||||
|
|
||||||
|
#Exclude things known not to be in critical path.
|
||||||
|
#Intended for characterizing read paths. Somewhat hacky implementation
|
||||||
|
s.s.bank.bitcell_array.graph_exclude_bits(15,0)
|
||||||
|
s.s.bank.graph_exclude_precharge()
|
||||||
|
s.s.graph_exclude_addr_dff()
|
||||||
|
s.s.graph_exclude_data_dff()
|
||||||
|
|
||||||
|
debug.info(1,'pins={}'.format(s.s.pins))
|
||||||
|
import graph_util
|
||||||
|
graph = graph_util.graph()
|
||||||
|
pins=['DIN0[0]', 'ADDR0[0]', 'ADDR0[1]', 'ADDR0[2]', 'ADDR0[3]', 'csb0', 'web0', 'clk0', 'DOUT0[0]', 'vdd', 'gnd']
|
||||||
|
s.s.build_graph(graph,"Xsram",pins)
|
||||||
|
graph.remove_edges('vdd')
|
||||||
|
graph.remove_edges('gnd')
|
||||||
|
debug.info(1,"{}".format(graph))
|
||||||
|
graph.printAllPaths('clk0', 'DOUT0[0]')
|
||||||
|
|
||||||
tempspice = OPTS.openram_temp + "temp.sp"
|
tempspice = OPTS.openram_temp + "temp.sp"
|
||||||
s.sp_write(tempspice)
|
s.sp_write(tempspice)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue