Merge branch 'dev' into multiport_characterization

This commit is contained in:
Hunter Nichols 2019-01-15 16:33:39 -08:00
commit 6152ec7ec5
63 changed files with 970 additions and 19416 deletions

View File

@ -31,7 +31,6 @@ The OpenRAM compiler has very few dependencies:
+ [Ngspice] 26 (or later) or HSpice I-2013.12-1 (or later) or CustomSim 2017 (or later) + [Ngspice] 26 (or later) or HSpice I-2013.12-1 (or later) or CustomSim 2017 (or later)
+ Python 3.5 or higher + Python 3.5 or higher
+ Python numpy (pip3 install numpy to install) + Python numpy (pip3 install numpy to install)
+ flask_table (pip3 install flask to install)
If you want to perform DRC and LVS, you will need either: If you want to perform DRC and LVS, you will need either:
+ Calibre (for [FreePDK45]) + Calibre (for [FreePDK45])
@ -98,6 +97,12 @@ output_name = "sram_{0}_{1}_{2}".format(word_size,num_words,tech_name)
# Disable analytical models for full characterization (WARNING: slow!) # Disable analytical models for full characterization (WARNING: slow!)
# analytical_delay = False # analytical_delay = False
# To force this to use magic and netgen for DRC/LVS/PEX
# Could be calibre for FreePDK45
drc_name = "magic"
lvs_name = "netgen"
pex_name = "magic"
``` ```
You can then run OpenRAM by executing: You can then run OpenRAM by executing:

View File

@ -10,7 +10,7 @@ from vector import vector
from pin_layout import pin_layout from pin_layout import pin_layout
import lef import lef
class layout(lef.lef): class layout():
""" """
Class consisting of a set of objs and instances for a module Class consisting of a set of objs and instances for a module
This provides a set of useful generic types for hierarchy This provides a set of useful generic types for hierarchy
@ -21,7 +21,6 @@ class layout(lef.lef):
""" """
def __init__(self, name): def __init__(self, name):
lef.lef.__init__(self, ["metal1", "metal2", "metal3"])
self.name = name self.name = name
self.width = None self.width = None
self.height = None self.height = None

View File

@ -2,9 +2,8 @@ import debug
import re import re
import os import os
import math import math
import verilog
class spice(verilog.verilog): class spice():
""" """
This provides a set of useful generic types for hierarchy This provides a set of useful generic types for hierarchy
management. If a module is a custom designed cell, it will read from management. If a module is a custom designed cell, it will read from

View File

@ -9,7 +9,8 @@ from collections import defaultdict
class lef: class lef:
""" """
SRAM LEF Class open GDS file, read pins information, obstruction SRAM LEF Class open GDS file, read pins information, obstruction
and write them to LEF file and write them to LEF file.
This is inherited by the sram_base class.
""" """
def __init__(self,layers): def __init__(self,layers):
# LEF db units per micron # LEF db units per micron

View File

@ -1,60 +1,165 @@
import debug import debug
class verilog: class verilog:
""" Create a behavioral Verilog file for simulation.""" """
Create a behavioral Verilog file for simulation.
This is inherited by the sram_base class.
"""
def __init__(self):
pass
def verilog_write(self,verilog_name): def verilog_write(self,verilog_name):
""" Write a behavioral Verilog model. """ """ Write a behavioral Verilog model. """
self.vf = open(verilog_name, "w") self.vf = open(verilog_name, "w")
self.vf.write("// OpenRAM SRAM model\n") self.vf.write("// OpenRAM SRAM model\n")
self.vf.write("// Words: {0}\n".format(self.num_words)) self.vf.write("// Words: {0}\n".format(self.num_words))
self.vf.write("// Word size: {0}\n\n".format(self.word_size)) self.vf.write("// Word size: {0}\n\n".format(self.word_size))
self.vf.write("module {0}(DATA,ADDR,CSb,WEb,OEb,clk);\n".format(self.name)) self.vf.write("module {0}(\n".format(self.name))
self.vf.write("\n") for port in self.all_ports:
if port in self.readwrite_ports:
self.vf.write("// Port {0}: RW\n".format(port))
elif port in self.read_ports:
self.vf.write("// Port {0}: R\n".format(port))
elif port in self.write_ports:
self.vf.write("// Port {0}: W\n".format(port))
if port in self.readwrite_ports:
self.vf.write(" clk{0},csb{0},web{0},ADDR{0},DIN{0},DOUT{0}".format(port))
elif port in self.write_ports:
self.vf.write(" clk{0},csb{0},ADDR{0},DIN{0}".format(port))
elif port in self.read_ports:
self.vf.write(" clk{0},csb{0},ADDR{0},DOUT{0}".format(port))
# Continue for every port on a new line
if port != self.all_ports[-1]:
self.vf.write(",\n")
self.vf.write("\n );\n\n")
self.vf.write(" parameter DATA_WIDTH = {0} ;\n".format(self.word_size)) self.vf.write(" parameter DATA_WIDTH = {0} ;\n".format(self.word_size))
self.vf.write(" parameter ADDR_WIDTH = {0} ;\n".format(self.addr_size)) self.vf.write(" parameter ADDR_WIDTH = {0} ;\n".format(self.addr_size))
self.vf.write(" parameter RAM_DEPTH = 1 << ADDR_WIDTH;\n") self.vf.write(" parameter RAM_DEPTH = 1 << ADDR_WIDTH;\n")
self.vf.write(" // FIXME: This delay is arbitrary.\n")
self.vf.write(" parameter DELAY = 3 ;\n") self.vf.write(" parameter DELAY = 3 ;\n")
self.vf.write("\n") self.vf.write("\n")
self.vf.write(" inout [DATA_WIDTH-1:0] DATA;\n")
self.vf.write(" input [ADDR_WIDTH-1:0] ADDR;\n") for port in self.all_ports:
self.vf.write(" input CSb; // active low chip select\n") self.add_inputs_outputs(port)
self.vf.write(" input WEb; // active low write control\n")
self.vf.write(" input OEb; // active output enable\n")
self.vf.write(" input clk; // clock\n")
self.vf.write("\n") self.vf.write("\n")
self.vf.write(" reg [DATA_WIDTH-1:0] data_out ;\n")
self.vf.write(" reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];\n") for port in self.all_ports:
self.vf.write("\n") self.register_inputs(port)
self.vf.write(" // Tri-State Buffer control\n")
self.vf.write(" // output : When WEb = 1, oeb = 0, csb = 0\n") # This is the memory array itself
self.vf.write(" assign DATA = (!CSb && !OEb && WEb) ? data_out : {0}'bz;\n".format(self.word_size)) self.vf.write("reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];\n")
self.vf.write("\n")
self.vf.write(" // Memory Write Block\n") for port in self.all_ports:
self.vf.write(" // Write Operation : When WEb = 0, CSb = 0\n") if port in self.write_ports:
self.vf.write(" always @ (posedge clk)\n") self.add_write_block(port)
self.vf.write(" begin : MEM_WRITE\n") if port in self.read_ports:
self.vf.write(" if ( !CSb && !WEb ) begin\n") self.add_read_block(port)
self.vf.write(" mem[ADDR] = DATA;\n")
self.vf.write(" $display($time,\" Writing %m ABUS=%b DATA=%b\",ADDR,DATA);\n")
self.vf.write(" end\n")
self.vf.write(" end\n\n")
self.vf.write("\n")
self.vf.write(" // Memory Read Block\n")
self.vf.write(" // Read Operation : When WEb = 1, CSb = 0\n")
self.vf.write(" always @ (posedge clk)\n")
self.vf.write(" begin : MEM_READ\n")
self.vf.write(" if (!CSb && WEb) begin\n")
self.vf.write(" data_out <= #(DELAY) mem[ADDR];\n")
self.vf.write(" $display($time,\" Reading %m ABUS=%b DATA=%b\",ADDR,mem[ADDR]);\n")
self.vf.write(" end\n")
self.vf.write(" end\n")
self.vf.write("\n") self.vf.write("\n")
self.vf.write("endmodule\n") self.vf.write("endmodule\n")
self.vf.close() self.vf.close()
def register_inputs(self, port):
"""
Register the control signal, address and data inputs.
"""
self.add_regs(port)
self.add_flops(port)
def add_regs(self, port):
"""
Create the input regs for the given port.
"""
self.vf.write(" reg csb{0}_reg;\n".format(port))
if port in self.readwrite_ports:
self.vf.write(" reg web{0}_reg;\n".format(port))
self.vf.write(" reg [ADDR_WIDTH-1:0] ADDR{0}_reg;\n".format(port))
if port in self.write_ports:
self.vf.write(" reg [DATA_WIDTH-1:0] DIN{0}_reg;\n".format(port))
if port in self.read_ports:
self.vf.write(" reg [DATA_WIDTH-1:0] DOUT{0};\n".format(port))
def add_flops(self, port):
"""
Add the flop behavior logic for a port.
"""
self.vf.write("\n")
self.vf.write(" // All inputs are registers\n")
self.vf.write(" always @(posedge clk{0})\n".format(port))
self.vf.write(" begin\n")
self.vf.write(" csb{0}_reg = csb{0};\n".format(port))
if port in self.readwrite_ports:
self.vf.write(" web{0}_reg = web{0};\n".format(port))
self.vf.write(" ADDR{0}_reg = ADDR{0};\n".format(port))
if port in self.write_ports:
self.vf.write(" DIN{0}_reg = DIN{0};\n".format(port))
if port in self.read_ports:
self.vf.write(" DOUT{0} = {1}'bx;\n".format(port,self.word_size))
if port in self.readwrite_ports:
self.vf.write(" if ( !csb{0}_reg && web{0}_reg ) \n".format(port))
self.vf.write(" $display($time,\" Reading %m ADDR{0}=%b DOUT{0}=%b\",ADDR{0}_reg,mem[ADDR{0}_reg]);\n".format(port))
elif port in self.read_ports:
self.vf.write(" if ( !csb{0}_reg ) \n".format(port))
self.vf.write(" $display($time,\" Reading %m ADDR{0}=%b DOUT{0}=%b\",ADDR{0}_reg,mem[ADDR{0}_reg]);\n".format(port))
if port in self.readwrite_ports:
self.vf.write(" if ( !csb{0}_reg && !web{0}_reg )\n".format(port))
self.vf.write(" $display($time,\" Writing %m ADDR{0}=%b DIN{0}=%b\",ADDR{0}_reg,DIN{0}_reg);\n".format(port))
elif port in self.write_ports:
self.vf.write(" if ( !csb{0}_reg )\n".format(port))
self.vf.write(" $display($time,\" Writing %m ADDR{0}=%b DIN{0}=%b\",ADDR{0}_reg,DIN{0}_reg);\n".format(port))
self.vf.write(" end\n\n")
def add_inputs_outputs(self, port):
"""
Add the module input and output declaration for a port.
"""
self.vf.write(" input clk{0}; // clock\n".format(port))
self.vf.write(" input csb{0}; // active low chip select\n".format(port))
if port in self.readwrite_ports:
self.vf.write(" input web{0}; // active low write control\n".format(port))
self.vf.write(" input [ADDR_WIDTH-1:0] ADDR{0};\n".format(port))
if port in self.write_ports:
self.vf.write(" input [DATA_WIDTH-1:0] DIN{0};\n".format(port))
if port in self.read_ports:
self.vf.write(" output [DATA_WIDTH-1:0] DOUT{0};\n".format(port))
def add_write_block(self, port):
"""
Add a write port block. Multiple simultaneous writes to the same address
have arbitrary priority and are not allowed.
"""
self.vf.write("\n")
self.vf.write(" // Memory Write Block Port {0}\n".format(port))
self.vf.write(" // Write Operation : When web{0} = 0, csb{0} = 0\n".format(port))
self.vf.write(" always @ (negedge clk{0})\n".format(port))
self.vf.write(" begin : MEM_WRITE{0}\n".format(port))
if port in self.readwrite_ports:
self.vf.write(" if ( !csb{0}_reg && !web{0}_reg )\n".format(port))
else:
self.vf.write(" if (!csb{0}_reg)\n".format(port))
self.vf.write(" mem[ADDR{0}_reg] = DIN{0}_reg;\n".format(port))
self.vf.write(" end\n")
def add_read_block(self, port):
"""
Add a read port block.
"""
self.vf.write("\n")
self.vf.write(" // Memory Read Block Port {0}\n".format(port))
self.vf.write(" // Read Operation : When web{0} = 1, csb{0} = 0\n".format(port))
self.vf.write(" always @ (negedge clk{0})\n".format(port))
self.vf.write(" begin : MEM_READ{0}\n".format(port))
if port in self.readwrite_ports:
self.vf.write(" if (!csb{0}_reg && web{0}_reg)\n".format(port))
else:
self.vf.write(" if (!csb{0}_reg)\n".format(port))
self.vf.write(" DOUT{0} <= #(DELAY) mem[ADDR{0}_reg];\n".format(port))
self.vf.write(" end\n")

View File

@ -23,7 +23,7 @@ if not OPTS.analytical_delay:
if OPTS.spice_exe=="" or OPTS.spice_exe==None: if OPTS.spice_exe=="" or OPTS.spice_exe==None:
debug.error("{0} not found. Unable to perform characterization.".format(OPTS.spice_name),1) debug.error("{0} not found. Unable to perform characterization.".format(OPTS.spice_name),1)
else: else:
(OPTS.spice_name,OPTS.spice_exe) = get_tool("spice",["xa", "hspice", "ngspice", "ngspice.exe"]) (OPTS.spice_name,OPTS.spice_exe) = get_tool("spice",["hspice", "ngspice", "ngspice.exe", "xa"])
# set the input dir for spice files if using ngspice # set the input dir for spice files if using ngspice
if OPTS.spice_name == "ngspice": if OPTS.spice_name == "ngspice":

View File

@ -1,6 +1,7 @@
import os,sys,re import os,sys,re
import debug import debug
import math import math
import datetime
from .setup_hold import * from .setup_hold import *
from .delay import * from .delay import *
from .charutils import * from .charutils import *
@ -324,11 +325,11 @@ class lib:
self.lib.write(" }\n") self.lib.write(" }\n")
self.lib.write(" pin(DOUT{1}[{0}:0]){{\n".format(self.sram.word_size - 1, read_port)) self.lib.write(" pin(DOUT{}){{\n".format(read_port))
self.lib.write(" timing(){ \n") self.lib.write(" timing(){ \n")
self.lib.write(" timing_sense : non_unate; \n") self.lib.write(" timing_sense : non_unate; \n")
self.lib.write(" related_pin : \"clk{0}\"; \n".format(read_port)) self.lib.write(" related_pin : \"clk{0}\"; \n".format(read_port))
self.lib.write(" timing_type : rising_edge; \n") self.lib.write(" timing_type : falling_edge; \n")
self.lib.write(" cell_rise(CELL_TABLE) {\n") self.lib.write(" cell_rise(CELL_TABLE) {\n")
self.write_values(self.char_port_results[read_port]["delay_lh"],len(self.loads)," ") self.write_values(self.char_port_results[read_port]["delay_lh"],len(self.loads)," ")
self.lib.write(" }\n") # rise delay self.lib.write(" }\n") # rise delay
@ -357,7 +358,7 @@ class lib:
self.lib.write(" address : ADDR{0}; \n".format(write_port)) self.lib.write(" address : ADDR{0}; \n".format(write_port))
self.lib.write(" clocked_on : clk{0}; \n".format(write_port)) self.lib.write(" clocked_on : clk{0}; \n".format(write_port))
self.lib.write(" }\n") self.lib.write(" }\n")
self.lib.write(" pin(DIN{1}[{0}:0]){{\n".format(self.sram.word_size - 1, write_port)) self.lib.write(" pin(DIN{}){{\n".format(write_port))
self.write_FF_setuphold(write_port) self.write_FF_setuphold(write_port)
self.lib.write(" }\n") # pin self.lib.write(" }\n") # pin
self.lib.write(" }\n") #bus self.lib.write(" }\n") #bus
@ -377,7 +378,7 @@ class lib:
self.lib.write(" direction : input; \n") self.lib.write(" direction : input; \n")
self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"])) self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"]))
self.lib.write(" max_transition : {0};\n".format(self.slews[-1])) self.lib.write(" max_transition : {0};\n".format(self.slews[-1]))
self.lib.write(" pin(ADDR{1}[{0}:0])".format(self.sram.addr_size - 1, port)) self.lib.write(" pin(ADDR{})".format(port))
self.lib.write("{\n") self.lib.write("{\n")
self.write_FF_setuphold(port) self.write_FF_setuphold(port)
@ -509,13 +510,23 @@ class lib:
git_id = 'AAAAAAAAAAAAAAAAAAAA' git_id = 'AAAAAAAAAAAAAAAAAAAA'
else: else:
with open(os.devnull, 'wb') as devnull: with open(os.devnull, 'wb') as devnull:
proc = subprocess.Popen(['git','rev-parse','HEAD'], stdout=subprocess.PIPE) proc = subprocess.Popen(['git','rev-parse','HEAD'], cwd=os.path.abspath(os.environ.get("OPENRAM_HOME")) + '/', stdout=subprocess.PIPE)
git_id = str(proc.stdout.read()) git_id = str(proc.stdout.read())
git_id = git_id[2:-3]
try:
git_id = git_id[2:-3]
except:
pass
if len(git_id) != 40:
debug.warning("Failed to retrieve git id")
git_id = 'Failed to retruieve'
datasheet = open(OPTS.openram_temp +'/datasheet.info', 'a+') 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( current_time = datetime.datetime.now()
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},".format(
"sram_{0}_{1}_{2}".format(OPTS.word_size, OPTS.num_words, OPTS.tech_name), "sram_{0}_{1}_{2}".format(OPTS.word_size, OPTS.num_words, OPTS.tech_name),
OPTS.num_words, OPTS.num_words,
OPTS.num_banks, OPTS.num_banks,
@ -530,9 +541,21 @@ class lib:
self.out_dir, self.out_dir,
lib_name, lib_name,
OPTS.word_size, OPTS.word_size,
git_id git_id,
current_time
)) ))
# information of checks
from hierarchy_design import total_drc_errors
from hierarchy_design import total_lvs_errors
DRC = 'skipped'
LVS = 'skipped'
if OPTS.check_lvsdrc:
DRC = str(total_drc_errors)
LVS = str(total_lvs_errors)
datasheet.write("{0},{1},".format(DRC, LVS))
for port in self.all_ports: for port in self.all_ports:
#DIN timings #DIN timings
if port in self.write_ports: if port in self.write_ports:
@ -629,6 +652,9 @@ class lib:
)) ))
datasheet.write("END\n") datasheet.write("END\n")
datasheet.close() datasheet.close()

View File

@ -1,23 +0,0 @@
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')
temperature = Col('Temperature')
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
self.power_supply = power_supply
self.temperature = temperature
self.library_name_suffix = library_name_suffix

View File

@ -1,11 +1,4 @@
from flask_table import * from table_gen import *
from operating_conditions import *
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 os
import csv import csv
import base64 import base64
@ -16,11 +9,6 @@ class datasheet():
Defines the layout,but not the data, of the html datasheet Defines the layout,but not the data, of the html datasheet
""" """
def __init__(self,identifier): def __init__(self,identifier):
self.io = []
self.corners = []
self.timing = []
self.operating = []
self.dlv = []
self.name = identifier self.name = identifier
self.html = "" self.html = ""
@ -33,20 +21,14 @@ class datasheet():
#css styling is kept in a seperate file #css styling is kept in a seperate file
self.html += datasheet_css.read() self.html += datasheet_css.read()
if OPTS.check_lvsdrc:
DRC = str(total_drc_errors) + ' errors' # with open(OPTS.openram_temp + "/datasheet.info") as info:
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 += '<!--' self.html += '<!--'
for row in info: # for row in info:
self.html += row # self.html += row
for item in self.description:
self.html += item + ','
self.html += 'EOL'
self.html +='-->' self.html +='-->'
vlsi_logo = 0 vlsi_logo = 0
@ -58,31 +40,37 @@ class datasheet():
openram_logo = base64.b64encode(image_file.read()) openram_logo = base64.b64encode(image_file.read())
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 += '<a href="https://vlsida.soe.ucsc.edu/"><img src="data:image/png;base64,{0}" alt="VLSIDA"></a>'.format(str(vlsi_logo)[2:-1])
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;">'+ 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;">Compiled at: '+ self.time + '</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;">'+ 'DRC errors: ' + str(self.DRC) + '</p>'
self.html +='<p style="font-size: 18px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">'+ 'LVS errors: ' + str(self.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: 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 +='<p style="font-size: 26px;font-family: Trebuchet MS, Arial, Helvetica, sans-serif;">Ports and Configuration</p>'
self.html += in_out(self.io,table_id='data').__html__().replace('&lt;','<').replace('&#34;','"').replace('&gt;',">") # self.html += in_out(self.io,table_id='data').__html__().replace('&lt;','<').replace('&#34;','"').replace('&gt;',">")
self.html += self.io_table.to_html()
self.html +='<p style="font-size: 26px;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 += operating_conditions(self.operating,table_id='data').__html__()
self.html += self.operating_table.to_html()
self.html += '<p style="font-size: 26px;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 += timing_and_current_data(self.timing,table_id='data').__html__()
self.html += self.timing_table.to_html()
self.html += '<p style="font-size: 26px;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 += characterization_corners(self.corners,table_id='data').__html__()
self.html += self.corners_table.to_html()
self.html +='<p style="font-size: 26px;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('&lt;','<').replace('&#34;','"').replace('&gt;',">") # self.html += deliverables(self.dlv,table_id='data').__html__().replace('&lt;','<').replace('&#34;','"').replace('&gt;',">")
self.html += self.dlv_table.to_html()

View File

@ -1,34 +1,21 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
""" """
This is a script to load data from the characterization and layout processes into 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 a web friendly html datasheet.
packages to be installed.
""" """
#TODO: #TODO:
#locate all port elements in .lib #include log file
#Locate all timing elements in .lib
#Diagram generation #Diagram generation
#Improve css #Improve css
import debug import debug
from globals import OPTS from globals import OPTS
import os, math
if OPTS.datasheet_gen: import optparse
import flask_table import csv
import os, math from datasheet import *
import optparse from table_gen import *
import csv
from deliverables import *
from operating_conditions import *
from timing_and_current_data import *
from characterization_corners import *
from datasheet import *
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): def process_name(corner):
""" """
@ -102,6 +89,14 @@ def parse_characterizer_csv(sram,f,pages):
ORIGIN_ID = row[col] ORIGIN_ID = row[col]
col += 1 col += 1
DATETIME = row[col]
col+= 1
DRC = row[col]
col += 1
LVS = row[col]
col += 1
for sheet in pages: for sheet in pages:
@ -111,69 +106,70 @@ def parse_characterizer_csv(sram,f,pages):
found = 1 found = 1
#if the .lib information is for an existing datasheet compare timing data #if the .lib information is for an existing datasheet compare timing data
for item in sheet.operating: for item in sheet.operating_table.rows:
#check if the new corner data is worse than the previous worse corner data #check if the new corner data is worse than the previous worse corner data
if item.parameter == 'Operating Temperature': if item[0] == 'Operating Temperature':
if float(TEMP) > float(item.max): if float(TEMP) > float(item[3]):
item.typ = item.max item[2] = item[3]
item.max = TEMP item[3] = TEMP
if float(TEMP) < float(item.min): if float(TEMP) < float(item[1]):
item.typ = item.min item[2] = item[1]
item.min = TEMP item[1] = TEMP
if item.parameter == 'Power supply (VDD) range': if item[0] == 'Power supply (VDD) range':
if float(VOLT) > float(item.max): if float(VOLT) > float(item[3]):
item.typ = item.max item[2] = item[3]
item.max = VOLT item[3] = VOLT
if float(VOLT) < float(item.min): if float(VOLT) < float(item[1]):
item.typ = item.min item[2] = item[1]
item.min = VOLT item[1] = VOLT
if item.parameter == 'Operating Frequncy (F)': if item[0] == 'Operating Frequncy (F)':
try: try:
if float(math.floor(1000/float(MIN_PERIOD)) < float(item.max)): if float(math.floor(1000/float(MIN_PERIOD)) < float(item[3])):
item.max = str(math.floor(1000/float(MIN_PERIOD))) item[3] = str(math.floor(1000/float(MIN_PERIOD)))
except Exception: except Exception:
pass pass
while(True): while(True):
if(row[col].startswith('DIN')): if(row[col].startswith('DIN')):
start = col start = col
for item in sheet.timing: for item in sheet.timing_table.rows:
if item.parameter.startswith(row[col]): if item[0].startswith(row[col]):
if item.parameter.endswith('setup rising'): if item[0].endswith('setup rising'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
elif item.parameter.endswith('setup falling'): elif item[0].endswith('setup falling'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
elif item.parameter.endswith('hold rising'): elif item[0].endswith('hold rising'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
elif item.parameter.endswith('hold falling'): elif item[0].endswith('hold falling'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
@ -181,38 +177,38 @@ def parse_characterizer_csv(sram,f,pages):
elif(row[col].startswith('DOUT')): elif(row[col].startswith('DOUT')):
start = col start = col
for item in sheet.timing: for item in sheet.timing_table.rows:
if item.parameter.startswith(row[col]): if item[0].startswith(row[col]):
if item.parameter.endswith('cell rise'): if item[0].endswith('cell rise'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
elif item.parameter.endswith('cell fall'): elif item[0].endswith('cell fall'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
elif item.parameter.endswith('rise transition'): elif item[0].endswith('rise transition'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
elif item.parameter.endswith('fall transition'): elif item[0].endswith('fall transition'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
@ -220,38 +216,38 @@ def parse_characterizer_csv(sram,f,pages):
elif(row[col].startswith('CSb')): elif(row[col].startswith('CSb')):
start = col start = col
for item in sheet.timing: for item in sheet.timing_table.rows:
if item.parameter.startswith(row[col]): if item[0].startswith(row[col]):
if item.parameter.endswith('setup rising'): if item[0].endswith('setup rising'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
elif item.parameter.endswith('setup falling'): elif item[0].endswith('setup falling'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
elif item.parameter.endswith('hold rising'): elif item[0].endswith('hold rising'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
elif item.parameter.endswith('hold falling'): elif item[0].endswith('hold falling'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
@ -260,38 +256,38 @@ def parse_characterizer_csv(sram,f,pages):
elif(row[col].startswith('WEb')): elif(row[col].startswith('WEb')):
start = col start = col
for item in sheet.timing: for item in sheet.timing_table.rows:
if item.parameter.startswith(row[col]): if item[0].startswith(row[col]):
if item.parameter.endswith('setup rising'): if item[0].endswith('setup rising'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
elif item.parameter.endswith('setup falling'): elif item[0].endswith('setup falling'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
elif item.parameter.endswith('hold rising'): elif item[0].endswith('hold rising'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
elif item.parameter.endswith('hold falling'): elif item[0].endswith('hold falling'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
@ -300,49 +296,51 @@ def parse_characterizer_csv(sram,f,pages):
elif(row[col].startswith('ADDR')): elif(row[col].startswith('ADDR')):
start = col start = col
for item in sheet.timing: for item in sheet.timing_table.rows:
if item.parameter.startswith(row[col]): if item[0].startswith(row[col]):
if item.parameter.endswith('setup rising'): if item[0].endswith('setup rising'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
elif item.parameter.endswith('setup falling'): elif item[0].endswith('setup falling'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
elif item.parameter.endswith('hold rising'): elif item[0].endswith('hold rising'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
elif item.parameter.endswith('hold falling'): elif item[0].endswith('hold falling'):
if float(row[col+1]) < float(item.min): if float(row[col+1]) < float(item[1]):
item.min = row[col+1] item[1] = row[col+1]
if float(row[col+2]) > float(item.max): if float(row[col+2]) > float(item[2]):
item.max = row[col+2] item[2] = row[col+2]
col += 2 col += 2
col += 1 col += 1
else: else:
break break
#regardless of if there is already a corner for the current sram, append the new corner to the datasheet new_sheet.corners_table.add_row([PROC,process_name(PROC),VOLT,TEMP,LIB_NAME.replace(OUT_DIR,'').replace(NAME,'')])
new_sheet.corners.append(characterization_corners_item(PROC,process_name(PROC),VOLT,TEMP,LIB_NAME.replace(OUT_DIR,'').replace(NAME,''))) new_sheet.dlv_table.add_row(['.lib','Synthesis models','<a href="file://{0}">{1}</a>'.format(LIB_NAME,LIB_NAME.replace(OUT_DIR,''))])
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 found == 0:
@ -351,125 +349,161 @@ def parse_characterizer_csv(sram,f,pages):
pages.append(new_sheet) pages.append(new_sheet)
new_sheet.git_id = ORIGIN_ID new_sheet.git_id = ORIGIN_ID
new_sheet.time = DATETIME
new_sheet.DRC = DRC
new_sheet.LVS = LVS
new_sheet.description = [NAME, NUM_WORDS, NUM_BANKS, NUM_RW_PORTS, NUM_W_PORTS, NUM_R_PORTS, TECH_NAME, WORD_SIZE, ORIGIN_ID, DATETIME]
new_sheet.corners.append(characterization_corners_item(PROC,process_name(PROC),VOLT,TEMP,LIB_NAME.replace(OUT_DIR,'').replace(NAME,''))) new_sheet.corners_table = table_gen("corners")
new_sheet.corners_table.add_row(['Corner Name','Process','Power Supply','Temperature','Library Name Suffix'])
new_sheet.corners_table.add_row([PROC,process_name(PROC),VOLT,TEMP,LIB_NAME.replace(OUT_DIR,'').replace(NAME,'')])
new_sheet.operating_table = table_gen("operating_table")
new_sheet.operating_table.add_row(['Parameter','Min','Typ','Max','Units'])
new_sheet.operating_table.add_row(['Power supply (VDD) range',VOLT,VOLT,VOLT,'Volts'])
new_sheet.operating_table.add_row(['Operating Temperature',TEMP,TEMP,TEMP,'Celsius'])
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: try:
new_sheet.operating.append(operating_conditions_item('Operating Frequency (F)','','',str(math.floor(1000/float(MIN_PERIOD))),'MHz')) new_sheet.operating_table.add_row(['Operating Frequency (F)','','',str(math.floor(1000/float(MIN_PERIOD))),'MHz'])
except Exception: except Exception:
new_sheet.operating.append(operating_conditions_item('Operating Frequency (F)','','',"not available in netlist only",'MHz')) #failed to provide non-zero MIN_PERIOD new_sheet.operating_table.add_row(['Operating Frequency (F)','','',"not available in netlist only",'MHz']) #failed to provide non-zero MIN_PERIOD
new_sheet.timing_table = table_gen("timing")
new_sheet.timing_table.add_row(['Parameter','Min','Max','Units'])
while(True): while(True):
if(row[col].startswith('DIN')): if(row[col].startswith('DIN')):
start = col start = col
new_sheet.timing.append(timing_and_current_data_item('{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns'))
new_sheet.timing_table.add_row(['{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
new_sheet.timing.append(timing_and_current_data_item('{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns'))
new_sheet.timing_table.add_row(['{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
new_sheet.timing.append(timing_and_current_data_item('{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns')) new_sheet.timing_table.add_row(['{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
new_sheet.timing.append(timing_and_current_data_item('{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns')) new_sheet.timing_table.add_row(['{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
col +=1 col +=1
elif(row[col].startswith('DOUT')): elif(row[col].startswith('DOUT')):
start = col start = col
new_sheet.timing.append(timing_and_current_data_item('{0} cell rise'.format(row[start]),row[col+1],row[col+2],'ns'))
new_sheet.timing_table.add_row(['{0} cell rise'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
new_sheet.timing.append(timing_and_current_data_item('{0} cell fall'.format(row[start]),row[col+1],row[col+2],'ns'))
new_sheet.timing_table.add_row(['{0} cell fall'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
new_sheet.timing.append(timing_and_current_data_item('{0} rise transition'.format(row[start]),row[col+1],row[col+2],'ns')) new_sheet.timing_table.add_row(['{0} rise transition'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
new_sheet.timing.append(timing_and_current_data_item('{0} fall transition'.format(row[start]),row[col+1],row[col+2],'ns')) new_sheet.timing_table.add_row(['{0} fall transition'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
col +=1 col +=1
elif(row[col].startswith('CSb')): elif(row[col].startswith('CSb')):
start = col start = col
new_sheet.timing.append(timing_and_current_data_item('{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns'))
new_sheet.timing_table.add_row(['{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
new_sheet.timing.append(timing_and_current_data_item('{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns'))
new_sheet.timing_table.add_row(['{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
new_sheet.timing.append(timing_and_current_data_item('{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns')) new_sheet.timing_table.add_row(['{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
new_sheet.timing.append(timing_and_current_data_item('{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns')) new_sheet.timing_table.add_row(['{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
col +=1 col +=1
elif(row[col].startswith('WEb')): elif(row[col].startswith('WEb')):
start = col start = col
new_sheet.timing.append(timing_and_current_data_item('{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns'))
new_sheet.timing_table.add_row(['{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
new_sheet.timing.append(timing_and_current_data_item('{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns'))
new_sheet.timing_table.add_row(['{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
new_sheet.timing.append(timing_and_current_data_item('{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns')) new_sheet.timing_table.add_row(['{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
new_sheet.timing.append(timing_and_current_data_item('{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns')) new_sheet.timing_table.add_row(['{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
col +=1 col +=1
elif(row[col].startswith('ADDR')): elif(row[col].startswith('ADDR')):
start = col start = col
new_sheet.timing.append(timing_and_current_data_item('{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns'))
new_sheet.timing_table.add_row(['{0} setup rising'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
new_sheet.timing.append(timing_and_current_data_item('{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns'))
new_sheet.timing_table.add_row(['{0} setup falling'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
new_sheet.timing.append(timing_and_current_data_item('{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns')) new_sheet.timing_table.add_row(['{0} hold rising'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
new_sheet.timing.append(timing_and_current_data_item('{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns')) new_sheet.timing_table.add_row(['{0} hold falling'.format(row[start]),row[col+1],row[col+2],'ns'])
col += 2 col += 2
col +=1 col +=1
else: else:
break break
new_sheet.dlv_table = table_gen("dlv")
new_sheet.dlv_table.add_row(['Type','Description','Link'])
new_sheet.io_table = table_gen("io")
new_sheet.io_table.add_row(['Type', 'Value'])
if not OPTS.netlist_only: if not OPTS.netlist_only:
#physical layout files should not be generated in netlist only mode #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_table.add_row(['.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_table.add_row(['.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_table.add_row(['.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_table.add_row(['.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_table.add_row(['.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_table.add_row(['.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'))) new_sheet.dlv_table.add_row(['.py','OpenRAM configuration file','<a href="{0}.{1}">{0}.{1}</a>'.format(OPTS.output_name,'py')])
new_sheet.io_table.add_row(['WORD_SIZE',WORD_SIZE])
new_sheet.io_table.add_row(['NUM_WORDS',NUM_WORDS])
#debug table for multiport information new_sheet.io_table.add_row(['NUM_BANKS',NUM_BANKS])
new_sheet.io.append(in_out_item('WORD_SIZE',WORD_SIZE)) new_sheet.io_table.add_row(['NUM_RW_PORTS',NUM_RW_PORTS])
new_sheet.io.append(in_out_item('NUM_WORDS',NUM_WORDS)) new_sheet.io_table.add_row(['NUM_R_PORTS',NUM_R_PORTS])
new_sheet.io.append(in_out_item('NUM_BANKS',NUM_BANKS)) new_sheet.io_table.add_row(['NUM_W_PORTS',NUM_W_PORTS])
new_sheet.io.append(in_out_item('NUM_RW_PORTS',NUM_RW_PORTS)) new_sheet.io_table.add_row(['Area',sram.width * sram.height])
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))
@ -479,18 +513,18 @@ def parse_characterizer_csv(sram,f,pages):
class datasheet_gen(): class datasheet_gen():
def datasheet_write(sram,name): def datasheet_write(sram,name):
if OPTS.datasheet_gen:
in_dir = OPTS.openram_temp
if not (os.path.isdir(in_dir)): in_dir = OPTS.openram_temp
os.mkdir(in_dir)
if not (os.path.isdir(in_dir)):
os.mkdir(in_dir)
datasheets = [] datasheets = []
parse_characterizer_csv(sram, in_dir + "/datasheet.info", datasheets) parse_characterizer_csv(sram, in_dir + "/datasheet.info", datasheets)
for sheets in datasheets: for sheets in datasheets:
with open(name, 'w+') as f: with open(name, 'w+') as f:
sheets.generate_html() sheets.generate_html()
f.write(sheets.html) f.write(sheets.html)

View File

@ -1,19 +0,0 @@
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
self.link = link

View File

@ -1,17 +0,0 @@
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

View File

@ -1,23 +0,0 @@
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')
max = Col('Max')
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
self.typ = typ
self.max = max
self.units = units

View File

@ -1,24 +0,0 @@
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))

View File

@ -1,7 +0,0 @@
class deliverable:
def __init__(self, name, file_type, path, size):
self.name = name
self.file_type = file_type
self.path = path
self.size = size

View File

@ -1,19 +0,0 @@
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))

View File

@ -1,116 +0,0 @@
<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>

View File

@ -1,767 +0,0 @@
**************************************************
* 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

View File

@ -1,47 +0,0 @@
// 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

View File

@ -1,321 +0,0 @@
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");
}
}
}
}
}

View File

@ -1,321 +0,0 @@
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");
}
}
}
}
}

View File

@ -1,625 +0,0 @@
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");
}
}
}
}
}

View File

@ -1,25 +0,0 @@
/* 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;
}

View File

@ -1,42 +0,0 @@
</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>

View File

@ -0,0 +1,43 @@
class table_gen:
def __init__(self,name):
self.name = name
self.rows = []
self.table_id = 'data'
def add_row(self,row):
self.rows.append(row)
def gen_table_head(self):
html = ''
html += '<thead>'
html += '<tr>'
for col in self.rows[0]:
html += '<th>' + str(col) + '</th>'
html += '</tr>'
html += '</thead>'
return html
def gen_table_body(self):
html = ''
html += '<tbody>'
html += '<tr>'
for row in self.rows[1:]:
html += '<tr>'
for col in row:
html += '<td>' + str(col) + '</td>'
html += '</tr>'
html += '</tr>'
html += '</tbody>'
return html
def to_html(self):
html = ''
html += '<table id= \"'+self.table_id+'\">'
html += self.gen_table_head()
html += self.gen_table_body()
html += '</table>'
return html

View File

@ -1,22 +0,0 @@
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
self.max = max
self.units = units

View File

@ -1,5 +1,5 @@
word_size = 2 word_size = 8
num_words = 16 num_words = 128
tech_name = "scn4m_subm" tech_name = "scn4m_subm"
process_corners = ["TT"] process_corners = ["TT"]
@ -9,10 +9,6 @@ temperatures = [ 25 ]
output_path = "temp" output_path = "temp"
output_name = "sram_{0}_{1}_{2}".format(word_size,num_words,tech_name) output_name = "sram_{0}_{1}_{2}".format(word_size,num_words,tech_name)
#Setting for multiport drc_name = "magic"
netlist_only = True lvs_name = "netgen"
bitcell = "pbitcell" pex_name = "magic"
replica_bitcell="replica_pbitcell"
num_rw_ports = 1
num_r_ports = 1
num_w_ports = 1

View File

@ -0,0 +1,20 @@
word_size = 2
num_words = 16
bitcell = "bitcell_1rw_1r"
replica_bitcell = "replica_bitcell_1rw_1r"
num_rw_ports = 1
num_r_ports = 1
num_w_ports = 0
tech_name = "scn4m_subm"
process_corners = ["TT"]
supply_voltages = [5.0]
temperatures = [25]
output_path = "temp"
output_name = "sram_1rw_1r_{0}_{1}_{2}".format(word_size,num_words,tech_name)
drc_name = "magic"
lvs_name = "netgen"
pex_name = "magic"

View File

@ -0,0 +1,14 @@
word_size = 16
num_words = 256
tech_name = "scn4m_subm"
process_corners = ["TT"]
supply_voltages = [ 3.3 ]
temperatures = [ 25 ]
output_path = "temp"
output_name = "sram_{0}_{1}_{2}".format(word_size,num_words,tech_name)
drc_name = "magic"
lvs_name = "netgen"
pex_name = "magic"

View File

@ -108,12 +108,6 @@ def check_versions():
# or, this could be done in each module (e.g. verify, characterizer, etc.) # or, this could be done in each module (e.g. verify, characterizer, etc.)
global OPTS global OPTS
try:
import flask_table
OPTS.datasheet_gen = 1
except:
OPTS.datasheet_gen = 0
try: try:
import coverage import coverage
OPTS.coverage = 1 OPTS.coverage = 1
@ -420,7 +414,7 @@ def report_status():
debug.error("Tech name must be specified in config file.") debug.error("Tech name must be specified in config file.")
print("Technology: {0}".format(OPTS.tech_name)) print("Technology: {0}".format(OPTS.tech_name))
print("Total size: {} kbits".format(OPTS.word_size*OPTS.num_words*OPTS.num_banks)) print("Total size: {} bits".format(OPTS.word_size*OPTS.num_words*OPTS.num_banks))
print("Word size: {0}\nWords: {1}\nBanks: {2}".format(OPTS.word_size, print("Word size: {0}\nWords: {1}\nBanks: {2}".format(OPTS.word_size,
OPTS.num_words, OPTS.num_words,
OPTS.num_banks)) OPTS.num_banks))

View File

@ -47,12 +47,10 @@ c = sram_config(word_size=OPTS.word_size,
print("Words per row: {}".format(c.words_per_row)) print("Words per row: {}".format(c.words_per_row))
#from parser import * #from parser import *
output_extensions = ["sp","v","lib","py"] output_extensions = ["sp","v","lib","py","html"]
if OPTS.datasheet_gen:
output_extensions.append("html")
if not OPTS.netlist_only: if not OPTS.netlist_only:
output_extensions.extend(["gds","lef"]) output_extensions.extend(["gds","lef"])
output_files = ["{0}.{1}".format(OPTS.output_name,x) for x in output_extensions] output_files = ["{0}{1}.{2}".format(OPTS.output_path,OPTS.output_name,x) for x in output_extensions]
print("Output files are: ") print("Output files are: ")
print(*output_files,sep="\n") print(*output_files,sep="\n")

View File

@ -13,26 +13,26 @@ class pdriver(pgate.pgate):
""" """
unique_id = 1 unique_id = 1
def __init__(self, height=None, name="", neg_polarity=False, c_load=8, size_list = []): def __init__(self, neg_polarity=False, fanout_size=8, size_list = [], height=None, name=""):
self.stage_effort = 4 self.stage_effort = 4
self.row_height = height self.height = height
self.neg_polarity = neg_polarity self.neg_polarity = neg_polarity
self.size_list = size_list self.size_list = size_list
self.c_load = c_load self.fanout_size = fanout_size
if len(self.size_list) > 0 and (self.c_load != 8 or self.neg_polarity): if len(self.size_list) > 0 and (self.fanout_size != 8 or self.neg_polarity):
raise Exception("Cannot specify both size_list and neg_polarity or c_load.") debug.error("Cannot specify both size_list and neg_polarity or fanout_size.", -1)
self.compute_sizes()
if name=="": if name=="":
name = "pdriver_{0}_{1}_".format(self.num_inv, pdriver.unique_id) name = "pdriver_{}".format(pdriver.unique_id)
pdriver.unique_id += 1 pdriver.unique_id += 1
pgate.pgate.__init__(self, name) pgate.pgate.__init__(self, name, height)
debug.info(1, "Creating {}".format(self.name)) debug.info(1, "Creating {}".format(self.name))
self.compute_sizes()
self.create_netlist() self.create_netlist()
if not OPTS.netlist_only: if not OPTS.netlist_only:
self.create_layout() self.create_layout()
@ -45,8 +45,8 @@ class pdriver(pgate.pgate):
self.num_inv = len(self.size_list) self.num_inv = len(self.size_list)
else: else:
# find the number of stages # find the number of stages
#c_load is a unit inverter fanout, not a capacitance so c_in=1 #fanout_size is a unit inverter fanout, not a capacitance so c_in=1
num_stages = int(round(log(self.c_load)/log(4))) num_stages = max(1,int(round(log(self.fanout_size)/log(4))))
# find inv_num and compute sizes # find inv_num and compute sizes
if self.neg_polarity: if self.neg_polarity:
@ -65,30 +65,35 @@ class pdriver(pgate.pgate):
self.calc_size_list = [] self.calc_size_list = []
self.num_inv = num_stages self.num_inv = num_stages
# compute sizes # compute sizes
c_prev = self.c_load fanout_size_prev = self.fanout_size
for x in range(self.num_inv-1,-1,-1): for x in range(self.num_inv-1,-1,-1):
c_prev = int(round(c_prev/self.stage_effort)) fanout_size_prev = int(round(fanout_size_prev/self.stage_effort))
self.calc_size_list.append(c_prev) self.calc_size_list.append(fanout_size_prev)
def diff_polarity(self, num_stages): def diff_polarity(self, num_stages):
self.calc_size_list = [] self.calc_size_list = []
# find which delay is smaller # find which delay is smaller
delay_below = ((num_stages-1)*(self.c_load**(1/num_stages-1))) + num_stages-1 if (num_stages > 1):
delay_above = ((num_stages+1)*(self.c_load**(1/num_stages+1))) + num_stages+1 delay_below = ((num_stages-1)*(self.fanout_size**(1/num_stages-1))) + num_stages-1
if (delay_above < delay_below): delay_above = ((num_stages+1)*(self.fanout_size**(1/num_stages+1))) + num_stages+1
# recompute stage_effort for this delay if (delay_above < delay_below):
# recompute stage_effort for this delay
self.num_inv = num_stages+1
polarity_stage_effort = self.fanout_size**(1/self.num_inv)
else:
self.num_inv = num_stages-1
polarity_stage_effort = self.fanout_size**(1/self.num_inv)
else: # num_stages is 1, can't go to 0
self.num_inv = num_stages+1 self.num_inv = num_stages+1
polarity_stage_effort = self.c_load**(1/self.num_inv) polarity_stage_effort = self.fanout_size**(1/self.num_inv)
else:
self.num_inv = num_stages-1
polarity_stage_effort = self.c_load**(1/self.num_inv)
# compute sizes # compute sizes
c_prev = self.c_load fanout_size_prev = self.fanout_size
for x in range(self.num_inv-1,-1,-1): for x in range(self.num_inv-1,-1,-1):
c_prev = int(round(c_prev/polarity_stage_effort)) fanout_size_prev = int(round(fanout_size_prev/polarity_stage_effort))
self.calc_size_list.append(c_prev) self.calc_size_list.append(fanout_size_prev)
def create_netlist(self): def create_netlist(self):
@ -118,11 +123,11 @@ class pdriver(pgate.pgate):
self.inv_list = [] self.inv_list = []
if len(self.size_list) > 0: # size list specified if len(self.size_list) > 0: # size list specified
for x in range(len(self.size_list)): for x in range(len(self.size_list)):
self.inv_list.append(pinv(size=self.size_list[x], height=self.row_height)) self.inv_list.append(pinv(size=self.size_list[x], height=self.height))
self.add_mod(self.inv_list[x]) self.add_mod(self.inv_list[x])
else: # find inv sizes else: # find inv sizes
for x in range(len(self.calc_size_list)): 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.inv_list.append(pinv(size=self.calc_size_list[x], height=self.height))
self.add_mod(self.inv_list[x]) self.add_mod(self.inv_list[x])

View File

@ -48,6 +48,9 @@ class sram():
def sp_write(self,name): def sp_write(self,name):
self.s.sp_write(name) self.s.sp_write(name)
def lef_write(self,name):
self.s.lef_write(name)
def gds_write(self,name): def gds_write(self,name):
self.s.gds_write(name) self.s.gds_write(name)
@ -63,21 +66,21 @@ class sram():
start_time = datetime.datetime.now() start_time = datetime.datetime.now()
gdsname = OPTS.output_path + self.s.name + ".gds" gdsname = OPTS.output_path + self.s.name + ".gds"
print("GDS: Writing to {0}".format(gdsname)) print("GDS: Writing to {0}".format(gdsname))
self.s.gds_write(gdsname) self.gds_write(gdsname)
print_time("GDS", datetime.datetime.now(), start_time) print_time("GDS", datetime.datetime.now(), start_time)
# Create a LEF physical model # Create a LEF physical model
start_time = datetime.datetime.now() start_time = datetime.datetime.now()
lefname = OPTS.output_path + self.s.name + ".lef" lefname = OPTS.output_path + self.s.name + ".lef"
print("LEF: Writing to {0}".format(lefname)) print("LEF: Writing to {0}".format(lefname))
self.s.lef_write(lefname) self.lef_write(lefname)
print_time("LEF", datetime.datetime.now(), start_time) print_time("LEF", datetime.datetime.now(), start_time)
# Save the spice file # Save the spice file
start_time = datetime.datetime.now() start_time = datetime.datetime.now()
spname = OPTS.output_path + self.s.name + ".sp" spname = OPTS.output_path + self.s.name + ".sp"
print("SP: Writing to {0}".format(spname)) print("SP: Writing to {0}".format(spname))
self.s.sp_write(spname) self.sp_write(spname)
print_time("Spice writing", datetime.datetime.now(), start_time) print_time("Spice writing", datetime.datetime.now(), start_time)
# Save the extracted spice file # Save the extracted spice file
@ -111,14 +114,14 @@ class sram():
start_time = datetime.datetime.now() start_time = datetime.datetime.now()
from shutil import copyfile from shutil import copyfile
copyfile(OPTS.config_file + '.py', OPTS.output_path + OPTS.output_name + '.py') 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("Config: Writing to {0}".format(OPTS.output_path + OPTS.output_name + '.py'))
print_time("Config", datetime.datetime.now(), start_time) print_time("Config", datetime.datetime.now(), start_time)
# Write the datasheet # Write the datasheet
start_time = datetime.datetime.now() start_time = datetime.datetime.now()
from datasheet_gen import datasheet_gen from datasheet_gen import datasheet_gen
dname = OPTS.output_path + self.s.name + ".html" dname = OPTS.output_path + self.s.name + ".html"
print("Datasheet: writing to {0}".format(dname)) print("Datasheet: Writing to {0}".format(dname))
datasheet_gen.datasheet_write(self.s,dname) datasheet_gen.datasheet_write(self.s,dname)
print_time("Datasheet", datetime.datetime.now(), start_time) print_time("Datasheet", datetime.datetime.now(), start_time)
@ -126,5 +129,5 @@ class sram():
start_time = datetime.datetime.now() start_time = datetime.datetime.now()
vname = OPTS.output_path + self.s.name + ".v" vname = OPTS.output_path + self.s.name + ".v"
print("Verilog: Writing to {0}".format(vname)) print("Verilog: Writing to {0}".format(vname))
self.s.verilog_write(vname) self.verilog_write(vname)
print_time("Verilog", datetime.datetime.now(), start_time) print_time("Verilog", datetime.datetime.now(), start_time)

View File

@ -8,14 +8,18 @@ from vector import vector
from globals import OPTS, print_time from globals import OPTS, print_time
import logical_effort import logical_effort
from design import design from design import design
from verilog import verilog
from lef import lef
class sram_base(design): class sram_base(design, verilog, lef):
""" """
Dynamically generated SRAM by connecting banks to control logic. The Dynamically generated SRAM by connecting banks to control logic. The
number of banks should be 1 , 2 or 4 number of banks should be 1 , 2 or 4
""" """
def __init__(self, name, sram_config): def __init__(self, name, sram_config):
design.__init__(self, name) design.__init__(self, name)
lef.__init__(self, ["metal1", "metal2", "metal3"])
verilog.__init__(self)
self.sram_config = sram_config self.sram_config = sram_config
sram_config.set_local_config(self) sram_config.set_local_config(self)

11
compiler/tests/04_pdriver_test.py Normal file → Executable file
View File

@ -11,7 +11,6 @@ import globals
from globals import OPTS from globals import OPTS
import debug import debug
@unittest.skip("SKIPPING 04_pdriver_test, LVS error in FreePDK45")
class pdriver_test(openram_test): class pdriver_test(openram_test):
def runTest(self): def runTest(self):
@ -23,12 +22,12 @@ class pdriver_test(openram_test):
debug.info(2, "Testing inverter/buffer 4x 8x") debug.info(2, "Testing inverter/buffer 4x 8x")
# a tests the error message for specifying conflicting conditions # a tests the error message for specifying conflicting conditions
#a = pdriver.pdriver(c_load = 4,size_list = [1,2,4,8]) #a = pdriver.pdriver(fanout_size = 4,size_list = [1,2,4,8])
b = pdriver.pdriver(size_list = [1,2,4,8]) b = pdriver.pdriver(size_list = [1,2,4,8])
c = pdriver.pdriver(c_load = 50) c = pdriver.pdriver(fanout_size = 50)
d = pdriver.pdriver(c_load = 50, neg_polarity = True) d = pdriver.pdriver(fanout_size = 50, neg_polarity = True)
e = pdriver.pdriver(c_load = 64) e = pdriver.pdriver(fanout_size = 64)
f = pdriver.pdriver(c_load = 64, neg_polarity = True) f = pdriver.pdriver(fanout_size = 64, neg_polarity = True)
#self.local_check(a) #self.local_check(a)
self.local_check(b) self.local_check(b)
self.local_check(c) self.local_check(c)

View File

@ -36,10 +36,7 @@ class lef_test(openram_test):
# let's diff the result with a golden model # let's diff the result with a golden model
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),leffile) golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),leffile)
self.isdiff(lefname,golden) self.assertTrue(self.isdiff(lefname,golden))
os.system("rm {0}".format(gdsname))
os.system("rm {0}".format(lefname))
globals.end_openram() globals.end_openram()

View File

@ -33,9 +33,7 @@ class verilog_test(openram_test):
# let's diff the result with a golden model # let's diff the result with a golden model
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),vfile) golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),vfile)
self.isdiff(vname,golden) self.assertTrue(self.isdiff(vname,golden))
os.system("rm {0}".format(vname))
globals.end_openram() globals.end_openram()

View File

@ -45,14 +45,16 @@ class openram_test(openram_test):
# Always perform code coverage # Always perform code coverage
if OPTS.coverage == 0: if OPTS.coverage == 0:
debug.warning("Failed to find coverage installation. This can be installed with pip3 install coverage") 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) exe_name = "{0}/openram.py ".format(OPENRAM_HOME)
else:
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) 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, cmd = "{0} -n -o {1} -p {2} {3} {4} 2>&1 > {5}/output.log".format(exe_name,
out_file, out_file,
out_path, out_path,
verbosity, verbosity,
config_name, config_name,
out_path) out_path)
debug.info(1, cmd) debug.info(1, cmd)
os.system(cmd) os.system(cmd)

View File

@ -2,46 +2,60 @@
// Words: 16 // Words: 16
// Word size: 2 // Word size: 2
module sram_2_16_1_freepdk45(DATA,ADDR,CSb,WEb,OEb,clk); module sram_2_16_1_freepdk45(
// Port 0: RW
clk0,csb0,web0,ADDR0,DIN0,DOUT0
);
parameter DATA_WIDTH = 2 ; parameter DATA_WIDTH = 2 ;
parameter ADDR_WIDTH = 4 ; parameter ADDR_WIDTH = 4 ;
parameter RAM_DEPTH = 1 << ADDR_WIDTH; parameter RAM_DEPTH = 1 << ADDR_WIDTH;
// FIXME: This delay is arbitrary.
parameter DELAY = 3 ; parameter DELAY = 3 ;
inout [DATA_WIDTH-1:0] DATA; input clk0; // clock
input [ADDR_WIDTH-1:0] ADDR; input csb0; // active low chip select
input CSb; // active low chip select input web0; // active low write control
input WEb; // active low write control input [ADDR_WIDTH-1:0] ADDR0;
input OEb; // active output enable input [DATA_WIDTH-1:0] DIN0;
input clk; // clock output [DATA_WIDTH-1:0] DOUT0;
reg [DATA_WIDTH-1:0] data_out ; reg csb0_reg;
reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1]; reg web0_reg;
reg [ADDR_WIDTH-1:0] ADDR0_reg;
reg [DATA_WIDTH-1:0] DIN0_reg;
reg [DATA_WIDTH-1:0] DOUT0;
// Tri-State Buffer control // All inputs are registers
// output : When WEb = 1, oeb = 0, csb = 0 always @(posedge clk0)
assign DATA = (!CSb && !OEb && WEb) ? data_out : 2'bz; begin
csb0_reg = csb0;
// Memory Write Block web0_reg = web0;
// Write Operation : When WEb = 0, CSb = 0 ADDR0_reg = ADDR0;
always @ (posedge clk) DIN0_reg = DIN0;
begin : MEM_WRITE DOUT0 = 2'bx;
if ( !CSb && !WEb ) begin if ( !csb0_reg && web0_reg )
mem[ADDR] = DATA; $display($time," Reading %m ADDR0=%b DOUT0=%b",ADDR0_reg,mem[ADDR0_reg]);
$display($time," Writing %m ABUS=%b DATA=%b",ADDR,DATA); if ( !csb0_reg && !web0_reg )
end $display($time," Writing %m ADDR0=%b DIN0=%b",ADDR0_reg,DIN0_reg);
end end
reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
// Memory Read Block // Memory Write Block Port 0
// Read Operation : When WEb = 1, CSb = 0 // Write Operation : When web0 = 0, csb0 = 0
always @ (posedge clk) always @ (negedge clk0)
begin : MEM_READ begin : MEM_WRITE0
if (!CSb && WEb) begin if ( !csb0_reg && !web0_reg )
data_out <= #(DELAY) mem[ADDR]; mem[ADDR0_reg] = DIN0_reg;
$display($time," Reading %m ABUS=%b DATA=%b",ADDR,mem[ADDR]); end
end
// Memory Read Block Port 0
// Read Operation : When web0 = 1, csb0 = 0
always @ (negedge clk0)
begin : MEM_READ0
if (!csb0_reg && web0_reg)
DOUT0 <= #(DELAY) mem[ADDR0_reg];
end end
endmodule endmodule

View File

@ -93,7 +93,7 @@ cell (sram_2_16_1_freepdk45){
address : ADDR0; address : ADDR0;
clocked_on : clk0; clocked_on : clk0;
} }
pin(DIN0[1:0]){ pin(DIN0){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -132,11 +132,11 @@ cell (sram_2_16_1_freepdk45){
memory_read(){ memory_read(){
address : ADDR0; address : ADDR0;
} }
pin(DOUT0[1:0]){ pin(DOUT0){
timing(){ timing(){
timing_sense : non_unate; timing_sense : non_unate;
related_pin : "clk0"; related_pin : "clk0";
timing_type : rising_edge; timing_type : falling_edge;
cell_rise(CELL_TABLE) { cell_rise(CELL_TABLE) {
values("0.235, 0.235, 0.239",\ values("0.235, 0.235, 0.239",\
"0.235, 0.236, 0.24",\ "0.235, 0.236, 0.24",\
@ -166,7 +166,7 @@ cell (sram_2_16_1_freepdk45){
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.2091;
max_transition : 0.04; max_transition : 0.04;
pin(ADDR0[3:0]){ pin(ADDR0){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";

View File

@ -93,7 +93,7 @@ cell (sram_2_16_1_freepdk45){
address : ADDR0; address : ADDR0;
clocked_on : clk0; clocked_on : clk0;
} }
pin(DIN0[1:0]){ pin(DIN0){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -132,11 +132,11 @@ cell (sram_2_16_1_freepdk45){
memory_read(){ memory_read(){
address : ADDR0; address : ADDR0;
} }
pin(DOUT0[1:0]){ pin(DOUT0){
timing(){ timing(){
timing_sense : non_unate; timing_sense : non_unate;
related_pin : "clk0"; related_pin : "clk0";
timing_type : rising_edge; timing_type : falling_edge;
cell_rise(CELL_TABLE) { cell_rise(CELL_TABLE) {
values("0.098, 0.098, 0.098",\ values("0.098, 0.098, 0.098",\
"0.098, 0.098, 0.098",\ "0.098, 0.098, 0.098",\
@ -166,7 +166,7 @@ cell (sram_2_16_1_freepdk45){
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.2091;
max_transition : 0.04; max_transition : 0.04;
pin(ADDR0[3:0]){ pin(ADDR0){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";

View File

@ -93,7 +93,7 @@ cell (sram_2_16_1_freepdk45){
address : ADDR0; address : ADDR0;
clocked_on : clk0; clocked_on : clk0;
} }
pin(DIN0[1:0]){ pin(DIN0){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -132,11 +132,11 @@ cell (sram_2_16_1_freepdk45){
memory_read(){ memory_read(){
address : ADDR0; address : ADDR0;
} }
pin(DOUT0[1:0]){ pin(DOUT0){
timing(){ timing(){
timing_sense : non_unate; timing_sense : non_unate;
related_pin : "clk0"; related_pin : "clk0";
timing_type : rising_edge; timing_type : falling_edge;
cell_rise(CELL_TABLE) { cell_rise(CELL_TABLE) {
values("0.233, 0.233, 0.237",\ values("0.233, 0.233, 0.237",\
"0.233, 0.234, 0.237",\ "0.233, 0.234, 0.237",\
@ -166,7 +166,7 @@ cell (sram_2_16_1_freepdk45){
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.2091;
max_transition : 0.04; max_transition : 0.04;
pin(ADDR0[3:0]){ pin(ADDR0){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";

File diff suppressed because it is too large Load Diff

View File

@ -1,681 +0,0 @@
* OpenRAM generated memory.
* User: mrg
.global vdd gnd
*master-slave flip-flop with both output and inverted ouput
.subckt ms_flop din dout dout_bar clk vdd gnd
xmaster din mout mout_bar clk clk_bar vdd gnd dlatch
xslave mout_bar dout_bar dout clk_bar clk_nn vdd gnd dlatch
.ends flop
.subckt dlatch din dout dout_bar clk clk_bar vdd gnd
*clk inverter
mPff1 clk_bar clk vdd vdd p W=1.8u L=0.6u m=1
mNff1 clk_bar clk gnd gnd n W=0.9u L=0.6u m=1
*transmission gate 1
mtmP1 din clk int1 vdd p W=1.8u L=0.6u m=1
mtmN1 din clk_bar int1 gnd n W=0.9u L=0.6u m=1
*foward inverter
mPff3 dout_bar int1 vdd vdd p W=1.8u L=0.6u m=1
mNff3 dout_bar int1 gnd gnd n W=0.9u L=0.6u m=1
*backward inverter
mPff4 dout dout_bar vdd vdd p W=1.8u L=0.6u m=1
mNf4 dout dout_bar gnd gnd n W=0.9u L=0.6u m=1
*transmission gate 2
mtmP2 int1 clk_bar dout vdd p W=1.8u L=0.6u m=1
mtmN2 int1 clk dout gnd n W=0.9u L=0.6u m=1
.ends dlatch
.SUBCKT inv_nmos11 D G S B
Mnmos D G S B n m=1 w=1.2u l=0.6u
.ENDS inv_nmos11
.SUBCKT inv_pmos12 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS inv_pmos12
.SUBCKT pinv A Z vdd gnd
Xpinv_nmos Z A gnd gnd inv_nmos11
Xpinv_pmos Z A vdd vdd inv_pmos12
.ENDS pinv
.SUBCKT nand_2_nmos13 D G S B
Mnmos D G S B n m=1 w=2.4u l=0.6u
.ENDS nand_2_nmos13
.SUBCKT nand_2_nmos24 D G S B
Mnmos D G S B n m=1 w=2.4u l=0.6u
.ENDS nand_2_nmos24
.SUBCKT nand_2_pmos15 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS nand_2_pmos15
.SUBCKT nand_2_pmos26 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS nand_2_pmos26
.SUBCKT nand2 A B Z vdd gnd
Xnmos1 Z A net1 gnd nand_2_nmos13
Xnmos2 net1 B gnd gnd nand_2_nmos24
Xpmos1 vdd A Z vdd nand_2_pmos15
Xpmos2 Z B vdd vdd nand_2_pmos26
.ENDS nand2
.SUBCKT nand_3_nmos17 D G S B
Mnmos D G S B n m=1 w=3.6u l=0.6u
.ENDS nand_3_nmos17
.SUBCKT nand_3_nmos28 D G S B
Mnmos D G S B n m=1 w=3.6u l=0.6u
.ENDS nand_3_nmos28
.SUBCKT nand_3_nmos39 D G S B
Mnmos D G S B n m=1 w=3.6u l=0.6u
.ENDS nand_3_nmos39
.SUBCKT nand_3_pmos110 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS nand_3_pmos110
.SUBCKT nand_3_pmos211 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS nand_3_pmos211
.SUBCKT nand_3_pmos312 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS nand_3_pmos312
.SUBCKT NAND3 A B C Z vdd gnd
Xnmos1 net2 A gnd gnd nand_3_nmos17
Xnmos2 net1 B net2 gnd nand_3_nmos28
Xnmos3 Z C net1 gnd nand_3_nmos39
Xpmos1 Z A vdd vdd nand_3_pmos110
Xpmos2 vdd B Z vdd nand_3_pmos211
Xpmos3 Z C vdd vdd nand_3_pmos312
.ENDS NAND3
.SUBCKT inv_nmos113 D G S B
Mnmos D G S B n m=4 w=1.2u l=0.6u
.ENDS inv_nmos113
.SUBCKT inv_pmos114 D G S B
Mpmos D G S B p m=4 w=2.4u l=0.6u
.ENDS inv_pmos114
.SUBCKT pinv4 A Z vdd gnd
Xpinv_nmos Z A gnd gnd inv_nmos113
Xpinv_pmos Z A vdd vdd inv_pmos114
.ENDS pinv4
.SUBCKT nor_2_nmos123 D G S B
Mnmos D G S B n m=1 w=1.2u l=0.6u
.ENDS nor_2_nmos123
.SUBCKT nor_2_nmos224 D G S B
Mnmos D G S B n m=1 w=1.2u l=0.6u
.ENDS nor_2_nmos224
.SUBCKT nor_2_pmos125 D G S B
Mpmos D G S B p m=4 w=1.2u l=0.6u
.ENDS nor_2_pmos125
.SUBCKT nor_2_pmos226 D G S B
Mpmos D G S B p m=4 w=1.2u l=0.6u
.ENDS nor_2_pmos226
.SUBCKT nor2 A B Z vdd gnd
Xnmos1 Z A gnd gnd nor_2_nmos123
Xnmos2 Z B gnd gnd nor_2_nmos224
Xpmos1 vdd A net1 vdd nor_2_pmos125
Xpmos2 net1 B Z vdd nor_2_pmos226
.ENDS nor2
.SUBCKT msf_control DATA[0] DATA[1] DATA[2] data_in[0] data_in_bar[0] data_in[1] data_in_bar[1] data_in[2] data_in_bar[2] clk vdd gnd
XXdff0 DATA[0] data_in[0] data_in_bar[0] clk vdd gnd ms_flop
XXdff1 DATA[1] data_in[1] data_in_bar[1] clk vdd gnd ms_flop
XXdff2 DATA[2] data_in[2] data_in_bar[2] clk vdd gnd ms_flop
.ENDS msf_control
*********************** "cell_6t" ******************************
.SUBCKT replica_cell_6t bl br wl vdd gnd
M_1 gnd net_2 vdd vdd p W='0.9u' L=1.2u
M_2 net_2 gnd vdd vdd p W='0.9u' L=1.2u
M_3 br wl net_2 gnd n W='1.2u' L=0.6u
M_4 bl wl gnd gnd n W='1.2u' L=0.6u
M_5 net_2 gnd gnd gnd n W='2.4u' L=0.6u
M_6 gnd net_2 gnd gnd n W='2.4u' L=0.6u
.ENDS $ replica_cell_6t
*********************** "cell_6t" ******************************
.SUBCKT cell_6t bl br wl vdd gnd
M_1 net_1 net_2 vdd vdd p W='0.9u' L=1.2u
M_2 net_2 net_1 vdd vdd p W='0.9u' L=1.2u
M_3 br wl net_2 gnd n W='1.2u' L=0.6u
M_4 bl wl net_1 gnd n W='1.2u' L=0.6u
M_5 net_2 net_1 gnd gnd n W='2.4u' L=0.6u
M_6 net_1 net_2 gnd gnd n W='2.4u' L=0.6u
.ENDS $ cell_6t
.SUBCKT bitline_load bl[0] br[0] wl[0] wl[1] vdd gnd
Xbit_r0_c0 bl[0] br[0] wl[0] vdd gnd cell_6t
Xbit_r1_c0 bl[0] br[0] wl[1] vdd gnd cell_6t
.ENDS bitline_load
.SUBCKT inv_nmos127 D G S B
Mnmos D G S B n m=1 w=1.2u l=0.6u
.ENDS inv_nmos127
.SUBCKT inv_pmos128 D G S B
Mpmos D G S B p m=1 w=3.6u l=0.6u
.ENDS inv_pmos128
.SUBCKT delay_chain_inv A Z vdd gnd
Xpinv_nmos Z A gnd gnd inv_nmos127
Xpinv_pmos Z A vdd vdd inv_pmos128
.ENDS delay_chain_inv
.SUBCKT delay_chain clk_in clk_out vdd gnd
Xinv_chain0 clk_in s1 vdd gnd delay_chain_inv
Xinv_chain1 s1 s2 vdd gnd delay_chain_inv
Xinv_chain2 s2 s3 vdd gnd delay_chain_inv
Xinv_chain3 s3 clk_out vdd gnd delay_chain_inv
.ENDS delay_chain
.SUBCKT inv_nmos129 D G S B
Mnmos D G S B n m=1 w=1.2u l=0.6u
.ENDS inv_nmos129
.SUBCKT inv_pmos130 D G S B
Mpmos D G S B p m=1 w=3.6u l=0.6u
.ENDS inv_pmos130
.SUBCKT RBL_inv A Z vdd gnd
Xpinv_nmos Z A gnd gnd inv_nmos129
Xpinv_pmos Z A vdd vdd inv_pmos130
.ENDS RBL_inv
.SUBCKT nor_2_nmos139 D G S B
Mnmos D G S B n m=1 w=1.2u l=0.6u
.ENDS nor_2_nmos139
.SUBCKT nor_2_nmos240 D G S B
Mnmos D G S B n m=1 w=1.2u l=0.6u
.ENDS nor_2_nmos240
.SUBCKT nor_2_pmos141 D G S B
Mpmos D G S B p m=4 w=1.2u l=0.6u
.ENDS nor_2_pmos141
.SUBCKT nor_2_pmos242 D G S B
Mpmos D G S B p m=4 w=1.2u l=0.6u
.ENDS nor_2_pmos242
.SUBCKT replica_bitline_nor2 A B Z vdd gnd
Xnmos1 Z A gnd gnd nor_2_nmos139
Xnmos2 Z B gnd gnd nor_2_nmos240
Xpmos1 vdd A net1 vdd nor_2_pmos141
Xpmos2 net1 B Z vdd nor_2_pmos242
.ENDS replica_bitline_nor2
.SUBCKT access_tx43 D G S B
Mpmos D G S B p m=1 w=1.2u l=0.6u
.ENDS access_tx43
.SUBCKT replica_bitline en out vdd gnd
XBL_inv bl[0] out vdd gnd RBL_inv
XBL_access_tx vdd delayed_en bl[0] vdd access_tx43
Xdelay_chain en delayed_en vdd gnd delay_chain
Xbitcell bl[0] br[0] delayed_en vdd gnd replica_cell_6t
Xload bl[0] br[0] gnd gnd vdd gnd bitline_load
.ENDS replica_bitline
.SUBCKT control_logic CSb WEb OEb s_en w_en tri_en tri_en_bar clk_bar clk vdd gnd
Xmsf_control CSb WEb OEb CS_bar CS WE_bar WE OE_bar OE clk vdd gnd msf_control
Xclk_inverter clk clk_bar vdd gnd pinv4
Xnor2 clk OE_bar tri_en vdd gnd nor2
Xnand2_tri_en OE clk_bar tri_en_bar vdd gnd nand2
Xreplica_bitline rblk pre_s_en vdd gnd replica_bitline
Xinv_s_en1 pre_s_en_bar s_en vdd gnd pinv
Xinv_s_en2 pre_s_en pre_s_en_bar vdd gnd pinv
XNAND3_rblk_bar clk_bar OE CS rblk_bar vdd gnd NAND3
XNAND3_w_en_bar clk_bar WE CS w_en_bar vdd gnd NAND3
Xinv_rblk rblk_bar rblk vdd gnd pinv
Xinv_w_en w_en_bar pre_w_en vdd gnd pinv
Xinv_w_en1 pre_w_en pre_w_en1 vdd gnd pinv
Xinv_w_en2 pre_w_en1 w_en vdd gnd pinv
.ENDS control_logic
.SUBCKT bitcell_array bl[0] br[0] bl[1] br[1] 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] vdd gnd
Xbit_r0_c0 bl[0] br[0] wl[0] vdd gnd cell_6t
Xbit_r1_c0 bl[0] br[0] wl[1] vdd gnd cell_6t
Xbit_r2_c0 bl[0] br[0] wl[2] vdd gnd cell_6t
Xbit_r3_c0 bl[0] br[0] wl[3] vdd gnd cell_6t
Xbit_r4_c0 bl[0] br[0] wl[4] vdd gnd cell_6t
Xbit_r5_c0 bl[0] br[0] wl[5] vdd gnd cell_6t
Xbit_r6_c0 bl[0] br[0] wl[6] vdd gnd cell_6t
Xbit_r7_c0 bl[0] br[0] wl[7] vdd gnd cell_6t
Xbit_r8_c0 bl[0] br[0] wl[8] vdd gnd cell_6t
Xbit_r9_c0 bl[0] br[0] wl[9] vdd gnd cell_6t
Xbit_r10_c0 bl[0] br[0] wl[10] vdd gnd cell_6t
Xbit_r11_c0 bl[0] br[0] wl[11] vdd gnd cell_6t
Xbit_r12_c0 bl[0] br[0] wl[12] vdd gnd cell_6t
Xbit_r13_c0 bl[0] br[0] wl[13] vdd gnd cell_6t
Xbit_r14_c0 bl[0] br[0] wl[14] vdd gnd cell_6t
Xbit_r15_c0 bl[0] br[0] wl[15] vdd gnd cell_6t
Xbit_r0_c1 bl[1] br[1] wl[0] vdd gnd cell_6t
Xbit_r1_c1 bl[1] br[1] wl[1] vdd gnd cell_6t
Xbit_r2_c1 bl[1] br[1] wl[2] vdd gnd cell_6t
Xbit_r3_c1 bl[1] br[1] wl[3] vdd gnd cell_6t
Xbit_r4_c1 bl[1] br[1] wl[4] vdd gnd cell_6t
Xbit_r5_c1 bl[1] br[1] wl[5] vdd gnd cell_6t
Xbit_r6_c1 bl[1] br[1] wl[6] vdd gnd cell_6t
Xbit_r7_c1 bl[1] br[1] wl[7] vdd gnd cell_6t
Xbit_r8_c1 bl[1] br[1] wl[8] vdd gnd cell_6t
Xbit_r9_c1 bl[1] br[1] wl[9] vdd gnd cell_6t
Xbit_r10_c1 bl[1] br[1] wl[10] vdd gnd cell_6t
Xbit_r11_c1 bl[1] br[1] wl[11] vdd gnd cell_6t
Xbit_r12_c1 bl[1] br[1] wl[12] vdd gnd cell_6t
Xbit_r13_c1 bl[1] br[1] wl[13] vdd gnd cell_6t
Xbit_r14_c1 bl[1] br[1] wl[14] vdd gnd cell_6t
Xbit_r15_c1 bl[1] br[1] wl[15] vdd gnd cell_6t
.ENDS bitcell_array
.SUBCKT lower_pmos44 D G S B
Mpmos D G S B p m=1 w=1.2u l=0.6u
.ENDS lower_pmos44
.SUBCKT upper_pmos45 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS upper_pmos45
.SUBCKT precharge_cell bl br clk vdd
Xlower_pmos bl clk br vdd lower_pmos44
Xupper_pmos1 bl clk vdd vdd upper_pmos45
Xupper_pmos2 br clk vdd vdd upper_pmos45
.ENDS precharge_cell
.SUBCKT precharge_array bl[0] br[0] bl[1] br[1] clk vdd
Xpre_column_0 bl[0] br[0] clk vdd precharge_cell
Xpre_column_1 bl[1] br[1] clk vdd precharge_cell
.ENDS precharge_array
*********************** "sense_amp" ******************************
.SUBCKT sense_amp bl br dout sclk vdd gnd
M_1 dout net_1 vdd vdd p W='5.4*1u' L=0.6u
M_2 dout net_1 net_2 gnd n W='2.7*1u' L=0.6u
M_3 net_1 dout vdd vdd p W='5.4*1u' L=0.6u
M_4 net_1 dout net_2 gnd n W='2.7*1u' L=0.6u
M_5 bl sclk dout vdd p W='7.2*1u' L=0.6u
M_6 br sclk net_1 vdd p W='7.2*1u' L=0.6u
M_7 net_2 sclk gnd gnd n W='2.7*1u' L=0.6u
.ENDS sense_amp
.SUBCKT sense_amp_array bl[0] br[0] bl[1] br[1] data_out[0] data_out[1] sclk vdd gnd
Xsa_d0 bl[0] br[0] data_out[0] sclk vdd gnd sense_amp
Xsa_d1 bl[1] br[1] data_out[1] sclk vdd gnd sense_amp
.ENDS sense_amp_array
*********************** Write_Driver ******************************
.SUBCKT write_driver din bl br wen vdd gnd
**** Inverter to conver Data_in to data_in_bar ******
M_1 net_3 din gnd gnd n W='1.2*1u' L=0.6u
M_2 net_3 din vdd vdd p W='2.1*1u' L=0.6u
**** 2input nand gate follwed by inverter to drive BL ******
M_3 net_2 wen net_7 gnd n W='2.1*1u' L=0.6u
M_4 net_7 din gnd gnd n W='2.1*1u' L=0.6u
M_5 net_2 wen vdd vdd p W='2.1*1u' L=0.6u
M_6 net_2 din vdd vdd p W='2.1*1u' L=0.6u
M_7 net_1 net_2 vdd vdd p W='2.1*1u' L=0.6u
M_8 net_1 net_2 gnd gnd n W='1.2*1u' L=0.6u
**** 2input nand gate follwed by inverter to drive BR******
M_9 net_4 wen vdd vdd p W='2.1*1u' L=0.6u
M_10 net_4 wen net_8 gnd n W='2.1*1u' L=0.6u
M_11 net_8 net_3 gnd gnd n W='2.1*1u' L=0.6u
M_12 net_4 net_3 vdd vdd p W='2.1*1u' L=0.6u
M_13 net_6 net_4 vdd vdd p W='2.1*1u' L=0.6u
M_14 net_6 net_4 gnd gnd n W='1.2*1u' L=0.6u
************************************************
M_15 bl net_6 net_5 gnd n W='3.6*1u' L=0.6u
M_16 br net_1 net_5 gnd n W='3.6*1u' L=0.6u
M_17 net_5 wen gnd gnd n W='3.6*1u' L=0.6u
.ENDS $ write_driver
.SUBCKT write_driver_array data_in[0] data_in[1] bl[0] br[0] bl[1] br[1] wen vdd gnd
XXwrite_driver0 data_in[0] bl[0] br[0] wen vdd gnd write_driver
XXwrite_driver1 data_in[1] bl[1] br[1] wen vdd gnd write_driver
.ENDS write_driver_array
.SUBCKT inv_nmos147 D G S B
Mnmos D G S B n m=1 w=1.2u l=0.6u
.ENDS inv_nmos147
.SUBCKT inv_pmos148 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS inv_pmos148
.SUBCKT INVERTER A Z vdd gnd
Xpinv_nmos Z A gnd gnd inv_nmos147
Xpinv_pmos Z A vdd vdd inv_pmos148
.ENDS INVERTER
.SUBCKT nand_2_nmos149 D G S B
Mnmos D G S B n m=1 w=2.4u l=0.6u
.ENDS nand_2_nmos149
.SUBCKT nand_2_nmos250 D G S B
Mnmos D G S B n m=1 w=2.4u l=0.6u
.ENDS nand_2_nmos250
.SUBCKT nand_2_pmos151 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS nand_2_pmos151
.SUBCKT nand_2_pmos252 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS nand_2_pmos252
.SUBCKT NAND2 A B Z vdd gnd
Xnmos1 Z A net1 gnd nand_2_nmos149
Xnmos2 net1 B gnd gnd nand_2_nmos250
Xpmos1 vdd A Z vdd nand_2_pmos151
Xpmos2 Z B vdd vdd nand_2_pmos252
.ENDS NAND2
.SUBCKT nand_2_nmos159 D G S B
Mnmos D G S B n m=1 w=2.4u l=0.6u
.ENDS nand_2_nmos159
.SUBCKT nand_2_nmos260 D G S B
Mnmos D G S B n m=1 w=2.4u l=0.6u
.ENDS nand_2_nmos260
.SUBCKT nand_2_pmos161 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS nand_2_pmos161
.SUBCKT nand_2_pmos262 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS nand_2_pmos262
.SUBCKT a_nand_2 A B Z vdd gnd
Xnmos1 Z A net1 gnd nand_2_nmos159
Xnmos2 net1 B gnd gnd nand_2_nmos260
Xpmos1 vdd A Z vdd nand_2_pmos161
Xpmos2 Z B vdd vdd nand_2_pmos262
.ENDS a_nand_2
.SUBCKT inv_nmos163 D G S B
Mnmos D G S B n m=1 w=1.2u l=0.6u
.ENDS inv_nmos163
.SUBCKT inv_pmos164 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS inv_pmos164
.SUBCKT a_inv_1 A Z vdd gnd
Xpinv_nmos Z A gnd gnd inv_nmos163
Xpinv_pmos Z A vdd vdd inv_pmos164
.ENDS a_inv_1
.SUBCKT pre2x4 A[0] A[1] out[0] out[1] out[2] out[3] vdd gnd
XXpre2x4_inv[0] A[0] B[0] vdd gnd a_inv_1
XXpre2x4_inv[1] A[1] B[1] vdd gnd a_inv_1
XXpre2x4_nand_inv[0] Z[0] out[0] vdd gnd a_inv_1
XXpre2x4_nand_inv[1] Z[1] out[1] vdd gnd a_inv_1
XXpre2x4_nand_inv[2] Z[2] out[2] vdd gnd a_inv_1
XXpre2x4_nand_inv[3] Z[3] out[3] vdd gnd a_inv_1
XXpre2x4_nand[0] A[0] A[1] Z[3] vdd gnd a_nand_2
XXpre2x4_nand[1] B[0] A[1] Z[2] vdd gnd a_nand_2
XXpre2x4_nand[2] A[0] B[1] Z[1] vdd gnd a_nand_2
XXpre2x4_nand[3] B[0] B[1] Z[0] vdd gnd a_nand_2
.ENDS pre2x4
.SUBCKT nand_3_nmos165 D G S B
Mnmos D G S B n m=1 w=3.6u l=0.6u
.ENDS nand_3_nmos165
.SUBCKT nand_3_nmos266 D G S B
Mnmos D G S B n m=1 w=3.6u l=0.6u
.ENDS nand_3_nmos266
.SUBCKT nand_3_nmos367 D G S B
Mnmos D G S B n m=1 w=3.6u l=0.6u
.ENDS nand_3_nmos367
.SUBCKT nand_3_pmos168 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS nand_3_pmos168
.SUBCKT nand_3_pmos269 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS nand_3_pmos269
.SUBCKT nand_3_pmos370 D G S B
Mpmos D G S B p m=1 w=2.4u l=0.6u
.ENDS nand_3_pmos370
.SUBCKT a_nand_3 A B C Z vdd gnd
Xnmos1 net2 A gnd gnd nand_3_nmos165
Xnmos2 net1 B net2 gnd nand_3_nmos266
Xnmos3 Z C net1 gnd nand_3_nmos367
Xpmos1 Z A vdd vdd nand_3_pmos168
Xpmos2 vdd B Z vdd nand_3_pmos269
Xpmos3 Z C vdd vdd nand_3_pmos370
.ENDS a_nand_3
.SUBCKT pre3x8 A[0] A[1] A[2] out[0] out[1] out[2] out[3] out[4] out[5] out[6] out[7] vdd gnd
XXpre2x4_inv[0] A[0] B[0] vdd gnd a_inv_1
XXpre2x4_inv[1] A[1] B[1] vdd gnd a_inv_1
XXpre2x4_inv[2] A[2] B[2] vdd gnd a_inv_1
XXpre2x4_nand_inv[0] Z[0] out[0] vdd gnd a_inv_1
XXpre2x4_nand_inv[1] Z[1] out[1] vdd gnd a_inv_1
XXpre2x4_nand_inv[2] Z[2] out[2] vdd gnd a_inv_1
XXpre2x4_nand_inv[3] Z[3] out[3] vdd gnd a_inv_1
XXpre2x4_nand_inv[4] Z[4] out[4] vdd gnd a_inv_1
XXpre2x4_nand_inv[5] Z[5] out[5] vdd gnd a_inv_1
XXpre2x4_nand_inv[6] Z[6] out[6] vdd gnd a_inv_1
XXpre2x4_nand_inv[7] Z[7] out[7] vdd gnd a_inv_1
XXpre3x8_nand[0] A[0] A[1] A[2] Z[7] vdd gnd a_nand_3
XXpre3x8_nand[1] A[0] A[1] B[2] Z[6] vdd gnd a_nand_3
XXpre3x8_nand[2] A[0] B[1] A[2] Z[5] vdd gnd a_nand_3
XXpre3x8_nand[3] A[0] B[1] B[2] Z[4] vdd gnd a_nand_3
XXpre3x8_nand[4] B[0] A[1] A[2] Z[3] vdd gnd a_nand_3
XXpre3x8_nand[5] B[0] A[1] B[2] Z[2] vdd gnd a_nand_3
XXpre3x8_nand[6] B[0] B[1] A[2] Z[1] vdd gnd a_nand_3
XXpre3x8_nand[7] B[0] B[1] B[2] Z[0] vdd gnd a_nand_3
.ENDS pre3x8
.SUBCKT hierarchical_decoder A[0] A[1] A[2] A[3] decode_out[0] decode_out[1] decode_out[2] decode_out[3] decode_out[4] decode_out[5] decode_out[6] decode_out[7] decode_out[8] decode_out[9] decode_out[10] decode_out[11] decode_out[12] decode_out[13] decode_out[14] decode_out[15] vdd gnd
Xpre[0] A[0] A[1] out[0] out[1] out[2] out[3] vdd gnd pre2x4
Xpre[1] A[2] A[3] out[4] out[5] out[6] out[7] vdd gnd pre2x4
XNAND2_[0] out[0] out[4] Z[0] vdd gnd NAND2
XNAND2_[1] out[0] out[5] Z[1] vdd gnd NAND2
XNAND2_[2] out[0] out[6] Z[2] vdd gnd NAND2
XNAND2_[3] out[0] out[7] Z[3] vdd gnd NAND2
XNAND2_[4] out[1] out[4] Z[4] vdd gnd NAND2
XNAND2_[5] out[1] out[5] Z[5] vdd gnd NAND2
XNAND2_[6] out[1] out[6] Z[6] vdd gnd NAND2
XNAND2_[7] out[1] out[7] Z[7] vdd gnd NAND2
XNAND2_[8] out[2] out[4] Z[8] vdd gnd NAND2
XNAND2_[9] out[2] out[5] Z[9] vdd gnd NAND2
XNAND2_[10] out[2] out[6] Z[10] vdd gnd NAND2
XNAND2_[11] out[2] out[7] Z[11] vdd gnd NAND2
XNAND2_[12] out[3] out[4] Z[12] vdd gnd NAND2
XNAND2_[13] out[3] out[5] Z[13] vdd gnd NAND2
XNAND2_[14] out[3] out[6] Z[14] vdd gnd NAND2
XNAND2_[15] out[3] out[7] Z[15] vdd gnd NAND2
XINVERTER_[0] Z[0] decode_out[0] vdd gnd INVERTER
XINVERTER_[1] Z[1] decode_out[1] vdd gnd INVERTER
XINVERTER_[2] Z[2] decode_out[2] vdd gnd INVERTER
XINVERTER_[3] Z[3] decode_out[3] vdd gnd INVERTER
XINVERTER_[4] Z[4] decode_out[4] vdd gnd INVERTER
XINVERTER_[5] Z[5] decode_out[5] vdd gnd INVERTER
XINVERTER_[6] Z[6] decode_out[6] vdd gnd INVERTER
XINVERTER_[7] Z[7] decode_out[7] vdd gnd INVERTER
XINVERTER_[8] Z[8] decode_out[8] vdd gnd INVERTER
XINVERTER_[9] Z[9] decode_out[9] vdd gnd INVERTER
XINVERTER_[10] Z[10] decode_out[10] vdd gnd INVERTER
XINVERTER_[11] Z[11] decode_out[11] vdd gnd INVERTER
XINVERTER_[12] Z[12] decode_out[12] vdd gnd INVERTER
XINVERTER_[13] Z[13] decode_out[13] vdd gnd INVERTER
XINVERTER_[14] Z[14] decode_out[14] vdd gnd INVERTER
XINVERTER_[15] Z[15] decode_out[15] vdd gnd INVERTER
.ENDS hierarchical_decoder
.SUBCKT msf_address ADDR[0] ADDR[1] ADDR[2] ADDR[3] A[0] A_bar[0] A[1] A_bar[1] A[2] A_bar[2] A[3] A_bar[3] addr_clk vdd gnd
XXdff0 ADDR[0] A[0] A_bar[0] addr_clk vdd gnd ms_flop
XXdff1 ADDR[1] A[1] A_bar[1] addr_clk vdd gnd ms_flop
XXdff2 ADDR[2] A[2] A_bar[2] addr_clk vdd gnd ms_flop
XXdff3 ADDR[3] A[3] A_bar[3] addr_clk vdd gnd ms_flop
.ENDS msf_address
.SUBCKT msf_data_in DATA[0] DATA[1] data_in[0] data_in_bar[0] data_in[1] data_in_bar[1] clk vdd gnd
XXdff0 DATA[0] data_in[0] data_in_bar[0] clk vdd gnd ms_flop
XXdff1 DATA[1] data_in[1] data_in_bar[1] clk vdd gnd ms_flop
.ENDS msf_data_in
.SUBCKT msf_data_out data_out[0] data_out[1] tri_in[0] tri_in_bar[0] tri_in[1] tri_in_bar[1] sclk vdd gnd
XXdff0 data_out[0] tri_in[0] tri_in_bar[0] sclk vdd gnd ms_flop
XXdff1 data_out[1] tri_in[1] tri_in_bar[1] sclk vdd gnd ms_flop
.ENDS msf_data_out
*********************** tri_gate ******************************
.SUBCKT tri_gate in out en en_bar vdd gnd
M_1 net_2 in_inv gnd gnd n W='1.2*1u' L=0.6u
M_2 net_3 in_inv vdd vdd p W='2.4*1u' L=0.6u
M_3 out en_bar net_3 vdd p W='2.4*1u' L=0.6u
M_4 out en net_2 gnd n W='1.2*1u' L=0.6u
M_5 in_inv in vdd vdd p W='2.4*1u' L=0.6u
M_6 in_inv in gnd gnd n W='1.2*1u' L=0.6u
.ENDS
.SUBCKT tri_gate_array tri_in[0] tri_in[1] DATA[0] DATA[1] en en_bar vdd gnd
XXtri_gate0 tri_in[0] DATA[0] en en_bar vdd gnd tri_gate
XXtri_gate1 tri_in[1] DATA[1] en en_bar vdd gnd tri_gate
.ENDS tri_gate_array
.SUBCKT wordline_driver decode_out[0] decode_out[1] decode_out[2] decode_out[3] decode_out[4] decode_out[5] decode_out[6] decode_out[7] decode_out[8] decode_out[9] decode_out[10] decode_out[11] decode_out[12] decode_out[13] decode_out[14] decode_out[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] clk vdd gnd
XWordline_driver_inv_clk0 clk clk_bar[0] vdd gnd INVERTER
XWordline_driver_nand0 decode_out[0] clk_bar[0] net[0] vdd gnd NAND2
XWordline_driver_inv0 net[0] wl[0] vdd gnd INVERTER
XWordline_driver_inv_clk1 clk clk_bar[1] vdd gnd INVERTER
XWordline_driver_nand1 decode_out[1] clk_bar[1] net[1] vdd gnd NAND2
XWordline_driver_inv1 net[1] wl[1] vdd gnd INVERTER
XWordline_driver_inv_clk2 clk clk_bar[2] vdd gnd INVERTER
XWordline_driver_nand2 decode_out[2] clk_bar[2] net[2] vdd gnd NAND2
XWordline_driver_inv2 net[2] wl[2] vdd gnd INVERTER
XWordline_driver_inv_clk3 clk clk_bar[3] vdd gnd INVERTER
XWordline_driver_nand3 decode_out[3] clk_bar[3] net[3] vdd gnd NAND2
XWordline_driver_inv3 net[3] wl[3] vdd gnd INVERTER
XWordline_driver_inv_clk4 clk clk_bar[4] vdd gnd INVERTER
XWordline_driver_nand4 decode_out[4] clk_bar[4] net[4] vdd gnd NAND2
XWordline_driver_inv4 net[4] wl[4] vdd gnd INVERTER
XWordline_driver_inv_clk5 clk clk_bar[5] vdd gnd INVERTER
XWordline_driver_nand5 decode_out[5] clk_bar[5] net[5] vdd gnd NAND2
XWordline_driver_inv5 net[5] wl[5] vdd gnd INVERTER
XWordline_driver_inv_clk6 clk clk_bar[6] vdd gnd INVERTER
XWordline_driver_nand6 decode_out[6] clk_bar[6] net[6] vdd gnd NAND2
XWordline_driver_inv6 net[6] wl[6] vdd gnd INVERTER
XWordline_driver_inv_clk7 clk clk_bar[7] vdd gnd INVERTER
XWordline_driver_nand7 decode_out[7] clk_bar[7] net[7] vdd gnd NAND2
XWordline_driver_inv7 net[7] wl[7] vdd gnd INVERTER
XWordline_driver_inv_clk8 clk clk_bar[8] vdd gnd INVERTER
XWordline_driver_nand8 decode_out[8] clk_bar[8] net[8] vdd gnd NAND2
XWordline_driver_inv8 net[8] wl[8] vdd gnd INVERTER
XWordline_driver_inv_clk9 clk clk_bar[9] vdd gnd INVERTER
XWordline_driver_nand9 decode_out[9] clk_bar[9] net[9] vdd gnd NAND2
XWordline_driver_inv9 net[9] wl[9] vdd gnd INVERTER
XWordline_driver_inv_clk10 clk clk_bar[10] vdd gnd INVERTER
XWordline_driver_nand10 decode_out[10] clk_bar[10] net[10] vdd gnd NAND2
XWordline_driver_inv10 net[10] wl[10] vdd gnd INVERTER
XWordline_driver_inv_clk11 clk clk_bar[11] vdd gnd INVERTER
XWordline_driver_nand11 decode_out[11] clk_bar[11] net[11] vdd gnd NAND2
XWordline_driver_inv11 net[11] wl[11] vdd gnd INVERTER
XWordline_driver_inv_clk12 clk clk_bar[12] vdd gnd INVERTER
XWordline_driver_nand12 decode_out[12] clk_bar[12] net[12] vdd gnd NAND2
XWordline_driver_inv12 net[12] wl[12] vdd gnd INVERTER
XWordline_driver_inv_clk13 clk clk_bar[13] vdd gnd INVERTER
XWordline_driver_nand13 decode_out[13] clk_bar[13] net[13] vdd gnd NAND2
XWordline_driver_inv13 net[13] wl[13] vdd gnd INVERTER
XWordline_driver_inv_clk14 clk clk_bar[14] vdd gnd INVERTER
XWordline_driver_nand14 decode_out[14] clk_bar[14] net[14] vdd gnd NAND2
XWordline_driver_inv14 net[14] wl[14] vdd gnd INVERTER
XWordline_driver_inv_clk15 clk clk_bar[15] vdd gnd INVERTER
XWordline_driver_nand15 decode_out[15] clk_bar[15] net[15] vdd gnd NAND2
XWordline_driver_inv15 net[15] wl[15] vdd gnd INVERTER
.ENDS wordline_driver
.SUBCKT inv_nmos181 D G S B
Mnmos D G S B n m=4 w=1.2u l=0.6u
.ENDS inv_nmos181
.SUBCKT inv_pmos182 D G S B
Mpmos D G S B p m=4 w=2.4u l=0.6u
.ENDS inv_pmos182
.SUBCKT pinv4x A Z vdd gnd
Xpinv_nmos Z A gnd gnd inv_nmos181
Xpinv_pmos Z A vdd vdd inv_pmos182
.ENDS pinv4x
.SUBCKT nor_2_nmos195 D G S B
Mnmos D G S B n m=1 w=1.2u l=0.6u
.ENDS nor_2_nmos195
.SUBCKT nor_2_nmos296 D G S B
Mnmos D G S B n m=1 w=1.2u l=0.6u
.ENDS nor_2_nmos296
.SUBCKT nor_2_pmos197 D G S B
Mpmos D G S B p m=4 w=1.2u l=0.6u
.ENDS nor_2_pmos197
.SUBCKT nor_2_pmos298 D G S B
Mpmos D G S B p m=4 w=1.2u l=0.6u
.ENDS nor_2_pmos298
.SUBCKT NOR2 A B Z vdd gnd
Xnmos1 Z A gnd gnd nor_2_nmos195
Xnmos2 Z B gnd gnd nor_2_nmos296
Xpmos1 vdd A net1 vdd nor_2_pmos197
Xpmos2 net1 B Z vdd nor_2_pmos298
.ENDS NOR2
.SUBCKT test_bank1 DATA[0] DATA[1] ADDR[0] ADDR[1] ADDR[2] ADDR[3] s_en w_en tri_en_bar tri_en clk_bar clk vdd gnd
Xbitcell_array bl[0] br[0] bl[1] br[1] 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] vdd gnd bitcell_array
Xprecharge_array bl[0] br[0] bl[1] br[1] clk_bar vdd precharge_array
Xsense_amp_array bl[0] br[0] bl[1] br[1] data_out[0] data_out[1] s_en vdd gnd sense_amp_array
Xwrite_driver_array data_in[0] data_in[1] bl[0] br[0] bl[1] br[1] w_en vdd gnd write_driver_array
Xdata_in_flop_array DATA[0] DATA[1] data_in[0] data_in_bar[0] data_in[1] data_in_bar[1] clk_bar vdd gnd msf_data_in
Xtrigate_data_array data_out[0] data_out[1] DATA[0] DATA[1] tri_en tri_en_bar vdd gnd tri_gate_array
Xaddress_decoder A[0] A[1] A[2] A[3] decode_out[0] decode_out[1] decode_out[2] decode_out[3] decode_out[4] decode_out[5] decode_out[6] decode_out[7] decode_out[8] decode_out[9] decode_out[10] decode_out[11] decode_out[12] decode_out[13] decode_out[14] decode_out[15] vdd gnd hierarchical_decoder
Xwordline_driver decode_out[0] decode_out[1] decode_out[2] decode_out[3] decode_out[4] decode_out[5] decode_out[6] decode_out[7] decode_out[8] decode_out[9] decode_out[10] decode_out[11] decode_out[12] decode_out[13] decode_out[14] decode_out[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] clk vdd gnd wordline_driver
Xaddress_flop_array ADDR[0] ADDR[1] ADDR[2] ADDR[3] A[0] A_bar[0] A[1] A_bar[1] A[2] A_bar[2] A[3] A_bar[3] clk vdd gnd msf_address
.ENDS test_bank1
.SUBCKT testsram DATA[0] DATA[1] ADDR[0] ADDR[1] ADDR[2] ADDR[3] CSb WEb OEb clk vdd gnd
Xbank0 DATA[0] DATA[1] ADDR[0] ADDR[1] ADDR[2] ADDR[3] s_en w_en tri_en_bar tri_en clk_bar clk vdd gnd test_bank1
Xcontrol CSb WEb OEb s_en w_en tri_en tri_en_bar clk_bar clk vdd gnd control_logic
.ENDS testsram

View File

@ -1,47 +0,0 @@
// OpenRAM SRAM model
// Words: 16
// Word size: 2
module sram_2_16_1_scn3me_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

View File

@ -1,319 +0,0 @@
library (sram_2_16_1_scn3me_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_1_scn3me_subm){
memory(){
type : ram;
address_width : 4;
word_width : 2;
}
interface_timing : true;
dont_use : true;
map_only : true;
dont_touch : true;
area : 142800.38999999998;
leakage_power () {
when : "CSb";
value : 0.0252988;
}
cell_leakage_power : 0;
bus(DIN){
bus_type : DATA;
direction : input;
capacitance : 9.8242;
memory_write(){
address : ADDR;
clocked_on : clk;
}
}
bus(DOUT){
bus_type : DATA;
direction : output;
max_capacitance : 78.5936;
min_capacitance : 2.45605;
memory_read(){
address : ADDR;
}
pin(DOUT[1:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027");
}
}
timing(){
timing_type : hold_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009");
}
fall_constraint(CONSTRAINT_TABLE) {
values("-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132");
}
}
timing(){
timing_sense : non_unate;
related_pin : "clk";
timing_type : rising_edge;
cell_rise(CELL_TABLE) {
values("0.945, 0.976, 1.139",\
"0.948, 0.98, 1.143",\
"1.003, 1.036, 1.202");
}
cell_fall(CELL_TABLE) {
values("11.211, 11.266, 11.754",\
"11.212, 11.267, 11.755",\
"11.264, 11.319, 11.806");
}
rise_transition(CELL_TABLE) {
values("0.605, 0.629, 0.98",\
"0.605, 0.629, 0.979",\
"0.604, 0.628, 0.973");
}
fall_transition(CELL_TABLE) {
values("11.17, 11.175, 1.284",\
"11.167, 11.173, 1.284",\
"11.173, 11.179, 11.473");
}
}
}
}
bus(ADDR){
bus_type : ADDR;
direction : input;
capacitance : 9.8242;
max_transition : 0.4;
pin(ADDR[3:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027");
}
}
timing(){
timing_type : hold_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009");
}
fall_constraint(CONSTRAINT_TABLE) {
values("-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132");
}
}
}
}
pin(CSb){
direction : input;
capacitance : 9.8242;
timing(){
timing_type : setup_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027");
}
}
timing(){
timing_type : hold_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009");
}
fall_constraint(CONSTRAINT_TABLE) {
values("-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132");
}
}
}
pin(WEb){
direction : input;
capacitance : 9.8242;
timing(){
timing_type : setup_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027");
}
}
timing(){
timing_type : hold_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009");
}
fall_constraint(CONSTRAINT_TABLE) {
values("-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132");
}
}
}
pin(clk){
clock : true;
direction : input;
capacitance : 9.8242;
internal_power(){
when : "!CSb & clk & !WEb";
rise_power(scalar){
values("2.1762222222222225");
}
fall_power(scalar){
values("2.1762222222222225");
}
}
internal_power(){
when : "!CSb & !clk & WEb";
rise_power(scalar){
values("2.167955555555556");
}
fall_power(scalar){
values("2.167955555555556");
}
}
internal_power(){
when : "CSb";
rise_power(scalar){
values("0");
}
fall_power(scalar){
values("0");
}
}
timing(){
timing_type :"min_pulse_width";
related_pin : clk;
rise_constraint(scalar) {
values("9.6875");
}
fall_constraint(scalar) {
values("9.6875");
}
}
timing(){
timing_type :"minimum_period";
related_pin : clk;
rise_constraint(scalar) {
values("19.375");
}
fall_constraint(scalar) {
values("19.375");
}
}
}
}
}

View File

@ -1,319 +0,0 @@
library (sram_2_16_1_scn3me_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_1_scn3me_subm){
memory(){
type : ram;
address_width : 4;
word_width : 2;
}
interface_timing : true;
dont_use : true;
map_only : true;
dont_touch : true;
area : 142800.38999999998;
leakage_power () {
when : "CSb";
value : 0.000168;
}
cell_leakage_power : 0;
bus(DIN){
bus_type : DATA;
direction : input;
capacitance : 9.8242;
memory_write(){
address : ADDR0;
clocked_on : clk;
}
}
bus(DOUT){
bus_type : DATA;
direction : output;
max_capacitance : 78.5936;
min_capacitance : 2.45605;
memory_read(){
address : ADDR0;
}
pin(DOUT[1:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk";
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 : "clk";
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");
}
}
timing(){
timing_sense : non_unate;
related_pin : "clk";
timing_type : rising_edge;
cell_rise(CELL_TABLE) {
values("0.54, 0.587, 1.028",\
"0.54, 0.587, 1.028",\
"0.54, 0.587, 1.028");
}
cell_fall(CELL_TABLE) {
values("0.54, 0.587, 1.028",\
"0.54, 0.587, 1.028",\
"0.54, 0.587, 1.028");
}
rise_transition(CELL_TABLE) {
values("0.024, 0.081, 0.61",\
"0.024, 0.081, 0.61",\
"0.024, 0.081, 0.61");
}
fall_transition(CELL_TABLE) {
values("0.024, 0.081, 0.61",\
"0.024, 0.081, 0.61",\
"0.024, 0.081, 0.61");
}
}
}
}
bus(ADDR){
bus_type : ADDR;
direction : input;
capacitance : 9.8242;
max_transition : 0.4;
pin(ADDR[3:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk";
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 : "clk";
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(CSb){
direction : input;
capacitance : 9.8242;
timing(){
timing_type : setup_rising;
related_pin : "clk";
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 : "clk";
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(WEb){
direction : input;
capacitance : 9.8242;
timing(){
timing_type : setup_rising;
related_pin : "clk";
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 : "clk";
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(clk){
clock : true;
direction : input;
capacitance : 9.8242;
internal_power(){
when : "!CSb & clk & !WEb";
rise_power(scalar){
values("10.559086132533329");
}
fall_power(scalar){
values("10.559086132533329");
}
}
internal_power(){
when : "!CSb & !clk & WEb";
rise_power(scalar){
values("10.559086132533329");
}
fall_power(scalar){
values("10.559086132533329");
}
}
internal_power(){
when : "CSb";
rise_power(scalar){
values("0");
}
fall_power(scalar){
values("0");
}
}
timing(){
timing_type :"min_pulse_width";
related_pin : clk;
rise_constraint(scalar) {
values("0.0");
}
fall_constraint(scalar) {
values("0.0");
}
}
timing(){
timing_type :"minimum_period";
related_pin : clk;
rise_constraint(scalar) {
values("0");
}
fall_constraint(scalar) {
values("0");
}
}
}
}
}

View File

@ -1,319 +0,0 @@
library (sram_2_16_1_scn3me_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_1_scn3me_subm){
memory(){
type : ram;
address_width : 4;
word_width : 2;
}
interface_timing : true;
dont_use : true;
map_only : true;
dont_touch : true;
area : 142800.38999999998;
leakage_power () {
when : "CSb";
value : 0.0252988;
}
cell_leakage_power : 0;
bus(DIN){
bus_type : DATA;
direction : input;
capacitance : 9.8242;
memory_write(){
address : ADDR;
clocked_on : clk;
}
}
bus(DOUT){
bus_type : DATA;
direction : output;
max_capacitance : 78.5936;
min_capacitance : 2.45605;
memory_read(){
address : ADDR;
}
pin(DOUT[1:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027");
}
}
timing(){
timing_type : hold_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009");
}
fall_constraint(CONSTRAINT_TABLE) {
values("-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132");
}
}
timing(){
timing_sense : non_unate;
related_pin : "clk";
timing_type : rising_edge;
cell_rise(CELL_TABLE) {
values("0.928, 0.959, 1.113",\
"0.931, 0.962, 1.116",\
"0.985, 1.018, 1.176");
}
cell_fall(CELL_TABLE) {
values("11.214, 11.27, 11.756",\
"11.22, 11.27, 11.761",\
"11.268, 11.323, 11.809");
}
rise_transition(CELL_TABLE) {
values("0.599, 0.624, 0.968",\
"0.599, 0.623, 0.97",\
"0.598, 0.623, 0.967");
}
fall_transition(CELL_TABLE) {
values("11.157, 11.165, 11.446",\
"11.159, 11.162, 1.271",\
"11.158, 11.165, 11.47");
}
}
}
}
bus(ADDR){
bus_type : ADDR;
direction : input;
capacitance : 9.8242;
max_transition : 0.4;
pin(ADDR[3:0]){
timing(){
timing_type : setup_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027");
}
}
timing(){
timing_type : hold_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009");
}
fall_constraint(CONSTRAINT_TABLE) {
values("-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132");
}
}
}
}
pin(CSb){
direction : input;
capacitance : 9.8242;
timing(){
timing_type : setup_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027");
}
}
timing(){
timing_type : hold_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009");
}
fall_constraint(CONSTRAINT_TABLE) {
values("-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132");
}
}
}
pin(WEb){
direction : input;
capacitance : 9.8242;
timing(){
timing_type : setup_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149",\
"0.076, 0.076, 0.149");
}
fall_constraint(CONSTRAINT_TABLE) {
values("0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027",\
"0.033, 0.039, 0.027");
}
}
timing(){
timing_type : hold_rising;
related_pin : "clk";
rise_constraint(CONSTRAINT_TABLE) {
values("-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009",\
"-0.004, -0.004, 0.009");
}
fall_constraint(CONSTRAINT_TABLE) {
values("-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132",\
"-0.052, -0.059, -0.132");
}
}
}
pin(clk){
clock : true;
direction : input;
capacitance : 9.8242;
internal_power(){
when : "!CSb & clk & !WEb";
rise_power(scalar){
values("2.033783461111111");
}
fall_power(scalar){
values("2.033783461111111");
}
}
internal_power(){
when : "!CSb & !clk & WEb";
rise_power(scalar){
values("2.032705683333334");
}
fall_power(scalar){
values("2.032705683333334");
}
}
internal_power(){
when : "CSb";
rise_power(scalar){
values("0");
}
fall_power(scalar){
values("0");
}
}
timing(){
timing_type :"min_pulse_width";
related_pin : clk;
rise_constraint(scalar) {
values("9.6875");
}
fall_constraint(scalar) {
values("9.6875");
}
}
timing(){
timing_type :"minimum_period";
related_pin : clk;
rise_constraint(scalar) {
values("19.375");
}
fall_constraint(scalar) {
values("19.375");
}
}
}
}
}

View File

@ -2,46 +2,60 @@
// Words: 16 // Words: 16
// Word size: 2 // Word size: 2
module sram_2_16_1_scn4m_subm(DATA,ADDR,CSb,WEb,OEb,clk); module sram_2_16_1_scn4m_subm(
// Port 0: RW
clk0,csb0,web0,ADDR0,DIN0,DOUT0
);
parameter DATA_WIDTH = 2 ; parameter DATA_WIDTH = 2 ;
parameter ADDR_WIDTH = 4 ; parameter ADDR_WIDTH = 4 ;
parameter RAM_DEPTH = 1 << ADDR_WIDTH; parameter RAM_DEPTH = 1 << ADDR_WIDTH;
// FIXME: This delay is arbitrary.
parameter DELAY = 3 ; parameter DELAY = 3 ;
inout [DATA_WIDTH-1:0] DATA; input clk0; // clock
input [ADDR_WIDTH-1:0] ADDR; input csb0; // active low chip select
input CSb; // active low chip select input web0; // active low write control
input WEb; // active low write control input [ADDR_WIDTH-1:0] ADDR0;
input OEb; // active output enable input [DATA_WIDTH-1:0] DIN0;
input clk; // clock output [DATA_WIDTH-1:0] DOUT0;
reg [DATA_WIDTH-1:0] data_out ; reg csb0_reg;
reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1]; reg web0_reg;
reg [ADDR_WIDTH-1:0] ADDR0_reg;
reg [DATA_WIDTH-1:0] DIN0_reg;
reg [DATA_WIDTH-1:0] DOUT0;
// Tri-State Buffer control // All inputs are registers
// output : When WEb = 1, oeb = 0, csb = 0 always @(posedge clk0)
assign DATA = (!CSb && !OEb && WEb) ? data_out : 2'bz; begin
csb0_reg = csb0;
// Memory Write Block web0_reg = web0;
// Write Operation : When WEb = 0, CSb = 0 ADDR0_reg = ADDR0;
always @ (posedge clk) DIN0_reg = DIN0;
begin : MEM_WRITE DOUT0 = 2'bx;
if ( !CSb && !WEb ) begin if ( !csb0_reg && web0_reg )
mem[ADDR] = DATA; $display($time," Reading %m ADDR0=%b DOUT0=%b",ADDR0_reg,mem[ADDR0_reg]);
$display($time," Writing %m ABUS=%b DATA=%b",ADDR,DATA); if ( !csb0_reg && !web0_reg )
end $display($time," Writing %m ADDR0=%b DIN0=%b",ADDR0_reg,DIN0_reg);
end end
reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
// Memory Read Block // Memory Write Block Port 0
// Read Operation : When WEb = 1, CSb = 0 // Write Operation : When web0 = 0, csb0 = 0
always @ (posedge clk) always @ (negedge clk0)
begin : MEM_READ begin : MEM_WRITE0
if (!CSb && WEb) begin if ( !csb0_reg && !web0_reg )
data_out <= #(DELAY) mem[ADDR]; mem[ADDR0_reg] = DIN0_reg;
$display($time," Reading %m ABUS=%b DATA=%b",ADDR,mem[ADDR]); end
end
// Memory Read Block Port 0
// Read Operation : When web0 = 1, csb0 = 0
always @ (negedge clk0)
begin : MEM_READ0
if (!csb0_reg && web0_reg)
DOUT0 <= #(DELAY) mem[ADDR0_reg];
end end
endmodule endmodule

View File

@ -93,7 +93,7 @@ cell (sram_2_16_1_scn4m_subm){
address : ADDR0; address : ADDR0;
clocked_on : clk0; clocked_on : clk0;
} }
pin(DIN0[1:0]){ pin(DIN0){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -132,11 +132,11 @@ cell (sram_2_16_1_scn4m_subm){
memory_read(){ memory_read(){
address : ADDR0; address : ADDR0;
} }
pin(DOUT0[1:0]){ pin(DOUT0){
timing(){ timing(){
timing_sense : non_unate; timing_sense : non_unate;
related_pin : "clk0"; related_pin : "clk0";
timing_type : rising_edge; timing_type : falling_edge;
cell_rise(CELL_TABLE) { cell_rise(CELL_TABLE) {
values("1.556, 1.576, 1.751",\ values("1.556, 1.576, 1.751",\
"1.559, 1.579, 1.754",\ "1.559, 1.579, 1.754",\
@ -166,7 +166,7 @@ cell (sram_2_16_1_scn4m_subm){
direction : input; direction : input;
capacitance : 9.8242; capacitance : 9.8242;
max_transition : 0.4; max_transition : 0.4;
pin(ADDR0[3:0]){ pin(ADDR0){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";

View File

@ -93,7 +93,7 @@ cell (sram_2_16_1_scn4m_subm){
address : ADDR0; address : ADDR0;
clocked_on : clk0; clocked_on : clk0;
} }
pin(DIN0[1:0]){ pin(DIN0){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -132,11 +132,11 @@ cell (sram_2_16_1_scn4m_subm){
memory_read(){ memory_read(){
address : ADDR0; address : ADDR0;
} }
pin(DOUT0[1:0]){ pin(DOUT0){
timing(){ timing(){
timing_sense : non_unate; timing_sense : non_unate;
related_pin : "clk0"; related_pin : "clk0";
timing_type : rising_edge; timing_type : falling_edge;
cell_rise(CELL_TABLE) { cell_rise(CELL_TABLE) {
values("0.268, 0.268, 0.268",\ values("0.268, 0.268, 0.268",\
"0.268, 0.268, 0.268",\ "0.268, 0.268, 0.268",\
@ -166,7 +166,7 @@ cell (sram_2_16_1_scn4m_subm){
direction : input; direction : input;
capacitance : 9.8242; capacitance : 9.8242;
max_transition : 0.4; max_transition : 0.4;
pin(ADDR0[3:0]){ pin(ADDR0){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";

View File

@ -93,7 +93,7 @@ cell (sram_2_16_1_scn4m_subm){
address : ADDR0; address : ADDR0;
clocked_on : clk0; clocked_on : clk0;
} }
pin(DIN0[1:0]){ pin(DIN0){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -132,11 +132,11 @@ cell (sram_2_16_1_scn4m_subm){
memory_read(){ memory_read(){
address : ADDR0; address : ADDR0;
} }
pin(DOUT0[1:0]){ pin(DOUT0){
timing(){ timing(){
timing_sense : non_unate; timing_sense : non_unate;
related_pin : "clk0"; related_pin : "clk0";
timing_type : rising_edge; timing_type : falling_edge;
cell_rise(CELL_TABLE) { cell_rise(CELL_TABLE) {
values("1.542, 1.562, 1.738",\ values("1.542, 1.562, 1.738",\
"1.545, 1.565, 1.741",\ "1.545, 1.565, 1.741",\
@ -166,7 +166,7 @@ cell (sram_2_16_1_scn4m_subm){
direction : input; direction : input;
capacitance : 9.8242; capacitance : 9.8242;
max_transition : 0.4; max_transition : 0.4;
pin(ADDR0[3:0]){ pin(ADDR0){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";

View File

@ -0,0 +1,143 @@
`define assert(signal, value) \
if (!(signal === value)) begin \
$display("ASSERTION FAILED in %m: signal != value"); \
$finish;\
end
module sram_1rw_1r_tb;
reg clk;
// 1rw port
reg [3:0] addr0;
reg [1:0] din0;
reg csb0;
reg web0;
wire [1:0] dout0;
// 1r port
reg [3:0] addr1;
reg csb1;
wire [1:0] dout1;
sram_1rw_1r_2_16_scn4m_subm U0 (.DIN0(din0),
.DOUT0(dout0),
.ADDR0(addr0),
.csb0(csb0),
.web0(web0),
.clk0(clk),
.DOUT1(dout1),
.ADDR1(addr1),
.csb1(csb1),
.clk1(clk)
);
initial
begin
//$monitor("%g addr0=%b din0=%b dout0=%b addr1=%b dout1=%b",
// $time, addr0, din0, dout0, addr1, dout1);
clk = 1;
csb0 = 1;
web0 = 1;
addr0 = 0;
din0 = 0;
csb1 = 1;
addr1 = 0;
// write
#10 din0=2'b10;
addr0=4'h1;
web0 = 0;
csb0 = 0;
// nop
csb1 = 1;
addr1 = 0;
// write another
#10 din0=2'b01;
addr0=4'hC;
web0 = 0;
csb0 = 0;
// read last
csb1 = 0;
addr1 = 4'h1;
#10 `assert(dout1, 2'b10)
// read undefined
din0=2'b11;
addr0=4'h0;
web0 = 1;
csb0 = 0;
// read another
csb1 = 0;
addr1 = 4'hC;
#10 `assert(dout0, 2'bxx)
`assert(dout1, 2'b01)
// read defined
din0=2'b11;
addr0=4'hC;
web0 = 1;
csb0 = 0;
// read undefined
csb1 = 0;
addr1 = 4'hD;
#10 `assert(dout0, 2'b01)
`assert(dout1, 2'bxx)
// write another
din0=2'b11;
addr0=4'hA;
web0 = 0;
csb0 = 0;
// read the feedthrough value
csb1 = 0;
addr1 = 4'hA;
#10 `assert(dout1, 2'b11)
// read defined
din0=2'b11;
addr0=4'h1;
web0 = 1;
csb0 = 0;
// read old value
csb1 = 0;
addr1 = 4'h1;
#10 `assert(dout0, 2'b10)
`assert(dout1, 2'b10)
// read defined
din0=2'b11;
addr0=4'hA;
web0 = 1;
csb0 = 0;
// dual read
csb1 = 0;
addr1 = 4'hA;
#10 `assert(dout0, 2'b11)
`assert(dout1, 2'b11)
// read undefined
din0=2'b11;
addr0=4'h0;
web0 = 1;
csb0 = 0;
#10 `assert(dout0, 2'bxx)
#10 $finish;
end
always
#5 clk = !clk;
endmodule

View File

@ -0,0 +1,103 @@
`define assert(signal, value) \
if (!(signal === value)) begin \
$display("ASSERTION FAILED in %m: signal != value"); \
$finish;\
end
module sram_1rw_tb;
reg clk;
reg [3:0] addr0;
reg [1:0] din0;
reg csb0;
reg web0;
wire [1:0] dout0;
sram_2_16_scn4m_subm U0 (.DIN0(din0),
.DOUT0(dout0),
.ADDR0(addr0),
.csb0(csb0),
.web0(web0),
.clk0(clk)
);
initial
begin
//$monitor("%g addr0=%b din0=%b dout0=%b",
// $time, addr0, din0, dout0);
clk = 1;
csb0 = 1;
web0 = 1;
addr0 = 0;
din0 = 0;
// write
#10 din0=2'b10;
addr0=4'h1;
web0 = 0;
csb0 = 0;
// write another
#10 din0=2'b01;
addr0=4'hC;
web0 = 0;
csb0 = 0;
// read undefined
#10 din0=2'b11;
addr0=4'h0;
web0 = 1;
csb0 = 0;
#10 `assert(dout0, 2'bxx)
// read defined
din0=2'b11;
addr0=4'hC;
web0 = 1;
csb0 = 0;
#10 `assert(dout0, 2'b01)
// write another
din0=2'b11;
addr0=4'hA;
web0 = 0;
csb0 = 0;
// read defined
#10 din0=2'b11;
addr0=4'h1;
web0 = 1;
csb0 = 0;
#10 `assert(dout0, 2'b10)
// read defined
din0=2'b11;
addr0=4'hA;
web0 = 1;
csb0 = 0;
#10 `assert(dout0, 2'b11)
// read undefined
din0=2'b11;
addr0=4'h0;
web0 = 1;
csb0 = 0;
#10 `assert(dout0, 2'bxx)
#10 $finish;
end
always
#5 clk = !clk;
endmodule