Add sketch for power grid routing code

This commit is contained in:
Matt Guthaus 2018-08-21 09:28:07 -07:00
parent 718897e123
commit ea52af3747
94 changed files with 1326 additions and 197 deletions

View File

@ -275,7 +275,7 @@ def setup_paths():
# Add all of the subdirs to the python path # Add all of the subdirs to the python path
# These subdirs are modules and don't need to be added: characterizer, verify # These subdirs are modules and don't need to be added: characterizer, verify
for subdir in ["gdsMill", "tests", "router", "modules", "base", "pgates"]: for subdir in ["gdsMill", "tests", "modules", "base", "pgates"]:
full_path = "{0}/{1}".format(OPENRAM_HOME,subdir) full_path = "{0}/{1}".format(OPENRAM_HOME,subdir)
debug.check(os.path.isdir(full_path), debug.check(os.path.isdir(full_path),
"$OPENRAM_HOME/{0} does not exist: {1}".format(subdir,full_path)) "$OPENRAM_HOME/{0} does not exist: {1}".format(subdir,full_path))

View File

@ -1,3 +0,0 @@
#!/bin/bash
python tests/regress.py -t freepdk45
python tests/regress.py -t scn3me_subm

View File

@ -1,43 +0,0 @@
def isclose(value1,value2,error_tolerance=1e-2):
""" This is used to compare relative values. """
import debug
relative_diff = abs(value1 - value2) / max(value1,value2)
check = relative_diff <= error_tolerance
if not check:
debug.info(1,"NOT CLOSE {0} {1} relative diff={2}".format(value1,value2,relative_diff))
else:
debug.info(2,"CLOSE {0} {1} relative diff={2}".format(value1,value2,relative_diff))
return (check)
def isdiff(file1,file2):
""" This is used to compare two files and display the diff if they are different.. """
import debug
import filecmp
import difflib
check = filecmp.cmp(file1,file2)
if not check:
debug.info(2,"MISMATCH {0} {1}".format(file1,file2))
f1 = open(file1,"r")
s1 = f1.readlines()
f2 = open(file2,"r")
s2 = f2.readlines()
for line in difflib.unified_diff(s1, s2):
debug.error(line)
else:
debug.info(2,"MATCH {0} {1}".format(file1,file2))
return (check)
def header(filename, technology):
tst = "Running Test for:"
print "\n"
print " ______________________________________________________________________________ "
print "|==============================================================================|"
print "|=========" + tst.center(60) + "=========|"
print "|=========" + technology.center(60) + "=========|"
print "|=========" + filename.center(60) + "=========|"
import globals
OPTS = globals.get_opts()
print "|=========" + OPTS.openram_temp.center(60) + "=========|"
print "|==============================================================================|"

View File

@ -4,6 +4,7 @@ import debug
from math import log,sqrt,ceil from math import log,sqrt,ceil
import datetime import datetime
import getpass import getpass
import numpy as np
from vector import vector from vector import vector
from globals import OPTS, print_time from globals import OPTS, print_time
@ -175,7 +176,6 @@ class sram_1bank(sram_base):
# the control logic to the bank # the control logic to the bank
self.add_wire(("metal3","via2","metal2"),[row_addr_clk_pos, mid1_pos, mid2_pos, control_clk_buf_pos]) self.add_wire(("metal3","via2","metal2"),[row_addr_clk_pos, mid1_pos, mid2_pos, control_clk_buf_pos])
def route_vdd_gnd(self): def route_vdd_gnd(self):
""" Propagate all vdd/gnd pins up to this level for all modules """ """ Propagate all vdd/gnd pins up to this level for all modules """
@ -192,6 +192,84 @@ class sram_1bank(sram_base):
self.copy_layout_pin(inst, "vdd") self.copy_layout_pin(inst, "vdd")
self.copy_layout_pin(inst, "gnd") self.copy_layout_pin(inst, "gnd")
def new_route_vdd_gnd(self):
""" Propagate all vdd/gnd pins up to this level for all modules """
# These are the instances that every bank has
top_instances = [self.bank_inst,
self.row_addr_dff_inst,
self.data_dff_inst,
self.control_logic_inst]
if self.col_addr_dff:
top_instances.append(self.col_addr_dff_inst)
# for inst in top_instances:
# self.copy_layout_pin(inst, "vdd")
# self.copy_layout_pin(inst, "gnd")
blockages=self.get_blockages("metal3", top_level=True)
# Gather all of the vdd/gnd pins
vdd_pins=[]
gnd_pins=[]
for inst in top_instances:
vdd_pins.extend([x for x in inst.get_pins("vdd") if x.layer == "metal3"])
gnd_pins.extend([x for x in inst.get_pins("gnd") if x.layer == "metal3"])
# Create candidate stripes on M3/M4
lowest=self.find_lowest_coords()
highest=self.find_highest_coords()
m3_y_coords = np.arange(lowest[1],highest[1],self.m2_pitch)
# These are the rails that will be available for vdd/gnd
m3_rects = []
# These are the "inflated" shapes for DRC checks
m3_drc_rects = []
for y in m3_y_coords:
# This is just what metal will be drawn
ll = vector(lowest[0], y - 0.5*self.m3_width)
ur = vector(highest[0], y + 0.5*self.m3_width)
m3_rects.append([ll, ur])
# This is a full m3 pitch for DRC conflict checking
ll = vector(lowest[0], y - 0.5*self.m3_pitch )
ur = vector(highest[0], y + 0.5*self.m3_pitch)
m3_drc_rects.append([ll, ur])
vdd_rects = []
gnd_rects = []
# Now, figure how if the rails intersect a blockage, vdd, or gnd pin
# Divide the rails up alternately
# This should be done in less than n^2 using a kd-tree or something
# for drc_rect,rect in zip(m3_drc_rects,m3_rects):
# for b in blockages:
# if rect_overlaps(b,drc_rect):
# break
# else:
# gnd_rects.append(rect)
# Create the vdd and gnd rails
for rect in m3_rects:
(ll,ur) = rect
for rect in gnd_rects:
(ll,ur) = rect
self.add_layout_pin(text="gnd",
layer="metal3",
offset=ll,
width=ur.x-ll.x,
height=ur.y-ll.y)
for rect in vdd_rects:
(ll,ur) = rect
self.add_layout_pin(text="vdd",
layer="metal3",
offset=ll,
width=ur.x-ll.x,
height=ur.y-ll.y)
def route_control_logic(self): def route_control_logic(self):
""" Route the outputs from the control logic module """ """ Route the outputs from the control logic module """
for n in self.control_logic_outputs: for n in self.control_logic_outputs:

View File

@ -13,9 +13,6 @@ class contact_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import contact import contact

View File

@ -13,9 +13,6 @@ class path_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import path import path
import tech import tech
import design import design

View File

@ -13,9 +13,6 @@ class ptx_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import ptx import ptx
import tech import tech

View File

@ -13,9 +13,6 @@ class ptx_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import ptx import ptx
import tech import tech

View File

@ -13,9 +13,6 @@ class ptx_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import ptx import ptx
import tech import tech

View File

@ -13,9 +13,6 @@ class ptx_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import ptx import ptx
import tech import tech

View File

@ -13,9 +13,6 @@ class ptx_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import ptx import ptx
import tech import tech

View File

@ -13,9 +13,6 @@ class ptx_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import ptx import ptx
import tech import tech

View File

@ -13,9 +13,6 @@ class wire_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import wire import wire
import tech import tech
import design import design

View File

@ -20,9 +20,6 @@ class pbitcell_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import pbitcell import pbitcell
import tech import tech

View File

@ -15,9 +15,6 @@ class pinv_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import pinv import pinv
import tech import tech

View File

@ -15,9 +15,6 @@ class pinv_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import pinv import pinv
import tech import tech

View File

@ -14,10 +14,6 @@ class pinv_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import pinv import pinv
import tech import tech

View File

@ -15,9 +15,6 @@ class pinv_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import pinv import pinv
import tech import tech

View File

@ -15,9 +15,6 @@ class pinvbuf_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import pinvbuf import pinvbuf
debug.info(2, "Testing inverter/buffer 4x 8x") debug.info(2, "Testing inverter/buffer 4x 8x")

View File

@ -17,9 +17,6 @@ class pnand2_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import pnand2 import pnand2
import tech import tech

View File

@ -17,9 +17,6 @@ class pnand3_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import pnand3 import pnand3
import tech import tech

View File

@ -17,9 +17,6 @@ class pnor2_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import pnor2 import pnor2
import tech import tech

View File

@ -15,9 +15,6 @@ class precharge_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import precharge import precharge
import tech import tech

View File

@ -17,9 +17,6 @@ class single_level_column_mux_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import single_level_column_mux import single_level_column_mux
import tech import tech

View File

@ -17,9 +17,6 @@ class array_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import bitcell_array import bitcell_array
debug.info(2, "Testing 4x4 array for 6t_cell") debug.info(2, "Testing 4x4 array for 6t_cell")

View File

@ -16,9 +16,6 @@ class pbitcell_array_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import bitcell_array import bitcell_array
debug.info(2, "Testing 4x4 array for multiport bitcell, with read ports at the edge of the bit cell") debug.info(2, "Testing 4x4 array for multiport bitcell, with read ports at the edge of the bit cell")

View File

@ -15,9 +15,6 @@ class hierarchical_decoder_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import hierarchical_decoder import hierarchical_decoder
import tech import tech

View File

@ -15,9 +15,6 @@ class hierarchical_predecode2x4_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import hierarchical_predecode2x4 as pre import hierarchical_predecode2x4 as pre
import tech import tech

View File

@ -15,9 +15,6 @@ class hierarchical_predecode3x8_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import hierarchical_predecode3x8 as pre import hierarchical_predecode3x8 as pre
import tech import tech

View File

@ -14,9 +14,6 @@ class single_level_column_mux_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import single_level_column_mux_array import single_level_column_mux_array
debug.info(1, "Testing sample for 2-way column_mux_array") debug.info(1, "Testing sample for 2-way column_mux_array")

View File

@ -15,9 +15,6 @@ class precharge_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import precharge_array import precharge_array
import tech import tech

View File

@ -17,9 +17,6 @@ class wordline_driver_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import wordline_driver import wordline_driver
import tech import tech

View File

@ -15,9 +15,6 @@ class sense_amp_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import sense_amp_array import sense_amp_array

View File

@ -15,9 +15,6 @@ class write_driver_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import write_driver_array import write_driver_array
debug.info(2, "Testing write_driver_array for columns=8, word_size=8") debug.info(2, "Testing write_driver_array for columns=8, word_size=8")

View File

@ -15,9 +15,6 @@ class dff_array_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import dff_array import dff_array
debug.info(2, "Testing dff_array for 3x3") debug.info(2, "Testing dff_array for 3x3")

View File

@ -15,9 +15,6 @@ class dff_buf_array_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import dff_buf_array import dff_buf_array
debug.info(2, "Testing dff_buf_array for 3x3") debug.info(2, "Testing dff_buf_array for 3x3")

View File

@ -15,9 +15,6 @@ class dff_buf_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import dff_buf import dff_buf
debug.info(2, "Testing dff_buf 4x 8x") debug.info(2, "Testing dff_buf 4x 8x")

View File

@ -15,9 +15,6 @@ class dff_inv_array_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import dff_inv_array import dff_inv_array
debug.info(2, "Testing dff_inv_array for 3x3") debug.info(2, "Testing dff_inv_array for 3x3")

View File

@ -15,9 +15,6 @@ class dff_inv_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import dff_inv import dff_inv
debug.info(2, "Testing dff_inv 4x") debug.info(2, "Testing dff_inv 4x")

View File

@ -15,9 +15,6 @@ class dff_array_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import ms_flop_array import ms_flop_array
debug.info(2, "Testing ms_flop_array for columns=8, word_size=8") debug.info(2, "Testing ms_flop_array for columns=8, word_size=8")

View File

@ -15,9 +15,6 @@ class tri_gate_array_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import tri_gate_array import tri_gate_array
debug.info(1, "Testing tri_gate_array for columns=8, word_size=8") debug.info(1, "Testing tri_gate_array for columns=8, word_size=8")

View File

@ -15,9 +15,6 @@ class delay_chain_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import delay_chain import delay_chain
debug.info(2, "Testing delay_chain") debug.info(2, "Testing delay_chain")

View File

@ -15,9 +15,6 @@ class replica_bitline_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import replica_bitline import replica_bitline
stages=4 stages=4

View File

@ -15,9 +15,6 @@ class control_logic_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import control_logic import control_logic
import tech import tech

View File

@ -15,9 +15,6 @@ class bank_select_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
import bank_select import bank_select
debug.info(1, "No column mux") debug.info(1, "No column mux")

View File

@ -15,9 +15,6 @@ class multi_bank_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
from bank import bank from bank import bank
debug.info(1, "No column mux") debug.info(1, "No column mux")

View File

@ -15,9 +15,6 @@ class single_bank_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
from bank import bank from bank import bank
debug.info(1, "No column mux") debug.info(1, "No column mux")

View File

@ -15,9 +15,6 @@ class sram_1bank_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
from sram import sram from sram import sram
debug.info(1, "Single bank, no column mux with control logic") debug.info(1, "Single bank, no column mux with control logic")

View File

@ -16,9 +16,6 @@ class sram_2bank_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
from sram import sram from sram import sram
debug.info(1, "Two bank, no column mux with control logic") debug.info(1, "Two bank, no column mux with control logic")

View File

@ -16,9 +16,6 @@ class sram_4bank_test(openram_test):
def runTest(self): def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name)) globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
from sram import sram from sram import sram
debug.info(1, "Four bank, no column mux with control logic") debug.info(1, "Four bank, no column mux with control logic")

View File

@ -27,9 +27,6 @@ class sram_func_test(openram_test):
if not OPTS.spice_exe: if not OPTS.spice_exe:
debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1) debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1)
global verify
import verify
self.func_test(bank_num=1) self.func_test(bank_num=1)
self.func_test(bank_num=2) self.func_test(bank_num=2)
self.func_test(bank_num=4) self.func_test(bank_num=4)

View File

@ -0,0 +1,4 @@
BSIM3v3.3.0 Parameter Checking.
Model = p
Warning: Pd = 0 is less than W.
Warning: Ps = 0 is less than W.

Binary file not shown.

0
compiler/tests/out.log Normal file
View File

BIN
compiler/tests/sram1.gds Normal file

Binary file not shown.

19
compiler/tests/sram1.lef Normal file
View File

@ -0,0 +1,19 @@
VERSION 5.4 ;
NAMESCASESENSITIVE ON ;
BUSBITCHARS "[]" ;
DIVIDERCHAR "/" ;
UNITS
DATABASE MICRONS 1000 ;
END UNITS
SITE MacroSite
CLASS Core ;
SIZE 324000.0 by 421500.0 ;
END MacroSite
MACRO sram1
CLASS BLOCK ;
SIZE 324000.0 BY 421500.0 ;
SYMMETRY X Y R90 ;
SITE MacroSite ;
PIN DIN[0]
DIRECTION INPUT ;
PORT

602
compiler/tests/sram1.sp vendored Normal file
View File

@ -0,0 +1,602 @@
**************************************************
* OpenRAM generated memory.
* Words: 16
* Data bits: 4
* Banks: 1
* Column mux: 1:1
**************************************************
* Positive edge-triggered FF
.subckt dff D Q clk vdd gnd
M0 vdd clk a_2_6# vdd p w=12u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M1 a_17_74# D vdd vdd p w=6u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M2 a_22_6# clk a_17_74# vdd p w=6u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M3 a_31_74# a_2_6# a_22_6# vdd p w=6u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M4 vdd a_34_4# a_31_74# vdd p w=6u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M5 a_34_4# a_22_6# vdd vdd p w=6u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M6 a_61_74# a_34_4# vdd vdd p w=6u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M7 a_66_6# a_2_6# a_61_74# vdd p w=6u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M8 a_76_84# clk a_66_6# vdd p w=3u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M9 vdd Q a_76_84# vdd p w=3u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M10 gnd clk a_2_6# gnd n w=6u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M11 Q a_66_6# vdd vdd p w=12u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M12 a_17_6# D gnd gnd n w=3u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M13 a_22_6# a_2_6# a_17_6# gnd n w=3u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M14 a_31_6# clk a_22_6# gnd n w=3u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M15 gnd a_34_4# a_31_6# gnd n w=3u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M16 a_34_4# a_22_6# gnd gnd n w=3u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M17 a_61_6# a_34_4# gnd gnd n w=3u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M18 a_66_6# clk a_61_6# gnd n w=3u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M19 a_76_6# a_2_6# a_66_6# gnd n w=3u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M20 gnd Q a_76_6# gnd n w=3u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
M21 Q a_66_6# gnd gnd n w=6u l=0.6u
+ ad=0p pd=0u as=0p ps=0u
.ends dff
* ptx M{0} {1} n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
* ptx M{0} {1} p m=1 w=4.8u l=0.6u pd=10.799999999999999u ps=10.799999999999999u as=7.199999999999999p ad=7.199999999999999p
.SUBCKT pinv_2 A Z vdd gnd
Mpinv_pmos Z A vdd vdd p m=1 w=4.8u l=0.6u pd=10.799999999999999u ps=10.799999999999999u as=7.199999999999999p ad=7.199999999999999p
Mpinv_nmos Z A gnd gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
.ENDS pinv_2
.SUBCKT dff_inv_2 D Q Qb clk vdd gnd
Xdff_inv_dff D Q clk vdd gnd dff
Xdff_inv_inv1 Q Qb vdd gnd pinv_2
.ENDS dff_inv_2
.SUBCKT dff_array_3x1 din[0] din[1] din[2] dout[0] dout_bar[0] dout[1] dout_bar[1] dout[2] dout_bar[2] clk vdd gnd
XXdff_r0_c0 din[0] dout[0] dout_bar[0] clk vdd gnd dff_inv_2
XXdff_r1_c0 din[1] dout[1] dout_bar[1] clk vdd gnd dff_inv_2
XXdff_r2_c0 din[2] dout[2] dout_bar[2] clk vdd gnd dff_inv_2
.ENDS dff_array_3x1
* ptx M{0} {1} p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
.SUBCKT pnand2_1 A B Z vdd gnd
Mpnand2_pmos1 vdd A Z vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand2_pmos2 Z B vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand2_nmos1 Z B net1 gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand2_nmos2 net1 A gnd gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
.ENDS pnand2_1
.SUBCKT pnand3_1 A B C Z vdd gnd
Mpnand3_pmos1 vdd A Z vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand3_pmos2 Z B vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand3_pmos3 Z C vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand3_nmos1 Z C net1 gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand3_nmos2 net1 B net2 gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand3_nmos3 net2 A gnd gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
.ENDS pnand3_1
* ptx M{0} {1} n m=1 w=1.2u l=0.6u pd=3.5999999999999996u ps=3.5999999999999996u as=1.7999999999999998p ad=1.7999999999999998p
.SUBCKT pinv_3 A Z vdd gnd
Mpinv_pmos Z A vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpinv_nmos Z A gnd gnd n m=1 w=1.2u l=0.6u pd=3.5999999999999996u ps=3.5999999999999996u as=1.7999999999999998p ad=1.7999999999999998p
.ENDS pinv_3
* ptx M{0} {1} n m=1 w=4.8u l=0.6u pd=10.799999999999999u ps=10.799999999999999u as=7.199999999999999p ad=7.199999999999999p
* ptx M{0} {1} p m=1 w=9.6u l=0.6u pd=20.4u ps=20.4u as=14.399999999999999p ad=14.399999999999999p
.SUBCKT pinv_4 A Z vdd gnd
Mpinv_pmos Z A vdd vdd p m=1 w=9.6u l=0.6u pd=20.4u ps=20.4u as=14.399999999999999p ad=14.399999999999999p
Mpinv_nmos Z A gnd gnd n m=1 w=4.8u l=0.6u pd=10.799999999999999u ps=10.799999999999999u as=7.199999999999999p ad=7.199999999999999p
.ENDS pinv_4
* ptx M{0} {1} n m=4 w=4.8u l=0.6u pd=10.799999999999999u ps=10.799999999999999u as=7.199999999999999p ad=7.199999999999999p
* ptx M{0} {1} p m=4 w=9.6u l=0.6u pd=20.4u ps=20.4u as=14.399999999999999p ad=14.399999999999999p
.SUBCKT pinv_5 A Z vdd gnd
Mpinv_pmos Z A vdd vdd p m=4 w=9.6u l=0.6u pd=20.4u ps=20.4u as=14.399999999999999p ad=14.399999999999999p
Mpinv_nmos Z A gnd gnd n m=4 w=4.8u l=0.6u pd=10.799999999999999u ps=10.799999999999999u as=7.199999999999999p ad=7.199999999999999p
.ENDS pinv_5
.SUBCKT pinvbuf_4_16 A Zb Z vdd gnd
Xbuf_inv1 A zb_int vdd gnd pinv_3
Xbuf_inv2 zb_int z_int vdd gnd pinv_4
Xbuf_inv3 z_int Zb vdd gnd pinv_5
Xbuf_inv4 zb_int Z vdd gnd pinv_5
.ENDS pinvbuf_4_16
.SUBCKT pinv_6 A Z vdd gnd
Mpinv_pmos Z A vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpinv_nmos Z A gnd gnd n m=1 w=1.2u l=0.6u pd=3.5999999999999996u ps=3.5999999999999996u as=1.7999999999999998p ad=1.7999999999999998p
.ENDS pinv_6
.SUBCKT pinv_7 A Z vdd gnd
Mpinv_pmos Z A vdd vdd p m=1 w=9.6u l=0.6u pd=20.4u ps=20.4u as=14.399999999999999p ad=14.399999999999999p
Mpinv_nmos Z A gnd gnd n m=1 w=4.8u l=0.6u pd=10.799999999999999u ps=10.799999999999999u as=7.199999999999999p ad=7.199999999999999p
.ENDS pinv_7
.SUBCKT pinv_8 A Z vdd gnd
Mpinv_pmos Z A vdd vdd p m=4 w=9.6u l=0.6u pd=20.4u ps=20.4u as=14.399999999999999p ad=14.399999999999999p
Mpinv_nmos Z A gnd gnd n m=4 w=4.8u l=0.6u pd=10.799999999999999u ps=10.799999999999999u as=7.199999999999999p ad=7.199999999999999p
.ENDS pinv_8
*********************** "cell_6t" ******************************
.SUBCKT replica_cell_6t bl br wl vdd gnd
M_1 gnd net_2 vdd vdd p W='0.9u' L=1.2u
M_2 net_2 gnd vdd vdd p W='0.9u' L=1.2u
M_3 br wl net_2 gnd n W='1.2u' L=0.6u
M_4 bl wl gnd gnd n W='1.2u' L=0.6u
M_5 net_2 gnd gnd gnd n W='2.4u' L=0.6u
M_6 gnd net_2 gnd gnd n W='2.4u' L=0.6u
.ENDS $ replica_cell_6t
*********************** "cell_6t" ******************************
.SUBCKT cell_6t bl br wl vdd gnd
M_1 net_1 net_2 vdd vdd p W='0.9u' L=1.2u
M_2 net_2 net_1 vdd vdd p W='0.9u' L=1.2u
M_3 br wl net_2 gnd n W='1.2u' L=0.6u
M_4 bl wl net_1 gnd n W='1.2u' L=0.6u
M_5 net_2 net_1 gnd gnd n W='2.4u' L=0.6u
M_6 net_1 net_2 gnd gnd n W='2.4u' L=0.6u
.ENDS $ cell_6t
.SUBCKT bitline_load bl[0] br[0] wl[0] wl[1] wl[2] wl[3] vdd gnd
Xbit_r0_c0 bl[0] br[0] wl[0] vdd gnd cell_6t
Xbit_r1_c0 bl[0] br[0] wl[1] vdd gnd cell_6t
Xbit_r2_c0 bl[0] br[0] wl[2] vdd gnd cell_6t
Xbit_r3_c0 bl[0] br[0] wl[3] vdd gnd cell_6t
.ENDS bitline_load
.SUBCKT pinv_9 A Z vdd gnd
Mpinv_pmos Z A vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpinv_nmos Z A gnd gnd n m=1 w=1.2u l=0.6u pd=3.5999999999999996u ps=3.5999999999999996u as=1.7999999999999998p ad=1.7999999999999998p
.ENDS pinv_9
.SUBCKT delay_chain in out vdd gnd
Xdinv0 in dout_1 vdd gnd pinv_9
Xdload_0_0 dout_1 n_0_0 vdd gnd pinv_9
Xdload_0_1 dout_1 n_0_1 vdd gnd pinv_9
Xdload_0_2 dout_1 n_0_2 vdd gnd pinv_9
Xdinv1 dout_1 dout_2 vdd gnd pinv_9
Xdload_1_0 dout_2 n_1_0 vdd gnd pinv_9
Xdload_1_1 dout_2 n_1_1 vdd gnd pinv_9
Xdload_1_2 dout_2 n_1_2 vdd gnd pinv_9
Xdinv2 dout_2 out vdd gnd pinv_9
Xdload_2_0 out n_2_0 vdd gnd pinv_9
Xdload_2_1 out n_2_1 vdd gnd pinv_9
Xdload_2_2 out n_2_2 vdd gnd pinv_9
.ENDS delay_chain
.SUBCKT pinv_10 A Z vdd gnd
Mpinv_pmos Z A vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpinv_nmos Z A gnd gnd n m=1 w=1.2u l=0.6u pd=3.5999999999999996u ps=3.5999999999999996u as=1.7999999999999998p ad=1.7999999999999998p
.ENDS pinv_10
* ptx M{0} {1} p m=1 w=1.2u l=0.6u pd=3.5999999999999996u ps=3.5999999999999996u as=1.7999999999999998p ad=1.7999999999999998p
.SUBCKT replica_bitline en out vdd gnd
Xrbl_inv bl[0] out vdd gnd pinv_10
Mrbl_access_tx vdd delayed_en bl[0] vdd p m=1 w=1.2u l=0.6u pd=3.5999999999999996u ps=3.5999999999999996u as=1.7999999999999998p ad=1.7999999999999998p
Xdelay_chain en delayed_en vdd gnd delay_chain
Xbitcell bl[0] br[0] delayed_en vdd gnd replica_cell_6t
Xload bl[0] br[0] gnd gnd gnd gnd vdd gnd bitline_load
.ENDS replica_bitline
.SUBCKT control_logic csb web oeb clk s_en w_en tri_en tri_en_bar clk_buf_bar clk_buf vdd gnd
Xctrl_dffs csb web oeb cs_bar cs we_bar we oe_bar oe clk_buf vdd gnd dff_array_3x1
Xclkbuf clk clk_buf_bar clk_buf vdd gnd pinvbuf_4_16
Xnand3_w_en_bar clk_buf_bar cs we w_en_bar vdd gnd pnand3_1
Xinv_pre_w_en w_en_bar pre_w_en vdd gnd pinv_6
Xinv_pre_w_en_bar pre_w_en pre_w_en_bar vdd gnd pinv_7
Xinv_w_en2 pre_w_en_bar w_en vdd gnd pinv_8
Xinv_tri_en1 pre_tri_en_bar pre_tri_en1 vdd gnd pinv_7
Xtri_en_buf1 pre_tri_en1 pre_tri_en_bar1 vdd gnd pinv_7
Xtri_en_buf2 pre_tri_en_bar1 tri_en vdd gnd pinv_8
Xnand2_tri_en clk_buf_bar oe pre_tri_en_bar vdd gnd pnand2_1
Xtri_en_bar_buf1 pre_tri_en_bar pre_tri_en2 vdd gnd pinv_7
Xtri_en_bar_buf2 pre_tri_en2 tri_en_bar vdd gnd pinv_8
Xnand3_rblk_bar clk_buf_bar oe cs rblk_bar vdd gnd pnand3_1
Xinv_rblk rblk_bar rblk vdd gnd pinv_6
Xinv_s_en pre_s_en_bar s_en vdd gnd pinv_8
Xinv_pre_s_en_bar pre_s_en pre_s_en_bar vdd gnd pinv_7
Xreplica_bitline rblk pre_s_en vdd gnd replica_bitline
.ENDS control_logic
.SUBCKT dff_array din[0] din[1] din[2] din[3] dout[0] dout[1] dout[2] dout[3] clk vdd gnd
XXdff_r0_c0 din[0] dout[0] clk vdd gnd dff
XXdff_r1_c0 din[1] dout[1] clk vdd gnd dff
XXdff_r2_c0 din[2] dout[2] clk vdd gnd dff
XXdff_r3_c0 din[3] dout[3] clk vdd gnd dff
.ENDS dff_array
.SUBCKT bitcell_array bl[0] br[0] bl[1] br[1] bl[2] br[2] bl[3] br[3] wl[0] wl[1] wl[2] wl[3] wl[4] wl[5] wl[6] wl[7] wl[8] wl[9] wl[10] wl[11] wl[12] wl[13] wl[14] wl[15] vdd gnd
Xbit_r0_c0 bl[0] br[0] wl[0] vdd gnd cell_6t
Xbit_r1_c0 bl[0] br[0] wl[1] vdd gnd cell_6t
Xbit_r2_c0 bl[0] br[0] wl[2] vdd gnd cell_6t
Xbit_r3_c0 bl[0] br[0] wl[3] vdd gnd cell_6t
Xbit_r4_c0 bl[0] br[0] wl[4] vdd gnd cell_6t
Xbit_r5_c0 bl[0] br[0] wl[5] vdd gnd cell_6t
Xbit_r6_c0 bl[0] br[0] wl[6] vdd gnd cell_6t
Xbit_r7_c0 bl[0] br[0] wl[7] vdd gnd cell_6t
Xbit_r8_c0 bl[0] br[0] wl[8] vdd gnd cell_6t
Xbit_r9_c0 bl[0] br[0] wl[9] vdd gnd cell_6t
Xbit_r10_c0 bl[0] br[0] wl[10] vdd gnd cell_6t
Xbit_r11_c0 bl[0] br[0] wl[11] vdd gnd cell_6t
Xbit_r12_c0 bl[0] br[0] wl[12] vdd gnd cell_6t
Xbit_r13_c0 bl[0] br[0] wl[13] vdd gnd cell_6t
Xbit_r14_c0 bl[0] br[0] wl[14] vdd gnd cell_6t
Xbit_r15_c0 bl[0] br[0] wl[15] vdd gnd cell_6t
Xbit_r0_c1 bl[1] br[1] wl[0] vdd gnd cell_6t
Xbit_r1_c1 bl[1] br[1] wl[1] vdd gnd cell_6t
Xbit_r2_c1 bl[1] br[1] wl[2] vdd gnd cell_6t
Xbit_r3_c1 bl[1] br[1] wl[3] vdd gnd cell_6t
Xbit_r4_c1 bl[1] br[1] wl[4] vdd gnd cell_6t
Xbit_r5_c1 bl[1] br[1] wl[5] vdd gnd cell_6t
Xbit_r6_c1 bl[1] br[1] wl[6] vdd gnd cell_6t
Xbit_r7_c1 bl[1] br[1] wl[7] vdd gnd cell_6t
Xbit_r8_c1 bl[1] br[1] wl[8] vdd gnd cell_6t
Xbit_r9_c1 bl[1] br[1] wl[9] vdd gnd cell_6t
Xbit_r10_c1 bl[1] br[1] wl[10] vdd gnd cell_6t
Xbit_r11_c1 bl[1] br[1] wl[11] vdd gnd cell_6t
Xbit_r12_c1 bl[1] br[1] wl[12] vdd gnd cell_6t
Xbit_r13_c1 bl[1] br[1] wl[13] vdd gnd cell_6t
Xbit_r14_c1 bl[1] br[1] wl[14] vdd gnd cell_6t
Xbit_r15_c1 bl[1] br[1] wl[15] vdd gnd cell_6t
Xbit_r0_c2 bl[2] br[2] wl[0] vdd gnd cell_6t
Xbit_r1_c2 bl[2] br[2] wl[1] vdd gnd cell_6t
Xbit_r2_c2 bl[2] br[2] wl[2] vdd gnd cell_6t
Xbit_r3_c2 bl[2] br[2] wl[3] vdd gnd cell_6t
Xbit_r4_c2 bl[2] br[2] wl[4] vdd gnd cell_6t
Xbit_r5_c2 bl[2] br[2] wl[5] vdd gnd cell_6t
Xbit_r6_c2 bl[2] br[2] wl[6] vdd gnd cell_6t
Xbit_r7_c2 bl[2] br[2] wl[7] vdd gnd cell_6t
Xbit_r8_c2 bl[2] br[2] wl[8] vdd gnd cell_6t
Xbit_r9_c2 bl[2] br[2] wl[9] vdd gnd cell_6t
Xbit_r10_c2 bl[2] br[2] wl[10] vdd gnd cell_6t
Xbit_r11_c2 bl[2] br[2] wl[11] vdd gnd cell_6t
Xbit_r12_c2 bl[2] br[2] wl[12] vdd gnd cell_6t
Xbit_r13_c2 bl[2] br[2] wl[13] vdd gnd cell_6t
Xbit_r14_c2 bl[2] br[2] wl[14] vdd gnd cell_6t
Xbit_r15_c2 bl[2] br[2] wl[15] vdd gnd cell_6t
Xbit_r0_c3 bl[3] br[3] wl[0] vdd gnd cell_6t
Xbit_r1_c3 bl[3] br[3] wl[1] vdd gnd cell_6t
Xbit_r2_c3 bl[3] br[3] wl[2] vdd gnd cell_6t
Xbit_r3_c3 bl[3] br[3] wl[3] vdd gnd cell_6t
Xbit_r4_c3 bl[3] br[3] wl[4] vdd gnd cell_6t
Xbit_r5_c3 bl[3] br[3] wl[5] vdd gnd cell_6t
Xbit_r6_c3 bl[3] br[3] wl[6] vdd gnd cell_6t
Xbit_r7_c3 bl[3] br[3] wl[7] vdd gnd cell_6t
Xbit_r8_c3 bl[3] br[3] wl[8] vdd gnd cell_6t
Xbit_r9_c3 bl[3] br[3] wl[9] vdd gnd cell_6t
Xbit_r10_c3 bl[3] br[3] wl[10] vdd gnd cell_6t
Xbit_r11_c3 bl[3] br[3] wl[11] vdd gnd cell_6t
Xbit_r12_c3 bl[3] br[3] wl[12] vdd gnd cell_6t
Xbit_r13_c3 bl[3] br[3] wl[13] vdd gnd cell_6t
Xbit_r14_c3 bl[3] br[3] wl[14] vdd gnd cell_6t
Xbit_r15_c3 bl[3] br[3] wl[15] vdd gnd cell_6t
.ENDS bitcell_array
* ptx M{0} {1} p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
.SUBCKT precharge bl br en vdd
Mlower_pmos bl en br vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mupper_pmos1 bl en vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mupper_pmos2 br en vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
.ENDS precharge
.SUBCKT precharge_array bl[0] br[0] bl[1] br[1] bl[2] br[2] bl[3] br[3] en vdd
Xpre_column_0 bl[0] br[0] en vdd precharge
Xpre_column_1 bl[1] br[1] en vdd precharge
Xpre_column_2 bl[2] br[2] en vdd precharge
Xpre_column_3 bl[3] br[3] en vdd precharge
.ENDS precharge_array
*********************** "sense_amp" ******************************
.SUBCKT sense_amp bl br dout en vdd gnd
M_1 dout net_1 vdd vdd p W='5.4*1u' L=0.6u
M_2 dout net_1 net_2 gnd n W='2.7*1u' L=0.6u
M_3 net_1 dout vdd vdd p W='5.4*1u' L=0.6u
M_4 net_1 dout net_2 gnd n W='2.7*1u' L=0.6u
M_5 bl en dout vdd p W='7.2*1u' L=0.6u
M_6 br en net_1 vdd p W='7.2*1u' L=0.6u
M_7 net_2 en gnd gnd n W='2.7*1u' L=0.6u
.ENDS sense_amp
.SUBCKT sense_amp_array data[0] bl[0] br[0] data[1] bl[1] br[1] data[2] bl[2] br[2] data[3] bl[3] br[3] en vdd gnd
Xsa_d0 bl[0] br[0] data[0] en vdd gnd sense_amp
Xsa_d1 bl[1] br[1] data[1] en vdd gnd sense_amp
Xsa_d2 bl[2] br[2] data[2] en vdd gnd sense_amp
Xsa_d3 bl[3] br[3] data[3] en vdd gnd sense_amp
.ENDS sense_amp_array
*********************** Write_Driver ******************************
.SUBCKT write_driver din bl br en vdd gnd
**** Inverter to conver Data_in to data_in_bar ******
M_1 net_3 din gnd gnd n W='1.2*1u' L=0.6u
M_2 net_3 din vdd vdd p W='2.1*1u' L=0.6u
**** 2input nand gate follwed by inverter to drive BL ******
M_3 net_2 en net_7 gnd n W='2.1*1u' L=0.6u
M_4 net_7 din gnd gnd n W='2.1*1u' L=0.6u
M_5 net_2 en vdd vdd p W='2.1*1u' L=0.6u
M_6 net_2 din vdd vdd p W='2.1*1u' L=0.6u
M_7 net_1 net_2 vdd vdd p W='2.1*1u' L=0.6u
M_8 net_1 net_2 gnd gnd n W='1.2*1u' L=0.6u
**** 2input nand gate follwed by inverter to drive BR******
M_9 net_4 en vdd vdd p W='2.1*1u' L=0.6u
M_10 net_4 en net_8 gnd n W='2.1*1u' L=0.6u
M_11 net_8 net_3 gnd gnd n W='2.1*1u' L=0.6u
M_12 net_4 net_3 vdd vdd p W='2.1*1u' L=0.6u
M_13 net_6 net_4 vdd vdd p W='2.1*1u' L=0.6u
M_14 net_6 net_4 gnd gnd n W='1.2*1u' L=0.6u
************************************************
M_15 bl net_6 net_5 gnd n W='3.6*1u' L=0.6u
M_16 br net_1 net_5 gnd n W='3.6*1u' L=0.6u
M_17 net_5 en gnd gnd n W='3.6*1u' L=0.6u
.ENDS $ write_driver
.SUBCKT write_driver_array data[0] data[1] data[2] data[3] bl[0] br[0] bl[1] br[1] bl[2] br[2] bl[3] br[3] en vdd gnd
XXwrite_driver0 data[0] bl[0] br[0] en vdd gnd write_driver
XXwrite_driver1 data[1] bl[1] br[1] en vdd gnd write_driver
XXwrite_driver2 data[2] bl[2] br[2] en vdd gnd write_driver
XXwrite_driver3 data[3] bl[3] br[3] en vdd gnd write_driver
.ENDS write_driver_array
.SUBCKT pinv_11 A Z vdd gnd
Mpinv_pmos Z A vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpinv_nmos Z A gnd gnd n m=1 w=1.2u l=0.6u pd=3.5999999999999996u ps=3.5999999999999996u as=1.7999999999999998p ad=1.7999999999999998p
.ENDS pinv_11
.SUBCKT pnand2_2 A B Z vdd gnd
Mpnand2_pmos1 vdd A Z vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand2_pmos2 Z B vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand2_nmos1 Z B net1 gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand2_nmos2 net1 A gnd gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
.ENDS pnand2_2
.SUBCKT pnand3_2 A B C Z vdd gnd
Mpnand3_pmos1 vdd A Z vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand3_pmos2 Z B vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand3_pmos3 Z C vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand3_nmos1 Z C net1 gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand3_nmos2 net1 B net2 gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand3_nmos3 net2 A gnd gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
.ENDS pnand3_2
.SUBCKT pinv_12 A Z vdd gnd
Mpinv_pmos Z A vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpinv_nmos Z A gnd gnd n m=1 w=1.2u l=0.6u pd=3.5999999999999996u ps=3.5999999999999996u as=1.7999999999999998p ad=1.7999999999999998p
.ENDS pinv_12
.SUBCKT pnand2_3 A B Z vdd gnd
Mpnand2_pmos1 vdd A Z vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand2_pmos2 Z B vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand2_nmos1 Z B net1 gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand2_nmos2 net1 A gnd gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
.ENDS pnand2_3
.SUBCKT pre2x4 in[0] in[1] out[0] out[1] out[2] out[3] vdd gnd
XXpre_inv[0] in[0] inbar[0] vdd gnd pinv_12
XXpre_inv[1] in[1] inbar[1] vdd gnd pinv_12
XXpre_nand_inv[0] Z[0] out[0] vdd gnd pinv_12
XXpre_nand_inv[1] Z[1] out[1] vdd gnd pinv_12
XXpre_nand_inv[2] Z[2] out[2] vdd gnd pinv_12
XXpre_nand_inv[3] Z[3] out[3] vdd gnd pinv_12
XXpre2x4_nand[0] inbar[0] inbar[1] Z[0] vdd gnd pnand2_3
XXpre2x4_nand[1] in[0] inbar[1] Z[1] vdd gnd pnand2_3
XXpre2x4_nand[2] inbar[0] in[1] Z[2] vdd gnd pnand2_3
XXpre2x4_nand[3] in[0] in[1] Z[3] vdd gnd pnand2_3
.ENDS pre2x4
.SUBCKT pinv_13 A Z vdd gnd
Mpinv_pmos Z A vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpinv_nmos Z A gnd gnd n m=1 w=1.2u l=0.6u pd=3.5999999999999996u ps=3.5999999999999996u as=1.7999999999999998p ad=1.7999999999999998p
.ENDS pinv_13
.SUBCKT pnand3_3 A B C Z vdd gnd
Mpnand3_pmos1 vdd A Z vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand3_pmos2 Z B vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand3_pmos3 Z C vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand3_nmos1 Z C net1 gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand3_nmos2 net1 B net2 gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand3_nmos3 net2 A gnd gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
.ENDS pnand3_3
.SUBCKT pre3x8 in[0] in[1] in[2] out[0] out[1] out[2] out[3] out[4] out[5] out[6] out[7] vdd gnd
XXpre_inv[0] in[0] inbar[0] vdd gnd pinv_13
XXpre_inv[1] in[1] inbar[1] vdd gnd pinv_13
XXpre_inv[2] in[2] inbar[2] vdd gnd pinv_13
XXpre_nand_inv[0] Z[0] out[0] vdd gnd pinv_13
XXpre_nand_inv[1] Z[1] out[1] vdd gnd pinv_13
XXpre_nand_inv[2] Z[2] out[2] vdd gnd pinv_13
XXpre_nand_inv[3] Z[3] out[3] vdd gnd pinv_13
XXpre_nand_inv[4] Z[4] out[4] vdd gnd pinv_13
XXpre_nand_inv[5] Z[5] out[5] vdd gnd pinv_13
XXpre_nand_inv[6] Z[6] out[6] vdd gnd pinv_13
XXpre_nand_inv[7] Z[7] out[7] vdd gnd pinv_13
XXpre3x8_nand[0] inbar[0] inbar[1] inbar[2] Z[0] vdd gnd pnand3_3
XXpre3x8_nand[1] in[0] inbar[1] inbar[2] Z[1] vdd gnd pnand3_3
XXpre3x8_nand[2] inbar[0] in[1] inbar[2] Z[2] vdd gnd pnand3_3
XXpre3x8_nand[3] in[0] in[1] inbar[2] Z[3] vdd gnd pnand3_3
XXpre3x8_nand[4] inbar[0] inbar[1] in[2] Z[4] vdd gnd pnand3_3
XXpre3x8_nand[5] in[0] inbar[1] in[2] Z[5] vdd gnd pnand3_3
XXpre3x8_nand[6] inbar[0] in[1] in[2] Z[6] vdd gnd pnand3_3
XXpre3x8_nand[7] in[0] in[1] in[2] Z[7] vdd gnd pnand3_3
.ENDS pre3x8
.SUBCKT hierarchical_decoder_16rows A[0] A[1] A[2] A[3] decode[0] decode[1] decode[2] decode[3] decode[4] decode[5] decode[6] decode[7] decode[8] decode[9] decode[10] decode[11] decode[12] decode[13] decode[14] decode[15] vdd gnd
Xpre[0] A[0] A[1] out[0] out[1] out[2] out[3] vdd gnd pre2x4
Xpre[1] A[2] A[3] out[4] out[5] out[6] out[7] vdd gnd pre2x4
XDEC_NAND[0] out[0] out[4] Z[0] vdd gnd pnand2_2
XDEC_NAND[1] out[0] out[5] Z[1] vdd gnd pnand2_2
XDEC_NAND[2] out[0] out[6] Z[2] vdd gnd pnand2_2
XDEC_NAND[3] out[0] out[7] Z[3] vdd gnd pnand2_2
XDEC_NAND[4] out[1] out[4] Z[4] vdd gnd pnand2_2
XDEC_NAND[5] out[1] out[5] Z[5] vdd gnd pnand2_2
XDEC_NAND[6] out[1] out[6] Z[6] vdd gnd pnand2_2
XDEC_NAND[7] out[1] out[7] Z[7] vdd gnd pnand2_2
XDEC_NAND[8] out[2] out[4] Z[8] vdd gnd pnand2_2
XDEC_NAND[9] out[2] out[5] Z[9] vdd gnd pnand2_2
XDEC_NAND[10] out[2] out[6] Z[10] vdd gnd pnand2_2
XDEC_NAND[11] out[2] out[7] Z[11] vdd gnd pnand2_2
XDEC_NAND[12] out[3] out[4] Z[12] vdd gnd pnand2_2
XDEC_NAND[13] out[3] out[5] Z[13] vdd gnd pnand2_2
XDEC_NAND[14] out[3] out[6] Z[14] vdd gnd pnand2_2
XDEC_NAND[15] out[3] out[7] Z[15] vdd gnd pnand2_2
XDEC_INV_[0] Z[0] decode[0] vdd gnd pinv_11
XDEC_INV_[1] Z[1] decode[1] vdd gnd pinv_11
XDEC_INV_[2] Z[2] decode[2] vdd gnd pinv_11
XDEC_INV_[3] Z[3] decode[3] vdd gnd pinv_11
XDEC_INV_[4] Z[4] decode[4] vdd gnd pinv_11
XDEC_INV_[5] Z[5] decode[5] vdd gnd pinv_11
XDEC_INV_[6] Z[6] decode[6] vdd gnd pinv_11
XDEC_INV_[7] Z[7] decode[7] vdd gnd pinv_11
XDEC_INV_[8] Z[8] decode[8] vdd gnd pinv_11
XDEC_INV_[9] Z[9] decode[9] vdd gnd pinv_11
XDEC_INV_[10] Z[10] decode[10] vdd gnd pinv_11
XDEC_INV_[11] Z[11] decode[11] vdd gnd pinv_11
XDEC_INV_[12] Z[12] decode[12] vdd gnd pinv_11
XDEC_INV_[13] Z[13] decode[13] vdd gnd pinv_11
XDEC_INV_[14] Z[14] decode[14] vdd gnd pinv_11
XDEC_INV_[15] Z[15] decode[15] vdd gnd pinv_11
.ENDS hierarchical_decoder_16rows
*********************** tri_gate ******************************
.SUBCKT tri_gate in out en en_bar vdd gnd
M_1 net_2 in_inv gnd gnd n W='1.2*1u' L=0.6u
M_2 net_3 in_inv vdd vdd p W='2.4*1u' L=0.6u
M_3 out en_bar net_3 vdd p W='2.4*1u' L=0.6u
M_4 out en net_2 gnd n W='1.2*1u' L=0.6u
M_5 in_inv in vdd vdd p W='2.4*1u' L=0.6u
M_6 in_inv in gnd gnd n W='1.2*1u' L=0.6u
.ENDS
.SUBCKT tri_gate_array in[0] in[1] in[2] in[3] out[0] out[1] out[2] out[3] en en_bar vdd gnd
XXtri_gate0 in[0] out[0] en en_bar vdd gnd tri_gate
XXtri_gate1 in[1] out[1] en en_bar vdd gnd tri_gate
XXtri_gate2 in[2] out[2] en en_bar vdd gnd tri_gate
XXtri_gate3 in[3] out[3] en en_bar vdd gnd tri_gate
.ENDS tri_gate_array
.SUBCKT pinv_14 A Z vdd gnd
Mpinv_pmos Z A vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpinv_nmos Z A gnd gnd n m=1 w=1.2u l=0.6u pd=3.5999999999999996u ps=3.5999999999999996u as=1.7999999999999998p ad=1.7999999999999998p
.ENDS pinv_14
.SUBCKT pinv_15 A Z vdd gnd
Mpinv_pmos Z A vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpinv_nmos Z A gnd gnd n m=1 w=1.2u l=0.6u pd=3.5999999999999996u ps=3.5999999999999996u as=1.7999999999999998p ad=1.7999999999999998p
.ENDS pinv_15
.SUBCKT pnand2_4 A B Z vdd gnd
Mpnand2_pmos1 vdd A Z vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand2_pmos2 Z B vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand2_nmos1 Z B net1 gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpnand2_nmos2 net1 A gnd gnd n m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
.ENDS pnand2_4
.SUBCKT wordline_driver in[0] in[1] in[2] in[3] in[4] in[5] in[6] in[7] in[8] in[9] in[10] in[11] in[12] in[13] in[14] in[15] wl[0] wl[1] wl[2] wl[3] wl[4] wl[5] wl[6] wl[7] wl[8] wl[9] wl[10] wl[11] wl[12] wl[13] wl[14] wl[15] en vdd gnd
Xwl_driver_inv_en0 en en_bar[0] vdd gnd pinv_15
Xwl_driver_nand0 en_bar[0] in[0] net[0] vdd gnd pnand2_4
Xwl_driver_inv0 net[0] wl[0] vdd gnd pinv_14
Xwl_driver_inv_en1 en en_bar[1] vdd gnd pinv_15
Xwl_driver_nand1 en_bar[1] in[1] net[1] vdd gnd pnand2_4
Xwl_driver_inv1 net[1] wl[1] vdd gnd pinv_14
Xwl_driver_inv_en2 en en_bar[2] vdd gnd pinv_15
Xwl_driver_nand2 en_bar[2] in[2] net[2] vdd gnd pnand2_4
Xwl_driver_inv2 net[2] wl[2] vdd gnd pinv_14
Xwl_driver_inv_en3 en en_bar[3] vdd gnd pinv_15
Xwl_driver_nand3 en_bar[3] in[3] net[3] vdd gnd pnand2_4
Xwl_driver_inv3 net[3] wl[3] vdd gnd pinv_14
Xwl_driver_inv_en4 en en_bar[4] vdd gnd pinv_15
Xwl_driver_nand4 en_bar[4] in[4] net[4] vdd gnd pnand2_4
Xwl_driver_inv4 net[4] wl[4] vdd gnd pinv_14
Xwl_driver_inv_en5 en en_bar[5] vdd gnd pinv_15
Xwl_driver_nand5 en_bar[5] in[5] net[5] vdd gnd pnand2_4
Xwl_driver_inv5 net[5] wl[5] vdd gnd pinv_14
Xwl_driver_inv_en6 en en_bar[6] vdd gnd pinv_15
Xwl_driver_nand6 en_bar[6] in[6] net[6] vdd gnd pnand2_4
Xwl_driver_inv6 net[6] wl[6] vdd gnd pinv_14
Xwl_driver_inv_en7 en en_bar[7] vdd gnd pinv_15
Xwl_driver_nand7 en_bar[7] in[7] net[7] vdd gnd pnand2_4
Xwl_driver_inv7 net[7] wl[7] vdd gnd pinv_14
Xwl_driver_inv_en8 en en_bar[8] vdd gnd pinv_15
Xwl_driver_nand8 en_bar[8] in[8] net[8] vdd gnd pnand2_4
Xwl_driver_inv8 net[8] wl[8] vdd gnd pinv_14
Xwl_driver_inv_en9 en en_bar[9] vdd gnd pinv_15
Xwl_driver_nand9 en_bar[9] in[9] net[9] vdd gnd pnand2_4
Xwl_driver_inv9 net[9] wl[9] vdd gnd pinv_14
Xwl_driver_inv_en10 en en_bar[10] vdd gnd pinv_15
Xwl_driver_nand10 en_bar[10] in[10] net[10] vdd gnd pnand2_4
Xwl_driver_inv10 net[10] wl[10] vdd gnd pinv_14
Xwl_driver_inv_en11 en en_bar[11] vdd gnd pinv_15
Xwl_driver_nand11 en_bar[11] in[11] net[11] vdd gnd pnand2_4
Xwl_driver_inv11 net[11] wl[11] vdd gnd pinv_14
Xwl_driver_inv_en12 en en_bar[12] vdd gnd pinv_15
Xwl_driver_nand12 en_bar[12] in[12] net[12] vdd gnd pnand2_4
Xwl_driver_inv12 net[12] wl[12] vdd gnd pinv_14
Xwl_driver_inv_en13 en en_bar[13] vdd gnd pinv_15
Xwl_driver_nand13 en_bar[13] in[13] net[13] vdd gnd pnand2_4
Xwl_driver_inv13 net[13] wl[13] vdd gnd pinv_14
Xwl_driver_inv_en14 en en_bar[14] vdd gnd pinv_15
Xwl_driver_nand14 en_bar[14] in[14] net[14] vdd gnd pnand2_4
Xwl_driver_inv14 net[14] wl[14] vdd gnd pinv_14
Xwl_driver_inv_en15 en en_bar[15] vdd gnd pinv_15
Xwl_driver_nand15 en_bar[15] in[15] net[15] vdd gnd pnand2_4
Xwl_driver_inv15 net[15] wl[15] vdd gnd pinv_14
.ENDS wordline_driver
.SUBCKT pinv_16 A Z vdd gnd
Mpinv_pmos Z A vdd vdd p m=1 w=2.4u l=0.6u pd=6.0u ps=6.0u as=3.5999999999999996p ad=3.5999999999999996p
Mpinv_nmos Z A gnd gnd n m=1 w=1.2u l=0.6u pd=3.5999999999999996u ps=3.5999999999999996u as=1.7999999999999998p ad=1.7999999999999998p
.ENDS pinv_16
.SUBCKT bank DOUT[0] DOUT[1] DOUT[2] DOUT[3] DIN[0] DIN[1] DIN[2] DIN[3] A[0] A[1] A[2] A[3] s_en w_en tri_en_bar tri_en clk_buf_bar clk_buf vdd gnd
Xbitcell_array bl[0] br[0] bl[1] br[1] bl[2] br[2] bl[3] br[3] wl[0] wl[1] wl[2] wl[3] wl[4] wl[5] wl[6] wl[7] wl[8] wl[9] wl[10] wl[11] wl[12] wl[13] wl[14] wl[15] vdd gnd bitcell_array
Xprecharge_array bl[0] br[0] bl[1] br[1] bl[2] br[2] bl[3] br[3] clk_buf_bar vdd precharge_array
Xsense_amp_array sa_out[0] bl[0] br[0] sa_out[1] bl[1] br[1] sa_out[2] bl[2] br[2] sa_out[3] bl[3] br[3] s_en vdd gnd sense_amp_array
Xwrite_driver_array DIN[0] DIN[1] DIN[2] DIN[3] bl[0] br[0] bl[1] br[1] bl[2] br[2] bl[3] br[3] w_en vdd gnd write_driver_array
Xtri_gate_array sa_out[0] sa_out[1] sa_out[2] sa_out[3] DOUT[0] DOUT[1] DOUT[2] DOUT[3] tri_en tri_en_bar vdd gnd tri_gate_array
Xrow_decoder A[0] A[1] A[2] A[3] dec_out[0] dec_out[1] dec_out[2] dec_out[3] dec_out[4] dec_out[5] dec_out[6] dec_out[7] dec_out[8] dec_out[9] dec_out[10] dec_out[11] dec_out[12] dec_out[13] dec_out[14] dec_out[15] vdd gnd hierarchical_decoder_16rows
Xwordline_driver dec_out[0] dec_out[1] dec_out[2] dec_out[3] dec_out[4] dec_out[5] dec_out[6] dec_out[7] dec_out[8] dec_out[9] dec_out[10] dec_out[11] dec_out[12] dec_out[13] dec_out[14] dec_out[15] wl[0] wl[1] wl[2] wl[3] wl[4] wl[5] wl[6] wl[7] wl[8] wl[9] wl[10] wl[11] wl[12] wl[13] wl[14] wl[15] clk_buf vdd gnd wordline_driver
.ENDS bank
.SUBCKT sram1 DIN[0] DIN[1] DIN[2] DIN[3] ADDR[0] ADDR[1] ADDR[2] ADDR[3] csb web oeb clk DOUT[0] DOUT[1] DOUT[2] DOUT[3] vdd gnd
Xbank0 DOUT[0] DOUT[1] DOUT[2] DOUT[3] DIN[0] DIN[1] DIN[2] DIN[3] A[0] A[1] A[2] A[3] s_en w_en tri_en_bar tri_en clk_buf_bar clk_buf vdd gnd bank
Xcontrol csb_s web_s oeb_s clk s_en w_en tri_en tri_en_bar clk_buf_bar clk_buf vdd gnd control_logic
Xaddress ADDR[0] ADDR[1] ADDR[2] ADDR[3] A[0] A[1] A[2] A[3] clk_buf vdd gnd dff_array
Xaddress ADDR[0] ADDR[1] ADDR[2] ADDR[3] A[0] A[1] A[2] A[3] clk_buf vdd gnd dff_array
.ENDS sram1

View File

@ -0,0 +1,347 @@
library (sram1_TT_5p0V_25C_lib){
delay_model : "table_lookup";
time_unit : "1ns" ;
voltage_unit : "1v" ;
current_unit : "1mA" ;
resistance_unit : "1kohm" ;
capacitive_load_unit(1 ,fF) ;
leakage_power_unit : "1mW" ;
pulling_resistance_unit :"1kohm" ;
operating_conditions(OC){
process : 1.0 ;
voltage : 5.0 ;
temperature : 25;
}
input_threshold_pct_fall : 50.0 ;
output_threshold_pct_fall : 50.0 ;
input_threshold_pct_rise : 50.0 ;
output_threshold_pct_rise : 50.0 ;
slew_lower_threshold_pct_fall : 10.0 ;
slew_upper_threshold_pct_fall : 90.0 ;
slew_lower_threshold_pct_rise : 10.0 ;
slew_upper_threshold_pct_rise : 90.0 ;
nom_voltage : 5.0;
nom_temperature : 25;
nom_process : 1.0;
default_cell_leakage_power : 0.0 ;
default_leakage_power_density : 0.0 ;
default_input_pin_cap : 1.0 ;
default_inout_pin_cap : 1.0 ;
default_output_pin_cap : 0.0 ;
default_max_transition : 0.5 ;
default_fanout_load : 1.0 ;
default_max_fanout : 4.0 ;
default_connection_class : universal ;
lu_table_template(CELL_TABLE){
variable_1 : input_net_transition;
variable_2 : total_output_net_capacitance;
index_1("0.0125, 0.05, 0.4");
index_2("2.45605, 9.8242, 78.5936");
}
lu_table_template(CONSTRAINT_TABLE){
variable_1 : related_pin_transition;
variable_2 : constrained_pin_transition;
index_1("0.0125, 0.05, 0.4");
index_2("0.0125, 0.05, 0.4");
}
default_operating_conditions : OC;
type (DATA){
base_type : array;
data_type : bit;
bit_width : 4;
bit_from : 0;
bit_to : 3;
}
type (ADDR){
base_type : array;
data_type : bit;
bit_width : 4;
bit_from : 0;
bit_to : 3;
}
cell (sram1){
memory(){
type : ram;
address_width : 4;
word_width : 4;
}
interface_timing : true;
dont_use : true;
map_only : true;
dont_touch : true;
area : 136566.0;
leakage_power () {
when : "CSb";
value : 0.000202;
}
cell_leakage_power : 0;
bus(DATA){
bus_type : DATA;
direction : inout;
max_capacitance : 78.5936;
min_capacitance : 2.45605;
three_state : "!OEb & !clk";
memory_write(){
address : ADDR;
clocked_on : clk;
}
memory_read(){
address : ADDR;
}
pin(DATA[3:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009");
}
}
timing(){
timing_type : hold_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001");
}
}
timing(){
timing_sense : non_unate;
related_pin : "clk";
timing_type : falling_edge;
cell_rise(CELL_TABLE) {
values("0.612, 0.66, 1.1",\
"0.612, 0.66, 1.1",\
"0.612, 0.66, 1.1");
}
cell_fall(CELL_TABLE) {
values("0.612, 0.66, 1.1",\
"0.612, 0.66, 1.1",\
"0.612, 0.66, 1.1");
}
rise_transition(CELL_TABLE) {
values("0.024, 0.081, 0.61",\
"0.024, 0.081, 0.61",\
"0.024, 0.081, 0.61");
}
fall_transition(CELL_TABLE) {
values("0.024, 0.081, 0.61",\
"0.024, 0.081, 0.61",\
"0.024, 0.081, 0.61");
}
}
}
}
bus(ADDR){
bus_type : ADDR;
direction : input;
capacitance : 9.8242;
max_transition : 0.4;
pin(ADDR[3:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009");
}
}
timing(){
timing_type : hold_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001");
}
}
}
}
pin(CSb){
direction : input;
capacitance : 9.8242;
timing(){
timing_type : setup_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009");
}
}
timing(){
timing_type : hold_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001");
}
}
}
pin(OEb){
direction : input;
capacitance : 9.8242;
timing(){
timing_type : setup_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009");
}
}
timing(){
timing_type : hold_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001");
}
}
}
pin(WEb){
direction : input;
capacitance : 9.8242;
timing(){
timing_type : setup_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009",\
"0.009, 0.009, 0.009");
}
}
timing(){
timing_type : hold_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001",\
"0.001, 0.001, 0.001");
}
}
}
pin(clk){
clock : true;
direction : input;
capacitance : 9.8242;
internal_power(){
when : "!CSb & clk & !WEb";
rise_power(scalar){
values("10.812808757533329");
}
fall_power(scalar){
values("10.812808757533329");
}
}
internal_power(){
when : "!CSb & !clk & WEb";
rise_power(scalar){
values("10.812808757533329");
}
fall_power(scalar){
values("10.812808757533329");
}
}
internal_power(){
when : "CSb";
rise_power(scalar){
values("0");
}
fall_power(scalar){
values("0");
}
}
timing(){
timing_type :"min_pulse_width";
related_pin : clk;
rise_constraint(scalar) {
values("0.0");
}
fall_constraint(scalar) {
values("0.0");
}
}
timing(){
timing_type :"minimum_period";
related_pin : clk;
rise_constraint(scalar) {
values("0");
}
fall_constraint(scalar) {
values("0");
}
}
}
}
}

View File

@ -8,7 +8,6 @@ sys.path.append(os.path.join(sys.path[0],"../.."))
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
import debug import debug
import calibre
OPTS = globals.OPTS OPTS = globals.OPTS
@ -19,6 +18,8 @@ class no_blockages_test(unittest.TestCase):
def runTest(self): def runTest(self):
globals.init_openram("config_{0}".format(OPTS.tech_name)) globals.init_openram("config_{0}".format(OPTS.tech_name))
global verify
import verify
import design import design
import router import router

View File

View File

@ -1,16 +1,16 @@
#!/usr/bin/env python2.7 #!/usr/bin/env python3
import re import re
import unittest import unittest
import sys,os import sys,os
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.path.join(sys.path[0],"../../compiler"))
sys.path.append(os.path.join(sys.path[0],"../..")) print(sys.path)
import globals import globals
(OPTS, args) = globals.parse_args() (OPTS, args) = globals.parse_args()
del sys.argv[1:] del sys.argv[1:]
from testutils import header from testutils import header,openram_test
header(__file__, OPTS.tech_name) header(__file__, OPTS.tech_name)
# get a list of all files in the tests directory # get a list of all files in the tests directory
@ -18,7 +18,7 @@ files = os.listdir(sys.path[0])
# assume any file that ends in "test.py" in it is a regression test # assume any file that ends in "test.py" in it is a regression test
nametest = re.compile("test\.py$", re.IGNORECASE) nametest = re.compile("test\.py$", re.IGNORECASE)
tests = filter(nametest.search, files) tests = list(filter(nametest.search, files))
tests.sort() tests.sort()
# import all of the modules # import all of the modules
@ -28,4 +28,13 @@ modules = map(__import__, moduleNames)
suite = unittest.TestSuite() suite = unittest.TestSuite()
load = unittest.defaultTestLoader.loadTestsFromModule load = unittest.defaultTestLoader.loadTestsFromModule
suite.addTests(map(load, modules)) suite.addTests(map(load, modules))
unittest.TextTestRunner(verbosity=2).run(suite)
test_runner = unittest.TextTestRunner(verbosity=2,stream=sys.stderr)
test_result = test_runner.run(suite)
import verify
verify.print_drc_stats()
verify.print_lvs_stats()
verify.print_pex_stats()
sys.exit(not test_result.wasSuccessful())

257
router/tests/testutils.py Executable file
View File

@ -0,0 +1,257 @@
import unittest,warnings
import sys,os,glob,copy
sys.path.append(os.path.join(sys.path[0],".."))
from globals import OPTS
import debug
class openram_test(unittest.TestCase):
""" Base unit test that we have some shared classes in. """
def local_drc_check(self, w):
self.reset()
tempgds = OPTS.openram_temp + "temp.gds"
w.gds_write(tempgds)
import verify
result=verify.run_drc(w.name, tempgds)
if result != 0:
self.fail("DRC failed: {}".format(w.name))
self.cleanup()
def local_check(self, a, final_verification=False):
self.reset()
tempspice = OPTS.openram_temp + "temp.sp"
tempgds = OPTS.openram_temp + "temp.gds"
a.sp_write(tempspice)
a.gds_write(tempgds)
import verify
result=verify.run_drc(a.name, tempgds)
if result != 0:
self.fail("DRC failed: {}".format(a.name))
result=verify.run_lvs(a.name, tempgds, tempspice, final_verification)
if result != 0:
self.fail("LVS mismatch: {}".format(a.name))
if OPTS.purge_temp:
self.cleanup()
def cleanup(self):
""" Reset the duplicate checker and cleanup files. """
files = glob.glob(OPTS.openram_temp + '*')
for f in files:
# Only remove the files
if os.path.isfile(f):
os.remove(f)
def reset(self):
"""
Reset everything after each test.
"""
# Reset the static duplicate name checker for unit tests.
import hierarchy_design
hierarchy_design.hierarchy_design.name_map=[]
def check_golden_data(self, data, golden_data, error_tolerance=1e-2):
"""
This function goes through two dictionaries, key by key and compares
each item. It uses relative comparisons for the items and returns false
if there is a mismatch.
"""
# Check each result
data_matches = True
for k in data.keys():
if type(data[k])==list:
for i in range(len(data[k])):
if not self.isclose(k,data[k][i],golden_data[k][i],error_tolerance):
data_matches = False
else:
self.isclose(k,data[k],golden_data[k],error_tolerance)
if not data_matches:
import pprint
data_string=pprint.pformat(data)
debug.error("Results exceeded {:.1f}% tolerance compared to golden results:\n".format(error_tolerance*100)+data_string)
return data_matches
def isclose(self,key,value,actual_value,error_tolerance=1e-2):
""" This is used to compare relative values. """
import debug
relative_diff = self.relative_diff(value,actual_value)
check = relative_diff <= error_tolerance
if check:
debug.info(2,"CLOSE\t{0: <10}\t{1:.3f}\t{2:.3f}\tdiff={3:.1f}%".format(key,value,actual_value,relative_diff*100))
return True
else:
debug.error("NOT CLOSE\t{0: <10}\t{1:.3f}\t{2:.3f}\tdiff={3:.1f}%".format(key,value,actual_value,relative_diff*100))
return False
def relative_diff(self, value1, value2):
""" Compute the relative difference of two values and normalize to the largest.
If largest value is 0, just return the difference."""
# Edge case to avoid divide by zero
if value1==0 and value2==0:
return 0.0
# Don't need relative, exact compare
if value1==value2:
return 0.0
# Get normalization value
norm_value = abs(max(value1, value2))
# Edge case where greater is a zero
if norm_value == 0:
min_value = abs(min(value1, value2))
return abs(value1 - value2) / norm_value
def relative_compare(self, value,actual_value,error_tolerance):
""" This is used to compare relative values. """
if (value==actual_value): # if we don't need a relative comparison!
return True
return (abs(value - actual_value) / max(value,actual_value) <= error_tolerance)
def isapproxdiff(self, filename1, filename2, error_tolerance=0.001):
"""Compare two files.
Arguments:
filename1 -- First file name
filename2 -- Second file name
Return value:
True if the files are the same, False otherwise.
"""
import re
import debug
numeric_const_pattern = r"""
[-+]? # optional sign
(?:
(?: \d* \. \d+ ) # .1 .12 .123 etc 9.1 etc 98.1 etc
|
(?: \d+ \.? ) # 1. 12. 123. etc 1 12 123 etc
)
# followed by optional exponent part if desired
(?: [Ee] [+-]? \d+ ) ?
"""
rx = re.compile(numeric_const_pattern, re.VERBOSE)
fp1 = open(filename1, 'rb')
fp2 = open(filename2, 'rb')
mismatches=0
line_num=0
while True:
line_num+=1
line1 = fp1.readline().decode('utf-8')
line2 = fp2.readline().decode('utf-8')
#print("line1:",line1)
#print("line2:",line2)
# 1. Find all of the floats using a regex
line1_floats=rx.findall(line1)
line2_floats=rx.findall(line2)
debug.info(3,"line1_floats: "+str(line1_floats))
debug.info(3,"line2_floats: "+str(line2_floats))
# 2. Remove the floats from the string
for f in line1_floats:
line1=line1.replace(f,"",1)
for f in line2_floats:
line2=line2.replace(f,"",1)
#print("line1:",line1)
#print("line2:",line2)
# 3. Convert to floats rather than strings
line1_floats = [float(x) for x in line1_floats]
line2_floats = [float(x) for x in line1_floats]
# 4. Check if remaining string matches
if line1 != line2:
if mismatches==0:
debug.error("Mismatching files:\nfile1={0}\nfile2={1}".format(filename1,filename2))
mismatches += 1
debug.error("MISMATCH Line ({0}):\n{1}\n!=\n{2}".format(line_num,line1.rstrip('\n'),line2.rstrip('\n')))
# 5. Now compare that the floats match
elif len(line1_floats)!=len(line2_floats):
if mismatches==0:
debug.error("Mismatching files:\nfile1={0}\nfile2={1}".format(filename1,filename2))
mismatches += 1
debug.error("MISMATCH Line ({0}) Length {1} != {2}".format(line_num,len(line1_floats),len(line2_floats)))
else:
for (float1,float2) in zip(line1_floats,line2_floats):
relative_diff = self.relative_diff(float1,float2)
check = relative_diff <= error_tolerance
if not check:
if mismatches==0:
debug.error("Mismatching files:\nfile1={0}\nfile2={1}".format(filename1,filename2))
mismatches += 1
debug.error("MISMATCH Line ({0}) Float {1} != {2} diff: {3:.1f}%".format(line_num,float1,float2,relative_diff*100))
# Only show the first 10 mismatch lines
if not line1 and not line2 or mismatches>10:
fp1.close()
fp2.close()
return mismatches==0
# Never reached
return False
def isdiff(self,filename1,filename2):
""" This is used to compare two files and display the diff if they are different.. """
import debug
import filecmp
import difflib
check = filecmp.cmp(filename1,filename2)
if not check:
debug.error("MISMATCH file1={0} file2={1}".format(filename1,filename2))
f1 = open(filename1,"r")
s1 = f1.readlines().decode('utf-8')
f1.close()
f2 = open(filename2,"r").decode('utf-8')
s2 = f2.readlines()
f2.close()
mismatches=0
for line in difflib.unified_diff(s1, s2):
mismatches += 1
self.error("DIFF LINES:",line)
if mismatches>10:
return False
return False
else:
debug.info(2,"MATCH {0} {1}".format(filename1,filename2))
return True
def header(filename, technology):
# Skip the header for gitlab regression
import getpass
if getpass.getuser() == "gitlab-runner":
return
tst = "Running Test for:"
print("\n")
print(" ______________________________________________________________________________ ")
print("|==============================================================================|")
print("|=========" + tst.center(60) + "=========|")
print("|=========" + technology.center(60) + "=========|")
print("|=========" + filename.center(60) + "=========|")
from globals import OPTS
print("|=========" + OPTS.openram_temp.center(60) + "=========|")
print("|==============================================================================|")