mirror of https://github.com/VLSIDA/OpenRAM.git
Merge branch 'dev' into supply_routing
This commit is contained in:
commit
5248482fab
|
|
@ -6,6 +6,8 @@ import debug
|
|||
import os
|
||||
from globals import OPTS
|
||||
|
||||
total_drc_errors = 0
|
||||
total_lvs_errors = 0
|
||||
|
||||
class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
||||
"""
|
||||
|
|
@ -13,7 +15,6 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
|||
Class consisting of a set of modules and instances of these modules
|
||||
"""
|
||||
name_map = []
|
||||
|
||||
|
||||
def __init__(self, name):
|
||||
try:
|
||||
|
|
@ -28,8 +29,8 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
|||
self.name = name
|
||||
hierarchy_layout.layout.__init__(self, name)
|
||||
hierarchy_spice.spice.__init__(self, name)
|
||||
|
||||
|
||||
|
||||
# Check if the name already exists, if so, give an error
|
||||
# because each reference must be a unique name.
|
||||
# These modules ensure unique names or have no changes if they
|
||||
|
|
@ -73,13 +74,23 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
|||
"""Checks both DRC and LVS for a module"""
|
||||
# Unit tests will check themselves.
|
||||
# Do not run if disabled in options.
|
||||
|
||||
if (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)):
|
||||
|
||||
global total_drc_errors
|
||||
global total_lvs_errors
|
||||
tempspice = OPTS.openram_temp + "/temp.sp"
|
||||
tempgds = OPTS.openram_temp + "/temp.gds"
|
||||
self.sp_write(tempspice)
|
||||
self.gds_write(tempgds)
|
||||
debug.check(verify.run_drc(self.name, tempgds, final_verification) == 0,"DRC failed for {0}".format(self.name))
|
||||
debug.check(verify.run_lvs(self.name, tempgds, tempspice, final_verification) == 0,"LVS failed for {0}".format(self.name))
|
||||
|
||||
num_drc_errors = verify.run_drc(self.name, tempgds, final_verification)
|
||||
num_lvs_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification)
|
||||
debug.check(num_drc_errors == 0,"DRC failed for {0} with {1} error(s)".format(self.name,num_drc_errors))
|
||||
debug.check(num_lvs_errors == 0,"LVS failed for {0} with {1} errors(s)".format(self.name,num_lvs_errors))
|
||||
total_drc_errors += num_drc_errors
|
||||
total_lvs_errors += num_lvs_errors
|
||||
|
||||
os.remove(tempspice)
|
||||
os.remove(tempgds)
|
||||
|
||||
|
|
@ -87,22 +98,31 @@ class hierarchy_design(hierarchy_spice.spice, hierarchy_layout.layout):
|
|||
"""Checks DRC for a module"""
|
||||
# Unit tests will check themselves.
|
||||
# Do not run if disabled in options.
|
||||
|
||||
if (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)):
|
||||
global total_drc_errors
|
||||
tempgds = OPTS.openram_temp + "/temp.gds"
|
||||
self.gds_write(tempgds)
|
||||
debug.check(verify.run_drc(self.name, tempgds, final_verification) == 0,"DRC failed for {0}".format(self.name))
|
||||
num_errors = verify.run_drc(self.name, tempgds, final_verification)
|
||||
total_drc_errors += num_errors
|
||||
debug.check(num_errors == 0,"DRC failed for {0} with {1} error(s)".format(self.name,num_error))
|
||||
|
||||
os.remove(tempgds)
|
||||
|
||||
def LVS(self, final_verification=False):
|
||||
"""Checks LVS for a module"""
|
||||
# Unit tests will check themselves.
|
||||
# Do not run if disabled in options.
|
||||
|
||||
if (not OPTS.is_unit_test and OPTS.check_lvsdrc and (OPTS.inline_lvsdrc or final_verification)):
|
||||
global total_lvs_errors
|
||||
tempspice = OPTS.openram_temp + "/temp.sp"
|
||||
tempgds = OPTS.openram_temp + "/temp.gds"
|
||||
self.sp_write(tempspice)
|
||||
self.gds_write(tempgds)
|
||||
debug.check(verify.run_lvs(self.name, tempgds, tempspice, final_verification) == 0,"LVS failed for {0}".format(self.name))
|
||||
num_errors = verify.run_lvs(self.name, tempgds, tempspice, final_verification)
|
||||
total_lvs_errors += num_errors
|
||||
debug.check(num_errors == 0,"LVS failed for {0} with {1} error(s)".format(self.name,num_errors))
|
||||
os.remove(tempspice)
|
||||
os.remove(tempgds)
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ class lib:
|
|||
debug.info(1,"Writing to {0}".format(lib_name))
|
||||
self.characterize()
|
||||
self.lib.close()
|
||||
self.parse_info()
|
||||
self.parse_info(self.corner,lib_name)
|
||||
def characterize(self):
|
||||
""" Characterize the current corner. """
|
||||
|
||||
|
|
@ -503,36 +503,132 @@ class lib:
|
|||
self.times = self.sh.analyze(self.slews,self.slews)
|
||||
|
||||
|
||||
def parse_info(self):
|
||||
def parse_info(self,corner,lib_name):
|
||||
""" Copies important characterization data to datasheet.info to be added to datasheet """
|
||||
if OPTS.is_unit_test:
|
||||
return
|
||||
datasheet = open(OPTS.openram_temp +'/datasheet.info', 'a+')
|
||||
|
||||
for (corner, lib_name) in zip(self.corners, self.lib_files):
|
||||
|
||||
# ports = ""
|
||||
# if OPTS.num_rw_ports>0:
|
||||
# ports += "{}_".format(OPTS.num_rw_ports)
|
||||
# if OPTS.num_w_ports>0:
|
||||
# ports += "{}_".format(OPTS.num_w_ports)
|
||||
# if OPTS.num_r_ports>0:
|
||||
# ports += "{}_".format(OPTS.num_r_ports)
|
||||
git_id = 'AAAAAAAAAAAAAAAAAAAA'
|
||||
else:
|
||||
with open(os.devnull, 'wb') as devnull:
|
||||
proc = subprocess.Popen(['git','rev-parse','HEAD'], stdout=subprocess.PIPE)
|
||||
git_id = str(proc.stdout.read())
|
||||
git_id = git_id[2:-3]
|
||||
|
||||
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13}".format("sram_{0}_{1}_{2}".format(OPTS.word_size, OPTS.num_words, OPTS.tech_name),
|
||||
OPTS.num_words,
|
||||
OPTS.num_banks,
|
||||
OPTS.num_rw_ports,
|
||||
OPTS.num_w_ports,
|
||||
OPTS.num_r_ports,
|
||||
OPTS.tech_name,
|
||||
self.corner[1],
|
||||
self.corner[2],
|
||||
self.corner[0],
|
||||
round_time(self.char_sram_results["min_period"]),
|
||||
self.out_dir,
|
||||
lib_name,
|
||||
OPTS.word_size))
|
||||
datasheet = open(OPTS.openram_temp +'/datasheet.info', 'a+')
|
||||
|
||||
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},".format(
|
||||
"sram_{0}_{1}_{2}".format(OPTS.word_size, OPTS.num_words, OPTS.tech_name),
|
||||
OPTS.num_words,
|
||||
OPTS.num_banks,
|
||||
OPTS.num_rw_ports,
|
||||
OPTS.num_w_ports,
|
||||
OPTS.num_r_ports,
|
||||
OPTS.tech_name,
|
||||
corner[2],
|
||||
corner[1],
|
||||
corner[0],
|
||||
round_time(self.char_sram_results["min_period"]),
|
||||
self.out_dir,
|
||||
lib_name,
|
||||
OPTS.word_size,
|
||||
git_id
|
||||
))
|
||||
|
||||
for port in self.all_ports:
|
||||
#DIN timings
|
||||
if port in self.write_ports:
|
||||
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
|
||||
"DIN{1}[{0}:0]".format(self.sram.word_size - 1, port),
|
||||
min(list(map(round_time,self.times["setup_times_LH"]))),
|
||||
max(list(map(round_time,self.times["setup_times_LH"]))),
|
||||
|
||||
min(list(map(round_time,self.times["setup_times_HL"]))),
|
||||
max(list(map(round_time,self.times["setup_times_HL"]))),
|
||||
|
||||
min(list(map(round_time,self.times["hold_times_LH"]))),
|
||||
max(list(map(round_time,self.times["hold_times_LH"]))),
|
||||
|
||||
min(list(map(round_time,self.times["hold_times_HL"]))),
|
||||
max(list(map(round_time,self.times["hold_times_HL"])))
|
||||
|
||||
))
|
||||
|
||||
for port in self.all_ports:
|
||||
#DOUT timing
|
||||
if port in self.read_ports:
|
||||
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
|
||||
"DOUT{1}[{0}:0]".format(self.sram.word_size - 1, port),
|
||||
min(list(map(round_time,self.char_port_results[port]["delay_lh"]))),
|
||||
max(list(map(round_time,self.char_port_results[port]["delay_lh"]))),
|
||||
|
||||
min(list(map(round_time,self.char_port_results[port]["delay_hl"]))),
|
||||
max(list(map(round_time,self.char_port_results[port]["delay_hl"]))),
|
||||
|
||||
min(list(map(round_time,self.char_port_results[port]["slew_lh"]))),
|
||||
max(list(map(round_time,self.char_port_results[port]["slew_lh"]))),
|
||||
|
||||
min(list(map(round_time,self.char_port_results[port]["slew_hl"]))),
|
||||
max(list(map(round_time,self.char_port_results[port]["slew_hl"])))
|
||||
|
||||
|
||||
))
|
||||
|
||||
for port in self.all_ports:
|
||||
#CSb timings
|
||||
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
|
||||
"CSb{0}".format(port),
|
||||
min(list(map(round_time,self.times["setup_times_LH"]))),
|
||||
max(list(map(round_time,self.times["setup_times_LH"]))),
|
||||
|
||||
min(list(map(round_time,self.times["setup_times_HL"]))),
|
||||
max(list(map(round_time,self.times["setup_times_HL"]))),
|
||||
|
||||
min(list(map(round_time,self.times["hold_times_LH"]))),
|
||||
max(list(map(round_time,self.times["hold_times_LH"]))),
|
||||
|
||||
min(list(map(round_time,self.times["hold_times_HL"]))),
|
||||
max(list(map(round_time,self.times["hold_times_HL"])))
|
||||
|
||||
))
|
||||
|
||||
for port in self.all_ports:
|
||||
#ADDR timings
|
||||
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
|
||||
"ADDR{1}[{0}:0]".format(self.sram.addr_size - 1, port),
|
||||
min(list(map(round_time,self.times["setup_times_LH"]))),
|
||||
max(list(map(round_time,self.times["setup_times_LH"]))),
|
||||
|
||||
min(list(map(round_time,self.times["setup_times_HL"]))),
|
||||
max(list(map(round_time,self.times["setup_times_HL"]))),
|
||||
|
||||
min(list(map(round_time,self.times["hold_times_LH"]))),
|
||||
max(list(map(round_time,self.times["hold_times_LH"]))),
|
||||
|
||||
min(list(map(round_time,self.times["hold_times_HL"]))),
|
||||
max(list(map(round_time,self.times["hold_times_HL"])))
|
||||
|
||||
))
|
||||
|
||||
|
||||
for port in self.all_ports:
|
||||
if port in self.readwrite_ports:
|
||||
|
||||
#WEb timings
|
||||
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
|
||||
"WEb{0}".format(port),
|
||||
min(list(map(round_time,self.times["setup_times_LH"]))),
|
||||
max(list(map(round_time,self.times["setup_times_LH"]))),
|
||||
|
||||
min(list(map(round_time,self.times["setup_times_HL"]))),
|
||||
max(list(map(round_time,self.times["setup_times_HL"]))),
|
||||
|
||||
min(list(map(round_time,self.times["hold_times_LH"]))),
|
||||
max(list(map(round_time,self.times["hold_times_LH"]))),
|
||||
|
||||
min(list(map(round_time,self.times["hold_times_HL"]))),
|
||||
max(list(map(round_time,self.times["hold_times_HL"])))
|
||||
|
||||
))
|
||||
|
||||
|
||||
datasheet.write("END\n")
|
||||
datasheet.close()
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
<style>
|
||||
#data {
|
||||
font-family: Trebuchet MS, Arial, Helvetica, sans-serif;
|
||||
border-collapse: collapse;
|
||||
width: 99%;
|
||||
max-width: 799px
|
||||
}
|
||||
|
||||
#data td, #data th {
|
||||
border: 0px solid #ddd;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
#data tr:nth-child(even){background-color: #f1f2f2;}
|
||||
|
||||
#data tr:hover {background-color: #ddd;}
|
||||
|
||||
#data th {
|
||||
padding-top: 11px;
|
||||
padding-bottom: 11px;
|
||||
text-align: left;
|
||||
background-color: #004184;
|
||||
color: #F1B521;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
|
|
@ -1,6 +1,9 @@
|
|||
from flask_table import *
|
||||
|
||||
class characterization_corners(Table):
|
||||
"""
|
||||
Set up characterization corners table columns and title information
|
||||
"""
|
||||
corner_name = Col('Corner Name')
|
||||
process = Col('Process')
|
||||
power_supply = Col('Power Supply')
|
||||
|
|
@ -8,6 +11,9 @@ class characterization_corners(Table):
|
|||
library_name_suffix = Col('Library Name Suffix')
|
||||
|
||||
class characterization_corners_item(object):
|
||||
"""
|
||||
Defines the contents of a charcaterization corner table row
|
||||
"""
|
||||
def __init__(self, corner_name, process, power_supply, temperature, library_name_suffix):
|
||||
self.corner_name = corner_name
|
||||
self.process = process
|
||||
|
|
|
|||
|
|
@ -4,11 +4,17 @@ from characterization_corners import *
|
|||
from deliverables import *
|
||||
from timing_and_current_data import *
|
||||
from in_out import *
|
||||
from hierarchy_design import total_drc_errors
|
||||
from hierarchy_design import total_lvs_errors
|
||||
import os
|
||||
import csv
|
||||
import base64
|
||||
from globals import OPTS
|
||||
|
||||
class datasheet():
|
||||
|
||||
"""
|
||||
Defines the layout,but not the data, of the html datasheet
|
||||
"""
|
||||
def __init__(self,identifier):
|
||||
self.io = []
|
||||
self.corners = []
|
||||
|
|
@ -20,50 +26,63 @@ class datasheet():
|
|||
|
||||
|
||||
def generate_html(self):
|
||||
self.html = """<style>
|
||||
#data {
|
||||
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
max-width: 800px
|
||||
}
|
||||
"""
|
||||
Generates html tables using flask-table
|
||||
"""
|
||||
with open(os.path.abspath(os.environ.get("OPENRAM_HOME")) + '/datasheet/assets/datasheet.css', 'r') as datasheet_css:
|
||||
#css styling is kept in a seperate file
|
||||
self.html += datasheet_css.read()
|
||||
|
||||
#data td, #data th {
|
||||
border: 1px solid #ddd;
|
||||
padding: 8px;
|
||||
}
|
||||
if OPTS.check_lvsdrc:
|
||||
|
||||
DRC = str(total_drc_errors) + ' errors'
|
||||
LVS = str(total_lvs_errors) + ' errors'
|
||||
PEX = 'n/a'
|
||||
else:
|
||||
DRC = 'skipped'
|
||||
LVS = 'skipped'
|
||||
PEX = 'skipped'
|
||||
|
||||
with open(OPTS.openram_temp + "/datasheet.info") as info:
|
||||
self.html += '<!--'
|
||||
for row in info:
|
||||
self.html += row
|
||||
self.html +='-->'
|
||||
|
||||
vlsi_logo = 0
|
||||
with open(os.path.abspath(os.environ.get("OPENRAM_HOME")) + '/datasheet/assets/vlsi_logo.png' , "rb") as image_file:
|
||||
vlsi_logo = base64.b64encode(image_file.read())
|
||||
|
||||
#data tr:nth-child(even){background-color: #f2f2f2;}
|
||||
openram_logo = 0
|
||||
with open(os.path.abspath(os.environ.get("OPENRAM_HOME")) + '/datasheet/assets/openram_logo_placeholder.png' , "rb") as image_file:
|
||||
openram_logo = base64.b64encode(image_file.read())
|
||||
|
||||
#data tr:hover {background-color: #ddd;}
|
||||
|
||||
#data th {
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
text-align: left;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
}
|
||||
</style>"""
|
||||
self.html +='<p style=font-size: 20px;font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;>'+ self.name + '.html' + '</p>'
|
||||
# self.html +='<p style=font-size: 20px;font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;>{0}</p>'
|
||||
# self.html +='<p style=font-size: 20px;font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;>{0}</p>'
|
||||
self.html += '<a href="https://vlsida.soe.ucsc.edu/"><img src="data:image/png;base64,{0}" alt="VLSIDA"></a><a href="https://vlsida.github.io/OpenRAM"><img src="data:image/png;base64,{1}"="OpenRAM"></a>'.format(str(vlsi_logo)[2:-1],str(openram_logo)[2:-1])
|
||||
|
||||
|
||||
self.html +='<p style=font-size: 20px;font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;>Ports and Configuration (DEBUG)</p>'
|
||||
|
||||
|
||||
|
||||
self.html +='<p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">'+ self.name + '.html' + '</p>'
|
||||
self.html +='<p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">'+ 'DRC: ' + str(DRC) + '</p>'
|
||||
self.html +='<p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">'+ 'LVS: ' + str(LVS) + '</p>'
|
||||
self.html += '<p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">'+ 'Git commit id: ' + str(self.git_id) + '</p>'
|
||||
|
||||
self.html +='<p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Ports and Configuration (DEBUG)</p>'
|
||||
self.html += in_out(self.io,table_id='data').__html__().replace('<','<').replace('"','"').replace('>',">")
|
||||
|
||||
self.html +='<p style=font-size: 20px;font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;>Operating Conditions</p>'
|
||||
self.html +='<p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Operating Conditions</p>'
|
||||
self.html += operating_conditions(self.operating,table_id='data').__html__()
|
||||
|
||||
self.html += '<p style=font-size: 20px;font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;>Timing and Current Data</p>'
|
||||
self.html += '<p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Timing and Current Data</p>'
|
||||
self.html += timing_and_current_data(self.timing,table_id='data').__html__()
|
||||
|
||||
self.html += '<p style=font-size: 20px;font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;>Characterization Corners</p>'
|
||||
self.html += '<p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Characterization Corners</p>'
|
||||
self.html += characterization_corners(self.corners,table_id='data').__html__()
|
||||
|
||||
self.html +='<p style=font-size: 20px;font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;>Deliverables</p>'
|
||||
self.html +='<p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Deliverables</p>'
|
||||
self.html += deliverables(self.dlv,table_id='data').__html__().replace('<','<').replace('"','"').replace('>',">")
|
||||
|
||||
self.html +='<p style=font-size: 20px;font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;>*Feature only supported with characterizer</p>'
|
||||
|
||||
self.html +='<img src=' + os.path.abspath(os.environ.get("OPENRAM_HOME")) + '/datasheet/assets/vlsi_logo.png alt="VLSIDA" />'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Datasheet Generator
|
||||
|
||||
TODO:
|
||||
locate all port elements in .lib
|
||||
Locate all timing elements in .lib
|
||||
Diagram generation
|
||||
Improve css
|
||||
This is a script to load data from the characterization and layout processes into
|
||||
a web friendly html datasheet. This script requres the python-flask and flask-table
|
||||
packages to be installed.
|
||||
"""
|
||||
#TODO:
|
||||
#locate all port elements in .lib
|
||||
#Locate all timing elements in .lib
|
||||
#Diagram generation
|
||||
#Improve css
|
||||
|
||||
|
||||
import debug
|
||||
from globals import OPTS
|
||||
|
||||
|
|
@ -24,10 +27,13 @@ if OPTS.datasheet_gen:
|
|||
from in_out import *
|
||||
else:
|
||||
debug.warning("Python library flask_table not found. Skipping html datasheet generation. This can be installed with pip install flask-table.")
|
||||
|
||||
#make sure appropriate python libraries are installed
|
||||
|
||||
|
||||
def process_name(corner):
|
||||
"""
|
||||
Expands the names of the characterization corner types into something human friendly
|
||||
"""
|
||||
if corner == "TT":
|
||||
return "Typical - Typical"
|
||||
if corner == "SS":
|
||||
|
|
@ -37,34 +43,76 @@ def process_name(corner):
|
|||
else:
|
||||
return "custom"
|
||||
|
||||
def parse_file(f,pages):
|
||||
def parse_characterizer_csv(sram,f,pages):
|
||||
"""
|
||||
Parses output data of the Liberty file generator in order to construct the timing and
|
||||
current table
|
||||
"""
|
||||
with open(f) as csv_file:
|
||||
csv_reader = csv.reader(csv_file, delimiter=',')
|
||||
line_count = 0
|
||||
for row in csv_reader:
|
||||
|
||||
found = 0
|
||||
NAME = row[0]
|
||||
NUM_WORDS = row[1]
|
||||
NUM_BANKS = row[2]
|
||||
NUM_RW_PORTS = row[3]
|
||||
NUM_W_PORTS = row[4]
|
||||
NUM_R_PORTS = row[5]
|
||||
TECH_NAME = row[6]
|
||||
TEMP = row[8]
|
||||
VOLT = row[7]
|
||||
PROC = row[9]
|
||||
MIN_PERIOD = row[10]
|
||||
OUT_DIR = row[11]
|
||||
LIB_NAME = row[12]
|
||||
WORD_SIZE = row[13]
|
||||
col = 0
|
||||
|
||||
#defines layout of csv file
|
||||
NAME = row[col]
|
||||
col += 1
|
||||
|
||||
NUM_WORDS = row[col]
|
||||
col += 1
|
||||
|
||||
NUM_BANKS = row[col]
|
||||
col += 1
|
||||
|
||||
NUM_RW_PORTS = row[col]
|
||||
col += 1
|
||||
|
||||
NUM_W_PORTS = row[col]
|
||||
col += 1
|
||||
|
||||
NUM_R_PORTS = row[col]
|
||||
col += 1
|
||||
|
||||
TECH_NAME = row[col]
|
||||
col += 1
|
||||
|
||||
TEMP = row[col]
|
||||
col += 1
|
||||
|
||||
VOLT = row[col]
|
||||
col += 1
|
||||
|
||||
PROC = row[col]
|
||||
col += 1
|
||||
|
||||
MIN_PERIOD = row[col]
|
||||
col += 1
|
||||
|
||||
OUT_DIR = row[col]
|
||||
col += 1
|
||||
|
||||
LIB_NAME = row[col]
|
||||
col += 1
|
||||
|
||||
WORD_SIZE = row[col]
|
||||
col += 1
|
||||
|
||||
ORIGIN_ID = row[col]
|
||||
col += 1
|
||||
|
||||
|
||||
for sheet in pages:
|
||||
|
||||
|
||||
if sheet.name == row[0]:
|
||||
if sheet.name == NAME:
|
||||
|
||||
found = 1
|
||||
#if the .lib information is for an existing datasheet compare timing data
|
||||
|
||||
for item in sheet.operating:
|
||||
#check if the new corner data is worse than the previous worse corner data
|
||||
|
||||
if item.parameter == 'Operating Temperature':
|
||||
if float(TEMP) > float(item.max):
|
||||
|
|
@ -91,52 +139,345 @@ def parse_file(f,pages):
|
|||
|
||||
|
||||
|
||||
while(True):
|
||||
if(row[col].startswith('DIN')):
|
||||
start = col
|
||||
for item in sheet.timing:
|
||||
if item.parameter.startswith(row[col]):
|
||||
|
||||
if item.parameter.endswith('setup rising'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
elif item.parameter.endswith('setup falling'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
elif item.parameter.endswith('hold rising'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
elif item.parameter.endswith('hold falling'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
col += 1
|
||||
|
||||
elif(row[col].startswith('DOUT')):
|
||||
start = col
|
||||
for item in sheet.timing:
|
||||
if item.parameter.startswith(row[col]):
|
||||
|
||||
if item.parameter.endswith('cell rise'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
elif item.parameter.endswith('cell fall'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
elif item.parameter.endswith('rise transition'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
elif item.parameter.endswith('fall transition'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
col += 1
|
||||
|
||||
elif(row[col].startswith('CSb')):
|
||||
start = col
|
||||
for item in sheet.timing:
|
||||
if item.parameter.startswith(row[col]):
|
||||
|
||||
if item.parameter.endswith('setup rising'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
elif item.parameter.endswith('setup falling'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
elif item.parameter.endswith('hold rising'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
elif item.parameter.endswith('hold falling'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
col += 1
|
||||
|
||||
|
||||
elif(row[col].startswith('WEb')):
|
||||
start = col
|
||||
for item in sheet.timing:
|
||||
if item.parameter.startswith(row[col]):
|
||||
|
||||
if item.parameter.endswith('setup rising'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
elif item.parameter.endswith('setup falling'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
elif item.parameter.endswith('hold rising'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
elif item.parameter.endswith('hold falling'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
col += 1
|
||||
|
||||
|
||||
elif(row[col].startswith('ADDR')):
|
||||
start = col
|
||||
for item in sheet.timing:
|
||||
if item.parameter.startswith(row[col]):
|
||||
|
||||
if item.parameter.endswith('setup rising'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
elif item.parameter.endswith('setup falling'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
elif item.parameter.endswith('hold rising'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
elif item.parameter.endswith('hold falling'):
|
||||
if float(row[col+1]) < float(item.min):
|
||||
item.min = row[col+1]
|
||||
if float(row[col+2]) > float(item.max):
|
||||
item.max = row[col+2]
|
||||
|
||||
col += 2
|
||||
|
||||
col += 1
|
||||
else:
|
||||
break
|
||||
|
||||
|
||||
#regardless of if there is already a corner for the current sram, append the new corner to the datasheet
|
||||
new_sheet.corners.append(characterization_corners_item(PROC,process_name(PROC),VOLT,TEMP,LIB_NAME.replace(OUT_DIR,'').replace(NAME,'')))
|
||||
new_sheet.dlv.append(deliverables_item('.lib','Synthesis models','<a href="file://{0}">{1}</a>'.format(LIB_NAME,LIB_NAME.replace(OUT_DIR,''))))
|
||||
|
||||
if found == 0:
|
||||
|
||||
#if this is the first corner for this sram, run first time configuration and set up tables
|
||||
new_sheet = datasheet(NAME)
|
||||
pages.append(new_sheet)
|
||||
|
||||
new_sheet.git_id = ORIGIN_ID
|
||||
|
||||
new_sheet.corners.append(characterization_corners_item(PROC,process_name(PROC),VOLT,TEMP,LIB_NAME.replace(OUT_DIR,'').replace(NAME,'')))
|
||||
|
||||
new_sheet.operating.append(operating_conditions_item('Power supply (VDD) range',VOLT,VOLT,VOLT,'Volts'))
|
||||
new_sheet.operating.append(operating_conditions_item('Operating Temperature',TEMP,TEMP,TEMP,'Celsius'))
|
||||
try:
|
||||
new_sheet.operating.append(operating_conditions_item('Operating Frequency (F)*','','',str(math.floor(1000/float(MIN_PERIOD))),'MHz'))
|
||||
new_sheet.operating.append(operating_conditions_item('Operating Frequency (F)','','',str(math.floor(1000/float(MIN_PERIOD))),'MHz'))
|
||||
except Exception:
|
||||
new_sheet.operating.append(operating_conditions_item('Operating Frequency (F)*','','',"unknown",'MHz')) #analytical model fails to provide MIN_PERIOD
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('Cycle time','2','3','4'))
|
||||
new_sheet.timing.append(timing_and_current_data_item('Access time','2','3','4'))
|
||||
new_sheet.timing.append(timing_and_current_data_item('Positive clk setup','2','3','4'))
|
||||
new_sheet.timing.append(timing_and_current_data_item('Positive clk hold','2','3','4'))
|
||||
new_sheet.timing.append(timing_and_current_data_item('RW setup','2','3','4'))
|
||||
new_sheet.timing.append(timing_and_current_data_item('RW hold','2','3','4'))
|
||||
new_sheet.timing.append(timing_and_current_data_item('AC current','2','3','4'))
|
||||
new_sheet.timing.append(timing_and_current_data_item('Standby current','2','3','4'))
|
||||
new_sheet.timing.append(timing_and_current_data_item('Area','2','3','4'))
|
||||
|
||||
|
||||
new_sheet.dlv.append(deliverables_item('.sp','SPICE netlists','<a href="file://{0}{1}.{2}">{1}.{2}</a>'.format(OUT_DIR,NAME,'sp')))
|
||||
new_sheet.dlv.append(deliverables_item('.v','Verilog simulation models','<a href="file://{0}{1}.{2}">{1}.{2}</a>'.format(OUT_DIR,NAME,'v')))
|
||||
new_sheet.dlv.append(deliverables_item('.gds','GDSII layout views','<a href="file://{0}{1}.{2}">{1}.{2}</a>'.format(OUT_DIR,NAME,'gds')))
|
||||
new_sheet.dlv.append(deliverables_item('.lef','LEF files','<a href="file://{0}{1}.{2}">{1}.{2}</a>'.format(OUT_DIR,NAME,'lef')))
|
||||
new_sheet.dlv.append(deliverables_item('.lib','Synthesis models','<a href="file://{0}">{1}</a>'.format(LIB_NAME,LIB_NAME.replace(OUT_DIR,''))))
|
||||
new_sheet.operating.append(operating_conditions_item('Operating Frequency (F)','','',"not available in netlist only",'MHz')) #failed to provide non-zero MIN_PERIOD
|
||||
|
||||
|
||||
while(True):
|
||||
if(row[col].startswith('DIN')):
|
||||
start = col
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
col +=1
|
||||
|
||||
elif(row[col].startswith('DOUT')):
|
||||
start = col
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} cell rise'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} cell fall'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} rise transition'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} fall transition'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
col +=1
|
||||
|
||||
elif(row[col].startswith('CSb')):
|
||||
start = col
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
col +=1
|
||||
|
||||
elif(row[col].startswith('WEb')):
|
||||
start = col
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
col +=1
|
||||
|
||||
elif(row[col].startswith('ADDR')):
|
||||
start = col
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
new_sheet.timing.append(timing_and_current_data_item('{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns'))
|
||||
col += 2
|
||||
|
||||
col +=1
|
||||
else:
|
||||
break
|
||||
|
||||
|
||||
|
||||
|
||||
if not OPTS.netlist_only:
|
||||
#physical layout files should not be generated in netlist only mode
|
||||
new_sheet.dlv.append(deliverables_item('.gds','GDSII layout views','<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name,'gds')))
|
||||
new_sheet.dlv.append(deliverables_item('.lef','LEF files','<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name,'lef')))
|
||||
|
||||
|
||||
new_sheet.dlv.append(deliverables_item('.sp','SPICE netlists','<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name,'sp')))
|
||||
new_sheet.dlv.append(deliverables_item('.v','Verilog simulation models','<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name,'v')))
|
||||
new_sheet.dlv.append(deliverables_item('.html','This datasheet','<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name,'html')))
|
||||
new_sheet.dlv.append(deliverables_item('.lib','Synthesis models','<a href="{1}">{1}</a>'.format(LIB_NAME,LIB_NAME.replace(OUT_DIR,''))))
|
||||
new_sheet.dlv.append(deliverables_item('.py','OpenRAM configuration file','<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name,'py')))
|
||||
|
||||
|
||||
|
||||
#debug table for multiport information
|
||||
new_sheet.io.append(in_out_item('WORD_SIZE',WORD_SIZE))
|
||||
new_sheet.io.append(in_out_item('NUM_WORDS',NUM_WORDS))
|
||||
new_sheet.io.append(in_out_item('NUM_BANKS',NUM_BANKS))
|
||||
new_sheet.io.append(in_out_item('NUM_RW_PORTS',NUM_RW_PORTS))
|
||||
new_sheet.io.append(in_out_item('NUM_R_PORTS',NUM_R_PORTS))
|
||||
new_sheet.io.append(in_out_item('NUM_W_PORTS',NUM_W_PORTS))
|
||||
new_sheet.io.append(in_out_item('Area',sram.width * sram.height))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class datasheet_gen():
|
||||
def datasheet_write(name):
|
||||
def datasheet_write(sram,name):
|
||||
|
||||
if OPTS.datasheet_gen:
|
||||
in_dir = OPTS.openram_temp
|
||||
|
|
@ -144,11 +485,9 @@ class datasheet_gen():
|
|||
if not (os.path.isdir(in_dir)):
|
||||
os.mkdir(in_dir)
|
||||
|
||||
#if not (os.path.isdir(out_dir)):
|
||||
# os.mkdir(out_dir)
|
||||
|
||||
datasheets = []
|
||||
parse_file(in_dir + "/datasheet.info", datasheets)
|
||||
parse_characterizer_csv(sram, in_dir + "/datasheet.info", datasheets)
|
||||
|
||||
|
||||
for sheets in datasheets:
|
||||
|
|
|
|||
|
|
@ -1,12 +1,18 @@
|
|||
from flask_table import *
|
||||
|
||||
class deliverables(Table):
|
||||
"""
|
||||
Set up delivarables table columns and title information
|
||||
"""
|
||||
typ = Col('Type')
|
||||
description = Col('Description')
|
||||
link = Col('Link')
|
||||
|
||||
|
||||
class deliverables_item(object):
|
||||
"""
|
||||
Define deliverables table row elemenent information
|
||||
"""
|
||||
def __init__(self, typ, description,link):
|
||||
self.typ = typ
|
||||
self.description = description
|
||||
|
|
|
|||
|
|
@ -1,11 +1,17 @@
|
|||
from flask_table import *
|
||||
|
||||
class in_out(Table):
|
||||
"""
|
||||
Set up I/O table columns and title information for multiport debugging
|
||||
"""
|
||||
typ = Col('Type')
|
||||
description = Col('Description')
|
||||
|
||||
|
||||
class in_out_item(object):
|
||||
"""
|
||||
Define table row element for I/O table
|
||||
"""
|
||||
def __init__(self, typ, description):
|
||||
self.typ = typ
|
||||
self.description = description
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
from flask_table import *
|
||||
|
||||
class operating_conditions(Table):
|
||||
"""
|
||||
Set up operating conditions columns and title information
|
||||
"""
|
||||
parameter = Col('Parameter')
|
||||
min = Col('Min')
|
||||
typ = Col('Typ')
|
||||
|
|
@ -8,6 +11,9 @@ class operating_conditions(Table):
|
|||
units = Col('Units')
|
||||
|
||||
class operating_conditions_item(object):
|
||||
"""
|
||||
Define operating conditions table row element
|
||||
"""
|
||||
def __init__(self, parameter, min, typ, max, units):
|
||||
self.parameter = parameter
|
||||
self.min = min
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
import os
|
||||
import jinja2
|
||||
from flask import Flask, render_template
|
||||
from filelist import *
|
||||
|
||||
|
||||
filedir = './files'
|
||||
file_data = './filelist.info'
|
||||
|
||||
|
||||
app = Flask('server_scripts')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
files = filelist()
|
||||
|
||||
files.update_filelist(filedir,file_data)
|
||||
|
||||
f = open('./index.html','w')
|
||||
with app.app_context():
|
||||
f.write(render_template('index.html', filedir = filedir , os = os))
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
class deliverable:
|
||||
def __init__(self, name, file_type, path, size):
|
||||
self.name = name
|
||||
self.file_type = file_type
|
||||
self.path = path
|
||||
self.size = size
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import os
|
||||
from deliverable import *
|
||||
class filelist:
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.list = []
|
||||
|
||||
def update_filelist(self,path,outdir):
|
||||
out_file = open(outdir,'w')
|
||||
for root, dirs, files in os.walk(path):
|
||||
for file in files:
|
||||
self.list.append(root + '/' + file)
|
||||
out_file.write('{}/{}\n'.format(root,file))
|
||||
#print('{}/{}'.format(root,file))
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1,116 @@
|
|||
<style>
|
||||
#data {
|
||||
font-family: Trebuchet MS, Arial, Helvetica, sans-serif;
|
||||
border-collapse: collapse;
|
||||
width: 99%;
|
||||
max-width: 799px
|
||||
}
|
||||
|
||||
#data td, #data th {
|
||||
border: 0px solid #ddd;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
#data tr:nth-child(even){background-color: #f1f2f2;}
|
||||
|
||||
#data tr:hover {background-color: #ddd;}
|
||||
|
||||
#data th {
|
||||
padding-top: 11px;
|
||||
padding-bottom: 11px;
|
||||
text-align: left;
|
||||
background-color: #004184;
|
||||
color: #F1B521;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<!--sram_2_16_scn4m_subm,16,1,1,1,1,scn4m_subm,25,5.0,TT,0,/home/jesse/clones/PrivateRAM/compiler/temp/,/home/jesse/clones/PrivateRAM/compiler/temp/sram_2_16_scn4m_subm_TT_5p0V_25C.lib,2,DIN0[1:0],0.009,0.009,0.009,0.009,0.001,0.001,0.001,0.001,DIN1[1:0],0.009,0.009,0.009,0.009,0.001,0.001,0.001,0.001,DOUT0[1:0],0.079,0.079,0.079,0.079,0.001,0.001,0.001,0.001,DOUT2[1:0],0.079,0.079,0.079,0.079,0.001,0.001,0.001,0.001,CSb0,0.009,0.009,0.009,0.009,0.001,0.001,0.001,0.001,CSb1,0.009,0.009,0.009,0.009,0.001,0.001,0.001,0.001,CSb2,0.009,0.009,0.009,0.009,0.001,0.001,0.001,0.001,ADDR0[3:0],0.009,0.009,0.009,0.009,0.001,0.001,0.001,0.001,ADDR1[3:0],0.009,0.009,0.009,0.009,0.001,0.001,0.001,0.001,ADDR2[3:0],0.009,0.009,0.009,0.009,0.001,0.001,0.001,0.001,WEb0,0.009,0.009,0.009,0.009,0.001,0.001,0.001,0.001,END
|
||||
--><a href="https://vlsida.soe.ucsc.edu/"><img src=/home/jesse/clones/PrivateRAM/compiler/datasheet/assets/vlsi_logo.png alt="VLSIDA"></a><a href="https://vlsida.github.io/OpenRAM"><img src=/home/jesse/clones/PrivateRAM/compiler/datasheet/assets/openram_logo_placeholder.png alt="OpenRAM"></a><p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">sram_2_16_scn4m_subm.html</p><p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">DRC: skipped</p><p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">LVS: skipped</p><p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Ports and Configuration (DEBUG)</p><table id="data">
|
||||
<thead><tr><th>Type</th><th>Description</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>WORD_SIZE</td><td>2</td></tr>
|
||||
<tr><td>NUM_WORDS</td><td>16</td></tr>
|
||||
<tr><td>NUM_BANKS</td><td>1</td></tr>
|
||||
<tr><td>NUM_RW_PORTS</td><td>1</td></tr>
|
||||
<tr><td>NUM_R_PORTS</td><td>1</td></tr>
|
||||
<tr><td>NUM_W_PORTS</td><td>1</td></tr>
|
||||
<tr><td>Area</td><td>0</td></tr>
|
||||
</tbody>
|
||||
</table><p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Operating Conditions</p><table id="data">
|
||||
<thead><tr><th>Parameter</th><th>Min</th><th>Typ</th><th>Max</th><th>Units</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>Power supply (VDD) range</td><td>5.0</td><td>5.0</td><td>5.0</td><td>Volts</td></tr>
|
||||
<tr><td>Operating Temperature</td><td>25</td><td>25</td><td>25</td><td>Celsius</td></tr>
|
||||
<tr><td>Operating Frequency (F)*</td><td></td><td></td><td>unknown</td><td>MHz</td></tr>
|
||||
</tbody>
|
||||
</table><p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Timing and Current Data</p><table id="data">
|
||||
<thead><tr><th>Parameter</th><th>Min</th><th>Max</th><th>Units</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>Cycle time</td><td>2</td><td>3</td><td>4</td></tr>
|
||||
<tr><td>Access time</td><td>2</td><td>3</td><td>4</td></tr>
|
||||
<tr><td>Positive clk setup</td><td>2</td><td>3</td><td>4</td></tr>
|
||||
<tr><td>Positive clk hold</td><td>2</td><td>3</td><td>4</td></tr>
|
||||
<tr><td>DIN0[1:0] setup rising</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>DIN0[1:0] setup falling</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>DIN0[1:0] hold rising</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>DIN0[1:0] hold falling</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>DIN1[1:0] setup rising</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>DIN1[1:0] setup falling</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>DIN1[1:0] hold rising</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>DIN1[1:0] hold falling</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>DOUT0[1:0] cell rise</td><td>0.079</td><td>0.079</td><td>ns</td></tr>
|
||||
<tr><td>DOUT0[1:0] cell fall</td><td>0.079</td><td>0.079</td><td>ns</td></tr>
|
||||
<tr><td>DOUT0[1:0] rise transition</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>DOUT0[1:0] fall transition</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>DOUT2[1:0] cell rise</td><td>0.079</td><td>0.079</td><td>ns</td></tr>
|
||||
<tr><td>DOUT2[1:0] cell fall</td><td>0.079</td><td>0.079</td><td>ns</td></tr>
|
||||
<tr><td>DOUT2[1:0] rise transition</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>DOUT2[1:0] fall transition</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>CSb0 setup rising</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>CSb0 setup falling</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>CSb0 hold rising</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>CSb0 hold falling</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>CSb1 setup rising</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>CSb1 setup falling</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>CSb1 hold rising</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>CSb1 hold falling</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>CSb2 setup rising</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>CSb2 setup falling</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>CSb2 hold rising</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>CSb2 hold falling</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>ADDR0[3:0] setup rising</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>ADDR0[3:0] setup falling</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>ADDR0[3:0] hold rising</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>ADDR0[3:0] hold falling</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>ADDR1[3:0] setup rising</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>ADDR1[3:0] setup falling</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>ADDR1[3:0] hold rising</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>ADDR1[3:0] hold falling</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>ADDR2[3:0] setup rising</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>ADDR2[3:0] setup falling</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>ADDR2[3:0] hold rising</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>ADDR2[3:0] hold falling</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>WEb0 setup rising</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>WEb0 setup falling</td><td>0.009</td><td>0.009</td><td>ns</td></tr>
|
||||
<tr><td>WEb0 hold rising</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>WEb0 hold falling</td><td>0.001</td><td>0.001</td><td>ns</td></tr>
|
||||
<tr><td>AC current</td><td>2</td><td>3</td><td>4</td></tr>
|
||||
<tr><td>Standby current</td><td>2</td><td>3</td><td>4</td></tr>
|
||||
</tbody>
|
||||
</table><p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Characterization Corners</p><table id="data">
|
||||
<thead><tr><th>Corner Name</th><th>Process</th><th>Power Supply</th><th>Temperature</th><th>Library Name Suffix</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>TT</td><td>Typical - Typical</td><td>5.0</td><td>25</td><td>_TT_5p0V_25C.lib</td></tr>
|
||||
</tbody>
|
||||
</table><p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Deliverables</p><table id="data">
|
||||
<thead><tr><th>Type</th><th>Description</th><th>Link</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>.sp</td><td>SPICE netlists</td><td><a href="sram_2_16_scn4m_subm.sp">sram_2_16_scn4m_subm.sp</a></td></tr>
|
||||
<tr><td>.v</td><td>Verilog simulation models</td><td><a href="sram_2_16_scn4m_subm.v">sram_2_16_scn4m_subm.v</a></td></tr>
|
||||
<tr><td>.html</td><td>This datasheet</td><td><a href="sram_2_16_scn4m_subm.html">sram_2_16_scn4m_subm.html</a></td></tr>
|
||||
<tr><td>.lib</td><td>Synthesis models</td><td><a href="sram_2_16_scn4m_subm_TT_5p0V_25C.lib">sram_2_16_scn4m_subm_TT_5p0V_25C.lib</a></td></tr>
|
||||
<tr><td>.py</td><td>OpenRAM configuration file</td><td><a href="sram_2_16_scn4m_subm.py">sram_2_16_scn4m_subm.py</a></td></tr>
|
||||
</tbody>
|
||||
</table><p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">*Feature only supported with characterizer</p>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,18 @@
|
|||
word_size = 2
|
||||
num_words = 16
|
||||
|
||||
tech_name = "scn4m_subm"
|
||||
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)
|
||||
|
||||
#Setting for multiport
|
||||
netlist_only = True
|
||||
bitcell = "pbitcell"
|
||||
replica_bitcell="replica_pbitcell"
|
||||
num_rw_ports = 1
|
||||
num_r_ports = 1
|
||||
num_w_ports = 1
|
||||
|
|
@ -0,0 +1,767 @@
|
|||
**************************************************
|
||||
* OpenRAM generated memory.
|
||||
* Words: 16
|
||||
* Data bits: 2
|
||||
* Banks: 1
|
||||
* Column mux: 1:1
|
||||
**************************************************
|
||||
*********************** "dff" ******************************
|
||||
* Positive edge-triggered FF
|
||||
.SUBCKT dff D Q clk vdd gnd
|
||||
|
||||
* SPICE3 file created from dff.ext - technology: scmos
|
||||
|
||||
M1000 vdd clk a_24_24# vdd p w=8u l=0.4u
|
||||
M1001 a_84_296# D vdd vdd p w=4u l=0.4u
|
||||
M1002 a_104_24# clk a_84_296# vdd p w=4u l=0.4u
|
||||
M1003 a_140_296# a_24_24# a_104_24# vdd p w=4u l=0.4u
|
||||
M1004 vdd a_152_16# a_140_296# vdd p w=4u l=0.4u
|
||||
M1005 a_152_16# a_104_24# vdd vdd p w=4u l=0.4u
|
||||
M1006 a_260_296# a_152_16# vdd vdd p w=4u l=0.4u
|
||||
M1007 a_280_24# a_24_24# a_260_296# vdd p w=4u l=0.4u
|
||||
M1008 a_320_336# clk a_280_24# vdd p w=2u l=0.4u
|
||||
M1009 vdd Q a_320_336# vdd p w=2u l=0.4u
|
||||
M1010 gnd clk a_24_24# gnd n w=4u l=0.4u
|
||||
M1011 Q a_280_24# vdd vdd p w=8u l=0.4u
|
||||
M1012 a_84_24# D gnd gnd n w=2u l=0.4u
|
||||
M1013 a_104_24# a_24_24# a_84_24# gnd n w=2u l=0.4u
|
||||
M1014 a_140_24# clk a_104_24# gnd n w=2u l=0.4u
|
||||
M1015 gnd a_152_16# a_140_24# gnd n w=2u l=0.4u
|
||||
M1016 a_152_16# a_104_24# gnd gnd n w=2u l=0.4u
|
||||
M1017 a_260_24# a_152_16# gnd gnd n w=2u l=0.4u
|
||||
M1018 a_280_24# clk a_260_24# gnd n w=2u l=0.4u
|
||||
M1019 a_320_24# a_24_24# a_280_24# gnd n w=2u l=0.4u
|
||||
M1020 gnd Q a_320_24# gnd n w=2u l=0.4u
|
||||
M1021 Q a_280_24# gnd gnd n w=4u l=0.4u
|
||||
|
||||
.ENDS
|
||||
|
||||
* ptx M{0} {1} n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
|
||||
* ptx M{0} {1} p m=1 w=3.2u l=0.4u pd=7.2u ps=7.2u as=3.2p ad=3.2p
|
||||
|
||||
.SUBCKT pinv_2 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=3.2u l=0.4u pd=7.2u ps=7.2u as=3.2p ad=3.2p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pinv_2
|
||||
|
||||
.SUBCKT dff_inv_2 D Q Qb clk vdd gnd
|
||||
Xdff_inv_dff D Q clk vdd gnd dff
|
||||
Xdff_inv_inv1 Q Qb vdd gnd pinv_2
|
||||
.ENDS dff_inv_2
|
||||
|
||||
.SUBCKT dff_inv_array_2x1_1 din_0 din_1 dout_0 dout_bar_0 dout_1 dout_bar_1 clk vdd gnd
|
||||
XXdff_r0_c0 din_0 dout_0 dout_bar_0 clk vdd gnd dff_inv_2
|
||||
XXdff_r1_c0 din_1 dout_1 dout_bar_1 clk vdd gnd dff_inv_2
|
||||
.ENDS dff_inv_array_2x1_1
|
||||
|
||||
* ptx M{0} {1} p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
|
||||
.SUBCKT pnand2_1 A B Z vdd gnd
|
||||
Mpnand2_pmos1 vdd A Z vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_pmos2 Z B vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_nmos1 Z B net1 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_nmos2 net1 A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pnand2_1
|
||||
|
||||
.SUBCKT pnand3_1 A B C Z vdd gnd
|
||||
Mpnand3_pmos1 vdd A Z vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_pmos2 Z B vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_pmos3 Z C vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_nmos1 Z C net1 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_nmos2 net1 B net2 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_nmos3 net2 A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pnand3_1
|
||||
|
||||
* ptx M{0} {1} n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
|
||||
.SUBCKT pinv_3 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_3
|
||||
|
||||
.SUBCKT pinv_4 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=3.2u l=0.4u pd=7.2u ps=7.2u as=3.2p ad=3.2p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pinv_4
|
||||
|
||||
* ptx M{0} {1} n m=1 w=3.2u l=0.4u pd=7.2u ps=7.2u as=3.2p ad=3.2p
|
||||
|
||||
* ptx M{0} {1} p m=1 w=6.4u l=0.4u pd=13.600000000000001u ps=13.600000000000001u as=6.4p ad=6.4p
|
||||
|
||||
.SUBCKT pinv_5 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=6.4u l=0.4u pd=13.600000000000001u ps=13.600000000000001u as=6.4p ad=6.4p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=3.2u l=0.4u pd=7.2u ps=7.2u as=3.2p ad=3.2p
|
||||
.ENDS pinv_5
|
||||
|
||||
.SUBCKT pinvbuf_2_4_1 A Zb Z vdd gnd
|
||||
Xbuf_inv1 A zb_int vdd gnd pinv_3
|
||||
Xbuf_inv2 zb_int z_int vdd gnd pinv_4
|
||||
Xbuf_inv3 z_int Zb vdd gnd pinv_5
|
||||
Xbuf_inv4 zb_int Z vdd gnd pinv_5
|
||||
.ENDS pinvbuf_2_4_1
|
||||
|
||||
.SUBCKT pinv_6 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_6
|
||||
|
||||
.SUBCKT pinv_7 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=6.4u l=0.4u pd=13.600000000000001u ps=13.600000000000001u as=6.4p ad=6.4p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=3.2u l=0.4u pd=7.2u ps=7.2u as=3.2p ad=3.2p
|
||||
.ENDS pinv_7
|
||||
|
||||
* ptx M{0} {1} n m=1 w=12.8u l=0.4u pd=26.400000000000002u ps=26.400000000000002u as=12.8p ad=12.8p
|
||||
|
||||
* ptx M{0} {1} p m=1 w=25.6u l=0.4u pd=52.0u ps=52.0u as=25.6p ad=25.6p
|
||||
|
||||
.SUBCKT pinv_8 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=25.6u l=0.4u pd=52.0u ps=52.0u as=25.6p ad=25.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=12.8u l=0.4u pd=26.400000000000002u ps=26.400000000000002u as=12.8p ad=12.8p
|
||||
.ENDS pinv_8
|
||||
|
||||
* ptx M{0} {1} n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
|
||||
* ptx M{0} {1} p m=1 w=0.6000000000000001u l=0.4u pd=2.0u ps=2.0u as=0.6000000000000001p ad=0.6000000000000001p
|
||||
|
||||
* ptx M{0} {1} n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
|
||||
* ptx M{0} {1} n m=1 w=1.2000000000000002u l=0.4u pd=3.2u ps=3.2u as=1.2000000000000002p ad=1.2000000000000002p
|
||||
|
||||
.SUBCKT replica_pbitcell_1RW_1W_1R bl0 br0 bl1 br1 bl2 br2 wl0 wl1 wl2 vdd gnd
|
||||
Minverter_nmos_left Q vdd gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Minverter_nmos_right gnd Q vdd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Minverter_pmos_left Q vdd vdd vdd p m=1 w=0.6000000000000001u l=0.4u pd=2.0u ps=2.0u as=0.6000000000000001p ad=0.6000000000000001p
|
||||
Minverter_pmos_right vdd Q vdd vdd p m=1 w=0.6000000000000001u l=0.4u pd=2.0u ps=2.0u as=0.6000000000000001p ad=0.6000000000000001p
|
||||
Mreadwrite_nmos_left0 bl0 wl0 Q gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
Mreadwrite_nmos_right0 vdd wl0 br0 gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
Mwrite_nmos_left0 bl1 wl1 Q gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
Mwrite_nmos_right0 vdd wl1 br1 gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
Mread_access_nmos_left0 RA_to_R_left0 vdd gnd gnd n m=1 w=1.2000000000000002u l=0.4u pd=3.2u ps=3.2u as=1.2000000000000002p ad=1.2000000000000002p
|
||||
Mread_access_nmos_right0 gnd Q RA_to_R_right0 gnd n m=1 w=1.2000000000000002u l=0.4u pd=3.2u ps=3.2u as=1.2000000000000002p ad=1.2000000000000002p
|
||||
Mread_nmos_left0 bl2 wl2 RA_to_R_left0 gnd n m=1 w=1.2000000000000002u l=0.4u pd=3.2u ps=3.2u as=1.2000000000000002p ad=1.2000000000000002p
|
||||
Mread_nmos_right0 RA_to_R_right0 wl2 br2 gnd n m=1 w=1.2000000000000002u l=0.4u pd=3.2u ps=3.2u as=1.2000000000000002p ad=1.2000000000000002p
|
||||
.ENDS replica_pbitcell_1RW_1W_1R
|
||||
|
||||
.SUBCKT replica_pbitcell bl0 br0 bl1 br1 bl2 br2 wl0 wl1 wl2 vdd gnd
|
||||
Xpbitcell bl0 br0 bl1 br1 bl2 br2 wl0 wl1 wl2 vdd gnd replica_pbitcell_1RW_1W_1R
|
||||
.ENDS replica_pbitcell
|
||||
|
||||
.SUBCKT pbitcell_1RW_1W_1R bl0 br0 bl1 br1 bl2 br2 wl0 wl1 wl2 vdd gnd
|
||||
Minverter_nmos_left Q Q_bar gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Minverter_nmos_right gnd Q Q_bar gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Minverter_pmos_left Q Q_bar vdd vdd p m=1 w=0.6000000000000001u l=0.4u pd=2.0u ps=2.0u as=0.6000000000000001p ad=0.6000000000000001p
|
||||
Minverter_pmos_right vdd Q Q_bar vdd p m=1 w=0.6000000000000001u l=0.4u pd=2.0u ps=2.0u as=0.6000000000000001p ad=0.6000000000000001p
|
||||
Mreadwrite_nmos_left0 bl0 wl0 Q gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
Mreadwrite_nmos_right0 Q_bar wl0 br0 gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
Mwrite_nmos_left0 bl1 wl1 Q gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
Mwrite_nmos_right0 Q_bar wl1 br1 gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
Mread_access_nmos_left0 RA_to_R_left0 Q_bar gnd gnd n m=1 w=1.2000000000000002u l=0.4u pd=3.2u ps=3.2u as=1.2000000000000002p ad=1.2000000000000002p
|
||||
Mread_access_nmos_right0 gnd Q RA_to_R_right0 gnd n m=1 w=1.2000000000000002u l=0.4u pd=3.2u ps=3.2u as=1.2000000000000002p ad=1.2000000000000002p
|
||||
Mread_nmos_left0 bl2 wl2 RA_to_R_left0 gnd n m=1 w=1.2000000000000002u l=0.4u pd=3.2u ps=3.2u as=1.2000000000000002p ad=1.2000000000000002p
|
||||
Mread_nmos_right0 RA_to_R_right0 wl2 br2 gnd n m=1 w=1.2000000000000002u l=0.4u pd=3.2u ps=3.2u as=1.2000000000000002p ad=1.2000000000000002p
|
||||
.ENDS pbitcell_1RW_1W_1R
|
||||
|
||||
.SUBCKT bitcell_array_8x1_1 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_0 wl1_0 wl2_0 wl0_1 wl1_1 wl2_1 wl0_2 wl1_2 wl2_2 wl0_3 wl1_3 wl2_3 wl0_4 wl1_4 wl2_4 wl0_5 wl1_5 wl2_5 wl0_6 wl1_6 wl2_6 wl0_7 wl1_7 wl2_7 vdd gnd
|
||||
Xbit_r0_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_0 wl1_0 wl2_0 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r1_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_1 wl1_1 wl2_1 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r2_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_2 wl1_2 wl2_2 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r3_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_3 wl1_3 wl2_3 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r4_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_4 wl1_4 wl2_4 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r5_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_5 wl1_5 wl2_5 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r6_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_6 wl1_6 wl2_6 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r7_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_7 wl1_7 wl2_7 vdd gnd pbitcell_1RW_1W_1R
|
||||
.ENDS bitcell_array_8x1_1
|
||||
|
||||
.SUBCKT pinv_9 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_9
|
||||
|
||||
.SUBCKT delay_chain_1 in out vdd gnd
|
||||
Xdinv0 in dout_1 vdd gnd pinv_9
|
||||
Xdload_0_0 dout_1 n_0_0 vdd gnd pinv_9
|
||||
Xdload_0_1 dout_1 n_0_1 vdd gnd pinv_9
|
||||
Xdload_0_2 dout_1 n_0_2 vdd gnd pinv_9
|
||||
Xdinv1 dout_1 dout_2 vdd gnd pinv_9
|
||||
Xdload_1_0 dout_2 n_1_0 vdd gnd pinv_9
|
||||
Xdload_1_1 dout_2 n_1_1 vdd gnd pinv_9
|
||||
Xdload_1_2 dout_2 n_1_2 vdd gnd pinv_9
|
||||
Xdinv2 dout_2 dout_3 vdd gnd pinv_9
|
||||
Xdload_2_0 dout_3 n_2_0 vdd gnd pinv_9
|
||||
Xdload_2_1 dout_3 n_2_1 vdd gnd pinv_9
|
||||
Xdload_2_2 dout_3 n_2_2 vdd gnd pinv_9
|
||||
Xdinv3 dout_3 out vdd gnd pinv_9
|
||||
Xdload_3_0 out n_3_0 vdd gnd pinv_9
|
||||
Xdload_3_1 out n_3_1 vdd gnd pinv_9
|
||||
Xdload_3_2 out n_3_2 vdd gnd pinv_9
|
||||
.ENDS delay_chain_1
|
||||
|
||||
.SUBCKT pinv_10 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_10
|
||||
|
||||
* ptx M{0} {1} p m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
|
||||
.SUBCKT replica_bitline_rw en out vdd gnd
|
||||
Xrbl_inv bl0_0 out vdd gnd pinv_10
|
||||
Mrbl_access_tx vdd delayed_en bl0_0 vdd p m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
Xdelay_chain en delayed_en vdd gnd delay_chain_1
|
||||
Xbitcell bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 delayed_en delayed_en delayed_en vdd gnd replica_pbitcell
|
||||
Xload bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd vdd gnd bitcell_array_8x1_1
|
||||
.ENDS replica_bitline_rw
|
||||
|
||||
.SUBCKT control_logic_rw csb web clk s_en w_en clk_buf_bar clk_buf vdd gnd
|
||||
Xctrl_dffs csb web cs_bar cs we_bar we clk_buf vdd gnd dff_inv_array_2x1_1
|
||||
Xclkbuf clk clk_buf_bar clk_buf vdd gnd pinvbuf_2_4_1
|
||||
Xnand3_w_en_bar clk_buf_bar cs we w_en_bar vdd gnd pnand3_1
|
||||
Xinv_pre_w_en w_en_bar pre_w_en vdd gnd pinv_6
|
||||
Xinv_pre_w_en_bar pre_w_en pre_w_en_bar vdd gnd pinv_7
|
||||
Xinv_w_en2 pre_w_en_bar w_en vdd gnd pinv_8
|
||||
Xnand2_rbl_in_bar clk_buf_bar cs rbl_in_bar vdd gnd pnand2_1
|
||||
Xinv_rbl_in rbl_in_bar rbl_in vdd gnd pinv_6
|
||||
Xinv_pre_s_en_bar pre_s_en pre_s_en_bar vdd gnd pinv_7
|
||||
Xinv_s_en pre_s_en_bar s_en vdd gnd pinv_8
|
||||
Xreplica_bitline rbl_in pre_s_en vdd gnd replica_bitline_rw
|
||||
.ENDS control_logic_rw
|
||||
|
||||
.SUBCKT pinv_12 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=3.2u l=0.4u pd=7.2u ps=7.2u as=3.2p ad=3.2p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pinv_12
|
||||
|
||||
.SUBCKT dff_inv_4 D Q Qb clk vdd gnd
|
||||
Xdff_inv_dff D Q clk vdd gnd dff
|
||||
Xdff_inv_inv1 Q Qb vdd gnd pinv_12
|
||||
.ENDS dff_inv_4
|
||||
|
||||
.SUBCKT dff_inv_array_1x1_2 din_0 dout_0 dout_bar_0 clk vdd gnd
|
||||
XXdff_r0_c0 din_0 dout_0 dout_bar_0 clk vdd gnd dff_inv_4
|
||||
.ENDS dff_inv_array_1x1_2
|
||||
|
||||
.SUBCKT pnand2_2 A B Z vdd gnd
|
||||
Mpnand2_pmos1 vdd A Z vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_pmos2 Z B vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_nmos1 Z B net1 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_nmos2 net1 A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pnand2_2
|
||||
|
||||
.SUBCKT pnand3_2 A B C Z vdd gnd
|
||||
Mpnand3_pmos1 vdd A Z vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_pmos2 Z B vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_pmos3 Z C vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_nmos1 Z C net1 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_nmos2 net1 B net2 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_nmos3 net2 A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pnand3_2
|
||||
|
||||
.SUBCKT pinv_13 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_13
|
||||
|
||||
.SUBCKT pinv_14 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=3.2u l=0.4u pd=7.2u ps=7.2u as=3.2p ad=3.2p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pinv_14
|
||||
|
||||
.SUBCKT pinv_15 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=6.4u l=0.4u pd=13.600000000000001u ps=13.600000000000001u as=6.4p ad=6.4p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=3.2u l=0.4u pd=7.2u ps=7.2u as=3.2p ad=3.2p
|
||||
.ENDS pinv_15
|
||||
|
||||
.SUBCKT pinvbuf_2_4_2 A Zb Z vdd gnd
|
||||
Xbuf_inv1 A zb_int vdd gnd pinv_13
|
||||
Xbuf_inv2 zb_int z_int vdd gnd pinv_14
|
||||
Xbuf_inv3 z_int Zb vdd gnd pinv_15
|
||||
Xbuf_inv4 zb_int Z vdd gnd pinv_15
|
||||
.ENDS pinvbuf_2_4_2
|
||||
|
||||
.SUBCKT pinv_16 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_16
|
||||
|
||||
.SUBCKT pinv_17 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=6.4u l=0.4u pd=13.600000000000001u ps=13.600000000000001u as=6.4p ad=6.4p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=3.2u l=0.4u pd=7.2u ps=7.2u as=3.2p ad=3.2p
|
||||
.ENDS pinv_17
|
||||
|
||||
.SUBCKT pinv_18 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=25.6u l=0.4u pd=52.0u ps=52.0u as=25.6p ad=25.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=12.8u l=0.4u pd=26.400000000000002u ps=26.400000000000002u as=12.8p ad=12.8p
|
||||
.ENDS pinv_18
|
||||
|
||||
.SUBCKT control_logic_w csb clk w_en clk_buf_bar clk_buf vdd gnd
|
||||
Xctrl_dffs csb cs_bar cs clk_buf vdd gnd dff_inv_array_1x1_2
|
||||
Xclkbuf clk clk_buf_bar clk_buf vdd gnd pinvbuf_2_4_2
|
||||
Xnand3_w_en_bar clk_buf_bar cs w_en_bar vdd gnd pnand2_2
|
||||
Xinv_pre_w_en w_en_bar pre_w_en vdd gnd pinv_16
|
||||
Xinv_pre_w_en_bar pre_w_en pre_w_en_bar vdd gnd pinv_17
|
||||
Xinv_w_en2 pre_w_en_bar w_en vdd gnd pinv_18
|
||||
.ENDS control_logic_w
|
||||
|
||||
.SUBCKT pinv_20 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=3.2u l=0.4u pd=7.2u ps=7.2u as=3.2p ad=3.2p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pinv_20
|
||||
|
||||
.SUBCKT dff_inv_6 D Q Qb clk vdd gnd
|
||||
Xdff_inv_dff D Q clk vdd gnd dff
|
||||
Xdff_inv_inv1 Q Qb vdd gnd pinv_20
|
||||
.ENDS dff_inv_6
|
||||
|
||||
.SUBCKT dff_inv_array_1x1_3 din_0 dout_0 dout_bar_0 clk vdd gnd
|
||||
XXdff_r0_c0 din_0 dout_0 dout_bar_0 clk vdd gnd dff_inv_6
|
||||
.ENDS dff_inv_array_1x1_3
|
||||
|
||||
.SUBCKT pnand2_3 A B Z vdd gnd
|
||||
Mpnand2_pmos1 vdd A Z vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_pmos2 Z B vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_nmos1 Z B net1 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_nmos2 net1 A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pnand2_3
|
||||
|
||||
.SUBCKT pnand3_3 A B C Z vdd gnd
|
||||
Mpnand3_pmos1 vdd A Z vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_pmos2 Z B vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_pmos3 Z C vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_nmos1 Z C net1 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_nmos2 net1 B net2 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_nmos3 net2 A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pnand3_3
|
||||
|
||||
.SUBCKT pinv_21 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_21
|
||||
|
||||
.SUBCKT pinv_22 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=3.2u l=0.4u pd=7.2u ps=7.2u as=3.2p ad=3.2p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pinv_22
|
||||
|
||||
.SUBCKT pinv_23 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=6.4u l=0.4u pd=13.600000000000001u ps=13.600000000000001u as=6.4p ad=6.4p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=3.2u l=0.4u pd=7.2u ps=7.2u as=3.2p ad=3.2p
|
||||
.ENDS pinv_23
|
||||
|
||||
.SUBCKT pinvbuf_2_4_3 A Zb Z vdd gnd
|
||||
Xbuf_inv1 A zb_int vdd gnd pinv_21
|
||||
Xbuf_inv2 zb_int z_int vdd gnd pinv_22
|
||||
Xbuf_inv3 z_int Zb vdd gnd pinv_23
|
||||
Xbuf_inv4 zb_int Z vdd gnd pinv_23
|
||||
.ENDS pinvbuf_2_4_3
|
||||
|
||||
.SUBCKT pinv_24 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_24
|
||||
|
||||
.SUBCKT pinv_25 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=6.4u l=0.4u pd=13.600000000000001u ps=13.600000000000001u as=6.4p ad=6.4p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=3.2u l=0.4u pd=7.2u ps=7.2u as=3.2p ad=3.2p
|
||||
.ENDS pinv_25
|
||||
|
||||
.SUBCKT pinv_26 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=25.6u l=0.4u pd=52.0u ps=52.0u as=25.6p ad=25.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=12.8u l=0.4u pd=26.400000000000002u ps=26.400000000000002u as=12.8p ad=12.8p
|
||||
.ENDS pinv_26
|
||||
|
||||
.SUBCKT bitcell_array_8x1_2 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_0 wl1_0 wl2_0 wl0_1 wl1_1 wl2_1 wl0_2 wl1_2 wl2_2 wl0_3 wl1_3 wl2_3 wl0_4 wl1_4 wl2_4 wl0_5 wl1_5 wl2_5 wl0_6 wl1_6 wl2_6 wl0_7 wl1_7 wl2_7 vdd gnd
|
||||
Xbit_r0_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_0 wl1_0 wl2_0 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r1_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_1 wl1_1 wl2_1 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r2_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_2 wl1_2 wl2_2 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r3_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_3 wl1_3 wl2_3 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r4_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_4 wl1_4 wl2_4 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r5_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_5 wl1_5 wl2_5 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r6_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_6 wl1_6 wl2_6 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r7_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_7 wl1_7 wl2_7 vdd gnd pbitcell_1RW_1W_1R
|
||||
.ENDS bitcell_array_8x1_2
|
||||
|
||||
.SUBCKT pinv_27 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_27
|
||||
|
||||
.SUBCKT delay_chain_2 in out vdd gnd
|
||||
Xdinv0 in dout_1 vdd gnd pinv_27
|
||||
Xdload_0_0 dout_1 n_0_0 vdd gnd pinv_27
|
||||
Xdload_0_1 dout_1 n_0_1 vdd gnd pinv_27
|
||||
Xdload_0_2 dout_1 n_0_2 vdd gnd pinv_27
|
||||
Xdinv1 dout_1 dout_2 vdd gnd pinv_27
|
||||
Xdload_1_0 dout_2 n_1_0 vdd gnd pinv_27
|
||||
Xdload_1_1 dout_2 n_1_1 vdd gnd pinv_27
|
||||
Xdload_1_2 dout_2 n_1_2 vdd gnd pinv_27
|
||||
Xdinv2 dout_2 dout_3 vdd gnd pinv_27
|
||||
Xdload_2_0 dout_3 n_2_0 vdd gnd pinv_27
|
||||
Xdload_2_1 dout_3 n_2_1 vdd gnd pinv_27
|
||||
Xdload_2_2 dout_3 n_2_2 vdd gnd pinv_27
|
||||
Xdinv3 dout_3 out vdd gnd pinv_27
|
||||
Xdload_3_0 out n_3_0 vdd gnd pinv_27
|
||||
Xdload_3_1 out n_3_1 vdd gnd pinv_27
|
||||
Xdload_3_2 out n_3_2 vdd gnd pinv_27
|
||||
.ENDS delay_chain_2
|
||||
|
||||
.SUBCKT pinv_28 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_28
|
||||
|
||||
.SUBCKT replica_bitline_r en out vdd gnd
|
||||
Xrbl_inv bl0_0 out vdd gnd pinv_28
|
||||
Mrbl_access_tx vdd delayed_en bl0_0 vdd p m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
Xdelay_chain en delayed_en vdd gnd delay_chain_2
|
||||
Xbitcell bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 delayed_en delayed_en delayed_en vdd gnd replica_pbitcell
|
||||
Xload bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd gnd vdd gnd bitcell_array_8x1_2
|
||||
.ENDS replica_bitline_r
|
||||
|
||||
.SUBCKT control_logic_r csb clk s_en clk_buf_bar clk_buf vdd gnd
|
||||
Xctrl_dffs csb cs_bar cs clk_buf vdd gnd dff_inv_array_1x1_3
|
||||
Xclkbuf clk clk_buf_bar clk_buf vdd gnd pinvbuf_2_4_3
|
||||
Xnand2_rbl_in_bar clk_buf_bar cs rbl_in_bar vdd gnd pnand2_3
|
||||
Xinv_rbl_in rbl_in_bar rbl_in vdd gnd pinv_24
|
||||
Xinv_pre_s_en_bar pre_s_en pre_s_en_bar vdd gnd pinv_25
|
||||
Xinv_s_en pre_s_en_bar s_en vdd gnd pinv_26
|
||||
Xreplica_bitline rbl_in pre_s_en vdd gnd replica_bitline_r
|
||||
.ENDS control_logic_r
|
||||
|
||||
.SUBCKT row_addr_dff din_0 din_1 din_2 din_3 dout_0 dout_1 dout_2 dout_3 clk vdd gnd
|
||||
XXdff_r0_c0 din_0 dout_0 clk vdd gnd dff
|
||||
XXdff_r1_c0 din_1 dout_1 clk vdd gnd dff
|
||||
XXdff_r2_c0 din_2 dout_2 clk vdd gnd dff
|
||||
XXdff_r3_c0 din_3 dout_3 clk vdd gnd dff
|
||||
.ENDS row_addr_dff
|
||||
|
||||
.SUBCKT data_dff din_0 din_1 dout_0 dout_1 clk vdd gnd
|
||||
XXdff_r0_c0 din_0 dout_0 clk vdd gnd dff
|
||||
XXdff_r0_c1 din_1 dout_1 clk vdd gnd dff
|
||||
.ENDS data_dff
|
||||
|
||||
.SUBCKT bitcell_array_16x2_1 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_0 wl1_0 wl2_0 wl0_1 wl1_1 wl2_1 wl0_2 wl1_2 wl2_2 wl0_3 wl1_3 wl2_3 wl0_4 wl1_4 wl2_4 wl0_5 wl1_5 wl2_5 wl0_6 wl1_6 wl2_6 wl0_7 wl1_7 wl2_7 wl0_8 wl1_8 wl2_8 wl0_9 wl1_9 wl2_9 wl0_10 wl1_10 wl2_10 wl0_11 wl1_11 wl2_11 wl0_12 wl1_12 wl2_12 wl0_13 wl1_13 wl2_13 wl0_14 wl1_14 wl2_14 wl0_15 wl1_15 wl2_15 vdd gnd
|
||||
Xbit_r0_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_0 wl1_0 wl2_0 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r1_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_1 wl1_1 wl2_1 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r2_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_2 wl1_2 wl2_2 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r3_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_3 wl1_3 wl2_3 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r4_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_4 wl1_4 wl2_4 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r5_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_5 wl1_5 wl2_5 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r6_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_6 wl1_6 wl2_6 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r7_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_7 wl1_7 wl2_7 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r8_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_8 wl1_8 wl2_8 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r9_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_9 wl1_9 wl2_9 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r10_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_10 wl1_10 wl2_10 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r11_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_11 wl1_11 wl2_11 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r12_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_12 wl1_12 wl2_12 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r13_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_13 wl1_13 wl2_13 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r14_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_14 wl1_14 wl2_14 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r15_c0 bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 wl0_15 wl1_15 wl2_15 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r0_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_0 wl1_0 wl2_0 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r1_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_1 wl1_1 wl2_1 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r2_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_2 wl1_2 wl2_2 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r3_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_3 wl1_3 wl2_3 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r4_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_4 wl1_4 wl2_4 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r5_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_5 wl1_5 wl2_5 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r6_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_6 wl1_6 wl2_6 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r7_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_7 wl1_7 wl2_7 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r8_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_8 wl1_8 wl2_8 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r9_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_9 wl1_9 wl2_9 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r10_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_10 wl1_10 wl2_10 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r11_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_11 wl1_11 wl2_11 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r12_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_12 wl1_12 wl2_12 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r13_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_13 wl1_13 wl2_13 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r14_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_14 wl1_14 wl2_14 vdd gnd pbitcell_1RW_1W_1R
|
||||
Xbit_r15_c1 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_15 wl1_15 wl2_15 vdd gnd pbitcell_1RW_1W_1R
|
||||
.ENDS bitcell_array_16x2_1
|
||||
|
||||
* ptx M{0} {1} p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
|
||||
.SUBCKT precharge_1 bl br en vdd
|
||||
Mlower_pmos bl en br vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mupper_pmos1 bl en vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mupper_pmos2 br en vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS precharge_1
|
||||
|
||||
.SUBCKT precharge_array_1 bl_0 br_0 bl_1 br_1 en vdd
|
||||
Xpre_column_0 bl_0 br_0 en vdd precharge_1
|
||||
Xpre_column_1 bl_1 br_1 en vdd precharge_1
|
||||
.ENDS precharge_array_1
|
||||
|
||||
.SUBCKT precharge_2 bl br en vdd
|
||||
Mlower_pmos bl en br vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mupper_pmos1 bl en vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mupper_pmos2 br en vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS precharge_2
|
||||
|
||||
.SUBCKT precharge_array_2 bl_0 br_0 bl_1 br_1 en vdd
|
||||
Xpre_column_0 bl_0 br_0 en vdd precharge_2
|
||||
Xpre_column_1 bl_1 br_1 en vdd precharge_2
|
||||
.ENDS precharge_array_2
|
||||
*********************** "sense_amp" ******************************
|
||||
|
||||
.SUBCKT sense_amp bl br dout en vdd gnd
|
||||
|
||||
* SPICE3 file created from sense_amp.ext - technology: scmos
|
||||
|
||||
M1000 gnd en a_56_432# gnd n w=1.8u l=0.4u
|
||||
M1001 a_56_432# a_48_304# dout gnd n w=1.8u l=0.4u
|
||||
M1002 a_48_304# dout a_56_432# gnd n w=1.8u l=0.4u
|
||||
M1003 vdd a_48_304# dout vdd p w=3.6u l=0.4u
|
||||
M1004 a_48_304# dout vdd vdd p w=3.6u l=0.4u
|
||||
M1005 bl en dout vdd p w=4.8u l=0.4u
|
||||
M1006 a_48_304# en br vdd p w=4.8u l=0.4u
|
||||
|
||||
.ENDS
|
||||
|
||||
.SUBCKT sense_amp_array data_0 bl_0 br_0 data_1 bl_1 br_1 en vdd gnd
|
||||
Xsa_d0 bl_0 br_0 data_0 en vdd gnd sense_amp
|
||||
Xsa_d1 bl_1 br_1 data_1 en vdd gnd sense_amp
|
||||
.ENDS sense_amp_array
|
||||
*********************** Write_Driver ******************************
|
||||
.SUBCKT write_driver din bl br en vdd gnd
|
||||
* SPICE3 file created from write_driver.ext - technology: scmos
|
||||
|
||||
M1000 a_44_708# a_36_700# bl gnd n w=2.4u l=0.4u
|
||||
M1001 br a_16_500# a_44_708# gnd n w=2.4u l=0.4u
|
||||
M1002 a_44_708# en gnd gnd n w=2.4u l=0.4u
|
||||
M1003 gnd a_8_284# a_16_500# gnd n w=0.8u l=0.4u
|
||||
M1004 a_36_700# a_20_328# gnd gnd n w=0.8u l=0.4u
|
||||
M1005 vdd a_8_284# a_16_500# vdd p w=1.4u l=0.4u
|
||||
M1006 a_36_700# a_20_328# vdd vdd p w=1.4u l=0.4u
|
||||
M1007 vdd en a_20_328# vdd p w=1.4u l=0.4u
|
||||
M1008 a_20_328# a_64_360# vdd vdd p w=1.4u l=0.4u
|
||||
M1009 a_48_328# en a_20_328# gnd n w=1.4u l=0.4u
|
||||
M1010 gnd a_64_360# a_48_328# gnd n w=1.4u l=0.4u
|
||||
M1011 a_40_228# en a_8_284# gnd n w=1.4u l=0.4u
|
||||
M1012 gnd din a_40_228# gnd n w=1.4u l=0.4u
|
||||
M1013 a_64_360# din gnd gnd n w=0.8u l=0.4u
|
||||
M1014 a_8_284# en vdd vdd p w=1.4u l=0.4u
|
||||
M1015 vdd din a_8_284# vdd p w=1.4u l=0.4u
|
||||
M1016 a_64_360# din vdd vdd p w=1.4u l=0.4u
|
||||
|
||||
.ENDS
|
||||
|
||||
.SUBCKT write_driver_array data_0 data_1 bl_0 br_0 bl_1 br_1 en vdd gnd
|
||||
XXwrite_driver0 data_0 bl_0 br_0 en vdd gnd write_driver
|
||||
XXwrite_driver1 data_1 bl_1 br_1 en vdd gnd write_driver
|
||||
.ENDS write_driver_array
|
||||
|
||||
.SUBCKT pinv_29 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_29
|
||||
|
||||
.SUBCKT pnand2_4 A B Z vdd gnd
|
||||
Mpnand2_pmos1 vdd A Z vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_pmos2 Z B vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_nmos1 Z B net1 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_nmos2 net1 A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pnand2_4
|
||||
|
||||
.SUBCKT pnand3_4 A B C Z vdd gnd
|
||||
Mpnand3_pmos1 vdd A Z vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_pmos2 Z B vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_pmos3 Z C vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_nmos1 Z C net1 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_nmos2 net1 B net2 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_nmos3 net2 A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pnand3_4
|
||||
|
||||
.SUBCKT pinv_30 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_30
|
||||
|
||||
.SUBCKT pnand2_5 A B Z vdd gnd
|
||||
Mpnand2_pmos1 vdd A Z vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_pmos2 Z B vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_nmos1 Z B net1 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_nmos2 net1 A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pnand2_5
|
||||
|
||||
.SUBCKT pre2x4 in_0 in_1 out_0 out_1 out_2 out_3 vdd gnd
|
||||
XXpre_inv_0 in_0 inbar_0 vdd gnd pinv_30
|
||||
XXpre_inv_1 in_1 inbar_1 vdd gnd pinv_30
|
||||
XXpre_nand_inv_0 Z_0 out_0 vdd gnd pinv_30
|
||||
XXpre_nand_inv_1 Z_1 out_1 vdd gnd pinv_30
|
||||
XXpre_nand_inv_2 Z_2 out_2 vdd gnd pinv_30
|
||||
XXpre_nand_inv_3 Z_3 out_3 vdd gnd pinv_30
|
||||
XXpre2x4_nand_0 inbar_0 inbar_1 Z_0 vdd gnd pnand2_5
|
||||
XXpre2x4_nand_1 in_0 inbar_1 Z_1 vdd gnd pnand2_5
|
||||
XXpre2x4_nand_2 inbar_0 in_1 Z_2 vdd gnd pnand2_5
|
||||
XXpre2x4_nand_3 in_0 in_1 Z_3 vdd gnd pnand2_5
|
||||
.ENDS pre2x4
|
||||
|
||||
.SUBCKT pinv_31 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_31
|
||||
|
||||
.SUBCKT pnand3_5 A B C Z vdd gnd
|
||||
Mpnand3_pmos1 vdd A Z vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_pmos2 Z B vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_pmos3 Z C vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_nmos1 Z C net1 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_nmos2 net1 B net2 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand3_nmos3 net2 A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pnand3_5
|
||||
|
||||
.SUBCKT pre3x8 in_0 in_1 in_2 out_0 out_1 out_2 out_3 out_4 out_5 out_6 out_7 vdd gnd
|
||||
XXpre_inv_0 in_0 inbar_0 vdd gnd pinv_31
|
||||
XXpre_inv_1 in_1 inbar_1 vdd gnd pinv_31
|
||||
XXpre_inv_2 in_2 inbar_2 vdd gnd pinv_31
|
||||
XXpre_nand_inv_0 Z_0 out_0 vdd gnd pinv_31
|
||||
XXpre_nand_inv_1 Z_1 out_1 vdd gnd pinv_31
|
||||
XXpre_nand_inv_2 Z_2 out_2 vdd gnd pinv_31
|
||||
XXpre_nand_inv_3 Z_3 out_3 vdd gnd pinv_31
|
||||
XXpre_nand_inv_4 Z_4 out_4 vdd gnd pinv_31
|
||||
XXpre_nand_inv_5 Z_5 out_5 vdd gnd pinv_31
|
||||
XXpre_nand_inv_6 Z_6 out_6 vdd gnd pinv_31
|
||||
XXpre_nand_inv_7 Z_7 out_7 vdd gnd pinv_31
|
||||
XXpre3x8_nand_0 inbar_0 inbar_1 inbar_2 Z_0 vdd gnd pnand3_5
|
||||
XXpre3x8_nand_1 in_0 inbar_1 inbar_2 Z_1 vdd gnd pnand3_5
|
||||
XXpre3x8_nand_2 inbar_0 in_1 inbar_2 Z_2 vdd gnd pnand3_5
|
||||
XXpre3x8_nand_3 in_0 in_1 inbar_2 Z_3 vdd gnd pnand3_5
|
||||
XXpre3x8_nand_4 inbar_0 inbar_1 in_2 Z_4 vdd gnd pnand3_5
|
||||
XXpre3x8_nand_5 in_0 inbar_1 in_2 Z_5 vdd gnd pnand3_5
|
||||
XXpre3x8_nand_6 inbar_0 in_1 in_2 Z_6 vdd gnd pnand3_5
|
||||
XXpre3x8_nand_7 in_0 in_1 in_2 Z_7 vdd gnd pnand3_5
|
||||
.ENDS pre3x8
|
||||
|
||||
.SUBCKT hierarchical_decoder_16rows addr_0 addr_1 addr_2 addr_3 decode_0 decode_1 decode_2 decode_3 decode_4 decode_5 decode_6 decode_7 decode_8 decode_9 decode_10 decode_11 decode_12 decode_13 decode_14 decode_15 vdd gnd
|
||||
Xpre_0 addr_0 addr_1 out_0 out_1 out_2 out_3 vdd gnd pre2x4
|
||||
Xpre_1 addr_2 addr_3 out_4 out_5 out_6 out_7 vdd gnd pre2x4
|
||||
XDEC_NAND_0 out_0 out_4 Z_0 vdd gnd pnand2_4
|
||||
XDEC_NAND_1 out_0 out_5 Z_1 vdd gnd pnand2_4
|
||||
XDEC_NAND_2 out_0 out_6 Z_2 vdd gnd pnand2_4
|
||||
XDEC_NAND_3 out_0 out_7 Z_3 vdd gnd pnand2_4
|
||||
XDEC_NAND_4 out_1 out_4 Z_4 vdd gnd pnand2_4
|
||||
XDEC_NAND_5 out_1 out_5 Z_5 vdd gnd pnand2_4
|
||||
XDEC_NAND_6 out_1 out_6 Z_6 vdd gnd pnand2_4
|
||||
XDEC_NAND_7 out_1 out_7 Z_7 vdd gnd pnand2_4
|
||||
XDEC_NAND_8 out_2 out_4 Z_8 vdd gnd pnand2_4
|
||||
XDEC_NAND_9 out_2 out_5 Z_9 vdd gnd pnand2_4
|
||||
XDEC_NAND_10 out_2 out_6 Z_10 vdd gnd pnand2_4
|
||||
XDEC_NAND_11 out_2 out_7 Z_11 vdd gnd pnand2_4
|
||||
XDEC_NAND_12 out_3 out_4 Z_12 vdd gnd pnand2_4
|
||||
XDEC_NAND_13 out_3 out_5 Z_13 vdd gnd pnand2_4
|
||||
XDEC_NAND_14 out_3 out_6 Z_14 vdd gnd pnand2_4
|
||||
XDEC_NAND_15 out_3 out_7 Z_15 vdd gnd pnand2_4
|
||||
XDEC_INV_0 Z_0 decode_0 vdd gnd pinv_29
|
||||
XDEC_INV_1 Z_1 decode_1 vdd gnd pinv_29
|
||||
XDEC_INV_2 Z_2 decode_2 vdd gnd pinv_29
|
||||
XDEC_INV_3 Z_3 decode_3 vdd gnd pinv_29
|
||||
XDEC_INV_4 Z_4 decode_4 vdd gnd pinv_29
|
||||
XDEC_INV_5 Z_5 decode_5 vdd gnd pinv_29
|
||||
XDEC_INV_6 Z_6 decode_6 vdd gnd pinv_29
|
||||
XDEC_INV_7 Z_7 decode_7 vdd gnd pinv_29
|
||||
XDEC_INV_8 Z_8 decode_8 vdd gnd pinv_29
|
||||
XDEC_INV_9 Z_9 decode_9 vdd gnd pinv_29
|
||||
XDEC_INV_10 Z_10 decode_10 vdd gnd pinv_29
|
||||
XDEC_INV_11 Z_11 decode_11 vdd gnd pinv_29
|
||||
XDEC_INV_12 Z_12 decode_12 vdd gnd pinv_29
|
||||
XDEC_INV_13 Z_13 decode_13 vdd gnd pinv_29
|
||||
XDEC_INV_14 Z_14 decode_14 vdd gnd pinv_29
|
||||
XDEC_INV_15 Z_15 decode_15 vdd gnd pinv_29
|
||||
.ENDS hierarchical_decoder_16rows
|
||||
|
||||
.SUBCKT pinv_32 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_32
|
||||
|
||||
.SUBCKT pinv_33 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_33
|
||||
|
||||
.SUBCKT pnand2_6 A B Z vdd gnd
|
||||
Mpnand2_pmos1 vdd A Z vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_pmos2 Z B vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_nmos1 Z B net1 gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpnand2_nmos2 net1 A gnd gnd n m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
.ENDS pnand2_6
|
||||
|
||||
.SUBCKT wordline_driver in_0 in_1 in_2 in_3 in_4 in_5 in_6 in_7 in_8 in_9 in_10 in_11 in_12 in_13 in_14 in_15 wl_0 wl_1 wl_2 wl_3 wl_4 wl_5 wl_6 wl_7 wl_8 wl_9 wl_10 wl_11 wl_12 wl_13 wl_14 wl_15 en vdd gnd
|
||||
Xwl_driver_inv_en0 en en_bar_0 vdd gnd pinv_33
|
||||
Xwl_driver_nand0 en_bar_0 in_0 wl_bar_0 vdd gnd pnand2_6
|
||||
Xwl_driver_inv0 wl_bar_0 wl_0 vdd gnd pinv_32
|
||||
Xwl_driver_inv_en1 en en_bar_1 vdd gnd pinv_33
|
||||
Xwl_driver_nand1 en_bar_1 in_1 wl_bar_1 vdd gnd pnand2_6
|
||||
Xwl_driver_inv1 wl_bar_1 wl_1 vdd gnd pinv_32
|
||||
Xwl_driver_inv_en2 en en_bar_2 vdd gnd pinv_33
|
||||
Xwl_driver_nand2 en_bar_2 in_2 wl_bar_2 vdd gnd pnand2_6
|
||||
Xwl_driver_inv2 wl_bar_2 wl_2 vdd gnd pinv_32
|
||||
Xwl_driver_inv_en3 en en_bar_3 vdd gnd pinv_33
|
||||
Xwl_driver_nand3 en_bar_3 in_3 wl_bar_3 vdd gnd pnand2_6
|
||||
Xwl_driver_inv3 wl_bar_3 wl_3 vdd gnd pinv_32
|
||||
Xwl_driver_inv_en4 en en_bar_4 vdd gnd pinv_33
|
||||
Xwl_driver_nand4 en_bar_4 in_4 wl_bar_4 vdd gnd pnand2_6
|
||||
Xwl_driver_inv4 wl_bar_4 wl_4 vdd gnd pinv_32
|
||||
Xwl_driver_inv_en5 en en_bar_5 vdd gnd pinv_33
|
||||
Xwl_driver_nand5 en_bar_5 in_5 wl_bar_5 vdd gnd pnand2_6
|
||||
Xwl_driver_inv5 wl_bar_5 wl_5 vdd gnd pinv_32
|
||||
Xwl_driver_inv_en6 en en_bar_6 vdd gnd pinv_33
|
||||
Xwl_driver_nand6 en_bar_6 in_6 wl_bar_6 vdd gnd pnand2_6
|
||||
Xwl_driver_inv6 wl_bar_6 wl_6 vdd gnd pinv_32
|
||||
Xwl_driver_inv_en7 en en_bar_7 vdd gnd pinv_33
|
||||
Xwl_driver_nand7 en_bar_7 in_7 wl_bar_7 vdd gnd pnand2_6
|
||||
Xwl_driver_inv7 wl_bar_7 wl_7 vdd gnd pinv_32
|
||||
Xwl_driver_inv_en8 en en_bar_8 vdd gnd pinv_33
|
||||
Xwl_driver_nand8 en_bar_8 in_8 wl_bar_8 vdd gnd pnand2_6
|
||||
Xwl_driver_inv8 wl_bar_8 wl_8 vdd gnd pinv_32
|
||||
Xwl_driver_inv_en9 en en_bar_9 vdd gnd pinv_33
|
||||
Xwl_driver_nand9 en_bar_9 in_9 wl_bar_9 vdd gnd pnand2_6
|
||||
Xwl_driver_inv9 wl_bar_9 wl_9 vdd gnd pinv_32
|
||||
Xwl_driver_inv_en10 en en_bar_10 vdd gnd pinv_33
|
||||
Xwl_driver_nand10 en_bar_10 in_10 wl_bar_10 vdd gnd pnand2_6
|
||||
Xwl_driver_inv10 wl_bar_10 wl_10 vdd gnd pinv_32
|
||||
Xwl_driver_inv_en11 en en_bar_11 vdd gnd pinv_33
|
||||
Xwl_driver_nand11 en_bar_11 in_11 wl_bar_11 vdd gnd pnand2_6
|
||||
Xwl_driver_inv11 wl_bar_11 wl_11 vdd gnd pinv_32
|
||||
Xwl_driver_inv_en12 en en_bar_12 vdd gnd pinv_33
|
||||
Xwl_driver_nand12 en_bar_12 in_12 wl_bar_12 vdd gnd pnand2_6
|
||||
Xwl_driver_inv12 wl_bar_12 wl_12 vdd gnd pinv_32
|
||||
Xwl_driver_inv_en13 en en_bar_13 vdd gnd pinv_33
|
||||
Xwl_driver_nand13 en_bar_13 in_13 wl_bar_13 vdd gnd pnand2_6
|
||||
Xwl_driver_inv13 wl_bar_13 wl_13 vdd gnd pinv_32
|
||||
Xwl_driver_inv_en14 en en_bar_14 vdd gnd pinv_33
|
||||
Xwl_driver_nand14 en_bar_14 in_14 wl_bar_14 vdd gnd pnand2_6
|
||||
Xwl_driver_inv14 wl_bar_14 wl_14 vdd gnd pinv_32
|
||||
Xwl_driver_inv_en15 en en_bar_15 vdd gnd pinv_33
|
||||
Xwl_driver_nand15 en_bar_15 in_15 wl_bar_15 vdd gnd pnand2_6
|
||||
Xwl_driver_inv15 wl_bar_15 wl_15 vdd gnd pinv_32
|
||||
.ENDS wordline_driver
|
||||
|
||||
.SUBCKT pinv_34 A Z vdd gnd
|
||||
Mpinv_pmos Z A vdd vdd p m=1 w=1.6u l=0.4u pd=4.0u ps=4.0u as=1.6p ad=1.6p
|
||||
Mpinv_nmos Z A gnd gnd n m=1 w=0.8u l=0.4u pd=2.4000000000000004u ps=2.4000000000000004u as=0.8p ad=0.8p
|
||||
.ENDS pinv_34
|
||||
|
||||
.SUBCKT bank dout0_0 dout0_1 dout2_0 dout2_1 din0_0 din0_1 din1_0 din1_1 addr0_0 addr0_1 addr0_2 addr0_3 addr1_0 addr1_1 addr1_2 addr1_3 addr2_0 addr2_1 addr2_2 addr2_3 s_en0 s_en2 w_en0 w_en1 clk_buf_bar0 clk_buf0 clk_buf_bar1 clk_buf1 clk_buf_bar2 clk_buf2 vdd gnd
|
||||
Xbitcell_array bl0_0 br0_0 bl1_0 br1_0 bl2_0 br2_0 bl0_1 br0_1 bl1_1 br1_1 bl2_1 br2_1 wl0_0 wl1_0 wl2_0 wl0_1 wl1_1 wl2_1 wl0_2 wl1_2 wl2_2 wl0_3 wl1_3 wl2_3 wl0_4 wl1_4 wl2_4 wl0_5 wl1_5 wl2_5 wl0_6 wl1_6 wl2_6 wl0_7 wl1_7 wl2_7 wl0_8 wl1_8 wl2_8 wl0_9 wl1_9 wl2_9 wl0_10 wl1_10 wl2_10 wl0_11 wl1_11 wl2_11 wl0_12 wl1_12 wl2_12 wl0_13 wl1_13 wl2_13 wl0_14 wl1_14 wl2_14 wl0_15 wl1_15 wl2_15 vdd gnd bitcell_array_16x2_1
|
||||
Xprecharge_array0 bl0_0 br0_0 bl0_1 br0_1 clk_buf_bar0 vdd precharge_array_1
|
||||
Xprecharge_array2 bl2_0 br2_0 bl2_1 br2_1 clk_buf_bar2 vdd precharge_array_2
|
||||
Xsense_amp_array0 dout0_0 bl0_0 br0_0 dout0_1 bl0_1 br0_1 s_en0 vdd gnd sense_amp_array
|
||||
Xsense_amp_array2 dout2_0 bl2_0 br2_0 dout2_1 bl2_1 br2_1 s_en2 vdd gnd sense_amp_array
|
||||
Xwrite_driver_array0 din0_0 din0_1 bl0_0 br0_0 bl0_1 br0_1 w_en0 vdd gnd write_driver_array
|
||||
Xwrite_driver_array1 din1_0 din1_1 bl1_0 br1_0 bl1_1 br1_1 w_en1 vdd gnd write_driver_array
|
||||
Xrow_decoder0 addr0_0 addr0_1 addr0_2 addr0_3 dec_out0_0 dec_out0_1 dec_out0_2 dec_out0_3 dec_out0_4 dec_out0_5 dec_out0_6 dec_out0_7 dec_out0_8 dec_out0_9 dec_out0_10 dec_out0_11 dec_out0_12 dec_out0_13 dec_out0_14 dec_out0_15 vdd gnd hierarchical_decoder_16rows
|
||||
Xrow_decoder1 addr1_0 addr1_1 addr1_2 addr1_3 dec_out1_0 dec_out1_1 dec_out1_2 dec_out1_3 dec_out1_4 dec_out1_5 dec_out1_6 dec_out1_7 dec_out1_8 dec_out1_9 dec_out1_10 dec_out1_11 dec_out1_12 dec_out1_13 dec_out1_14 dec_out1_15 vdd gnd hierarchical_decoder_16rows
|
||||
Xrow_decoder2 addr2_0 addr2_1 addr2_2 addr2_3 dec_out2_0 dec_out2_1 dec_out2_2 dec_out2_3 dec_out2_4 dec_out2_5 dec_out2_6 dec_out2_7 dec_out2_8 dec_out2_9 dec_out2_10 dec_out2_11 dec_out2_12 dec_out2_13 dec_out2_14 dec_out2_15 vdd gnd hierarchical_decoder_16rows
|
||||
Xwordline_driver0 dec_out0_0 dec_out0_1 dec_out0_2 dec_out0_3 dec_out0_4 dec_out0_5 dec_out0_6 dec_out0_7 dec_out0_8 dec_out0_9 dec_out0_10 dec_out0_11 dec_out0_12 dec_out0_13 dec_out0_14 dec_out0_15 wl0_0 wl0_1 wl0_2 wl0_3 wl0_4 wl0_5 wl0_6 wl0_7 wl0_8 wl0_9 wl0_10 wl0_11 wl0_12 wl0_13 wl0_14 wl0_15 clk_buf0 vdd gnd wordline_driver
|
||||
Xwordline_driver1 dec_out1_0 dec_out1_1 dec_out1_2 dec_out1_3 dec_out1_4 dec_out1_5 dec_out1_6 dec_out1_7 dec_out1_8 dec_out1_9 dec_out1_10 dec_out1_11 dec_out1_12 dec_out1_13 dec_out1_14 dec_out1_15 wl1_0 wl1_1 wl1_2 wl1_3 wl1_4 wl1_5 wl1_6 wl1_7 wl1_8 wl1_9 wl1_10 wl1_11 wl1_12 wl1_13 wl1_14 wl1_15 clk_buf1 vdd gnd wordline_driver
|
||||
Xwordline_driver2 dec_out2_0 dec_out2_1 dec_out2_2 dec_out2_3 dec_out2_4 dec_out2_5 dec_out2_6 dec_out2_7 dec_out2_8 dec_out2_9 dec_out2_10 dec_out2_11 dec_out2_12 dec_out2_13 dec_out2_14 dec_out2_15 wl2_0 wl2_1 wl2_2 wl2_3 wl2_4 wl2_5 wl2_6 wl2_7 wl2_8 wl2_9 wl2_10 wl2_11 wl2_12 wl2_13 wl2_14 wl2_15 clk_buf2 vdd gnd wordline_driver
|
||||
.ENDS bank
|
||||
|
||||
.SUBCKT sram_2_16_scn4m_subm DIN0[0] DIN0[1] DIN1[0] DIN1[1] ADDR0[0] ADDR0[1] ADDR0[2] ADDR0[3] ADDR1[0] ADDR1[1] ADDR1[2] ADDR1[3] ADDR2[0] ADDR2[1] ADDR2[2] ADDR2[3] csb0 csb1 csb2 web0 clk0 clk1 clk2 DOUT0[0] DOUT0[1] DOUT2[0] DOUT2[1] vdd gnd
|
||||
Xbank0 DOUT0[0] DOUT0[1] DOUT2[0] DOUT2[1] BANK_DIN0[0] BANK_DIN0[1] BANK_DIN1[0] BANK_DIN1[1] A0[0] A0[1] A0[2] A0[3] A1[0] A1[1] A1[2] A1[3] A2[0] A2[1] A2[2] A2[3] s_en0 s_en2 w_en0 w_en1 clk_buf_bar0 clk_buf0 clk_buf_bar1 clk_buf1 clk_buf_bar2 clk_buf2 vdd gnd bank
|
||||
Xcontrol0 csb0 web0 clk0 s_en0 w_en0 clk_buf_bar0 clk_buf0 vdd gnd control_logic_rw
|
||||
Xcontrol1 csb1 clk1 w_en1 clk_buf_bar1 clk_buf1 vdd gnd control_logic_w
|
||||
Xcontrol2 csb2 clk2 s_en2 clk_buf_bar2 clk_buf2 vdd gnd control_logic_r
|
||||
Xrow_address0 ADDR0[0] ADDR0[1] ADDR0[2] ADDR0[3] A0[0] A0[1] A0[2] A0[3] clk_buf0 vdd gnd row_addr_dff
|
||||
Xrow_address1 ADDR1[0] ADDR1[1] ADDR1[2] ADDR1[3] A1[0] A1[1] A1[2] A1[3] clk_buf1 vdd gnd row_addr_dff
|
||||
Xrow_address2 ADDR2[0] ADDR2[1] ADDR2[2] ADDR2[3] A2[0] A2[1] A2[2] A2[3] clk_buf2 vdd gnd row_addr_dff
|
||||
Xdata_dff0 DIN0[0] DIN0[1] BANK_DIN0[0] BANK_DIN0[1] clk_buf0 vdd gnd data_dff
|
||||
Xdata_dff1 DIN1[0] DIN1[1] BANK_DIN1[0] BANK_DIN1[1] clk_buf1 vdd gnd data_dff
|
||||
.ENDS sram_2_16_scn4m_subm
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// OpenRAM SRAM model
|
||||
// Words: 16
|
||||
// Word size: 2
|
||||
|
||||
module sram_2_16_scn4m_subm(DATA,ADDR,CSb,WEb,OEb,clk);
|
||||
|
||||
parameter DATA_WIDTH = 2 ;
|
||||
parameter ADDR_WIDTH = 4 ;
|
||||
parameter RAM_DEPTH = 1 << ADDR_WIDTH;
|
||||
parameter DELAY = 3 ;
|
||||
|
||||
inout [DATA_WIDTH-1:0] DATA;
|
||||
input [ADDR_WIDTH-1:0] ADDR;
|
||||
input CSb; // active low chip select
|
||||
input WEb; // active low write control
|
||||
input OEb; // active output enable
|
||||
input clk; // clock
|
||||
|
||||
reg [DATA_WIDTH-1:0] data_out ;
|
||||
reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
|
||||
|
||||
// Tri-State Buffer control
|
||||
// output : When WEb = 1, oeb = 0, csb = 0
|
||||
assign DATA = (!CSb && !OEb && WEb) ? data_out : 2'bz;
|
||||
|
||||
// Memory Write Block
|
||||
// Write Operation : When WEb = 0, CSb = 0
|
||||
always @ (posedge clk)
|
||||
begin : MEM_WRITE
|
||||
if ( !CSb && !WEb ) begin
|
||||
mem[ADDR] = DATA;
|
||||
$display($time," Writing %m ABUS=%b DATA=%b",ADDR,DATA);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Memory Read Block
|
||||
// Read Operation : When WEb = 1, CSb = 0
|
||||
always @ (posedge clk)
|
||||
begin : MEM_READ
|
||||
if (!CSb && WEb) begin
|
||||
data_out <= #(DELAY) mem[ADDR];
|
||||
$display($time," Reading %m ABUS=%b DATA=%b",ADDR,mem[ADDR]);
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,321 @@
|
|||
library (sram_2_16_scn4m_subm_TT_3p3V_25C_lib){
|
||||
delay_model : "table_lookup";
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1v" ;
|
||||
current_unit : "1mA" ;
|
||||
resistance_unit : "1kohm" ;
|
||||
capacitive_load_unit(1 ,fF) ;
|
||||
leakage_power_unit : "1mW" ;
|
||||
pulling_resistance_unit :"1kohm" ;
|
||||
operating_conditions(OC){
|
||||
process : 1.0 ;
|
||||
voltage : 3.3 ;
|
||||
temperature : 25;
|
||||
}
|
||||
|
||||
input_threshold_pct_fall : 50.0 ;
|
||||
output_threshold_pct_fall : 50.0 ;
|
||||
input_threshold_pct_rise : 50.0 ;
|
||||
output_threshold_pct_rise : 50.0 ;
|
||||
slew_lower_threshold_pct_fall : 10.0 ;
|
||||
slew_upper_threshold_pct_fall : 90.0 ;
|
||||
slew_lower_threshold_pct_rise : 10.0 ;
|
||||
slew_upper_threshold_pct_rise : 90.0 ;
|
||||
|
||||
nom_voltage : 5.0;
|
||||
nom_temperature : 25;
|
||||
nom_process : 1.0;
|
||||
default_cell_leakage_power : 0.0 ;
|
||||
default_leakage_power_density : 0.0 ;
|
||||
default_input_pin_cap : 1.0 ;
|
||||
default_inout_pin_cap : 1.0 ;
|
||||
default_output_pin_cap : 0.0 ;
|
||||
default_max_transition : 0.5 ;
|
||||
default_fanout_load : 1.0 ;
|
||||
default_max_fanout : 4.0 ;
|
||||
default_connection_class : universal ;
|
||||
|
||||
lu_table_template(CELL_TABLE){
|
||||
variable_1 : input_net_transition;
|
||||
variable_2 : total_output_net_capacitance;
|
||||
index_1("0.0125, 0.05, 0.4");
|
||||
index_2("2.45605, 9.8242, 78.5936");
|
||||
}
|
||||
|
||||
lu_table_template(CONSTRAINT_TABLE){
|
||||
variable_1 : related_pin_transition;
|
||||
variable_2 : constrained_pin_transition;
|
||||
index_1("0.0125, 0.05, 0.4");
|
||||
index_2("0.0125, 0.05, 0.4");
|
||||
}
|
||||
|
||||
default_operating_conditions : OC;
|
||||
|
||||
|
||||
type (DATA){
|
||||
base_type : array;
|
||||
data_type : bit;
|
||||
bit_width : 2;
|
||||
bit_from : 0;
|
||||
bit_to : 1;
|
||||
}
|
||||
|
||||
type (ADDR){
|
||||
base_type : array;
|
||||
data_type : bit;
|
||||
bit_width : 4;
|
||||
bit_from : 0;
|
||||
bit_to : 3;
|
||||
}
|
||||
|
||||
cell (sram_2_16_scn4m_subm){
|
||||
memory(){
|
||||
type : ram;
|
||||
address_width : 4;
|
||||
word_width : 2;
|
||||
}
|
||||
interface_timing : true;
|
||||
dont_use : true;
|
||||
map_only : true;
|
||||
dont_touch : true;
|
||||
area : 69426.85;
|
||||
|
||||
leakage_power () {
|
||||
when : "CSb0";
|
||||
value : 0.000179;
|
||||
}
|
||||
cell_leakage_power : 0;
|
||||
bus(DIN0){
|
||||
bus_type : DATA;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
memory_write(){
|
||||
address : ADDR0;
|
||||
clocked_on : clk0;
|
||||
}
|
||||
pin(DIN0[1:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bus(DOUT0){
|
||||
bus_type : DATA;
|
||||
direction : output;
|
||||
max_capacitance : 78.5936;
|
||||
min_capacitance : 2.45605;
|
||||
memory_read(){
|
||||
address : ADDR0;
|
||||
}
|
||||
pin(DOUT0[1:0]){
|
||||
timing(){
|
||||
timing_sense : non_unate;
|
||||
related_pin : "clk0";
|
||||
timing_type : rising_edge;
|
||||
cell_rise(CELL_TABLE) {
|
||||
values("0.268, 0.268, 0.268",\
|
||||
"0.268, 0.268, 0.268",\
|
||||
"0.268, 0.268, 0.268");
|
||||
}
|
||||
cell_fall(CELL_TABLE) {
|
||||
values("0.268, 0.268, 0.268",\
|
||||
"0.268, 0.268, 0.268",\
|
||||
"0.268, 0.268, 0.268");
|
||||
}
|
||||
rise_transition(CELL_TABLE) {
|
||||
values("0.004, 0.004, 0.004",\
|
||||
"0.004, 0.004, 0.004",\
|
||||
"0.004, 0.004, 0.004");
|
||||
}
|
||||
fall_transition(CELL_TABLE) {
|
||||
values("0.004, 0.004, 0.004",\
|
||||
"0.004, 0.004, 0.004",\
|
||||
"0.004, 0.004, 0.004");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bus(ADDR0){
|
||||
bus_type : ADDR;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
max_transition : 0.4;
|
||||
pin(ADDR0[3:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(CSb0){
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(WEb0){
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(clk0){
|
||||
clock : true;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
internal_power(){
|
||||
when : "!CSb0 & clk0 & !WEb0";
|
||||
rise_power(scalar){
|
||||
values("2.46222038320038");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("2.46222038320038");
|
||||
}
|
||||
}
|
||||
internal_power(){
|
||||
when : "!CSb0 & !clk0 & WEb0";
|
||||
rise_power(scalar){
|
||||
values("2.46222038320038");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("2.46222038320038");
|
||||
}
|
||||
}
|
||||
internal_power(){
|
||||
when : "CSb0";
|
||||
rise_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"min_pulse_width";
|
||||
related_pin : clk0;
|
||||
rise_constraint(scalar) {
|
||||
values("0.0");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0.0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"minimum_period";
|
||||
related_pin : clk0;
|
||||
rise_constraint(scalar) {
|
||||
values("0");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,321 @@
|
|||
library (sram_2_16_scn4m_subm_TT_5V_25C_lib){
|
||||
delay_model : "table_lookup";
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1v" ;
|
||||
current_unit : "1mA" ;
|
||||
resistance_unit : "1kohm" ;
|
||||
capacitive_load_unit(1 ,fF) ;
|
||||
leakage_power_unit : "1mW" ;
|
||||
pulling_resistance_unit :"1kohm" ;
|
||||
operating_conditions(OC){
|
||||
process : 1.0 ;
|
||||
voltage : 5 ;
|
||||
temperature : 25;
|
||||
}
|
||||
|
||||
input_threshold_pct_fall : 50.0 ;
|
||||
output_threshold_pct_fall : 50.0 ;
|
||||
input_threshold_pct_rise : 50.0 ;
|
||||
output_threshold_pct_rise : 50.0 ;
|
||||
slew_lower_threshold_pct_fall : 10.0 ;
|
||||
slew_upper_threshold_pct_fall : 90.0 ;
|
||||
slew_lower_threshold_pct_rise : 10.0 ;
|
||||
slew_upper_threshold_pct_rise : 90.0 ;
|
||||
|
||||
nom_voltage : 5.0;
|
||||
nom_temperature : 25;
|
||||
nom_process : 1.0;
|
||||
default_cell_leakage_power : 0.0 ;
|
||||
default_leakage_power_density : 0.0 ;
|
||||
default_input_pin_cap : 1.0 ;
|
||||
default_inout_pin_cap : 1.0 ;
|
||||
default_output_pin_cap : 0.0 ;
|
||||
default_max_transition : 0.5 ;
|
||||
default_fanout_load : 1.0 ;
|
||||
default_max_fanout : 4.0 ;
|
||||
default_connection_class : universal ;
|
||||
|
||||
lu_table_template(CELL_TABLE){
|
||||
variable_1 : input_net_transition;
|
||||
variable_2 : total_output_net_capacitance;
|
||||
index_1("0.0125, 0.05, 0.4");
|
||||
index_2("2.45605, 9.8242, 78.5936");
|
||||
}
|
||||
|
||||
lu_table_template(CONSTRAINT_TABLE){
|
||||
variable_1 : related_pin_transition;
|
||||
variable_2 : constrained_pin_transition;
|
||||
index_1("0.0125, 0.05, 0.4");
|
||||
index_2("0.0125, 0.05, 0.4");
|
||||
}
|
||||
|
||||
default_operating_conditions : OC;
|
||||
|
||||
|
||||
type (DATA){
|
||||
base_type : array;
|
||||
data_type : bit;
|
||||
bit_width : 2;
|
||||
bit_from : 0;
|
||||
bit_to : 1;
|
||||
}
|
||||
|
||||
type (ADDR){
|
||||
base_type : array;
|
||||
data_type : bit;
|
||||
bit_width : 4;
|
||||
bit_from : 0;
|
||||
bit_to : 3;
|
||||
}
|
||||
|
||||
cell (sram_2_16_scn4m_subm){
|
||||
memory(){
|
||||
type : ram;
|
||||
address_width : 4;
|
||||
word_width : 2;
|
||||
}
|
||||
interface_timing : true;
|
||||
dont_use : true;
|
||||
map_only : true;
|
||||
dont_touch : true;
|
||||
area : 68347.21;
|
||||
|
||||
leakage_power () {
|
||||
when : "CSb0";
|
||||
value : 0.000179;
|
||||
}
|
||||
cell_leakage_power : 0;
|
||||
bus(DIN0){
|
||||
bus_type : DATA;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
memory_write(){
|
||||
address : ADDR0;
|
||||
clocked_on : clk0;
|
||||
}
|
||||
pin(DIN0[1:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bus(DOUT0){
|
||||
bus_type : DATA;
|
||||
direction : output;
|
||||
max_capacitance : 78.5936;
|
||||
min_capacitance : 2.45605;
|
||||
memory_read(){
|
||||
address : ADDR0;
|
||||
}
|
||||
pin(DOUT0[1:0]){
|
||||
timing(){
|
||||
timing_sense : non_unate;
|
||||
related_pin : "clk0";
|
||||
timing_type : rising_edge;
|
||||
cell_rise(CELL_TABLE) {
|
||||
values("0.268, 0.268, 0.268",\
|
||||
"0.268, 0.268, 0.268",\
|
||||
"0.268, 0.268, 0.268");
|
||||
}
|
||||
cell_fall(CELL_TABLE) {
|
||||
values("0.268, 0.268, 0.268",\
|
||||
"0.268, 0.268, 0.268",\
|
||||
"0.268, 0.268, 0.268");
|
||||
}
|
||||
rise_transition(CELL_TABLE) {
|
||||
values("0.004, 0.004, 0.004",\
|
||||
"0.004, 0.004, 0.004",\
|
||||
"0.004, 0.004, 0.004");
|
||||
}
|
||||
fall_transition(CELL_TABLE) {
|
||||
values("0.004, 0.004, 0.004",\
|
||||
"0.004, 0.004, 0.004",\
|
||||
"0.004, 0.004, 0.004");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bus(ADDR0){
|
||||
bus_type : ADDR;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
max_transition : 0.4;
|
||||
pin(ADDR0[3:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(CSb0){
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(WEb0){
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(clk0){
|
||||
clock : true;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
internal_power(){
|
||||
when : "!CSb0 & clk0 & !WEb0";
|
||||
rise_power(scalar){
|
||||
values("2.46222038320038");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("2.46222038320038");
|
||||
}
|
||||
}
|
||||
internal_power(){
|
||||
when : "!CSb0 & !clk0 & WEb0";
|
||||
rise_power(scalar){
|
||||
values("2.46222038320038");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("2.46222038320038");
|
||||
}
|
||||
}
|
||||
internal_power(){
|
||||
when : "CSb0";
|
||||
rise_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"min_pulse_width";
|
||||
related_pin : clk0;
|
||||
rise_constraint(scalar) {
|
||||
values("0.0");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0.0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"minimum_period";
|
||||
related_pin : clk0;
|
||||
rise_constraint(scalar) {
|
||||
values("0");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,625 @@
|
|||
library (sram_2_16_scn4m_subm_TT_5p0V_25C_lib){
|
||||
delay_model : "table_lookup";
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1v" ;
|
||||
current_unit : "1mA" ;
|
||||
resistance_unit : "1kohm" ;
|
||||
capacitive_load_unit(1 ,fF) ;
|
||||
leakage_power_unit : "1mW" ;
|
||||
pulling_resistance_unit :"1kohm" ;
|
||||
operating_conditions(OC){
|
||||
process : 1.0 ;
|
||||
voltage : 5.0 ;
|
||||
temperature : 25;
|
||||
}
|
||||
|
||||
input_threshold_pct_fall : 50.0 ;
|
||||
output_threshold_pct_fall : 50.0 ;
|
||||
input_threshold_pct_rise : 50.0 ;
|
||||
output_threshold_pct_rise : 50.0 ;
|
||||
slew_lower_threshold_pct_fall : 10.0 ;
|
||||
slew_upper_threshold_pct_fall : 90.0 ;
|
||||
slew_lower_threshold_pct_rise : 10.0 ;
|
||||
slew_upper_threshold_pct_rise : 90.0 ;
|
||||
|
||||
nom_voltage : 5.0;
|
||||
nom_temperature : 25;
|
||||
nom_process : 1.0;
|
||||
default_cell_leakage_power : 0.0 ;
|
||||
default_leakage_power_density : 0.0 ;
|
||||
default_input_pin_cap : 1.0 ;
|
||||
default_inout_pin_cap : 1.0 ;
|
||||
default_output_pin_cap : 0.0 ;
|
||||
default_max_transition : 0.5 ;
|
||||
default_fanout_load : 1.0 ;
|
||||
default_max_fanout : 4.0 ;
|
||||
default_connection_class : universal ;
|
||||
|
||||
lu_table_template(CELL_TABLE){
|
||||
variable_1 : input_net_transition;
|
||||
variable_2 : total_output_net_capacitance;
|
||||
index_1("0.0125, 0.05, 0.4");
|
||||
index_2("2.45605, 9.8242, 78.5936");
|
||||
}
|
||||
|
||||
lu_table_template(CONSTRAINT_TABLE){
|
||||
variable_1 : related_pin_transition;
|
||||
variable_2 : constrained_pin_transition;
|
||||
index_1("0.0125, 0.05, 0.4");
|
||||
index_2("0.0125, 0.05, 0.4");
|
||||
}
|
||||
|
||||
default_operating_conditions : OC;
|
||||
|
||||
|
||||
type (DATA){
|
||||
base_type : array;
|
||||
data_type : bit;
|
||||
bit_width : 2;
|
||||
bit_from : 0;
|
||||
bit_to : 1;
|
||||
}
|
||||
|
||||
type (ADDR){
|
||||
base_type : array;
|
||||
data_type : bit;
|
||||
bit_width : 4;
|
||||
bit_from : 0;
|
||||
bit_to : 3;
|
||||
}
|
||||
|
||||
cell (sram_2_16_scn4m_subm){
|
||||
memory(){
|
||||
type : ram;
|
||||
address_width : 4;
|
||||
word_width : 2;
|
||||
}
|
||||
interface_timing : true;
|
||||
dont_use : true;
|
||||
map_only : true;
|
||||
dont_touch : true;
|
||||
area : 0;
|
||||
|
||||
leakage_power () {
|
||||
when : "CSb0 & CSb1 & CSb2";
|
||||
value : 0.000436;
|
||||
}
|
||||
cell_leakage_power : 0;
|
||||
bus(DIN0){
|
||||
bus_type : DATA;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
memory_write(){
|
||||
address : ADDR0;
|
||||
clocked_on : clk0;
|
||||
}
|
||||
pin(DIN0[1:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bus(DOUT0){
|
||||
bus_type : DATA;
|
||||
direction : output;
|
||||
max_capacitance : 78.5936;
|
||||
min_capacitance : 2.45605;
|
||||
memory_read(){
|
||||
address : ADDR0;
|
||||
}
|
||||
pin(DOUT0[1:0]){
|
||||
timing(){
|
||||
timing_sense : non_unate;
|
||||
related_pin : "clk0";
|
||||
timing_type : rising_edge;
|
||||
cell_rise(CELL_TABLE) {
|
||||
values("0.079, 0.079, 0.079",\
|
||||
"0.079, 0.079, 0.079",\
|
||||
"0.079, 0.079, 0.079");
|
||||
}
|
||||
cell_fall(CELL_TABLE) {
|
||||
values("0.079, 0.079, 0.079",\
|
||||
"0.079, 0.079, 0.079",\
|
||||
"0.079, 0.079, 0.079");
|
||||
}
|
||||
rise_transition(CELL_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_transition(CELL_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bus(ADDR0){
|
||||
bus_type : ADDR;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
max_transition : 0.4;
|
||||
pin(ADDR0[3:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(CSb0){
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(WEb0){
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk0";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(clk0){
|
||||
clock : true;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
internal_power(){
|
||||
when : "!CSb0 & clk0 & !WEb0";
|
||||
rise_power(scalar){
|
||||
values("15.41143495605");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("15.41143495605");
|
||||
}
|
||||
}
|
||||
internal_power(){
|
||||
when : "!CSb0 & !clk0 & WEb0";
|
||||
rise_power(scalar){
|
||||
values("15.41143495605");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("15.41143495605");
|
||||
}
|
||||
}
|
||||
internal_power(){
|
||||
when : "CSb0";
|
||||
rise_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"min_pulse_width";
|
||||
related_pin : clk0;
|
||||
rise_constraint(scalar) {
|
||||
values("0.0");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0.0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"minimum_period";
|
||||
related_pin : clk0;
|
||||
rise_constraint(scalar) {
|
||||
values("0");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bus(DIN1){
|
||||
bus_type : DATA;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
memory_write(){
|
||||
address : ADDR1;
|
||||
clocked_on : clk1;
|
||||
}
|
||||
pin(DIN1[1:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk1";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk1";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bus(ADDR1){
|
||||
bus_type : ADDR;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
max_transition : 0.4;
|
||||
pin(ADDR1[3:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk1";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk1";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(CSb1){
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk1";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk1";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(clk1){
|
||||
clock : true;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
internal_power(){
|
||||
when : "!CSb1 & clk1";
|
||||
rise_power(scalar){
|
||||
values("15.41143495605");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("15.41143495605");
|
||||
}
|
||||
}
|
||||
internal_power(){
|
||||
when : "CSb1";
|
||||
rise_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"min_pulse_width";
|
||||
related_pin : clk1;
|
||||
rise_constraint(scalar) {
|
||||
values("0.0");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0.0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"minimum_period";
|
||||
related_pin : clk1;
|
||||
rise_constraint(scalar) {
|
||||
values("0");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bus(DOUT2){
|
||||
bus_type : DATA;
|
||||
direction : output;
|
||||
max_capacitance : 78.5936;
|
||||
min_capacitance : 2.45605;
|
||||
memory_read(){
|
||||
address : ADDR2;
|
||||
}
|
||||
pin(DOUT2[1:0]){
|
||||
timing(){
|
||||
timing_sense : non_unate;
|
||||
related_pin : "clk2";
|
||||
timing_type : rising_edge;
|
||||
cell_rise(CELL_TABLE) {
|
||||
values("0.079, 0.079, 0.079",\
|
||||
"0.079, 0.079, 0.079",\
|
||||
"0.079, 0.079, 0.079");
|
||||
}
|
||||
cell_fall(CELL_TABLE) {
|
||||
values("0.079, 0.079, 0.079",\
|
||||
"0.079, 0.079, 0.079",\
|
||||
"0.079, 0.079, 0.079");
|
||||
}
|
||||
rise_transition(CELL_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_transition(CELL_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bus(ADDR2){
|
||||
bus_type : ADDR;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
max_transition : 0.4;
|
||||
pin(ADDR2[3:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk2";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk2";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(CSb2){
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk2";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009",\
|
||||
"0.009, 0.009, 0.009");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : hold_rising;
|
||||
related_pin : "clk2";
|
||||
rise_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
fall_constraint(CONSTRAINT_TABLE) {
|
||||
values("0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001",\
|
||||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pin(clk2){
|
||||
clock : true;
|
||||
direction : input;
|
||||
capacitance : 9.8242;
|
||||
internal_power(){
|
||||
when : "!CSb2 & !clk2";
|
||||
rise_power(scalar){
|
||||
values("15.41143495605");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("15.41143495605");
|
||||
}
|
||||
}
|
||||
internal_power(){
|
||||
when : "CSb2";
|
||||
rise_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"min_pulse_width";
|
||||
related_pin : clk2;
|
||||
rise_constraint(scalar) {
|
||||
values("0.0");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0.0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"minimum_period";
|
||||
related_pin : clk2;
|
||||
rise_constraint(scalar) {
|
||||
values("0");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/* Style the button that is used to open and close the collapsible content */
|
||||
.collapsible {
|
||||
background-color: #eee;
|
||||
color: #444;
|
||||
cursor: pointer;
|
||||
padding: 18px;
|
||||
width: 100%;
|
||||
border: none;
|
||||
text-align: left;
|
||||
outline: none;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
/* Add a background color to the button if it is clicked on (add the .active class with JS), and when you move the mouse over it (hover) */
|
||||
.active, .collapsible:hover {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
/* Style the collapsible content. Note: hidden by default */
|
||||
.content {
|
||||
padding: 0 18px;
|
||||
display: none;
|
||||
overflow: hidden;
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
</ul>
|
||||
<link rel="stylesheet" href="static/index.css">
|
||||
|
||||
<button class="collapsible">files</button>
|
||||
<div class="content">
|
||||
{% for root, dir, files in os.walk(filedir) %}
|
||||
{% if root != filedir %}
|
||||
|
||||
|
||||
<button class="collapsible">{{ root }}</button>
|
||||
<div class="content">
|
||||
{% for f in files %}
|
||||
<button class="collapsible">{{ f }}</button>
|
||||
<div class="content">
|
||||
<a href="{{ root }}/{{ f }}">link</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
var coll = document.getElementsByClassName("collapsible");
|
||||
var i;
|
||||
|
||||
for (i = 0; i < coll.length; i++) {
|
||||
coll[i].addEventListener("click", function() {
|
||||
this.classList.toggle("active");
|
||||
var content = this.nextElementSibling;
|
||||
if (content.style.display === "block") {
|
||||
content.style.display = "none";
|
||||
} else {
|
||||
content.style.display = "block";
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</ul>
|
||||
|
|
@ -1,12 +1,18 @@
|
|||
from flask_table import *
|
||||
|
||||
class timing_and_current_data(Table):
|
||||
"""
|
||||
Set up timing and current table columns and title information
|
||||
"""
|
||||
parameter = Col('Parameter')
|
||||
min = Col('Min')
|
||||
max = Col('Max')
|
||||
units = Col('Units')
|
||||
|
||||
class timing_and_current_data_item(object):
|
||||
"""
|
||||
Define timing and current data row element
|
||||
"""
|
||||
def __init__(self, parameter, min, max, units):
|
||||
self.parameter = parameter
|
||||
self.min = min
|
||||
|
|
|
|||
|
|
@ -0,0 +1,827 @@
|
|||
#!/usr/bin/python
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2011-2016 Aliaksei Chapyzhenka
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
# Translated to Python from original file:
|
||||
# https://github.com/drom/wavedrom/blob/master/src/WaveDrom.js
|
||||
#
|
||||
|
||||
import sys
|
||||
import json
|
||||
import math
|
||||
import waveskin
|
||||
|
||||
font_width = 7
|
||||
|
||||
lane = {
|
||||
"xs" : 20, # tmpgraphlane0.width
|
||||
"ys" : 20, # tmpgraphlane0.height
|
||||
"xg" : 120, # tmpgraphlane0.x
|
||||
"yg" : 0, # head gap
|
||||
"yh0" : 0, # head gap title
|
||||
"yh1" : 0, # head gap
|
||||
"yf0" : 0, # foot gap
|
||||
"yf1" : 0, # foot gap
|
||||
"y0" : 5, # tmpgraphlane0.y
|
||||
"yo" : 30, # tmpgraphlane1.y - y0
|
||||
"tgo" : -10, # tmptextlane0.x - xg
|
||||
"ym" : 15, # tmptextlane0.y - y0
|
||||
"xlabel" : 6, # tmptextlabel.x - xg
|
||||
"xmax" : 1,
|
||||
"scale" : 1,
|
||||
"head" : {},
|
||||
"foot" : {}
|
||||
}
|
||||
|
||||
def genBrick (texts, extra, times) :
|
||||
|
||||
R = []
|
||||
if len( texts ) == 4 :
|
||||
for j in range( times ):
|
||||
|
||||
R.append(texts[0])
|
||||
|
||||
for i in range ( extra ):
|
||||
R.append(texts[1])
|
||||
|
||||
R.append(texts[2])
|
||||
for i in range ( extra ):
|
||||
R.append(texts[3])
|
||||
|
||||
return R
|
||||
|
||||
if len( texts ) == 1 :
|
||||
texts.append(texts[0])
|
||||
|
||||
R.append(texts[0])
|
||||
for i in range (times * (2 * (extra + 1)) - 1) :
|
||||
R.append(texts[1])
|
||||
return R
|
||||
|
||||
def genFirstWaveBrick (text, extra, times) :
|
||||
|
||||
pattern = {
|
||||
'p': ['pclk', '111', 'nclk', '000'],
|
||||
'n': ['nclk', '000', 'pclk', '111'],
|
||||
'P': ['Pclk', '111', 'nclk', '000'],
|
||||
'N': ['Nclk', '000', 'pclk', '111'],
|
||||
'l': ['000'],
|
||||
'L': ['000'],
|
||||
'0': ['000'],
|
||||
'h': ['111'],
|
||||
'H': ['111'],
|
||||
'1': ['111'],
|
||||
'=': ['vvv-2'],
|
||||
'2': ['vvv-2'],
|
||||
'3': ['vvv-3'],
|
||||
'4': ['vvv-4'],
|
||||
'5': ['vvv-5'],
|
||||
'd': ['ddd'],
|
||||
'u': ['uuu'],
|
||||
'z': ['zzz']
|
||||
}
|
||||
|
||||
return genBrick( pattern.get( text, ['xxx'] ) , extra, times );
|
||||
|
||||
def genWaveBrick (text, extra, times) :
|
||||
|
||||
x1 = {'p':'pclk', 'n':'nclk', 'P':'Pclk', 'N':'Nclk', 'h':'pclk', 'l':'nclk', 'H':'Pclk', 'L':'Nclk'}
|
||||
x2 = {'0':'0', '1':'1', 'x':'x', 'd':'d', 'u':'u', 'z':'z', '=':'v', '2':'v', '3':'v', '4':'v', '5':'v' }
|
||||
x3 = {'0': '', '1': '', 'x': '', 'd': '', 'u': '', 'z': '', '=':'-2', '2':'-2', '3':'-3', '4':'-4', '5':'-5'}
|
||||
y1 = {
|
||||
'p':'0', 'n':'1',
|
||||
'P':'0', 'N':'1',
|
||||
'h':'1', 'l':'0',
|
||||
'H':'1', 'L':'0',
|
||||
'0':'0', '1':'1', 'x':'x', 'd':'d', 'u':'u', 'z':'z', '=':'v', '2':'v', '3':'v', '4':'v', '5':'v'}
|
||||
|
||||
y2 = {
|
||||
'p': '', 'n': '',
|
||||
'P': '', 'N': '',
|
||||
'h': '', 'l': '',
|
||||
'H': '', 'L': '',
|
||||
'0': '', '1': '', 'x': '', 'd': '', 'u': '', 'z': '', '=':'-2', '2':'-2', '3':'-3', '4':'-4', '5':'-5'}
|
||||
|
||||
x4 = {
|
||||
'p': '111', 'n': '000',
|
||||
'P': '111', 'N': '000',
|
||||
'h': '111', 'l': '000',
|
||||
'H': '111', 'L': '000',
|
||||
'0': '000', '1': '111', 'x': 'xxx', 'd': 'ddd', 'u': 'uuu', 'z': 'zzz',
|
||||
'=': 'vvv-2', '2': 'vvv-2', '3': 'vvv-3', '4': 'vvv-4', '5': 'vvv-5'}
|
||||
|
||||
x5 = {'p':'nclk', 'n':'pclk', 'P':'nclk', 'N':'pclk'}
|
||||
x6 = {'p': '000', 'n': '111', 'P': '000', 'N': '111'}
|
||||
xclude = {'hp':'111', 'Hp':'111', 'ln': '000', 'Ln': '000', 'nh':'111', 'Nh':'111', 'pl': '000', 'Pl':'000'}
|
||||
|
||||
#atext = text.split()
|
||||
atext = text
|
||||
|
||||
tmp0 = x4.get(atext[1])
|
||||
tmp1 = x1.get(atext[1])
|
||||
if tmp1 == None :
|
||||
tmp2 = x2.get(atext[1])
|
||||
if tmp2 == None :
|
||||
# unknown
|
||||
return genBrick(['xxx'], extra, times)
|
||||
else :
|
||||
tmp3 = y1.get(atext[0])
|
||||
if tmp3 == None :
|
||||
# unknown
|
||||
return genBrick(['xxx'], extra, times)
|
||||
|
||||
# soft curves
|
||||
return genBrick([tmp3 + 'm' + tmp2 + y2[atext[0]] + x3[atext[1]], tmp0], extra, times)
|
||||
|
||||
else :
|
||||
tmp4 = xclude.get(text)
|
||||
if tmp4 != None :
|
||||
tmp1 = tmp4
|
||||
|
||||
# sharp curves
|
||||
tmp2 = x5.get(atext[1])
|
||||
if tmp2 == None :
|
||||
# hlHL
|
||||
return genBrick([tmp1, tmp0], extra, times)
|
||||
else :
|
||||
# pnPN
|
||||
return genBrick([tmp1, tmp0, tmp2, x6[atext[1]]], extra, times)
|
||||
|
||||
def parseWaveLane (text, extra) :
|
||||
|
||||
R = []
|
||||
Stack = text
|
||||
Next = Stack[0]
|
||||
Stack = Stack[1:]
|
||||
|
||||
Repeats = 1
|
||||
while len(Stack) and ( Stack[0] == '.' or Stack[0] == '|' ): # repeaters parser
|
||||
Stack=Stack[1:]
|
||||
Repeats += 1
|
||||
|
||||
R.extend(genFirstWaveBrick(Next, extra, Repeats))
|
||||
|
||||
while len(Stack) :
|
||||
Top = Next
|
||||
Next = Stack[0]
|
||||
Stack = Stack[1:]
|
||||
Repeats = 1
|
||||
while len(Stack) and ( Stack[0] == '.' or Stack[0] == '|' ) : # repeaters parser
|
||||
Stack=Stack[1:]
|
||||
Repeats += 1
|
||||
R.extend(genWaveBrick((Top + Next), extra, Repeats))
|
||||
|
||||
for i in range( lane['phase'] ):
|
||||
R = R[1:]
|
||||
return R
|
||||
|
||||
def parseWaveLanes (sig) :
|
||||
|
||||
def data_extract (e) :
|
||||
tmp = e.get('data')
|
||||
if tmp == None : return None
|
||||
if is_type_str (tmp) : tmp=tmp.split()
|
||||
return tmp
|
||||
|
||||
content = []
|
||||
for sigx in sig :
|
||||
lane['period'] = sigx.get('period',1)
|
||||
lane['phase'] = int( sigx.get('phase',0 ) * 2 )
|
||||
sub_content=[]
|
||||
sub_content.append( [sigx.get('name',' '), sigx.get('phase',0 ) ] )
|
||||
sub_content.append( parseWaveLane( sigx['wave'], int(lane['period'] * lane['hscale'] - 1 ) ) if sigx.get('wave') else None )
|
||||
sub_content.append( data_extract(sigx) )
|
||||
content.append(sub_content)
|
||||
|
||||
return content
|
||||
|
||||
def findLaneMarkers (lanetext) :
|
||||
|
||||
lcount = 0
|
||||
gcount = 0
|
||||
ret = []
|
||||
for i in range( len( lanetext ) ) :
|
||||
if lanetext[i] == 'vvv-2' or lanetext[i] == 'vvv-3' or lanetext[i] == 'vvv-4' or lanetext[i] == 'vvv-5' :
|
||||
lcount += 1
|
||||
else :
|
||||
if lcount !=0 :
|
||||
ret.append(gcount - ((lcount + 1) / 2))
|
||||
lcount = 0
|
||||
|
||||
gcount += 1
|
||||
|
||||
if lcount != 0 :
|
||||
ret.append(gcount - ((lcount + 1) / 2))
|
||||
|
||||
return ret
|
||||
|
||||
def renderWaveLane (root, content, index) :
|
||||
|
||||
xmax = 0
|
||||
xgmax = 0
|
||||
glengths = []
|
||||
svgns = 'http://www.w3.org/2000/svg'
|
||||
xlinkns = 'http://www.w3.org/1999/xlink'
|
||||
xmlns = 'http://www.w3.org/XML/1998/namespace'
|
||||
for j in range( len(content) ):
|
||||
name = content[j][0][0]
|
||||
if name : # check name
|
||||
g = [
|
||||
'g',
|
||||
{
|
||||
'id': 'wavelane_' + str(j) + '_' + str(index),
|
||||
'transform': 'translate(0,' + str(lane['y0'] + j * lane['yo']) + ')'
|
||||
}
|
||||
]
|
||||
root.append(g)
|
||||
title = [
|
||||
'text',
|
||||
{
|
||||
'x': lane['tgo'],
|
||||
'y': lane['ym'],
|
||||
'class': 'info',
|
||||
'text-anchor': 'end',
|
||||
'xml:space': 'preserve'
|
||||
},
|
||||
['tspan', name]
|
||||
]
|
||||
g.append(title)
|
||||
|
||||
glengths.append( len(name) * font_width + font_width )
|
||||
|
||||
xoffset = content[j][0][1]
|
||||
xoffset = math.ceil(2 * xoffset) - 2 * xoffset if xoffset > 0 else -2 * xoffset
|
||||
gg = [
|
||||
'g',
|
||||
{
|
||||
'id': 'wavelane_draw_' + str(j) + '_' + str(index),
|
||||
'transform': 'translate(' + str( xoffset * lane['xs'] ) + ', 0)'
|
||||
}
|
||||
]
|
||||
g.append(gg)
|
||||
|
||||
if content[j][1] :
|
||||
for i in range( len(content[j][1]) ) :
|
||||
b = [
|
||||
'use',
|
||||
{
|
||||
#'id': 'use_' + str(i) + '_' + str(j) + '_' + str(index),
|
||||
'xmlns:xlink':xlinkns,
|
||||
'xlink:href': '#' + str( content[j][1][i] ),
|
||||
'transform': 'translate(' + str(i * lane['xs']) + ')'
|
||||
}
|
||||
]
|
||||
gg.append(b)
|
||||
|
||||
if content[j][2] and len(content[j][2]) :
|
||||
labels = findLaneMarkers(content[j][1])
|
||||
if len(labels) != 0 :
|
||||
for k in range( len(labels) ) :
|
||||
if content[j][2] and k < len(content[j][2]) :
|
||||
title = [
|
||||
'text',
|
||||
{
|
||||
'x': int(labels[k]) * lane['xs'] + lane['xlabel'],
|
||||
'y': lane['ym'],
|
||||
'text-anchor': 'middle',
|
||||
'xml:space': 'preserve'
|
||||
},
|
||||
['tspan',content[j][2][k]]
|
||||
]
|
||||
gg.append(title)
|
||||
|
||||
|
||||
if len(content[j][1]) > xmax :
|
||||
xmax = len(content[j][1])
|
||||
|
||||
lane['xmax'] = xmax
|
||||
lane['xg'] = xgmax + 20
|
||||
return glengths
|
||||
|
||||
def renderMarks (root, content, index) :
|
||||
|
||||
def captext ( g, cxt, anchor, y ) :
|
||||
|
||||
if cxt.get(anchor) and cxt[anchor].get('text') :
|
||||
tmark = [
|
||||
'text',
|
||||
{
|
||||
'x': float( cxt['xmax'] ) * float( cxt['xs'] ) / 2,
|
||||
'y': y,
|
||||
'text-anchor': 'middle',
|
||||
'fill': '#000',
|
||||
'xml:space': 'preserve'
|
||||
}, cxt[anchor]['text']
|
||||
]
|
||||
g.append(tmark)
|
||||
|
||||
def ticktock ( g, cxt, ref1, ref2, x, dx, y, length ) :
|
||||
L = []
|
||||
|
||||
if cxt.get(ref1) == None or cxt[ref1].get(ref2) == None :
|
||||
return
|
||||
|
||||
val = cxt[ref1][ref2]
|
||||
if is_type_str( val ) :
|
||||
val = val.split()
|
||||
elif type( val ) is int :
|
||||
offset = val
|
||||
val = []
|
||||
for i in range ( length ) :
|
||||
val.append(i + offset)
|
||||
|
||||
if type( val ) is list :
|
||||
if len( val ) == 0 :
|
||||
return
|
||||
elif len( val ) == 1 :
|
||||
offset = val[0]
|
||||
if is_type_str(offset) :
|
||||
L = val
|
||||
else :
|
||||
for i in range ( length ) :
|
||||
L[i] = i + offset
|
||||
|
||||
elif len( val ) == 2:
|
||||
offset = int(val[0])
|
||||
step = int(val[1])
|
||||
tmp = val[1].split('.')
|
||||
if len( tmp ) == 2 :
|
||||
dp = len( tmp[1] )
|
||||
|
||||
if is_type_str(offset) or is_type_str(step) :
|
||||
L = val
|
||||
else :
|
||||
offset = step * offset
|
||||
for i in range( length ) :
|
||||
L[i] = "{0:.",dp,"f}".format(step * i + offset)
|
||||
|
||||
else :
|
||||
L = val
|
||||
|
||||
else :
|
||||
return
|
||||
|
||||
for i in range( length ) :
|
||||
tmp = L[i]
|
||||
tmark = [
|
||||
'text',
|
||||
{
|
||||
'x': i * dx + x,
|
||||
'y': y,
|
||||
'text-anchor': 'middle',
|
||||
'class': 'muted',
|
||||
'xml:space': 'preserve'
|
||||
}, str(tmp)
|
||||
]
|
||||
g.append(tmark)
|
||||
|
||||
mstep = 2 * int(lane['hscale'])
|
||||
mmstep = mstep * lane['xs']
|
||||
marks = int( lane['xmax'] / mstep )
|
||||
gy = len( content ) * int(lane['yo'])
|
||||
|
||||
g = ['g', {'id': 'gmarks_' + str(index)}]
|
||||
root.insert(0,g)
|
||||
|
||||
for i in range( marks + 1):
|
||||
gg = [
|
||||
'path',
|
||||
{
|
||||
'id': 'gmark_' + str(i) + '_' + str(index),
|
||||
'd': 'm ' + str(i * mmstep) + ',' + '0' + ' 0,' + str(gy),
|
||||
'style': 'stroke:#888;stroke-width:0.5;stroke-dasharray:1,3'
|
||||
}
|
||||
]
|
||||
g.append( gg )
|
||||
|
||||
captext(g, lane, 'head', -33 if lane['yh0'] else -13 )
|
||||
captext(g, lane, 'foot', gy + ( 45 if lane['yf0'] else 25 ) )
|
||||
|
||||
ticktock( g, lane, 'head', 'tick', 0, mmstep, -5, marks + 1)
|
||||
ticktock( g, lane, 'head', 'tock', mmstep / 2, mmstep, -5, marks)
|
||||
ticktock( g, lane, 'foot', 'tick', 0, mmstep, gy + 15, marks + 1)
|
||||
ticktock( g, lane, 'foot', 'tock', mmstep / 2, mmstep, gy + 15, marks)
|
||||
|
||||
def renderArcs (root, source, index, top) :
|
||||
|
||||
Stack = []
|
||||
Edge = {'words': [], 'frm': 0, 'shape': '', 'to': 0, 'label': ''}
|
||||
Events = {}
|
||||
svgns = 'http://www.w3.org/2000/svg'
|
||||
xmlns = 'http://www.w3.org/XML/1998/namespace'
|
||||
|
||||
if source :
|
||||
for i in range (len (source) ) :
|
||||
lane['period'] = source[i].get('period',1)
|
||||
lane['phase'] = int( source[i].get('phase',0 ) * 2 )
|
||||
text = source[i].get('node')
|
||||
if text:
|
||||
Stack = text
|
||||
pos = 0
|
||||
while len( Stack ) :
|
||||
eventname = Stack[0]
|
||||
Stack=Stack[1:]
|
||||
if eventname != '.' :
|
||||
Events[eventname] = {
|
||||
'x' : str( int( float( lane['xs'] ) * (2 * pos * lane['period'] * lane['hscale'] - lane['phase'] ) + float( lane['xlabel'] ) ) ),
|
||||
'y' : str( int( i * lane['yo'] + lane['y0'] + float( lane['ys'] ) * 0.5 ) )
|
||||
}
|
||||
pos += 1
|
||||
|
||||
gg = [ 'g', { 'id' : 'wavearcs_' + str( index ) } ]
|
||||
root.append(gg)
|
||||
|
||||
if top.get('edge') :
|
||||
for i in range( len ( top['edge'] ) ) :
|
||||
Edge['words'] = top['edge'][i].split()
|
||||
Edge['label'] = top['edge'][i][len(Edge['words'][0]):]
|
||||
Edge['label'] = Edge['label'][1:]
|
||||
Edge['frm'] = Edge['words'][0][0]
|
||||
Edge['to'] = Edge['words'][0][-1]
|
||||
Edge['shape'] = Edge['words'][0][1:-1]
|
||||
frm = Events[Edge['frm']]
|
||||
to = Events[Edge['to']]
|
||||
gmark = [
|
||||
'path',
|
||||
{
|
||||
'id': 'gmark_' + Edge['frm'] + '_' + Edge['to'],
|
||||
'd': 'M ' + frm['x'] + ',' + frm['y'] + ' ' + to['x'] + ',' + to['y'],
|
||||
'style': 'fill:none;stroke:#00F;stroke-width:1'
|
||||
}
|
||||
]
|
||||
gg.append(gmark)
|
||||
dx = float( to['x'] ) - float( frm['x'] )
|
||||
dy = float( to['y'] ) - float( frm['y'] )
|
||||
lx = (float(frm['x']) + float(to['x'])) / 2
|
||||
ly = (float(frm['y']) + float(to['y'])) / 2
|
||||
pattern = {
|
||||
'~' : {'d': 'M ' + frm['x'] + ',' + frm['y'] + ' c ' + str(0.7 * dx) + ', 0 ' + str(0.3 * dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy) },
|
||||
'-~' : {'d': 'M ' + frm['x'] + ',' + frm['y'] + ' c ' + str(0.7 * dx) + ', 0 ' + str(dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy) },
|
||||
'~-' : {'d': 'M ' + frm['x'] + ',' + frm['y'] + ' c ' + '0' + ', 0 ' + str(0.3 * dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy) },
|
||||
'-|' : {'d': 'm ' + frm['x'] + ',' + frm['y'] + ' ' + str(dx) + ',0 0,' + str(dy)},
|
||||
'|-' : {'d': 'm ' + frm['x'] + ',' + frm['y'] + ' 0,' + str(dy) + ' ' + str(dx) + ',0'},
|
||||
'-|-' : {'d': 'm ' + frm['x'] + ',' + frm['y'] + ' ' + str(dx / 2) + ',0 0,' + str(dy) + ' ' + str(dx / 2) + ',0'},
|
||||
'->' : {'style': 'marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none'},
|
||||
'~>' : {'style': 'marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none', 'd': 'M ' + frm['x'] + ',' + frm['y'] + ' ' + 'c ' + str(0.7 * dx) + ', 0 ' + str(0.3 * dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy)},
|
||||
'-~>' : {'style': 'marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none', 'd': 'M ' + frm['x'] + ',' + frm['y'] + ' ' + 'c ' + str(0.7 * dx) + ', 0 ' + str(dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy)},
|
||||
'~->' : {'style': 'marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none', 'd': 'M ' + frm['x'] + ',' + frm['y'] + ' ' + 'c ' + '0' + ', 0 ' + str(0.3 * dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy)},
|
||||
'-|>' : {'style': 'marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none', 'd': 'm ' + frm['x'] + ',' + frm['y'] + ' ' + str(dx) + ',0 0,' + str(dy)},
|
||||
'|->' : {'style': 'marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none', 'd': 'm ' + frm['x'] + ',' + frm['y'] + ' 0,' + str(dy) + ' ' + str(dx) + ',0'},
|
||||
'-|->' : {'style': 'marker-end:url(#arrowhead);stroke:#0041c4;stroke-width:1;fill:none', 'd': 'm ' + frm['x'] + ',' + frm['y'] + ' ' + str(dx / 2) + ',0 0,' + str(dy) + ' ' + str(dx / 2) + ',0'},
|
||||
'<->' : {'style': 'marker-end:url(#arrowhead);marker-start:url(#arrowtail);stroke:#0041c4;stroke-width:1;fill:none'},
|
||||
'<~>' : {'style': 'marker-end:url(#arrowhead);marker-start:url(#arrowtail);stroke:#0041c4;stroke-width:1;fill:none','d': 'M ' + frm['x'] + ',' + frm['y'] + ' ' + 'c ' + str(0.7 * dx) + ', 0 ' + str(0.3 * dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy)},
|
||||
'<-~>' : {'style': 'marker-end:url(#arrowhead);marker-start:url(#arrowtail);stroke:#0041c4;stroke-width:1;fill:none','d': 'M ' + frm['x'] + ',' + frm['y'] + ' ' + 'c ' + str(0.7 * dx) + ', 0 ' + str(dx) + ', ' + str(dy) + ' ' + str(dx) + ', ' + str(dy)},
|
||||
'<-|>' : {'style': 'marker-end:url(#arrowhead);marker-start:url(#arrowtail);stroke:#0041c4;stroke-width:1;fill:none','d': 'm ' + frm['x'] + ',' + frm['y'] + ' ' + str(dx) + ',0 0,' + str(dy)},
|
||||
'<-|->': {'style': 'marker-end:url(#arrowhead);marker-start:url(#arrowtail);stroke:#0041c4;stroke-width:1;fill:none','d': 'm ' + frm['x'] + ',' + frm['y'] + ' ' + str(dx / 2) + ',0 0,' + str(dy) + ' ' + str(dx / 2) + ',0'}
|
||||
}
|
||||
gmark[1].update( pattern.get( Edge['shape'], { 'style': 'fill:none;stroke:#00F;stroke-width:1' } ) )
|
||||
|
||||
if Edge['label']:
|
||||
if Edge['shape'] == '-~' :
|
||||
lx = float(frm['x']) + (float(to['x']) - float(frm['x'])) * 0.75
|
||||
if Edge['shape'] == '~-' :
|
||||
lx = float(frm['x']) + (float(to['x']) - float(frm['x'])) * 0.25
|
||||
if Edge['shape'] == '-|' :
|
||||
lx = float(to['x'])
|
||||
if Edge['shape'] == '|-' :
|
||||
lx = float(frm['x'])
|
||||
if Edge['shape'] == '-~>':
|
||||
lx = float(frm['x']) + (float(to['x']) - float(frm['x'])) * 0.75
|
||||
if Edge['shape'] == '~->':
|
||||
lx = float(frm['x']) + (float(to['x']) - float(frm['x'])) * 0.25
|
||||
if Edge['shape'] == '-|>' :
|
||||
lx = float(to['x'])
|
||||
if Edge['shape'] == '|->' :
|
||||
lx = float(frm['x'])
|
||||
if Edge['shape'] == '<-~>':
|
||||
lx = float(frm['x']) + (float(to['x']) - float(frm['x'])) * 0.75
|
||||
if Edge['shape'] =='<-|>' :
|
||||
lx = float(to['x'])
|
||||
|
||||
lwidth = len( Edge['label'] ) * font_width
|
||||
label = [
|
||||
'text',
|
||||
{
|
||||
'style': 'font-size:10px;',
|
||||
'text-anchor': 'middle',
|
||||
'xml:space': 'preserve',
|
||||
'x': int( lx ),
|
||||
'y': int( ly + 3 )
|
||||
},
|
||||
[ 'tspan', Edge['label'] ]
|
||||
]
|
||||
underlabel = [
|
||||
'rect',
|
||||
{
|
||||
'height': 9,
|
||||
'style': 'fill:#FFF;',
|
||||
'width': lwidth,
|
||||
'x': int( lx - lwidth / 2 ),
|
||||
'y': int( ly - 5 )
|
||||
}
|
||||
]
|
||||
gg.append(underlabel)
|
||||
gg.append(label)
|
||||
|
||||
for k in Events:
|
||||
if k.islower() :
|
||||
if int( Events[k]['x'] ) > 0 :
|
||||
lwidth = len( k ) * font_width
|
||||
underlabel = [
|
||||
'rect',
|
||||
{
|
||||
'x': float( Events[k]['x'] ) - float(lwidth) / 2,
|
||||
'y': int( Events[k]['y'] ) - 4,
|
||||
'height': 8,
|
||||
'width': lwidth,
|
||||
'style': 'fill:#FFF;'
|
||||
}
|
||||
]
|
||||
gg.append(underlabel)
|
||||
label = [
|
||||
'text',
|
||||
{
|
||||
'style': 'font-size:8px;',
|
||||
'x': int( Events[k]['x'] ),
|
||||
'y': int( Events[k]['y'] ) + 2,
|
||||
'width': lwidth,
|
||||
'text-anchor': 'middle'
|
||||
},
|
||||
k
|
||||
]
|
||||
gg.append(label)
|
||||
|
||||
def parseConfig (source) :
|
||||
|
||||
lane['hscale'] = 1
|
||||
if lane.get('hscale0') :
|
||||
lane['hscale'] = lane['hscale0']
|
||||
|
||||
if source and source.get('config') and source.get('config').get('hscale'):
|
||||
hscale = round(source.get('config').get('hscale'))
|
||||
if hscale > 0 :
|
||||
if hscale > 100 : hscale = 100
|
||||
lane['hscale'] = hscale
|
||||
|
||||
lane['yh0'] = 0
|
||||
lane['yh1'] = 0
|
||||
if source and source.get('head') :
|
||||
lane['head'] = source['head']
|
||||
if source.get('head').get('tick',0) == 0 : lane['yh0'] = 20
|
||||
if source.get('head').get('tock',0) == 0 : lane['yh0'] = 20
|
||||
if source.get('head').get('text') : lane['yh1'] = 46; lane['head']['text'] = source['head']['text']
|
||||
|
||||
lane['yf0'] = 0
|
||||
lane['yf1'] = 0
|
||||
if source and source.get('foot') :
|
||||
lane['foot'] = source['foot']
|
||||
if source.get('foot').get('tick',0) == 0 : lane['yf0'] = 20
|
||||
if source.get('foot').get('tock',0) == 0 : lane['yf0'] = 20
|
||||
if source.get('foot').get('text') : lane['yf1'] = 46; lane['foot']['text'] = source['foot']['text']
|
||||
|
||||
def rec (tmp, state) :
|
||||
|
||||
name = str( tmp[0] )
|
||||
delta_x = 25
|
||||
|
||||
state['x'] += delta_x
|
||||
for i in range( len( tmp ) ) :
|
||||
if type( tmp[i] ) is list :
|
||||
old_y = state['y']
|
||||
rec( tmp[i], state )
|
||||
state['groups'].append( {'x':state['xx'], 'y':old_y, 'height':state['y'] - old_y, 'name': state['name'] } )
|
||||
elif type( tmp[i] ) is dict :
|
||||
state['lanes'].append(tmp[i])
|
||||
state['width'].append(state['x'])
|
||||
state['y'] += 1
|
||||
|
||||
state['xx'] = state['x']
|
||||
state['x'] -= delta_x
|
||||
state['name'] = name
|
||||
|
||||
def insertSVGTemplate (index, parent, source) :
|
||||
|
||||
e = waveskin.WaveSkin['default']
|
||||
|
||||
if source.get('config') and source.get('config').get('skin') :
|
||||
if waveskin.WaveSkin.get( source.get('config').get('skin') ) :
|
||||
e = waveskin.WaveSkin[ source.get('config').get('skin') ]
|
||||
|
||||
if index == 0 :
|
||||
lane['xs'] = int( e[3][1][2][1]['width'] )
|
||||
lane['ys'] = int( e[3][1][2][1]['height'] )
|
||||
lane['xlabel'] = int( e[3][1][2][1]['x'] )
|
||||
lane['ym'] = int( e[3][1][2][1]['y'] )
|
||||
|
||||
else :
|
||||
e = ['svg', {'id': 'svg', 'xmlns': 'http://www.w3.org/2000/svg', 'xmlns:xlink': 'http://www.w3.org/1999/xlink', 'height': '0'},
|
||||
['g', {'id': 'waves'},
|
||||
['g', {'id': 'lanes'}],
|
||||
['g', {'id': 'groups'}]
|
||||
]
|
||||
]
|
||||
|
||||
e[-1][1]['id'] = 'waves_' + str(index)
|
||||
e[-1][2][1]['id'] = 'lanes_' + str(index)
|
||||
e[-1][3][1]['id'] = 'groups_' + str(index)
|
||||
e[1]['id'] = 'svgcontent_' + str(index)
|
||||
e[1]['height'] = 0
|
||||
|
||||
parent.extend(e)
|
||||
|
||||
def renderWaveForm (index, source, output) :
|
||||
|
||||
xmax = 0
|
||||
root = []
|
||||
groups = []
|
||||
|
||||
if source.get('signal'):
|
||||
insertSVGTemplate(index, output, source)
|
||||
parseConfig( source )
|
||||
ret = {'x':0, 'y':0, 'xmax':0, 'width':[], 'lanes':[], 'groups':[] }
|
||||
rec( source['signal'], ret )
|
||||
content = parseWaveLanes(ret['lanes'])
|
||||
glengths = renderWaveLane(root, content, index)
|
||||
for i in range( len( glengths ) ):
|
||||
xmax = max( xmax, ( glengths[i] + ret['width'][i] ) )
|
||||
renderMarks(root, content, index)
|
||||
renderArcs(root, ret['lanes'], index, source)
|
||||
renderGaps(root, ret['lanes'], index)
|
||||
renderGroups(groups, ret['groups'], index)
|
||||
lane['xg'] = int( math.ceil( float( xmax - lane['tgo'] ) / float(lane['xs'] ) ) ) * lane['xs']
|
||||
width = (lane['xg'] + lane['xs'] * (lane['xmax'] + 1) )
|
||||
height = len(content) * lane['yo'] + lane['yh0'] + lane['yh1'] + lane['yf0'] + lane['yf1']
|
||||
output[1]={
|
||||
'id' :'svgcontent_' + str(index),
|
||||
'xmlns' :"http://www.w3.org/2000/svg",
|
||||
'xmlns:xlink':"http://www.w3.org/1999/xlink",
|
||||
'width' :str(width),
|
||||
'height' :str(height),
|
||||
'viewBox' :'0 0 ' + str(width) + ' ' + str(height),
|
||||
'overflow' :"hidden"
|
||||
}
|
||||
output[-1][2][1]['transform']='translate(' + str(lane['xg'] + 0.5) + ', ' + str((float(lane['yh0']) + float(lane['yh1'])) + 0.5) + ')'
|
||||
|
||||
output[-1][2].extend(root)
|
||||
output[-1][3].extend(groups)
|
||||
|
||||
def renderGroups (root, groups, index) :
|
||||
|
||||
svgns = 'http://www.w3.org/2000/svg',
|
||||
xmlns = 'http://www.w3.org/XML/1998/namespace'
|
||||
|
||||
for i in range( len( groups ) ) :
|
||||
group = [
|
||||
'path',
|
||||
{
|
||||
'id': 'group_' + str(i) + '_' + str(index),
|
||||
'd': 'm ' + str( groups[i]['x'] + 0.5 ) + ',' + str( groups[i]['y']* lane['yo'] + 3.5 + lane['yh0'] + lane['yh1'] ) + ' c -3,0 -5,2 -5,5 l 0,' + str( int( groups[i]['height'] * lane['yo'] - 16 ) ) + ' c 0,3 2,5 5,5',
|
||||
'style': 'stroke:#0041c4;stroke-width:1;fill:none'
|
||||
}
|
||||
]
|
||||
root.append(group)
|
||||
|
||||
name = groups[i]['name']
|
||||
x = str( int( groups[i]['x'] - 10 ) )
|
||||
y = str( int( lane['yo'] * (groups[i]['y'] + (float(groups[i]['height']) / 2)) + lane['yh0'] + lane['yh1'] ) )
|
||||
label = [
|
||||
['g',
|
||||
{'transform': 'translate(' + x + ',' + y + ')'},
|
||||
['g', {'transform': 'rotate(270)'},
|
||||
'text',
|
||||
{
|
||||
'text-anchor': 'middle',
|
||||
'class': 'info',
|
||||
'xml:space' : 'preserve'
|
||||
},
|
||||
['tspan',name]
|
||||
]
|
||||
]
|
||||
]
|
||||
root.append(label)
|
||||
|
||||
def renderGaps (root, source, index) :
|
||||
|
||||
Stack = []
|
||||
svgns = 'http://www.w3.org/2000/svg',
|
||||
xlinkns = 'http://www.w3.org/1999/xlink'
|
||||
|
||||
if source:
|
||||
|
||||
gg = [
|
||||
'g',
|
||||
{ 'id': 'wavegaps_' + str(index) }
|
||||
]
|
||||
|
||||
for i in range( len( source )):
|
||||
lane['period'] = source[i].get('period',1)
|
||||
lane['phase'] = int( source[i].get('phase',0 ) * 2 )
|
||||
|
||||
g = [
|
||||
'g',
|
||||
{
|
||||
'id': 'wavegap_' + str(i) + '_' + str(index),
|
||||
'transform': 'translate(0,' + str(lane['y0'] + i * lane['yo']) + ')'
|
||||
}
|
||||
]
|
||||
gg.append(g)
|
||||
|
||||
if source[i].get('wave'):
|
||||
text = source[i]['wave']
|
||||
Stack = text
|
||||
pos = 0
|
||||
while len( Stack ) :
|
||||
c = Stack [0]
|
||||
Stack = Stack[1:]
|
||||
if c == '|' :
|
||||
b = [
|
||||
'use',
|
||||
{
|
||||
'xmlns:xlink':xlinkns,
|
||||
'xlink:href':'#gap',
|
||||
'transform': 'translate(' + str(int(float(lane['xs']) * ((2 * pos + 1) * float(lane['period']) * float(lane['hscale']) - float(lane['phase'])))) + ')'
|
||||
}
|
||||
]
|
||||
g.append(b)
|
||||
pos += 1
|
||||
|
||||
root.append( gg )
|
||||
|
||||
def is_type_str( var ) :
|
||||
if sys.version_info[0] < 3:
|
||||
return type( var ) is str or type( var ) is unicode
|
||||
else:
|
||||
return type( var ) is str
|
||||
|
||||
def convert_to_svg( root ) :
|
||||
|
||||
svg_output = ''
|
||||
|
||||
if type( root ) is list:
|
||||
if len(root) >= 2 and type( root[1] ) is dict:
|
||||
if len( root ) == 2 :
|
||||
svg_output += '<' + root[0] + convert_to_svg( root[1] ) + '/>\n'
|
||||
elif len( root ) >= 3 :
|
||||
svg_output += '<' + root[0] + convert_to_svg( root[1] ) + '>\n'
|
||||
if len( root ) == 3:
|
||||
svg_output += convert_to_svg( root[2] )
|
||||
else:
|
||||
svg_output += convert_to_svg( root[2:] )
|
||||
svg_output += '</' + root[0] + '>\n'
|
||||
elif type( root[0] ) is list:
|
||||
for eleml in root:
|
||||
svg_output += convert_to_svg( eleml )
|
||||
else:
|
||||
svg_output += '<' + root[0] + '>\n'
|
||||
for eleml in root[1:]:
|
||||
svg_output += convert_to_svg( eleml )
|
||||
svg_output += '</' + root[0] + '>\n'
|
||||
elif type( root ) is dict:
|
||||
for elemd in root :
|
||||
svg_output += ' ' + elemd + '="' + str(root[elemd]) + '"'
|
||||
else:
|
||||
svg_output += root
|
||||
|
||||
return svg_output
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
if len( sys.argv ) != 5:
|
||||
print ( 'Usage : ' + sys.argv[0] + ' source <input.json> svg <output.svg>' )
|
||||
exit(1)
|
||||
|
||||
if sys.argv[3] != 'svg' :
|
||||
print ( 'Error: only SVG format supported.' )
|
||||
exit(1)
|
||||
|
||||
output=[]
|
||||
inputfile = sys.argv[2]
|
||||
outputfile = sys.argv[4]
|
||||
|
||||
with open(inputfile,'r') as f:
|
||||
jinput = json.load(f)
|
||||
|
||||
renderWaveForm(0,jinput,output)
|
||||
svg_output = convert_to_svg(output)
|
||||
|
||||
with open(outputfile,'w') as f:
|
||||
f.write( svg_output )
|
||||
|
|
@ -0,0 +1 @@
|
|||
468eb9a4a038201c2b0004fe6e4ae9b2d37fdd57
|
||||
|
|
@ -114,6 +114,11 @@ def check_versions():
|
|||
except:
|
||||
OPTS.datasheet_gen = 0
|
||||
|
||||
try:
|
||||
import coverage
|
||||
OPTS.coverage = 1
|
||||
except:
|
||||
OPTS.coverage = 0
|
||||
|
||||
def init_openram(config_file, is_unit_test=True):
|
||||
"""Initialize the technology, paths, simulators, etc."""
|
||||
|
|
@ -200,6 +205,7 @@ def read_config(config_file, is_unit_test=True):
|
|||
config_file = re.sub(r'\.py$', "", config_file)
|
||||
# Expand the user if it is used
|
||||
config_file = os.path.expanduser(config_file)
|
||||
OPTS.config_file = config_file
|
||||
# Add the path to the system path so we can import things in the other directory
|
||||
dir_name = os.path.dirname(config_file)
|
||||
file_name = os.path.basename(config_file)
|
||||
|
|
@ -247,7 +253,7 @@ def read_config(config_file, is_unit_test=True):
|
|||
OPTS.num_words,
|
||||
ports,
|
||||
OPTS.tech_name)
|
||||
|
||||
|
||||
|
||||
|
||||
def end_openram():
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ c = sram_config(word_size=OPTS.word_size,
|
|||
print("Words per row: {}".format(c.words_per_row))
|
||||
|
||||
#from parser import *
|
||||
output_extensions = ["sp","v","lib"]
|
||||
output_extensions = ["sp","v","lib","py"]
|
||||
if OPTS.datasheet_gen:
|
||||
output_extensions.append("html")
|
||||
if not OPTS.netlist_only:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,227 @@
|
|||
import debug
|
||||
import pgate
|
||||
import math
|
||||
from tech import drc
|
||||
from math import log
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
from pinv import pinv
|
||||
|
||||
class pdriver(pgate.pgate):
|
||||
"""
|
||||
This instantiates an even or odd number of inverters sized for driving a load.
|
||||
"""
|
||||
unique_id = 1
|
||||
inv_list = []
|
||||
inv_inst_list = []
|
||||
calc_size_list = []
|
||||
|
||||
def __init__(self, height=None, name="", neg_polarity=False, c_load=8, size_list = []):
|
||||
|
||||
self.stage_effort = 4
|
||||
self.row_height = height
|
||||
self.neg_polarity = neg_polarity
|
||||
self.size_list = size_list
|
||||
self.c_load = c_load
|
||||
|
||||
if len(self.size_list) > 0 and (self.c_load != 8 or self.neg_polarity):
|
||||
raise Exception("Cannot specify both size_list and neg_polarity or c_load.")
|
||||
|
||||
self.compute_sizes()
|
||||
|
||||
if name=="":
|
||||
name = "pdriver_{0}_{1}_".format(self.num_inv, pdriver.unique_id)
|
||||
pdriver.unique_id += 1
|
||||
|
||||
pgate.pgate.__init__(self, name)
|
||||
debug.info(1, "Creating {}".format(self.name))
|
||||
|
||||
self.create_netlist()
|
||||
if not OPTS.netlist_only:
|
||||
self.create_layout()
|
||||
|
||||
def compute_sizes(self):
|
||||
# size_list specified
|
||||
if len(self.size_list) > 0:
|
||||
if not len(self.size_list) % 2:
|
||||
neg_polarity = True
|
||||
self.num_inv = len(self.size_list)
|
||||
else:
|
||||
# find the number of stages
|
||||
c_prev = int(round(self.c_load/self.stage_effort))
|
||||
num_stages = 1
|
||||
while c_prev > 1: #stop when the first stage is 1
|
||||
c_prev = int(round(c_prev/self.stage_effort))
|
||||
num_stages+=1
|
||||
|
||||
# find inv_num and compute sizes
|
||||
if self.neg_polarity:
|
||||
if (num_stages % 2 == 0): # if num_stages is even
|
||||
self.diff_polarity(num_stages=num_stages)
|
||||
else: # if num_stages is odd
|
||||
self.same_polarity(num_stages=num_stages)
|
||||
else: # positive polarity
|
||||
if (num_stages % 2 == 0):
|
||||
self.same_polarity(num_stages=num_stages)
|
||||
else:
|
||||
self.diff_polarity(num_stages=num_stages)
|
||||
|
||||
|
||||
def same_polarity(self, num_stages):
|
||||
self.num_inv = num_stages
|
||||
# compute sizes
|
||||
c_prev = self.c_load
|
||||
for x in range(self.num_inv-1,-1,-1):
|
||||
c_prev = int(round(c_prev/self.stage_effort))
|
||||
self.calc_size_list.append(c_prev)
|
||||
|
||||
|
||||
def diff_polarity(self, num_stages):
|
||||
# find which delay is smaller
|
||||
delay_below = ((num_stages-1)*(self.c_load**(1/num_stages-1))) + num_stages-1
|
||||
delay_above = ((num_stages+1)*(self.c_load**(1/num_stages+1))) + num_stages+1
|
||||
if (delay_above < delay_below):
|
||||
# recompute stage_effort for this delay
|
||||
self.num_inv = num_stages+1
|
||||
polarity_stage_effort = self.c_load**(1/self.num_inv)
|
||||
else:
|
||||
self.num_inv = num_stages-1
|
||||
polarity_stage_effort = self.c_load**(1/self.num_inv)
|
||||
|
||||
# compute sizes
|
||||
c_prev = self.c_load
|
||||
for x in range(self.num_inv-1,-1,-1):
|
||||
c_prev = int(round(c_prev/polarity_stage_effort))
|
||||
self.calc_size_list.append(c_prev)
|
||||
|
||||
|
||||
def create_netlist(self):
|
||||
self.add_pins()
|
||||
self.add_modules()
|
||||
self.create_insts()
|
||||
|
||||
def create_layout(self):
|
||||
self.width = self.num_inv * self.inv_list[0].width
|
||||
self.height = self.inv_list[0].height
|
||||
|
||||
self.place_modules()
|
||||
self.route_wires()
|
||||
self.add_layout_pins()
|
||||
|
||||
self.DRC_LVS()
|
||||
|
||||
def add_pins(self):
|
||||
self.add_pin("A")
|
||||
self.add_pin("Z")
|
||||
self.add_pin("vdd")
|
||||
self.add_pin("gnd")
|
||||
|
||||
def add_modules(self):
|
||||
if len(self.size_list) > 0: # size list specified
|
||||
for x in range(len(self.size_list)):
|
||||
self.inv_list.append(pinv(size=self.size_list[x], height=self.row_height))
|
||||
self.add_mod(self.inv_list[x])
|
||||
else: # find inv sizes
|
||||
for x in range(len(self.calc_size_list)):
|
||||
self.inv_list.append(pinv(size=self.calc_size_list[x], height=self.row_height))
|
||||
self.add_mod(self.inv_list[x])
|
||||
|
||||
|
||||
def create_insts(self):
|
||||
for x in range(1,self.num_inv+1):
|
||||
# Create first inverter
|
||||
if x == 1:
|
||||
zbx_int = "Zb{}_int".format(x);
|
||||
self.inv_inst_list.append(self.add_inst(name="buf_inv{}".format(x),
|
||||
mod=self.inv_list[x-1]))
|
||||
if self.num_inv == 1:
|
||||
self.connect_inst(["A", "Z", "vdd", "gnd"])
|
||||
else:
|
||||
self.connect_inst(["A", zbx_int, "vdd", "gnd"])
|
||||
|
||||
# Create last inverter
|
||||
elif x == self.num_inv:
|
||||
zbn_int = "Zb{}_int".format(x-1);
|
||||
self.inv_inst_list.append(self.add_inst(name="buf_inv{}".format(x),
|
||||
mod=self.inv_list[x-1]))
|
||||
self.connect_inst([zbn_int, "Z", "vdd", "gnd"])
|
||||
|
||||
# Create middle inverters
|
||||
else:
|
||||
zbx_int = "Zb{}_int".format(x-1);
|
||||
zbn_int = "Zb{}_int".format(x);
|
||||
self.inv_inst_list.append(self.add_inst(name="buf_inv{}".format(x),
|
||||
mod=self.inv_list[x-1]))
|
||||
self.connect_inst([zbx_int, zbn_int, "vdd", "gnd"])
|
||||
|
||||
|
||||
def place_modules(self):
|
||||
# Add INV1 to the left
|
||||
self.inv_inst_list[0].place(vector(0,0))
|
||||
|
||||
# Add inverters to the right of INV1
|
||||
for x in range(1,len(self.inv_inst_list)):
|
||||
self.inv_inst_list[x].place(vector(self.inv_inst_list[x-1].rx(),0))
|
||||
|
||||
|
||||
def route_wires(self):
|
||||
z_inst_list = []
|
||||
a_inst_list = []
|
||||
# inv_current Z to inv_next A
|
||||
for x in range(0,len(self.inv_inst_list)-1):
|
||||
z_inst_list.append(self.inv_inst_list[x].get_pin("Z"))
|
||||
a_inst_list.append(self.inv_inst_list[x+1].get_pin("A"))
|
||||
mid_point = vector(z_inst_list[x].cx(), a_inst_list[x].cy())
|
||||
self.add_path("metal1", [z_inst_list[x].center(), mid_point, a_inst_list[x].center()])
|
||||
|
||||
|
||||
def add_layout_pins(self):
|
||||
# Continous vdd rail along with label.
|
||||
vdd_pin=self.inv_inst_list[0].get_pin("vdd")
|
||||
self.add_layout_pin(text="vdd",
|
||||
layer="metal1",
|
||||
offset=vdd_pin.ll().scale(0,1),
|
||||
width=self.width,
|
||||
height=vdd_pin.height())
|
||||
|
||||
# Continous gnd rail along with label.
|
||||
gnd_pin=self.inv_inst_list[0].get_pin("gnd")
|
||||
self.add_layout_pin(text="gnd",
|
||||
layer="metal1",
|
||||
offset=gnd_pin.ll().scale(0,1),
|
||||
width=self.width,
|
||||
height=vdd_pin.height())
|
||||
|
||||
z_pin = self.inv_inst_list[len(self.inv_inst_list)-1].get_pin("Z")
|
||||
self.add_layout_pin_rect_center(text="Z",
|
||||
layer=z_pin.layer,
|
||||
offset=z_pin.center(),
|
||||
width = z_pin.width(),
|
||||
height = z_pin.height())
|
||||
|
||||
a_pin = self.inv_inst_list[0].get_pin("A")
|
||||
self.add_layout_pin_rect_center(text="A",
|
||||
layer=a_pin.layer,
|
||||
offset=a_pin.center(),
|
||||
width = a_pin.width(),
|
||||
height = a_pin.height())
|
||||
|
||||
def analytical_delay(self, slew, load=0.0):
|
||||
"""Calculate the analytical delay of INV1 -> ... -> INVn"""
|
||||
delay = 0;
|
||||
if len(self.inv_inst_list) == 1:
|
||||
delay = self.inv_inst_list[x].analytical_delay(slew=slew);
|
||||
else:
|
||||
for x in range(len(self.inv_inst_list-1)):
|
||||
load_next = 0.0
|
||||
for n in range(x,len(self.inv_inst_list+1)):
|
||||
load_next += self.inv_inst_list[x+1]
|
||||
if x == 1:
|
||||
delay += self.inv_inst_list[x].analytical_delay(slew=slew,
|
||||
load=load_next)
|
||||
else:
|
||||
delay += self.inv_inst_list[x+1].analytical_delay(slew=delay.slew,
|
||||
load=load_next)
|
||||
return delay
|
||||
|
||||
|
||||
|
|
@ -105,13 +105,21 @@ class sram():
|
|||
print("Trimming netlist to speed up characterization.")
|
||||
lib(out_dir=OPTS.output_path, sram=self.s, sp_file=sp_file)
|
||||
print_time("Characterization", datetime.datetime.now(), start_time)
|
||||
|
||||
|
||||
|
||||
# Write the config file
|
||||
start_time = datetime.datetime.now()
|
||||
from shutil import copyfile
|
||||
copyfile(OPTS.config_file + '.py', OPTS.output_path + OPTS.output_name + '.py')
|
||||
print("Config: writing to {0}".format(OPTS.output_path + OPTS.output_name + '.py'))
|
||||
print_time("Config", datetime.datetime.now(), start_time)
|
||||
|
||||
# Write the datasheet
|
||||
start_time = datetime.datetime.now()
|
||||
from datasheet_gen import datasheet_gen
|
||||
dname = OPTS.output_path + self.s.name + ".html"
|
||||
print("Datasheet: writing to {0}".format(dname))
|
||||
datasheet_gen.datasheet_write(dname)
|
||||
datasheet_gen.datasheet_write(self.s,dname)
|
||||
print_time("Datasheet", datetime.datetime.now(), start_time)
|
||||
|
||||
# Write a verilog model
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Run a regression test on a 2-row buffer cell
|
||||
"""
|
||||
|
||||
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 04_pdriver_test, LVS error in FreePDK45")
|
||||
class pdriver_test(openram_test):
|
||||
|
||||
def runTest(self):
|
||||
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
|
||||
global verify
|
||||
import verify
|
||||
|
||||
import pdriver
|
||||
|
||||
debug.info(2, "Testing inverter/buffer 4x 8x")
|
||||
# a tests the error message for specifying conflicting conditions
|
||||
#a = pdriver.pdriver(c_load = 4,size_list = [1,2,4,8])
|
||||
b = pdriver.pdriver(size_list = [1,2,4,8])
|
||||
c = pdriver.pdriver(c_load = 50)
|
||||
d = pdriver.pdriver(c_load = 50, neg_polarity = True)
|
||||
e = pdriver.pdriver(c_load = 64)
|
||||
f = pdriver.pdriver(c_load = 64, neg_polarity = True)
|
||||
#self.local_check(a)
|
||||
self.local_check(b)
|
||||
self.local_check(c)
|
||||
self.local_check(d)
|
||||
self.local_check(e)
|
||||
self.local_check(f)
|
||||
|
||||
globals.end_openram()
|
||||
|
||||
# instantiate a copdsay 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()
|
||||
|
|
@ -17,7 +17,8 @@ import getpass
|
|||
class openram_test(openram_test):
|
||||
|
||||
def runTest(self):
|
||||
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
|
||||
OPENRAM_HOME = os.path.abspath(os.environ.get("OPENRAM_HOME"))
|
||||
globals.init_openram("{0}/tests/config_20_{1}".format(OPENRAM_HOME,OPTS.tech_name))
|
||||
|
||||
debug.info(1, "Testing top-level openram.py with 2-bit, 16 word SRAM.")
|
||||
out_file = "testsram"
|
||||
|
|
@ -41,14 +42,16 @@ class openram_test(openram_test):
|
|||
verbosity += " -v"
|
||||
|
||||
|
||||
OPENRAM_HOME = os.path.abspath(os.environ.get("OPENRAM_HOME"))
|
||||
# Always perform code coverage
|
||||
exe_name = "coverage run -p {0}/openram.py ".format(OPENRAM_HOME)
|
||||
cmd = "{0} -n -o {1} -p {2} {3} config_20_{4}.py 2>&1 > {5}/output.log".format(exe_name,
|
||||
if OPTS.coverage == 0:
|
||||
debug.warning("Failed to find coverage installation. This can be installed with pip3 install coverage")
|
||||
exe_name = "coverage run -p {0}/openram.py ".format(OPENRAM_HOME)
|
||||
config_name = "{0}config_20_{1}.py".format(OPENRAM_HOME + "/tests/",OPTS.tech_name)
|
||||
cmd = "{0} -n -o {1} -p {2} {3} {4} 2>&1 > {5}/output.log".format(exe_name,
|
||||
out_file,
|
||||
out_path,
|
||||
verbosity,
|
||||
OPTS.tech_name,
|
||||
config_name,
|
||||
out_path)
|
||||
debug.info(1, cmd)
|
||||
os.system(cmd)
|
||||
|
|
|
|||
Loading…
Reference in New Issue