mirror of https://github.com/VLSIDA/OpenRAM.git
Merge remote-tracking branch 'private/dev' into dev
This commit is contained in:
commit
e3bc5454f9
|
|
@ -244,6 +244,19 @@ class layout():
|
||||||
return inst
|
return inst
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def add_flat_inst(self, name, mod, offset=[0, 0]):
|
||||||
|
""" Copies all of the items in instance into this module """
|
||||||
|
for item in mod.objs:
|
||||||
|
item.offset += offset
|
||||||
|
self.objs.append(item)
|
||||||
|
for item in mod.insts:
|
||||||
|
item.offset += offset
|
||||||
|
self.insts.append(item)
|
||||||
|
debug.check(len(item.mod.pins) == 0, "Cannot add flat instance with subinstances.")
|
||||||
|
self.connect_inst([])
|
||||||
|
debug.info(3, "adding flat instance {}".format(name))
|
||||||
|
return None
|
||||||
|
|
||||||
def add_rect(self, layer, offset, width=None, height=None):
|
def add_rect(self, layer, offset, width=None, height=None):
|
||||||
"""
|
"""
|
||||||
Adds a rectangle on a given layer,offset with width and height
|
Adds a rectangle on a given layer,offset with width and height
|
||||||
|
|
@ -1078,8 +1091,11 @@ class layout():
|
||||||
"""
|
"""
|
||||||
import channel_route
|
import channel_route
|
||||||
cr = channel_route.channel_route(netlist, offset, layer_stack, directions, vertical=True, parent=self)
|
cr = channel_route.channel_route(netlist, offset, layer_stack, directions, vertical=True, parent=self)
|
||||||
self.add_inst(cr.name, cr)
|
# This causes problem in magic since it sometimes cannot extract connectivity of isntances
|
||||||
self.connect_inst([])
|
# with no active devices.
|
||||||
|
# self.add_inst(cr.name, cr)
|
||||||
|
# self.connect_inst([])
|
||||||
|
self.add_flat_inst(cr.name, cr)
|
||||||
|
|
||||||
def create_horizontal_channel_route(self, netlist, offset, layer_stack, directions=None):
|
def create_horizontal_channel_route(self, netlist, offset, layer_stack, directions=None):
|
||||||
"""
|
"""
|
||||||
|
|
@ -1087,8 +1103,11 @@ class layout():
|
||||||
"""
|
"""
|
||||||
import channel_route
|
import channel_route
|
||||||
cr = channel_route.channel_route(netlist, offset, layer_stack, directions, vertical=False, parent=self)
|
cr = channel_route.channel_route(netlist, offset, layer_stack, directions, vertical=False, parent=self)
|
||||||
self.add_inst(cr.name, cr)
|
# This causes problem in magic since it sometimes cannot extract connectivity of isntances
|
||||||
self.connect_inst([])
|
# with no active devices.
|
||||||
|
# self.add_inst(cr.name, cr)
|
||||||
|
# self.connect_inst([])
|
||||||
|
self.add_flat_inst(cr.name, cr)
|
||||||
|
|
||||||
def add_boundary(self, ll=vector(0, 0), ur=None):
|
def add_boundary(self, ll=vector(0, 0), ur=None):
|
||||||
""" Add boundary for debugging dimensions """
|
""" Add boundary for debugging dimensions """
|
||||||
|
|
|
||||||
|
|
@ -1362,8 +1362,9 @@ class delay(simulation):
|
||||||
else:
|
else:
|
||||||
debug.error("Measurement name not recognized: {}".format(mname), 1)
|
debug.error("Measurement name not recognized: {}".format(mname), 1)
|
||||||
|
|
||||||
# Estimate the period as double the delay with margin
|
# Margin for error in period. Calculated by averaging required margin for a small and large
|
||||||
period_margin = 0.1
|
# memory. FIXME: margin is quite large, should be looked into.
|
||||||
|
period_margin = 1.85
|
||||||
sram_data = {"min_period": (max_delay / 1e3) * 2 * period_margin,
|
sram_data = {"min_period": (max_delay / 1e3) * 2 * period_margin,
|
||||||
"leakage_power": power.leakage}
|
"leakage_power": power.leakage}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import math
|
||||||
from sram_factory import factory
|
from sram_factory import factory
|
||||||
from vector import vector
|
from vector import vector
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
from tech import layer
|
|
||||||
|
|
||||||
class write_mask_and_array(design.design):
|
class write_mask_and_array(design.design):
|
||||||
"""
|
"""
|
||||||
|
|
@ -95,9 +95,9 @@ class write_mask_and_array(design.design):
|
||||||
if not self.offsets:
|
if not self.offsets:
|
||||||
self.offsets = []
|
self.offsets = []
|
||||||
for i in range(self.columns):
|
for i in range(self.columns):
|
||||||
self.offsets.append(i * self.driver_spacing)
|
self.offsets.append((i + self.write_size - 1) * self.driver_spacing)
|
||||||
|
|
||||||
self.width = self.offsets[-1] + self.driver_spacing
|
self.width = self.offsets[-1] + self.bitcell.width
|
||||||
self.height = self.and2.height
|
self.height = self.and2.height
|
||||||
|
|
||||||
write_bits = self.columns / self.num_wmasks
|
write_bits = self.columns / self.num_wmasks
|
||||||
|
|
@ -139,11 +139,12 @@ class write_mask_and_array(design.design):
|
||||||
to_layer="m3",
|
to_layer="m3",
|
||||||
offset=en_pos)
|
offset=en_pos)
|
||||||
|
|
||||||
for supply in ["gnd", "vdd"]:
|
|
||||||
supply_pin=self.and2_insts[i].get_pin(supply)
|
|
||||||
self.add_power_pin(supply, supply_pin.center(), start_layer=supply_pin.layer)
|
|
||||||
|
|
||||||
for supply in ["gnd", "vdd"]:
|
for supply in ["gnd", "vdd"]:
|
||||||
supply_pin_left = self.and2_insts[0].get_pin(supply)
|
supply_pin = self.and2_insts[0].get_pin(supply)
|
||||||
supply_pin_right = self.and2_insts[self.num_wmasks - 1].get_pin(supply)
|
supply_pin_yoffset = supply_pin.cy()
|
||||||
self.add_path(supply_pin_left.layer, [supply_pin_left.lc(), supply_pin_right.rc()])
|
left_loc = vector(0, supply_pin_yoffset)
|
||||||
|
right_loc = vector(self.width, supply_pin_yoffset)
|
||||||
|
self.add_path(supply_pin.layer, [left_loc, right_loc])
|
||||||
|
self.add_power_pin(supply, left_loc, start_layer=supply_pin.layer)
|
||||||
|
self.add_power_pin(supply, right_loc, start_layer=supply_pin.layer)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -865,7 +865,7 @@ class router(router_tech):
|
||||||
debug.check(index<self.num_pin_components(pin_name),"Pin component index too large.")
|
debug.check(index<self.num_pin_components(pin_name),"Pin component index too large.")
|
||||||
|
|
||||||
pin_in_tracks = self.pin_groups[pin_name][index].grids
|
pin_in_tracks = self.pin_groups[pin_name][index].grids
|
||||||
debug.info(2, "Set target: " + str(pin_name) + " " + str(pin_in_tracks))
|
debug.info(3, "Set target: " + str(pin_name) + " " + str(pin_in_tracks))
|
||||||
self.rg.add_target(pin_in_tracks)
|
self.rg.add_target(pin_in_tracks)
|
||||||
|
|
||||||
def add_pin_component_target_except(self, pin_name, index):
|
def add_pin_component_target_except(self, pin_name, index):
|
||||||
|
|
@ -1000,8 +1000,7 @@ class router(router_tech):
|
||||||
# Double check source and taget are not same node, if so, we are done!
|
# Double check source and taget are not same node, if so, we are done!
|
||||||
for k, v in self.rg.map.items():
|
for k, v in self.rg.map.items():
|
||||||
if v.source and v.target:
|
if v.source and v.target:
|
||||||
debug.error("Grid cell is source and target! {}".format(k))
|
return True
|
||||||
return False
|
|
||||||
|
|
||||||
# returns the path in tracks
|
# returns the path in tracks
|
||||||
(path, cost) = self.rg.route(detour_scale)
|
(path, cost) = self.rg.route(detour_scale)
|
||||||
|
|
@ -1013,12 +1012,9 @@ class router(router_tech):
|
||||||
|
|
||||||
path_set = grid_utils.flatten_set(path)
|
path_set = grid_utils.flatten_set(path)
|
||||||
self.path_blockages.append(path_set)
|
self.path_blockages.append(path_set)
|
||||||
|
return True
|
||||||
else:
|
else:
|
||||||
self.write_debug_gds("failed_route.gds")
|
|
||||||
# clean up so we can try a reroute
|
|
||||||
self.rg.reinit()
|
|
||||||
return False
|
return False
|
||||||
return True
|
|
||||||
|
|
||||||
def annotate_pin_and_tracks(self, pin, tracks):
|
def annotate_pin_and_tracks(self, pin, tracks):
|
||||||
""""
|
""""
|
||||||
|
|
@ -1156,6 +1152,19 @@ class router(router_tech):
|
||||||
width=pin.width(),
|
width=pin.width(),
|
||||||
height=pin.height())
|
height=pin.height())
|
||||||
|
|
||||||
|
def get_pin(self, pin_name):
|
||||||
|
""" Return the lowest, leftest pin group """
|
||||||
|
keep_pin = None
|
||||||
|
for index,pg in enumerate(self.pin_groups[pin_name]):
|
||||||
|
for pin in pg.enclosures:
|
||||||
|
if not keep_pin:
|
||||||
|
keep_pin = pin
|
||||||
|
else:
|
||||||
|
if pin.lx() <= keep_pin.lx() and pin.by() <= keep_pin.by():
|
||||||
|
keep_pin = pin
|
||||||
|
|
||||||
|
return keep_pin
|
||||||
|
|
||||||
|
|
||||||
# FIXME: This should be replaced with vector.snap_to_grid at some point
|
# FIXME: This should be replaced with vector.snap_to_grid at some point
|
||||||
def snap_to_grid(offset):
|
def snap_to_grid(offset):
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,6 @@ class signal_grid(grid):
|
||||||
#else:
|
#else:
|
||||||
# print("Cost bounded")
|
# print("Cost bounded")
|
||||||
|
|
||||||
debug.warning("Unable to route path. Expand the detour_scale to allow detours.")
|
|
||||||
return (None,None)
|
return (None,None)
|
||||||
|
|
||||||
def expand_dirs(self,curpath):
|
def expand_dirs(self,curpath):
|
||||||
|
|
|
||||||
|
|
@ -5,20 +5,14 @@
|
||||||
#(acting for and on behalf of Oklahoma State University)
|
#(acting for and on behalf of Oklahoma State University)
|
||||||
#All rights reserved.
|
#All rights reserved.
|
||||||
#
|
#
|
||||||
import gdsMill
|
|
||||||
import tech
|
|
||||||
import math
|
|
||||||
import debug
|
import debug
|
||||||
from globals import OPTS,print_time
|
from globals import print_time
|
||||||
from contact import contact
|
|
||||||
from pin_group import pin_group
|
|
||||||
from pin_layout import pin_layout
|
|
||||||
from vector3d import vector3d
|
|
||||||
from router import router
|
from router import router
|
||||||
from direction import direction
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import grid
|
|
||||||
import grid_utils
|
import grid_utils
|
||||||
|
from scipy.sparse import csr_matrix
|
||||||
|
from scipy.sparse.csgraph import minimum_spanning_tree
|
||||||
|
|
||||||
|
|
||||||
class supply_tree_router(router):
|
class supply_tree_router(router):
|
||||||
"""
|
"""
|
||||||
|
|
@ -36,7 +30,6 @@ class supply_tree_router(router):
|
||||||
|
|
||||||
router.__init__(self, layers, design, gds_filename, self.rail_track_width)
|
router.__init__(self, layers, design, gds_filename, self.rail_track_width)
|
||||||
|
|
||||||
|
|
||||||
def create_routing_grid(self):
|
def create_routing_grid(self):
|
||||||
"""
|
"""
|
||||||
Create a sprase routing grid with A* expansion functions.
|
Create a sprase routing grid with A* expansion functions.
|
||||||
|
|
@ -133,7 +126,6 @@ class supply_tree_router(router):
|
||||||
self.set_blockages(blockage_grids,False)
|
self.set_blockages(blockage_grids,False)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def route_pins(self, pin_name):
|
def route_pins(self, pin_name):
|
||||||
"""
|
"""
|
||||||
This will route each of the remaining pin components to the other pins.
|
This will route each of the remaining pin components to the other pins.
|
||||||
|
|
@ -141,14 +133,45 @@ class supply_tree_router(router):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
remaining_components = sum(not x.is_routed() for x in self.pin_groups[pin_name])
|
remaining_components = sum(not x.is_routed() for x in self.pin_groups[pin_name])
|
||||||
debug.info(1,"Maze routing {0} with {1} pin components to connect.".format(pin_name,
|
debug.info(1,"Routing {0} with {1} pin components to connect.".format(pin_name,
|
||||||
remaining_components))
|
remaining_components))
|
||||||
|
|
||||||
for index,pg in enumerate(self.pin_groups[pin_name]):
|
# Create full graph
|
||||||
if pg.is_routed():
|
pin_size = len(self.pin_groups[pin_name])
|
||||||
continue
|
adj_matrix = [[0] * pin_size for i in range(pin_size)]
|
||||||
|
|
||||||
debug.info(1,"Routing component {0} {1}".format(pin_name, index))
|
for index1,pg1 in enumerate(self.pin_groups[pin_name]):
|
||||||
|
for index2,pg2 in enumerate(self.pin_groups[pin_name]):
|
||||||
|
if index1>=index2:
|
||||||
|
continue
|
||||||
|
dist = int(grid_utils.distance_set(list(pg1.grids)[0], pg2.grids))
|
||||||
|
adj_matrix[index1][index2] = dist
|
||||||
|
|
||||||
|
# Find MST
|
||||||
|
X = csr_matrix(adj_matrix)
|
||||||
|
Tcsr = minimum_spanning_tree(X)
|
||||||
|
mst = Tcsr.toarray().astype(int)
|
||||||
|
connections = []
|
||||||
|
for x in range(pin_size):
|
||||||
|
for y in range(pin_size):
|
||||||
|
if x >= y:
|
||||||
|
continue
|
||||||
|
if mst[x][y]>0:
|
||||||
|
connections.append((x, y))
|
||||||
|
|
||||||
|
debug.info(1,"MST has {0} segments.".format(len(connections)))
|
||||||
|
|
||||||
|
# Route MST components
|
||||||
|
for (src, dest) in connections:
|
||||||
|
self.route_signal(pin_name, src, dest)
|
||||||
|
|
||||||
|
#self.write_debug_gds("final.gds", True)
|
||||||
|
#return
|
||||||
|
|
||||||
|
def route_signal(self, pin_name, src_idx, dest_idx):
|
||||||
|
|
||||||
|
for detour_scale in [5 * pow(2, x) for x in range(5)]:
|
||||||
|
debug.info(2, "Routing {0} to {1} with scale {2}".format(src_idx, dest_idx, detour_scale))
|
||||||
|
|
||||||
# Clear everything in the routing grid.
|
# Clear everything in the routing grid.
|
||||||
self.rg.reinit()
|
self.rg.reinit()
|
||||||
|
|
@ -159,35 +182,16 @@ class supply_tree_router(router):
|
||||||
|
|
||||||
# Add the single component of the pin as the source
|
# Add the single component of the pin as the source
|
||||||
# which unmarks it as a blockage too
|
# which unmarks it as a blockage too
|
||||||
self.add_pin_component_source(pin_name,index)
|
self.add_pin_component_source(pin_name, src_idx)
|
||||||
|
|
||||||
# Marks all pin components except index as target
|
# Marks all pin components except index as target
|
||||||
self.add_pin_component_target_except(pin_name,index)
|
self.add_pin_component_target(pin_name, dest_idx)
|
||||||
# Add the prevous paths as a target too
|
|
||||||
self.add_path_target(self.paths)
|
|
||||||
|
|
||||||
print("SOURCE: ")
|
|
||||||
for k,v in self.rg.map.items():
|
|
||||||
if v.source:
|
|
||||||
print(k)
|
|
||||||
|
|
||||||
print("TARGET: ")
|
|
||||||
for k,v in self.rg.map.items():
|
|
||||||
if v.target:
|
|
||||||
print(k)
|
|
||||||
|
|
||||||
import pdb; pdb.set_trace()
|
|
||||||
if index==1:
|
|
||||||
self.write_debug_gds("debug{}.gds".format(pin_name),False)
|
|
||||||
|
|
||||||
# Actually run the A* router
|
# Actually run the A* router
|
||||||
if not self.run_router(detour_scale=5):
|
if self.run_router(detour_scale=detour_scale):
|
||||||
self.write_debug_gds("debug_route.gds",True)
|
return
|
||||||
|
|
||||||
#if index==3 and pin_name=="vdd":
|
|
||||||
# self.write_debug_gds("route.gds",False)
|
|
||||||
|
|
||||||
|
|
||||||
|
self.write_debug_gds("debug_route.gds", True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -402,25 +402,6 @@ class sram_1bank(sram_base):
|
||||||
bank_pins = [self.bank_inst.get_pin(x) for x in bank_names]
|
bank_pins = [self.bank_inst.get_pin(x) for x in bank_names]
|
||||||
route_map.extend(list(zip(bank_pins, dff_pins)))
|
route_map.extend(list(zip(bank_pins, dff_pins)))
|
||||||
|
|
||||||
if port == 0:
|
|
||||||
offset = vector(self.control_logic_insts[port].rx() + self.dff.width,
|
|
||||||
- self.data_bus_size[port] + 2 * self.m1_pitch)
|
|
||||||
else:
|
|
||||||
offset = vector(0,
|
|
||||||
self.bank.height + 2 * self.m1_space)
|
|
||||||
|
|
||||||
cr = channel_route.channel_route(netlist=route_map,
|
|
||||||
offset=offset,
|
|
||||||
layer_stack=self.m1_stack,
|
|
||||||
parent=self)
|
|
||||||
if add_routes:
|
|
||||||
self.add_inst(cr.name, cr)
|
|
||||||
self.connect_inst([])
|
|
||||||
else:
|
|
||||||
self.col_addr_bus_size[port] = cr.height
|
|
||||||
|
|
||||||
route_map = []
|
|
||||||
|
|
||||||
# wmask dff
|
# wmask dff
|
||||||
if self.num_wmasks > 0 and port in self.write_ports:
|
if self.num_wmasks > 0 and port in self.write_ports:
|
||||||
dff_names = ["dout_{}".format(x) for x in range(self.num_wmasks)]
|
dff_names = ["dout_{}".format(x) for x in range(self.num_wmasks)]
|
||||||
|
|
@ -464,26 +445,32 @@ class sram_1bank(sram_base):
|
||||||
|
|
||||||
if port == 0:
|
if port == 0:
|
||||||
offset = vector(self.control_logic_insts[port].rx() + self.dff.width,
|
offset = vector(self.control_logic_insts[port].rx() + self.dff.width,
|
||||||
- self.data_bus_size[port] + 2 * self.m1_pitch)
|
- self.data_bus_size[port] + 2 * self.m3_pitch)
|
||||||
cr = channel_route.channel_route(netlist=route_map,
|
cr = channel_route.channel_route(netlist=route_map,
|
||||||
offset=offset,
|
offset=offset,
|
||||||
layer_stack=layer_stack,
|
layer_stack=layer_stack,
|
||||||
parent=self)
|
parent=self)
|
||||||
if add_routes:
|
if add_routes:
|
||||||
self.add_inst(cr.name, cr)
|
# This causes problem in magic since it sometimes cannot extract connectivity of isntances
|
||||||
self.connect_inst([])
|
# with no active devices.
|
||||||
|
# self.add_inst(cr.name, cr)
|
||||||
|
# self.connect_inst([])
|
||||||
|
self.add_flat_inst(cr.name, cr)
|
||||||
else:
|
else:
|
||||||
self.data_bus_size[port] = max(cr.height, self.col_addr_bus_size[port]) + self.data_bus_gap
|
self.data_bus_size[port] = max(cr.height, self.col_addr_bus_size[port]) + self.data_bus_gap
|
||||||
else:
|
else:
|
||||||
offset = vector(0,
|
offset = vector(0,
|
||||||
self.bank.height + 2 * self.m1_space)
|
self.bank.height + self.m3_pitch)
|
||||||
cr = channel_route.channel_route(netlist=route_map,
|
cr = channel_route.channel_route(netlist=route_map,
|
||||||
offset=offset,
|
offset=offset,
|
||||||
layer_stack=layer_stack,
|
layer_stack=layer_stack,
|
||||||
parent=self)
|
parent=self)
|
||||||
if add_routes:
|
if add_routes:
|
||||||
self.add_inst(cr.name, cr)
|
# This causes problem in magic since it sometimes cannot extract connectivity of isntances
|
||||||
self.connect_inst([])
|
# with no active devices.
|
||||||
|
# self.add_inst(cr.name, cr)
|
||||||
|
# self.connect_inst([])
|
||||||
|
self.add_flat_inst(cr.name, cr)
|
||||||
else:
|
else:
|
||||||
self.data_bus_size[port] = max(cr.height, self.col_addr_bus_size[port]) + self.data_bus_gap
|
self.data_bus_size[port] = max(cr.height, self.col_addr_bus_size[port]) + self.data_bus_gap
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -221,31 +221,40 @@ class sram_base(design, verilog, lef):
|
||||||
|
|
||||||
# Copy the pins to the top level
|
# Copy the pins to the top level
|
||||||
# This will either be used to route or left unconnected.
|
# This will either be used to route or left unconnected.
|
||||||
for inst in self.insts:
|
for pin_name in ["vdd", "gnd"]:
|
||||||
self.copy_power_pins(inst, "vdd")
|
for inst in self.insts:
|
||||||
self.copy_power_pins(inst, "gnd")
|
self.copy_power_pins(inst, pin_name)
|
||||||
|
|
||||||
if not OPTS.route_supplies:
|
if not OPTS.route_supplies:
|
||||||
# Do not route the power supply (leave as must-connect pins)
|
# Do not route the power supply (leave as must-connect pins)
|
||||||
return
|
return
|
||||||
|
|
||||||
grid_stack = set()
|
|
||||||
try:
|
try:
|
||||||
from tech import power_grid
|
from tech import power_grid
|
||||||
grid_stack = power_grid
|
grid_stack = power_grid
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# if no power_grid is specified by tech we use sensible defaults
|
# if no power_grid is specified by tech we use sensible defaults
|
||||||
import tech
|
# Route a M3/M4 grid
|
||||||
if "m4" in tech.layer:
|
grid_stack = self.m3_stack
|
||||||
# Route a M3/M4 grid
|
|
||||||
grid_stack = self.m3_stack
|
if OPTS.route_supplies == "grid":
|
||||||
elif "m3" in tech.layer:
|
from supply_grid_router import supply_grid_router as router
|
||||||
grid_stack =("m3",)
|
elif OPTS.route_supplies:
|
||||||
|
from supply_tree_router import supply_tree_router as router
|
||||||
|
|
||||||
from supply_grid_router import supply_grid_router as router
|
|
||||||
rtr=router(grid_stack, self)
|
rtr=router(grid_stack, self)
|
||||||
rtr.route()
|
rtr.route()
|
||||||
|
|
||||||
|
vdd_pin = rtr.get_pin("vdd")
|
||||||
|
gnd_pin = rtr.get_pin("gnd")
|
||||||
|
for pin_name, pin in [("vdd", vdd_pin), ("gnd", gnd_pin)]:
|
||||||
|
self.remove_layout_pin(pin_name)
|
||||||
|
self.add_layout_pin(pin_name,
|
||||||
|
pin.layer,
|
||||||
|
pin.ll(),
|
||||||
|
pin.width(),
|
||||||
|
pin.height())
|
||||||
|
|
||||||
def compute_bus_sizes(self):
|
def compute_bus_sizes(self):
|
||||||
""" Compute the independent bus widths shared between two and four bank SRAMs """
|
""" Compute the independent bus widths shared between two and four bank SRAMs """
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,9 @@ class model_delay_test(openram_test):
|
||||||
|
|
||||||
# Only compare the delays
|
# Only compare the delays
|
||||||
spice_delays = {key:value for key, value in spice_data.items() if 'delay' in key}
|
spice_delays = {key:value for key, value in spice_data.items() if 'delay' in key}
|
||||||
|
spice_delays['min_period'] = spice_data['min_period']
|
||||||
model_delays = {key:value for key, value in model_data.items() if 'delay' in key}
|
model_delays = {key:value for key, value in model_data.items() if 'delay' in key}
|
||||||
|
model_delays['min_period'] = model_data['min_period']
|
||||||
debug.info(1,"Spice Delays={}".format(spice_delays))
|
debug.info(1,"Spice Delays={}".format(spice_delays))
|
||||||
debug.info(1,"Model Delays={}".format(model_delays))
|
debug.info(1,"Model Delays={}".format(model_delays))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,6 @@ num_words = 16
|
||||||
tech_name = OPTS.tech_name
|
tech_name = OPTS.tech_name
|
||||||
|
|
||||||
nominal_corner_only = True
|
nominal_corner_only = True
|
||||||
route_supplies = True
|
route_supplies = "tree"
|
||||||
check_lvsdrc = True
|
check_lvsdrc = True
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ def write_drc_script(cell_name, gds_name, extract, final_verification, output_pa
|
||||||
f.write("drc off\n")
|
f.write("drc off\n")
|
||||||
f.write("gds polygon subcell true\n")
|
f.write("gds polygon subcell true\n")
|
||||||
f.write("gds warning default\n")
|
f.write("gds warning default\n")
|
||||||
f.write("#gds flatten true\n")
|
f.write("gds flatten true\n")
|
||||||
f.write("gds readonly true\n")
|
f.write("gds readonly true\n")
|
||||||
f.write("#gds ordering true\n")
|
f.write("#gds ordering true\n")
|
||||||
f.write("gds read {}\n".format(gds_name))
|
f.write("gds read {}\n".format(gds_name))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue