Merge branch 'dev' into s8_update

This commit is contained in:
Joey Kunzler 2020-06-03 11:53:33 -07:00
commit 6430aad857
9 changed files with 79 additions and 79 deletions

View File

@ -40,7 +40,6 @@ class hierarchical_predecode(design.design):
def add_modules(self):
""" Add the INV and AND gate modules """
# FIXME: Default parms are required for hard cells for now.
if self.number_of_inputs == 2:
self.and_mod = factory.create(module_type="and2_dec",
height=self.cell_height)
@ -60,7 +59,6 @@ class hierarchical_predecode(design.design):
size=1)
self.add_mod(self.inv)
def create_layout(self):
""" The general organization is from left to right:
1) a set of M2 rails for input signals

View File

@ -180,6 +180,7 @@ class port_data(design.design):
# Precharge will be shifted left if needed
self.precharge_array = factory.create(module_type="precharge_array",
columns=self.num_cols + 1,
port=self.port,
bitcell_bl=self.bl_names[self.port],
bitcell_br=self.br_names[self.port])
self.add_mod(self.precharge_array)
@ -195,6 +196,7 @@ class port_data(design.design):
if self.col_addr_size > 0:
self.column_mux_array = factory.create(module_type="column_mux_array",
columns=self.num_cols,
port=self.port,
word_size=self.word_size,
bitcell_bl=self.bl_names[self.port],
bitcell_br=self.br_names[self.port])
@ -250,6 +252,7 @@ class port_data(design.design):
# module, which happens before we create the real precharge_array
self.precharge_array = factory.create(module_type="precharge_array",
columns=self.num_cols + 1,
port=self.port,
bitcell_bl=self.bl_names[self.port],
bitcell_br=self.br_names[self.port])
@ -536,11 +539,18 @@ class port_data(design.design):
# This could be a channel route, but in some techs the bitlines
# are too close together.
self.channel_route_bitlines(inst1=inst1,
inst1_bls_template=inst1_bls_templ,
inst2=inst2,
num_bits=self.word_size,
inst1_start_bit=start_bit)
if OPTS.tech_name == "s8":
self.connect_bitlines(inst1=inst1,
inst1_bls_template=inst1_bls_templ,
inst2=inst2,
num_bits=self.word_size,
inst1_start_bit=start_bit)
else:
self.channel_route_bitlines(inst1=inst1,
inst1_bls_template=inst1_bls_templ,
inst2=inst2,
num_bits=self.word_size,
inst1_start_bit=start_bit)
def route_write_driver_to_column_mux_or_precharge_array(self, port):
""" Routing of BL and BR between sense_amp and column mux or precharge array """
@ -562,11 +572,17 @@ class port_data(design.design):
# This could be a channel route, but in some techs the bitlines
# are too close together.
self.channel_route_bitlines(inst1=inst1, inst2=inst2,
num_bits=self.word_size,
inst1_bls_template=inst1_bls_templ,
inst1_start_bit=start_bit)
if OPTS.tech_name == "s8":
self.connect_bitlines(inst1=inst1, inst2=inst2,
num_bits=self.word_size,
inst1_bls_template=inst1_bls_templ,
inst1_start_bit=start_bit)
else:
self.channel_route_bitlines(inst1=inst1, inst2=inst2,
num_bits=self.word_size,
inst1_bls_template=inst1_bls_templ,
inst1_start_bit=start_bit)
def route_write_driver_to_sense_amp(self, port):
""" Routing of BL and BR between write driver and sense amp """

View File

@ -7,7 +7,6 @@
#
import design
import debug
from tech import drc
from vector import vector
from sram_factory import factory
from globals import OPTS
@ -19,13 +18,14 @@ class precharge_array(design.design):
of bit line columns, height is the height of the bit-cell array.
"""
def __init__(self, name, columns, size=1, bitcell_bl="bl", bitcell_br="br"):
def __init__(self, name, columns, port, size=1, bitcell_bl="bl", bitcell_br="br"):
design.design.__init__(self, name)
debug.info(1, "Creating {0}".format(self.name))
self.add_comment("cols: {0} size: {1} bl: {2} br: {3}".format(columns, size, bitcell_bl, bitcell_br))
self.columns = columns
self.size = size
self.port = port
self.bitcell_bl = bitcell_bl
self.bitcell_br = bitcell_br
@ -106,7 +106,7 @@ class precharge_array(design.design):
xoffset = 0
for i in range(self.columns):
tempx = xoffset
if cell_properties.bitcell.mirror.y and (i + 1) % 2:
if cell_properties.bitcell.mirror.y and (i + 1 + self.port) % 2:
mirror = "MY"
tempx = tempx + self.pc_cell.width
else:

