mirror of https://github.com/VLSIDA/OpenRAM.git
Add netlist only mode to new pgates
This commit is contained in:
parent
2eff166527
commit
b440031855
|
|
@ -4,8 +4,9 @@ from tech import drc, parameter
|
|||
import debug
|
||||
import contact
|
||||
from pinv import pinv
|
||||
from pbuf import pbuf
|
||||
from pand2 import pand2
|
||||
from pnand2 import pnand2
|
||||
from pnand3 import pnand3
|
||||
from pinvbuf import pinvbuf
|
||||
from dff_inv import dff_inv
|
||||
from dff_inv_array import dff_inv_array
|
||||
|
|
@ -71,22 +72,30 @@ class control_logic(design.design):
|
|||
self.ctrl_dff_array = dff_inv_array(rows=self.num_control_signals,columns=1)
|
||||
self.add_mod(self.ctrl_dff_array)
|
||||
|
||||
self.and2 = pand2(height=dff_height)
|
||||
self.add_mod(self.and2)
|
||||
|
||||
self.nand2 = pnand2(height=dff_height)
|
||||
self.add_mod(self.nand2)
|
||||
self.nand3 = pnand3(height=dff_height)
|
||||
self.add_mod(self.nand3)
|
||||
|
||||
# Special gates: inverters for buffering
|
||||
# Size the clock for the number of rows (fanout)
|
||||
clock_driver_size = max(1,int(self.num_rows/4))
|
||||
self.clkbuf = pinvbuf(clock_driver_size,height=dff_height)
|
||||
self.clkbuf = pbuf(size=clock_driver_size, height=dff_height)
|
||||
self.add_mod(self.clkbuf)
|
||||
self.inv = self.inv1 = pinv(size=1, height=dff_height)
|
||||
self.add_mod(self.inv1)
|
||||
self.inv2 = pinv(size=4, height=dff_height)
|
||||
self.add_mod(self.inv2)
|
||||
self.inv8 = pinv(size=16, height=dff_height)
|
||||
self.add_mod(self.inv8)
|
||||
|
||||
self.pbuf8 = pbuf(size=8, height=dff_height)
|
||||
self.add_mod(self.pbuf8)
|
||||
|
||||
self.pbuf1 = pbuf(size=1, height=dff_height)
|
||||
self.add_mod(self.pbuf1)
|
||||
|
||||
# self.inv = self.inv1 = pinv(size=1, height=dff_height)
|
||||
# self.add_mod(self.inv1)
|
||||
# self.inv2 = pinv(size=4, height=dff_height)
|
||||
# self.add_mod(self.inv2)
|
||||
# self.inv8 = pinv(size=16, height=dff_height)
|
||||
# self.add_mod(self.inv8)
|
||||
|
||||
if (self.port_type == "rw") or (self.port_type == "r"):
|
||||
from importlib import reload
|
||||
|
|
@ -157,7 +166,7 @@ class control_logic(design.design):
|
|||
def create_instances(self):
|
||||
""" Create all the instances """
|
||||
self.create_dffs()
|
||||
self.create_clk_row()
|
||||
self.create_clk_rows()
|
||||
if (self.port_type == "rw") or (self.port_type == "w"):
|
||||
self.create_we_row()
|
||||
if (self.port_type == "rw") or (self.port_type == "r"):
|
||||
|
|
@ -177,8 +186,10 @@ class control_logic(design.design):
|
|||
|
||||
row = 0
|
||||
# Add the logic on the right of the bus
|
||||
self.place_clk_row(row=row) # clk is a double-high cell
|
||||
row += 2
|
||||
self.place_clkbuf_row(row=row)
|
||||
row += 1
|
||||
self.place_gated_clk_row(row=row)
|
||||
row += 1
|
||||
if (self.port_type == "rw") or (self.port_type == "w"):
|
||||
self.place_we_row(row=row)
|
||||
height = self.w_en_inst.uy()
|
||||
|
|
@ -219,11 +230,11 @@ class control_logic(design.design):
|
|||
""" Create the replica bitline """
|
||||
self.rbl_inst=self.add_inst(name="replica_bitline",
|
||||
mod=self.replica_bitline)
|
||||
self.connect_inst(["rbl_in", "pre_s_en", "vdd", "gnd"])
|
||||
self.connect_inst(["pre_p_en", "pre_s_en", "vdd", "gnd"])
|
||||
|
||||
def place_rbl(self,row):
|
||||
""" Place the replica bitline """
|
||||
y_off = row * self.inv1.height + 2*self.m1_pitch
|
||||
y_off = row * self.nand2.height + 2*self.m1_pitch
|
||||
|
||||
# Add the RBL above the rows
|
||||
# Add to the right of the control rows and routing channel
|
||||
|
|
@ -231,30 +242,38 @@ class control_logic(design.design):
|
|||
self.rbl_inst.place(self.replica_bitline_offset)
|
||||
|
||||
|
||||
def create_clk_row(self):
|
||||
""" Create the multistage clock buffer """
|
||||
def create_clk_rows(self):
|
||||
""" Create the multistage and gated clock buffer """
|
||||
self.clkbuf_inst = self.add_inst(name="clkbuf",
|
||||
mod=self.clkbuf)
|
||||
self.connect_inst(["clk","clk_buf_bar","clk_buf","vdd","gnd"])
|
||||
self.connect_inst(["clk","clk_buf","vdd","gnd"])
|
||||
|
||||
def place_clk_row(self,row):
|
||||
self.gated_clk_inst = self.add_inst(name="gated_clkbuf",
|
||||
mod=self.pbuf1)
|
||||
self.connect_inst(["cs","clk_buf","gated_clk","vdd","gnd"])
|
||||
|
||||
def place_clkbuf_row(self,row):
|
||||
""" Place the multistage clock buffer below the control flops """
|
||||
x_off = self.ctrl_dff_array.width + self.internal_bus_width
|
||||
(y_off,mirror)=self.get_offset(row)
|
||||
clkbuf_offset = vector(x_off,y_off)
|
||||
self.clkbuf_inst.place(clkbuf_offset)
|
||||
offset = vector(x_off,y_off)
|
||||
self.clkbuf_inst.place(offset)
|
||||
self.row_end_inst.append(self.clkbuf_inst)
|
||||
|
||||
def place_gatedclk_row(self,row):
|
||||
""" Place the gated clk logic below the control flops """
|
||||
x_off = self.ctrl_dff_array.width + self.internal_bus_width
|
||||
(y_off,mirror)=self.get_offset(row)
|
||||
offset = vector(x_off,y_off)
|
||||
self.gated_clk_inst.place(offset)
|
||||
self.row_end_inst.append(self.gated_clk_inst)
|
||||
|
||||
|
||||
def create_rbl_in_row(self):
|
||||
self.rbl_in_bar_inst=self.add_inst(name="nand2_rbl_in_bar",
|
||||
mod=self.nand2)
|
||||
self.connect_inst(["clk_buf_bar", "cs", "rbl_in_bar", "vdd", "gnd"])
|
||||
|
||||
# input: rbl_in_bar, output: rbl_in
|
||||
self.rbl_in_inst=self.add_inst(name="inv_rbl_in",
|
||||
mod=self.inv1)
|
||||
self.connect_inst(["rbl_in_bar", "rbl_in", "vdd", "gnd"])
|
||||
# input: gated_clk, we_bar, output: pre_p_en
|
||||
self.pre_p_en_inst=self.add_inst(name="and2_pre_p_en",
|
||||
mod=self.and2)
|
||||
self.connect_inst(["gated_clk", "we_bar", "pre_p_en", "vdd", "gnd"])
|
||||
|
||||
|
||||
def place_rbl_in_row(self,row):
|
||||
|
|
@ -262,28 +281,20 @@ class control_logic(design.design):
|
|||
(y_off,mirror)=self.get_offset(row)
|
||||
|
||||
|
||||
self.rbl_in_bar_offset = vector(x_off, y_off)
|
||||
self.rbl_in_bar_inst.place(offset=self.rbl_in_bar_offset,
|
||||
mirror=mirror)
|
||||
x_off += self.nand2.width
|
||||
self.pre_p_en_offset = vector(x_off, y_off)
|
||||
self.pre_p_en_inst.place(offset=self.pre_p_en_offset,
|
||||
mirror=mirror)
|
||||
x_off += self.and2.width
|
||||
|
||||
self.rbl_in_offset = vector(x_off, y_off)
|
||||
self.rbl_in_inst.place(offset=self.rbl_in_offset,
|
||||
mirror=mirror)
|
||||
self.row_end_inst.append(self.rbl_in_inst)
|
||||
self.row_end_inst.append(self.pre_p_en_inst)
|
||||
|
||||
def create_sen_row(self):
|
||||
""" Create the sense enable buffer. """
|
||||
# input: pre_s_en, output: pre_s_en_bar
|
||||
self.pre_s_en_bar_inst=self.add_inst(name="inv_pre_s_en_bar",
|
||||
mod=self.inv2)
|
||||
self.connect_inst(["pre_s_en", "pre_s_en_bar", "vdd", "gnd"])
|
||||
|
||||
# BUFFER INVERTERS FOR S_EN
|
||||
# input: input: pre_s_en_bar, output: s_en
|
||||
self.s_en_inst=self.add_inst(name="inv_s_en",
|
||||
mod=self.inv8)
|
||||
self.connect_inst(["pre_s_en_bar", "s_en", "vdd", "gnd"])
|
||||
# BUFFER FOR S_EN
|
||||
# input: pre_s_en, output: s_en
|
||||
self.s_en_inst=self.add_inst(name="buf_s_en",
|
||||
mod=self.pbuf8)
|
||||
self.connect_inst(["pre_s_en", "s_en", "vdd", "gnd"])
|
||||
|
||||
def place_sen_row(self,row):
|
||||
"""
|
||||
|
|
@ -293,11 +304,6 @@ class control_logic(design.design):
|
|||
x_off = self.ctrl_dff_array.width + self.internal_bus_width
|
||||
(y_off,mirror)=self.get_offset(row)
|
||||
|
||||
self.pre_s_en_bar_offset = vector(x_off, y_off)
|
||||
self.pre_s_en_bar_inst.place(offset=self.pre_s_en_bar_offset,
|
||||
mirror=mirror)
|
||||
x_off += self.inv2.width
|
||||
|
||||
self.s_en_offset = vector(x_off, y_off)
|
||||
self.s_en_inst.place(offset=self.s_en_offset,
|
||||
mirror=mirror)
|
||||
|
|
@ -341,9 +347,9 @@ class control_logic(design.design):
|
|||
|
||||
def get_offset(self,row):
|
||||
""" Compute the y-offset and mirroring """
|
||||
y_off = row*self.inv1.height
|
||||
y_off = row*self.nand2.height
|
||||
if row % 2:
|
||||
y_off += self.inv1.height
|
||||
y_off += self.nand2.height
|
||||
mirror="MX"
|
||||
else:
|
||||
mirror="R0"
|
||||
|
|
@ -351,60 +357,36 @@ class control_logic(design.design):
|
|||
return (y_off,mirror)
|
||||
|
||||
def create_we_row(self):
|
||||
# input: WE, CS output: w_en_bar
|
||||
# input: we, gated_clk output: pre_w_en
|
||||
if self.port_type == "rw":
|
||||
nand_mod = self.nand3
|
||||
temp = ["clk_buf_bar", "cs", "we", "w_en_bar", "vdd", "gnd"]
|
||||
self.pre_w_en_inst = self.add_inst(name="and_pre_w_en",
|
||||
mod=self.pand2)
|
||||
self.connect_inst(["we", "gated_clk", "pre_w_en", "vdd", "gnd"])
|
||||
input_name = "pre_w_en"
|
||||
else:
|
||||
nand_mod = self.nand2
|
||||
temp = ["clk_buf_bar", "cs", "w_en_bar", "vdd", "gnd"]
|
||||
|
||||
self.w_en_bar_inst = self.add_inst(name="nand3_w_en_bar",
|
||||
mod=nand_mod)
|
||||
self.connect_inst(temp)
|
||||
|
||||
# input: w_en_bar, output: pre_w_en
|
||||
self.pre_w_en_inst = self.add_inst(name="inv_pre_w_en",
|
||||
mod=self.inv1)
|
||||
self.connect_inst(["w_en_bar", "pre_w_en", "vdd", "gnd"])
|
||||
|
||||
# BUFFER INVERTERS FOR W_EN
|
||||
self.pre_w_en_bar_inst = self.add_inst(name="inv_pre_w_en_bar",
|
||||
mod=self.inv2)
|
||||
self.connect_inst(["pre_w_en", "pre_w_en_bar", "vdd", "gnd"])
|
||||
|
||||
self.w_en_inst = self.add_inst(name="inv_w_en2",
|
||||
mod=self.inv8)
|
||||
self.connect_inst(["pre_w_en_bar", "w_en", "vdd", "gnd"])
|
||||
# No we signal is needed for write-only ports
|
||||
input_name = "gated_clk"
|
||||
|
||||
# BUFFER FOR W_EN
|
||||
self.w_en_inst = self.add_inst(name="w_en_buf",
|
||||
mod=self.pbuf8)
|
||||
self.connect_inst([input_name, "w_en", "vdd", "gnd"])
|
||||
|
||||
|
||||
def place_we_row(self,row):
|
||||
x_off = self.ctrl_dff_inst.width + self.internal_bus_width
|
||||
(y_off,mirror)=self.get_offset(row)
|
||||
|
||||
w_en_bar_offset = vector(x_off, y_off)
|
||||
self.w_en_bar_inst.place(offset=w_en_bar_offset,
|
||||
mirror=mirror)
|
||||
if self.port_type == "rw":
|
||||
x_off += self.nand3.width
|
||||
else:
|
||||
pre_w_en_offset = vector(x_off, y_off)
|
||||
self.pre_w_en_inst.place(offset=pre_w_en_offset,
|
||||
mirror=mirror)
|
||||
x_off += self.nand2.width
|
||||
|
||||
pre_w_en_offset = vector(x_off, y_off)
|
||||
self.pre_w_en_inst.place(offset=pre_w_en_offset,
|
||||
mirror=mirror)
|
||||
x_off += self.inv1.width
|
||||
|
||||
pre_w_en_bar_offset = vector(x_off, y_off)
|
||||
self.pre_w_en_bar_inst.place(offset=pre_w_en_bar_offset,
|
||||
mirror=mirror)
|
||||
x_off += self.inv2.width
|
||||
|
||||
w_en_offset = vector(x_off, y_off)
|
||||
w_en_offset = vector(x_off, y_off)
|
||||
self.w_en_inst.place(offset=w_en_offset,
|
||||
mirror=mirror)
|
||||
x_off += self.inv8.width
|
||||
|
||||
|
||||
self.row_end_inst.append(self.w_en_inst)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -17,38 +17,40 @@ class pand2(design.design):
|
|||
|
||||
unique_id = 1
|
||||
|
||||
def __init__(self, driver_size=4, height=bitcell.height, name=""):
|
||||
|
||||
stage_effort = 4
|
||||
# FIXME: Change the number of stages to support high drives.
|
||||
def __init__(self, size=1, height=bitcell.height, name=""):
|
||||
|
||||
self.size = size
|
||||
self.height = height
|
||||
|
||||
if name=="":
|
||||
name = "pand2_{0}_{1}".format(driver_size, pand2.unique_id)
|
||||
name = "pand2_{0}_{1}".format(size, pand2.unique_id)
|
||||
pand2.unique_id += 1
|
||||
|
||||
design.design.__init__(self, name)
|
||||
debug.info(1, "Creating {}".format(self.name))
|
||||
|
||||
|
||||
self.create_netlist()
|
||||
if not OPTS.netlist_only:
|
||||
self.create_layout()
|
||||
|
||||
|
||||
def create_netlist(self):
|
||||
self.add_pins()
|
||||
self.create_modules()
|
||||
self.create_insts()
|
||||
|
||||
def create_modules(self):
|
||||
# Shield the cap, but have at least a stage effort of 4
|
||||
self.nand = pnand2(height=height)
|
||||
self.nand = pnand2(height=self.height)
|
||||
self.add_mod(self.nand)
|
||||
|
||||
self.inv = pinv(size=driver_size, height=height)
|
||||
self.inv = pinv(size=self.size, height=self.height)
|
||||
self.add_mod(self.inv)
|
||||
|
||||
self.width = self.nand.width + self.inv.width
|
||||
self.height = self.inv.height
|
||||
|
||||
self.create_layout()
|
||||
|
||||
#self.offset_all_coordinates()
|
||||
|
||||
self.DRC_LVS()
|
||||
|
||||
def create_layout(self):
|
||||
self.add_pins()
|
||||
self.add_insts()
|
||||
self.width = self.nand.width + self.inv.width
|
||||
self.place_insts()
|
||||
self.add_wires()
|
||||
self.add_layout_pins()
|
||||
|
||||
|
|
@ -59,20 +61,21 @@ class pand2(design.design):
|
|||
self.add_pin("vdd")
|
||||
self.add_pin("gnd")
|
||||
|
||||
def add_insts(self):
|
||||
# Add NAND to the right
|
||||
def create_insts(self):
|
||||
self.nand_inst=self.add_inst(name="pand2_nand",
|
||||
mod=self.nand,
|
||||
offset=vector(0,0))
|
||||
mod=self.nand)
|
||||
self.connect_inst(["A", "B", "zb_int", "vdd", "gnd"])
|
||||
|
||||
self.inv_inst=self.add_inst(name="pand2_inv",
|
||||
mod=self.inv)
|
||||
self.connect_inst(["zb_int", "Z", "vdd", "gnd"])
|
||||
|
||||
def place_insts(self):
|
||||
# Add NAND to the right
|
||||
self.nand_inst.place(offset=vector(0,0))
|
||||
|
||||
# Add INV to the right
|
||||
self.inv_inst=self.add_inst(name="pand2_inv",
|
||||
mod=self.inv,
|
||||
offset=vector(self.nand_inst.rx(),0))
|
||||
self.connect_inst(["zb_int", "Z", "vdd", "gnd"])
|
||||
|
||||
self.inv_inst.place(offset=vector(self.nand_inst.rx(),0))
|
||||
|
||||
def add_wires(self):
|
||||
# nand Z to inv A
|
||||
|
|
|
|||
|
|
@ -16,39 +16,33 @@ class pbuf(design.design):
|
|||
|
||||
unique_id = 1
|
||||
|
||||
def __init__(self, driver_size=4, height=bitcell.height, name=""):
|
||||
def __init__(self, size=4, height=bitcell.height, name=""):
|
||||
|
||||
stage_effort = 4
|
||||
self.stage_effort = 4
|
||||
self.size = size
|
||||
self.width = 0
|
||||
self.height = height
|
||||
# FIXME: Change the number of stages to support high drives.
|
||||
|
||||
if name=="":
|
||||
name = "pbuf_{0}_{1}".format(driver_size, pbuf.unique_id)
|
||||
name = "pbuf_{0}_{1}".format(self.size, pbuf.unique_id)
|
||||
pbuf.unique_id += 1
|
||||
|
||||
design.design.__init__(self, name)
|
||||
debug.info(1, "Creating {}".format(self.name))
|
||||
|
||||
|
||||
# Shield the cap, but have at least a stage effort of 4
|
||||
input_size = max(1,int(driver_size/stage_effort))
|
||||
self.inv1 = pinv(size=input_size, height=height) # 1
|
||||
self.add_mod(self.inv1)
|
||||
|
||||
self.inv2 = pinv(size=driver_size, height=height) # 2
|
||||
self.add_mod(self.inv2)
|
||||
self.create_netlist()
|
||||
if not OPTS.netlist_only:
|
||||
self.create_layout()
|
||||
|
||||
self.width = self.inv1.width + self.inv2.width
|
||||
self.height = self.inv1.height
|
||||
|
||||
self.create_layout()
|
||||
|
||||
#self.offset_all_coordinates()
|
||||
|
||||
self.DRC_LVS()
|
||||
def create_netlist(self):
|
||||
self.add_pins()
|
||||
self.create_modules()
|
||||
self.create_insts()
|
||||
|
||||
def create_layout(self):
|
||||
self.add_pins()
|
||||
self.add_insts()
|
||||
self.width = self.inv1.width + self.inv2.width
|
||||
self.place_insts()
|
||||
self.add_wires()
|
||||
self.add_layout_pins()
|
||||
|
||||
|
|
@ -58,19 +52,31 @@ class pbuf(design.design):
|
|||
self.add_pin("vdd")
|
||||
self.add_pin("gnd")
|
||||
|
||||
def add_insts(self):
|
||||
# Add INV1 to the right
|
||||
def create_modules(self):
|
||||
# Shield the cap, but have at least a stage effort of 4
|
||||
input_size = max(1,int(self.size/self.stage_effort))
|
||||
self.inv1 = pinv(size=input_size, height=self.height)
|
||||
self.add_mod(self.inv1)
|
||||
|
||||
self.inv2 = pinv(size=self.size, height=self.height)
|
||||
self.add_mod(self.inv2)
|
||||
|
||||
def create_insts(self):
|
||||
self.inv1_inst=self.add_inst(name="buf_inv1",
|
||||
mod=self.inv1,
|
||||
offset=vector(0,0))
|
||||
mod=self.inv1)
|
||||
self.connect_inst(["A", "zb_int", "vdd", "gnd"])
|
||||
|
||||
|
||||
# Add INV2 to the right
|
||||
self.inv2_inst=self.add_inst(name="buf_inv2",
|
||||
mod=self.inv2,
|
||||
offset=vector(self.inv1_inst.rx(),0))
|
||||
mod=self.inv2)
|
||||
self.connect_inst(["zb_int", "Z", "vdd", "gnd"])
|
||||
|
||||
def place_insts(self):
|
||||
# Add INV1 to the right
|
||||
self.inv1_inst.place(vector(0,0))
|
||||
|
||||
# Add INV2 to the right
|
||||
self.inv2_inst.place(vector(self.inv1_inst.rx(),0))
|
||||
|
||||
|
||||
def add_wires(self):
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ class pnand2(pgate.pgate):
|
|||
self.create_netlist()
|
||||
if not OPTS.netlist_only:
|
||||
self.create_layout()
|
||||
#self.DRC_LVS()
|
||||
|
||||
|
||||
def create_netlist(self):
|
||||
|
|
|
|||
Loading…
Reference in New Issue