mirror of https://github.com/VLSIDA/OpenRAM.git
Configured bitline directions into prot_data
This commit is contained in:
parent
cbb67ad483
commit
7f65176908
|
|
@ -974,6 +974,7 @@ class layout():
|
|||
def create_channel_route(self, netlist,
|
||||
offset,
|
||||
layer_stack,
|
||||
layer_dirs=None,
|
||||
vertical=False):
|
||||
"""
|
||||
The net list is a list of the nets. Each net is a list of pins
|
||||
|
|
@ -1012,25 +1013,38 @@ class layout():
|
|||
|
||||
def vcg_pin_overlap(pin1, pin2, vertical, pitch):
|
||||
""" Check for vertical or horizontal overlap of the two pins """
|
||||
|
||||
# FIXME: If the pins are not in a row, this may break.
|
||||
# However, a top pin shouldn't overlap another top pin,
|
||||
# for example, so the
|
||||
# extra comparison *shouldn't* matter.
|
||||
|
||||
# Pin 1 must be in the "BOTTOM" set
|
||||
x_overlap = pin1.by() < pin2.by() and abs(pin1.center().x-pin2.center().x)<pitch
|
||||
x_overlap = pin1.by() < pin2.by() and abs(pin1.center().x - pin2.center().x) < pitch
|
||||
|
||||
# Pin 1 must be in the "LEFT" set
|
||||
y_overlap = pin1.lx() < pin2.lx() and abs(pin1.center().y-pin2.center().y)<pitch
|
||||
y_overlap = pin1.lx() < pin2.lx() and abs(pin1.center().y - pin2.center().y) < pitch
|
||||
overlaps = (not vertical and x_overlap) or (vertical and y_overlap)
|
||||
return overlaps
|
||||
|
||||
if self.get_preferred_direction(layer_stack[0]) == "V":
|
||||
self.vertical_layer = layer_stack[0]
|
||||
self.horizontal_layer = layer_stack[2]
|
||||
if not layer_dirs:
|
||||
# Use the preferred layer directions
|
||||
if self.get_preferred_direction(layer_stack[0]) == "V":
|
||||
self.vertical_layer = layer_stack[0]
|
||||
self.horizontal_layer = layer_stack[2]
|
||||
else:
|
||||
self.vertical_layer = layer_stack[2]
|
||||
self.horizontal_layer = layer_stack[0]
|
||||
else:
|
||||
self.vertical_layer = layer_stack[2]
|
||||
self.horizontal_layer = layer_stack[0]
|
||||
# Use the layer directions specified to the router rather than
|
||||
# the preferred directions
|
||||
debug.check(layer_dirs[0] != layer_dirs[1], "Must have unique layer directions.")
|
||||
if layer_dirs[0] == "V":
|
||||
self.vertical_layer = layer_stack[0]
|
||||
self.horizontal_layer = layer_stack[2]
|
||||
else:
|
||||
self.horizontal_layer = layer_stack[0]
|
||||
self.vertical_layer = layer_stack[2]
|
||||
|
||||
layer_stuff = self.get_layer_pitch(self.vertical_layer)
|
||||
(self.vertical_pitch, self.vertical_width, self.vertical_space) = layer_stuff
|
||||
|
|
@ -1113,17 +1127,17 @@ class layout():
|
|||
self.horizontal_pitch)
|
||||
offset += vector(0, self.horizontal_pitch)
|
||||
|
||||
def create_vertical_channel_route(self, netlist, offset, layer_stack):
|
||||
def create_vertical_channel_route(self, netlist, offset, layer_stack, layer_dirs):
|
||||
"""
|
||||
Wrapper to create a vertical channel route
|
||||
"""
|
||||
self.create_channel_route(netlist, offset, layer_stack, vertical=True)
|
||||
self.create_channel_route(netlist, offset, layer_stack, layer_dirs, vertical=True)
|
||||
|
||||
def create_horizontal_channel_route(self, netlist, offset, layer_stack):
|
||||
def create_horizontal_channel_route(self, netlist, offset, layer_stack, layer_dirs):
|
||||
"""
|
||||
Wrapper to create a horizontal channel route
|
||||
"""
|
||||
self.create_channel_route(netlist, offset, layer_stack, vertical=False)
|
||||
self.create_channel_route(netlist, offset, layer_stack, layer_dirs, vertical=False)
|
||||
|
||||
def add_boundary(self, ll=vector(0, 0), ur=None):
|
||||
""" Add boundary for debugging dimensions """
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ class bitcell_array(bitcell_base_array):
|
|||
# the replica bitcell in the control logic
|
||||
# self.offset_all_coordinates()
|
||||
|
||||
|
||||
def create_netlist(self):
|
||||
""" Create and connect the netlist """
|
||||
self.add_modules()
|
||||
|
|
@ -56,22 +55,21 @@ class bitcell_array(bitcell_base_array):
|
|||
for col in range(self.column_size):
|
||||
for row in range(self.row_size):
|
||||
name = "bit_r{0}_c{1}".format(row, col)
|
||||
self.cell_inst[row,col]=self.add_inst(name=name,
|
||||
mod=self.cell)
|
||||
self.cell_inst[row, col]=self.add_inst(name=name,
|
||||
mod=self.cell)
|
||||
self.connect_inst(self.get_bitcell_pins(col, row))
|
||||
|
||||
def analytical_power(self, corner, load):
|
||||
"""Power of Bitcell array and bitline in nW."""
|
||||
from tech import drc, parameter
|
||||
|
||||
# Dynamic Power from Bitline
|
||||
bl_wire = self.gen_bl_wire()
|
||||
cell_load = 2 * bl_wire.return_input_cap()
|
||||
cell_load = 2 * bl_wire.return_input_cap()
|
||||
bl_swing = OPTS.rbl_delay_percentage
|
||||
freq = spice["default_event_frequency"]
|
||||
bitline_dynamic = self.calc_dynamic_power(corner, cell_load, freq, swing=bl_swing)
|
||||
|
||||
# Calculate the bitcell power which currently only includes leakage
|
||||
# Calculate the bitcell power which currently only includes leakage
|
||||
cell_power = self.cell.analytical_power(corner, load)
|
||||
|
||||
# Leakage power grows with entire array and bitlines.
|
||||
|
|
@ -85,7 +83,7 @@ class bitcell_array(bitcell_base_array):
|
|||
else:
|
||||
width = self.width
|
||||
wl_wire = self.generate_rc_net(int(self.column_size), width, drc("minwidth_m1"))
|
||||
wl_wire.wire_c = 2*spice["min_tx_gate_c"] + wl_wire.wire_c # 2 access tx gate per cell
|
||||
wl_wire.wire_c = 2 * spice["min_tx_gate_c"] + wl_wire.wire_c # 2 access tx gate per cell
|
||||
return wl_wire
|
||||
|
||||
def gen_bl_wire(self):
|
||||
|
|
@ -94,26 +92,26 @@ class bitcell_array(bitcell_base_array):
|
|||
else:
|
||||
height = self.height
|
||||
bl_pos = 0
|
||||
bl_wire = self.generate_rc_net(int(self.row_size-bl_pos), height, drc("minwidth_m1"))
|
||||
bl_wire = self.generate_rc_net(int(self.row_size - bl_pos), height, drc("minwidth_m1"))
|
||||
bl_wire.wire_c =spice["min_tx_drain_c"] + bl_wire.wire_c # 1 access tx d/s per cell
|
||||
return bl_wire
|
||||
|
||||
def get_wordline_cin(self):
|
||||
"""Get the relative input capacitance from the wordline connections in all the bitcell"""
|
||||
#A single wordline is connected to all the bitcells in a single row meaning the capacitance depends on the # of columns
|
||||
# A single wordline is connected to all the bitcells in a single row meaning the capacitance depends on the # of columns
|
||||
bitcell_wl_cin = self.cell.get_wl_cin()
|
||||
total_cin = bitcell_wl_cin * self.column_size
|
||||
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
|
||||
# Function is not robust with column mux configurations
|
||||
for row in range(self.row_size):
|
||||
for col in range(self.column_size):
|
||||
if row == targ_row and col == targ_col:
|
||||
continue
|
||||
self.graph_inst_exclude.add(self.cell_inst[row,col])
|
||||
self.graph_inst_exclude.add(self.cell_inst[row, col])
|
||||
|
||||
def get_cell_name(self, inst_name, row, col):
|
||||
"""Gets the spice name of the target bitcell."""
|
||||
return inst_name+'.x'+self.cell_inst[row,col].name, self.cell_inst[row,col]
|
||||
"""Gets the spice name of the target bitcell."""
|
||||
return inst_name + '.x' + self.cell_inst[row, col].name, self.cell_inst[row, col]
|
||||
|
|
|
|||
|
|
@ -699,8 +699,13 @@ class port_data(design.design):
|
|||
bottom_names = self._get_bitline_pins(bot_inst_group, bit)
|
||||
top_names = self._get_bitline_pins(top_inst_group, bit)
|
||||
|
||||
if bottom_names[0].layer == "m2":
|
||||
bitline_dirs = ("H", "V")
|
||||
elif bottom_names[0].layer == "m1":
|
||||
bitline_dirs = ("V", "H")
|
||||
|
||||
route_map = list(zip(bottom_names, top_names))
|
||||
self.create_horizontal_channel_route(route_map, offset, self.m1_stack)
|
||||
self.create_horizontal_channel_route(route_map, offset, self.m1_stack, bitline_dirs)
|
||||
|
||||
def connect_bitlines(self, inst1, inst2, num_bits,
|
||||
inst1_bls_template="{inst}_{bit}",
|
||||
|
|
|
|||
Loading…
Reference in New Issue