View File

@ -7,7 +7,7 @@
#
import design
import debug
from tech import layer
from tech import layer, preferred_directions
from vector import vector
from sram_factory import factory
from globals import OPTS
@ -20,12 +20,13 @@ class single_level_column_mux_array(design.design):
Array of column mux to read the bitlines through the 6T.
"""
def __init__(self, name, columns, word_size, bitcell_bl="bl", bitcell_br="br"):
def __init__(self, name, columns, port, word_size, bitcell_bl="bl", bitcell_br="br"):
design.design.__init__(self, name)
debug.info(1, "Creating {0}".format(self.name))
self.add_comment("cols: {0} word_size: {1} bl: {2} br: {3}".format(columns, word_size, bitcell_bl, bitcell_br))
self.columns = columns
self.port = port
self.word_size = word_size
self.words_per_row = int(self.columns / self.word_size)
self.bitcell_bl = bitcell_bl
@ -33,10 +34,15 @@ class single_level_column_mux_array(design.design):
if "li" in layer:
self.col_mux_stack = self.li_stack
self.col_mux_stack_pitch = self.li_pitch
self.col_mux_stack_pitch = self.m1_pitch
else:
self.col_mux_stack = self.m1_stack
self.col_mux_stack_pitch = self.m1_pitch
if preferred_directions[self.col_mux_stack[0]] == "V":
self.via_directions = ("H", "H")
else:
self.via_directions = "pref"
self.create_netlist()
if not OPTS.netlist_only:
@ -112,7 +118,7 @@ class single_level_column_mux_array(design.design):
# For every column, add a pass gate
for col_num in range(self.columns):
xoffset = col_num * self.mux.width
if cell_properties.bitcell.mirror.y and col_num % 2:
if cell_properties.bitcell.mirror.y and (col_num + self.port) % 2:
mirror = "MY"
xoffset = xoffset + self.mux.width
else:
@ -173,73 +179,53 @@ class single_level_column_mux_array(design.design):
self.get_pin("sel_{}".format(sel_index)).cy())
# Add the poly contact with a shift to account for the rotation
self.add_via_center(layers=self.poly_stack,
offset=offset)
offset=offset,
directions=self.via_directions)
self.add_path("poly", [offset, gate_offset])
def route_bitlines(self):
""" Connect the output bit-lines to form the appropriate width mux """
from tech import cell_properties
for j in range(self.columns):
bl_offset = self.mux_inst[j].get_pin("bl_out").bc()
br_offset = self.mux_inst[j].get_pin("br_out").bc()
bl_out_offset = bl_offset - vector(0, (self.words_per_row + 1) * self.col_mux_stack_pitch)
br_out_offset = br_offset - vector(0, (self.words_per_row + 2) * self.col_mux_stack_pitch)
bl_offset_begin = self.mux_inst[j].get_pin("bl_out").bc()
br_offset_begin = self.mux_inst[j].get_pin("br_out").bc()
bl_out_offset_end = bl_out_offset + vector(0, self.route_height)
br_out_offset_end = br_out_offset + vector(0, self.route_height)
bl_out_offset_begin = bl_offset_begin - vector(0, (self.words_per_row + 1) * self.col_mux_stack_pitch)
br_out_offset_begin = br_offset_begin - vector(0, (self.words_per_row + 2) * self.col_mux_stack_pitch)
if cell_properties.bitcell.mirror.y and j % 2:
tmp_bl_out_end = br_out_offset_end
tmp_br_out_end = bl_out_offset_end
else:
tmp_bl_out_end = bl_out_offset_end
tmp_br_out_end = br_out_offset_end
if (j % self.words_per_row) == 0:
# Create the metal1 to connect the n-way mux output from the pass gate
# These will be located below the select lines. Yes, these are M2 width
# to ensure vias are enclosed and M1 min width rules.
width = self.m2_width + self.mux.width * (self.words_per_row - 1)
if cell_properties.bitcell.mirror.y and (j % 2) == 0:
bl = self.mux.get_pin("bl")
br = self.mux.get_pin("br")
dist = abs(bl.ll().x - br.ll().x)
else:
dist = 0
self.add_path(self.col_mux_stack[0], [bl_out_offset, bl_out_offset + vector(width + dist, 0)])
self.add_path(self.col_mux_stack[0], [br_out_offset, br_out_offset + vector(width - dist, 0)])
# Add the horizontal wires for the first bit
if j % self.words_per_row == 0:
bl_offset_end = self.mux_inst[j + self.words_per_row - 1].get_pin("bl_out").bc()
br_offset_end = self.mux_inst[j + self.words_per_row - 1].get_pin("br_out").bc()
bl_out_offset_end = bl_offset_end - vector(0, (self.words_per_row + 1) * self.col_mux_stack_pitch)
br_out_offset_end = br_offset_end - vector(0, (self.words_per_row + 2) * self.col_mux_stack_pitch)
self.add_path(self.col_mux_stack[0], [bl_out_offset_begin, bl_out_offset_end])
self.add_path(self.col_mux_stack[0], [br_out_offset_begin, br_out_offset_end])
# Extend the bitline output rails and gnd downward on the first bit of each n-way mux
self.add_layout_pin_segment_center(text="bl_out_{}".format(int(j / self.words_per_row)),
layer=self.col_mux_stack[2],
start=bl_out_offset,
end=tmp_bl_out_end)
start=bl_offset_begin,
end=bl_out_offset_begin)
self.add_layout_pin_segment_center(text="br_out_{}".format(int(j / self.words_per_row)),
layer=self.col_mux_stack[2],
start=br_out_offset,
end=tmp_br_out_end)
# This via is on the right of the wire
self.add_via_center(layers=self.col_mux_stack,
offset=bl_out_offset)
# This via is on the left of the wire
self.add_via_center(layers=self.col_mux_stack,
offset=br_out_offset)
start=br_offset_begin,
end=br_out_offset_begin)
else:
self.add_path(self.col_mux_stack[2], [bl_out_offset, bl_offset])
self.add_path(self.col_mux_stack[2], [br_out_offset, br_offset])
self.add_path(self.col_mux_stack[2], [bl_out_offset_begin, bl_offset_begin])
self.add_path(self.col_mux_stack[2], [br_out_offset_begin, br_offset_begin])
# This via is on the right of the wire
self.add_via_center(layers=self.col_mux_stack,
offset=bl_out_offset)
# This via is on the left of the wire
self.add_via_center(layers=self.col_mux_stack,
offset=br_out_offset)
# This via is on the right of the wire
self.add_via_center(layers=self.col_mux_stack,
offset=bl_out_offset_begin,
directions=self.via_directions)
# This via is on the left of the wire
self.add_via_center(layers=self.col_mux_stack,
offset=br_out_offset_begin,
directions=self.via_directions)
def get_drain_cin(self):
"""Get the relative capacitance of the drain of the NMOS pass TX"""

View File

@ -29,19 +29,19 @@ class single_level_column_mux_pbitcell_test(openram_test):
factory.reset()
debug.info(1, "Testing sample for 2-way column_mux_array in multi-port")
a = factory.create(module_type="single_level_column_mux_array", columns=16, word_size=8, bitcell_bl="bl0", bitcell_br="br0")
a = factory.create(module_type="single_level_column_mux_array", columns=16, port=0, word_size=8, bitcell_bl="bl0", bitcell_br="br0")
self.local_check(a)
debug.info(1, "Testing sample for 4-way column_mux_array in multi-port")
a = factory.create(module_type="single_level_column_mux_array", columns=16, word_size=4, bitcell_bl="bl0", bitcell_br="br0")
a = factory.create(module_type="single_level_column_mux_array", columns=16, port=0, word_size=4, bitcell_bl="bl0", bitcell_br="br0")
self.local_check(a)
debug.info(1, "Testing sample for 8-way column_mux_array in multi-port (innermost connections)")
a = factory.create(module_type="single_level_column_mux_array", columns=32, word_size=4, bitcell_bl="bl0", bitcell_br="br0")
a = factory.create(module_type="single_level_column_mux_array", columns=32, port=0, word_size=4, bitcell_bl="bl0", bitcell_br="br0")
self.local_check(a)
debug.info(1, "Testing sample for 8-way column_mux_array in multi-port (outermost connections)")
a = factory.create(module_type="single_level_column_mux_array", columns=32, word_size=4, bitcell_bl="bl2", bitcell_br="br2")
a = factory.create(module_type="single_level_column_mux_array", columns=32, port=3, word_size=4, bitcell_bl="bl2", bitcell_br="br2")
self.local_check(a)
globals.end_openram()

View File

@ -23,15 +23,15 @@ class single_level_column_mux_test(openram_test):
# check single level column mux array in single port
debug.info(1, "Testing sample for 2-way column_mux_array")
a = factory.create(module_type="single_level_column_mux_array", columns=16, word_size=8)
a = factory.create(module_type="single_level_column_mux_array", columns=16, port=0, word_size=8)
self.local_check(a)
debug.info(1, "Testing sample for 4-way column_mux_array")
a = factory.create(module_type="single_level_column_mux_array", columns=16, word_size=4)
a = factory.create(module_type="single_level_column_mux_array", columns=16, port=0, word_size=4)
self.local_check(a)
debug.info(1, "Testing sample for 8-way column_mux_array")
a = factory.create(module_type="single_level_column_mux_array", columns=32, word_size=4)
a = factory.create(module_type="single_level_column_mux_array", columns=32, port=0, word_size=4)
self.local_check(a)
globals.end_openram()

View File

@ -29,7 +29,7 @@ class precharge_test(openram_test):
factory.reset()
debug.info(2, "Checking 3 column precharge array for 1RW/1R bitcell")
pc = factory.create(module_type="precharge_array", columns=3, bitcell_bl="bl0", bitcell_br="br0")
pc = factory.create(module_type="precharge_array", columns=3, port=0, bitcell_bl="bl0", bitcell_br="br0")
self.local_check(pc)
# debug.info(2, "Checking 3 column precharge array for pbitcell (innermost connections)")

View File

@ -23,7 +23,7 @@ class precharge_test(openram_test):
# check precharge array in single port
debug.info(2, "Checking 3 column precharge")
pc = factory.create(module_type="precharge_array", columns=3)
pc = factory.create(module_type="precharge_array", columns=3, port=0)
self.local_check(pc)
globals.end_openram()

View File

@ -36,7 +36,7 @@ class port_data_1rw_1r_test(openram_test):
self.local_check(a)
a = factory.create("port_data", sram_config=c, port=1)
self.local_check(a)
c.num_words=32
c.words_per_row=2
factory.reset()