mirror of https://github.com/VLSIDA/OpenRAM.git
PEP8 Formatting
This commit is contained in:
parent
287a31f598
commit
7adeef6c9e
|
|
@ -1,18 +1,17 @@
|
|||
# See LICENSE for licensing information.
|
||||
#
|
||||
# Copyright (c) 2016-2019 Regents of the University of California
|
||||
# Copyright (c) 2016-2019 Regents of the University of California
|
||||
# All rights reserved.
|
||||
#
|
||||
import sys
|
||||
from tech import drc, parameter
|
||||
from tech import drc
|
||||
import debug
|
||||
import design
|
||||
from sram_factory import factory
|
||||
from collections import namedtuple
|
||||
from vector import vector
|
||||
|
||||
from globals import OPTS
|
||||
|
||||
|
||||
class port_data(design.design):
|
||||
"""
|
||||
Create the data port (column mux, sense amps, write driver, etc.) for the given port number.
|
||||
|
|
@ -24,18 +23,21 @@ class port_data(design.design):
|
|||
sram_config.set_local_config(self)
|
||||
self.port = port
|
||||
if self.write_size is not None:
|
||||
self.num_wmasks = int(self.word_size/self.write_size)
|
||||
self.num_wmasks = int(self.word_size / self.write_size)
|
||||
else:
|
||||
self.num_wmasks = 0
|
||||
|
||||
if name == "":
|
||||
name = "port_data_{0}".format(self.port)
|
||||
design.design.__init__(self, name)
|
||||
debug.info(2, "create data port of size {0} with {1} words per row".format(self.word_size,self.words_per_row))
|
||||
debug.info(2,
|
||||
"create data port of size {0} with {1} words per row".format(self.word_size,
|
||||
self.words_per_row))
|
||||
|
||||
self.create_netlist()
|
||||
if not OPTS.netlist_only:
|
||||
debug.check(len(self.all_ports)<=2,"Bank layout cannot handle more than two ports.")
|
||||
debug.check(len(self.all_ports)<=2,
|
||||
"Bank layout cannot handle more than two ports.")
|
||||
self.create_layout()
|
||||
self.add_boundary()
|
||||
|
||||
|
|
@ -93,8 +95,6 @@ class port_data(design.design):
|
|||
else:
|
||||
self.column_mux_array_inst = None
|
||||
|
||||
|
||||
|
||||
def create_layout(self):
|
||||
self.compute_instance_offsets()
|
||||
self.place_instances()
|
||||
|
|
@ -104,33 +104,32 @@ class port_data(design.design):
|
|||
def add_pins(self):
|
||||
""" Adding pins for port address module"""
|
||||
|
||||
self.add_pin("rbl_bl","INOUT")
|
||||
self.add_pin("rbl_br","INOUT")
|
||||
self.add_pin("rbl_bl", "INOUT")
|
||||
self.add_pin("rbl_br", "INOUT")
|
||||
for bit in range(self.num_cols):
|
||||
bl_name = self.get_bl_name(self.port)
|
||||
br_name = self.get_br_name(self.port)
|
||||
self.add_pin("{0}_{1}".format(bl_name, bit),"INOUT")
|
||||
self.add_pin("{0}_{1}".format(br_name, bit),"INOUT")
|
||||
self.add_pin("{0}_{1}".format(bl_name, bit), "INOUT")
|
||||
self.add_pin("{0}_{1}".format(br_name, bit), "INOUT")
|
||||
if self.port in self.read_ports:
|
||||
for bit in range(self.word_size):
|
||||
self.add_pin("dout_{}".format(bit),"OUTPUT")
|
||||
self.add_pin("dout_{}".format(bit), "OUTPUT")
|
||||
if self.port in self.write_ports:
|
||||
for bit in range(self.word_size):
|
||||
self.add_pin("din_{}".format(bit),"INPUT")
|
||||
self.add_pin("din_{}".format(bit), "INPUT")
|
||||
# Will be empty if no col addr lines
|
||||
sel_names = ["sel_{}".format(x) for x in range(self.num_col_addr_lines)]
|
||||
for pin_name in sel_names:
|
||||
self.add_pin(pin_name,"INPUT")
|
||||
self.add_pin(pin_name, "INPUT")
|
||||
if self.port in self.read_ports:
|
||||
self.add_pin("s_en", "INPUT")
|
||||
self.add_pin("p_en_bar", "INPUT")
|
||||
if self.port in self.write_ports:
|
||||
self.add_pin("w_en", "INPUT")
|
||||
for bit in range(self.num_wmasks):
|
||||
self.add_pin("bank_wmask_{}".format(bit),"INPUT")
|
||||
self.add_pin("vdd","POWER")
|
||||
self.add_pin("gnd","GROUND")
|
||||
|
||||
self.add_pin("bank_wmask_{}".format(bit), "INPUT")
|
||||
self.add_pin("vdd", "POWER")
|
||||
self.add_pin("gnd", "GROUND")
|
||||
|
||||
def route_layout(self):
|
||||
""" Create routing among the modules """
|
||||
|
|
@ -172,8 +171,8 @@ class port_data(design.design):
|
|||
""" Propagate all vdd/gnd pins up to this level for all modules """
|
||||
|
||||
for inst in self.insts:
|
||||
self.copy_power_pins(inst,"vdd")
|
||||
self.copy_power_pins(inst,"gnd")
|
||||
self.copy_power_pins(inst, "vdd")
|
||||
self.copy_power_pins(inst, "gnd")
|
||||
|
||||
def add_modules(self):
|
||||
|
||||
|
|
@ -193,7 +192,6 @@ class port_data(design.design):
|
|||
else:
|
||||
self.sense_amp_array = None
|
||||
|
||||
|
||||
if self.col_addr_size > 0:
|
||||
self.column_mux_array = factory.create(module_type="column_mux_array",
|
||||
columns=self.num_cols,
|
||||
|
|
@ -204,7 +202,6 @@ class port_data(design.design):
|
|||
else:
|
||||
self.column_mux_array = None
|
||||
|
||||
|
||||
if self.port in self.write_ports:
|
||||
self.write_driver_array = factory.create(module_type="write_driver_array",
|
||||
columns=self.num_cols,
|
||||
|
|
@ -234,29 +231,27 @@ class port_data(design.design):
|
|||
else:
|
||||
self.num_col_addr_lines = 0
|
||||
|
||||
|
||||
# A space for wells or jogging m2 between modules
|
||||
self.m2_gap = max(2*drc("pwell_to_nwell") + drc("nwell_enclose_active"),
|
||||
3*self.m2_pitch)
|
||||
self.m2_gap = max(2 * drc("pwell_to_nwell") + drc("nwell_enclose_active"),
|
||||
3 * self.m2_pitch)
|
||||
|
||||
|
||||
# create arrays of bitline and bitline_bar names for read, write, or all ports
|
||||
# create arrays of bitline and bitline_bar names for read,
|
||||
# write, or all ports
|
||||
self.bitcell = factory.create(module_type="bitcell")
|
||||
self.bl_names = self.bitcell.get_all_bl_names()
|
||||
self.br_names = self.bitcell.get_all_br_names()
|
||||
self.wl_names = self.bitcell.get_all_wl_names()
|
||||
# used for bl/br names
|
||||
self.precharge = factory.create(module_type="precharge",
|
||||
bitcell_bl = self.bl_names[0],
|
||||
bitcell_br = self.br_names[0])
|
||||
bitcell_bl=self.bl_names[0],
|
||||
bitcell_br=self.br_names[0])
|
||||
# We create a dummy here to get bl/br names to add those pins to this
|
||||
# module, which happens before we create the real precharge_array
|
||||
self.precharge_array = factory.create(module_type="precharge_array",
|
||||
columns=self.num_cols + 1,
|
||||
bitcell_bl=self.bl_names[self.port],
|
||||
bitcell_br=self.br_names[self.port])
|
||||
|
||||
|
||||
columns=self.num_cols + 1,
|
||||
bitcell_bl=self.bl_names[self.port],
|
||||
bitcell_br=self.br_names[self.port])
|
||||
|
||||
def create_precharge_array(self):
|
||||
""" Creating Precharge """
|
||||
|
|
@ -285,13 +280,11 @@ class port_data(design.design):
|
|||
temp.extend(["p_en_bar", "vdd"])
|
||||
self.connect_inst(temp)
|
||||
|
||||
|
||||
def place_precharge_array(self, offset):
|
||||
""" Placing Precharge """
|
||||
|
||||
self.precharge_array_inst.place(offset=offset, mirror="MX")
|
||||
|
||||
|
||||
def create_column_mux_array(self):
|
||||
""" Creating Column Mux when words_per_row > 1 . """
|
||||
|
||||
|
|
@ -314,7 +307,6 @@ class port_data(design.design):
|
|||
temp.append("gnd")
|
||||
self.connect_inst(temp)
|
||||
|
||||
|
||||
def place_column_mux_array(self, offset):
|
||||
""" Placing Column Mux when words_per_row > 1 . """
|
||||
if self.col_addr_size == 0:
|
||||
|
|
@ -322,7 +314,6 @@ class port_data(design.design):
|
|||
|
||||
self.column_mux_array_inst.place(offset=offset, mirror="MX")
|
||||
|
||||
|
||||
def create_sense_amp_array(self):
|
||||
""" Creating Sense amp """
|
||||
self.sense_amp_array_inst = self.add_inst(name="sense_amp_array{}".format(self.port),
|
||||
|
|
@ -340,16 +331,13 @@ class port_data(design.design):
|
|||
temp.append("{0}_out_{1}".format(bl_name, bit))
|
||||
temp.append("{0}_out_{1}".format(br_name, bit))
|
||||
|
||||
|
||||
temp.extend(["s_en", "vdd", "gnd"])
|
||||
self.connect_inst(temp)
|
||||
|
||||
|
||||
def place_sense_amp_array(self, offset):
|
||||
""" Placing Sense amp """
|
||||
self.sense_amp_array_inst.place(offset=offset, mirror="MX")
|
||||
|
||||
|
||||
def create_write_driver_array(self):
|
||||
""" Creating Write Driver """
|
||||
self.write_driver_array_inst = self.add_inst(name="write_driver_array{}".format(self.port),
|
||||
|
|
@ -378,12 +366,10 @@ class port_data(design.design):
|
|||
|
||||
self.connect_inst(temp)
|
||||
|
||||
|
||||
def place_write_driver_array(self, offset):
|
||||
""" Placing Write Driver """
|
||||
self.write_driver_array_inst.place(offset=offset, mirror="MX")
|
||||
|
||||
|
||||
def create_write_mask_and_array(self):
|
||||
""" Creating Write Mask AND Array """
|
||||
self.write_mask_and_array_inst = self.add_inst(name="write_mask_and_array{}".format(self.port),
|
||||
|
|
@ -398,12 +384,10 @@ class port_data(design.design):
|
|||
temp.extend(["vdd", "gnd"])
|
||||
self.connect_inst(temp)
|
||||
|
||||
|
||||
def place_write_mask_and_array(self, offset):
|
||||
""" Placing Write Mask AND array """
|
||||
self.write_mask_and_array_inst.place(offset=offset, mirror="MX")
|
||||
|
||||
|
||||
def compute_instance_offsets(self):
|
||||
"""
|
||||
Compute the empty instance offsets for port0 and port1 (if needed)
|
||||
|
|
@ -458,19 +442,17 @@ class port_data(design.design):
|
|||
if self.column_mux_offset:
|
||||
self.place_column_mux_array(self.column_mux_offset)
|
||||
|
||||
|
||||
def route_sense_amp_out(self, port):
|
||||
""" Add pins for the sense amp output """
|
||||
|
||||
for bit in range(self.word_size):
|
||||
data_pin = self.sense_amp_array_inst.get_pin("data_{}".format(bit))
|
||||
self.add_layout_pin_rect_center(text="dout_{0}".format(bit),
|
||||
layer=data_pin.layer,
|
||||
layer=data_pin.layer,
|
||||
offset=data_pin.center(),
|
||||
height=data_pin.height(),
|
||||
width=data_pin.width())
|
||||
|
||||
|
||||
def route_write_driver_in(self, port):
|
||||
""" Connecting write driver """
|
||||
|
||||
|
|
@ -479,7 +461,6 @@ class port_data(design.design):
|
|||
din_name = "din_{}".format(row)
|
||||
self.copy_layout_pin(self.write_driver_array_inst, data_name, din_name)
|
||||
|
||||
|
||||
def route_write_mask_and_array_in(self, port):
|
||||
""" Add pins for the write mask and array input """
|
||||
|
||||
|
|
@ -488,7 +469,6 @@ class port_data(design.design):
|
|||
bank_wmask_name = "bank_wmask_{}".format(bit)
|
||||
self.copy_layout_pin(self.write_mask_and_array_inst, wmask_in_name, bank_wmask_name)
|
||||
|
||||
|
||||
def route_write_mask_and_array_to_write_driver(self,port):
|
||||
""" Routing of wdriver_sel_{} between write mask AND array and write driver array. Adds layout pin for write
|
||||
mask AND array output and via for write driver enable """
|
||||
|
|
@ -511,15 +491,15 @@ class port_data(design.design):
|
|||
while (wmask_out_pin.lx() + self.m2_pitch > inst2.get_pin("data_{0}".format(loc)).rx()):
|
||||
loc += 1
|
||||
length = inst2.get_pin("data_{0}".format(loc)).rx() + self.m2_pitch
|
||||
debug.check(loc<=self.num_wmasks,"Couldn't route the write mask select.")
|
||||
debug.check(loc<=self.num_wmasks,
|
||||
"Couldn't route the write mask select.")
|
||||
else:
|
||||
# Stride by the write size rather than finding the next pin to the right
|
||||
loc += self.write_size
|
||||
length = inst2.get_pin("data_{0}".format(loc)).rx() + self.m2_pitch
|
||||
|
||||
length = inst2.get_pin("data_{0}".format(loc)).rx() + self.m2_pitch
|
||||
|
||||
beg_pos = wmask_out_pin.center()
|
||||
middle_pos = vector(length,wmask_out_pin.cy())
|
||||
middle_pos = vector(length, wmask_out_pin.cy())
|
||||
end_pos = vector(length, wdriver_en_pin.cy())
|
||||
|
||||
# Add via for the write driver array's enable input
|
||||
|
|
@ -529,7 +509,6 @@ class port_data(design.design):
|
|||
# Route between write mask AND array and write driver array
|
||||
self.add_wire(self.m1_stack, [beg_pos, middle_pos, end_pos])
|
||||
|
||||
|
||||
def route_column_mux_to_precharge_array(self, port):
|
||||
""" Routing of BL and BR between col mux and precharge array """
|
||||
|
||||
|
|
@ -547,7 +526,6 @@ class port_data(design.design):
|
|||
num_bits=self.num_cols,
|
||||
inst2_start_bit=insn2_start_bit)
|
||||
|
||||
|
||||
def route_sense_amp_to_column_mux_or_precharge_array(self, port):
|
||||
""" Routing of BL and BR between sense_amp and column mux or precharge array """
|
||||
inst2 = self.sense_amp_array_inst
|
||||
|
|
@ -573,12 +551,9 @@ class port_data(design.design):
|
|||
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 """
|
||||
inst2 = self.write_driver_array_inst
|
||||
inst2_bl_name = inst2.mod.get_bl_name()
|
||||
inst2_br_name = inst2.mod.get_br_name()
|
||||
|
||||
if self.col_addr_size>0:
|
||||
# Write driver is connected to the col mux
|
||||
|
|
@ -599,7 +574,6 @@ class port_data(design.design):
|
|||
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 """
|
||||
|
||||
|
|
@ -612,7 +586,6 @@ class port_data(design.design):
|
|||
inst2=inst2,
|
||||
num_bits=self.word_size)
|
||||
|
||||
|
||||
def route_bitline_pins(self):
|
||||
""" Add the bitline pins for the given port """
|
||||
|
||||
|
|
@ -630,12 +603,15 @@ class port_data(design.design):
|
|||
|
||||
for bit in range(self.num_cols):
|
||||
if self.precharge_array_inst:
|
||||
self.copy_layout_pin(self.precharge_array_inst, "bl_{}".format(bit+bit_offset), "bl_{}".format(bit))
|
||||
self.copy_layout_pin(self.precharge_array_inst, "br_{}".format(bit+bit_offset), "br_{}".format(bit))
|
||||
self.copy_layout_pin(self.precharge_array_inst,
|
||||
"bl_{}".format(bit + bit_offset),
|
||||
"bl_{}".format(bit))
|
||||
self.copy_layout_pin(self.precharge_array_inst,
|
||||
"br_{}".format(bit + bit_offset),
|
||||
"br_{}".format(bit))
|
||||
else:
|
||||
debug.error("Didn't find precharge array.")
|
||||
|
||||
|
||||
def route_control_pins(self):
|
||||
""" Add the control pins: s_en, p_en_bar, w_en """
|
||||
if self.precharge_array_inst:
|
||||
|
|
@ -656,8 +632,6 @@ class port_data(design.design):
|
|||
if self.write_mask_and_array_inst:
|
||||
self.copy_layout_pin(self.write_mask_and_array_inst, "en", "w_en")
|
||||
|
||||
|
||||
|
||||
def _group_bitline_instances(self, inst1, inst2, num_bits,
|
||||
inst1_bls_template,
|
||||
inst1_start_bit,
|
||||
|
|
@ -694,17 +668,16 @@ class port_data(design.design):
|
|||
Extracts bl/br pins from an InstanceGroup based on the bit modifier.
|
||||
"""
|
||||
full_bl_name = inst_group.bls_template.format(
|
||||
**{'inst' : inst_group.bl_name,
|
||||
'bit' : inst_group.start_bit + bit}
|
||||
)
|
||||
**{'inst': inst_group.bl_name,
|
||||
'bit': inst_group.start_bit + bit}
|
||||
)
|
||||
full_br_name = inst_group.bls_template.format(
|
||||
**{'inst' : inst_group.br_name,
|
||||
'bit' : inst_group.start_bit + bit}
|
||||
)
|
||||
**{'inst': inst_group.br_name,
|
||||
'bit': inst_group.start_bit + bit}
|
||||
)
|
||||
return (inst_group.inst.get_pin(full_bl_name),
|
||||
inst_group.inst.get_pin(full_br_name))
|
||||
|
||||
|
||||
def channel_route_bitlines(self, inst1, inst2, num_bits,
|
||||
inst1_bls_template="{inst}_{bit}",
|
||||
inst1_start_bit=0,
|
||||
|
|
@ -721,14 +694,13 @@ class port_data(design.design):
|
|||
|
||||
# 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!
|
||||
offset = bot_inst_group.inst.ul() + vector(0,self.m1_pitch)
|
||||
offset = bot_inst_group.inst.ul() + vector(0, self.m1_pitch)
|
||||
for bit in range(num_bits):
|
||||
bottom_names = self._get_bitline_pins(bot_inst_group, bit)
|
||||
top_names = self._get_bitline_pins(top_inst_group, bit)
|
||||
|
||||
route_map = list(zip(bottom_names, top_names))
|
||||
self.create_horizontal_channel_route(route_map, offset, self.m1_stack)
|
||||
|
||||
|
||||
def connect_bitlines(self, inst1, inst2, num_bits,
|
||||
inst1_bls_template="{inst}_{bit}",
|
||||
|
|
@ -742,11 +714,9 @@ class port_data(design.design):
|
|||
"""
|
||||
|
||||
bot_inst_group, top_inst_group = self._group_bitline_instances(
|
||||
inst1, inst2, num_bits,
|
||||
inst1_bls_template, inst1_start_bit,
|
||||
inst2_bls_template, inst2_start_bit)
|
||||
bottom_inst = bot_inst_group.inst
|
||||
top_inst = top_inst_group.inst
|
||||
inst1, inst2, num_bits,
|
||||
inst1_bls_template, inst1_start_bit,
|
||||
inst2_bls_template, inst2_start_bit)
|
||||
|
||||
for col in range(num_bits):
|
||||
bot_bl_pin, bot_br_pin = self._get_bitline_pins(bot_inst_group, col)
|
||||
|
|
@ -754,11 +724,15 @@ class port_data(design.design):
|
|||
bot_bl, bot_br = bot_bl_pin.uc(), bot_br_pin.uc()
|
||||
top_bl, top_br = top_bl_pin.bc(), top_br_pin.bc()
|
||||
|
||||
yoffset = 0.5*(top_bl.y+bot_bl.y)
|
||||
self.add_path("m2",[bot_bl, vector(bot_bl.x,yoffset),
|
||||
vector(top_bl.x,yoffset), top_bl])
|
||||
self.add_path("m2",[bot_br, vector(bot_br.x,yoffset),
|
||||
vector(top_br.x,yoffset), top_br])
|
||||
yoffset = 0.5 * (top_bl.y + bot_bl.y)
|
||||
self.add_path("m2", [bot_bl,
|
||||
vector(bot_bl.x, yoffset),
|
||||
vector(top_bl.x, yoffset),
|
||||
top_bl])
|
||||
self.add_path("m2", [bot_br,
|
||||
vector(bot_br.x, yoffset),
|
||||
vector(top_br.x, yoffset),
|
||||
top_br])
|
||||
|
||||
def graph_exclude_precharge(self):
|
||||
"""Precharge adds a loop between bitlines, can be excluded to reduce complexity"""
|
||||
|
|
|
|||
Loading…
Reference in New Issue