mirror of
https://github.com/VLSIDA/OpenRAM.git
synced 2026-09-01 10:39:35 +02:00
Merged with dev, addressed conflict in port data
This commit is contained in:
@@ -392,14 +392,12 @@ class bank(design.design):
|
||||
cols=self.num_cols + self.num_spare_cols,
|
||||
rows=self.num_rows)
|
||||
self.add_mod(self.bitcell_array)
|
||||
if self.num_spare_cols == 0:
|
||||
self.num_spare_cols = (self.bitcell_array.column_size % (self.word_size *self.words_per_row))
|
||||
|
||||
self.port_address = []
|
||||
for port in self.all_ports:
|
||||
self.port_address.append(factory.create(module_type="port_address",
|
||||
cols=self.bitcell_array.column_size,
|
||||
rows=self.bitcell_array.row_size,
|
||||
cols=self.num_cols + self.num_spare_cols,
|
||||
rows=self.num_rows,
|
||||
port=port))
|
||||
self.add_mod(self.port_address[port])
|
||||
|
||||
@@ -408,10 +406,6 @@ class bank(design.design):
|
||||
for port in self.all_ports:
|
||||
temp_pre = factory.create(module_type="port_data",
|
||||
sram_config=self.sram_config,
|
||||
dimension_override=True,
|
||||
cols=self.bitcell_array.column_size - self.num_spare_cols,
|
||||
rows=self.bitcell_array.row_size,
|
||||
num_spare_cols=self.num_spare_cols,
|
||||
port=port,
|
||||
bit_offsets=self.bit_offsets)
|
||||
self.port_data.append(temp_pre)
|
||||
@@ -500,7 +494,7 @@ class bank(design.design):
|
||||
mod=self.port_address[port])
|
||||
|
||||
temp = []
|
||||
for bit in range(ceil(log(self.bitcell_array.row_size, 2))):
|
||||
for bit in range(self.row_addr_size):
|
||||
temp.append("addr{0}_{1}".format(port, bit + self.col_addr_size))
|
||||
temp.append("wl_en{}".format(port))
|
||||
wordline_names = self.bitcell_array.get_wordline_names(port)
|
||||
@@ -626,7 +620,7 @@ class bank(design.design):
|
||||
self.copy_power_pins(inst, "gnd", add_vias=False)
|
||||
|
||||
if 'vpb' in self.bitcell_array_inst.mod.pins and 'vnb' in self.bitcell_array_inst.mod.pins:
|
||||
for pin_name, supply_name in zip(['vpb','vnb'],['vdd','gnd']):
|
||||
for pin_name, supply_name in zip(['vpb','vnb'],['gnd','vdd']):
|
||||
self.copy_power_pins(self.bitcell_array_inst, pin_name, new_name=supply_name)
|
||||
|
||||
# If we use the pinvbuf as the decoder, we need to add power pins.
|
||||
|
||||
@@ -11,8 +11,10 @@ import math
|
||||
from sram_factory import factory
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
from tech import layer_indices
|
||||
from tech import layer_stacks
|
||||
from tech import layer_properties as layer_props
|
||||
|
||||
from tech import drc
|
||||
|
||||
class hierarchical_decoder(design.design):
|
||||
"""
|
||||
@@ -29,7 +31,7 @@ class hierarchical_decoder(design.design):
|
||||
|
||||
b = factory.create(module_type=OPTS.bitcell)
|
||||
self.cell_height = b.height
|
||||
|
||||
self.predecode_bus_rail_pos = []
|
||||
self.num_outputs = num_outputs
|
||||
self.num_inputs = math.ceil(math.log(self.num_outputs, 2))
|
||||
(self.no_of_pre2x4, self.no_of_pre3x8, self.no_of_pre4x16)=self.determine_predecodes(self.num_inputs)
|
||||
@@ -504,9 +506,9 @@ class hierarchical_decoder(design.design):
|
||||
offset=vector(self.bus_pitch, 0),
|
||||
names=input_bus_names,
|
||||
length=self.height)
|
||||
|
||||
self.route_predecodes_to_bus()
|
||||
self.route_bus_to_decoder()
|
||||
self.route_predecodes_to_bus()
|
||||
|
||||
|
||||
def route_predecodes_to_bus(self):
|
||||
"""
|
||||
@@ -521,7 +523,7 @@ class hierarchical_decoder(design.design):
|
||||
pin = self.pre2x4_inst[pre_num].get_pin(out_name)
|
||||
x_offset = self.pre2x4_inst[pre_num].rx() + self.output_layer_pitch
|
||||
y_offset = self.pre2x4_inst[pre_num].by() + i * self.cell_height
|
||||
self.route_predecode_bus_inputs(predecode_name, pin, x_offset, y_offset)
|
||||
self.route_predecode_bus_inputs(predecode_name, pin, x_offset, y_offset, "pre2x4")
|
||||
|
||||
# FIXME: convert to connect_bus
|
||||
for pre_num in range(self.no_of_pre3x8):
|
||||
@@ -531,7 +533,7 @@ class hierarchical_decoder(design.design):
|
||||
pin = self.pre3x8_inst[pre_num].get_pin(out_name)
|
||||
x_offset = self.pre3x8_inst[pre_num].rx() + self.output_layer_pitch
|
||||
y_offset = self.pre3x8_inst[pre_num].by() + i * self.cell_height
|
||||
self.route_predecode_bus_inputs(predecode_name, pin, x_offset, y_offset)
|
||||
self.route_predecode_bus_inputs(predecode_name, pin, x_offset, y_offset, "pre3x8")
|
||||
|
||||
# FIXME: convert to connect_bus
|
||||
for pre_num in range(self.no_of_pre4x16):
|
||||
@@ -541,7 +543,7 @@ class hierarchical_decoder(design.design):
|
||||
pin = self.pre4x16_inst[pre_num].get_pin(out_name)
|
||||
x_offset = self.pre4x16_inst[pre_num].rx() + self.output_layer_pitch
|
||||
y_offset = self.pre4x16_inst[pre_num].by() + i * self.cell_height
|
||||
self.route_predecode_bus_inputs(predecode_name, pin, x_offset, y_offset)
|
||||
self.route_predecode_bus_inputs(predecode_name, pin, x_offset, y_offset, "pre4x16")
|
||||
|
||||
def route_bus_to_decoder(self):
|
||||
"""
|
||||
@@ -649,8 +651,9 @@ class hierarchical_decoder(design.design):
|
||||
to_layer=self.input_layer,
|
||||
offset=pin_pos,
|
||||
directions=("H", "H"))
|
||||
self.predecode_bus_rail_pos.append(rail_pos)
|
||||
|
||||
def route_predecode_bus_inputs(self, rail_name, pin, x_offset, y_offset):
|
||||
def route_predecode_bus_inputs(self, rail_name, pin, x_offset, y_offset, predecode_type):
|
||||
"""
|
||||
Connect the routing rail to the given metal1 pin using a jog
|
||||
to the right of the cell at the given x_offset.
|
||||
@@ -661,14 +664,58 @@ class hierarchical_decoder(design.design):
|
||||
mid_point1 = vector(x_offset, pin_pos.y)
|
||||
mid_point2 = vector(x_offset, y_offset)
|
||||
rail_pos = vector(self.predecode_bus[rail_name].cx(), mid_point2.y)
|
||||
self.add_path(self.output_layer, [pin_pos, mid_point1, mid_point2, rail_pos])
|
||||
if layer_props.hierarchical_decoder.vertical_supply:
|
||||
above_rail = vector(self.predecode_bus[rail_name].cx(), mid_point2.y + (self.cell_height / 2))
|
||||
self.add_path(self.bus_layer, [rail_pos, above_rail], width=self.li_width + self.m1_enclose_mcon * 2)
|
||||
#self.add_path(self.output_layer, [pin_pos, mid_point1, mid_point2, rail_pos])
|
||||
#if layer_props.hierarchical_decoder.vertical_supply:
|
||||
# above_rail = vector(self.predecode_bus[rail_name].cx(), mid_point2.y + (self.cell_height / 2))
|
||||
# self.add_path(self.bus_layer, [rail_pos, above_rail], width=self.li_width + self.m1_enclose_mcon * 2)
|
||||
|
||||
#pin_pos = pin.center()
|
||||
#rail_pos = vector(self.predecode_bus[rail_name].cx(), pin_pos.y)
|
||||
#self.add_path(self.output_layer, [pin_pos, rail_pos])
|
||||
|
||||
# create via for dimensions
|
||||
from_layer = self.output_layer
|
||||
to_layer = self.bus_layer
|
||||
|
||||
cur_layer = from_layer
|
||||
from_id = layer_indices[cur_layer]
|
||||
to_id = layer_indices[to_layer]
|
||||
|
||||
if from_id < to_id: # grow the stack up
|
||||
search_id = 0
|
||||
next_id = 2
|
||||
else: # grow the stack down
|
||||
search_id = 2
|
||||
next_id = 0
|
||||
curr_stack = next(filter(lambda stack: stack[search_id] == cur_layer, layer_stacks), None)
|
||||
via = factory.create(module_type="contact",
|
||||
layer_stack=curr_stack,
|
||||
dimensions=[1, 1],
|
||||
directions=self.bus_directions)
|
||||
overlapping_pin_space = getattr(self, "{}_space".format(self.output_layer))
|
||||
total_buffer_space = (overlapping_pin_space + via.height)
|
||||
while(True):
|
||||
drc_error = 0
|
||||
for and_input in self.predecode_bus_rail_pos:
|
||||
if and_input.x == rail_pos.x:
|
||||
if (abs(y_offset - and_input.y) < total_buffer_space) or (abs(y_offset - and_input.y) < via.height):
|
||||
drc_error = 1
|
||||
if drc_error == 0:
|
||||
break
|
||||
else:
|
||||
y_offset += drc["grid"]
|
||||
rail_pos.y = y_offset
|
||||
|
||||
if predecode_type == "pre2x4":
|
||||
right_pos = pin_pos
|
||||
elif predecode_type =="pre3x8":
|
||||
right_pos = pin_pos
|
||||
elif predecode_type == "pre4x16":
|
||||
right_pos = pin_pos
|
||||
# else:
|
||||
# error("invalid predcoder type {}".format(predecode_type))
|
||||
self.add_path(self.output_layer, [pin_pos, right_pos, vector(right_pos.x, y_offset), rail_pos])
|
||||
|
||||
# pin_pos = pin.center()
|
||||
# rail_pos = vector(self.predecode_bus[rail_name].cx(), pin_pos.y)
|
||||
# self.add_path(self.output_layer, [pin_pos, rail_pos])
|
||||
self.add_via_stack_center(from_layer=pin.layer,
|
||||
to_layer=self.output_layer,
|
||||
offset=pin_pos)
|
||||
|
||||
@@ -122,7 +122,7 @@ class hierarchical_predecode(design.design):
|
||||
self.input_rails = self.create_vertical_bus(layer=self.bus_layer,
|
||||
offset=offset,
|
||||
names=input_names,
|
||||
length=self.height - 2 * self.bus_pitch,
|
||||
length=self.height - self.bus_pitch,
|
||||
pitch=self.bus_pitch)
|
||||
|
||||
invert_names = ["Abar_{}".format(x) for x in range(self.number_of_inputs)]
|
||||
@@ -132,7 +132,7 @@ class hierarchical_predecode(design.design):
|
||||
self.decode_rails = self.create_vertical_bus(layer=self.bus_layer,
|
||||
offset=offset,
|
||||
names=decode_names,
|
||||
length=self.height - 2 * self.bus_pitch,
|
||||
length=self.height - self.bus_pitch,
|
||||
pitch=self.bus_pitch)
|
||||
|
||||
def create_input_inverters(self):
|
||||
@@ -195,7 +195,7 @@ class hierarchical_predecode(design.design):
|
||||
|
||||
def route_inputs_to_rails(self):
|
||||
""" Route the uninverted inputs to the second set of rails """
|
||||
|
||||
|
||||
top_and_gate = self.and_inst[-1]
|
||||
for num in range(self.number_of_inputs):
|
||||
if num == 0:
|
||||
@@ -215,13 +215,25 @@ class hierarchical_predecode(design.design):
|
||||
in_pos = vector(self.input_rails[in_pin].cx(), y_offset)
|
||||
a_pos = vector(self.decode_rails[a_pin].cx(), y_offset)
|
||||
self.add_path(self.input_layer, [in_pos, a_pos])
|
||||
self.add_via_stack_center(from_layer=self.input_layer,
|
||||
to_layer=self.bus_layer,
|
||||
offset=[self.input_rails[in_pin].cx(), y_offset])
|
||||
self.add_via_stack_center(from_layer=self.input_layer,
|
||||
to_layer=self.bus_layer,
|
||||
offset=[self.decode_rails[a_pin].cx(), y_offset])
|
||||
|
||||
if(layer_props.hierarchical_predecode.force_horizontal_input_contact):
|
||||
self.add_via_stack_center(from_layer=self.input_layer,
|
||||
to_layer=self.bus_layer,
|
||||
offset=[self.input_rails[in_pin].cx(), y_offset],
|
||||
directions= ("H", "H"))
|
||||
|
||||
self.add_via_stack_center(from_layer=self.input_layer,
|
||||
to_layer=self.bus_layer,
|
||||
offset=[self.decode_rails[a_pin].cx(), y_offset],
|
||||
directions=("H", "H"))
|
||||
else:
|
||||
self.add_via_stack_center(from_layer=self.input_layer,
|
||||
to_layer=self.bus_layer,
|
||||
offset=[self.input_rails[in_pin].cx(), y_offset])
|
||||
|
||||
self.add_via_stack_center(from_layer=self.input_layer,
|
||||
to_layer=self.bus_layer,
|
||||
offset=[self.decode_rails[a_pin].cx(), y_offset])
|
||||
def route_output_ands(self):
|
||||
"""
|
||||
Route all conections of the outputs and gates
|
||||
@@ -317,7 +329,6 @@ class hierarchical_predecode(design.design):
|
||||
y_offset += drc["grid"]
|
||||
rail_pos.y = y_offset
|
||||
right_pos = inv_out_pos + vector(self.inv.width - self.inv.get_pin("Z").rx(), 0)
|
||||
|
||||
self.add_path(self.output_layer, [inv_out_pos, right_pos, vector(right_pos.x, y_offset), rail_pos])
|
||||
|
||||
self.add_via_stack_center(from_layer=inv_out_pin.layer,
|
||||
@@ -332,7 +343,7 @@ class hierarchical_predecode(design.design):
|
||||
"""
|
||||
Route the different permutations of the NAND/AND decocer cells.
|
||||
"""
|
||||
|
||||
|
||||
# This 2D array defines the connection mapping
|
||||
and_input_line_combination = self.get_and_input_line_combination()
|
||||
for k in range(self.number_of_outputs):
|
||||
|
||||
@@ -21,24 +21,19 @@ class port_data(design.design):
|
||||
Port 0 always has the RBL on the left while port 1 is on the right.
|
||||
"""
|
||||
|
||||
def __init__(self, sram_config, port, num_spare_cols=None, bit_offsets=None, name="", rows=None, cols=None, dimension_override=False):
|
||||
sram_config.set_local_config(self)
|
||||
if dimension_override:
|
||||
self.num_rows = rows
|
||||
self.num_cols = cols
|
||||
self.word_size = sram_config.word_size
|
||||
def __init__(self, sram_config, port, num_spare_cols=None, bit_offsets=None, name="",):
|
||||
|
||||
sram_config.set_local_config(self)
|
||||
self.port = port
|
||||
if self.write_size is not None:
|
||||
self.num_wmasks = int(math.ceil(self.word_size / self.write_size))
|
||||
else:
|
||||
self.num_wmasks = 0
|
||||
|
||||
if num_spare_cols:
|
||||
self.num_spare_cols = num_spare_cols
|
||||
elif self.num_spare_cols is None:
|
||||
|
||||
if num_spare_cols is not None:
|
||||
self.num_spare_cols = num_spare_cols + self.num_spare_cols
|
||||
if self.num_spare_cols is None:
|
||||
self.num_spare_cols = 0
|
||||
|
||||
if not bit_offsets:
|
||||
bitcell = factory.create(module_type=OPTS.bitcell)
|
||||
if(cell_properties.use_strap == True and OPTS.num_ports == 1):
|
||||
@@ -869,4 +864,4 @@ class port_data(design.design):
|
||||
Clear mux exclusions to allow different bit tests.
|
||||
"""
|
||||
if self.column_mux_array:
|
||||
self.column_mux_array.init_graph_params()
|
||||
self.column_mux_array.init_graph_params()
|
||||
|
||||
@@ -238,5 +238,4 @@ class replica_column(bitcell_base_array):
|
||||
for row, cell in enumerate(self.cell_inst):
|
||||
if row != self.replica_bit:
|
||||
self.graph_inst_exclude.add(cell)
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user