mirror of https://github.com/VLSIDA/OpenRAM.git
Merge branch 'tech_migration' into dev
This commit is contained in:
commit
77fb7017c4
|
|
@ -219,8 +219,6 @@ class layout():
|
||||||
if not height:
|
if not height:
|
||||||
height = drc["minwidth_{}".format(layer)]
|
height = drc["minwidth_{}".format(layer)]
|
||||||
lpp = techlayer[layer]
|
lpp = techlayer[layer]
|
||||||
if abs(offset[0]-5.16250)<0.01 and abs(offset[1]-8.70750)<0.01:
|
|
||||||
import pdb; pdb.set_trace()
|
|
||||||
self.objs.append(geometry.rectangle(lpp,
|
self.objs.append(geometry.rectangle(lpp,
|
||||||
offset,
|
offset,
|
||||||
width,
|
width,
|
||||||
|
|
@ -838,51 +836,57 @@ class layout():
|
||||||
if not pitch:
|
if not pitch:
|
||||||
pitch = getattr(self, "{}_pitch".format(layer))
|
pitch = getattr(self, "{}_pitch".format(layer))
|
||||||
|
|
||||||
line_positions = {}
|
pins = {}
|
||||||
if vertical:
|
if vertical:
|
||||||
for i in range(len(names)):
|
for i in range(len(names)):
|
||||||
line_offset = offset + vector(i * pitch,
|
line_offset = offset + vector(i * pitch,
|
||||||
0)
|
0)
|
||||||
if make_pins:
|
if make_pins:
|
||||||
self.add_layout_pin(text=names[i],
|
new_pin = self.add_layout_pin(text=names[i],
|
||||||
layer=layer,
|
layer=layer,
|
||||||
offset=line_offset,
|
offset=line_offset,
|
||||||
height=length)
|
height=length)
|
||||||
else:
|
else:
|
||||||
self.add_rect(layer=layer,
|
rect = self.add_rect(layer=layer,
|
||||||
offset=line_offset,
|
offset=line_offset,
|
||||||
height=length)
|
height=length)
|
||||||
line_positions[names[i]] = line_offset + vector(half_minwidth, 0)
|
new_pin = pin_layout(names[i],
|
||||||
|
[rect.ll(), rect.ur()],
|
||||||
|
layer)
|
||||||
|
|
||||||
|
pins[names[i]] = new_pin
|
||||||
else:
|
else:
|
||||||
for i in range(len(names)):
|
for i in range(len(names)):
|
||||||
line_offset = offset + vector(0,
|
line_offset = offset + vector(0,
|
||||||
i * pitch + half_minwidth)
|
i * pitch + half_minwidth)
|
||||||
if make_pins:
|
if make_pins:
|
||||||
self.add_layout_pin(text=names[i],
|
new_pin = self.add_layout_pin(text=names[i],
|
||||||
layer=layer,
|
layer=layer,
|
||||||
offset=line_offset,
|
offset=line_offset,
|
||||||
width=length)
|
width=length)
|
||||||
else:
|
else:
|
||||||
self.add_rect(layer=layer,
|
rect = self.add_rect(layer=layer,
|
||||||
offset=line_offset,
|
offset=line_offset,
|
||||||
width=length)
|
width=length)
|
||||||
# Make this the center of the rail
|
new_pin = pin_layout(names[i],
|
||||||
line_positions[names[i]] = line_offset + vector(0.5 * length,
|
[rect.ll(), rect.ur()],
|
||||||
half_minwidth)
|
layer)
|
||||||
|
|
||||||
return line_positions
|
pins[names[i]] = new_pin
|
||||||
|
|
||||||
def connect_horizontal_bus(self, mapping, inst, bus_offsets,
|
return pins
|
||||||
|
|
||||||
|
def connect_horizontal_bus(self, mapping, inst, bus_pins,
|
||||||
layer_stack=("m1", "via1", "m2")):
|
layer_stack=("m1", "via1", "m2")):
|
||||||
""" Horizontal version of connect_bus. """
|
""" Horizontal version of connect_bus. """
|
||||||
self.connect_bus(mapping, inst, bus_offsets, layer_stack, True)
|
self.connect_bus(mapping, inst, bus_pins, layer_stack, True)
|
||||||
|
|
||||||
def connect_vertical_bus(self, mapping, inst, bus_offsets,
|
def connect_vertical_bus(self, mapping, inst, bus_pins,
|
||||||
layer_stack=("m1", "via1", "m2")):
|
layer_stack=("m1", "via1", "m2")):
|
||||||
""" Vertical version of connect_bus. """
|
""" Vertical version of connect_bus. """
|
||||||
self.connect_bus(mapping, inst, bus_offsets, layer_stack, False)
|
self.connect_bus(mapping, inst, bus_pins, layer_stack, False)
|
||||||
|
|
||||||
def connect_bus(self, mapping, inst, bus_offsets, layer_stack, horizontal):
|
def connect_bus(self, mapping, inst, bus_pins, layer_stack, horizontal):
|
||||||
"""
|
"""
|
||||||
Connect a mapping of pin -> name for a bus. This could be
|
Connect a mapping of pin -> name for a bus. This could be
|
||||||
replaced with a channel router in the future.
|
replaced with a channel router in the future.
|
||||||
|
|
@ -898,7 +902,7 @@ class layout():
|
||||||
for (pin_name, bus_name) in mapping:
|
for (pin_name, bus_name) in mapping:
|
||||||
pin = inst.get_pin(pin_name)
|
pin = inst.get_pin(pin_name)
|
||||||
pin_pos = pin.center()
|
pin_pos = pin.center()
|
||||||
bus_pos = bus_offsets[bus_name]
|
bus_pos = bus_pins[bus_name].center()
|
||||||
|
|
||||||
if horizontal:
|
if horizontal:
|
||||||
# up/down then left/right
|
# up/down then left/right
|
||||||
|
|
|
||||||
|
|
@ -601,7 +601,7 @@ class bank(design.design):
|
||||||
# Connect the inverter output to the central bus
|
# Connect the inverter output to the central bus
|
||||||
out_pos = self.bank_select_inst[port].get_pin(gated_bank_sel_signals[signal]).rc()
|
out_pos = self.bank_select_inst[port].get_pin(gated_bank_sel_signals[signal]).rc()
|
||||||
name = self.control_signals[port][signal]
|
name = self.control_signals[port][signal]
|
||||||
bus_pos = vector(self.bus_xoffset[port][name].x, out_pos.y)
|
bus_pos = vector(self.bus_pins[port][name].cx(), out_pos.y)
|
||||||
self.add_path("m3", [out_pos, bus_pos])
|
self.add_path("m3", [out_pos, bus_pos])
|
||||||
self.add_via_center(layers=self.m2_stack,
|
self.add_via_center(layers=self.m2_stack,
|
||||||
offset=bus_pos)
|
offset=bus_pos)
|
||||||
|
|
@ -636,19 +636,19 @@ class bank(design.design):
|
||||||
# Overall central bus width. It includes all the column mux lines,
|
# Overall central bus width. It includes all the column mux lines,
|
||||||
# and control lines.
|
# and control lines.
|
||||||
|
|
||||||
self.bus_xoffset = [None] * len(self.all_ports)
|
self.bus_pins = [None] * len(self.all_ports)
|
||||||
# Port 0
|
# Port 0
|
||||||
# The bank is at (0,0), so this is to the left of the y-axis.
|
# The bank is at (0,0), so this is to the left of the y-axis.
|
||||||
# 2 pitches on the right for vias/jogs to access the inputs
|
# 2 pitches on the right for vias/jogs to access the inputs
|
||||||
control_bus_offset = vector(-self.m3_pitch * self.num_control_lines[0] - self.m3_pitch, self.min_y_offset)
|
control_bus_offset = vector(-self.m3_pitch * self.num_control_lines[0] - self.m3_pitch, self.min_y_offset)
|
||||||
# The control bus is routed up to two pitches below the bitcell array
|
# The control bus is routed up to two pitches below the bitcell array
|
||||||
control_bus_length = self.main_bitcell_array_bottom - self.min_y_offset - 2 * self.m1_pitch
|
control_bus_length = self.main_bitcell_array_bottom - self.min_y_offset - 2 * self.m1_pitch
|
||||||
self.bus_xoffset[0] = self.create_bus(layer="m2",
|
self.bus_pins[0] = self.create_bus(layer="m2",
|
||||||
offset=control_bus_offset,
|
offset=control_bus_offset,
|
||||||
names=self.control_signals[0],
|
names=self.control_signals[0],
|
||||||
length=control_bus_length,
|
length=control_bus_length,
|
||||||
vertical=True,
|
vertical=True,
|
||||||
make_pins=(self.num_banks==1))
|
make_pins=(self.num_banks==1))
|
||||||
|
|
||||||
# Port 1
|
# Port 1
|
||||||
if len(self.all_ports)==2:
|
if len(self.all_ports)==2:
|
||||||
|
|
@ -657,12 +657,12 @@ class bank(design.design):
|
||||||
control_bus_offset = vector(self.bitcell_array_right + self.m3_pitch,
|
control_bus_offset = vector(self.bitcell_array_right + self.m3_pitch,
|
||||||
self.max_y_offset - control_bus_length)
|
self.max_y_offset - control_bus_length)
|
||||||
# The bus for the right port is reversed so that the rbl_wl is closest to the array
|
# The bus for the right port is reversed so that the rbl_wl is closest to the array
|
||||||
self.bus_xoffset[1] = self.create_bus(layer="m2",
|
self.bus_pins[1] = self.create_bus(layer="m2",
|
||||||
offset=control_bus_offset,
|
offset=control_bus_offset,
|
||||||
names=list(reversed(self.control_signals[1])),
|
names=list(reversed(self.control_signals[1])),
|
||||||
length=control_bus_length,
|
length=control_bus_length,
|
||||||
vertical=True,
|
vertical=True,
|
||||||
make_pins=(self.num_banks==1))
|
make_pins=(self.num_banks==1))
|
||||||
|
|
||||||
def route_port_data_to_bitcell_array(self, port):
|
def route_port_data_to_bitcell_array(self, port):
|
||||||
""" Routing of BL and BR between port data and bitcell array """
|
""" Routing of BL and BR between port data and bitcell array """
|
||||||
|
|
@ -937,39 +937,32 @@ class bank(design.design):
|
||||||
# pre-decoder and this connection is in metal3
|
# pre-decoder and this connection is in metal3
|
||||||
connection = []
|
connection = []
|
||||||
connection.append((self.prefix + "p_en_bar{}".format(port),
|
connection.append((self.prefix + "p_en_bar{}".format(port),
|
||||||
self.port_data_inst[port].get_pin("p_en_bar").lc(),
|
self.port_data_inst[port].get_pin("p_en_bar")))
|
||||||
self.port_data_inst[port].get_pin("p_en_bar").layer))
|
|
||||||
|
|
||||||
rbl_wl_name = self.bitcell_array.get_rbl_wl_name(self.port_rbl_map[port])
|
rbl_wl_name = self.bitcell_array.get_rbl_wl_name(self.port_rbl_map[port])
|
||||||
connection.append((self.prefix + "wl_en{}".format(port),
|
connection.append((self.prefix + "wl_en{}".format(port),
|
||||||
self.bitcell_array_inst.get_pin(rbl_wl_name).lc(),
|
self.bitcell_array_inst.get_pin(rbl_wl_name)))
|
||||||
self.bitcell_array_inst.get_pin(rbl_wl_name).layer))
|
|
||||||
|
|
||||||
if port in self.write_ports:
|
if port in self.write_ports:
|
||||||
if port % 2:
|
connection.append((self.prefix + "w_en{}".format(port),
|
||||||
connection.append((self.prefix + "w_en{}".format(port),
|
self.port_data_inst[port].get_pin("w_en")))
|
||||||
self.port_data_inst[port].get_pin("w_en").rc(),
|
|
||||||
self.port_data_inst[port].get_pin("w_en").layer))
|
|
||||||
else:
|
|
||||||
connection.append((self.prefix + "w_en{}".format(port),
|
|
||||||
self.port_data_inst[port].get_pin("w_en").lc(),
|
|
||||||
self.port_data_inst[port].get_pin("w_en").layer))
|
|
||||||
|
|
||||||
if port in self.read_ports:
|
if port in self.read_ports:
|
||||||
connection.append((self.prefix + "s_en{}".format(port),
|
connection.append((self.prefix + "s_en{}".format(port),
|
||||||
self.port_data_inst[port].get_pin("s_en").lc(),
|
self.port_data_inst[port].get_pin("s_en")))
|
||||||
self.port_data_inst[port].get_pin("s_en").layer))
|
|
||||||
|
|
||||||
for (control_signal, pin_pos, pin_layer) in connection:
|
for (control_signal, pin) in connection:
|
||||||
if port==0:
|
control_pin = self.bus_pins[port][control_signal]
|
||||||
y_offset = self.min_y_offset
|
control_pos = vector(control_pin.cx(), pin.cy())
|
||||||
else:
|
# If the y doesn't overlap the bus, add a segment
|
||||||
y_offset = self.max_y_offset
|
if pin.cy() < control_pin.by():
|
||||||
control_pos = vector(self.bus_xoffset[port][control_signal].x, y_offset)
|
self.add_path("m2", [control_pos, control_pin.bc()])
|
||||||
if pin_layer == "m1":
|
elif pin.cy() > control_pin.uy():
|
||||||
self.add_wire(self.m1_stack, [control_pos, pin_pos])
|
self.add_path("m2", [control_pos, control_pin.uc()])
|
||||||
elif pin_layer == "m3":
|
self.add_path(pin.layer, [control_pos, pin.center()])
|
||||||
self.add_wire(self.m2_stack[::-1], [control_pos, pin_pos])
|
self.add_via_stack_center(from_layer=pin.layer,
|
||||||
|
to_layer="m2",
|
||||||
|
offset=control_pos)
|
||||||
|
|
||||||
# clk to wordline_driver
|
# clk to wordline_driver
|
||||||
control_signal = self.prefix + "wl_en{}".format(port)
|
control_signal = self.prefix + "wl_en{}".format(port)
|
||||||
|
|
@ -979,7 +972,7 @@ class bank(design.design):
|
||||||
else:
|
else:
|
||||||
pin_pos = self.port_address_inst[port].get_pin("wl_en").bc()
|
pin_pos = self.port_address_inst[port].get_pin("wl_en").bc()
|
||||||
mid_pos = pin_pos - vector(0, 2 * self.m2_gap) # to route down to the top of the bus
|
mid_pos = pin_pos - vector(0, 2 * self.m2_gap) # to route down to the top of the bus
|
||||||
control_x_offset = self.bus_xoffset[port][control_signal].x
|
control_x_offset = self.bus_pins[port][control_signal].cx()
|
||||||
control_pos = vector(control_x_offset, mid_pos.y)
|
control_pos = vector(control_x_offset, mid_pos.y)
|
||||||
self.add_wire(self.m1_stack, [pin_pos, mid_pos, control_pos])
|
self.add_wire(self.m1_stack, [pin_pos, mid_pos, control_pos])
|
||||||
self.add_via_center(layers=self.m1_stack,
|
self.add_via_center(layers=self.m1_stack,
|
||||||
|
|
|
||||||
|
|
@ -389,10 +389,10 @@ class control_logic(design.design):
|
||||||
height = self.control_logic_center.y - self.m2_pitch
|
height = self.control_logic_center.y - self.m2_pitch
|
||||||
offset = vector(self.ctrl_dff_array.width, 0)
|
offset = vector(self.ctrl_dff_array.width, 0)
|
||||||
|
|
||||||
self.rail_offsets = self.create_vertical_bus("m2",
|
self.input_bus = self.create_vertical_bus("m2",
|
||||||
offset,
|
offset,
|
||||||
self.internal_bus_list,
|
self.internal_bus_list,
|
||||||
height)
|
height)
|
||||||
|
|
||||||
def create_instances(self):
|
def create_instances(self):
|
||||||
""" Create all the instances """
|
""" Create all the instances """
|
||||||
|
|
@ -498,7 +498,7 @@ class control_logic(design.design):
|
||||||
# Connect to the rail level with the vdd rail
|
# Connect to the rail level with the vdd rail
|
||||||
# Use pen since it is in every type of control logic
|
# Use pen since it is in every type of control logic
|
||||||
vdd_ypos = self.p_en_bar_nand_inst.get_pin("vdd").by()
|
vdd_ypos = self.p_en_bar_nand_inst.get_pin("vdd").by()
|
||||||
in_pos = vector(self.rail_offsets["rbl_bl_delay"].x, vdd_ypos)
|
in_pos = vector(self.input_bus["rbl_bl_delay"].cx(), vdd_ypos)
|
||||||
mid1 = vector(out_pos.x, in_pos.y)
|
mid1 = vector(out_pos.x, in_pos.y)
|
||||||
self.add_wire(self.m1_stack, [out_pos, mid1, in_pos])
|
self.add_wire(self.m1_stack, [out_pos, mid1, in_pos])
|
||||||
self.add_via_center(layers=self.m1_stack,
|
self.add_via_center(layers=self.m1_stack,
|
||||||
|
|
@ -553,7 +553,7 @@ class control_logic(design.design):
|
||||||
|
|
||||||
def route_gated_clk_bar(self):
|
def route_gated_clk_bar(self):
|
||||||
clkbuf_map = zip(["A"], ["clk_buf"])
|
clkbuf_map = zip(["A"], ["clk_buf"])
|
||||||
self.connect_vertical_bus(clkbuf_map, self.clk_bar_inst, self.rail_offsets)
|
self.connect_vertical_bus(clkbuf_map, self.clk_bar_inst, self.input_bus)
|
||||||
|
|
||||||
out_pos = self.clk_bar_inst.get_pin("Z").center()
|
out_pos = self.clk_bar_inst.get_pin("Z").center()
|
||||||
in_pos = self.gated_clk_bar_inst.get_pin("A").center()
|
in_pos = self.gated_clk_bar_inst.get_pin("A").center()
|
||||||
|
|
@ -563,7 +563,7 @@ class control_logic(design.design):
|
||||||
clkbuf_map = zip(["B"], ["cs"])
|
clkbuf_map = zip(["B"], ["cs"])
|
||||||
self.connect_vertical_bus(clkbuf_map,
|
self.connect_vertical_bus(clkbuf_map,
|
||||||
self.gated_clk_bar_inst,
|
self.gated_clk_bar_inst,
|
||||||
self.rail_offsets,
|
self.input_bus,
|
||||||
self.m2_stack[::-1])
|
self.m2_stack[::-1])
|
||||||
# The pin is on M1, so we need another via as well
|
# The pin is on M1, so we need another via as well
|
||||||
b_pin = self.gated_clk_bar_inst.get_pin("B")
|
b_pin = self.gated_clk_bar_inst.get_pin("B")
|
||||||
|
|
@ -591,12 +591,12 @@ class control_logic(design.design):
|
||||||
clkbuf_map = zip(["A", "B"], ["clk_buf", "cs"])
|
clkbuf_map = zip(["A", "B"], ["clk_buf", "cs"])
|
||||||
self.connect_vertical_bus(clkbuf_map,
|
self.connect_vertical_bus(clkbuf_map,
|
||||||
self.gated_clk_buf_inst,
|
self.gated_clk_buf_inst,
|
||||||
self.rail_offsets)
|
self.input_bus)
|
||||||
|
|
||||||
clkbuf_map = zip(["Z"], ["gated_clk_buf"])
|
clkbuf_map = zip(["Z"], ["gated_clk_buf"])
|
||||||
self.connect_vertical_bus(clkbuf_map,
|
self.connect_vertical_bus(clkbuf_map,
|
||||||
self.gated_clk_buf_inst,
|
self.gated_clk_buf_inst,
|
||||||
self.rail_offsets,
|
self.input_bus,
|
||||||
self.m2_stack[::-1])
|
self.m2_stack[::-1])
|
||||||
# The pin is on M1, so we need another via as well
|
# The pin is on M1, so we need another via as well
|
||||||
z_pin = self.gated_clk_buf_inst.get_pin("Z")
|
z_pin = self.gated_clk_buf_inst.get_pin("Z")
|
||||||
|
|
@ -619,7 +619,7 @@ class control_logic(design.design):
|
||||||
|
|
||||||
def route_wlen(self):
|
def route_wlen(self):
|
||||||
wlen_map = zip(["A"], ["gated_clk_bar"])
|
wlen_map = zip(["A"], ["gated_clk_bar"])
|
||||||
self.connect_vertical_bus(wlen_map, self.wl_en_inst, self.rail_offsets)
|
self.connect_vertical_bus(wlen_map, self.wl_en_inst, self.input_bus)
|
||||||
|
|
||||||
self.connect_output(self.wl_en_inst, "Z", "wl_en")
|
self.connect_output(self.wl_en_inst, "Z", "wl_en")
|
||||||
|
|
||||||
|
|
@ -644,7 +644,7 @@ class control_logic(design.design):
|
||||||
|
|
||||||
def route_pen(self):
|
def route_pen(self):
|
||||||
in_map = zip(["A", "B"], ["gated_clk_buf", "rbl_bl_delay"])
|
in_map = zip(["A", "B"], ["gated_clk_buf", "rbl_bl_delay"])
|
||||||
self.connect_vertical_bus(in_map, self.p_en_bar_nand_inst, self.rail_offsets)
|
self.connect_vertical_bus(in_map, self.p_en_bar_nand_inst, self.input_bus)
|
||||||
|
|
||||||
out_pin = self.p_en_bar_nand_inst.get_pin("Z")
|
out_pin = self.p_en_bar_nand_inst.get_pin("Z")
|
||||||
out_pos = out_pin.center()
|
out_pos = out_pin.center()
|
||||||
|
|
@ -687,7 +687,7 @@ class control_logic(design.design):
|
||||||
input_name = "cs"
|
input_name = "cs"
|
||||||
|
|
||||||
sen_map = zip(["A", "B", "C"], ["rbl_bl_delay", "gated_clk_bar", input_name])
|
sen_map = zip(["A", "B", "C"], ["rbl_bl_delay", "gated_clk_bar", input_name])
|
||||||
self.connect_vertical_bus(sen_map, self.s_en_gate_inst, self.rail_offsets)
|
self.connect_vertical_bus(sen_map, self.s_en_gate_inst, self.input_bus)
|
||||||
|
|
||||||
self.connect_output(self.s_en_gate_inst, "Z", "s_en")
|
self.connect_output(self.s_en_gate_inst, "Z", "s_en")
|
||||||
|
|
||||||
|
|
@ -711,7 +711,7 @@ class control_logic(design.design):
|
||||||
self.route_output_to_bus_jogged(self.rbl_bl_delay_inv_inst, "rbl_bl_delay_bar")
|
self.route_output_to_bus_jogged(self.rbl_bl_delay_inv_inst, "rbl_bl_delay_bar")
|
||||||
|
|
||||||
rbl_map = zip(["A"], ["rbl_bl_delay"])
|
rbl_map = zip(["A"], ["rbl_bl_delay"])
|
||||||
self.connect_vertical_bus(rbl_map, self.rbl_bl_delay_inv_inst, self.rail_offsets)
|
self.connect_vertical_bus(rbl_map, self.rbl_bl_delay_inv_inst, self.input_bus)
|
||||||
|
|
||||||
def create_wen_row(self):
|
def create_wen_row(self):
|
||||||
|
|
||||||
|
|
@ -743,7 +743,7 @@ class control_logic(design.design):
|
||||||
input_name = "cs"
|
input_name = "cs"
|
||||||
|
|
||||||
wen_map = zip(["A", "B", "C"], [input_name, "rbl_bl_delay_bar", "gated_clk_bar"])
|
wen_map = zip(["A", "B", "C"], [input_name, "rbl_bl_delay_bar", "gated_clk_bar"])
|
||||||
self.connect_vertical_bus(wen_map, self.w_en_gate_inst, self.rail_offsets)
|
self.connect_vertical_bus(wen_map, self.w_en_gate_inst, self.input_bus)
|
||||||
|
|
||||||
self.connect_output(self.w_en_gate_inst, "Z", "w_en")
|
self.connect_output(self.w_en_gate_inst, "Z", "w_en")
|
||||||
|
|
||||||
|
|
@ -766,13 +766,13 @@ class control_logic(design.design):
|
||||||
dff_out_map = zip(["dout_bar_0", "dout_0"], ["cs", "cs_bar"])
|
dff_out_map = zip(["dout_bar_0", "dout_0"], ["cs", "cs_bar"])
|
||||||
else:
|
else:
|
||||||
dff_out_map = zip(["dout_bar_0"], ["cs"])
|
dff_out_map = zip(["dout_bar_0"], ["cs"])
|
||||||
self.connect_vertical_bus(dff_out_map, self.ctrl_dff_inst, self.rail_offsets, self.m2_stack[::-1])
|
self.connect_vertical_bus(dff_out_map, self.ctrl_dff_inst, self.input_bus, self.m2_stack[::-1])
|
||||||
|
|
||||||
# Connect the clock rail to the other clock rail
|
# Connect the clock rail to the other clock rail
|
||||||
# by routing in the supply rail track to avoid channel conflicts
|
# by routing in the supply rail track to avoid channel conflicts
|
||||||
in_pos = self.ctrl_dff_inst.get_pin("clk").uc()
|
in_pos = self.ctrl_dff_inst.get_pin("clk").uc()
|
||||||
mid_pos = in_pos + vector(0, self.and2.height)
|
mid_pos = in_pos + vector(0, self.and2.height)
|
||||||
rail_pos = vector(self.rail_offsets["clk_buf"].x, mid_pos.y)
|
rail_pos = vector(self.input_bus["clk_buf"].cx(), mid_pos.y)
|
||||||
self.add_wire(self.m1_stack, [in_pos, mid_pos, rail_pos])
|
self.add_wire(self.m1_stack, [in_pos, mid_pos, rail_pos])
|
||||||
self.add_via_center(layers=self.m1_stack,
|
self.add_via_center(layers=self.m1_stack,
|
||||||
offset=rail_pos)
|
offset=rail_pos)
|
||||||
|
|
@ -1006,8 +1006,8 @@ class control_logic(design.design):
|
||||||
# Connect this at the bottom of the buffer
|
# Connect this at the bottom of the buffer
|
||||||
out_pos = inst.get_pin("Z").center()
|
out_pos = inst.get_pin("Z").center()
|
||||||
mid1 = vector(out_pos.x, out_pos.y - 0.25 * inst.mod.height)
|
mid1 = vector(out_pos.x, out_pos.y - 0.25 * inst.mod.height)
|
||||||
mid2 = vector(self.rail_offsets[name].x, mid1.y)
|
mid2 = vector(self.input_bus[name].cx(), mid1.y)
|
||||||
bus_pos = self.rail_offsets[name]
|
bus_pos = self.input_bus[name].center()
|
||||||
self.add_wire(self.m2_stack[::-1], [out_pos, mid1, mid2, bus_pos])
|
self.add_wire(self.m2_stack[::-1], [out_pos, mid1, mid2, bus_pos])
|
||||||
# The pin is on M1, so we need another via as well
|
# The pin is on M1, so we need another via as well
|
||||||
self.add_via_center(layers=self.m1_stack,
|
self.add_via_center(layers=self.m1_stack,
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ class hierarchical_decoder(design.design):
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
index = pre_num * 2 + i
|
index = pre_num * 2 + i
|
||||||
|
|
||||||
input_pos = self.input_bus["addr_{}".format(index)]
|
input_pos = self.input_bus["addr_{}".format(index)].center()
|
||||||
|
|
||||||
in_name = "in_{}".format(i)
|
in_name = "in_{}".format(i)
|
||||||
decoder_pin = self.pre2x4_inst[pre_num].get_pin(in_name)
|
decoder_pin = self.pre2x4_inst[pre_num].get_pin(in_name)
|
||||||
|
|
@ -223,7 +223,7 @@ class hierarchical_decoder(design.design):
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
index = pre_num * 3 + i + self.no_of_pre2x4 * 2
|
index = pre_num * 3 + i + self.no_of_pre2x4 * 2
|
||||||
|
|
||||||
input_pos = self.input_bus["addr_{}".format(index)]
|
input_pos = self.input_bus["addr_{}".format(index)].center()
|
||||||
|
|
||||||
in_name = "in_{}".format(i)
|
in_name = "in_{}".format(i)
|
||||||
decoder_pin = self.pre3x8_inst[pre_num].get_pin(in_name)
|
decoder_pin = self.pre3x8_inst[pre_num].get_pin(in_name)
|
||||||
|
|
@ -572,7 +572,7 @@ class hierarchical_decoder(design.design):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pin_pos = pin.center()
|
pin_pos = pin.center()
|
||||||
rail_pos = vector(self.predecode_bus[rail_name].x, pin_pos.y)
|
rail_pos = vector(self.predecode_bus[rail_name].cx(), pin_pos.y)
|
||||||
self.add_path(self.input_layer, [rail_pos, pin_pos])
|
self.add_path(self.input_layer, [rail_pos, pin_pos])
|
||||||
|
|
||||||
self.add_via_stack_center(from_layer=self.bus_layer,
|
self.add_via_stack_center(from_layer=self.bus_layer,
|
||||||
|
|
@ -595,11 +595,11 @@ class hierarchical_decoder(design.design):
|
||||||
pin_pos = pin.rc()
|
pin_pos = pin.rc()
|
||||||
mid_point1 = vector(x_offset, pin_pos.y)
|
mid_point1 = vector(x_offset, pin_pos.y)
|
||||||
mid_point2 = vector(x_offset, y_offset)
|
mid_point2 = vector(x_offset, y_offset)
|
||||||
rail_pos = vector(self.predecode_bus[rail_name].x, mid_point2.y)
|
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])
|
self.add_path(self.output_layer, [pin_pos, mid_point1, mid_point2, rail_pos])
|
||||||
|
|
||||||
# pin_pos = pin.center()
|
# pin_pos = pin.center()
|
||||||
# rail_pos = vector(self.predecode_bus[rail_name].x, pin_pos.y)
|
# rail_pos = vector(self.predecode_bus[rail_name].cx(), pin_pos.y)
|
||||||
# self.add_path(self.output_layer, [pin_pos, rail_pos])
|
# self.add_path(self.output_layer, [pin_pos, rail_pos])
|
||||||
self.add_via_stack_center(from_layer=pin.layer,
|
self.add_via_stack_center(from_layer=pin.layer,
|
||||||
to_layer=self.output_layer,
|
to_layer=self.output_layer,
|
||||||
|
|
|
||||||
|
|
@ -202,15 +202,15 @@ class hierarchical_predecode(design.design):
|
||||||
y_offset = pin.cy()
|
y_offset = pin.cy()
|
||||||
in_pin = "in_{}".format(num)
|
in_pin = "in_{}".format(num)
|
||||||
a_pin = "A_{}".format(num)
|
a_pin = "A_{}".format(num)
|
||||||
in_pos = vector(self.input_rails[in_pin].x, y_offset)
|
in_pos = vector(self.input_rails[in_pin].cx(), y_offset)
|
||||||
a_pos = vector(self.decode_rails[a_pin].x, 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_path(self.input_layer, [in_pos, a_pos])
|
||||||
self.add_via_stack_center(from_layer=self.input_layer,
|
self.add_via_stack_center(from_layer=self.input_layer,
|
||||||
to_layer=self.bus_layer,
|
to_layer=self.bus_layer,
|
||||||
offset=[self.input_rails[in_pin].x, y_offset])
|
offset=[self.input_rails[in_pin].cx(), y_offset])
|
||||||
self.add_via_stack_center(from_layer=self.input_layer,
|
self.add_via_stack_center(from_layer=self.input_layer,
|
||||||
to_layer=self.bus_layer,
|
to_layer=self.bus_layer,
|
||||||
offset=[self.decode_rails[a_pin].x, y_offset])
|
offset=[self.decode_rails[a_pin].cx(), y_offset])
|
||||||
|
|
||||||
def route_output_and(self):
|
def route_output_and(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -240,12 +240,12 @@ class hierarchical_predecode(design.design):
|
||||||
# since this is where the p/n devices are and there are no
|
# since this is where the p/n devices are and there are no
|
||||||
# pins in the and gates.
|
# pins in the and gates.
|
||||||
if OPTS.tech_name == "s8":
|
if OPTS.tech_name == "s8":
|
||||||
rail_pos = vector(self.decode_rails[out_pin].x, inv_out_pos.y)
|
rail_pos = vector(self.decode_rails[out_pin].cx(), inv_out_pos.y)
|
||||||
self.add_path(self.output_layer, [inv_out_pos, rail_pos])
|
self.add_path(self.output_layer, [inv_out_pos, rail_pos])
|
||||||
else:
|
else:
|
||||||
y_offset = (inv_num + 1) * self.inv.height - self.output_layer_pitch
|
y_offset = (inv_num + 1) * self.inv.height - self.output_layer_pitch
|
||||||
right_pos = inv_out_pos + vector(self.inv.width - self.inv.get_pin("Z").rx(), 0)
|
right_pos = inv_out_pos + vector(self.inv.width - self.inv.get_pin("Z").rx(), 0)
|
||||||
rail_pos = vector(self.decode_rails[out_pin].x, y_offset)
|
rail_pos = vector(self.decode_rails[out_pin].cx(), y_offset)
|
||||||
self.add_path(self.output_layer, [inv_out_pos, right_pos, vector(right_pos.x, y_offset), rail_pos])
|
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,
|
self.add_via_stack_center(from_layer=inv_out_pin.layer,
|
||||||
|
|
@ -259,7 +259,7 @@ class hierarchical_predecode(design.design):
|
||||||
# route input
|
# route input
|
||||||
pin = self.inv_inst[inv_num].get_pin("A")
|
pin = self.inv_inst[inv_num].get_pin("A")
|
||||||
inv_in_pos = pin.center()
|
inv_in_pos = pin.center()
|
||||||
in_pos = vector(self.input_rails[in_pin].x, inv_in_pos.y)
|
in_pos = vector(self.input_rails[in_pin].cx(), inv_in_pos.y)
|
||||||
self.add_path(self.input_layer, [in_pos, inv_in_pos])
|
self.add_path(self.input_layer, [in_pos, inv_in_pos])
|
||||||
self.add_via_stack_center(from_layer=pin.layer,
|
self.add_via_stack_center(from_layer=pin.layer,
|
||||||
to_layer=self.input_layer,
|
to_layer=self.input_layer,
|
||||||
|
|
@ -290,7 +290,7 @@ class hierarchical_predecode(design.design):
|
||||||
for rail_pin, gate_pin in zip(index_lst, gate_lst):
|
for rail_pin, gate_pin in zip(index_lst, gate_lst):
|
||||||
pin = self.and_inst[k].get_pin(gate_pin)
|
pin = self.and_inst[k].get_pin(gate_pin)
|
||||||
pin_pos = pin.center()
|
pin_pos = pin.center()
|
||||||
rail_pos = vector(self.decode_rails[rail_pin].x, pin_pos.y)
|
rail_pos = vector(self.decode_rails[rail_pin].cx(), pin_pos.y)
|
||||||
self.add_path(self.input_layer, [rail_pos, pin_pos])
|
self.add_path(self.input_layer, [rail_pos, pin_pos])
|
||||||
self.add_via_stack_center(from_layer=self.input_layer,
|
self.add_via_stack_center(from_layer=self.input_layer,
|
||||||
to_layer=self.bus_layer,
|
to_layer=self.bus_layer,
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import debug
|
||||||
from vector import vector
|
from vector import vector
|
||||||
from sram_factory import factory
|
from sram_factory import factory
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
|
from tech import layer
|
||||||
|
|
||||||
|
|
||||||
class precharge_array(design.design):
|
class precharge_array(design.design):
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ from tech import parameter
|
||||||
from vector import vector
|
from vector import vector
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
from sram_factory import factory
|
from sram_factory import factory
|
||||||
from tech import drc
|
from tech import drc, layer
|
||||||
|
|
||||||
|
|
||||||
class precharge(design.design):
|
class precharge(design.design):
|
||||||
|
|
@ -38,10 +38,16 @@ class precharge(design.design):
|
||||||
|
|
||||||
if self.bitcell_bl_pin.layer == "m1":
|
if self.bitcell_bl_pin.layer == "m1":
|
||||||
self.bitline_layer = "m1"
|
self.bitline_layer = "m1"
|
||||||
self.en_layer = "m2"
|
if "li" in layer:
|
||||||
|
self.en_layer = "li"
|
||||||
|
else:
|
||||||
|
self.en_layer = "m2"
|
||||||
else:
|
else:
|
||||||
self.bitline_layer = "m2"
|
self.bitline_layer = "m2"
|
||||||
self.en_layer = "m1"
|
if "li" in layer:
|
||||||
|
self.en_layer = "li"
|
||||||
|
else:
|
||||||
|
self.en_layer = "m1"
|
||||||
|
|
||||||
# Creates the netlist and layout
|
# Creates the netlist and layout
|
||||||
# Since it has variable height, it is not a pgate.
|
# Since it has variable height, it is not a pgate.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue