Make pand2 and pbuf derive pgate. Initial DRC wrong layout.

This commit is contained in:
Matt Guthaus 2018-11-26 16:19:18 -08:00
parent dd79fc560b
commit 9e0b31d685
3 changed files with 52 additions and 64 deletions

View File

@ -48,9 +48,7 @@ class control_logic(design.design):
""" Create layout and route between modules """ """ Create layout and route between modules """
self.place_instances() self.place_instances()
self.route_all() self.route_all()
#self.add_lvs_correspondence_points() #self.add_lvs_correspondence_points()
self.DRC_LVS() self.DRC_LVS()
@ -136,20 +134,19 @@ class control_logic(design.design):
# list of output control signals (for making a vertical bus) # list of output control signals (for making a vertical bus)
if self.port_type == "rw": if self.port_type == "rw":
self.internal_bus_list = ["clk_buf", "clk_buf_bar", "we", "cs"] self.internal_bus_list = ["clk_buf", "gated_clk", "we", "we_bar", "cs"]
else: else:
self.internal_bus_list = ["clk_buf", "clk_buf_bar", "cs"] self.internal_bus_list = ["clk_buf", "gated_clk", "cs"]
# leave space for the bus plus one extra space # leave space for the bus plus one extra space
self.internal_bus_width = (len(self.internal_bus_list)+1)*self.m2_pitch self.internal_bus_width = (len(self.internal_bus_list)+1)*self.m2_pitch
# Outputs to the bank # Outputs to the bank
if self.port_type == "r": if self.port_type == "r":
self.output_list = ["s_en"] self.output_list = ["s_en", "p_en"]
elif self.port_type == "w": elif self.port_type == "w":
self.output_list = ["w_en"] self.output_list = ["w_en"]
else: else:
self.output_list = ["s_en", "w_en"] self.output_list = ["s_en", "w_en", "p_en"]
self.output_list.append("clk_buf_bar")
self.output_list.append("clk_buf") self.output_list.append("clk_buf")
self.supply_list = ["vdd", "gnd"] self.supply_list = ["vdd", "gnd"]
@ -170,7 +167,7 @@ class control_logic(design.design):
if (self.port_type == "rw") or (self.port_type == "w"): if (self.port_type == "rw") or (self.port_type == "w"):
self.create_we_row() self.create_we_row()
if (self.port_type == "rw") or (self.port_type == "r"): if (self.port_type == "rw") or (self.port_type == "r"):
self.create_rbl_in_row() self.create_pen_row()
self.create_sen_row() self.create_sen_row()
self.create_rbl() self.create_rbl()
@ -196,7 +193,7 @@ class control_logic(design.design):
control_center_y = self.w_en_inst.uy() control_center_y = self.w_en_inst.uy()
row += 1 row += 1
if (self.port_type == "rw") or (self.port_type == "r"): if (self.port_type == "rw") or (self.port_type == "r"):
self.place_rbl_in_row(row=row) self.place_pen_row(row=row)
self.place_sen_row(row=row+1) self.place_sen_row(row=row+1)
self.place_rbl(row=row+2) self.place_rbl(row=row+2)
height = self.rbl_inst.uy() height = self.rbl_inst.uy()
@ -220,7 +217,7 @@ class control_logic(design.design):
if (self.port_type == "rw") or (self.port_type == "w"): if (self.port_type == "rw") or (self.port_type == "w"):
self.route_wen() self.route_wen()
if (self.port_type == "rw") or (self.port_type == "r"): if (self.port_type == "rw") or (self.port_type == "r"):
self.route_rbl_in() self.route_rbl()
self.route_sen() self.route_sen()
self.route_clk() self.route_clk()
self.route_supply() self.route_supply()
@ -260,7 +257,7 @@ class control_logic(design.design):
self.clkbuf_inst.place(offset) self.clkbuf_inst.place(offset)
self.row_end_inst.append(self.clkbuf_inst) self.row_end_inst.append(self.clkbuf_inst)
def place_gatedclk_row(self,row): def place_gated_clk_row(self,row):
""" Place the gated clk logic below the control flops """ """ Place the gated clk logic below the control flops """
x_off = self.ctrl_dff_array.width + self.internal_bus_width x_off = self.ctrl_dff_array.width + self.internal_bus_width
(y_off,mirror)=self.get_offset(row) (y_off,mirror)=self.get_offset(row)
@ -269,14 +266,20 @@ class control_logic(design.design):
self.row_end_inst.append(self.gated_clk_inst) self.row_end_inst.append(self.gated_clk_inst)
def create_rbl_in_row(self): def create_pen_row(self):
# input: gated_clk, we_bar, output: pre_p_en # input: gated_clk, we_bar, output: pre_p_en
self.pre_p_en_inst=self.add_inst(name="and2_pre_p_en", self.pre_p_en_inst=self.add_inst(name="and2_pre_p_en",
mod=self.and2) mod=self.and2)
self.connect_inst(["gated_clk", "we_bar", "pre_p_en", "vdd", "gnd"]) self.connect_inst(["gated_clk", "we_bar", "pre_p_en", "vdd", "gnd"])
def place_rbl_in_row(self,row): # input: pre_p_en, output: p_en
self.p_en_inst=self.add_inst(name="buf_p_en",
mod=self.pbuf8)
self.connect_inst(["pre_p_en", "p_en", "vdd", "gnd"])
def place_pen_row(self,row):
x_off = self.ctrl_dff_array.width + self.internal_bus_width x_off = self.ctrl_dff_array.width + self.internal_bus_width
(y_off,mirror)=self.get_offset(row) (y_off,mirror)=self.get_offset(row)
@ -361,7 +364,7 @@ class control_logic(design.design):
if self.port_type == "rw": if self.port_type == "rw":
self.pre_w_en_inst = self.add_inst(name="and_pre_w_en", self.pre_w_en_inst = self.add_inst(name="and_pre_w_en",
mod=self.and2) mod=self.and2)
self.connect_inst(["we", "gated_clk", "pre_w_en", "vdd", "gnd"]) self.connect_inst(["gated_clk", "we", "pre_w_en", "vdd", "gnd"])
input_name = "pre_w_en" input_name = "pre_w_en"
else: else:
# No we signal is needed for write-only ports # No we signal is needed for write-only ports
@ -390,28 +393,23 @@ class control_logic(design.design):
self.row_end_inst.append(self.w_en_inst) self.row_end_inst.append(self.w_en_inst)
def route_rbl_in(self): def route_rbl(self):
""" Connect the logic for the rbl_in generation """ """ Connect the logic for the rbl_in generation """
rbl_in_map = zip(["A", "B"], ["clk_buf_bar", "cs"])
self.connect_vertical_bus(rbl_in_map, self.rbl_in_bar_inst, self.rail_offsets)
# Connect the NAND3 output to the inverter
# The pins are assumed to extend all the way to the cell edge
rbl_in_bar_pos = self.rbl_in_bar_inst.get_pin("Z").center()
inv_in_pos = self.rbl_in_inst.get_pin("A").center()
mid1 = vector(inv_in_pos.x,rbl_in_bar_pos.y)
self.add_path("metal1",[rbl_in_bar_pos,mid1,inv_in_pos])
# Connect the output to the RBL # Connect the NAND gate inputs to the bus
rbl_out_pos = self.rbl_in_inst.get_pin("Z").center() pre_p_en_in_map = zip(["A", "B"], ["gated_clk", "we_bar"])
self.connect_vertical_bus(pre_p_en_in_map, self.pre_p_en_inst, self.rail_offsets)
# Connect the output of the precharge enable to the RBL input
pre_p_en_out_pos = self.pre_p_en_inst.get_pin("Z").center()
rbl_in_pos = self.rbl_inst.get_pin("en").center() rbl_in_pos = self.rbl_inst.get_pin("en").center()
mid1 = vector(rbl_in_pos.x,rbl_out_pos.y) mid1 = vector(rbl_in_pos.x,pre_p_en_out_pos.y)
self.add_wire(("metal3","via2","metal2"),[rbl_out_pos,mid1,rbl_in_pos]) self.add_wire(("metal3","via2","metal2"),[pre_p_en_out_pos,mid1,rbl_in_pos])
self.add_via_center(layers=("metal1","via1","metal2"), self.add_via_center(layers=("metal1","via1","metal2"),
offset=rbl_out_pos, offset=pre_p_en_out_pos,
rotate=90) rotate=90)
self.add_via_center(layers=("metal2","via2","metal3"), self.add_via_center(layers=("metal2","via2","metal3"),
offset=rbl_out_pos, offset=pre_p_en_out_pos,
rotate=90) rotate=90)
@ -464,32 +462,24 @@ class control_logic(design.design):
def route_wen(self): def route_wen(self):
if self.port_type == "rw":
wen_map = zip(["A", "B", "C"], ["clk_buf_bar", "cs", "we"])
else:
wen_map = zip(["A", "B"], ["clk_buf_bar", "cs"])
self.connect_vertical_bus(wen_map, self.w_en_bar_inst, self.rail_offsets)
# Connect the NAND3 output to the inverter
# The pins are assumed to extend all the way to the cell edge
w_en_bar_pos = self.w_en_bar_inst.get_pin("Z").center()
inv_in_pos = self.pre_w_en_inst.get_pin("A").center()
mid1 = vector(inv_in_pos.x,w_en_bar_pos.y)
self.add_path("metal1",[w_en_bar_pos,mid1,inv_in_pos])
self.add_path("metal1",[self.pre_w_en_inst.get_pin("Z").center(), self.pre_w_en_bar_inst.get_pin("A").center()]) if self.port_type == "rw":
self.add_path("metal1",[self.pre_w_en_bar_inst.get_pin("Z").center(), self.w_en_inst.get_pin("A").center()]) wen_map = zip(["A", "B"], ["gated_clk", "we"])
self.connect_vertical_bus(wen_map, self.pre_w_en_inst, self.rail_offsets)
self.add_path("metal1",[self.pre_w_en_inst.get_pin("Z").center(), self.w_en_inst.get_pin("A").center()])
else:
wen_map = zip(["A"], ["gated_clk"])
self.connect_vertical_bus(wen_map, self.w_en_inst, self.rail_offsets)
self.connect_output(self.w_en_inst, "Z", "w_en") self.connect_output(self.w_en_inst, "Z", "w_en")
def route_sen(self): def route_sen(self):
rbl_out_pos = self.rbl_inst.get_pin("out").bc() rbl_out_pos = self.rbl_inst.get_pin("out").bc()
in_pos = self.pre_s_en_bar_inst.get_pin("A").lc() in_pos = self.s_en_inst.get_pin("A").lc()
mid1 = vector(rbl_out_pos.x,in_pos.y) mid1 = vector(rbl_out_pos.x,in_pos.y)
self.add_wire(("metal1","via1","metal2"),[rbl_out_pos,mid1,in_pos]) self.add_wire(("metal1","via1","metal2"),[rbl_out_pos,mid1,in_pos])
#s_en_pos = self.s_en.get_pin("Z").lc()
self.add_path("metal1",[self.pre_s_en_bar_inst.get_pin("Z").center(), self.s_en_inst.get_pin("A").center()])
self.connect_output(self.s_en_inst, "Z", "s_en") self.connect_output(self.s_en_inst, "Z", "s_en")
@ -502,13 +492,13 @@ class control_logic(design.design):
start=clk_pin.bc(), start=clk_pin.bc(),
end=clk_pin.bc().scale(1,0)) end=clk_pin.bc().scale(1,0))
clkbuf_map = zip(["Z", "Zb"], ["clk_buf", "clk_buf_bar"]) clkbuf_map = zip(["Z"], ["clk_buf"])
self.connect_vertical_bus(clkbuf_map, self.clkbuf_inst, self.rail_offsets, ("metal3", "via2", "metal2")) self.connect_vertical_bus(clkbuf_map, self.clkbuf_inst, self.rail_offsets, ("metal3", "via2", "metal2"))
# self.connect_rail_from_right_m2m3(self.clkbuf_inst, "Z", "clk_buf") clkbuf_map = zip(["Z"], ["gated_clk"])
# self.connect_rail_from_right_m2m3(self.clkbuf_inst, "Zb", "clk_buf_bar") self.connect_vertical_bus(clkbuf_map, self.gated_clk_inst, self.rail_offsets, ("metal3", "via2", "metal2"))
self.connect_output(self.clkbuf_inst, "Z", "clk_buf") self.connect_output(self.clkbuf_inst, "Z", "clk_buf")
self.connect_output(self.clkbuf_inst, "Zb", "clk_buf_bar")
def connect_output(self, inst, pin_name, out_name): def connect_output(self, inst, pin_name, out_name):
""" Create an output pin on the right side from the pin of a given instance. """ """ Create an output pin on the right side from the pin of a given instance. """

