mirror of https://github.com/VLSIDA/OpenRAM.git
Merge branch 'tech_migration' into dev
This commit is contained in:
commit
dff28a9997
|
|
@ -172,6 +172,20 @@ class design(hierarchy_design):
|
|||
self.well_extend_active = max(self.well_extend_active, self.nwell_extend_active)
|
||||
if "pwell" in layer:
|
||||
self.well_extend_active = max(self.well_extend_active, self.pwell_extend_active)
|
||||
|
||||
# The active offset is due to the well extension
|
||||
if "pwell" in layer:
|
||||
self.pwell_enclose_active = drc("pwell_enclose_active")
|
||||
else:
|
||||
self.pwell_enclose_active = 0
|
||||
if "nwell" in layer:
|
||||
self.nwell_enclose_active = drc("nwell_enclose_active")
|
||||
else:
|
||||
self.nwell_enclose_active = 0
|
||||
# Use the max of either so that the poly gates will align properly
|
||||
self.well_enclose_active = max(self.pwell_enclose_active,
|
||||
self.nwell_enclose_active,
|
||||
self.active_space)
|
||||
|
||||
# These are for debugging previous manual rules
|
||||
if False:
|
||||
|
|
|
|||
|
|
@ -695,8 +695,8 @@ class layout():
|
|||
# we should add a boundary just for DRC in some technologies
|
||||
if not self.is_library_cell and not self.bounding_box:
|
||||
# If there is a boundary layer, and we didn't create one, add one.
|
||||
if "stdc" in techlayer.keys():
|
||||
boundary_layer = "stdc"
|
||||
if "boundary" in techlayer.keys():
|
||||
boundary_layer = "boundary"
|
||||
boundary = [self.find_lowest_coords(),
|
||||
self.find_highest_coords()]
|
||||
debug.check(boundary[0] and boundary[1], "No shapes to make a boundary.")
|
||||
|
|
@ -1259,10 +1259,7 @@ class layout():
|
|||
if OPTS.netlist_only:
|
||||
return
|
||||
|
||||
if "stdc" in techlayer.keys():
|
||||
boundary_layer = "stdc"
|
||||
else:
|
||||
boundary_layer = "boundary"
|
||||
boundary_layer = "boundary"
|
||||
if not ur:
|
||||
self.bounding_box = self.add_rect(layer=boundary_layer,
|
||||
offset=ll,
|
||||
|
|
@ -1307,13 +1304,10 @@ class layout():
|
|||
pin.ll(),
|
||||
pin.width(),
|
||||
pin.height())
|
||||
elif pin.layer == "m1":
|
||||
self.add_power_pin(name, pin.center())
|
||||
else:
|
||||
debug.warning("{0} pins of {1} should be on {2} or metal1 for "\
|
||||
"supply router."
|
||||
.format(name, inst.name, self.pwr_grid_layer))
|
||||
|
||||
else:
|
||||
self.add_power_pin(name, pin.center(), start_layer=pin.layer)
|
||||
|
||||
def add_power_pin(self, name, loc, size=[1, 1], directions=None, start_layer="m1"):
|
||||
"""
|
||||
Add a single power pin from the lowest power_grid layer down to M1 (or li) at
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#
|
||||
import debug
|
||||
import design
|
||||
from tech import parameter
|
||||
from tech import parameter, layer
|
||||
from tech import cell_properties as props
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
|
|
@ -52,7 +52,6 @@ class dff_buf(design.design):
|
|||
def create_layout(self):
|
||||
self.place_instances()
|
||||
self.width = self.inv2_inst.rx()
|
||||
|
||||
self.height = self.dff.height
|
||||
self.route_wires()
|
||||
self.add_layout_pins()
|
||||
|
|
@ -120,39 +119,37 @@ class dff_buf(design.design):
|
|||
except AttributeError:
|
||||
pass
|
||||
self.inv1_inst.place(vector(self.dff_inst.rx() + well_spacing + self.well_extend_active, 0))
|
||||
|
||||
|
||||
# Add INV2 to the right
|
||||
self.inv2_inst.place(vector(self.inv1_inst.rx(), 0))
|
||||
|
||||
def route_wires(self):
|
||||
if "li" in layer:
|
||||
self.route_layer = "li"
|
||||
else:
|
||||
self.route_layer = "m1"
|
||||
|
||||
# Route dff q to inv1 a
|
||||
q_pin = self.dff_inst.get_pin("Q")
|
||||
a1_pin = self.inv1_inst.get_pin("A")
|
||||
mid_x_offset = 0.5 * (a1_pin.cx() + q_pin.cx())
|
||||
mid1 = vector(mid_x_offset, q_pin.cy())
|
||||
mid2 = vector(mid_x_offset, a1_pin.cy())
|
||||
self.add_path("m3", [q_pin.center(), mid1, mid2, a1_pin.center()])
|
||||
self.add_via_center(layers=self.m2_stack,
|
||||
offset=q_pin.center())
|
||||
self.add_via_center(layers=self.m2_stack,
|
||||
offset=a1_pin.center())
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
offset=a1_pin.center())
|
||||
mid1 = vector(a1_pin.cx(), q_pin.cy())
|
||||
self.add_path(q_pin.layer, [q_pin.center(), mid1, a1_pin.center()])
|
||||
self.add_via_stack_center(from_layer=a1_pin.layer,
|
||||
to_layer=q_pin.layer,
|
||||
offset=a1_pin.center())
|
||||
|
||||
# Route inv1 z to inv2 a
|
||||
z1_pin = self.inv1_inst.get_pin("Z")
|
||||
a2_pin = self.inv2_inst.get_pin("A")
|
||||
mid_x_offset = 0.5 * (z1_pin.cx() + a2_pin.cx())
|
||||
self.mid_qb_pos = vector(mid_x_offset, z1_pin.cy())
|
||||
mid2 = vector(mid_x_offset, a2_pin.cy())
|
||||
self.add_path("m1", [z1_pin.center(), self.mid_qb_pos, mid2, a2_pin.center()])
|
||||
self.mid_qb_pos = vector(0.5 * (z1_pin.cx() + a2_pin.cx()), z1_pin.cy())
|
||||
self.add_zjog(z1_pin.layer, z1_pin.center(), a2_pin.center())
|
||||
|
||||
def add_layout_pins(self):
|
||||
|
||||
# Continous vdd rail along with label.
|
||||
vdd_pin=self.dff_inst.get_pin("vdd")
|
||||
self.add_layout_pin(text="vdd",
|
||||
layer="m1",
|
||||
layer=vdd_pin.layer,
|
||||
offset=vdd_pin.ll(),
|
||||
width=self.width,
|
||||
height=vdd_pin.height())
|
||||
|
|
@ -160,7 +157,7 @@ class dff_buf(design.design):
|
|||
# Continous gnd rail along with label.
|
||||
gnd_pin=self.dff_inst.get_pin("gnd")
|
||||
self.add_layout_pin(text="gnd",
|
||||
layer="m1",
|
||||
layer=gnd_pin.layer,
|
||||
offset=gnd_pin.ll(),
|
||||
width=self.width,
|
||||
height=vdd_pin.height())
|
||||
|
|
@ -185,17 +182,20 @@ class dff_buf(design.design):
|
|||
self.add_layout_pin_rect_center(text="Q",
|
||||
layer="m2",
|
||||
offset=q_pos)
|
||||
self.add_path("m1", [dout_pin.center(), mid_pos, q_pos])
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
offset=q_pos)
|
||||
self.add_path(self.route_layer, [dout_pin.center(), mid_pos, q_pos])
|
||||
self.add_via_stack_center(from_layer=dout_pin.layer,
|
||||
to_layer="m2",
|
||||
offset=q_pos)
|
||||
|
||||
qb_pos = self.mid_qb_pos + vector(0, self.m2_pitch)
|
||||
self.add_layout_pin_rect_center(text="Qb",
|
||||
layer="m2",
|
||||
offset=qb_pos)
|
||||
self.add_path("m1", [self.mid_qb_pos, qb_pos])
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
offset=qb_pos)
|
||||
self.add_path(self.route_layer, [self.mid_qb_pos, qb_pos])
|
||||
a2_pin = self.inv2_inst.get_pin("A")
|
||||
self.add_via_stack_center(from_layer=a2_pin.layer,
|
||||
to_layer="m2",
|
||||
offset=qb_pos)
|
||||
|
||||
def get_clk_cin(self):
|
||||
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff"""
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ class replica_column(design.design):
|
|||
bl_pin = self.cell_inst[0].get_pin(bl_name)
|
||||
self.add_layout_pin(text=bl_name,
|
||||
layer=bl_pin.layer,
|
||||
offset=bl_pin.ll(),
|
||||
offset=bl_pin.ll().scale(1, 0),
|
||||
width=bl_pin.width(),
|
||||
height=self.height)
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ class pgate(design.design):
|
|||
# This is the space from a S/D contact to the supply rail
|
||||
contact_to_vdd_rail_space = 0.5 * self.m1_width + self.m1_space
|
||||
# This is a poly-to-poly of a flipped cell
|
||||
poly_to_poly_gate_space = self.poly_extend_active + self.poly_space
|
||||
poly_to_poly_gate_space = self.poly_extend_active + 0.5 * self.poly_space
|
||||
|
||||
self.top_bottom_space = max(contact_to_vdd_rail_space,
|
||||
poly_to_poly_gate_space)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import debug
|
|||
import pgate
|
||||
from vector import vector
|
||||
from sram_factory import factory
|
||||
|
||||
from tech import layer
|
||||
|
||||
class pinvbuf(pgate.pgate):
|
||||
"""
|
||||
|
|
@ -111,33 +111,45 @@ class pinvbuf(pgate.pgate):
|
|||
mirror="MX")
|
||||
|
||||
def route_wires(self):
|
||||
if "li" in layer:
|
||||
route_stack = self.li_stack
|
||||
else:
|
||||
route_stack = self.m1_stack
|
||||
|
||||
# inv1 Z to inv2 A
|
||||
z1_pin = self.inv1_inst.get_pin("Z")
|
||||
a2_pin = self.inv2_inst.get_pin("A")
|
||||
mid_point = vector(z1_pin.cx(), a2_pin.cy())
|
||||
self.add_path("m1", [z1_pin.center(), mid_point, a2_pin.center()])
|
||||
self.add_path(z1_pin.layer, [z1_pin.center(), mid_point, a2_pin.center()])
|
||||
self.add_via_stack_center(from_layer=z1_pin.layer,
|
||||
to_layer=a2_pin.layer,
|
||||
offset=a2_pin.center())
|
||||
|
||||
# inv2 Z to inv3 A
|
||||
z2_pin = self.inv2_inst.get_pin("Z")
|
||||
a3_pin = self.inv3_inst.get_pin("A")
|
||||
mid_point = vector(z2_pin.cx(), a3_pin.cy())
|
||||
self.add_path("m1", [z2_pin.center(), mid_point, a3_pin.center()])
|
||||
self.add_path(z2_pin.layer, [z2_pin.center(), mid_point, a3_pin.center()])
|
||||
self.add_via_stack_center(from_layer=z2_pin.layer,
|
||||
to_layer=a3_pin.layer,
|
||||
offset=a3_pin.center())
|
||||
|
||||
# inv1 Z to inv4 A (up and over)
|
||||
z1_pin = self.inv1_inst.get_pin("Z")
|
||||
a4_pin = self.inv4_inst.get_pin("A")
|
||||
mid_point = vector(z1_pin.cx(), a4_pin.cy())
|
||||
self.add_wire(self.m1_stack,
|
||||
self.add_wire(route_stack,
|
||||
[z1_pin.center(), mid_point, a4_pin.center()])
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
offset=z1_pin.center())
|
||||
self.add_via_stack_center(from_layer=z1_pin.layer,
|
||||
to_layer=route_stack[2],
|
||||
offset=z1_pin.center())
|
||||
|
||||
def add_layout_pins(self):
|
||||
|
||||
# Continous vdd rail along with label.
|
||||
vdd_pin = self.inv1_inst.get_pin("vdd")
|
||||
self.add_layout_pin(text="vdd",
|
||||
layer="m1",
|
||||
layer=vdd_pin.layer,
|
||||
offset=vdd_pin.ll().scale(0, 1),
|
||||
width=self.width,
|
||||
height=vdd_pin.height())
|
||||
|
|
@ -145,7 +157,7 @@ class pinvbuf(pgate.pgate):
|
|||
# Continous vdd rail along with label.
|
||||
gnd_pin = self.inv4_inst.get_pin("gnd")
|
||||
self.add_layout_pin(text="gnd",
|
||||
layer="m1",
|
||||
layer=gnd_pin.layer,
|
||||
offset=gnd_pin.ll().scale(0, 1),
|
||||
width=self.width,
|
||||
height=gnd_pin.height())
|
||||
|
|
@ -153,31 +165,25 @@ class pinvbuf(pgate.pgate):
|
|||
# Continous gnd rail along with label.
|
||||
gnd_pin = self.inv1_inst.get_pin("gnd")
|
||||
self.add_layout_pin(text="gnd",
|
||||
layer="m1",
|
||||
layer=gnd_pin.layer,
|
||||
offset=gnd_pin.ll().scale(0, 1),
|
||||
width=self.width,
|
||||
height=vdd_pin.height())
|
||||
|
||||
z_pin = self.inv4_inst.get_pin("Z")
|
||||
self.add_layout_pin_rect_center(text="Z",
|
||||
layer="m2",
|
||||
layer=z_pin.layer,
|
||||
offset=z_pin.center())
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
offset=z_pin.center())
|
||||
|
||||
zb_pin = self.inv3_inst.get_pin("Z")
|
||||
self.add_layout_pin_rect_center(text="Zb",
|
||||
layer="m2",
|
||||
layer=zb_pin.layer,
|
||||
offset=zb_pin.center())
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
offset=zb_pin.center())
|
||||
|
||||
a_pin = self.inv1_inst.get_pin("A")
|
||||
self.add_layout_pin_rect_center(text="A",
|
||||
layer="m2",
|
||||
layer=a_pin.layer,
|
||||
offset=a_pin.center())
|
||||
self.add_via_center(layers=self.m1_stack,
|
||||
offset=a_pin.center())
|
||||
|
||||
def determine_clk_buf_stage_efforts(self, external_cout, inp_is_rise=False):
|
||||
"""Get the stage efforts of the clk -> clk_buf path"""
|
||||
|
|
|
|||
|
|
@ -177,9 +177,9 @@ class pnand2(pgate.pgate):
|
|||
|
||||
|
||||
# Top of NMOS drain
|
||||
nmos_pin = self.nmos2_inst.get_pin("D")
|
||||
bottom_pin_offset = nmos_pin.uy()
|
||||
self.inputA_yoffset = bottom_pin_offset + self.m1_pitch
|
||||
bottom_pin = self.nmos2_inst.get_pin("D")
|
||||
self.inputA_yoffset = max(bottom_pin.uy() + self.m1_pitch,
|
||||
self.nmos2_inst.uy() + self.poly_to_active)
|
||||
|
||||
self.inputB_yoffset = self.inputA_yoffset + self.m3_pitch
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ from vector import vector
|
|||
import logical_effort
|
||||
from sram_factory import factory
|
||||
from globals import OPTS
|
||||
|
||||
import contact
|
||||
|
||||
class pnand3(pgate.pgate):
|
||||
"""
|
||||
|
|
@ -209,13 +209,21 @@ class pnand3(pgate.pgate):
|
|||
def route_inputs(self):
|
||||
""" Route the A and B and C inputs """
|
||||
|
||||
# We can use this pitch because the contacts and overlap won't be adjacent
|
||||
non_contact_pitch = 0.5 * self.m1_width + self.m1_space + 0.5 * contact.poly_contact.second_layer_height
|
||||
pmos_drain_bottom = self.pmos1_inst.get_pin("D").by()
|
||||
self.output_yoffset = pmos_drain_bottom - 0.5 * self.route_layer_width - self.route_layer_space
|
||||
|
||||
# This is a more compact offset, but the bottom one works better in the decoders to "center" the pins
|
||||
# in the height of the gates
|
||||
self.inputA_yoffset = self.output_yoffset - 0.5 * self.route_layer_width - self.route_layer_space
|
||||
# self.inputA_yoffset = self.output_yoffset - self.m1_pitch
|
||||
bottom_pin = self.nmos1_inst.get_pin("D")
|
||||
# active contact metal to poly contact metal spacing
|
||||
active_contact_to_poly_contact = bottom_pin.uy() + self.m1_space + 0.5 * contact.poly_contact.second_layer_height
|
||||
# active diffusion to poly contact spacing
|
||||
# doesn't use nmos uy because that is calculated using offset + poly height
|
||||
active_to_poly_contact = self.nmos1_inst.by() + self.nmos1_inst.mod.active_height \
|
||||
+ self.poly_to_active + 0.5 * contact.poly_contact.first_layer_height
|
||||
|
||||
self.inputA_yoffset = max(active_contact_to_poly_contact,
|
||||
active_to_poly_contact)
|
||||
self.route_input_gate(self.pmos1_inst,
|
||||
self.nmos1_inst,
|
||||
self.inputA_yoffset,
|
||||
|
|
@ -223,14 +231,14 @@ class pnand3(pgate.pgate):
|
|||
position="left")
|
||||
|
||||
# Put B right on the well line
|
||||
self.inputB_yoffset = self.inputA_yoffset - self.m1_pitch
|
||||
self.inputB_yoffset = self.inputA_yoffset + non_contact_pitch
|
||||
self.route_input_gate(self.pmos2_inst,
|
||||
self.nmos2_inst,
|
||||
self.inputB_yoffset,
|
||||
"B",
|
||||
position="center")
|
||||
|
||||
self.inputC_yoffset = self.inputB_yoffset - self.m1_pitch
|
||||
self.inputC_yoffset = self.inputB_yoffset + non_contact_pitch
|
||||
self.route_input_gate(self.pmos3_inst,
|
||||
self.nmos3_inst,
|
||||
self.inputC_yoffset,
|
||||
|
|
|
|||
|
|
@ -149,13 +149,9 @@ class precharge(design.design):
|
|||
# Compute the other pmos2 location,
|
||||
# but determining offset to overlap the source and drain pins
|
||||
overlap_offset = self.pmos.get_pin("D").ll() - self.pmos.get_pin("S").ll()
|
||||
# This is how much the contact is placed inside the ptx active
|
||||
contact_xdiff = self.pmos.get_pin("S").lx()
|
||||
|
||||
# adds the lower pmos to layout
|
||||
bl_xoffset = self.bitcell_bl_pin.lx()
|
||||
self.lower_pmos_position = vector(max(bl_xoffset - contact_xdiff,
|
||||
self.nwell_enclose_active),
|
||||
self.lower_pmos_position = vector(self.well_enclose_active + 0.5 * self.m1_width,
|
||||
self.initial_yoffset)
|
||||
self.lower_pmos_inst.place(self.lower_pmos_position)
|
||||
|
||||
|
|
@ -218,7 +214,7 @@ class precharge(design.design):
|
|||
|
||||
# adds the contact from active to metal1
|
||||
offset_height = self.upper_pmos1_inst.uy() + \
|
||||
0.5 * contact.active_contact.height + \
|
||||
contact.active_contact.height + \
|
||||
self.nwell_extend_active
|
||||
self.well_contact_pos = self.upper_pmos1_inst.get_pin("D").center().scale(1, 0) + \
|
||||
vector(0, offset_height)
|
||||
|
|
|
|||
|
|
@ -205,28 +205,15 @@ class ptx(design.design):
|
|||
# Poly height must include poly extension over active
|
||||
self.poly_height = self.tx_width + 2 * self.poly_extend_active
|
||||
|
||||
# The active offset is due to the well extension
|
||||
if "pwell" in layer:
|
||||
pwell_enclose_active = drc("pwell_enclose_active")
|
||||
else:
|
||||
pwell_enclose_active = 0
|
||||
if "nwell" in layer:
|
||||
nwell_enclose_active = drc("nwell_enclose_active")
|
||||
else:
|
||||
nwell_enclose_active = 0
|
||||
# Use the max of either so that the poly gates will align properly
|
||||
well_enclose_active = max(pwell_enclose_active,
|
||||
nwell_enclose_active)
|
||||
self.active_offset = vector([well_enclose_active] * 2)
|
||||
self.active_offset = vector([self.well_enclose_active] * 2)
|
||||
|
||||
# Well enclosure of active, ensure minwidth as well
|
||||
well_name = "{}well".format(self.well_type)
|
||||
if well_name in layer:
|
||||
well_width_rule = drc("minwidth_" + well_name)
|
||||
well_enclose_active = drc(well_name + "_enclose_active")
|
||||
self.well_width = max(self.active_width + 2 * well_enclose_active,
|
||||
self.well_width = max(self.active_width + 2 * self.well_enclose_active,
|
||||
well_width_rule)
|
||||
self.well_height = max(self.active_height + 2 * well_enclose_active,
|
||||
self.well_height = max(self.active_height + 2 * self.well_enclose_active,
|
||||
well_width_rule)
|
||||
# We are going to shift the 0,0, so include that in the width and height
|
||||
self.height = self.well_height - self.active_offset.y
|
||||
|
|
|
|||
|
|
@ -29,10 +29,6 @@ class pand2_test(openram_test):
|
|||
a = pand2.pand2(name="pand2x4", size=4)
|
||||
self.local_check(a)
|
||||
|
||||
debug.info(2, "Testing vertical pand2 gate 4x")
|
||||
a = pand2.pand2(name="pand2x4", size=4, vertical=True)
|
||||
self.local_check(a)
|
||||
|
||||
globals.end_openram()
|
||||
|
||||
# instantiate a copdsay of the class to actually run the test
|
||||
|
|
|
|||
|
|
@ -29,10 +29,6 @@ class pand3_test(openram_test):
|
|||
a = pand3.pand3(name="pand3x4", size=4)
|
||||
self.local_check(a)
|
||||
|
||||
debug.info(2, "Testing vertical pand3 gate 4x")
|
||||
a = pand3.pand3(name="pand3x4", size=4, vertical=True)
|
||||
self.local_check(a)
|
||||
|
||||
globals.end_openram()
|
||||
|
||||
# instantiate a copdsay of the class to actually run the test
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
#!/usr/bin/env python3
|
||||
# See LICENSE for licensing information.
|
||||
#
|
||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||
# (acting for and on behalf of Oklahoma State University)
|
||||
# All rights reserved.
|
||||
#
|
||||
import unittest
|
||||
from testutils import *
|
||||
import sys,os
|
||||
sys.path.append(os.getenv("OPENRAM_HOME"))
|
||||
import globals
|
||||
from globals import OPTS
|
||||
from sram_factory import factory
|
||||
import debug
|
||||
|
||||
|
||||
class precharge_test(openram_test):
|
||||
|
||||
def runTest(self):
|
||||
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
|
||||
globals.init_openram(config_file)
|
||||
|
||||
# check precharge array in multi-port
|
||||
OPTS.num_rw_ports = 1
|
||||
OPTS.num_r_ports = 1
|
||||
OPTS.num_w_ports = 0
|
||||
globals.setup_bitcell()
|
||||
|
||||
debug.info(2, "Checking precharge for 1rw1r port 0")
|
||||
tx = factory.create(module_type="precharge", size=1, bitcell_bl="bl0", bitcell_br="br0")
|
||||
self.local_check(tx)
|
||||
|
||||
factory.reset()
|
||||
debug.info(2, "Checking precharge for 1rw1r port 1")
|
||||
tx = factory.create(module_type="precharge", size=1, bitcell_bl="bl1", bitcell_br="br1")
|
||||
self.local_check(tx)
|
||||
|
||||
globals.end_openram()
|
||||
|
||||
# run the test from the command line
|
||||
if __name__ == "__main__":
|
||||
(OPTS, args) = globals.parse_args()
|
||||
del sys.argv[1:]
|
||||
header(__file__, OPTS.tech_name)
|
||||
unittest.main(testRunner=debugTestRunner())
|
||||
|
|
@ -17,7 +17,7 @@ import debug
|
|||
|
||||
#@unittest.skip("SKIPPING 05_bitcell_1rw_1r_array_test")
|
||||
|
||||
class bitcell_1rw_1r_array_test(openram_test):
|
||||
class bitcell_array_1rw_1r_test(openram_test):
|
||||
|
||||
def runTest(self):
|
||||
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/env python3
|
||||
# See LICENSE for licensing information.
|
||||
#
|
||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||
# (acting for and on behalf of Oklahoma State University)
|
||||
# All rights reserved.
|
||||
#
|
||||
import unittest
|
||||
from testutils import *
|
||||
import sys,os
|
||||
sys.path.append(os.getenv("OPENRAM_HOME"))
|
||||
import globals
|
||||
from globals import OPTS
|
||||
from sram_factory import factory
|
||||
import debug
|
||||
|
||||
class sense_amp_test(openram_test):
|
||||
|
||||
def runTest(self):
|
||||
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
|
||||
globals.init_openram(config_file)
|
||||
|
||||
OPTS.num_rw_ports = 1
|
||||
OPTS.num_r_ports = 1
|
||||
OPTS.num_w_ports = 0
|
||||
globals.setup_bitcell()
|
||||
|
||||
debug.info(2, "Testing sense_amp_array for word_size=4, words_per_row=1")
|
||||
a = factory.create(module_type="sense_amp_array", word_size=4, words_per_row=1)
|
||||
self.local_check(a)
|
||||
|
||||
debug.info(2, "Testing sense_amp_array for word_size=4, words_per_row=2")
|
||||
a = factory.create(module_type="sense_amp_array", word_size=4, words_per_row=2)
|
||||
self.local_check(a)
|
||||
|
||||
debug.info(2, "Testing sense_amp_array for word_size=4, words_per_row=4")
|
||||
a = factory.create(module_type="sense_amp_array", word_size=4, words_per_row=4)
|
||||
self.local_check(a)
|
||||
|
||||
globals.end_openram()
|
||||
|
||||
# run the test from the command line
|
||||
if __name__ == "__main__":
|
||||
(OPTS, args) = globals.parse_args()
|
||||
del sys.argv[1:]
|
||||
header(__file__, OPTS.tech_name)
|
||||
unittest.main(testRunner=debugTestRunner())
|
||||
|
|
@ -13,7 +13,7 @@ from globals import OPTS
|
|||
from sram_factory import factory
|
||||
import debug
|
||||
|
||||
class replica_bitcell_array_test(openram_test):
|
||||
class replica_bitcell_array_1rw_1r_test(openram_test):
|
||||
|
||||
def runTest(self):
|
||||
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/env python3
|
||||
# See LICENSE for licensing information.
|
||||
#
|
||||
# Copyright (c) 2016-2019 Regents of the University of California
|
||||
# All rights reserved.
|
||||
#
|
||||
import unittest
|
||||
from testutils import *
|
||||
import sys,os
|
||||
sys.path.append(os.getenv("OPENRAM_HOME"))
|
||||
import globals
|
||||
from globals import OPTS
|
||||
from sram_factory import factory
|
||||
import debug
|
||||
|
||||
class replica_column_test(openram_test):
|
||||
|
||||
def runTest(self):
|
||||
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
|
||||
globals.init_openram(config_file)
|
||||
|
||||
OPTS.num_rw_ports = 1
|
||||
OPTS.num_r_ports = 1
|
||||
OPTS.num_w_ports = 0
|
||||
globals.setup_bitcell()
|
||||
|
||||
debug.info(2, "Testing replica column for 6t_cell")
|
||||
a = factory.create(module_type="replica_column", rows=4, left_rbl=1, right_rbl=0, replica_bit=1)
|
||||
self.local_check(a)
|
||||
|
||||
debug.info(2, "Testing replica column for 6t_cell")
|
||||
a = factory.create(module_type="replica_column", rows=4, left_rbl=1, right_rbl=1, replica_bit=6)
|
||||
self.local_check(a)
|
||||
|
||||
debug.info(2, "Testing replica column for 6t_cell")
|
||||
a = factory.create(module_type="replica_column", rows=4, left_rbl=2, right_rbl=0, replica_bit=2)
|
||||
self.local_check(a)
|
||||
|
||||
globals.end_openram()
|
||||
|
||||
# run the test from the command line
|
||||
if __name__ == "__main__":
|
||||
(OPTS, args) = globals.parse_args()
|
||||
del sys.argv[1:]
|
||||
header(__file__, OPTS.tech_name)
|
||||
unittest.main(testRunner=debugTestRunner())
|
||||
|
|
@ -15,7 +15,6 @@ from globals import OPTS
|
|||
from sram_factory import factory
|
||||
import debug
|
||||
|
||||
@unittest.skip("SKIPPING 20_psram_1bank_4mux_1rw_1r_test - Matt sucks, don't do this")
|
||||
class psram_1bank_4mux_1rw_1r_test(openram_test):
|
||||
|
||||
def runTest(self):
|
||||
|
|
|
|||
|
|
@ -22,14 +22,26 @@ header(__file__, OPTS.tech_name)
|
|||
# get a list of all files in the tests directory
|
||||
files = os.listdir(sys.path[0])
|
||||
|
||||
# load a file with all tests to skip in a given technology
|
||||
# since tech_name is dynamically loaded, we can't use @skip directives
|
||||
try:
|
||||
skip_file_name = "{0}/tests/skip_tests_{1}.txt".format(os.getenv("OPENRAM_HOME"), OPTS.tech_name)
|
||||
skip_file = open(skip_file_name, "r")
|
||||
skip_tests = skip_file.read().splitlines()
|
||||
for st in skip_tests:
|
||||
debug.warning("Skipping: " + st)
|
||||
except FileNotFoundError:
|
||||
skip_tests = []
|
||||
|
||||
# assume any file that ends in "test.py" in it is a regression test
|
||||
nametest = re.compile("test\.py$", re.IGNORECASE)
|
||||
tests = list(filter(nametest.search, files))
|
||||
tests.sort()
|
||||
all_tests = list(filter(nametest.search, files))
|
||||
filtered_tests = list(filter(lambda i: i not in skip_tests, all_tests))
|
||||
filtered_tests.sort()
|
||||
|
||||
# import all of the modules
|
||||
filenameToModuleName = lambda f: os.path.splitext(f)[0]
|
||||
moduleNames = map(filenameToModuleName, tests)
|
||||
moduleNames = map(filenameToModuleName, filtered_tests)
|
||||
modules = map(__import__, moduleNames)
|
||||
suite = unittest.TestSuite()
|
||||
load = unittest.defaultTestLoader.loadTestsFromModule
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
04_dummy_pbitcell_test.py
|
||||
04_pbitcell_test.py
|
||||
04_precharge_pbitcell_test.py
|
||||
04_replica_pbitcell_test.py
|
||||
04_single_level_column_mux_pbitcell_test.py
|
||||
05_bitcell_1rw_1r_array_test.py
|
||||
05_bitcell_array_test.py
|
||||
05_dummy_array_test.py
|
||||
05_pbitcell_array_test.py
|
||||
06_hierarchical_decoder_pbitcell_test.py
|
||||
06_hierarchical_decoder_test.py
|
||||
06_hierarchical_predecode2x4_pbitcell_test.py
|
||||
06_hierarchical_predecode2x4_test.py
|
||||
06_hierarchical_predecode3x8_pbitcell_test.py
|
||||
06_hierarchical_predecode3x8_test.py
|
||||
06_hierarchical_predecode4x16_test.py
|
||||
07_single_level_column_mux_array_pbitcell_test.py
|
||||
08_wordline_driver_array_pbitcell_test.py
|
||||
08_wordline_driver_array_test.py
|
||||
09_sense_amp_array_test_pbitcell.py
|
||||
09_sense_amp_array_test.py
|
||||
10_write_driver_array_pbitcell_test.py
|
||||
10_write_driver_array_test.py
|
||||
10_write_driver_array_wmask_pbitcell_test.py
|
||||
10_write_driver_array_wmask_test.py
|
||||
10_write_mask_and_array_pbitcell_test.py
|
||||
10_write_mask_and_array_test.py
|
||||
12_tri_gate_array_test.py
|
||||
14_replica_pbitcell_array_test.py
|
||||
14_replica_bitcell_array_test.py
|
||||
14_replica_column_test.py
|
||||
14_replica_column_1rw_1r_test.py
|
||||
18_port_address_test.py
|
||||
18_port_data_test.py
|
||||
18_port_data_wmask_test.py
|
||||
19_bank_select_pbitcell_test.py
|
||||
19_bank_select_test.py
|
||||
19_psingle_bank_test.py
|
||||
19_bank_select_pbitcell_test.py
|
||||
19_pmulti_bank_test.py
|
||||
19_multi_bank_test.py
|
||||
19_psingle_bank_test.py
|
||||
19_single_bank_1w_1r_test.py
|
||||
19_single_bank_wmask_1rw_1r_test.py
|
||||
19_single_bank_1rw_1r_test.py
|
||||
19_single_bank_test.py
|
||||
19_single_bank_wmask_test.py
|
||||
20_psram_1bank_2mux_1rw_1w_test.py
|
||||
20_psram_1bank_2mux_1rw_1w_wmask_test.py
|
||||
20_psram_1bank_2mux_1w_1r_test.py
|
||||
20_psram_1bank_2mux_test.py
|
||||
20_psram_1bank_4mux_1rw_1r_test.py
|
||||
20_sram_1bank_2mux_1w_1r_test.py
|
||||
20_sram_1bank_2mux_test.py
|
||||
20_sram_1bank_2mux_wmask_test.py
|
||||
20_sram_1bank_32b_1024_wmask_test.py
|
||||
20_sram_1bank_4mux_test.py
|
||||
20_sram_1bank_8mux_test.py
|
||||
20_sram_1bank_nomux_test.py
|
||||
20_sram_1bank_nomux_wmask_test.py
|
||||
20_sram_2bank_test.py
|
||||
21_hspice_delay_test.py
|
||||
21_hspice_setuphold_test.py
|
||||
21_model_delay_test.py
|
||||
21_ngspice_delay_test.py
|
||||
21_ngspice_setuphold_test.py
|
||||
22_psram_1bank_2mux_func_test.py
|
||||
22_psram_1bank_4mux_func_test.py
|
||||
22_psram_1bank_8mux_func_test.py
|
||||
22_psram_1bank_nomux_func_test.py
|
||||
22_sram_1bank_2mux_func_test.py
|
||||
22_sram_1bank_4mux_func_test.py
|
||||
22_sram_1bank_8mux_func_test.py
|
||||
22_sram_1bank_nomux_func_test.py
|
||||
22_sram_1rw_1r_1bank_nomux_func_test.py
|
||||
22_sram_wmask_func_test.py
|
||||
23_lib_sram_model_corners_test.py
|
||||
23_lib_sram_model_test.py
|
||||
23_lib_sram_prune_test.py
|
||||
23_lib_sram_test.py
|
||||
24_lef_sram_test.py
|
||||
25_verilog_sram_test.py
|
||||
26_hspice_pex_pinv_test.py
|
||||
26_ngspice_pex_pinv_test.py
|
||||
26_pex_test.py
|
||||
30_openram_back_end_test.py
|
||||
30_openram_front_end_test.py
|
||||
Binary file not shown.
Loading…
Reference in New Issue