mirror of https://github.com/VLSIDA/OpenRAM.git
Jog connection on M1 for bank select.
This commit is contained in:
parent
43dcf675a1
commit
32d190b8b1
|
|
@ -45,11 +45,9 @@ class bank_select(design.design):
|
||||||
self.height = max([x.uy() for x in self.inv_inst]) + self.m1_width
|
self.height = max([x.uy() for x in self.inv_inst]) + self.m1_width
|
||||||
self.width = max([x.rx() for x in self.inv_inst])
|
self.width = max([x.rx() for x in self.inv_inst])
|
||||||
|
|
||||||
|
|
||||||
self.add_boundary()
|
self.add_boundary()
|
||||||
self.DRC_LVS()
|
self.DRC_LVS()
|
||||||
|
|
||||||
|
|
||||||
def add_pins(self):
|
def add_pins(self):
|
||||||
|
|
||||||
# Number of control lines in the bus
|
# Number of control lines in the bus
|
||||||
|
|
@ -65,19 +63,18 @@ class bank_select(design.design):
|
||||||
if (self.port == "rw") or (self.port == "r"):
|
if (self.port == "rw") or (self.port == "r"):
|
||||||
self.input_control_signals.append("s_en")
|
self.input_control_signals.append("s_en")
|
||||||
# These will be outputs of the gaters if this is multibank
|
# These will be outputs of the gaters if this is multibank
|
||||||
self.control_signals = ["gated_"+str for str in self.input_control_signals]
|
self.control_signals = ["gated_" + str for str in self.input_control_signals]
|
||||||
|
|
||||||
self.add_pin_list(self.input_control_signals, "INPUT")
|
self.add_pin_list(self.input_control_signals, "INPUT")
|
||||||
self.add_pin("bank_sel")
|
self.add_pin("bank_sel")
|
||||||
self.add_pin_list(self.control_signals, "OUTPUT")
|
self.add_pin_list(self.control_signals, "OUTPUT")
|
||||||
self.add_pin("vdd","POWER")
|
self.add_pin("vdd", "POWER")
|
||||||
self.add_pin("gnd","GROUND")
|
self.add_pin("gnd", "GROUND")
|
||||||
|
|
||||||
def add_modules(self):
|
def add_modules(self):
|
||||||
""" Create modules for later instantiation """
|
""" Create modules for later instantiation """
|
||||||
self.bitcell = factory.create(module_type="bitcell")
|
self.dff = factory.create(module_type="dff")
|
||||||
|
height = self.dff.height + drc("poly_to_active")
|
||||||
height = self.bitcell.height + drc("poly_to_active")
|
|
||||||
|
|
||||||
# 1x Inverter
|
# 1x Inverter
|
||||||
self.inv_sel = factory.create(module_type="pinv", height=height)
|
self.inv_sel = factory.create(module_type="pinv", height=height)
|
||||||
|
|
@ -98,17 +95,15 @@ class bank_select(design.design):
|
||||||
|
|
||||||
def calculate_module_offsets(self):
|
def calculate_module_offsets(self):
|
||||||
|
|
||||||
self.xoffset_nand = self.inv4x.width + 2*self.m2_pitch + drc("pwell_to_nwell")
|
self.xoffset_nand = self.inv4x.width + 2 * self.m2_pitch + drc("pwell_to_nwell")
|
||||||
self.xoffset_nor = self.inv4x.width + 2*self.m2_pitch + drc("pwell_to_nwell")
|
self.xoffset_nor = self.inv4x.width + 2 * self.m2_pitch + drc("pwell_to_nwell")
|
||||||
self.xoffset_bank_sel_inv = 0
|
self.xoffset_bank_sel_inv = 0
|
||||||
self.xoffset_inputs = 0
|
self.xoffset_inputs = 0
|
||||||
|
|
||||||
self.yoffset_maxpoint = self.num_control_lines * self.inv4x.height
|
self.yoffset_maxpoint = self.num_control_lines * self.inv4x.height
|
||||||
|
|
||||||
|
|
||||||
def create_instances(self):
|
def create_instances(self):
|
||||||
|
|
||||||
self.bank_sel_inv=self.add_inst(name="bank_sel_inv",
|
self.bank_sel_inv=self.add_inst(name="bank_sel_inv",
|
||||||
mod=self.inv_sel)
|
mod=self.inv_sel)
|
||||||
self.connect_inst(["bank_sel", "bank_sel_bar", "vdd", "gnd"])
|
self.connect_inst(["bank_sel", "bank_sel_bar", "vdd", "gnd"])
|
||||||
|
|
||||||
|
|
@ -125,36 +120,36 @@ class bank_select(design.design):
|
||||||
# (writes occur on clk low)
|
# (writes occur on clk low)
|
||||||
if input_name in ("clk_buf"):
|
if input_name in ("clk_buf"):
|
||||||
|
|
||||||
self.logic_inst.append(self.add_inst(name=name_nor,
|
self.logic_inst.append(self.add_inst(name=name_nor,
|
||||||
mod=self.nor2))
|
mod=self.nor2))
|
||||||
self.connect_inst([input_name,
|
self.connect_inst([input_name,
|
||||||
"bank_sel_bar",
|
"bank_sel_bar",
|
||||||
gated_name+"_temp_bar",
|
gated_name + "_temp_bar",
|
||||||
"vdd",
|
"vdd",
|
||||||
"gnd"])
|
"gnd"])
|
||||||
|
|
||||||
# They all get inverters on the output
|
# They all get inverters on the output
|
||||||
self.inv_inst.append(self.add_inst(name=name_inv,
|
self.inv_inst.append(self.add_inst(name=name_inv,
|
||||||
mod=self.inv4x_nor))
|
mod=self.inv4x_nor))
|
||||||
self.connect_inst([gated_name+"_temp_bar",
|
self.connect_inst([gated_name + "_temp_bar",
|
||||||
gated_name,
|
gated_name,
|
||||||
"vdd",
|
"vdd",
|
||||||
"gnd"])
|
"gnd"])
|
||||||
|
|
||||||
# the rest are AND (nand2+inv) gates
|
# the rest are AND (nand2+inv) gates
|
||||||
else:
|
else:
|
||||||
self.logic_inst.append(self.add_inst(name=name_nand,
|
self.logic_inst.append(self.add_inst(name=name_nand,
|
||||||
mod=self.nand2))
|
mod=self.nand2))
|
||||||
self.connect_inst([input_name,
|
self.connect_inst([input_name,
|
||||||
"bank_sel",
|
"bank_sel",
|
||||||
gated_name+"_temp_bar",
|
gated_name + "_temp_bar",
|
||||||
"vdd",
|
"vdd",
|
||||||
"gnd"])
|
"gnd"])
|
||||||
|
|
||||||
# They all get inverters on the output
|
# They all get inverters on the output
|
||||||
self.inv_inst.append(self.add_inst(name=name_inv,
|
self.inv_inst.append(self.add_inst(name=name_inv,
|
||||||
mod=self.inv4x))
|
mod=self.inv4x))
|
||||||
self.connect_inst([gated_name+"_temp_bar",
|
self.connect_inst([gated_name + "_temp_bar",
|
||||||
gated_name,
|
gated_name,
|
||||||
"vdd",
|
"vdd",
|
||||||
"gnd"])
|
"gnd"])
|
||||||
|
|
@ -177,9 +172,9 @@ class bank_select(design.design):
|
||||||
if i == 0:
|
if i == 0:
|
||||||
y_offset = 0
|
y_offset = 0
|
||||||
else:
|
else:
|
||||||
y_offset = self.inv4x_nor.height + self.inv4x.height * (i-1)
|
y_offset = self.inv4x_nor.height + self.inv4x.height * (i - 1)
|
||||||
|
|
||||||
if i%2:
|
if i % 2:
|
||||||
y_offset += self.inv4x.height
|
y_offset += self.inv4x.height
|
||||||
mirror = "MX"
|
mirror = "MX"
|
||||||
else:
|
else:
|
||||||
|
|
@ -200,7 +195,6 @@ class bank_select(design.design):
|
||||||
# They all get inverters on the output
|
# They all get inverters on the output
|
||||||
inv_inst.place(offset=[logic_inst.rx(), y_offset],
|
inv_inst.place(offset=[logic_inst.rx(), y_offset],
|
||||||
mirror=mirror)
|
mirror=mirror)
|
||||||
|
|
||||||
|
|
||||||
def route_instances(self):
|
def route_instances(self):
|
||||||
|
|
||||||
|
|
@ -222,57 +216,56 @@ class bank_select(design.design):
|
||||||
end=bank_sel_pin_end)
|
end=bank_sel_pin_end)
|
||||||
self.add_via_center(layers=self.m2_stack,
|
self.add_via_center(layers=self.m2_stack,
|
||||||
offset=bank_sel_pin_end,
|
offset=bank_sel_pin_end,
|
||||||
directions=("H","H"))
|
directions=("H", "H"))
|
||||||
|
|
||||||
# bank_sel_bar is vertical wire
|
# bank_sel_bar is vertical wire
|
||||||
bank_sel_bar_pin = self.bank_sel_inv.get_pin("Z")
|
bank_sel_bar_pin = self.bank_sel_inv.get_pin("Z")
|
||||||
xoffset_bank_sel_bar = bank_sel_bar_pin.rx()
|
xoffset_bank_sel_bar = bank_sel_bar_pin.rx()
|
||||||
self.add_label_pin(text="bank_sel_bar",
|
self.add_label_pin(text="bank_sel_bar",
|
||||||
layer="m2",
|
layer="m2",
|
||||||
offset=vector(xoffset_bank_sel_bar, 0),
|
offset=vector(xoffset_bank_sel_bar, 0),
|
||||||
height=self.inv4x.height)
|
height=self.inv4x.height)
|
||||||
self.add_via_center(layers=self.m1_stack,
|
self.add_via_center(layers=self.m1_stack,
|
||||||
offset=bank_sel_bar_pin.rc())
|
offset=bank_sel_bar_pin.rc())
|
||||||
|
|
||||||
|
|
||||||
for i in range(self.num_control_lines):
|
for i in range(self.num_control_lines):
|
||||||
|
|
||||||
logic_inst = self.logic_inst[i]
|
logic_inst = self.logic_inst[i]
|
||||||
inv_inst = self.inv_inst[i]
|
inv_inst = self.inv_inst[i]
|
||||||
|
|
||||||
input_name = self.input_control_signals[i]
|
input_name = self.input_control_signals[i]
|
||||||
gated_name = self.control_signals[i]
|
gated_name = self.control_signals[i]
|
||||||
if input_name in ("clk_buf"):
|
if input_name in ("clk_buf"):
|
||||||
xoffset_bank_signal = xoffset_bank_sel_bar
|
xoffset_bank_signal = xoffset_bank_sel_bar
|
||||||
else:
|
else:
|
||||||
xoffset_bank_signal = xoffset_bank_sel
|
xoffset_bank_signal = xoffset_bank_sel
|
||||||
|
|
||||||
# Connect the logic output to inverter input
|
# Connect the logic output to inverter input
|
||||||
pre = logic_inst.get_pin("Z").lc()
|
out_pin = logic_inst.get_pin("Z")
|
||||||
out_position = logic_inst.get_pin("Z").rc() + vector(0.5*self.m1_width,0)
|
out_pos = out_pin.rc()
|
||||||
in_position = inv_inst.get_pin("A").lc() + vector(0.5*self.m1_width,0)
|
in_pin = inv_inst.get_pin("A")
|
||||||
post = inv_inst.get_pin("A").rc()
|
in_pos = in_pin.lc()
|
||||||
self.add_path("m1", [pre, out_position, in_position, post])
|
mid1_pos = vector(0.5 * (out_pos.x + in_pos.x), out_pos.y)
|
||||||
|
mid2_pos = vector(0.5 * (out_pos.x + in_pos.x), in_pos.y)
|
||||||
|
self.add_path("m1", [out_pos, mid1_pos, mid2_pos, in_pos])
|
||||||
|
|
||||||
|
# Connect the logic B input to bank_sel / bank_sel_bar
|
||||||
# Connect the logic B input to bank_sel/bank_sel_bar
|
logic_pos = logic_inst.get_pin("B").lc() - vector(0.5 * contact.m1_via.height, 0)
|
||||||
logic_pos = logic_inst.get_pin("B").lc() - vector(0.5*contact.m1_via.height,0)
|
|
||||||
input_pos = vector(xoffset_bank_signal, logic_pos.y)
|
input_pos = vector(xoffset_bank_signal, logic_pos.y)
|
||||||
self.add_path("m2",[logic_pos, input_pos])
|
self.add_path("m2", [logic_pos, input_pos])
|
||||||
self.add_via_center(layers=self.m1_stack,
|
self.add_via_center(layers=self.m1_stack,
|
||||||
offset=logic_pos,
|
offset=logic_pos,
|
||||||
directions=("H","H"))
|
directions=("H", "H"))
|
||||||
|
|
||||||
|
|
||||||
# Connect the logic A input to the input pin
|
# Connect the logic A input to the input pin
|
||||||
logic_pos = logic_inst.get_pin("A").lc()
|
logic_pos = logic_inst.get_pin("A").lc()
|
||||||
input_pos = vector(0,logic_pos.y)
|
input_pos = vector(0, logic_pos.y)
|
||||||
self.add_via_center(layers=self.m1_stack,
|
self.add_via_center(layers=self.m1_stack,
|
||||||
offset=logic_pos,
|
offset=logic_pos,
|
||||||
directions=("H","H"))
|
directions=("H", "H"))
|
||||||
self.add_via_center(layers=self.m2_stack,
|
self.add_via_center(layers=self.m2_stack,
|
||||||
offset=logic_pos,
|
offset=logic_pos,
|
||||||
directions=("H","H"))
|
directions=("H", "H"))
|
||||||
self.add_layout_pin_segment_center(text=input_name,
|
self.add_layout_pin_segment_center(text=input_name,
|
||||||
layer="m3",
|
layer="m3",
|
||||||
start=input_pos,
|
start=input_pos,
|
||||||
|
|
@ -286,7 +279,6 @@ class bank_select(design.design):
|
||||||
width=inv_inst.rx() - out_pin.lx(),
|
width=inv_inst.rx() - out_pin.lx(),
|
||||||
height=out_pin.height())
|
height=out_pin.height())
|
||||||
|
|
||||||
|
|
||||||
# Find the x offsets for where the vias/pins should be placed
|
# Find the x offsets for where the vias/pins should be placed
|
||||||
a_xoffset = self.logic_inst[0].lx()
|
a_xoffset = self.logic_inst[0].lx()
|
||||||
b_xoffset = self.inv_inst[0].lx()
|
b_xoffset = self.inv_inst[0].lx()
|
||||||
|
|
@ -294,7 +286,7 @@ class bank_select(design.design):
|
||||||
# Route both supplies
|
# Route both supplies
|
||||||
for n in ["vdd", "gnd"]:
|
for n in ["vdd", "gnd"]:
|
||||||
supply_pin = self.inv_inst[num].get_pin(n)
|
supply_pin = self.inv_inst[num].get_pin(n)
|
||||||
supply_offset = supply_pin.ll().scale(0,1)
|
supply_offset = supply_pin.ll().scale(0, 1)
|
||||||
self.add_rect(layer="m1",
|
self.add_rect(layer="m1",
|
||||||
offset=supply_offset,
|
offset=supply_offset,
|
||||||
width=self.width)
|
width=self.width)
|
||||||
|
|
@ -304,10 +296,10 @@ class bank_select(design.design):
|
||||||
pin_pos = vector(xoffset, supply_pin.cy())
|
pin_pos = vector(xoffset, supply_pin.cy())
|
||||||
self.add_via_center(layers=self.m1_stack,
|
self.add_via_center(layers=self.m1_stack,
|
||||||
offset=pin_pos,
|
offset=pin_pos,
|
||||||
directions=("H","H"))
|
directions=("H", "H"))
|
||||||
self.add_via_center(layers=self.m2_stack,
|
self.add_via_center(layers=self.m2_stack,
|
||||||
offset=pin_pos,
|
offset=pin_pos,
|
||||||
directions=("H","H"))
|
directions=("H", "H"))
|
||||||
self.add_layout_pin_rect_center(text=n,
|
self.add_layout_pin_rect_center(text=n,
|
||||||
layer="m3",
|
layer="m3",
|
||||||
offset=pin_pos)
|
offset=pin_pos)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue