Merge branch 'dev' into fix_rbl_cell_connections

This commit is contained in:
Matt Guthaus 2018-11-05 16:38:46 -08:00
commit c01f0f5274
25 changed files with 407 additions and 37 deletions

View File

@ -0,0 +1,23 @@
import design
import debug
import utils
from tech import GDS,layer
class replica_bitcell_1rw_1r(design.design):
"""
A single bit cell which is forced to store a 0.
This module implements the single memory cell used in the design. It
is a hand-made cell, so the layout and netlist should be available in
the technology library. """
pin_names = ["bl0", "br0", "bl1", "br1", "wl0", "wl1", "vdd", "gnd"]
(width,height) = utils.get_libcell_size("replica_cell_1rw_1r", GDS["unit"], layer["boundary"])
pin_map = utils.get_libcell_pins(pin_names, "replica_cell_1rw_1r", GDS["unit"], layer["boundary"])
def __init__(self):
design.design.__init__(self, "replica_cell_1rw_1r")
debug.info(2, "Create replica bitcell 1rw+1r object")
self.width = replica_bitcell_1rw_1r.width
self.height = replica_bitcell_1rw_1r.height
self.pin_map = replica_bitcell_1rw_1r.pin_map

View File

@ -36,6 +36,14 @@ class functional(simulation):
self.write_check = [] self.write_check = []
self.read_check = [] self.read_check = []
def set_spice_constants(self):
"""Spice constants for functional test"""
simulation.set_spice_constants(self)
#Heuristic increase for functional period. Base feasible period typically does not pass the functional test
#for column mux of this size. Increase the feasible period by 20% for this case.
if self.sram.words_per_row >= 4:
self.period = self.period*1.2
def run(self): def run(self):
# Generate a random sequence of reads and writes # Generate a random sequence of reads and writes
self.write_random_memory_sequence() self.write_random_memory_sequence()

View File

@ -208,14 +208,14 @@ class simulation():
t_current, t_current,
t_current+self.period) t_current+self.period)
elif op == "write": elif op == "write":
comment = "\tWriting {0} to address {1} (from port {2}) during cylce {3} ({4}ns - {5}ns)".format(word, comment = "\tWriting {0} to address {1} (from port {2}) during cycle {3} ({4}ns - {5}ns)".format(word,
addr, addr,
port, port,
int(t_current/self.period), int(t_current/self.period),
t_current, t_current,
t_current+self.period) t_current+self.period)
else: else:
comment = "\tReading {0} from address {1} (from port {2}) during cylce {3} ({4}ns - {5}ns)".format(word, comment = "\tReading {0} from address {1} (from port {2}) during cycle {3} ({4}ns - {5}ns)".format(word,
addr, addr,
port, port,
int(t_current/self.period), int(t_current/self.period),

View File

@ -18,13 +18,14 @@ class control_logic(design.design):
Dynamically generated Control logic for the total SRAM circuit. Dynamically generated Control logic for the total SRAM circuit.
""" """
def __init__(self, num_rows, port_type="rw"): def __init__(self, num_rows, words_per_row, port_type="rw"):
""" Constructor """ """ Constructor """
name = "control_logic_" + port_type name = "control_logic_" + port_type
design.design.__init__(self, name) design.design.__init__(self, name)
debug.info(1, "Creating {}".format(name)) debug.info(1, "Creating {}".format(name))
self.num_rows = num_rows self.num_rows = num_rows
self.words_per_row = words_per_row
self.port_type = port_type self.port_type = port_type
if self.port_type == "rw": if self.port_type == "rw":
@ -92,13 +93,24 @@ class control_logic(design.design):
from importlib import reload from importlib import reload
c = reload(__import__(OPTS.replica_bitline)) c = reload(__import__(OPTS.replica_bitline))
replica_bitline = getattr(c, OPTS.replica_bitline) replica_bitline = getattr(c, OPTS.replica_bitline)
# FIXME: These should be tuned according to the size!
delay_stages = 4 # Must be non-inverting delay_stages, delay_fanout = self.get_delay_chain_size()
delay_fanout = 3 # This can be anything >=2
bitcell_loads = int(math.ceil(self.num_rows / 2.0)) bitcell_loads = int(math.ceil(self.num_rows / 2.0))
self.replica_bitline = replica_bitline(delay_stages, delay_fanout, bitcell_loads, name="replica_bitline_"+self.port_type) self.replica_bitline = replica_bitline(delay_stages, delay_fanout, bitcell_loads, name="replica_bitline_"+self.port_type)
self.add_mod(self.replica_bitline) self.add_mod(self.replica_bitline)
def get_delay_chain_size(self):
"""Determine the size of the delay chain used for the Sense Amp Enable """
# FIXME: These should be tuned according to the additional size parameters
delay_fanout = 3 # This can be anything >=2
# Delay stages Must be non-inverting
if self.words_per_row >= 8:
delay_stages = 8
elif self.words_per_row == 4:
delay_stages = 6
else:
delay_stages = 4
return (delay_stages, delay_fanout)
def setup_signal_busses(self): def setup_signal_busses(self):
""" Setup bus names, determine the size of the busses etc """ """ Setup bus names, determine the size of the busses etc """

View File

@ -189,15 +189,65 @@ class replica_bitline(design.design):
if pin.layer != "metal1": if pin.layer != "metal1":
continue continue
self.add_path("metal1", [pin_right, pin_extension]) pin_width_ydir = pin.uy()-pin.by()
#Width is set to pin y width to avoid DRC issues with m1 gaps
self.add_path("metal1", [pin_right, pin_extension], pin_width_ydir)
self.add_power_pin("gnd", pin_extension) self.add_power_pin("gnd", pin_extension)
# for multiport, need to short wordlines to each other so they all connect to gnd # for multiport, need to short wordlines to each other so they all connect to gnd.
wl_last = self.wl_list[self.total_ports-1]+"_{}".format(row) wl_last = self.wl_list[self.total_ports-1]+"_{}".format(row)
pin_last = self.rbl_inst.get_pin(wl_last) pin_last = self.rbl_inst.get_pin(wl_last)
self.short_wordlines(pin, pin_last, "right", False, row, vector(self.m3_pitch,0))
def short_wordlines(self, wl_pin_a, wl_pin_b, pin_side, is_replica_cell, cell_row=0, offset_x_vec=None):
"""Connects the word lines together for a single bitcell. Also requires which side of the bitcell to short the pins."""
#Assumes input pins are wordlines. Also assumes the word lines are horizontal in metal1. Also assumes pins have same x coord.
#This is my (Hunter) first time editing layout in openram so this function is likely not optimal.
if self.total_ports > 1:
#1. Create vertical metal for all the bitlines to connect to
#m1 needs to be extended in the y directions, direction needs to be determined as every other cell is flipped
correct_y = vector(0, 0.5*drc("minwidth_metal1"))
#x spacing depends on the side being drawn. Unknown to me (Hunter) why the size of the space differs by the side.
#I assume this is related to how a wire is draw, but I have not investigated the issue.
if pin_side == "right":
correct_x = vector(0.5*drc("minwidth_metal1"), 0)
if offset_x_vec != None:
correct_x = offset_x_vec
else:
correct_x = vector(1.5*drc("minwidth_metal1"), 0)
if wl_pin_a.uy() > wl_pin_b.uy():
self.add_path("metal1", [wl_pin_a.rc()+correct_x+correct_y, wl_pin_b.rc()+correct_x-correct_y])
else:
self.add_path("metal1", [wl_pin_a.rc()+correct_x-correct_y, wl_pin_b.rc()+correct_x+correct_y])
elif pin_side == "left":
if offset_x_vec != None:
correct_x = offset_x_vec
else:
correct_x = vector(1.5*drc("minwidth_metal1"), 0)
if wl_pin_a.uy() > wl_pin_b.uy():
self.add_path("metal1", [wl_pin_a.lc()-correct_x+correct_y, wl_pin_b.lc()-correct_x-correct_y])
else:
self.add_path("metal1", [wl_pin_a.lc()-correct_x-correct_y, wl_pin_b.lc()-correct_x+correct_y])
else:
debug.error("Could not connect wordlines on specified input side={}".format(pin_side),1)
#2. Connect word lines horizontally. Only replica cell needs. Bitline loads currently already do this.
for port in range(self.total_ports):
if is_replica_cell:
wl = self.wl_list[port]
pin = self.rbc_inst.get_pin(wl)
else:
wl = self.wl_list[port]+"_{}".format(cell_row)
pin = self.rbl_inst.get_pin(wl)
if pin_side == "left":
self.add_path("metal1", [pin.lc()-correct_x, pin.lc()])
elif pin_side == "right":
self.add_path("metal1", [pin.rc()+correct_x, pin.rc()])
correct = vector(0.5*drc("minwidth_metal1"), 0)
self.add_path("metal1", [pin.rc()-correct, pin_last.rc()-correct])
def route_supplies(self): def route_supplies(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 """
@ -217,8 +267,13 @@ class replica_bitline(design.design):
# Replica bitcell needs to be routed up to M3 # Replica bitcell needs to be routed up to M3
pin=self.rbc_inst.get_pin("vdd") pin=self.rbc_inst.get_pin("vdd")
# Don't rotate this via to vit in FreePDK45 # Don't rotate this via to vit in FreePDK45. In the custom cell, the pin cannot be placed
self.add_power_pin("vdd", pin.center(), rotate=0) # directly on vdd or there will be a drc error with a wordline. Place the pin slightly farther
# away then route to it. A better solution would be to rotate the m1 in the via or move the pin
# a m1_pitch below the entire cell.
pin_extension = pin.center() - vector(0,self.m1_pitch)
self.add_power_pin("vdd", pin_extension, rotate=0)
self.add_path("metal1", [pin.center(), pin_extension])
for pin in self.rbc_inst.get_pins("gnd"): for pin in self.rbc_inst.get_pins("gnd"):
self.add_power_pin("gnd", pin.center()) self.add_power_pin("gnd", pin.center())
@ -267,9 +322,10 @@ class replica_bitline(design.design):
wl_last = self.wl_list[self.total_ports-1] wl_last = self.wl_list[self.total_ports-1]
pin = self.rbc_inst.get_pin(wl) pin = self.rbc_inst.get_pin(wl)
pin_last = self.rbc_inst.get_pin(wl_last) pin_last = self.rbc_inst.get_pin(wl_last)
x_offset = self.short_wordlines(pin, pin_last, "left", True)
correct = vector(0.5*drc("minwidth_metal1"), 0) #correct = vector(0.5*drc("minwidth_metal1"), 0)
self.add_path("metal1", [pin.lc()+correct, pin_last.lc()+correct]) #self.add_path("metal1", [pin.lc()+correct, pin_last.lc()+correct])
# DRAIN ROUTE # DRAIN ROUTE
# Route the drain to the vdd rail # Route the drain to the vdd rail

View File

@ -25,6 +25,7 @@ class sense_amp(design.design):
def input_load(self): def input_load(self):
#Input load for the bitlines which are connected to the source/drain of a TX. Not the selects. #Input load for the bitlines which are connected to the source/drain of a TX. Not the selects.
from tech import spice, parameter
bitline_pmos_size = 8 #FIXME: This should be set somewhere and referenced. Probably in tech file. bitline_pmos_size = 8 #FIXME: This should be set somewhere and referenced. Probably in tech file.
return spice["min_tx_drain_c"]*(bitline_pmos_size/parameter["min_tx_size"])#ff return spice["min_tx_drain_c"]*(bitline_pmos_size/parameter["min_tx_size"])#ff

View File

@ -218,7 +218,7 @@ class single_level_column_mux_array(design.design):
rotate=90) rotate=90)
def analytical_delay(self, vdd, slew, load=0.0): def analytical_delay(self, vdd, slew, load=0.0):
from tech import spice from tech import spice, parameter
r = spice["min_tx_r"]/(self.mux.ptx_width/parameter["min_tx_size"]) r = spice["min_tx_r"]/(self.mux.ptx_width/parameter["min_tx_size"])
#Drains of mux transistors make up capacitance. #Drains of mux transistors make up capacitance.
c_para = spice["min_tx_drain_c"]*(self.mux.ptx_width/parameter["min_tx_size"])*self.words_per_row#ff c_para = spice["min_tx_drain_c"]*(self.mux.ptx_width/parameter["min_tx_size"])*self.words_per_row#ff

View File

@ -223,13 +223,13 @@ class sram_base(design):
from control_logic import control_logic from control_logic import control_logic
# Create the control logic module for each port type # Create the control logic module for each port type
if OPTS.num_rw_ports>0: if OPTS.num_rw_ports>0:
self.control_logic = self.control_logic_rw = control_logic(num_rows=self.num_rows, port_type="rw") self.control_logic = self.control_logic_rw = control_logic(num_rows=self.num_rows, words_per_row=self.words_per_row, port_type="rw")
self.add_mod(self.control_logic_rw) self.add_mod(self.control_logic_rw)
if OPTS.num_w_ports>0: if OPTS.num_w_ports>0:
self.control_logic_w = control_logic(num_rows=self.num_rows, port_type="w") self.control_logic_w = control_logic(num_rows=self.num_rows, words_per_row=self.words_per_row, port_type="w")
self.add_mod(self.control_logic_w) self.add_mod(self.control_logic_w)
if OPTS.num_r_ports>0: if OPTS.num_r_ports>0:
self.control_logic_r = control_logic(num_rows=self.num_rows, port_type="r") self.control_logic_r = control_logic(num_rows=self.num_rows, words_per_row=self.words_per_row, port_type="r")
self.add_mod(self.control_logic_r) self.add_mod(self.control_logic_r)
# Create the address and control flops (but not the clk) # Create the address and control flops (but not the clk)

View File

@ -24,6 +24,7 @@ class replica_bitline_test(openram_test):
debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows)) debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows))
a = replica_bitline.replica_bitline(stages,fanout,rows) a = replica_bitline.replica_bitline(stages,fanout,rows)
self.local_check(a) self.local_check(a)
#debug.error("Exiting...", 1)
stages=8 stages=8
rows=100 rows=100
@ -31,7 +32,26 @@ class replica_bitline_test(openram_test):
a = replica_bitline.replica_bitline(stages,fanout,rows) a = replica_bitline.replica_bitline(stages,fanout,rows)
self.local_check(a) self.local_check(a)
# check replica bitline in multi-port #check replica bitline in handmade multi-port 1rw+1r cell
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.replica_bitcell = "replica_bitcell_1rw_1r"
OPTS.num_rw_ports = 1
OPTS.num_w_ports = 0
OPTS.num_r_ports = 1
stages=4
fanout=4
rows=13
debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows))
a = replica_bitline.replica_bitline(stages,fanout,rows)
self.local_check(a)
stages=8
rows=100
debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows))
a = replica_bitline.replica_bitline(stages,fanout,rows)
self.local_check(a)
# check replica bitline in pbitcell multi-port
OPTS.bitcell = "pbitcell" OPTS.bitcell = "pbitcell"
OPTS.replica_bitcell = "replica_pbitcell" OPTS.replica_bitcell = "replica_pbitcell"
OPTS.num_rw_ports = 1 OPTS.num_rw_ports = 1

View File

@ -20,7 +20,7 @@ class control_logic_test(openram_test):
# check control logic for single port # check control logic for single port
debug.info(1, "Testing sample for control_logic") debug.info(1, "Testing sample for control_logic")
a = control_logic.control_logic(num_rows=128) a = control_logic.control_logic(num_rows=128, words_per_row=1)
self.local_check(a) self.local_check(a)
# check control logic for multi-port # check control logic for multi-port
@ -31,7 +31,7 @@ class control_logic_test(openram_test):
OPTS.num_r_ports = 0 OPTS.num_r_ports = 0
debug.info(1, "Testing sample for control_logic for multiport") debug.info(1, "Testing sample for control_logic for multiport")
a = control_logic.control_logic(num_rows=128) a = control_logic.control_logic(num_rows=128, words_per_row=1)
self.local_check(a) self.local_check(a)
# Check port specific control logic # Check port specific control logic
@ -40,15 +40,15 @@ class control_logic_test(openram_test):
OPTS.num_r_ports = 1 OPTS.num_r_ports = 1
debug.info(1, "Testing sample for control_logic for multiport, only write control logic") debug.info(1, "Testing sample for control_logic for multiport, only write control logic")
a = control_logic.control_logic(num_rows=128, port_type="rw") a = control_logic.control_logic(num_rows=128, words_per_row=1, port_type="rw")
self.local_check(a) self.local_check(a)
debug.info(1, "Testing sample for control_logic for multiport, only write control logic") debug.info(1, "Testing sample for control_logic for multiport, only write control logic")
a = control_logic.control_logic(num_rows=128, port_type="w") a = control_logic.control_logic(num_rows=128, words_per_row=1, port_type="w")
self.local_check(a) self.local_check(a)
debug.info(1, "Testing sample for control_logic for multiport, only read control logic") debug.info(1, "Testing sample for control_logic for multiport, only read control logic")
a = control_logic.control_logic(num_rows=128, port_type="r") a = control_logic.control_logic(num_rows=128, words_per_row=1, port_type="r")
self.local_check(a) self.local_check(a)
globals.end_openram() globals.end_openram()

View File

@ -20,6 +20,9 @@ class psram_1bank_2mux_func_test(openram_test):
OPTS.netlist_only = True OPTS.netlist_only = True
OPTS.bitcell = "pbitcell" OPTS.bitcell = "pbitcell"
OPTS.replica_bitcell="replica_pbitcell" OPTS.replica_bitcell="replica_pbitcell"
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 1
# This is a hack to reload the characterizer __init__ with the spice version # This is a hack to reload the characterizer __init__ with the spice version
from importlib import reload from importlib import reload

View File

@ -11,7 +11,7 @@ import globals
from globals import OPTS from globals import OPTS
import debug import debug
@unittest.skip("SKIPPING 22_psram_1bank_4mux_func_test") #@unittest.skip("SKIPPING 22_psram_1bank_4mux_func_test")
class psram_1bank_4mux_func_test(openram_test): class psram_1bank_4mux_func_test(openram_test):
def runTest(self): def runTest(self):
@ -20,6 +20,9 @@ class psram_1bank_4mux_func_test(openram_test):
OPTS.netlist_only = True OPTS.netlist_only = True
OPTS.bitcell = "pbitcell" OPTS.bitcell = "pbitcell"
OPTS.replica_bitcell="replica_pbitcell" OPTS.replica_bitcell="replica_pbitcell"
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 1
# This is a hack to reload the characterizer __init__ with the spice version # This is a hack to reload the characterizer __init__ with the spice version
from importlib import reload from importlib import reload

View File

@ -11,7 +11,7 @@ import globals
from globals import OPTS from globals import OPTS
import debug import debug
@unittest.skip("SKIPPING 22_psram_1bank_8mux_func_test") #@unittest.skip("SKIPPING 22_psram_1bank_8mux_func_test")
class psram_1bank_8mux_func_test(openram_test): class psram_1bank_8mux_func_test(openram_test):
def runTest(self): def runTest(self):
@ -20,6 +20,9 @@ class psram_1bank_8mux_func_test(openram_test):
OPTS.netlist_only = True OPTS.netlist_only = True
OPTS.bitcell = "pbitcell" OPTS.bitcell = "pbitcell"
OPTS.replica_bitcell="replica_pbitcell" OPTS.replica_bitcell="replica_pbitcell"
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 1
# This is a hack to reload the characterizer __init__ with the spice version # This is a hack to reload the characterizer __init__ with the spice version
from importlib import reload from importlib import reload
@ -29,7 +32,7 @@ class psram_1bank_8mux_func_test(openram_test):
from sram import sram from sram import sram
from sram_config import sram_config from sram_config import sram_config
c = sram_config(word_size=4, c = sram_config(word_size=4,
num_words=512, num_words=256,
num_banks=1) num_banks=1)
c.words_per_row=8 c.words_per_row=8
debug.info(1, "Functional test for psram with {} bit words, {} words, {} words per row, {} banks".format(c.word_size, debug.info(1, "Functional test for psram with {} bit words, {} words, {} words per row, {} banks".format(c.word_size,

View File

@ -20,6 +20,9 @@ class psram_1bank_nomux_func_test(openram_test):
OPTS.netlist_only = True OPTS.netlist_only = True
OPTS.bitcell = "pbitcell" OPTS.bitcell = "pbitcell"
OPTS.replica_bitcell="replica_pbitcell" OPTS.replica_bitcell="replica_pbitcell"
OPTS.num_rw_ports = 1
OPTS.num_r_ports = 1
OPTS.num_w_ports = 1
# This is a hack to reload the characterizer __init__ with the spice version # This is a hack to reload the characterizer __init__ with the spice version
from importlib import reload from importlib import reload

View File

@ -11,7 +11,7 @@ import globals
from globals import OPTS from globals import OPTS
import debug import debug
@unittest.skip("SKIPPING 22_sram_1bank_4mux_func_test") #@unittest.skip("SKIPPING 22_sram_1bank_4mux_func_test")
class sram_1bank_4mux_func_test(openram_test): class sram_1bank_4mux_func_test(openram_test):
def runTest(self): def runTest(self):

View File

@ -11,7 +11,7 @@ import globals
from globals import OPTS from globals import OPTS
import debug import debug
@unittest.skip("SKIPPING 22_sram_1bank_8mux_func_test") #@unittest.skip("SKIPPING 22_sram_1bank_8mux_func_test")
class sram_1bank_8mux_func_test(openram_test): class sram_1bank_8mux_func_test(openram_test):
def runTest(self): def runTest(self):
@ -30,7 +30,7 @@ class sram_1bank_8mux_func_test(openram_test):
from sram import sram from sram import sram
from sram_config import sram_config from sram_config import sram_config
c = sram_config(word_size=4, c = sram_config(word_size=4,
num_words=512, num_words=256,
num_banks=1) num_banks=1)
c.words_per_row=8 c.words_per_row=8
debug.info(1, "Functional test for sram with {} bit words, {} words, {} words per row, {} banks".format(c.word_size, debug.info(1, "Functional test for sram with {} bit words, {} words, {} words per row, {} banks".format(c.word_size,
@ -39,6 +39,7 @@ class sram_1bank_8mux_func_test(openram_test):
c.num_banks)) c.num_banks))
s = sram(c, name="sram") s = sram(c, name="sram")
tempspice = OPTS.openram_temp + "temp.sp" tempspice = OPTS.openram_temp + "temp.sp"
tempspice = OPTS.openram_temp + "temp.sp"
s.sp_write(tempspice) s.sp_write(tempspice)
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0]) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])

View File

@ -0,0 +1,60 @@
#!/usr/bin/env python3
"""
Run a functioal test on 1 bank SRAM
"""
import unittest
from testutils import header,openram_test
import sys,os
sys.path.append(os.path.join(sys.path[0],".."))
import globals
from globals import OPTS
import debug
#@unittest.skip("SKIPPING 22_sram_1rw_1r_1bank_nomux_func_test")
class psram_1bank_nomux_func_test(openram_test):
def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
OPTS.analytical_delay = False
OPTS.netlist_only = True
OPTS.bitcell = "bitcell_1rw_1r"
OPTS.replica_bitcell = "replica_bitcell_1rw_1r"
OPTS.num_rw_ports = 1
OPTS.num_w_ports = 0
OPTS.num_r_ports = 1
# This is a hack to reload the characterizer __init__ with the spice version
from importlib import reload
import characterizer
reload(characterizer)
from characterizer import functional
from sram import sram
from sram_config import sram_config
c = sram_config(word_size=4,
num_words=32,
num_banks=1)
c.words_per_row=1
debug.info(1, "Functional test for sram 1rw,1r with {} bit words, {} words, {} words per row, {} banks".format(c.word_size,
c.num_words,
c.words_per_row,
c.num_banks))
s = sram(c, name="sram")
tempspice = OPTS.openram_temp + "temp.sp"
s.sp_write(tempspice)
corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
f = functional(s.s, tempspice, corner)
f.num_cycles = 10
(fail, error) = f.run()
self.assertTrue(fail,error)
globals.end_openram()
# instantiate a copy 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()

Binary file not shown.

View File

@ -0,0 +1,14 @@
.SUBCKT replica_cell_1rw_1r bl0 br0 bl1 br1 wl0 wl1 vdd gnd
MM9 RA_to_R_right wl1 br1 gnd NMOS_VTG W=180.0n L=50n m=1
MM8 RA_to_R_right Q gnd gnd NMOS_VTG W=180.0n L=50n m=1
MM7 RA_to_R_left vdd gnd gnd NMOS_VTG W=180.0n L=50n m=1
MM6 RA_to_R_left wl1 bl1 gnd NMOS_VTG W=180.0n L=50n m=1
MM5 Q wl0 bl0 gnd NMOS_VTG W=135.00n L=50n m=1
MM4 vdd wl0 br0 gnd NMOS_VTG W=135.00n L=50n m=1
MM1 Q vdd gnd gnd NMOS_VTG W=270.0n L=50n m=1
MM0 vdd Q gnd gnd NMOS_VTG W=270.0n L=50n m=1
MM3 Q vdd vdd vdd PMOS_VTG W=90n L=50n m=1
MM2 vdd Q vdd vdd PMOS_VTG W=90n L=50n m=1
.ENDS

Binary file not shown.

View File

@ -1,6 +1,6 @@
magic magic
tech scmos tech scmos
timestamp 1540504134 timestamp 1541193956
<< nwell >> << nwell >>
rect 0 50 54 79 rect 0 50 54 79
<< pwell >> << pwell >>
@ -139,10 +139,10 @@ rect 0 0 54 74
<< labels >> << labels >>
rlabel metal1 27 4 27 4 1 wl1 rlabel metal1 27 4 27 4 1 wl1
rlabel psubstratepcontact 27 11 27 11 1 gnd rlabel psubstratepcontact 27 11 27 11 1 gnd
rlabel m2contact 27 74 27 74 5 vdd
rlabel metal1 19 67 19 67 1 wl0 rlabel metal1 19 67 19 67 1 wl0
rlabel metal2 4 7 4 7 2 bl0 rlabel metal2 4 7 4 7 2 bl0
rlabel metal2 11 7 11 7 1 bl1 rlabel metal2 11 7 11 7 1 bl1
rlabel metal2 43 7 43 7 1 br1 rlabel metal2 43 7 43 7 1 br1
rlabel metal2 50 7 50 7 8 br0 rlabel metal2 50 7 50 7 8 br0
rlabel metal1 19 74 19 74 5 vdd
<< end >> << end >>

View File

@ -0,0 +1,149 @@
magic
tech scmos
timestamp 1541194096
<< nwell >>
rect 0 50 54 79
<< pwell >>
rect 0 0 54 50
<< ntransistor >>
rect 14 35 16 41
rect 22 29 24 41
rect 30 29 32 41
rect 38 35 40 41
rect 14 17 16 25
rect 22 17 24 25
rect 30 17 32 25
rect 38 17 40 25
<< ptransistor >>
rect 22 58 24 62
rect 30 58 32 62
<< ndiffusion >>
rect 9 39 14 41
rect 13 35 14 39
rect 16 35 17 41
rect 21 33 22 41
rect 17 29 22 33
rect 24 29 25 41
rect 29 29 30 41
rect 32 33 33 41
rect 37 35 38 41
rect 40 39 45 41
rect 40 35 41 39
rect 32 29 37 33
rect 9 23 14 25
rect 13 19 14 23
rect 9 17 14 19
rect 16 17 22 25
rect 24 17 25 25
rect 29 17 30 25
rect 32 17 38 25
rect 40 23 45 25
rect 40 19 41 23
rect 40 17 45 19
<< pdiffusion >>
rect 21 58 22 62
rect 24 58 25 62
rect 29 58 30 62
rect 32 58 33 62
<< ndcontact >>
rect 9 35 13 39
rect 17 33 21 41
rect 25 29 29 41
rect 33 33 37 41
rect 41 35 45 39
rect 9 19 13 23
rect 25 17 29 25
rect 41 19 45 23
<< pdcontact >>
rect 17 58 21 62
rect 25 58 29 62
rect 33 58 37 62
<< psubstratepcontact >>
rect 25 9 29 13
<< nsubstratencontact >>
rect 25 72 29 76
<< polysilicon >>
rect 22 62 24 64
rect 30 62 32 64
rect 22 48 24 58
rect 30 55 32 58
rect 31 51 32 55
rect 14 41 16 46
rect 22 44 23 48
rect 22 41 24 44
rect 30 41 32 51
rect 38 41 40 46
rect 14 33 16 35
rect 38 33 40 35
rect 14 25 16 26
rect 22 25 24 29
rect 30 25 32 29
rect 38 25 40 26
rect 14 15 16 17
rect 22 15 24 17
rect 30 15 32 17
rect 38 15 40 17
<< polycontact >>
rect 27 51 31 55
rect 10 42 14 46
rect 23 44 27 48
rect 40 42 44 46
rect 12 26 16 30
rect 38 26 42 30
<< metal1 >>
rect 0 72 25 76
rect 29 72 54 76
rect 0 65 54 69
rect 10 46 14 65
rect 29 58 33 62
rect 17 55 20 58
rect 17 51 27 55
rect 17 41 20 51
rect 34 48 37 58
rect 27 44 37 48
rect 34 41 37 44
rect 40 46 44 65
rect 6 35 9 39
rect 45 35 48 39
rect 25 25 29 29
rect 25 13 29 17
rect 0 9 25 13
rect 29 9 54 13
rect 0 2 16 6
rect 20 2 34 6
rect 38 2 54 6
<< m2contact >>
rect 25 72 29 76
rect 25 58 29 62
rect 2 35 6 39
rect 16 26 20 30
rect 48 35 52 39
rect 34 26 38 30
rect 9 19 13 23
rect 41 19 45 23
rect 16 2 20 6
rect 34 2 38 6
<< metal2 >>
rect 2 39 6 76
rect 2 0 6 35
rect 9 23 13 76
rect 25 62 29 72
rect 9 0 13 19
rect 16 6 20 26
rect 34 6 38 26
rect 41 23 45 76
rect 41 0 45 19
rect 48 39 52 76
rect 48 0 52 35
<< bb >>
rect 0 0 54 74
<< labels >>
rlabel metal1 27 4 27 4 1 wl1
rlabel psubstratepcontact 27 11 27 11 1 gnd
rlabel metal1 19 67 19 67 1 wl0
rlabel metal2 4 7 4 7 2 bl0
rlabel metal2 11 7 11 7 1 bl1
rlabel metal2 43 7 43 7 1 br1
rlabel metal2 50 7 50 7 8 br0
rlabel metal1 19 74 19 74 5 vdd
<< end >>

View File

@ -0,0 +1,14 @@
.SUBCKT replica_cell_1rw_1r bl0 br0 bl1 br1 wl0 wl1 vdd gnd
MM9 RA_to_R_right wl1 br1 gnd n w=1.6u l=0.4u
MM8 RA_to_R_right Q gnd gnd n w=1.6u l=0.4u
MM7 RA_to_R_left vdd gnd gnd n w=1.6u l=0.4u
MM6 RA_to_R_left wl1 bl1 gnd n w=1.6u l=0.4u
MM5 Q wl0 bl0 gnd n w=1.2u l=0.4u
MM4 vdd wl0 br0 gnd n w=1.2u l=0.4u
MM1 Q vdd gnd gnd n w=2.4u l=0.4u
MM0 vdd Q gnd gnd n w=2.4u l=0.4u
MM3 Q vdd vdd vdd p w=0.8u l=0.4u
MM2 vdd Q vdd vdd p w=0.8u l=0.4u
.ENDS