mirror of https://github.com/VLSIDA/OpenRAM.git
Add missing vias by using via stack function
This commit is contained in:
parent
4a67f7dc71
commit
82dc937768
|
|
@ -534,11 +534,14 @@ class port_data(design.design):
|
||||||
else:
|
else:
|
||||||
start_bit=0
|
start_bit=0
|
||||||
|
|
||||||
self.channel_route_bitlines(inst1=inst1,
|
# This could be a channel route, but in some techs the bitlines
|
||||||
inst1_bls_template=inst1_bls_templ,
|
# are too close together.
|
||||||
inst2=inst2,
|
print("SA to precharge")
|
||||||
num_bits=self.word_size,
|
self.connect_bitlines(inst1=inst1,
|
||||||
inst1_start_bit=start_bit)
|
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):
|
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 """
|
""" Routing of BL and BR between sense_amp and column mux or precharge array """
|
||||||
|
|
@ -558,10 +561,13 @@ class port_data(design.design):
|
||||||
else:
|
else:
|
||||||
start_bit=0
|
start_bit=0
|
||||||
|
|
||||||
self.channel_route_bitlines(inst1=inst1, inst2=inst2,
|
# This could be a channel route, but in some techs the bitlines
|
||||||
num_bits=self.word_size,
|
# are too close together.
|
||||||
inst1_bls_template=inst1_bls_templ,
|
print("WD to precharge")
|
||||||
inst1_start_bit=start_bit)
|
self.connect_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):
|
def route_write_driver_to_sense_amp(self, port):
|
||||||
""" Routing of BL and BR between write driver and sense amp """
|
""" Routing of BL and BR between write driver and sense amp """
|
||||||
|
|
@ -569,11 +575,12 @@ class port_data(design.design):
|
||||||
inst1 = self.write_driver_array_inst
|
inst1 = self.write_driver_array_inst
|
||||||
inst2 = self.sense_amp_array_inst
|
inst2 = self.sense_amp_array_inst
|
||||||
|
|
||||||
# These should be pitch matched in the cell library,
|
# This could be a channel route, but in some techs the bitlines
|
||||||
# but just in case, do a channel route.
|
# are too close together.
|
||||||
self.channel_route_bitlines(inst1=inst1,
|
print("WD to SA")
|
||||||
inst2=inst2,
|
self.connect_bitlines(inst1=inst1,
|
||||||
num_bits=self.word_size)
|
inst2=inst2,
|
||||||
|
num_bits=self.word_size)
|
||||||
|
|
||||||
def route_bitline_pins(self):
|
def route_bitline_pins(self):
|
||||||
""" Add the bitline pins for the given port """
|
""" Add the bitline pins for the given port """
|
||||||
|
|
@ -676,10 +683,9 @@ class port_data(design.design):
|
||||||
Route the bl and br of two modules using the channel router.
|
Route the bl and br of two modules using the channel router.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
bot_inst_group, top_inst_group = self._group_bitline_instances(
|
bot_inst_group, top_inst_group = self._group_bitline_instances(inst1, inst2, num_bits,
|
||||||
inst1, inst2, num_bits,
|
inst1_bls_template, inst1_start_bit,
|
||||||
inst1_bls_template, inst1_start_bit,
|
inst2_bls_template, inst2_start_bit)
|
||||||
inst2_bls_template, inst2_start_bit)
|
|
||||||
|
|
||||||
# Channel route each mux separately since we don't minimize the number
|
# Channel route each mux separately since we don't minimize the number
|
||||||
# of tracks in teh channel router yet. If we did, we could route all the bits at once!
|
# of tracks in teh channel router yet. If we did, we could route all the bits at once!
|
||||||
|
|
@ -688,13 +694,8 @@ class port_data(design.design):
|
||||||
bottom_names = self._get_bitline_pins(bot_inst_group, bit)
|
bottom_names = self._get_bitline_pins(bot_inst_group, bit)
|
||||||
top_names = self._get_bitline_pins(top_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))
|
route_map = list(zip(bottom_names, top_names))
|
||||||
self.create_horizontal_channel_route(route_map, offset, self.m1_stack, bitline_dirs)
|
self.create_horizontal_channel_route(route_map, offset, self.m1_stack)
|
||||||
|
|
||||||
def connect_bitlines(self, inst1, inst2, num_bits,
|
def connect_bitlines(self, inst1, inst2, num_bits,
|
||||||
inst1_bls_template="{inst}_{bit}",
|
inst1_bls_template="{inst}_{bit}",
|
||||||
|
|
@ -707,26 +708,23 @@ class port_data(design.design):
|
||||||
in the middle between the two modules (if needed).
|
in the middle between the two modules (if needed).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
bot_inst_group, top_inst_group = self._group_bitline_instances(
|
bot_inst_group, top_inst_group = self._group_bitline_instances(inst1, inst2, num_bits,
|
||||||
inst1, inst2, num_bits,
|
inst1_bls_template, inst1_start_bit,
|
||||||
inst1_bls_template, inst1_start_bit,
|
inst2_bls_template, inst2_start_bit)
|
||||||
inst2_bls_template, inst2_start_bit)
|
|
||||||
|
|
||||||
for col in range(num_bits):
|
for col in range(num_bits):
|
||||||
|
print(col)
|
||||||
bot_bl_pin, bot_br_pin = self._get_bitline_pins(bot_inst_group, col)
|
bot_bl_pin, bot_br_pin = self._get_bitline_pins(bot_inst_group, col)
|
||||||
top_bl_pin, top_br_pin = self._get_bitline_pins(top_inst_group, col)
|
top_bl_pin, top_br_pin = self._get_bitline_pins(top_inst_group, col)
|
||||||
bot_bl, bot_br = bot_bl_pin.uc(), bot_br_pin.uc()
|
bot_bl, bot_br = bot_bl_pin.uc(), bot_br_pin.uc()
|
||||||
top_bl, top_br = top_bl_pin.bc(), top_br_pin.bc()
|
top_bl, top_br = top_bl_pin.bc(), top_br_pin.bc()
|
||||||
|
|
||||||
yoffset = 0.5 * (top_bl.y + bot_bl.y)
|
print("BL", bot_bl, top_bl)
|
||||||
self.add_path("m2", [bot_bl,
|
print(bot_bl_pin, top_bl_pin)
|
||||||
vector(bot_bl.x, yoffset),
|
print("BR", bot_br, top_br)
|
||||||
vector(top_bl.x, yoffset),
|
print(bot_br_pin, top_br_pin)
|
||||||
top_bl])
|
self.add_zjog(bot_bl_pin.layer, bot_bl, top_bl, "V")
|
||||||
self.add_path("m2", [bot_br,
|
self.add_zjog(bot_br_pin.layer, bot_br, top_br, "V")
|
||||||
vector(bot_br.x, yoffset),
|
|
||||||
vector(top_br.x, yoffset),
|
|
||||||
top_br])
|
|
||||||
|
|
||||||
def graph_exclude_precharge(self):
|
def graph_exclude_precharge(self):
|
||||||
"""Precharge adds a loop between bitlines, can be excluded to reduce complexity"""
|
"""Precharge adds a loop between bitlines, can be excluded to reduce complexity"""
|
||||||
|
|
|
||||||
|
|
@ -105,21 +105,19 @@ class precharge(design.design):
|
||||||
|
|
||||||
# center of vdd rail
|
# center of vdd rail
|
||||||
pmos_vdd_pos = vector(pmos_pin.cx(), vdd_position.y)
|
pmos_vdd_pos = vector(pmos_pin.cx(), vdd_position.y)
|
||||||
self.add_path("m1", [pmos_pin.uc(), pmos_vdd_pos])
|
self.add_path(self.bitline_layer, [pmos_pin.center(), pmos_vdd_pos])
|
||||||
|
|
||||||
# if enable is not on M1, the supply can be
|
self.add_via_stack_center(from_layer=self.bitline_layer,
|
||||||
if self.en_layer != "m1":
|
to_layer=self.en_layer,
|
||||||
self.add_via_center(layers=self.m1_stack,
|
offset=pmos_vdd_pos)
|
||||||
offset=pmos_vdd_pos)
|
|
||||||
|
|
||||||
self.add_power_pin("vdd",
|
self.add_power_pin("vdd",
|
||||||
self.well_contact_pos,
|
self.well_contact_pos,
|
||||||
directions=("V", "V"))
|
directions=("V", "V"))
|
||||||
|
|
||||||
# Hack for li layers
|
self.add_via_stack_center(from_layer=pmos_pin.layer,
|
||||||
if hasattr(self, "li_stack"):
|
to_layer=self.bitline_layer,
|
||||||
self.add_via_center(layers=self.li_stack,
|
offset=pmos_pin.center(),
|
||||||
offset=self.well_contact_pos)
|
directions=("V", "V"))
|
||||||
|
|
||||||
def create_ptx(self):
|
def create_ptx(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -199,14 +197,9 @@ class precharge(design.design):
|
||||||
# midway in the 4 M2 tracks
|
# midway in the 4 M2 tracks
|
||||||
offset = self.lower_pmos_inst.get_pin("G").ul() \
|
offset = self.lower_pmos_inst.get_pin("G").ul() \
|
||||||
+ vector(0, 0.5 * self.m2_pitch)
|
+ vector(0, 0.5 * self.m2_pitch)
|
||||||
self.add_via_center(layers=self.poly_stack,
|
self.add_via_stack_center(from_layer="poly",
|
||||||
offset=offset)
|
to_layer=self.en_layer,
|
||||||
if self.en_layer == "m2":
|
offset=offset)
|
||||||
self.add_via_center(layers=self.m1_stack,
|
|
||||||
offset=offset)
|
|
||||||
if hasattr(self, "li_stack"):
|
|
||||||
self.add_via_center(layers=self.li_stack,
|
|
||||||
offset=offset)
|
|
||||||
|
|
||||||
# adds the en rail on metal1
|
# adds the en rail on metal1
|
||||||
self.add_layout_pin_segment_center(text="en_bar",
|
self.add_layout_pin_segment_center(text="en_bar",
|
||||||
|
|
@ -225,13 +218,13 @@ class precharge(design.design):
|
||||||
self.nwell_extend_active
|
self.nwell_extend_active
|
||||||
self.well_contact_pos = self.upper_pmos1_inst.get_pin("D").center().scale(1, 0) + \
|
self.well_contact_pos = self.upper_pmos1_inst.get_pin("D").center().scale(1, 0) + \
|
||||||
vector(0, offset_height)
|
vector(0, offset_height)
|
||||||
self.add_via_center(layers=self.active_stack,
|
self.well_contact = self.add_via_center(layers=self.active_stack,
|
||||||
offset=self.well_contact_pos,
|
offset=self.well_contact_pos,
|
||||||
implant_type="n",
|
implant_type="n",
|
||||||
well_type="n")
|
well_type="n")
|
||||||
if hasattr(self, "li_stack"):
|
self.add_via_stack_center(from_layer=self.active_stack[2],
|
||||||
self.add_via_center(layers=self.li_stack,
|
to_layer=self.bitline_layer,
|
||||||
offset=self.well_contact_pos)
|
offset=self.well_contact_pos)
|
||||||
|
|
||||||
self.height = self.well_contact_pos.y + contact.active_contact.height + self.m1_space
|
self.height = self.well_contact_pos.y + contact.active_contact.height + self.m1_space
|
||||||
|
|
||||||
|
|
@ -288,31 +281,19 @@ class precharge(design.design):
|
||||||
Adds contacts/via from metal1 to metal2 for bit-lines
|
Adds contacts/via from metal1 to metal2 for bit-lines
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# No contacts needed if M1
|
|
||||||
if self.bitline_layer == "m1":
|
|
||||||
return
|
|
||||||
|
|
||||||
# BL
|
# BL
|
||||||
lower_pin = self.lower_pmos_inst.get_pin("S")
|
for lower_pin in [self.lower_pmos_inst.get_pin("S"), self.lower_pmos_inst.get_pin("D")]:
|
||||||
self.lower_via = self.add_via_center(layers=self.m1_stack,
|
self.add_via_stack_center(from_layer=lower_pin.layer,
|
||||||
offset=lower_pin.center(),
|
to_layer=self.bitline_layer,
|
||||||
directions=("V", "V"))
|
offset=lower_pin.center(),
|
||||||
|
directions=("V", "V"))
|
||||||
|
|
||||||
lower_pin = self.lower_pmos_inst.get_pin("D")
|
|
||||||
self.lower_via = self.add_via_center(layers=self.m1_stack,
|
|
||||||
offset=lower_pin.center(),
|
|
||||||
directions=("V", "V"))
|
|
||||||
|
|
||||||
# BR
|
# BR
|
||||||
upper_pin = self.upper_pmos1_inst.get_pin("S")
|
for upper_pin in [self.upper_pmos1_inst.get_pin("S"), self.upper_pmos2_inst.get_pin("D")]:
|
||||||
self.upper_via2 = self.add_via_center(layers=self.m1_stack,
|
self.add_via_stack_center(from_layer=upper_pin.layer,
|
||||||
offset=upper_pin.center(),
|
to_layer=self.bitline_layer,
|
||||||
directions=("V", "V"))
|
offset=upper_pin.center(),
|
||||||
|
directions=("V", "V"))
|
||||||
upper_pin = self.upper_pmos2_inst.get_pin("D")
|
|
||||||
self.upper_via2 = self.add_via_center(layers=self.m1_stack,
|
|
||||||
offset=upper_pin.center(),
|
|
||||||
directions=("V", "V"))
|
|
||||||
|
|
||||||
def connect_pmos(self, pmos_pin, bit_xoffset):
|
def connect_pmos(self, pmos_pin, bit_xoffset):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue