mirror of https://github.com/VLSIDA/OpenRAM.git
Merge branch 'dev' of https://github.com/VLSIDA/PrivateRAM into dev
This commit is contained in:
commit
52a4ba711b
|
|
@ -17,6 +17,7 @@ class trim_spice():
|
|||
# Load the file into a buffer for performance
|
||||
sp = open(self.sp_file, "r")
|
||||
self.spice = sp.readlines()
|
||||
sp.close()
|
||||
for i in range(len(self.spice)):
|
||||
self.spice[i] = self.spice[i].rstrip(" \n")
|
||||
|
||||
|
|
@ -97,6 +98,7 @@ class trim_spice():
|
|||
# Finally, write out the buffer as the new reduced file
|
||||
sp = open(self.reduced_spfile, "w")
|
||||
sp.write("\n".join(self.sp_buffer))
|
||||
sp.close()
|
||||
|
||||
|
||||
def remove_insts(self, subckt_name, keep_inst_list):
|
||||
|
|
|
|||
|
|
@ -33,9 +33,8 @@ class sense_amp_array(design.design):
|
|||
|
||||
def add_pins(self):
|
||||
|
||||
for i in range(0,self.row_size,self.words_per_row):
|
||||
index = int(i/self.words_per_row)
|
||||
self.add_pin("data[{0}]".format(index))
|
||||
for i in range(0,self.word_size):
|
||||
self.add_pin("data[{0}]".format(i))
|
||||
self.add_pin("bl[{0}]".format(i))
|
||||
self.add_pin("br[{0}]".format(i))
|
||||
|
||||
|
|
@ -55,7 +54,7 @@ class sense_amp_array(design.design):
|
|||
br_pin = self.amp.get_pin("br")
|
||||
dout_pin = self.amp.get_pin("dout")
|
||||
|
||||
for i in range(0,self.row_size,self.words_per_row):
|
||||
for i in range(0,self.word_size):
|
||||
|
||||
name = "sa_d{0}".format(i)
|
||||
amp_position = vector(self.amp.width * i, 0)
|
||||
|
|
@ -64,14 +63,12 @@ class sense_amp_array(design.design):
|
|||
br_offset = amp_position + br_pin.ll().scale(1,0)
|
||||
dout_offset = amp_position + dout_pin.ll()
|
||||
|
||||
index = int(i/self.words_per_row)
|
||||
|
||||
inst = self.add_inst(name=name,
|
||||
mod=self.amp,
|
||||
offset=amp_position)
|
||||
self.connect_inst(["bl[{0}]".format(i),
|
||||
"br[{0}]".format(i),
|
||||
"data[{0}]".format(index),
|
||||
"data[{0}]".format(i),
|
||||
"en", "vdd", "gnd"])
|
||||
|
||||
|
||||
|
|
@ -100,7 +97,7 @@ class sense_amp_array(design.design):
|
|||
width=br_pin.width(),
|
||||
height=br_pin.height())
|
||||
|
||||
self.add_layout_pin(text="data[{0}]".format(index),
|
||||
self.add_layout_pin(text="data[{0}]".format(i),
|
||||
layer="metal2",
|
||||
offset=dout_offset,
|
||||
width=dout_pin.width(),
|
||||
|
|
|
|||
|
|
@ -15,11 +15,8 @@ class pbitcell(pgate.pgate):
|
|||
width = None
|
||||
height = None
|
||||
|
||||
unique_id = 1
|
||||
|
||||
def __init__(self, num_readwrite=OPTS.rw_ports, num_write=OPTS.w_ports, num_read=OPTS.r_ports):
|
||||
name = "pbitcell_{0}RW_{1}W_{2}R_{3}".format(num_readwrite, num_write, num_read, pbitcell.unique_id)
|
||||
pbitcell.unique_id += 1
|
||||
name = "pbitcell_{0}RW_{1}W_{2}R".format(num_readwrite, num_write, num_read)
|
||||
pgate.pgate.__init__(self, name)
|
||||
debug.info(2, "create a multi-port bitcell with {0} write ports and {1} read ports".format(num_write, num_read))
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class single_level_column_mux(design.design):
|
|||
self.add_ptx()
|
||||
self.pin_height = 2*self.m2_width
|
||||
self.width = self.bitcell.width
|
||||
self.height = self.nmos2.uy() + self.pin_height
|
||||
self.height = self.nmos_upper.uy() + self.pin_height
|
||||
self.connect_poly()
|
||||
self.add_bitline_pins()
|
||||
self.connect_bitlines()
|
||||
|
|
@ -67,32 +67,32 @@ class single_level_column_mux(design.design):
|
|||
def add_ptx(self):
|
||||
""" Create the two pass gate NMOS transistors to switch the bitlines"""
|
||||
|
||||
# Adds nmos1,nmos2 to the module
|
||||
# Adds nmos_lower,nmos_upper to the module
|
||||
self.nmos = ptx(width=self.ptx_width)
|
||||
self.add_mod(self.nmos)
|
||||
|
||||
# Space it in the center
|
||||
nmos1_position = self.nmos.active_offset.scale(0,1) + vector(0.5*self.bitcell.width-0.5*self.nmos.active_width,0)
|
||||
self.nmos1=self.add_inst(name="mux_tx1",
|
||||
nmos_lower_position = self.nmos.active_offset.scale(0,1) + vector(0.5*self.bitcell.width-0.5*self.nmos.active_width,0)
|
||||
self.nmos_lower=self.add_inst(name="mux_tx1",
|
||||
mod=self.nmos,
|
||||
offset=nmos1_position)
|
||||
offset=nmos_lower_position)
|
||||
self.connect_inst(["bl", "sel", "bl_out", "gnd"])
|
||||
|
||||
# This aligns it directly above the other tx with gates abutting
|
||||
nmos2_position = nmos1_position + vector(0,self.nmos.active_height + self.poly_space)
|
||||
self.nmos2=self.add_inst(name="mux_tx2",
|
||||
nmos_upper_position = nmos_lower_position + vector(0,self.nmos.active_height + self.poly_space)
|
||||
self.nmos_upper=self.add_inst(name="mux_tx2",
|
||||
mod=self.nmos,
|
||||
offset=nmos2_position)
|
||||
offset=nmos_upper_position)
|
||||
self.connect_inst(["br", "sel", "br_out", "gnd"])
|
||||
|
||||
|
||||
def connect_poly(self):
|
||||
""" Connect the poly gate of the two pass transistors """
|
||||
|
||||
height=self.nmos2.get_pin("G").uy() - self.nmos1.get_pin("G").by()
|
||||
height=self.nmos_upper.get_pin("G").uy() - self.nmos_lower.get_pin("G").by()
|
||||
self.add_layout_pin(text="sel",
|
||||
layer="poly",
|
||||
offset=self.nmos1.get_pin("G").ll(),
|
||||
offset=self.nmos_lower.get_pin("G").ll(),
|
||||
height=height)
|
||||
|
||||
|
||||
|
|
@ -105,36 +105,36 @@ class single_level_column_mux(design.design):
|
|||
br_out_pin = self.get_pin("br_out")
|
||||
|
||||
# These are on metal1
|
||||
nmos1_s_pin = self.nmos1.get_pin("S")
|
||||
nmos1_d_pin = self.nmos1.get_pin("D")
|
||||
nmos2_s_pin = self.nmos2.get_pin("S")
|
||||
nmos2_d_pin = self.nmos2.get_pin("D")
|
||||
nmos_lower_s_pin = self.nmos_lower.get_pin("S")
|
||||
nmos_lower_d_pin = self.nmos_lower.get_pin("D")
|
||||
nmos_upper_s_pin = self.nmos_upper.get_pin("S")
|
||||
nmos_upper_d_pin = self.nmos_upper.get_pin("D")
|
||||
|
||||
# Add vias to bl, br_out, nmos2/S, nmos1/D
|
||||
# Add vias to bl, br_out, nmos_upper/S, nmos_lower/D
|
||||
self.add_via_center(layers=("metal1","via1","metal2"),
|
||||
offset=bl_pin.bc())
|
||||
self.add_via_center(layers=("metal1","via1","metal2"),
|
||||
offset=br_out_pin.uc())
|
||||
self.add_via_center(layers=("metal1","via1","metal2"),
|
||||
offset=nmos2_s_pin.center())
|
||||
offset=nmos_upper_s_pin.center())
|
||||
self.add_via_center(layers=("metal1","via1","metal2"),
|
||||
offset=nmos1_d_pin.center())
|
||||
offset=nmos_lower_d_pin.center())
|
||||
|
||||
# bl -> nmos2/D on metal1
|
||||
# bl_out -> nmos2/S on metal2
|
||||
self.add_path("metal1",[bl_pin.ll(), vector(nmos2_d_pin.cx(),bl_pin.by()), nmos2_d_pin.center()])
|
||||
# bl -> nmos_upper/D on metal1
|
||||
# bl_out -> nmos_upper/S on metal2
|
||||
self.add_path("metal1",[bl_pin.ll(), vector(nmos_upper_d_pin.cx(),bl_pin.by()), nmos_upper_d_pin.center()])
|
||||
# halfway up, move over
|
||||
mid1 = bl_out_pin.uc().scale(1,0.5)+nmos2_s_pin.bc().scale(0,0.5)
|
||||
mid2 = bl_out_pin.uc().scale(0,0.5)+nmos2_s_pin.bc().scale(1,0.5)
|
||||
self.add_path("metal2",[bl_out_pin.uc(), mid1, mid2, nmos2_s_pin.bc()])
|
||||
mid1 = bl_out_pin.uc().scale(1,0.5)+nmos_upper_s_pin.bc().scale(0,0.5)
|
||||
mid2 = bl_out_pin.uc().scale(0,0.5)+nmos_upper_s_pin.bc().scale(1,0.5)
|
||||
self.add_path("metal2",[bl_out_pin.uc(), mid1, mid2, nmos_upper_s_pin.bc()])
|
||||
|
||||
# br -> nmos1/D on metal2
|
||||
# br_out -> nmos1/S on metal1
|
||||
self.add_path("metal1",[br_out_pin.uc(), vector(nmos1_s_pin.cx(),br_out_pin.uy()), nmos1_s_pin.center()])
|
||||
# br -> nmos_lower/D on metal2
|
||||
# br_out -> nmos_lower/S on metal1
|
||||
self.add_path("metal1",[br_out_pin.uc(), vector(nmos_lower_s_pin.cx(),br_out_pin.uy()), nmos_lower_s_pin.center()])
|
||||
# halfway up, move over
|
||||
mid1 = br_pin.bc().scale(1,0.5)+nmos1_d_pin.uc().scale(0,0.5)
|
||||
mid2 = br_pin.bc().scale(0,0.5)+nmos1_d_pin.uc().scale(1,0.5)
|
||||
self.add_path("metal2",[br_pin.bc(), mid1, mid2, nmos1_d_pin.uc()])
|
||||
mid1 = br_pin.bc().scale(1,0.5)+nmos_lower_d_pin.uc().scale(0,0.5)
|
||||
mid2 = br_pin.bc().scale(0,0.5)+nmos_lower_d_pin.uc().scale(1,0.5)
|
||||
self.add_path("metal2",[br_pin.bc(), mid1, mid2, nmos_lower_d_pin.uc()])
|
||||
|
||||
|
||||
def add_wells(self):
|
||||
|
|
@ -144,11 +144,11 @@ class single_level_column_mux(design.design):
|
|||
"""
|
||||
|
||||
# Add it to the right, aligned in between the two tx
|
||||
active_pos = self.nmos2.lr().scale(0,0.5) + self.nmos1.ur().scale(1,0.5)
|
||||
self.add_via_center(layers=("active", "contact", "metal1"),
|
||||
offset=active_pos,
|
||||
implant_type="p",
|
||||
well_type="p")
|
||||
active_pos = vector(self.bitcell.width,self.nmos_upper.by())
|
||||
active_via = self.add_via_center(layers=("active", "contact", "metal1"),
|
||||
offset=active_pos,
|
||||
implant_type="p",
|
||||
well_type="p")
|
||||
|
||||
|
||||
# Add the M1->M2->M3 stack
|
||||
|
|
@ -159,6 +159,12 @@ class single_level_column_mux(design.design):
|
|||
self.add_layout_pin_rect_center(text="gnd",
|
||||
layer="metal3",
|
||||
offset=active_pos)
|
||||
|
||||
# Add well enclosure over all the tx and contact
|
||||
self.add_rect(layer="pwell",
|
||||
offset=vector(0,0),
|
||||
width=self.bitcell.width,
|
||||
height=self.height)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,154 +0,0 @@
|
|||
#!/usr/bin/env python2.7
|
||||
"Run a regresion test on a basic parameterized transistors"
|
||||
|
||||
import unittest
|
||||
from testutils import header
|
||||
import sys,os
|
||||
sys.path.append(os.path.join(sys.path[0],".."))
|
||||
import globals
|
||||
from globals import OPTS
|
||||
import debug
|
||||
|
||||
class ptx_test(unittest.TestCase):
|
||||
|
||||
def runTest(self):
|
||||
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
|
||||
global verify
|
||||
import verify
|
||||
OPTS.check_lvsdrc = False
|
||||
|
||||
import ptx
|
||||
import tech
|
||||
|
||||
debug.info(2, "Checking three fingers PMOS")
|
||||
fet = ptx.ptx(width=tech.drc["minwidth_tx"],
|
||||
mults=4,
|
||||
tx_type="pmos",
|
||||
connect_active=True,
|
||||
connect_poly=True)
|
||||
self.local_check(fet)
|
||||
|
||||
OPTS.check_lvsdrc = True
|
||||
globals.end_openram()
|
||||
|
||||
def add_mods(self, fet):
|
||||
self.create_contacts()
|
||||
self.add_well_extension(fet)
|
||||
self.add_wire_extension(fet)
|
||||
self.add_well_tiedown(fet)
|
||||
self.add_poly_tiedown(fet)
|
||||
|
||||
def create_contacts(self):
|
||||
layer_stack = ("active", "contact", "metal1")
|
||||
self.well_contact = contact.contact(layer_stack)
|
||||
|
||||
layer_stack = ("poly", "contact", "metal1")
|
||||
self.poly_contact = contact.contact(layer_stack)
|
||||
|
||||
def add_well_tiedown(self, fet):
|
||||
offset = [fet.active_contact_positions[0][0],
|
||||
fet.active_contact_positions[0][1] + fet.well_height]
|
||||
fet.add_inst(name="well_tap",
|
||||
mod=self.well_contact,
|
||||
offset=offset,
|
||||
mirror="R0",
|
||||
rotate=0)
|
||||
fet.well_contact = self.well_contact
|
||||
fet.well_tiedown_location = offset
|
||||
|
||||
def add_well_extension(self, fet):
|
||||
well_define = {"pmos": "nwell",
|
||||
"nmos": "pwell"}
|
||||
well_type = well_define[fet.tx_type]
|
||||
offset = getattr(fet,"{}_position".format(well_type))
|
||||
if tech.info["has_{0}".format(well_type)]:
|
||||
fet.add_rect(layerNumber=tech.layer[well_type],
|
||||
offset=offset,
|
||||
width=fet.well_width,
|
||||
height=2 * fet.well_height)
|
||||
fet.add_rect(layerNumber=tech.layer["{0}implant".format(fet.tx_type[0])],
|
||||
offset=offset,
|
||||
width=fet.well_width,
|
||||
height=2 * fet.well_height)
|
||||
fet.add_rect(layerNumber=tech.layer["vtg"],
|
||||
offset=offset,
|
||||
width=fet.well_width,
|
||||
height=2 * fet.well_height)
|
||||
|
||||
well_type = "{0}well".format(fet.tx_type[0])
|
||||
offset[1] = offset[1] - 3 * fet.well_height
|
||||
if tech.info["has_{0}".format(well_type)]:
|
||||
fet.add_rect(layerNumber=tech.layer[well_type],
|
||||
offset=offset,
|
||||
width=fet.well_width,
|
||||
height=3 * fet.well_height)
|
||||
fet.add_rect(layerNumber=tech.layer["{0}implant".format(well_define[fet.tx_type][
|
||||
0])],
|
||||
offset=offset,
|
||||
width=fet.well_width,
|
||||
height=3 * fet.well_height)
|
||||
fet.add_rect(layerNumber=tech.layer["vtg"],
|
||||
offset=offset,
|
||||
width=fet.well_width,
|
||||
height=3 * fet.well_height)
|
||||
|
||||
def add_wire_extension(self, fet):
|
||||
xcorrect = (fet.active_contact.width / 2) - (tech.drc["minwidth_metal1"] / 2)
|
||||
offset = [fet.active_contact_positions[0][0] + xcorrect,
|
||||
fet.active_contact_positions[0][1]]
|
||||
fet.add_rect(layerNumber=tech.layer["metal1"],
|
||||
offset=offset,
|
||||
width=tech.drc["minwidth_metal1"],
|
||||
height=fet.well_height)
|
||||
|
||||
offset = [fet.active_contact_positions[-1][0] + xcorrect,
|
||||
fet.active_contact_positions[-1][1] - 2 * fet.well_height]
|
||||
fet.add_rect(layerNumber=tech.layer["metal1"],
|
||||
offset=offset,
|
||||
width=tech.drc["minwidth_metal1"],
|
||||
height=2 * fet.well_height)
|
||||
|
||||
offset = [fet.poly_positions[-1][0],
|
||||
fet.poly_positions[-1][1] - (fet.well_height)]
|
||||
fet.add_rect(layerNumber=tech.layer["poly"],
|
||||
offset=offset,
|
||||
width=tech.drc["minwidth_poly"],
|
||||
height=fet.well_height)
|
||||
|
||||
def add_poly_tiedown(self, fet):
|
||||
xcorrect = abs(self.poly_contact.upper_layer_vertical_enclosure -
|
||||
self.poly_contact.lower_layer_vertical_enclosure)
|
||||
offset = [fet.poly_positions[-1][0] - xcorrect,
|
||||
fet.poly_positions[-1][1] - (fet.well_height)]
|
||||
fet.add_inst(name="poly_contact",
|
||||
mod=self.poly_contact,
|
||||
offset=offset,
|
||||
mirror="R270")
|
||||
|
||||
|
||||
offset = [fet.active_contact_positions[-1][0], fet.active_contact_positions
|
||||
[-1][1] - 2 * fet.well_height - self.well_contact.height]
|
||||
fet.poly_tiedown_location = offset
|
||||
fet.add_inst(name="n_tiedown",
|
||||
mod=self.well_contact,
|
||||
offset=offset)
|
||||
tech.ptx_port.add_custom_layer(fet)
|
||||
|
||||
def local_check(self, fet):
|
||||
tempspice = OPTS.openram_temp + "temp.sp"
|
||||
tempgds = OPTS.openram_temp + "temp.gds"
|
||||
|
||||
fet.sp_write(tempspice)
|
||||
fet.gds_write(tempgds)
|
||||
|
||||
self.assertFalse(verify.run_drc(fet.name, tempgds))
|
||||
|
||||
os.remove(tempspice)
|
||||
os.remove(tempgds)
|
||||
|
||||
# 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()
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
#!/usr/bin/env python2.7
|
||||
"""
|
||||
Run regresion tests on a parameterized bitcell
|
||||
"""
|
||||
|
||||
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
|
||||
|
||||
OPTS = globals.OPTS
|
||||
|
||||
#@unittest.skip("SKIPPING 04_pbitcell_1X_test")
|
||||
|
||||
|
||||
class pbitcell_test(openram_test):
|
||||
|
||||
def runTest(self):
|
||||
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
|
||||
global verify
|
||||
import verify
|
||||
OPTS.check_lvsdrc = False
|
||||
|
||||
import pbitcell
|
||||
import tech
|
||||
|
||||
debug.info(2, "Bitcell with 1 of each port: read/write, write, and read")
|
||||
tx = pbitcell.pbitcell(num_readwrite=1,num_write=1,num_read=1)
|
||||
self.local_check(tx)
|
||||
|
||||
debug.info(2, "Bitcell with 0 read/write ports")
|
||||
tx = pbitcell.pbitcell(num_readwrite=0,num_write=1,num_read=1)
|
||||
self.local_check(tx)
|
||||
|
||||
debug.info(2, "Bitcell with 0 write ports")
|
||||
tx = pbitcell.pbitcell(num_readwrite=1,num_write=0,num_read=1)
|
||||
self.local_check(tx)
|
||||
|
||||
debug.info(2, "Bitcell with 0 read ports")
|
||||
tx = pbitcell.pbitcell(num_readwrite=1,num_write=1,num_read=0)
|
||||
self.local_check(tx)
|
||||
|
||||
debug.info(2, "Bitcell with 0 read ports and 0 write ports")
|
||||
tx = pbitcell.pbitcell(num_readwrite=1,num_write=0,num_read=0)
|
||||
self.local_check(tx)
|
||||
|
||||
OPTS.check_lvsdrc = True
|
||||
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()
|
||||
|
|
@ -27,6 +27,26 @@ class pbitcell_test(openram_test):
|
|||
import pbitcell
|
||||
import tech
|
||||
|
||||
debug.info(2, "Bitcell with 1 of each port: read/write, write, and read")
|
||||
tx = pbitcell.pbitcell(num_readwrite=1,num_write=1,num_read=1)
|
||||
self.local_check(tx)
|
||||
|
||||
debug.info(2, "Bitcell with 0 read/write ports")
|
||||
tx = pbitcell.pbitcell(num_readwrite=0,num_write=1,num_read=1)
|
||||
self.local_check(tx)
|
||||
|
||||
debug.info(2, "Bitcell with 0 write ports")
|
||||
tx = pbitcell.pbitcell(num_readwrite=1,num_write=0,num_read=1)
|
||||
self.local_check(tx)
|
||||
|
||||
debug.info(2, "Bitcell with 0 read ports")
|
||||
tx = pbitcell.pbitcell(num_readwrite=1,num_write=1,num_read=0)
|
||||
self.local_check(tx)
|
||||
|
||||
debug.info(2, "Bitcell with 0 read ports and 0 write ports")
|
||||
tx = pbitcell.pbitcell(num_readwrite=1,num_write=0,num_read=0)
|
||||
self.local_check(tx)
|
||||
|
||||
debug.info(2, "Bitcell with 2 of each port: read/write, write, and read")
|
||||
tx = pbitcell.pbitcell(num_readwrite=2,num_write=2,num_read=2)
|
||||
self.local_check(tx)
|
||||
|
|
@ -49,6 +69,7 @@ class pbitcell_test(openram_test):
|
|||
|
||||
OPTS.check_lvsdrc = True
|
||||
globals.end_openram()
|
||||
OPTS.bitcell = "bitcell"
|
||||
|
||||
|
||||
# instantiate a copy of the class to actually run the test
|
||||
|
|
|
|||
|
|
@ -1,52 +1,53 @@
|
|||
#!/usr/bin/env python2.7
|
||||
"""
|
||||
Run a regresion test on a basic array
|
||||
"""
|
||||
|
||||
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 05_array_multiport_test")
|
||||
|
||||
class array_multiport_test(openram_test):
|
||||
|
||||
def runTest(self):
|
||||
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
|
||||
global verify
|
||||
import verify
|
||||
OPTS.check_lvsdrc = False
|
||||
|
||||
import bitcell_array
|
||||
|
||||
OPTS.bitcell = "pbitcell"
|
||||
OPTS.rw_ports = 2
|
||||
OPTS.r_ports = 2
|
||||
OPTS.w_ports = 2
|
||||
|
||||
debug.info(2, "Testing 4x4 array for multiport bitcell, with read ports at the edge of the bit cell")
|
||||
a = bitcell_array.bitcell_array(name="pbitcell_array", cols=4, rows=4)
|
||||
self.local_check(a)
|
||||
|
||||
OPTS.rw_ports = 2
|
||||
OPTS.r_ports = 0
|
||||
OPTS.w_ports = 2
|
||||
|
||||
debug.info(2, "Testing 4x4 array for multiport bitcell, with read/write ports at the edge of the bit cell")
|
||||
a = bitcell_array.bitcell_array(name="pbitcell_array", cols=4, rows=4)
|
||||
self.local_check(a)
|
||||
|
||||
|
||||
OPTS.check_lvsdrc = True
|
||||
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()
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Run a regression test on a basic array
|
||||
"""
|
||||
|
||||
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 05_array_multiport_test")
|
||||
|
||||
class array_multiport_test(openram_test):
|
||||
|
||||
def runTest(self):
|
||||
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
|
||||
global verify
|
||||
import verify
|
||||
OPTS.check_lvsdrc = False
|
||||
|
||||
import bitcell_array
|
||||
|
||||
OPTS.bitcell = "pbitcell"
|
||||
OPTS.rw_ports = 2
|
||||
OPTS.r_ports = 2
|
||||
OPTS.w_ports = 2
|
||||
|
||||
debug.info(2, "Testing 4x4 array for multiport bitcell, with read ports at the edge of the bit cell")
|
||||
a = bitcell_array.bitcell_array(name="pbitcell_array", cols=4, rows=4)
|
||||
self.local_check(a)
|
||||
|
||||
OPTS.rw_ports = 2
|
||||
OPTS.r_ports = 0
|
||||
OPTS.w_ports = 2
|
||||
|
||||
debug.info(2, "Testing 4x4 array for multiport bitcell, with read/write ports at the edge of the bit cell")
|
||||
a = bitcell_array.bitcell_array(name="pbitcell_array", cols=4, rows=4)
|
||||
self.local_check(a)
|
||||
|
||||
|
||||
OPTS.bitcell = "bitcell"
|
||||
OPTS.check_lvsdrc = True
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class lib_test(openram_test):
|
|||
tempspice = OPTS.openram_temp + "temp.sp"
|
||||
s.sp_write(tempspice)
|
||||
|
||||
lib.lib(out_dir=OPTS.openram_temp, sram=s, sp_file=tempspice, use_model=True)
|
||||
lib(out_dir=OPTS.openram_temp, sram=s, sp_file=tempspice, use_model=True)
|
||||
|
||||
# get all of the .lib files generated
|
||||
files = os.listdir(OPTS.openram_temp)
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class lib_test(openram_test):
|
|||
tempspice = OPTS.openram_temp + "temp.sp"
|
||||
s.sp_write(tempspice)
|
||||
|
||||
lib.lib(out_dir=OPTS.openram_temp, sram=s, sp_file=tempspice, use_model=False)
|
||||
lib(out_dir=OPTS.openram_temp, sram=s, sp_file=tempspice, use_model=False)
|
||||
|
||||
# get all of the .lib files generated
|
||||
files = os.listdir(OPTS.openram_temp)
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class lib_test(openram_test):
|
|||
tempspice = OPTS.openram_temp + "temp.sp"
|
||||
s.sp_write(tempspice)
|
||||
|
||||
lib.lib(out_dir=OPTS.openram_temp, sram=s, sp_file=tempspice, use_model=False)
|
||||
lib(out_dir=OPTS.openram_temp, sram=s, sp_file=tempspice, use_model=False)
|
||||
|
||||
# get all of the .lib files generated
|
||||
files = os.listdir(OPTS.openram_temp)
|
||||
|
|
|
|||
|
|
@ -91,25 +91,25 @@ class openram_test(unittest.TestCase):
|
|||
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)
|
||||
with open(f1, 'rb') as fp1, open(f2, 'rb') as fp2:
|
||||
while True:
|
||||
b1 = fp1.readline()
|
||||
b2 = fp2.readline()
|
||||
b1 = fp1.readline().decode('utf-8')
|
||||
b2 = fp2.readline().decode('utf-8')
|
||||
#print "b1:",b1,
|
||||
#print "b2:",b2,
|
||||
|
||||
# 1. Find all of the floats using a regex
|
||||
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)
|
||||
b1_floats=rx.findall(b1)
|
||||
b2_floats=rx.findall(b2)
|
||||
debug.info(3,"b1_floats: "+str(b1_floats))
|
||||
|
|
@ -117,9 +117,9 @@ class openram_test(unittest.TestCase):
|
|||
|
||||
# 2. Remove the floats from the string
|
||||
for f in b1_floats:
|
||||
b1=b1.replace(str(f),"",1)
|
||||
b1=b1.replace(f,"",1)
|
||||
for f in b2_floats:
|
||||
b2=b2.replace(str(f),"",1)
|
||||
b2=b2.replace(f,"",1)
|
||||
#print "b1:",b1,
|
||||
#print "b2:",b2,
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue