Merge branch 'dev' into analytical_cleanup

This commit is contained in:
Hunter Nichols 2019-08-08 13:20:27 -07:00
commit d273c0eef5
6 changed files with 259 additions and 93 deletions

View File

@ -84,8 +84,6 @@ class bank(design.design):
self.add_pin("dout{0}_{1}".format(port,bit),"OUTPUT") self.add_pin("dout{0}_{1}".format(port,bit),"OUTPUT")
for port in self.read_ports: for port in self.read_ports:
self.add_pin(self.bitcell_array.get_rbl_bl_name(self.port_rbl_map[port]),"OUTPUT") self.add_pin(self.bitcell_array.get_rbl_bl_name(self.port_rbl_map[port]),"OUTPUT")
for port in self.read_ports:
self.add_pin(self.bitcell_array.get_rbl_wl_name(self.port_rbl_map[port]),"INPUT")
for port in self.write_ports: for port in self.write_ports:
for bit in range(self.word_size): for bit in range(self.word_size):
self.add_pin("din{0}_{1}".format(port,bit),"INPUT") self.add_pin("din{0}_{1}".format(port,bit),"INPUT")
@ -306,13 +304,13 @@ class bank(design.design):
self.input_control_signals = [] self.input_control_signals = []
port_num = 0 port_num = 0
for port in range(OPTS.num_rw_ports): for port in range(OPTS.num_rw_ports):
self.input_control_signals.append(["wl_en{}".format(port_num), "w_en{}".format(port_num), "s_en{}".format(port_num), "p_en_bar{}".format(port_num), "rbl_wl{}".format(port_num)]) self.input_control_signals.append(["w_en{}".format(port_num), "s_en{}".format(port_num), "p_en_bar{}".format(port_num), "wl_en{}".format(port_num)])
port_num += 1 port_num += 1
for port in range(OPTS.num_w_ports): for port in range(OPTS.num_w_ports):
self.input_control_signals.append(["wl_en{}".format(port_num), "w_en{}".format(port_num), "p_en_bar{}".format(port_num)]) self.input_control_signals.append(["w_en{}".format(port_num), "p_en_bar{}".format(port_num), "wl_en{}".format(port_num)])
port_num += 1 port_num += 1
for port in range(OPTS.num_r_ports): for port in range(OPTS.num_r_ports):
self.input_control_signals.append(["wl_en{}".format(port_num), "s_en{}".format(port_num), "p_en_bar{}".format(port_num), "rbl_wl{}".format(port_num)]) self.input_control_signals.append(["s_en{}".format(port_num), "p_en_bar{}".format(port_num), "wl_en{}".format(port_num)])
port_num += 1 port_num += 1
# Number of control lines in the bus for each port # Number of control lines in the bus for each port
@ -422,9 +420,9 @@ class bank(design.design):
for row in range(self.num_rows): for row in range(self.num_rows):
for wordline in self.wl_names: for wordline in self.wl_names:
temp.append("{0}_{1}".format(wordline,row)) temp.append("{0}_{1}".format(wordline,row))
for rbl in range(self.num_rbl): for port in self.all_ports:
rbl_wl_name=self.bitcell_array.get_rbl_wl_name(rbl) if self.port_data[port].has_rbl():
temp.append(rbl_wl_name) temp.append("wl_en{0}".format(port))
temp.append("vdd") temp.append("vdd")
temp.append("gnd") temp.append("gnd")
self.connect_inst(temp) self.connect_inst(temp)
@ -947,7 +945,7 @@ class bank(design.design):
if port in self.read_ports: if port in self.read_ports:
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+"rbl_wl{}".format(port), self.bitcell_array_inst.get_pin(rbl_wl_name).lc())) connection.append((self.prefix+"wl_en{}".format(port), self.bitcell_array_inst.get_pin(rbl_wl_name).lc()))
if port in self.write_ports: if port in self.write_ports:
connection.append((self.prefix+"w_en{}".format(port), self.port_data_inst[port].get_pin("w_en").lc())) connection.append((self.prefix+"w_en{}".format(port), self.port_data_inst[port].get_pin("w_en").lc()))
@ -967,10 +965,10 @@ class bank(design.design):
control_signal = self.prefix+"wl_en{}".format(port) control_signal = self.prefix+"wl_en{}".format(port)
if port%2: if port%2:
pin_pos = self.port_address_inst[port].get_pin("wl_en").uc() pin_pos = self.port_address_inst[port].get_pin("wl_en").uc()
mid_pos = pin_pos + vector(0,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
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,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_xoffset[port][control_signal].x
control_pos = vector(control_x_offset, mid_pos.y) control_pos = vector(control_x_offset, mid_pos.y)
self.add_wire(("metal1","via1","metal2"),[pin_pos, mid_pos, control_pos]) self.add_wire(("metal1","via1","metal2"),[pin_pos, mid_pos, control_pos])

View File

@ -101,17 +101,23 @@ class control_logic(design.design):
self.add_mod(self.rbl_driver) self.add_mod(self.rbl_driver)
# clk_buf drives a flop for every address and control bit # clk_buf drives a flop for every address
addr_flops = math.log(self.num_words,2) + math.log(self.words_per_row,2)
# plus data flops and control flops
num_flops = addr_flops + self.word_size + self.num_control_signals
# each flop internally has a FO 5 approximately
# plus about 5 fanouts for the control logic # plus about 5 fanouts for the control logic
# each flop internally has a FO 4 approximately clock_fanout = 5*num_flops + 5
clock_fanout = 4*(math.log(self.num_words,2) + math.log(self.words_per_row,2) \
+ self.num_control_signals) + 5
self.clk_buf_driver = factory.create(module_type="pdriver", self.clk_buf_driver = factory.create(module_type="pdriver",
fanout=clock_fanout, fanout=clock_fanout,
height=dff_height) height=dff_height)
self.add_mod(self.clk_buf_driver) self.add_mod(self.clk_buf_driver)
# We will use the maximum since this same value is used to size the wl_en
# and the p_en_bar drivers
max_fanout = max(self.num_rows,self.num_cols)
# wl_en drives every row in the bank # wl_en drives every row in the bank
self.wl_en_driver = factory.create(module_type="pdriver", self.wl_en_driver = factory.create(module_type="pdriver",
fanout=self.num_rows, fanout=self.num_rows,
@ -132,14 +138,16 @@ class control_logic(design.design):
# used to generate inverted signals with low fanout # used to generate inverted signals with low fanout
self.inv = factory.create(module_type="pinv", self.inv = factory.create(module_type="pinv",
size=1, size=1,
height=dff_height) height=dff_height)
self.add_mod(self.inv) self.add_mod(self.inv)
# p_en_bar drives every column in the bitcell array # p_en_bar drives every column in the bitcell array
# but it is sized the same as the wl_en driver with
# prepended 3 inverter stages to guarantee it is slower and odd polarity
self.p_en_bar_driver = factory.create(module_type="pdriver", self.p_en_bar_driver = factory.create(module_type="pdriver",
neg_polarity=True,
fanout=self.num_cols, fanout=self.num_cols,
neg_polarity=True,
height=dff_height) height=dff_height)
self.add_mod(self.p_en_bar_driver) self.add_mod(self.p_en_bar_driver)
@ -346,9 +354,9 @@ class control_logic(design.design):
# Outputs to the bank # Outputs to the bank
if self.port_type == "rw": if self.port_type == "rw":
self.output_list = ["rbl_wl", "s_en", "w_en"] self.output_list = ["s_en", "w_en"]
elif self.port_type == "r": elif self.port_type == "r":
self.output_list = ["rbl_wl", "s_en"] self.output_list = ["s_en"]
else: else:
self.output_list = ["w_en"] self.output_list = ["w_en"]
self.output_list.append("p_en_bar") self.output_list.append("p_en_bar")
@ -376,7 +384,6 @@ 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_wen_row() self.create_wen_row()
if (self.port_type == "rw") or (self.port_type == "r"): if (self.port_type == "rw") or (self.port_type == "r"):
self.create_rbl_row()
self.create_sen_row() self.create_sen_row()
self.create_delay() self.create_delay()
self.create_pen_row() self.create_pen_row()
@ -410,9 +417,6 @@ class control_logic(design.design):
height = self.w_en_gate_inst.uy() height = self.w_en_gate_inst.uy()
control_center_y = self.w_en_gate_inst.uy() control_center_y = self.w_en_gate_inst.uy()
row += 1 row += 1
if (self.port_type == "rw") or (self.port_type == "r"):
self.place_rbl_row(row)
row += 1
self.place_pen_row(row) self.place_pen_row(row)
row += 1 row += 1
if (self.port_type == "rw") or (self.port_type == "r"): if (self.port_type == "rw") or (self.port_type == "r"):
@ -441,7 +445,6 @@ 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()
self.route_sen() self.route_sen()
self.route_pen() self.route_pen()
self.route_clk_buf() self.route_clk_buf()
@ -596,42 +599,15 @@ 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.rail_offsets)
self.connect_output(self.wl_en_inst, "Z", "wl_en") self.connect_output(self.wl_en_inst, "Z", "wl_en")
def create_rbl_row(self):
self.rbl_inst=self.add_inst(name="rbl_driver",
mod=self.rbl_driver)
# input: gated_clk_bar, output: rbl_wl
self.connect_inst(["gated_clk_bar", "rbl_wl", "vdd", "gnd"])
def place_rbl_row(self,row):
x_off = self.control_x_offset
(y_off,mirror)=self.get_offset(row)
offset = vector(x_off, y_off)
self.rbl_inst.place(offset, mirror)
self.row_end_inst.append(self.rbl_inst)
def route_rbl(self):
""" Connect the logic for the rbl_in generation """
rbl_in_map = zip(["A"], ["gated_clk_bar"])
self.connect_vertical_bus(rbl_in_map, self.rbl_inst, self.rail_offsets)
self.connect_output(self.rbl_inst, "Z", "rbl_wl")
# Input from RBL goes to the delay line for futher delay
self.copy_layout_pin(self.delay_inst, "in", "rbl_bl")
def create_pen_row(self): def create_pen_row(self):
input_name = "gated_clk_buf" # input: gated_clk_bar, output: p_en_bar
# input: pre_p_en, output: p_en_bar
self.p_en_bar_inst=self.add_inst(name="inv_p_en_bar", self.p_en_bar_inst=self.add_inst(name="inv_p_en_bar",
mod=self.p_en_bar_driver) mod=self.p_en_bar_driver)
self.connect_inst([input_name, "p_en_bar", "vdd", "gnd"]) self.connect_inst(["gated_clk_buf", "p_en_bar", "vdd", "gnd"])
def place_pen_row(self,row): def place_pen_row(self,row):
@ -690,6 +666,10 @@ class control_logic(design.design):
self.add_wire(("metal1","via1","metal2"),[out_pos, mid1,in_pos]) self.add_wire(("metal1","via1","metal2"),[out_pos, mid1,in_pos])
self.connect_output(self.s_en_gate_inst, "Z", "s_en") self.connect_output(self.s_en_gate_inst, "Z", "s_en")
# Input from RBL goes to the delay line for futher delay
self.copy_layout_pin(self.delay_inst, "in", "rbl_bl")
def create_wen_row(self): def create_wen_row(self):

138
compiler/pgates/pand3.py Normal file
View File

@ -0,0 +1,138 @@
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2019 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
import debug
from tech import drc
from math import log
from vector import vector
from globals import OPTS
import pgate
from sram_factory import factory
class pand3(pgate.pgate):
"""
This is a simple buffer used for driving loads.
"""
def __init__(self, name, size=1, height=None):
debug.info(1, "Creating pand3 {}".format(name))
self.add_comment("size: {}".format(size))
self.size = size
# Creates the netlist and layout
pgate.pgate.__init__(self, name, height)
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 = factory.create(module_type="pnand3",height=self.height)
self.add_mod(self.nand)
self.inv = factory.create(module_type="pinv", size=self.size, height=self.height)
self.add_mod(self.inv)
def create_layout(self):
self.width = self.nand.width + self.inv.width
self.place_insts()
self.add_wires()
self.add_layout_pins()
self.DRC_LVS()
def add_pins(self):
self.add_pin("A", "INPUT")
self.add_pin("B", "INPUT")
self.add_pin("C", "INPUT")
self.add_pin("Z", "OUTPUT")
self.add_pin("vdd", "POWER")
self.add_pin("gnd", "GROUND")
def create_insts(self):
self.nand_inst=self.add_inst(name="pand3_nand",
mod=self.nand)
self.connect_inst(["A", "B", "C", "zb_int", "vdd", "gnd"])
self.inv_inst=self.add_inst(name="pand3_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.place(offset=vector(self.nand_inst.rx(),0))
def add_wires(self):
# nand Z to inv A
z1_pin = self.nand_inst.get_pin("Z")
a2_pin = self.inv_inst.get_pin("A")
mid1_point = vector(0.5*(z1_pin.cx()+a2_pin.cx()), z1_pin.cy())
mid2_point = vector(mid1_point, a2_pin.cy())
self.add_path("metal1", [z1_pin.center(), mid1_point, mid2_point, a2_pin.center()])
def add_layout_pins(self):
# Continous vdd rail along with label.
vdd_pin=self.inv_inst.get_pin("vdd")
self.add_layout_pin(text="vdd",
layer="metal1",
offset=vdd_pin.ll().scale(0,1),
width=self.width,
height=vdd_pin.height())
# Continous gnd rail along with label.
gnd_pin=self.inv_inst.get_pin("gnd")
self.add_layout_pin(text="gnd",
layer="metal1",
offset=gnd_pin.ll().scale(0,1),
width=self.width,
height=vdd_pin.height())
pin = self.inv_inst.get_pin("Z")
self.add_layout_pin_rect_center(text="Z",
layer=pin.layer,
offset=pin.center(),
width=pin.width(),
height=pin.height())
for pin_name in ["A","B", "C"]:
pin = self.nand_inst.get_pin(pin_name)
self.add_layout_pin_rect_center(text=pin_name,
layer=pin.layer,
offset=pin.center(),
width=pin.width(),
height=pin.height())
def analytical_delay(self, corner, slew, load=0.0):
""" Calculate the analytical delay of DFF-> INV -> INV """
nand_delay = self.nand.analytical_delay(corner, slew=slew, load=self.inv.input_load())
inv_delay = self.inv.analytical_delay(corner, slew=nand_delay.slew, load=load)
return nand_delay + inv_delay
def get_stage_efforts(self, external_cout, inp_is_rise=False):
"""Get the stage efforts of the A or B -> Z path"""
stage_effort_list = []
stage1_cout = self.inv.get_cin()
stage1 = self.nand.get_stage_effort(stage1_cout, inp_is_rise)
stage_effort_list.append(stage1)
last_stage_is_rise = stage1.is_rise
stage2 = self.inv.get_stage_effort(external_cout, last_stage_is_rise)
stage_effort_list.append(stage2)
return stage_effort_list
def get_cin(self):
"""Return the relative input capacitance of a single input"""
return self.nand.get_cin()

View File

@ -5,12 +5,13 @@
# (acting for and on behalf of Oklahoma State University) # (acting for and on behalf of Oklahoma State University)
# All rights reserved. # All rights reserved.
# #
import contact
import pgate import pgate
import debug import debug
from tech import drc, parameter, spice from tech import drc, parameter, spice
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
import contact import logical_effort
from sram_factory import factory from sram_factory import factory
class pnor2(pgate.pgate): class pnor2(pgate.pgate):
@ -38,28 +39,30 @@ class pnor2(pgate.pgate):
pgate.pgate.__init__(self, name, height) pgate.pgate.__init__(self, name, height)
def add_pins(self):
""" Adds pins for spice netlist """
pin_list = ["A", "B", "Z", "vdd", "gnd"]
dir_list = ["INPUT", "INPUT", "OUTPUT", "INOUT", "INOUT"]
self.add_pin_list(pin_list, dir_list)
def create_netlist(self): def create_netlist(self):
self.add_pins() self.add_pins()
self.add_ptx()
self.create_ptx() self.create_ptx()
self.setup_layout_constants()
def create_layout(self): def create_layout(self):
""" Calls all functions related to the generation of the layout """ """ Calls all functions related to the generation of the layout """
self.add_supply_rails()
self.add_ptx() self.setup_layout_constants()
self.route_supply_rails()
self.place_ptx()
self.connect_rails() self.connect_rails()
self.add_well_contacts() self.add_well_contacts()
self.extend_wells(self.well_pos) self.extend_wells(self.well_pos)
self.route_inputs() self.route_inputs()
self.route_output() self.route_output()
def create_ptx(self): def add_pins(self):
""" Adds pins for spice netlist """
pin_list = ["A", "B", "Z", "vdd", "gnd"]
dir_list = ["INPUT", "INPUT", "OUTPUT", "INOUT", "INOUT"]
self.add_pin_list(pin_list, dir_list)
def add_ptx(self):
""" Create the PMOS and NMOS transistors. """ """ Create the PMOS and NMOS transistors. """
self.nmos = factory.create(module_type="ptx", self.nmos = factory.create(module_type="ptx",
width=self.nmos_width, width=self.nmos_width,
@ -104,7 +107,7 @@ class pnor2(pgate.pgate):
self.top_bottom_space = max(0.5*self.m1_width + self.m1_space + extra_contact_space, self.top_bottom_space = max(0.5*self.m1_width + self.m1_space + extra_contact_space,
drc("poly_extend_active"), self.poly_space) drc("poly_extend_active"), self.poly_space)
def add_supply_rails(self): def route_supply_rails(self):
""" Add vdd/gnd rails to the top and bottom. """ """ Add vdd/gnd rails to the top and bottom. """
self.add_layout_pin_rect_center(text="gnd", self.add_layout_pin_rect_center(text="gnd",
layer="metal1", layer="metal1",
@ -116,7 +119,31 @@ class pnor2(pgate.pgate):
offset=vector(0.5*self.width,self.height), offset=vector(0.5*self.width,self.height),
width=self.width) width=self.width)
def add_ptx(self): def create_ptx(self):
"""
Add PMOS and NMOS to the layout at the upper-most and lowest position
to provide maximum routing in channel
"""
self.pmos1_inst=self.add_inst(name="pnor2_pmos1",
mod=self.pmos)
self.connect_inst(["vdd", "A", "net1", "vdd"])
self.pmos2_inst = self.add_inst(name="pnor2_pmos2",
mod=self.pmos)
self.connect_inst(["net1", "B", "Z", "vdd"])
self.nmos1_inst=self.add_inst(name="pnor2_nmos1",
mod=self.nmos)
self.connect_inst(["Z", "A", "gnd", "gnd"])
self.nmos2_inst=self.add_inst(name="pnor2_nmos2",
mod=self.nmos)
self.connect_inst(["Z", "B", "gnd", "gnd"])
def place_ptx(self):
""" """
Add PMOS and NMOS to the layout at the upper-most and lowest position Add PMOS and NMOS to the layout at the upper-most and lowest position
to provide maximum routing in channel to provide maximum routing in channel
@ -124,29 +151,16 @@ class pnor2(pgate.pgate):
pmos1_pos = vector(self.pmos.active_offset.x, pmos1_pos = vector(self.pmos.active_offset.x,
self.height - self.pmos.active_height - self.top_bottom_space) self.height - self.pmos.active_height - self.top_bottom_space)
self.pmos1_inst=self.add_inst(name="pnor2_pmos1", self.pmos1_inst.place(pmos1_pos)
mod=self.pmos,
offset=pmos1_pos)
self.connect_inst(["vdd", "A", "net1", "vdd"])
self.pmos2_pos = pmos1_pos + self.overlap_offset self.pmos2_pos = pmos1_pos + self.overlap_offset
self.pmos2_inst = self.add_inst(name="pnor2_pmos2", self.pmos2_inst.place(self.pmos2_pos)
mod=self.pmos,
offset=self.pmos2_pos)
self.connect_inst(["net1", "B", "Z", "vdd"])
nmos1_pos = vector(self.pmos.active_offset.x, self.top_bottom_space) nmos1_pos = vector(self.pmos.active_offset.x, self.top_bottom_space)
self.nmos1_inst=self.add_inst(name="pnor2_nmos1", self.nmos1_inst.place(nmos1_pos)
mod=self.nmos,
offset=nmos1_pos)
self.connect_inst(["Z", "A", "gnd", "gnd"])
self.nmos2_pos = nmos1_pos + self.overlap_offset self.nmos2_pos = nmos1_pos + self.overlap_offset
self.nmos2_inst=self.add_inst(name="pnor2_nmos2", self.nmos2_inst.place(self.nmos2_pos)
mod=self.nmos,
offset=self.nmos2_pos)
self.connect_inst(["Z", "B", "gnd", "gnd"])
# Output position will be in between the PMOS and NMOS # Output position will be in between the PMOS and NMOS
self.output_pos = vector(0,0.5*(pmos1_pos.y+nmos1_pos.y+self.nmos.active_height)) self.output_pos = vector(0,0.5*(pmos1_pos.y+nmos1_pos.y+self.nmos.active_height))

View File

@ -341,8 +341,6 @@ class sram_base(design, verilog, lef):
temp.append("DOUT{0}[{1}]".format(port,bit)) temp.append("DOUT{0}[{1}]".format(port,bit))
for port in self.read_ports: for port in self.read_ports:
temp.append("rbl_bl{0}".format(port)) temp.append("rbl_bl{0}".format(port))
for port in self.read_ports:
temp.append("rbl_wl{0}".format(port))
for port in self.write_ports: for port in self.write_ports:
for bit in range(self.word_size): for bit in range(self.word_size):
temp.append("BANK_DIN{0}[{1}]".format(port,bit)) temp.append("BANK_DIN{0}[{1}]".format(port,bit))
@ -506,9 +504,6 @@ class sram_base(design, verilog, lef):
temp.append("rbl_bl{}".format(port)) temp.append("rbl_bl{}".format(port))
# Ouputs # Ouputs
if port in self.read_ports:
temp.append("rbl_wl{}".format(port))
if port in self.read_ports: if port in self.read_ports:
temp.append("s_en{}".format(port)) temp.append("s_en{}".format(port))
if port in self.write_ports: if port in self.write_ports:
@ -530,7 +525,10 @@ class sram_base(design, verilog, lef):
in_pos = src_pin.rc() in_pos = src_pin.rc()
else: else:
in_pos = src_pin.lc() in_pos = src_pin.lc()
out_pos = dest_pin.center() if src_pin.cy() < dest_pin.cy():
out_pos = dest_pin.bc()
else:
out_pos = dest_pin.uc()
# move horizontal first # move horizontal first
self.add_wire(("metal3","via2","metal2"),[in_pos, vector(out_pos.x,in_pos.y),out_pos]) self.add_wire(("metal3","via2","metal2"),[in_pos, vector(out_pos.x,in_pos.y),out_pos])

38
compiler/tests/04_pand3_test.py Executable file
View File

@ -0,0 +1,38 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2019 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
import unittest
from testutils import *
import sys,os
sys.path.append(os.getenv("OPENRAM_HOME"))
import globals
from globals import OPTS
from sram_factory import factory
import debug
class pand3_test(openram_test):
def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name))
global verify
import verify
import pand3
debug.info(2, "Testing pand3 gate 4x")
a = pand3.pand3(name="pand3x4", size=4)
self.local_check(a)
globals.end_openram()
# instantiate a copdsay of the class to actually run the test
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())