View File

@ -1,13 +1,13 @@
import debug import debug
import design
from tech import drc from tech import drc
from math import log from math import log
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from pnand2 import pnand2 from pnand2 import pnand2
from pinv import pinv from pinv import pinv
import pgate
class pand2(design.design): class pand2(pgate.pgate):
""" """
This is a simple buffer used for driving loads. This is a simple buffer used for driving loads.
""" """
@ -17,16 +17,15 @@ class pand2(design.design):
unique_id = 1 unique_id = 1
def __init__(self, size=1, height=bitcell.height, name=""): def __init__(self, size=1, height=None, name=""):
self.size = size self.size = size
self.height = height
if name=="": if name=="":
name = "pand2_{0}_{1}".format(size, pand2.unique_id) name = "pand2_{0}_{1}".format(size, pand2.unique_id)
pand2.unique_id += 1 pand2.unique_id += 1
design.design.__init__(self, name) pgate.pgate.__init__(self, name, height)
debug.info(1, "Creating {}".format(self.name)) debug.info(1, "Creating {}".format(self.name))

View File

@ -1,12 +1,12 @@
import debug import debug
import design
from tech import drc from tech import drc
from math import log from math import log
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from pinv import pinv from pinv import pinv
import pgate
class pbuf(design.design): class pbuf(pgate.pgate):
""" """
This is a simple buffer used for driving loads. This is a simple buffer used for driving loads.
""" """
@ -16,25 +16,24 @@ class pbuf(design.design):
unique_id = 1 unique_id = 1
def __init__(self, size=4, height=bitcell.height, name=""): def __init__(self, size=4, height=None, name=""):
self.stage_effort = 4 self.stage_effort = 4
self.size = size self.size = size
self.width = 0
self.height = height self.height = height
# FIXME: Change the number of stages to support high drives.
if name=="": if name=="":
name = "pbuf_{0}_{1}".format(self.size, pbuf.unique_id) name = "pbuf_{0}_{1}".format(self.size, pbuf.unique_id)
pbuf.unique_id += 1 pbuf.unique_id += 1
design.design.__init__(self, name) pgate.pgate.__init__(self, name, height)
debug.info(1, "Creating {}".format(self.name)) debug.info(1, "creating {0} with size of {1}".format(self.name,self.size))
self.create_netlist() self.create_netlist()
if not OPTS.netlist_only: if not OPTS.netlist_only:
self.create_layout() self.create_layout()
def create_netlist(self): def create_netlist(self):
self.add_pins() self.add_pins()
self.create_modules() self.create_modules()