Merge branch 'dev' into characterizer_bug_fixes

This commit is contained in:
Hunter Nichols 2020-11-20 11:16:41 -08:00
commit 53e64fb696
35 changed files with 233 additions and 191 deletions

View File

@ -26,8 +26,14 @@ class design(hierarchy_design):
# This allows us to use different GDS/spice circuits for hard cells instead of the default ones
# Except bitcell names are generated automatically by the globals.py setup_bitcells routines
# depending on the number of ports.
if name in props.names:
cell_name = props.names[name]
if type(props.names[name]) is list:
num_ports = OPTS.num_rw_ports + OPTS.num_r_ports + OPTS.num_w_ports - 1
cell_name = props.names[name][num_ports]
else:
cell_name = props.names[name]
elif not cell_name:
cell_name = name
super().__init__(name, cell_name)

View File

@ -21,22 +21,6 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
name_map = []
def __init__(self, name, cell_name):
self.gds_file = OPTS.openram_tech + "gds_lib/" + cell_name + ".gds"
self.sp_file = OPTS.openram_tech + "sp_lib/" + cell_name + ".sp"
# If we have a separate lvs directory, then all the lvs files
# should be in there (all or nothing!)
try:
lvs_subdir = tech.lvs_lib
except AttributeError:
lvs_subdir = "lvs_lib"
lvs_dir = OPTS.openram_tech + lvs_subdir + "/"
if os.path.exists(lvs_dir):
self.lvs_file = lvs_dir + cell_name + ".sp"
else:
self.lvs_file = self.sp_file
self.drc_errors = "skipped"
self.lvs_errors = "skipped"

View File

@ -36,6 +36,8 @@ class layout():
self.name = name
self.cell_name = cell_name
self.gds_file = OPTS.openram_tech + "gds_lib/" + cell_name + ".gds"
self.width = None
self.height = None
self.bounding_box = None
@ -375,7 +377,7 @@ class layout():
"""
Return a pin list of all pins
"""
return self.pin_map.keys()
return self.pins
def copy_layout_pin(self, instance, pin_name, new_name=""):
"""

View File

@ -10,6 +10,7 @@ import re
import os
import math
import tech
from globals import OPTS
from pprint import pformat
from delay_data import delay_data
from wire_spice_model import wire_spice_model
@ -32,6 +33,21 @@ class spice():
self.name = name
self.cell_name = cell_name
self.sp_file = OPTS.openram_tech + "sp_lib/" + cell_name + ".sp"
# If we have a separate lvs directory, then all the lvs files
# should be in there (all or nothing!)
try:
lvs_subdir = tech.lvs_lib
except AttributeError:
lvs_subdir = "lvs_lib"
lvs_dir = OPTS.openram_tech + lvs_subdir + "/"
if os.path.exists(lvs_dir):
self.lvs_file = lvs_dir + cell_name + ".sp"
else:
self.lvs_file = self.sp_file
self.valid_signal_types = ["INOUT", "INPUT", "OUTPUT", "POWER", "GROUND"]
# Holds subckts/mods for this module
self.mods = []

View File

@ -84,7 +84,6 @@ class verilog:
self.vf.write("endmodule\n")
self.vf.close()
def register_inputs(self, port):
"""
Register the control signal, address and data inputs.
@ -129,7 +128,7 @@ class verilog:
if port in self.write_ports:
self.vf.write(" din{0}_reg = din{0};\n".format(port))
if port in self.read_ports:
self.vf.write(" dout{0} = {1}'bx;\n".format(port,self.word_size))
self.vf.write(" dout{0} = {1}'bx;\n".format(port, self.word_size))
if port in self.readwrite_ports:
self.vf.write(" if ( !csb{0}_reg && web{0}_reg ) \n".format(port))
self.vf.write(" $display($time,\" Reading %m addr{0}=%b dout{0}=%b\",addr{0}_reg,mem[addr{0}_reg]);\n".format(port))
@ -151,7 +150,6 @@ class verilog:
self.vf.write(" end\n\n")
def add_inputs_outputs(self, port):
"""
Add the module input and output declaration for a port.
@ -191,14 +189,14 @@ class verilog:
if self.write_size:
remainder_bits = self.word_size % self.write_size
for mask in range(0,self.num_wmasks):
for mask in range(0, self.num_wmasks):
lower = mask * self.write_size
if (remainder_bits and mask == self.num_wmasks - 1):
upper = lower + remainder_bits - 1
else:
upper = lower + self.write_size - 1
self.vf.write(" if (wmask{0}_reg[{1}])\n".format(port,mask))
self.vf.write(" mem[addr{0}_reg][{1}:{2}] = din{0}_reg[{1}:{2}];\n".format(port,upper,lower))
self.vf.write(" if (wmask{0}_reg[{1}])\n".format(port, mask))
self.vf.write(" mem[addr{0}_reg][{1}:{2}] = din{0}_reg[{1}:{2}];\n".format(port, upper, lower))
self.vf.write(" end\n")
else:
self.vf.write(" mem[addr{0}_reg] = din{0}_reg;\n".format(port))
@ -220,9 +218,6 @@ class verilog:
self.vf.write(" dout{0} <= #(DELAY) mem[addr{0}_reg];\n".format(port))
self.vf.write(" end\n")
self.vf.write(" always @(csb{0})\n".format(port))
self.vf.write(" dout{0} = 0)\n".format(port))
def add_address_check(self, wport, rport):
""" Output a warning if the two addresses match """
# If the rport is actually reading... and addresses match.
@ -235,8 +230,8 @@ class verilog:
else:
wport_control = "!csb{0}".format(wport)
self.vf.write(" if ({1} && {3} && (addr{0} == addr{2}))\n".format(wport,wport_control,rport,rport_control))
self.vf.write(" $display($time,\" WARNING: Writing and reading addr{0}=%b and addr{1}=%b simultaneously!\",addr{0},addr{1});\n".format(wport,rport))
self.vf.write(" if ({1} && {3} && (addr{0} == addr{2}))\n".format(wport, wport_control, rport, rport_control))
self.vf.write(" $display($time,\" WARNING: Writing and reading addr{0}=%b and addr{1}=%b simultaneously!\",addr{0},addr{1});\n".format(wport, rport))
def add_write_read_checks(self, rport):
"""
@ -247,4 +242,4 @@ class verilog:
if wport == rport:
continue
else:
self.add_address_check(wport,rport)
self.add_address_check(wport, rport)

View File

@ -91,7 +91,7 @@ class bitcell_2port(bitcell_base.bitcell_base):
def build_graph(self, graph, inst_name, port_nets):
"""Adds edges to graph. Multiport bitcell timing graph is too complex
to use the add_graph_edges function."""
pin_dict = {pin: port for pin, port in zip(self.pin_names, port_nets)}
pin_dict = {pin: port for pin, port in zip(self.get_original_pin_names(), port_nets)}
# Edges hardcoded here. Essentially wl->bl/br for both ports.
# Port 0 edges
graph.add_edge(pin_dict["wl0"], pin_dict["bl0"], self)

View File

@ -1120,7 +1120,7 @@ class pbitcell(bitcell_base.bitcell_base):
def get_wl_name(self, port=0):
"""Get wl name by port"""
debug.check(port < 2, "Two ports for bitcell_1rw_1r only.")
debug.check(port < 2, "Two ports for bitcell_2port only.")
return "wl{}".format(port)
def get_stage_effort(self, load):
@ -1163,6 +1163,7 @@ class pbitcell(bitcell_base.bitcell_base):
return
pin_dict = {pin: port for pin, port in zip(self.pins, port_nets)}
# Edges added wl->bl, wl->br for every port except write ports
rw_pin_names = zip(self.r_wl_names, self.r_bl_names, self.r_br_names)
r_pin_names = zip(self.rw_wl_names, self.rw_bl_names, self.rw_br_names)

View File

@ -41,7 +41,7 @@ class replica_bitcell_2port(bitcell_base.bitcell_base):
def build_graph(self, graph, inst_name, port_nets):
"""Adds edges to graph. Multiport bitcell timing graph is too complex
to use the add_graph_edges function."""
pin_dict = {pin: port for pin, port in zip(self.pin_names, port_nets)}
pin_dict = {pin: port for pin, port in zip(self.get_original_pin_names(), port_nets)}
# Edges hardcoded here. Essentially wl->bl/br for both ports.
# Port 0 edges
graph.add_edge(pin_dict["wl0"], pin_dict["bl0"], self)

View File

@ -1,12 +1,22 @@
word_size = 32
num_words = 128
num_rw_ports = 1
num_r_ports = 0
num_w_ports = 0
tech_name = "scn4m_subm"
nominal_corner_only = False
process_corners = ["TT"]
supply_voltages = [5.0]
temperatures = [25]
output_path = "temp"
output_name = "sram_{0}_{1}_{2}".format(word_size, num_words, tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -14,7 +14,10 @@ temperatures = [25]
route_supplies = True
check_lvsdrc = True
output_path = "temp"
output_name = "sram_1rw_1r_{0}_{1}_{2}".format(word_size,
num_words,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -15,7 +15,10 @@ temperatures = [25]
route_supplies = False
check_lvsdrc = True
output_path = "temp"
output_name = "sram_1rw_1r_{0}_{1}_{2}".format(word_size,
num_words,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -15,7 +15,10 @@ temperatures = [25]
# route_supplies = True
check_lvsdrc = True
output_path = "temp"
output_name = "sram_1rw_{0}_{1}_{2}".format(word_size,
num_words,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -14,8 +14,11 @@ temperatures = [25]
route_supplies = True
check_lvsdrc = True
output_path = "temp"
output_name = "sram_1w_1r_{0}_{1}_{2}".format(word_size,
num_words,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -14,8 +14,11 @@ temperatures = [25]
route_supplies = False
check_lvsdrc = True
output_path = "temp"
output_name = "sram_1w_1r_{0}_{1}_{2}".format(word_size,
num_words,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -1,6 +1,11 @@
word_size = 2
num_words = 16
num_rw_ports = 1
num_r_ports = 0
num_w_ports = 0
tech_name = "freepdk45"
nominal_corner_only = False
process_corners = ["TT"]
@ -13,8 +18,11 @@ check_lvsdrc = True
load_scales = [0.5, 1, 4]
slew_scales = [0.5, 1]
output_path = "temp"
output_name = "sram_{0}_{1}_{2}".format(word_size,
num_words,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -1,6 +1,10 @@
word_size = 2
num_words = 16
num_rw_ports = 1
num_r_ports = 0
num_w_ports = 0
tech_name = "scn4m_subm"
nominal_corner_only = False
process_corners = ["TT"]
@ -10,8 +14,11 @@ temperatures = [25]
route_supplies = True
check_lvsdrc = True
output_path = "temp"
output_name = "sram_{0}_{1}_{2}".format(word_size,
num_words,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -1,13 +1,21 @@
word_size = 64
num_words = 1024
num_rw_ports = 1
num_r_ports = 0
num_w_ports = 0
tech_name = "scn4m_subm"
nominal_corner_only = False
process_corners = ["TT"]
supply_voltages = [ 5.0 ]
temperatures = [ 25 ]
supply_voltages = [5.0]
temperatures = [25]
output_path = "temp"
output_name = "sram_{0}_{1}_{2}".format(word_size,
num_words,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -1,14 +1,21 @@
word_size = 16
num_words = 256
num_rw_ports = 1
num_r_ports = 0
num_w_ports = 0
tech_name = "scn4m_subm"
nominal_corner_only = False
process_corners = ["TT"]
supply_voltages = [5.0]
temperatures = [25]
output_path = "temp"
output_name = "sram_{0}_{1}_{2}".format(word_size,
num_words,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -16,11 +16,11 @@ check_lvsdrc = False
perimeter_pins = False
#netlist_only = True
#analytical_delay = False
output_path = "macros/sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -16,11 +16,10 @@ check_lvsdrc = False
perimeter_pins = False
#netlist_only = True
#analytical_delay = False
output_path = "macros/sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -14,11 +14,10 @@ check_lvsdrc = True
perimeter_pins = True
#netlist_only = True
#analytical_delay = False
output_path = "macros/sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -14,11 +14,10 @@ check_lvsdrc = True
perimeter_pins = True
#netlist_only = True
#analytical_delay = False
output_path = "macros/sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -16,11 +16,10 @@ check_lvsdrc = False
perimeter_pins = False
#netlist_only = True
#analytical_delay = False
output_path = "macros/sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -14,11 +14,10 @@ check_lvsdrc = True
perimeter_pins = True
#netlist_only = True
#analytical_delay = False
output_path = "macros/sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -16,11 +16,10 @@ check_lvsdrc = False
perimeter_pins = False
#netlist_only = True
#analytical_delay = False
output_path = "macros/sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -16,11 +16,10 @@ check_lvsdrc = True
perimeter_pins = False
#netlist_only = True
#analytical_delay = False
output_path = "macros/sram_1rw_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_1rw_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -16,11 +16,10 @@ check_lvsdrc = True
perimeter_pins = False
#netlist_only = True
#analytical_delay = False
output_path = "macros/sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -16,11 +16,10 @@ check_lvsdrc = True
perimeter_pins = False
#netlist_only = True
#analytical_delay = False
output_path = "macros/sram_1rw_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_1rw_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -16,11 +16,10 @@ check_lvsdrc = True
perimeter_pins = False
#netlist_only = True
#analytical_delay = False
output_path = "macros/sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -16,11 +16,10 @@ check_lvsdrc = True
perimeter_pins = False
#netlist_only = True
#analytical_delay = False
output_path = "macros/sram_1rw_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_1rw_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -16,11 +16,10 @@ check_lvsdrc = True
perimeter_pins = False
#netlist_only = True
#analytical_delay = False
output_path = "macros/sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_1rw1r_{0}_{1}_{2}_{3}".format(word_size,
num_words,
write_size,
tech_name)
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
num_r_ports,
num_w_ports,
word_size,
num_words,
tech_name)
output_path = "macro/{}".format(output_name)

View File

@ -375,10 +375,7 @@ class bank(design.design):
port=port))
self.add_mod(self.port_address[port])
try:
local_array_size = OPTS.local_array_size
except AttributeError:
local_array_size = 0
local_array_size = OPTS.local_array_size
if local_array_size > 0:
# Find the even multiple that satisfies the fanout with equal sized local arrays

View File

@ -145,11 +145,10 @@ class port_address(design.design):
cols=self.num_cols)
self.add_mod(self.wordline_driver_array)
try:
local_array_size = OPTS.local_array_size
local_array_size = OPTS.local_array_size
if local_array_size > 0:
driver_size = max(int(self.num_cols / local_array_size), 1)
except AttributeError:
local_array_size = 0
else:
# Defautl to FO4
driver_size = max(int(self.num_cols / 4), 1)

View File

@ -30,8 +30,8 @@ class options(optparse.Values):
num_r_ports = 0
num_w_ports = 0
# By default, use local arrays with a max fanout of 16
#local_array_size = 16
# By default, don't use hierarchical wordline
local_array_size = 0
# Write mask size, default will be overwritten with word_size if not user specified
write_size = None

View File

@ -44,11 +44,10 @@ class wordline_driver(design.design):
self.nand = factory.create(module_type="nand2_dec",
height=self.height)
try:
local_array_size = OPTS.local_array_size
local_array_size = OPTS.local_array_size
if local_array_size > 0:
driver_size = max(int(self.cols / local_array_size), 1)
except AttributeError:
local_array_size = 0
else:
# Defautl to FO4
driver_size = max(int(self.cols / 4), 1)