Merge branch 'master' of https://github.com/mguthaus/OpenRAM into multiport

This commit is contained in:
Michael Timothy Grimes 2018-02-28 04:29:38 -08:00
commit bf7d846e5f
262 changed files with 4310516 additions and 4391 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
*.sp linguist-vendored

5
.gitignore vendored
View File

@ -1,4 +1,7 @@
.DS_Store .DS_Store
*~ *~
*.pyc *.pyc
*.log *.aux
*.out
*.toc
*.synctex.gz

View File

@ -96,15 +96,14 @@ the tests on your contributions before they will be accepted.
git pull upstream dev git pull upstream dev
``` ```
9. Merge the changes from dev into your branch 9. Frequently rebase your branch to keep track of current changes in dev.
``` ```
git merge dev git fetch upstream
git rebase origin/dev
``` ```
10. After you are done, rebase your branch to minimize the number of commits if you
had a lot. I prefer a single commit that you contribute. After this, 10. After a final rebase and your code is working, push your branch to YOUR repository:
push your branch to YOUR repository:
``` ```
git rebase dev
git push -u origin useful-branch-name git push -u origin useful-branch-name
``` ```
Remember origin is your copy on github and useful-branch-name is the Remember origin is your copy on github and useful-branch-name is the

View File

@ -27,7 +27,7 @@ def parse_output(filename, key):
if val != None: if val != None:
debug.info(4, "Key = " + key + " Val = " + val.group(1)) debug.info(4, "Key = " + key + " Val = " + val.group(1))
return val.group(1) return convert_to_float(val.group(1))
else: else:
return "Failed" return "Failed"

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
import os,sys,re,shutil import os,sys,re
import debug import debug
import math import math
import setup_hold import setup_hold
@ -6,40 +6,31 @@ import delay
import charutils as ch import charutils as ch
import tech import tech
import numpy as np import numpy as np
from trim_spice import trim_spice
from globals import OPTS from globals import OPTS
class lib: class lib:
""" lib file generation.""" """ lib file generation."""
def __init__(self, libname, sram, spfile, use_model=OPTS.analytical_delay): def __init__(self, out_dir, sram, sp_file, use_model=OPTS.analytical_delay):
self.out_dir = out_dir
self.sram = sram self.sram = sram
self.sp_file = spfile self.sp_file = sp_file
self.use_model = use_model self.use_model = use_model
self.name = sram.name
self.num_words = sram.num_words
self.word_size = sram.word_size
self.addr_size = sram.addr_size
# Set up to trim the netlist here if that is enabled self.prepare_tables()
if OPTS.trim_netlist:
self.sim_sp_file = "{}reduced.sp".format(OPTS.openram_temp)
self.trimsp=trim_spice(self.sp_file, self.sim_sp_file)
self.trimsp.set_configuration(self.sram.num_banks,
self.sram.num_rows,
self.sram.num_cols,
self.sram.word_size)
else:
# Else, use the non-reduced netlist file for simulation
self.sim_sp_file = "{}sram.sp".format(OPTS.openram_temp)
# Make a copy in temp for debugging
shutil.copy(self.sp_file, self.sim_sp_file)
self.create_corners()
self.characterize_corners()
def prepare_tables(self):
""" Determine the load/slews if they aren't specified in the config file. """
# These are the parameters to determine the table sizes # These are the parameters to determine the table sizes
#self.load_scales = np.array([0.1, 0.25, 0.5, 1, 2, 4, 8]) #self.load_scales = np.array([0.1, 0.25, 0.5, 1, 2, 4, 8])
self.load_scales = np.array([0.25, 1, 8]) self.load_scales = np.array([0.25, 1, 8])
#self.load_scales = np.array([0.25, 1]) #self.load_scales = np.array([0.25, 1])
self.load = tech.spice["FF_in_cap"] self.load = tech.spice["dff_in_cap"]
self.loads = self.load_scales*self.load self.loads = self.load_scales*self.load
debug.info(1,"Loads: {0}".format(self.loads)) debug.info(1,"Loads: {0}".format(self.loads))
@ -49,9 +40,48 @@ class lib:
self.slew = tech.spice["rise_time"] self.slew = tech.spice["rise_time"]
self.slews = self.slew_scales*self.slew self.slews = self.slew_scales*self.slew
debug.info(1,"Slews: {0}".format(self.slews)) debug.info(1,"Slews: {0}".format(self.slews))
debug.info(1,"Writing to {0}".format(libname))
self.lib = open(libname, "w") def create_corners(self):
""" Create corners for characterization. """
# Get the corners from the options file
self.temperatures = OPTS.temperatures
self.supply_voltages = OPTS.supply_voltages
self.process_corners = OPTS.process_corners
# Enumerate all possible corners
self.corners = []
self.lib_files = []
for proc in self.process_corners:
for temp in self.temperatures:
for volt in self.supply_voltages:
self.corner_name = "{0}_{1}_{2}V_{3}C".format(self.sram.name,
proc,
volt,
temp)
self.corner_name = self.corner_name.replace(".","p") # Remove decimals
lib_name = self.out_dir+"{}.lib".format(self.corner_name)
# A corner is a tuple of PVT
self.corners.append((proc, volt, temp))
self.lib_files.append(lib_name)
def characterize_corners(self):
""" Characterize the list of corners. """
for (self.corner,lib_name) in zip(self.corners,self.lib_files):
debug.info(1,"Corner: " + str(self.corner))
(self.process, self.voltage, self.temperature) = self.corner
self.lib = open(lib_name, "w")
debug.info(1,"Writing to {0}".format(lib_name))
self.characterize()
self.lib.close()
def characterize(self):
""" Characterize the current corner. """
self.compute_delay()
self.compute_setup_hold()
self.write_header() self.write_header()
@ -62,12 +92,17 @@ class lib:
self.write_control_pins() self.write_control_pins()
self.write_clk() self.write_clk()
self.write_footer()
self.lib.close() def write_footer(self):
""" Write the footer """
self.lib.write("}\n")
def write_header(self): def write_header(self):
""" Write the header information """ """ Write the header information """
self.lib.write("library ({0}_lib)".format(self.name)) self.lib.write("library ({0}_lib)".format(self.corner_name))
self.lib.write("{\n") self.lib.write("{\n")
self.lib.write(" delay_model : \"table_lookup\";\n") self.lib.write(" delay_model : \"table_lookup\";\n")
@ -75,22 +110,29 @@ class lib:
self.write_defaults() self.write_defaults()
self.write_LUT_templates() self.write_LUT_templates()
self.lib.write(" default_operating_conditions : TT; \n") self.lib.write(" default_operating_conditions : OC; \n")
self.write_bus() self.write_bus()
self.lib.write("cell ({0})".format(self.name)) self.lib.write("cell ({0})".format(self.sram.name))
self.lib.write("{\n") self.lib.write("{\n")
self.lib.write(" memory(){ \n") self.lib.write(" memory(){ \n")
self.lib.write(" type : ram;\n") self.lib.write(" type : ram;\n")
self.lib.write(" address_width : {0};\n".format(self.addr_size)) self.lib.write(" address_width : {};\n".format(self.sram.addr_size))
self.lib.write(" word_width : {0};\n".format(self.word_size)) self.lib.write(" word_width : {};\n".format(self.sram.word_size))
self.lib.write(" }\n") self.lib.write(" }\n")
self.lib.write(" interface_timing : true;\n") self.lib.write(" interface_timing : true;\n")
self.lib.write(" dont_use : true;\n") self.lib.write(" dont_use : true;\n")
self.lib.write(" map_only : true;\n") self.lib.write(" map_only : true;\n")
self.lib.write(" dont_touch : true;\n") self.lib.write(" dont_touch : true;\n")
self.lib.write(" area : {0};\n\n".format(self.sram.width * self.sram.height)) self.lib.write(" area : {};\n\n".format(self.sram.width * self.sram.height))
# Leakage is included in dynamic when macro is enabled
self.lib.write(" leakage_power () {\n")
self.lib.write(" when : \"CSb\";\n")
self.lib.write(" value : {};\n".format(self.char_results["leakage_power"]))
self.lib.write(" }\n")
self.lib.write(" cell_leakage_power : {};\n".format(0))
def write_units(self): def write_units(self):
@ -103,9 +145,10 @@ class lib:
self.lib.write(" capacitive_load_unit(1 ,fF) ;\n") self.lib.write(" capacitive_load_unit(1 ,fF) ;\n")
self.lib.write(" leakage_power_unit : \"1mW\" ;\n") self.lib.write(" leakage_power_unit : \"1mW\" ;\n")
self.lib.write(" pulling_resistance_unit :\"1kohm\" ;\n") self.lib.write(" pulling_resistance_unit :\"1kohm\" ;\n")
self.lib.write(" operating_conditions(TT){\n") self.lib.write(" operating_conditions(OC){\n")
self.lib.write(" voltage : {0} ;\n".format(tech.spice["supply_voltage"])) self.lib.write(" process : {} ;\n".format(1.0)) # How to use TT, FF, SS?
self.lib.write(" temperature : 25.000 ;\n") self.lib.write(" voltage : {} ;\n".format(self.voltage))
self.lib.write(" temperature : {};\n".format(self.temperature))
self.lib.write(" }\n\n") self.lib.write(" }\n\n")
def write_defaults(self): def write_defaults(self):
@ -120,6 +163,10 @@ class lib:
self.lib.write(" slew_lower_threshold_pct_rise : 10.0 ;\n") self.lib.write(" slew_lower_threshold_pct_rise : 10.0 ;\n")
self.lib.write(" slew_upper_threshold_pct_rise : 90.0 ;\n\n") self.lib.write(" slew_upper_threshold_pct_rise : 90.0 ;\n\n")
self.lib.write(" nom_voltage : {};\n".format(tech.spice["nom_supply_voltage"]))
self.lib.write(" nom_temperature : {};\n".format(tech.spice["nom_temperature"]))
self.lib.write(" nom_process : {};\n".format(1.0))
self.lib.write(" default_cell_leakage_power : 0.0 ;\n") self.lib.write(" default_cell_leakage_power : 0.0 ;\n")
self.lib.write(" default_leakage_power_density : 0.0 ;\n") self.lib.write(" default_leakage_power_density : 0.0 ;\n")
self.lib.write(" default_input_pin_cap : 1.0 ;\n") self.lib.write(" default_input_pin_cap : 1.0 ;\n")
@ -206,25 +253,23 @@ class lib:
self.lib.write(" type (DATA){\n") self.lib.write(" type (DATA){\n")
self.lib.write(" base_type : array;\n") self.lib.write(" base_type : array;\n")
self.lib.write(" data_type : bit;\n") self.lib.write(" data_type : bit;\n")
self.lib.write(" bit_width : {0};\n".format(self.word_size)) self.lib.write(" bit_width : {0};\n".format(self.sram.word_size))
self.lib.write(" bit_from : 0;\n") self.lib.write(" bit_from : 0;\n")
self.lib.write(" bit_to : {0};\n".format(self.word_size - 1)) self.lib.write(" bit_to : {0};\n".format(self.sram.word_size - 1))
self.lib.write(" }\n\n") self.lib.write(" }\n\n")
self.lib.write(" type (ADDR){\n") self.lib.write(" type (ADDR){\n")
self.lib.write(" base_type : array;\n") self.lib.write(" base_type : array;\n")
self.lib.write(" data_type : bit;\n") self.lib.write(" data_type : bit;\n")
self.lib.write(" bit_width : {0};\n".format(self.addr_size)) self.lib.write(" bit_width : {0};\n".format(self.sram.addr_size))
self.lib.write(" bit_from : 0;\n") self.lib.write(" bit_from : 0;\n")
self.lib.write(" bit_to : {0};\n".format(self.addr_size - 1)) self.lib.write(" bit_to : {0};\n".format(self.sram.addr_size - 1))
self.lib.write(" }\n\n") self.lib.write(" }\n\n")
def write_FF_setuphold(self): def write_FF_setuphold(self):
""" Adds Setup and Hold timing results""" """ Adds Setup and Hold timing results"""
self.compute_setup_hold()
self.lib.write(" timing(){ \n") self.lib.write(" timing(){ \n")
self.lib.write(" timing_type : setup_rising; \n") self.lib.write(" timing_type : setup_rising; \n")
self.lib.write(" related_pin : \"clk\"; \n") self.lib.write(" related_pin : \"clk\"; \n")
@ -255,12 +300,12 @@ class lib:
def write_data_bus(self): def write_data_bus(self):
""" Adds data bus timing results.""" """ Adds data bus timing results."""
self.compute_delay()
self.lib.write(" bus(DATA){\n") self.lib.write(" bus(DATA){\n")
self.lib.write(" bus_type : DATA; \n") self.lib.write(" bus_type : DATA; \n")
self.lib.write(" direction : inout; \n") self.lib.write(" direction : inout; \n")
self.lib.write(" max_capacitance : {0}; \n".format(8*tech.spice["FF_in_cap"])) # This is conservative, but limit to range that we characterized.
self.lib.write(" max_capacitance : {0}; \n".format(max(self.loads)))
self.lib.write(" min_capacitance : {0}; \n".format(min(self.loads)))
self.lib.write(" three_state : \"!OEb & !clk\"; \n") self.lib.write(" three_state : \"!OEb & !clk\"; \n")
self.lib.write(" memory_write(){ \n") self.lib.write(" memory_write(){ \n")
self.lib.write(" address : ADDR; \n") self.lib.write(" address : ADDR; \n")
@ -269,53 +314,29 @@ class lib:
self.lib.write(" memory_read(){ \n") self.lib.write(" memory_read(){ \n")
self.lib.write(" address : ADDR; \n") self.lib.write(" address : ADDR; \n")
self.lib.write(" }\n") self.lib.write(" }\n")
self.lib.write(" pin(DATA[{0}:0])".format(self.word_size - 1))
self.lib.write("{\n")
self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"OEb & !clk\"; \n")
self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(self.delay["write1_power"]))
self.lib.write(" }\n")
self.lib.write(" fall_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(self.delay["write0_power"]))
self.lib.write(" }\n")
self.lib.write(" }\n")
self.lib.write(" pin(DATA[{0}:0]){{\n".format(self.sram.word_size - 1))
self.write_FF_setuphold() self.write_FF_setuphold()
self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"!OEb & !clk\"; \n")
self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(self.delay["read1_power"]))
self.lib.write(" }\n")
self.lib.write(" fall_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(self.delay["read0_power"]))
self.lib.write(" }\n")
self.lib.write(" }\n")
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\"; \n") self.lib.write(" related_pin : \"clk\"; \n")
self.lib.write(" timing_type : falling_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")
rounded_values = map(ch.round_time,self.delay["delay1"]) self.write_values(self.char_results["delay_lh"],len(self.loads)," ")
self.write_values(rounded_values,len(self.loads)," ") self.lib.write(" }\n") # rise delay
self.lib.write(" }\n")
self.lib.write(" cell_fall(CELL_TABLE) {\n") self.lib.write(" cell_fall(CELL_TABLE) {\n")
rounded_values = map(ch.round_time,self.delay["delay0"]) self.write_values(self.char_results["delay_hl"],len(self.loads)," ")
self.write_values(rounded_values,len(self.loads)," ") self.lib.write(" }\n") # fall delay
self.lib.write(" }\n") self.lib.write(" rise_transition(CELL_TABLE) {\n")
self.lib.write(" rise_transition(CELL_TABLE) {\n") self.write_values(self.char_results["slew_lh"],len(self.loads)," ")
rounded_values = map(ch.round_time,self.delay["slew1"]) self.lib.write(" }\n") # rise trans
self.write_values(rounded_values,len(self.loads)," ") self.lib.write(" fall_transition(CELL_TABLE) {\n")
self.lib.write(" }\n") self.write_values(self.char_results["slew_hl"],len(self.loads)," ")
self.lib.write(" fall_transition(CELL_TABLE) {\n") self.lib.write(" }\n") # fall trans
rounded_values = map(ch.round_time,self.delay["slew0"]) self.lib.write(" }\n") # timing
self.write_values(rounded_values,len(self.loads)," ") self.lib.write(" }\n") # pin
self.lib.write(" }\n") self.lib.write(" }\n\n") # bus
self.lib.write(" }\n")
self.lib.write(" }\n")
self.lib.write(" }\n\n")
def write_addr_bus(self): def write_addr_bus(self):
@ -324,10 +345,9 @@ class lib:
self.lib.write(" bus(ADDR){\n") self.lib.write(" bus(ADDR){\n")
self.lib.write(" bus_type : ADDR; \n") self.lib.write(" bus_type : ADDR; \n")
self.lib.write(" direction : input; \n") self.lib.write(" direction : input; \n")
self.lib.write(" capacitance : {0}; \n".format(tech.spice["FF_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(" fanout_load : 1.000000;\n") self.lib.write(" pin(ADDR[{0}:0])".format(self.sram.addr_size - 1))
self.lib.write(" pin(ADDR[{0}:0])".format(self.addr_size - 1))
self.lib.write("{\n") self.lib.write("{\n")
self.write_FF_setuphold() self.write_FF_setuphold()
@ -343,7 +363,7 @@ class lib:
self.lib.write(" pin({0})".format(i)) self.lib.write(" pin({0})".format(i))
self.lib.write("{\n") self.lib.write("{\n")
self.lib.write(" direction : input; \n") self.lib.write(" direction : input; \n")
self.lib.write(" capacitance : {0}; \n".format(tech.spice["FF_in_cap"])) self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"]))
self.write_FF_setuphold() self.write_FF_setuphold()
self.lib.write(" }\n\n") self.lib.write(" }\n\n")
@ -351,14 +371,50 @@ class lib:
def write_clk(self): def write_clk(self):
""" Adds clk pin timing results.""" """ Adds clk pin timing results."""
self.compute_delay()
self.lib.write(" pin(clk){\n") self.lib.write(" pin(clk){\n")
self.lib.write(" clock : true;\n") self.lib.write(" clock : true;\n")
self.lib.write(" direction : input; \n") self.lib.write(" direction : input; \n")
self.lib.write(" capacitance : {0}; \n".format(tech.spice["FF_in_cap"])) # This should actually be a min inverter cap, but ok...
min_pulse_width = ch.round_time(self.delay["min_period"])/2.0 self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"]))
min_period = ch.round_time(self.delay["min_period"])
# Find the average power of 1 and 0 bits for writes and reads over all loads/slews
# Could make it a table, but this is fine for now.
avg_write_power = np.mean(self.char_results["write1_power"] + self.char_results["write0_power"])
avg_read_power = np.mean(self.char_results["read1_power"] + self.char_results["read0_power"])
# Equally divide read/write power between first and second half of clock period
self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"!CSb & clk & !WEb\"; \n")
self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_write_power/2.0))
self.lib.write(" }\n")
self.lib.write(" fall_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_write_power/2.0))
self.lib.write(" }\n")
self.lib.write(" }\n")
self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"!CSb & !clk & WEb\"; \n")
self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_read_power/2.0))
self.lib.write(" }\n")
self.lib.write(" fall_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_read_power/2.0))
self.lib.write(" }\n")
self.lib.write(" }\n")
# Have 0 internal power when disabled, this will be represented as leakage power.
self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"CSb\"; \n")
self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"0\");\n")
self.lib.write(" }\n")
self.lib.write(" fall_power(scalar){\n")
self.lib.write(" values(\"0\");\n")
self.lib.write(" }\n")
self.lib.write(" }\n")
min_pulse_width = ch.round_time(self.char_results["min_period"])/2.0
min_period = ch.round_time(self.char_results["min_period"])
self.lib.write(" timing(){ \n") self.lib.write(" timing(){ \n")
self.lib.write(" timing_type :\"min_pulse_width\"; \n") self.lib.write(" timing_type :\"min_pulse_width\"; \n")
self.lib.write(" related_pin : clk; \n") self.lib.write(" related_pin : clk; \n")
@ -381,23 +437,20 @@ class lib:
self.lib.write(" }\n") self.lib.write(" }\n")
self.lib.write(" }\n") self.lib.write(" }\n")
self.lib.write(" }\n") self.lib.write(" }\n")
self.lib.write("}\n")
def compute_delay(self): def compute_delay(self):
""" Do the analysis if we haven't characterized the SRAM yet """ """ Do the analysis if we haven't characterized the SRAM yet """
try: try:
self.d self.d
except AttributeError: except AttributeError:
self.d = delay.delay(self.sram, self.sim_sp_file) self.d = delay.delay(self.sram, self.sp_file, self.corner)
if self.use_model: if self.use_model:
self.delay = self.d.analytical_model(self.sram,self.slews,self.loads) self.char_results = self.d.analytical_delay(self.sram,self.slews,self.loads)
else: else:
probe_address = "1" * self.addr_size probe_address = "1" * self.sram.addr_size
probe_data = self.word_size - 1 probe_data = self.sram.word_size - 1
# We must trim based on a specific address and data bit self.char_results = self.d.analyze(probe_address, probe_data, self.slews, self.loads)
if OPTS.trim_netlist:
self.trimsp.trim(probe_address,probe_data)
self.delay = self.d.analyze(probe_address, probe_data, self.slews, self.loads)
def compute_setup_hold(self): def compute_setup_hold(self):
""" Do the analysis if we haven't characterized a FF yet """ """ Do the analysis if we haven't characterized a FF yet """
@ -405,9 +458,9 @@ class lib:
try: try:
self.sh self.sh
except AttributeError: except AttributeError:
self.sh = setup_hold.setup_hold() self.sh = setup_hold.setup_hold(self.corner)
if self.use_model: if self.use_model:
self.times = self.sh.analytical_model(self.slews,self.loads) self.times = self.sh.analytical_setuphold(self.slews,self.loads)
else: else:
self.times = self.sh.analyze(self.slews,self.slews) self.times = self.sh.analyze(self.slews,self.slews)

View File

@ -13,18 +13,23 @@ class setup_hold():
(Bisection Methodology) (Bisection Methodology)
""" """
def __init__(self): def __init__(self, corner):
# This must match the spice model order # This must match the spice model order
self.pins = ["data", "dout", "dout_bar", "clk", "vdd", "gnd"] self.pins = ["data", "dout", "dout_bar", "clk", "vdd", "gnd"]
self.model_name = "ms_flop" self.model_name = "ms_flop"
self.model_location = OPTS.openram_tech + "sp_lib/ms_flop.sp" self.model_location = OPTS.openram_tech + "sp_lib/ms_flop.sp"
self.period = tech.spice["feasible_period"] self.period = tech.spice["feasible_period"]
self.vdd = tech.spice["supply_voltage"]
self.gnd = tech.spice["gnd_voltage"]
debug.info(2,"Feasible period from technology file: {0} ".format(self.period)) debug.info(2,"Feasible period from technology file: {0} ".format(self.period))
self.set_corner(corner)
def set_corner(self,corner):
""" Set the corner values """
self.corner = corner
(self.process, self.vdd_voltage, self.temperature) = corner
self.gnd_voltage = 0
def write_stimulus(self, mode, target_time, correct_value): def write_stimulus(self, mode, target_time, correct_value):
@ -33,14 +38,14 @@ class setup_hold():
# creates and opens the stimulus file for writing # creates and opens the stimulus file for writing
temp_stim = OPTS.openram_temp + "stim.sp" temp_stim = OPTS.openram_temp + "stim.sp"
self.sf = open(temp_stim, "w") self.sf = open(temp_stim, "w")
self.stim = stimuli.stimuli(self.sf, self.corner)
self.write_header(correct_value) self.write_header(correct_value)
# instantiate the master-slave d-flip-flop # instantiate the master-slave d-flip-flop
self.sf.write("\n* Instantiation of the Master-Slave D-flip-flop\n") self.sf.write("\n* Instantiation of the Master-Slave D-flip-flop\n")
stimuli.inst_model(stim_file=self.sf, self.stim.inst_model(pins=self.pins,
pins=self.pins, model_name=self.model_name)
model_name=self.model_name)
self.write_data(mode=mode, self.write_data(mode=mode,
target_time=target_time, target_time=target_time,
@ -52,7 +57,7 @@ class setup_hold():
correct_value=correct_value) correct_value=correct_value)
stimuli.write_control(self.sf,4*self.period) self.stim.write_control(4*self.period)
self.sf.close() self.sf.close()
@ -61,13 +66,11 @@ class setup_hold():
self.sf.write("\n* Stimulus for setup/hold: data {0} period {1}n\n".format(correct_value, self.period)) self.sf.write("\n* Stimulus for setup/hold: data {0} period {1}n\n".format(correct_value, self.period))
# include files in stimulus file # include files in stimulus file
self.model_list = tech.spice["fet_models"] + [self.model_location] self.stim.write_include(self.model_location)
stimuli.write_include(stim_file=self.sf,
models=self.model_list)
# add vdd/gnd statements # add vdd/gnd statements
self.sf.write("\n* Global Power Supplies\n") self.sf.write("\n* Global Power Supplies\n")
stimuli.write_supply(self.sf) self.stim.write_supply()
def write_data(self, mode, target_time, correct_value): def write_data(self, mode, target_time, correct_value):
@ -77,7 +80,7 @@ class setup_hold():
""" """
self.sf.write("\n* Generation of the data and clk signals\n") self.sf.write("\n* Generation of the data and clk signals\n")
incorrect_value = stimuli.get_inverse_value(correct_value) incorrect_value = self.stim.get_inverse_value(correct_value)
if mode=="HOLD": if mode=="HOLD":
init_value = incorrect_value init_value = incorrect_value
start_value = correct_value start_value = correct_value
@ -87,29 +90,27 @@ class setup_hold():
start_value = incorrect_value start_value = incorrect_value
end_value = correct_value end_value = correct_value
stimuli.gen_pwl(stim_file=self.sf, self.stim.gen_pwl(sig_name="data",
sig_name="data", clk_times=[0, self.period, target_time],
clk_times=[0, self.period, target_time], data_values=[init_value, start_value, end_value],
data_values=[init_value, start_value, end_value], period=target_time,
period=target_time, slew=self.constrained_input_slew,
slew=self.constrained_input_slew, setup=0)
setup=0)
def write_clock(self): def write_clock(self):
""" Create the clock signal for setup/hold analysis. First period initializes the FF """ Create the clock signal for setup/hold analysis. First period initializes the FF
while the second is used for characterization.""" while the second is used for characterization."""
stimuli.gen_pwl(stim_file=self.sf, self.stim.gen_pwl(sig_name="clk",
sig_name="clk", # initial clk edge is right after the 0 time to initialize a flop
# initial clk edge is right after the 0 time to initialize a flop # without using .IC on an internal node.
# without using .IC on an internal node. # Return input to value after one period.
# Return input to value after one period. # The second pulse is the characterization one at 2*period
# The second pulse is the characterization one at 2*period clk_times=[0, 0.1*self.period,self.period,2*self.period],
clk_times=[0, 0.1*self.period,self.period,2*self.period], data_values=[0, 1, 0, 1],
data_values=[0, 1, 0, 1], period=2*self.period,
period=2*self.period, slew=self.constrained_input_slew,
slew=self.constrained_input_slew, setup=0)
setup=0)
@ -135,32 +136,30 @@ class setup_hold():
self.sf.write("\n* Measure statements for pass/fail verification\n") self.sf.write("\n* Measure statements for pass/fail verification\n")
trig_name = "clk" trig_name = "clk"
targ_name = "dout" targ_name = "dout"
trig_val = targ_val = 0.5 * self.vdd trig_val = targ_val = 0.5 * self.vdd_voltage
# Start triggers right before the clock edge at 2*period # Start triggers right before the clock edge at 2*period
stimuli.gen_meas_delay(stim_file=self.sf, self.stim.gen_meas_delay(meas_name="clk2q_delay",
meas_name="clk2q_delay", trig_name=trig_name,
trig_name=trig_name, targ_name=targ_name,
targ_name=targ_name, trig_val=trig_val,
trig_val=trig_val, targ_val=targ_val,
targ_val=targ_val, trig_dir="RISE",
trig_dir="RISE", targ_dir=dout_rise_or_fall,
targ_dir=dout_rise_or_fall, trig_td=1.9*self.period,
trig_td=1.9*self.period, targ_td=1.9*self.period)
targ_td=1.9*self.period)
targ_name = "data" targ_name = "data"
# Start triggers right after initialize value is returned to normal # Start triggers right after initialize value is returned to normal
# at one period # at one period
stimuli.gen_meas_delay(stim_file=self.sf, self.stim.gen_meas_delay(meas_name="setup_hold_time",
meas_name="setup_hold_time", trig_name=trig_name,
trig_name=trig_name, targ_name=targ_name,
targ_name=targ_name, trig_val=trig_val,
trig_val=trig_val, targ_val=targ_val,
targ_val=targ_val, trig_dir="RISE",
trig_dir="RISE", targ_dir=din_rise_or_fall,
targ_dir=din_rise_or_fall, trig_td=1.2*self.period,
trig_td=1.2*self.period, targ_td=1.2*self.period)
targ_td=1.2*self.period)
@ -186,7 +185,7 @@ class setup_hold():
self.write_stimulus(mode=mode, self.write_stimulus(mode=mode,
target_time=feasible_bound, target_time=feasible_bound,
correct_value=correct_value) correct_value=correct_value)
stimuli.run_sim() self.stim.run_sim()
ideal_clk_to_q = ch.convert_to_float(ch.parse_output("timing", "clk2q_delay")) ideal_clk_to_q = ch.convert_to_float(ch.parse_output("timing", "clk2q_delay"))
setuphold_time = ch.convert_to_float(ch.parse_output("timing", "setup_hold_time")) setuphold_time = ch.convert_to_float(ch.parse_output("timing", "setup_hold_time"))
debug.info(2,"*** {0} CHECK: {1} Ideal Clk-to-Q: {2} Setup/Hold: {3}".format(mode, correct_value,ideal_clk_to_q,setuphold_time)) debug.info(2,"*** {0} CHECK: {1} Ideal Clk-to-Q: {2} Setup/Hold: {3}".format(mode, correct_value,ideal_clk_to_q,setuphold_time))
@ -219,7 +218,7 @@ class setup_hold():
feasible_bound)) feasible_bound))
stimuli.run_sim() self.stim.run_sim()
clk_to_q = ch.convert_to_float(ch.parse_output("timing", "clk2q_delay")) clk_to_q = ch.convert_to_float(ch.parse_output("timing", "clk2q_delay"))
setuphold_time = ch.convert_to_float(ch.parse_output("timing", "setup_hold_time")) setuphold_time = ch.convert_to_float(ch.parse_output("timing", "setup_hold_time"))
if type(clk_to_q)==float and (clk_to_q<1.1*ideal_clk_to_q) and type(setuphold_time)==float: if type(clk_to_q)==float and (clk_to_q<1.1*ideal_clk_to_q) and type(setuphold_time)==float:
@ -300,7 +299,7 @@ class setup_hold():
} }
return times return times
def analytical_model(self,related_slews, constrained_slews): def analytical_setuphold(self,related_slews, constrained_slews):
""" Just return the fixed setup/hold times from the technology. """ Just return the fixed setup/hold times from the technology.
""" """
LH_setup = [] LH_setup = []

View File

@ -12,290 +12,302 @@ import sys
import numpy as np import numpy as np
from globals import OPTS from globals import OPTS
vdd_voltage = tech.spice["supply_voltage"]
gnd_voltage = tech.spice["gnd_voltage"]
vdd_name = tech.spice["vdd_name"]
gnd_name = tech.spice["gnd_name"]
pmos_name = tech.spice["pmos_name"]
nmos_name = tech.spice["nmos_name"]
tx_width = tech.spice["minwidth_tx"]
tx_length = tech.spice["channel"]
def inst_sram(stim_file, abits, dbits, sram_name): class stimuli():
""" Function to instatiate an SRAM subckt. """ """ Class for providing stimuli functions """
stim_file.write("Xsram ")
for i in range(dbits):
stim_file.write("D[{0}] ".format(i))
for i in range(abits):
stim_file.write("A[{0}] ".format(i))
for i in tech.spice["control_signals"]:
stim_file.write("{0} ".format(i))
stim_file.write("{0} ".format(tech.spice["clk"]))
stim_file.write("{0} {1} ".format(vdd_name, gnd_name))
stim_file.write("{0}\n".format(sram_name))
def __init__(self, stim_file, corner):
self.vdd_name = tech.spice["vdd_name"]
self.gnd_name = tech.spice["gnd_name"]
self.pmos_name = tech.spice["pmos"]
self.nmos_name = tech.spice["nmos"]
self.tx_width = tech.spice["minwidth_tx"]
self.tx_length = tech.spice["channel"]
def inst_model(stim_file, pins, model_name): self.sf = stim_file
""" Function to instantiate a generic model with a set of pins """
stim_file.write("X{0} ".format(model_name))
for pin in pins:
stim_file.write("{0} ".format(pin))
stim_file.write("{0}\n".format(model_name))
def create_inverter(stim_file, size=1, beta=2.5):
""" Generates inverter for the top level signals (only for sim purposes) """
stim_file.write(".SUBCKT test_inv in out {0} {1}\n".format(vdd_name, gnd_name))
stim_file.write("mpinv out in {0} {0} {1} w={2}u l={3}u\n".format(vdd_name,
pmos_name,
beta * size * tx_width,
tx_length))
stim_file.write("mninv out in {0} {0} {1} w={2}u l={3}u\n".format(gnd_name,
nmos_name,
size * tx_width,
tx_length))
stim_file.write(".ENDS test_inv\n")
def create_buffer(stim_file, buffer_name, size=[1,3], beta=2.5):
"""
Generates buffer for top level signals (only for sim
purposes). Size is pair for PMOS, NMOS width multiple.
"""
stim_file.write(".SUBCKT test_{2} in out {0} {1}\n".format(vdd_name,
gnd_name,
buffer_name))
stim_file.write("mpinv1 out_inv in {0} {0} {1} w={2}u l={3}u\n".format(vdd_name,
pmos_name,
beta * size[0] * tx_width,
tx_length))
stim_file.write("mninv1 out_inv in {0} {0} {1} w={2}u l={3}u\n".format(gnd_name,
nmos_name,
size[0] * tx_width,
tx_length))
stim_file.write("mpinv2 out out_inv {0} {0} {1} w={2}u l={3}u\n".format(vdd_name,
pmos_name,
beta * size[1] * tx_width,
tx_length))
stim_file.write("mninv2 out out_inv {0} {0} {1} w={2}u l={3}u\n".format(gnd_name,
nmos_name,
size[1] * tx_width,
tx_length))
stim_file.write(".ENDS test_{0}\n\n".format(buffer_name))
def inst_buffer(stim_file, buffer_name, signal_list):
""" Adds buffers to each top level signal that is in signal_list (only for sim purposes) """
for signal in signal_list:
stim_file.write("X{0}_buffer {0} {0}_buf {1} {2} test_{3}\n".format(signal,
"test"+vdd_name,
"test"+gnd_name,
buffer_name))
def inst_inverter(stim_file, signal_list):
""" Adds inv for each signal that needs its inverted version (only for sim purposes) """
for signal in signal_list:
stim_file.write("X{0}_inv {0} {0}_inv {1} {2} test_inv\n".format(signal,
"test"+vdd_name,
"test"+gnd_name))
def inst_accesstx(stim_file, dbits):
""" Adds transmission gate for inputs to data-bus (only for sim purposes) """
stim_file.write("* Tx Pin-list: Drain Gate Source Body\n")
for i in range(dbits):
pmos_access_string="mp{0} DATA[{0}] acc_en D[{0}] {1} {2} w={3}u l={4}u\n"
stim_file.write(pmos_access_string.format(i,
"test"+vdd_name,
pmos_name,
2 * tx_width,
tx_length))
nmos_access_string="mn{0} DATA[{0}] acc_en_inv D[{0}] {1} {2} w={3}u l={4}u\n"
stim_file.write(nmos_access_string.format(i,
"test"+gnd_name,
nmos_name,
2 * tx_width,
tx_length))
def gen_pulse(stim_file, sig_name, v1=gnd_voltage, v2=vdd_voltage, offset=0, period=1, t_rise=0, t_fall=0):
"""
Generates a periodic signal with 50% duty cycle and slew rates. Period is measured
from 50% to 50%.
"""
stim_file.write("* PULSE: period={0}\n".format(period))
pulse_string="V{0} {0} 0 PULSE ({1} {2} {3}n {4}n {5}n {6}n {7}n)\n"
stim_file.write(pulse_string.format(sig_name,
v1,
v2,
offset,
t_rise,
t_fall,
0.5*period-0.5*t_rise-0.5*t_fall,
period))
def gen_pwl(stim_file, sig_name, clk_times, data_values, period, slew, setup):
"""
Generate a PWL stimulus given a signal name and data values at each period.
Automatically creates slews and ensures each data occurs a setup before the clock
edge. The first clk_time should be 0 and is the initial time that corresponds
to the initial value.
"""
# the initial value is not a clock time
debug.check(len(clk_times)==len(data_values),"Clock and data value lengths don't match.")
# shift signal times earlier for setup time
times = np.array(clk_times) - setup*period
values = np.array(data_values) * vdd_voltage
half_slew = 0.5 * slew
stim_file.write("* (time, data): {}\n".format(zip(clk_times, data_values)))
stim_file.write("V{0} {0} 0 PWL (0n {1}v ".format(sig_name, values[0]))
for i in range(1,len(times)):
stim_file.write("{0}n {1}v {2}n {3}v ".format(times[i]-half_slew,
values[i-1],
times[i]+half_slew,
values[i]))
stim_file.write(")\n")
def gen_constant(stim_file, sig_name, v_val):
""" Generates a constant signal with reference voltage and the voltage value """
stim_file.write("V{0} {0} 0 DC {1}\n".format(sig_name, v_val))
def get_inverse_voltage(value):
if value > 0.5*vdd_voltage:
return gnd_voltage
elif value <= 0.5*vdd_voltage:
return vdd_voltage
else:
debug.error("Invalid value to get an inverse of: {0}".format(value))
def get_inverse_value(value):
if value > 0.5:
return 0
elif value <= 0.5:
return 1
else:
debug.error("Invalid value to get an inverse of: {0}".format(value))
(self.process, self.voltage, self.temperature) = corner
self.device_models = tech.spice["fet_models"][self.process]
def gen_meas_delay(stim_file, meas_name, trig_name, targ_name, trig_val, targ_val, trig_dir, targ_dir, trig_td, targ_td):
""" Creates the .meas statement for the measurement of delay """
measure_string=".meas tran {0} TRIG v({1}) VAL={2} {3}=1 TD={4}n TARG v({5}) VAL={6} {7}=1 TD={8}n\n\n"
stim_file.write(measure_string.format(meas_name,
trig_name,
trig_val,
trig_dir,
trig_td,
targ_name,
targ_val,
targ_dir,
targ_td))
def gen_meas_power(stim_file, meas_name, t_initial, t_final): def inst_sram(self, abits, dbits, sram_name):
""" Creates the .meas statement for the measurement of avg power """ """ Function to instatiate an SRAM subckt. """
# power mea cmd is different in different spice: self.sf.write("Xsram ")
if OPTS.spice_name == "hspice": for i in range(dbits):
power_exp = "power" self.sf.write("D[{0}] ".format(i))
else: for i in range(abits):
power_exp = "par('(-1*v(" + str(vdd_name) + ")*I(v" + str(vdd_name) + "))')" self.sf.write("A[{0}] ".format(i))
stim_file.write(".meas tran {0} avg {1} from={2}n to={3}n\n\n".format(meas_name, for i in tech.spice["control_signals"]:
power_exp, self.sf.write("{0} ".format(i))
t_initial, self.sf.write("{0} ".format(tech.spice["clk"]))
t_final)) self.sf.write("{0} {1} ".format(self.vdd_name, self.gnd_name))
self.sf.write("{0}\n".format(sram_name))
def write_control(stim_file, end_time):
""" Write the control cards to run and end the simulation """
# UIC is needed for ngspice to converge
stim_file.write(".TRAN 5p {0}n UIC\n".format(end_time))
if OPTS.spice_name == "ngspice":
# ngspice sometimes has convergence problems if not using gear method
# which is more accurate, but slower than the default trapezoid method
# Do not remove this or it may not converge due to some "pa_00" nodes
# unless you figure out what these are.
stim_file.write(".OPTIONS POST=1 RUNLVL=4 PROBE method=gear\n")
else:
stim_file.write(".OPTIONS POST=1 RUNLVL=4 PROBE\n")
# create plots for all signals
stim_file.write("* probe is used for hspice/xa, while plot is used in ngspice\n")
if OPTS.debug_level>0:
if OPTS.spice_name in ["hspice","xa"]:
stim_file.write(".probe V(*)\n")
else:
stim_file.write(".plot V(*)\n")
else:
stim_file.write("*.probe V(*)\n")
stim_file.write("*.plot V(*)\n")
# end the stimulus file
stim_file.write(".end\n\n")
def write_include(stim_file, models): def inst_model(self, pins, model_name):
"""Writes include statements, inputs are lists of model files""" """ Function to instantiate a generic model with a set of pins """
for item in list(models): self.sf.write("X{0} ".format(model_name))
if os.path.isfile(item): for pin in pins:
stim_file.write(".include \"{0}\"\n".format(item)) self.sf.write("{0} ".format(pin))
else: self.sf.write("{0}\n".format(model_name))
debug.error("Could not find spice model: {0}\nSet SPICE_MODEL_DIR to over-ride path.\n".format(item))
def write_supply(stim_file): def create_inverter(self, size=1, beta=2.5):
""" Writes supply voltage statements """ """ Generates inverter for the top level signals (only for sim purposes) """
stim_file.write("V{0} {0} 0.0 {1}\n".format(vdd_name, vdd_voltage)) self.sf.write(".SUBCKT test_inv in out {0} {1}\n".format(self.vdd_name, self.gnd_name))
stim_file.write("V{0} {0} 0.0 {1}\n".format(gnd_name, gnd_voltage)) self.sf.write("mpinv out in {0} {0} {1} w={2}u l={3}u\n".format(self.vdd_name,
# This is for the test power supply self.pmos_name,
stim_file.write("V{0} {0} 0.0 {1}\n".format("test"+vdd_name, vdd_voltage)) beta * size * self.tx_width,
stim_file.write("V{0} {0} 0.0 {1}\n".format("test"+gnd_name, gnd_voltage)) self.tx_length))
self.sf.write("mninv out in {0} {0} {1} w={2}u l={3}u\n".format(self.gnd_name,
self.nmos_name,
size * self.tx_width,
self.tx_length))
self.sf.write(".ENDS test_inv\n")
def run_sim(): def create_buffer(self, buffer_name, size=[1,3], beta=2.5):
""" Run hspice in batch mode and output rawfile to parse. """ """
temp_stim = "{0}stim.sp".format(OPTS.openram_temp) Generates buffer for top level signals (only for sim
import datetime purposes). Size is pair for PMOS, NMOS width multiple.
start_time = datetime.datetime.now() """
debug.check(OPTS.spice_exe!="","No spice simulator has been found.")
self.sf.write(".SUBCKT test_{2} in out {0} {1}\n".format(self.vdd_name,
if OPTS.spice_name == "xa": self.gnd_name,
# Output the xa configurations here. FIXME: Move this to write it once. buffer_name))
xa_cfg = open("{}xa.cfg".format(OPTS.openram_temp), "w") self.sf.write("mpinv1 out_inv in {0} {0} {1} w={2}u l={3}u\n".format(self.vdd_name,
xa_cfg.write("set_sim_level -level 7\n") self.pmos_name,
xa_cfg.write("set_powernet_level 7 -node vdd\n") beta * size[0] * self.tx_width,
xa_cfg.close() self.tx_length))
cmd = "{0} {1} -c {2}xa.cfg -o {2}xa -mt 2".format(OPTS.spice_exe, self.sf.write("mninv1 out_inv in {0} {0} {1} w={2}u l={3}u\n".format(self.gnd_name,
temp_stim, self.nmos_name,
OPTS.openram_temp) size[0] * self.tx_width,
valid_retcode=0 self.tx_length))
elif OPTS.spice_name == "hspice": self.sf.write("mpinv2 out out_inv {0} {0} {1} w={2}u l={3}u\n".format(self.vdd_name,
# TODO: Should make multithreading parameter a configuration option self.pmos_name,
cmd = "{0} -mt 2 -i {1} -o {2}timing".format(OPTS.spice_exe, beta * size[1] * self.tx_width,
temp_stim, self.tx_length))
OPTS.openram_temp) self.sf.write("mninv2 out out_inv {0} {0} {1} w={2}u l={3}u\n".format(self.gnd_name,
valid_retcode=0 self.nmos_name,
else: size[1] * self.tx_width,
cmd = "{0} -b -o {2}timing.lis {1}".format(OPTS.spice_exe, self.tx_length))
temp_stim, self.sf.write(".ENDS test_{0}\n\n".format(buffer_name))
OPTS.openram_temp)
# for some reason, ngspice-25 returns 1 when it only has acceptable warnings
valid_retcode=1 def inst_buffer(self, buffer_name, signal_list):
""" Adds buffers to each top level signal that is in signal_list (only for sim purposes) """
for signal in signal_list:
self.sf.write("X{0}_buffer {0} {0}_buf {1} {2} test_{3}\n".format(signal,
"test"+self.vdd_name,
"test"+self.gnd_name,
buffer_name))
def inst_inverter(self, signal_list):
""" Adds inv for each signal that needs its inverted version (only for sim purposes) """
for signal in signal_list:
self.sf.write("X{0}_inv {0} {0}_inv {1} {2} test_inv\n".format(signal,
"test"+self.vdd_name,
"test"+self.gnd_name))
spice_stdout = open("{0}spice_stdout.log".format(OPTS.openram_temp), 'w') def inst_accesstx(self, dbits):
spice_stderr = open("{0}spice_stderr.log".format(OPTS.openram_temp), 'w') """ Adds transmission gate for inputs to data-bus (only for sim purposes) """
self.sf.write("* Tx Pin-list: Drain Gate Source Body\n")
for i in range(dbits):
pmos_access_string="mp{0} DATA[{0}] acc_en D[{0}] {1} {2} w={3}u l={4}u\n"
self.sf.write(pmos_access_string.format(i,
"test"+self.vdd_name,
self.pmos_name,
2 * self.tx_width,
self.tx_length))
nmos_access_string="mn{0} DATA[{0}] acc_en_inv D[{0}] {1} {2} w={3}u l={4}u\n"
self.sf.write(nmos_access_string.format(i,
"test"+self.gnd_name,
self.nmos_name,
2 * self.tx_width,
self.tx_length))
debug.info(3, cmd) def gen_pulse(self, sig_name, v1, v2, offset, period, t_rise, t_fall):
retcode = subprocess.call(cmd, stdout=spice_stdout, stderr=spice_stderr, shell=True) """
Generates a periodic signal with 50% duty cycle and slew rates. Period is measured
from 50% to 50%.
"""
self.sf.write("* PULSE: period={0}\n".format(period))
pulse_string="V{0} {0} 0 PULSE ({1} {2} {3}n {4}n {5}n {6}n {7}n)\n"
self.sf.write(pulse_string.format(sig_name,
v1,
v2,
offset,
t_rise,
t_fall,
0.5*period-0.5*t_rise-0.5*t_fall,
period))
spice_stdout.close()
spice_stderr.close() def gen_pwl(self, sig_name, clk_times, data_values, period, slew, setup):
"""
Generate a PWL stimulus given a signal name and data values at each period.
Automatically creates slews and ensures each data occurs a setup before the clock
edge. The first clk_time should be 0 and is the initial time that corresponds
to the initial value.
"""
# the initial value is not a clock time
debug.check(len(clk_times)==len(data_values),"Clock and data value lengths don't match.")
if (retcode > valid_retcode): # shift signal times earlier for setup time
debug.error("Spice simulation error: " + cmd, -1) times = np.array(clk_times) - setup*period
else: values = np.array(data_values) * self.voltage
end_time = datetime.datetime.now() half_slew = 0.5 * slew
delta_time = round((end_time-start_time).total_seconds(),1) self.sf.write("* (time, data): {}\n".format(zip(clk_times, data_values)))
debug.info(2,"*** Spice: {} seconds".format(delta_time)) self.sf.write("V{0} {0} 0 PWL (0n {1}v ".format(sig_name, values[0]))
for i in range(1,len(times)):
self.sf.write("{0}n {1}v {2}n {3}v ".format(times[i]-half_slew,
values[i-1],
times[i]+half_slew,
values[i]))
self.sf.write(")\n")
def gen_constant(self, sig_name, v_val):
""" Generates a constant signal with reference voltage and the voltage value """
self.sf.write("V{0} {0} 0 DC {1}\n".format(sig_name, v_val))
def get_inverse_voltage(self, value):
if value > 0.5*self.voltage:
return 0
elif value <= 0.5*self.voltage:
return self.voltage
else:
debug.error("Invalid value to get an inverse of: {0}".format(value))
def get_inverse_value(self, value):
if value > 0.5:
return 0
elif value <= 0.5:
return 1
else:
debug.error("Invalid value to get an inverse of: {0}".format(value))
def gen_meas_delay(self, meas_name, trig_name, targ_name, trig_val, targ_val, trig_dir, targ_dir, trig_td, targ_td):
""" Creates the .meas statement for the measurement of delay """
measure_string=".meas tran {0} TRIG v({1}) VAL={2} {3}=1 TD={4}n TARG v({5}) VAL={6} {7}=1 TD={8}n\n\n"
self.sf.write(measure_string.format(meas_name,
trig_name,
trig_val,
trig_dir,
trig_td,
targ_name,
targ_val,
targ_dir,
targ_td))
def gen_meas_power(self, meas_name, t_initial, t_final):
""" Creates the .meas statement for the measurement of avg power """
# power mea cmd is different in different spice:
if OPTS.spice_name == "hspice":
power_exp = "power"
else:
power_exp = "par('(-1*v(" + str(self.vdd_name) + ")*I(v" + str(self.vdd_name) + "))')"
self.sf.write(".meas tran {0} avg {1} from={2}n to={3}n\n\n".format(meas_name,
power_exp,
t_initial,
t_final))
def write_control(self, end_time):
""" Write the control cards to run and end the simulation """
# UIC is needed for ngspice to converge
self.sf.write(".TRAN 5p {0}n UIC\n".format(end_time))
if OPTS.spice_name == "ngspice":
# ngspice sometimes has convergence problems if not using gear method
# which is more accurate, but slower than the default trapezoid method
# Do not remove this or it may not converge due to some "pa_00" nodes
# unless you figure out what these are.
self.sf.write(".OPTIONS POST=1 RUNLVL=4 PROBE method=gear TEMP={}\n".format(self.temperature))
else:
self.sf.write(".OPTIONS POST=1 RUNLVL=4 PROBE TEMP={}\n".format(self.temperature))
# create plots for all signals
self.sf.write("* probe is used for hspice/xa, while plot is used in ngspice\n")
if OPTS.debug_level>0:
if OPTS.spice_name in ["hspice","xa"]:
self.sf.write(".probe V(*)\n")
else:
self.sf.write(".plot V(*)\n")
else:
self.sf.write("*.probe V(*)\n")
self.sf.write("*.plot V(*)\n")
# end the stimulus file
self.sf.write(".end\n\n")
def write_include(self, circuit):
"""Writes include statements, inputs are lists of model files"""
includes = self.device_models + [circuit]
self.sf.write("* {} process corner\n".format(self.process))
for item in list(includes):
if os.path.isfile(item):
self.sf.write(".include \"{0}\"\n".format(item))
else:
debug.error("Could not find spice model: {0}\nSet SPICE_MODEL_DIR to over-ride path.\n".format(item))
def write_supply(self):
""" Writes supply voltage statements """
self.sf.write("V{0} {0} 0.0 {1}\n".format(self.vdd_name, self.voltage))
self.sf.write("V{0} {0} 0.0 {1}\n".format(self.gnd_name, 0))
# This is for the test power supply
self.sf.write("V{0} {0} 0.0 {1}\n".format("test"+self.vdd_name, self.voltage))
self.sf.write("V{0} {0} 0.0 {1}\n".format("test"+self.gnd_name, 0))
def run_sim(self):
""" Run hspice in batch mode and output rawfile to parse. """
temp_stim = "{0}stim.sp".format(OPTS.openram_temp)
import datetime
start_time = datetime.datetime.now()
debug.check(OPTS.spice_exe!="","No spice simulator has been found.")
if OPTS.spice_name == "xa":
# Output the xa configurations here. FIXME: Move this to write it once.
xa_cfg = open("{}xa.cfg".format(OPTS.openram_temp), "w")
xa_cfg.write("set_sim_level -level 7\n")
xa_cfg.write("set_powernet_level 7 -node vdd\n")
xa_cfg.close()
cmd = "{0} {1} -c {2}xa.cfg -o {2}xa -mt 2".format(OPTS.spice_exe,
temp_stim,
OPTS.openram_temp)
valid_retcode=0
elif OPTS.spice_name == "hspice":
# TODO: Should make multithreading parameter a configuration option
cmd = "{0} -mt 2 -i {1} -o {2}timing".format(OPTS.spice_exe,
temp_stim,
OPTS.openram_temp)
valid_retcode=0
else:
# ngspice 27+ supports threading with "set num_threads=4" in the stimulus file or a .spiceinit
cmd = "{0} -b -o {2}timing.lis {1}".format(OPTS.spice_exe,
temp_stim,
OPTS.openram_temp)
# for some reason, ngspice-25 returns 1 when it only has acceptable warnings
valid_retcode=1
spice_stdout = open("{0}spice_stdout.log".format(OPTS.openram_temp), 'w')
spice_stderr = open("{0}spice_stderr.log".format(OPTS.openram_temp), 'w')
debug.info(3, cmd)
retcode = subprocess.call(cmd, stdout=spice_stdout, stderr=spice_stderr, shell=True)
spice_stdout.close()
spice_stderr.close()
if (retcode > valid_retcode):
debug.error("Spice simulation error: " + cmd, -1)
else:
end_time = datetime.datetime.now()
delta_time = round((end_time-start_time).total_seconds(),1)
debug.info(2,"*** Spice: {} seconds".format(delta_time))

View File

@ -1,8 +1,11 @@
word_size = 2 word_size = 2
num_words = 128 num_words = 16
num_banks = 1 num_banks = 1
tech_name = "freepdk45" tech_name = "freepdk45"
process_corners = ["TT"]
supply_voltages = [1.0]
temperatures = [25]
output_path = "temp" output_path = "temp"
output_name = "sram_2_16_1_freepdk45" output_name = "sram_2_16_1_freepdk45"

View File

@ -3,6 +3,10 @@ num_words = 16
num_banks = 1 num_banks = 1
tech_name = "scn3me_subm" tech_name = "scn3me_subm"
process_corners = ["TT"]
supply_voltages = [ 5.0 ]
temperatures = [ 25 ]
output_path = "temp" output_path = "temp"
output_name = "sram_2_16_1_scn3me_subm" output_name = "sram_2_16_1_scn3me_subm"

View File

@ -772,29 +772,36 @@ class VlsiLayout:
return boundaries return boundaries
def getPinInStructure(self,coordinates,layer,Structure): def getPinInStructure(self,coordinates,layer,structure):
""" """
Go through all the shapes in a structure and return the list of shapes Go through all the shapes in a structure and return the list of shapes
that the label coordinates are inside. that the label coordinates are inside.
""" """
StructureName=Structure[0]
StructureOrigin=[Structure[1][0],Structure[1][1]] # check if this is a rectangle
StructureuVector=[Structure[2][0],Structure[2][1],Structure[2][2]] structureName=structure[0]
StructurevVector=[Structure[3][0],Structure[3][1],Structure[3][2]] structureOrigin=[structure[1][0],structure[1][1]]
structureuVector=[structure[2][0],structure[2][1],structure[2][2]]
structurevVector=[structure[3][0],structure[3][1],structure[3][2]]
boundaries = [] boundaries = []
for boundary in self.structures[str(StructureName)].boundaries: for boundary in self.structures[str(structureName)].boundaries:
# Pin enclosures only work on rectangular pins so ignore any non rectangle
# This may report not finding pins, but the user should fix this by adding a rectangle.
if len(boundary.coordinates)!=5:
continue
if layer==boundary.drawingLayer: if layer==boundary.drawingLayer:
left_bottom=boundary.coordinates[0] left_bottom=boundary.coordinates[0]
right_top=boundary.coordinates[2] right_top=boundary.coordinates[2]
MetalBoundary=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]] # Rectangle is [leftx, bottomy, rightx, topy].
MetalBoundary=self.transformRectangle(MetalBoundary,StructureuVector,StructurevVector) boundaryRect=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]]
MetalBoundary=[MetalBoundary[0]+StructureOrigin[0],MetalBoundary[1]+StructureOrigin[1], boundaryRect=self.transformRectangle(boundaryRect,structureuVector,structurevVector)
MetalBoundary[2]+StructureOrigin[0],MetalBoundary[3]+StructureOrigin[1]] boundaryRect=[boundaryRect[0]+structureOrigin[0],boundaryRect[1]+structureOrigin[1],
boundaryRect[2]+structureOrigin[0],boundaryRect[3]+structureOrigin[1]]
if self.labelInRectangle(coordinates,MetalBoundary): if self.labelInRectangle(coordinates,boundaryRect):
boundaries.append(MetalBoundary) boundaries.append(boundaryRect)
return boundaries return boundaries
@ -829,7 +836,7 @@ class VlsiLayout:
def labelInRectangle(self,coordinate,rectangle): def labelInRectangle(self,coordinate,rectangle):
""" """
Checks if a coordinate is within a given rectangle. Checks if a coordinate is within a given rectangle. Rectangle is [leftx, bottomy, rightx, topy].
""" """
coordinate_In_Rectangle_x_range=(coordinate[0]>=int(rectangle[0]))&(coordinate[0]<=int(rectangle[2])) coordinate_In_Rectangle_x_range=(coordinate[0]>=int(rectangle[0]))&(coordinate[0]<=int(rectangle[2]))
coordinate_In_Rectangle_y_range=(coordinate[1]>=int(rectangle[1]))&(coordinate[1]<=int(rectangle[3])) coordinate_In_Rectangle_y_range=(coordinate[1]>=int(rectangle[1]))&(coordinate[1]<=int(rectangle[3]))

86
compiler/gen_stimulus.py Executable file
View File

@ -0,0 +1,86 @@
#!/usr/bin/env python2.7
"""
This script will generate a stimulus file for a given period, load, and slew input
for the given dimension SRAM. It is useful for debugging after an SRAM has been
created without re-running the entire process. Right now, it assumes the nominal
corner, but should probably be extended.
"""
import sys,os
import datetime
import re
import importlib
from globals import *
(OPTS, args) = parse_args()
# Override the usage
USAGE = "Usage: {} [options] <config file> <period in ns> <load in fF> <slew in ns>\nUse -h for help.\n".format(__file__)
# Check that we are left with a single configuration file as argument.
if len(args) != 4:
print(USAGE)
sys.exit(2)
# We need to get the:
# config file
config_file = args[0]
# period
period = float(args[1])
# load
load = float(args[2])
# slew
slew = float(args[3])
# These depend on arguments, so don't load them until now.
import debug
init_openram(config_file=config_file, is_unit_test=False)
OPTS.check_lvsdrc = False
# Put the temp output in the output path since it is what we want to generate!
old_openram_temp = OPTS.openram_temp
OPTS.openram_temp = OPTS.output_path
import sram
class fake_sram(sram.sram):
""" This is an SRAM that doesn't actually create itself, just computes
the sizes. """
def __init__(self, word_size, num_words, num_banks, name):
self.name = name
self.word_size = word_size
self.num_words = num_words
self.num_banks = num_banks
c = reload(__import__(OPTS.bitcell))
self.mod_bitcell = getattr(c, OPTS.bitcell)
self.bitcell = self.mod_bitcell()
# to get the row, col, etc.
self.compute_sizes()
sram = fake_sram(OPTS.word_size, OPTS.num_words, OPTS.num_banks, OPTS.output_name)
sp_file = OPTS.output_path+OPTS.output_name + ".sp"
from characterizer import delay
import tech
# Set up the delay and set to the nominal corner
d = delay.delay(sram, sp_file, ("TT", tech.spice["nom_supply_voltage"], tech.spice["nom_temperature"]))
# Set the period
d.period = period
# Set the load of outputs and slew of inputs
d.set_load_slew(load,slew)
# Set the probe address/bit
probe_address = "1" * sram.addr_size
probe_data = sram.word_size - 1
d.set_probe(probe_address, probe_data)
d.write_delay_stimulus()
# Output info about this run
report_status()
print("Output files are:\n{0}stim.sp\n{0}sram.sp\n{0}reduced.sp".format(OPTS.output_path))
OPTS.openram_temp = old_openram_temp
# Delete temp files, remove the dir, etc.
end_openram()

View File

@ -16,12 +16,6 @@ USAGE = "Usage: openram.py [options] <config file>\nUse -h for help.\n"
# Anonymous object that will be the options # Anonymous object that will be the options
OPTS = options.options() OPTS = options.options()
# check that we are not using version 3 and at least 2.7
major_python_version = sys.version_info.major
minor_python_version = sys.version_info.minor
if not (major_python_version == 2 and minor_python_version >= 7):
debug.error("Python 2.7 is required.",-1)
def parse_args(): def parse_args():
""" Parse the optional arguments for OpenRAM """ """ Parse the optional arguments for OpenRAM """
@ -36,8 +30,6 @@ def parse_args():
help="Output file(s) location"), help="Output file(s) location"),
optparse.make_option("-n", "--nocheck", action="store_false", optparse.make_option("-n", "--nocheck", action="store_false",
help="Disable inline LVS/DRC checks", dest="check_lvsdrc"), help="Disable inline LVS/DRC checks", dest="check_lvsdrc"),
optparse.make_option("-q", "--quiet", action="store_false", dest="print_banner",
help="Don\'t display banner"),
optparse.make_option("-v", "--verbose", action="count", dest="debug_level", optparse.make_option("-v", "--verbose", action="count", dest="debug_level",
help="Increase the verbosity level"), help="Increase the verbosity level"),
optparse.make_option("-t", "--tech", dest="tech_name", optparse.make_option("-t", "--tech", dest="tech_name",
@ -66,13 +58,13 @@ def parse_args():
# Alias SCMOS to AMI 0.5um # Alias SCMOS to AMI 0.5um
if OPTS.tech_name == "scmos": if OPTS.tech_name == "scmos":
OPTS.tech_name = "scn3me_subm" OPTS.tech_name = "scn3me_subm"
return (options, args) return (options, args)
def print_banner(): def print_banner():
""" Conditionally print the banner to stdout """ """ Conditionally print the banner to stdout """
global OPTS global OPTS
if not OPTS.print_banner: if OPTS.is_unit_test:
return return
print("|==============================================================================|") print("|==============================================================================|")
@ -85,22 +77,41 @@ def print_banner():
print("|=========" + "VLSI Computer Architecture Research Group".center(60) + "=========|") print("|=========" + "VLSI Computer Architecture Research Group".center(60) + "=========|")
print("|=========" + "Oklahoma State University ECE Department".center(60) + "=========|") print("|=========" + "Oklahoma State University ECE Department".center(60) + "=========|")
print("|=========" + " ".center(60) + "=========|") print("|=========" + " ".center(60) + "=========|")
print("|=========" + OPTS.openram_temp.center(60) + "=========|") user_info = "Usage help: openram-user-group@ucsc.edu"
print("|=========" + user_info.center(60) + "=========|")
dev_info = "Development help: openram-dev-group@ucsc.edu"
print("|=========" + dev_info.center(60) + "=========|")
temp_info = "Temp dir: {}".format(OPTS.openram_temp)
print("|=========" + temp_info.center(60) + "=========|")
print("|==============================================================================|") print("|==============================================================================|")
def init_openram(config_file): def check_versions():
""" Run some checks of required software versions. """
# check that we are not using version 3 and at least 2.7
major_python_version = sys.version_info.major
minor_python_version = sys.version_info.minor
if not (major_python_version == 2 and minor_python_version >= 7):
debug.error("Python 2.7 is required.",-1)
# FIXME: Check versions of other tools here??
# or, this could be done in each module (e.g. verify, characterizer, etc.)
def init_openram(config_file, is_unit_test=True):
"""Initialize the technology, paths, simulators, etc.""" """Initialize the technology, paths, simulators, etc."""
check_versions()
debug.info(1,"Initializing OpenRAM...") debug.info(1,"Initializing OpenRAM...")
setup_paths() setup_paths()
read_config(config_file) read_config(config_file, is_unit_test)
import_tech() import_tech()
def get_tool(tool_type, preferences): def get_tool(tool_type, preferences):
""" """
Find which tool we have from a list of preferences and return the Find which tool we have from a list of preferences and return the
@ -120,7 +131,7 @@ def get_tool(tool_type, preferences):
def read_config(config_file): def read_config(config_file, is_unit_test=True):
""" """
Read the configuration file that defines a few parameters. The Read the configuration file that defines a few parameters. The
config file is just a Python file that defines some config config file is just a Python file that defines some config
@ -156,8 +167,20 @@ def read_config(config_file):
if not OPTS.output_path.endswith('/'): if not OPTS.output_path.endswith('/'):
OPTS.output_path += "/" OPTS.output_path += "/"
if not OPTS.output_path.startswith('/'):
OPTS.output_path = os.getcwd() + "/" + OPTS.output_path
debug.info(1, "Output saved in " + OPTS.output_path) debug.info(1, "Output saved in " + OPTS.output_path)
OPTS.is_unit_test=is_unit_test
# If config didn't set output name, make a reasonable default.
if (OPTS.output_name == ""):
OPTS.output_name = "sram_{0}rw_{1}b_{2}w_{3}bank_{4}".format(OPTS.rw_ports,
OPTS.word_size,
OPTS.num_words,
OPTS.num_banks,
OPTS.tech_name)
# Don't delete the output dir, it may have other files! # Don't delete the output dir, it may have other files!
# make the directory if it doesn't exist # make the directory if it doesn't exist
try: try:
@ -173,6 +196,7 @@ def read_config(config_file):
def end_openram(): def end_openram():
""" Clean up openram for a proper exit """ """ Clean up openram for a proper exit """
cleanup_paths() cleanup_paths()
@ -197,16 +221,14 @@ def setup_paths():
except: except:
debug.error("$OPENRAM_HOME is not properly defined.",1) debug.error("$OPENRAM_HOME is not properly defined.",1)
debug.check(os.path.isdir(OPENRAM_HOME),"$OPENRAM_HOME does not exist: {0}".format(OPENRAM_HOME)) debug.check(os.path.isdir(OPENRAM_HOME),"$OPENRAM_HOME does not exist: {0}".format(OPENRAM_HOME))
debug.check(os.path.isdir(OPENRAM_HOME+"/gdsMill"), # Add all of the subdirs to the python path
"$OPENRAM_HOME/gdsMill does not exist: {0}".format(OPENRAM_HOME+"/gdsMill")) # These subdirs are modules and don't need to be added: characterizer, verify
sys.path.append("{0}/gdsMill".format(OPENRAM_HOME)) for subdir in ["gdsMill", "tests", "router", "modules", "base", "pgates"]:
debug.check(os.path.isdir(OPENRAM_HOME+"/tests"), full_path = "{0}/{1}".format(OPENRAM_HOME,subdir)
"$OPENRAM_HOME/tests does not exist: {0}".format(OPENRAM_HOME+"/tests")) debug.check(os.path.isdir(full_path),
sys.path.append("{0}/tests".format(OPENRAM_HOME)) "$OPENRAM_HOME/{0} does not exist: {1}".format(subdir,full_path))
debug.check(os.path.isdir(OPENRAM_HOME+"/router"), sys.path.append("{0}".format(full_path))
"$OPENRAM_HOME/router does not exist: {0}".format(OPENRAM_HOME+"/router"))
sys.path.append("{0}/router".format(OPENRAM_HOME))
if not OPTS.openram_temp.endswith('/'): if not OPTS.openram_temp.endswith('/'):
OPTS.openram_temp += "/" OPTS.openram_temp += "/"
@ -244,9 +266,8 @@ def import_tech():
# Set the tech to the config file we read in instead of the command line value. # Set the tech to the config file we read in instead of the command line value.
OPTS.tech_name = OPTS.tech_name OPTS.tech_name = OPTS.tech_name
# environment variable should point to the technology dir
# environment variable should point to the technology dir
try: try:
OPENRAM_TECH = os.path.abspath(os.environ.get("OPENRAM_TECH")) OPENRAM_TECH = os.path.abspath(os.environ.get("OPENRAM_TECH"))
except: except:
@ -270,3 +291,42 @@ def import_tech():
debug.error("Nonexistent technology_setup_file: {0}.py".format(filename)) debug.error("Nonexistent technology_setup_file: {0}.py".format(filename))
sys.exit(1) sys.exit(1)
import tech
# Set some default options now based on the technology...
if (OPTS.process_corners == ""):
OPTS.process_corners = tech.spice["fet_models"].keys()
if (OPTS.supply_voltages == ""):
OPTS.supply_voltages = tech.spice["supply_voltages"]
if (OPTS.temperatures == ""):
OPTS.temperatures = tech.spice["temperatures"]
def print_time(name, now_time, last_time=None):
""" Print a statement about the time delta. """
if last_time:
time = round((now_time-last_time).total_seconds(),1)
else:
time = now_time
print("** {0}: {1} seconds".format(name,time))
def report_status():
""" Check for valid arguments and report the info about the SRAM being generated """
# Check if all arguments are integers for bits, size, banks
if type(OPTS.word_size)!=int:
debug.error("{0} is not an integer in config file.".format(OPTS.word_size))
if type(OPTS.num_words)!=int:
debug.error("{0} is not an integer in config file.".format(OPTS.sram_size))
if type(OPTS.num_banks)!=int:
debug.error("{0} is not an integer in config file.".format(OPTS.num_banks))
if not OPTS.tech_name:
debug.error("Tech name must be specified in config file.")
print("Technology: {0}".format(OPTS.tech_name))
print("Word size: {0}\nWords: {1}\nBanks: {2}".format(OPTS.word_size,
OPTS.num_words,
OPTS.num_banks))
if not OPTS.check_lvsdrc:
print("DRC/LVS/PEX checking is disabled.")

View File

@ -69,9 +69,10 @@ class control_logic(design.design):
c = reload(__import__(OPTS.replica_bitline)) c = reload(__import__(OPTS.replica_bitline))
replica_bitline = getattr(c, OPTS.replica_bitline) replica_bitline = getattr(c, OPTS.replica_bitline)
# FIXME: These should be tuned according to the size! # FIXME: These should be tuned according to the size!
FO4_stages = 4 delay_stages = 4 # This should be even so that the delay line is inverting!
bitcell_loads = int(math.ceil(self.num_rows / 10.0)) delay_fanout = 3
self.replica_bitline = replica_bitline(FO4_stages, bitcell_loads) bitcell_loads = int(math.ceil(self.num_rows / 5.0))
self.replica_bitline = replica_bitline(delay_stages, delay_fanout, bitcell_loads)
self.add_mod(self.replica_bitline) self.add_mod(self.replica_bitline)

View File

@ -8,7 +8,8 @@ from globals import OPTS
class delay_chain(design.design): class delay_chain(design.design):
""" """
Generate a logic effort based delay chain. Generate a delay chain with the given number of stages and fanout.
This automatically adds an extra inverter with no load on the input.
Input is a list contains the electrical effort of each stage. Input is a list contains the electrical effort of each stage.
""" """
@ -19,6 +20,9 @@ class delay_chain(design.design):
# and there should be functions to get # and there should be functions to get
# area efficient inverter stage list # area efficient inverter stage list
for f in fanout_list:
debug.check(f>0,"Must have non-zero fanouts for each stage.")
# number of inverters including any fanout loads. # number of inverters including any fanout loads.
self.fanout_list = fanout_list self.fanout_list = fanout_list
self.num_inverters = 1 + sum(fanout_list) self.num_inverters = 1 + sum(fanout_list)

29
compiler/modules/dff.py Normal file
View File

@ -0,0 +1,29 @@
import globals
import design
from math import log
import design
from tech import GDS,layer
import utils
class dff(design.design):
"""
Memory address flip-flop
"""
pin_names = ["d", "q", "clk", "vdd", "gnd"]
(width,height) = utils.get_libcell_size("dff", GDS["unit"], layer["boundary"])
pin_map = utils.get_libcell_pins(pin_names, "dff", GDS["unit"], layer["boundary"])
def __init__(self, name="dff"):
design.design.__init__(self, name)
self.width = dff.width
self.height = dff.height
self.pin_map = dff.pin_map
def analytical_delay(self, slew, load = 0.0):
# dont know how to calculate this now, use constant in tech file
from tech import spice
result = self.return_delay(spice["dff_delay"], spice["dff_slew"])
return result

View File

@ -0,0 +1,141 @@
import debug
import design
from tech import drc
from math import log
from vector import vector
from globals import OPTS
class dff_array(design.design):
"""
This is a simple row (or multiple rows) of flops.
Unlike the data flops, these are never spaced out.
"""
def __init__(self, rows, columns, name=""):
self.rows = rows
self.columns = columns
if name=="":
name = "dff_array_{0}x{1}".format(rows, columns)
design.design.__init__(self, name)
debug.info(1, "Creating {}".format(self.name))
c = reload(__import__(OPTS.dff))
self.mod_dff = getattr(c, OPTS.dff)
self.ms = self.mod_dff("dff")
self.add_mod(self.ms)
self.width = self.columns * self.ms.width
self.height = self.rows * self.ms.height
self.create_layout()
def create_layout(self):
self.add_pins()
self.create_dff_array()
self.add_layout_pins()
self.DRC_LVS()
def add_pins(self):
for row in range(self.rows):
for col in range(self.columns):
self.add_pin("din[{0}][{1}]".format(row,col))
for row in range(self.rows):
for col in range(self.columns):
self.add_pin("dout[{0}][{1}]".format(row,col))
#self.add_pin("dout_bar[{0}]".format(i))
self.add_pin("clk")
self.add_pin("vdd")
self.add_pin("gnd")
def create_dff_array(self):
self.dff_insts={}
for y in range(self.rows):
for x in range(self.columns):
name = "Xdff_r{0}_c{1}".format(y,x)
if (y % 2 == 0):
base = vector(x*self.ms.width,y*self.ms.height)
mirror = "R0"
else:
base = vector(x*self.ms.width,(y+1)*self.ms.height)
mirror = "MX"
self.dff_insts[x,y]=self.add_inst(name=name,
mod=self.ms,
offset=base,
mirror=mirror)
self.connect_inst(["din[{0}][{1}]".format(x,y),
"dout[{0}][{1}]".format(x,y),
"clk",
"vdd",
"gnd"])
def add_layout_pins(self):
for y in range(self.rows):
# Continous vdd rail along with label.
vdd_pin=self.dff_insts[0,y].get_pin("vdd")
self.add_layout_pin(text="vdd",
layer="metal1",
offset=vdd_pin.ll(),
width=self.width,
height=self.m1_width)
# Continous gnd rail along with label.
gnd_pin=self.dff_insts[0,y].get_pin("gnd")
self.add_layout_pin(text="gnd",
layer="metal1",
offset=gnd_pin.ll(),
width=self.width,
height=self.m1_width)
for y in range(self.rows):
for x in range(self.columns):
din_pin = self.dff_insts[x,y].get_pin("d")
debug.check(din_pin.layer=="metal2","DFF d pin not on metal2")
self.add_layout_pin(text="din[{0}][{1}]".format(x,y),
layer=din_pin.layer,
offset=din_pin.ll(),
width=din_pin.width(),
height=din_pin.height())
dout_pin = self.dff_insts[x,y].get_pin("q")
debug.check(dout_pin.layer=="metal2","DFF q pin not on metal2")
self.add_layout_pin(text="dout[{0}][{1}]".format(x,y),
layer=dout_pin.layer,
offset=dout_pin.ll(),
width=dout_pin.width(),
height=dout_pin.height())
# Create vertical spines to a single horizontal rail
clk_pin = self.dff_insts[0,0].get_pin("clk")
debug.check(clk_pin.layer=="metal2","DFF clk pin not on metal2")
if self.columns==1:
self.add_layout_pin(text="clk",
layer="metal2",
offset=clk_pin.ll().scale(1,0),
width=self.m2_width,
height=self.height)
else:
self.add_layout_pin(text="clk",
layer="metal3",
offset=clk_pin.ll().scale(0,1),
width=self.width,
height=self.m3_width)
for x in range(self.columns):
clk_pin = self.dff_insts[x,0].get_pin("clk")
# Make a vertical strip for each column
self.add_layout_pin(text="clk",
layer="metal2",
offset=clk_pin.ll().scale(1,0),
width=self.m2_width,
height=self.height)
# Drop a via to the M3 pin
self.add_via_center(layers=("metal2","via2","metal3"),
offset=clk_pin.center())
def analytical_delay(self, slew, load=0.0):
return self.ms.analytical_delay(slew=slew, load=load)

View File

@ -29,13 +29,13 @@ class precharge(pgate.pgate):
self.DRC_LVS() self.DRC_LVS()
def add_pins(self): def add_pins(self):
self.add_pin_list(["bl", "br", "clk", "vdd"]) self.add_pin_list(["bl", "br", "en", "vdd"])
def create_layout(self): def create_layout(self):
self.create_ptx() self.create_ptx()
self.add_ptx() self.add_ptx()
self.connect_poly() self.connect_poly()
self.add_pclk() self.add_en()
self.add_nwell_and_contact() self.add_nwell_and_contact()
self.add_vdd_rail() self.add_vdd_rail()
self.add_bitlines() self.add_bitlines()
@ -74,7 +74,7 @@ class precharge(pgate.pgate):
self.lower_pmos_inst=self.add_inst(name="lower_pmos", self.lower_pmos_inst=self.add_inst(name="lower_pmos",
mod=self.pmos, mod=self.pmos,
offset=self.lower_pmos_position) offset=self.lower_pmos_position)
self.connect_inst(["bl", "clk", "BR", "vdd"]) self.connect_inst(["bl", "en", "BR", "vdd"])
# adds the upper pmos(s) to layout # adds the upper pmos(s) to layout
ydiff = self.pmos.height + 2*self.m1_space + contact.poly.width ydiff = self.pmos.height + 2*self.m1_space + contact.poly.width
@ -82,13 +82,13 @@ class precharge(pgate.pgate):
self.upper_pmos1_inst=self.add_inst(name="upper_pmos1", self.upper_pmos1_inst=self.add_inst(name="upper_pmos1",
mod=self.pmos, mod=self.pmos,
offset=self.upper_pmos1_pos) offset=self.upper_pmos1_pos)
self.connect_inst(["bl", "clk", "vdd", "vdd"]) self.connect_inst(["bl", "en", "vdd", "vdd"])
upper_pmos2_pos = self.upper_pmos1_pos + self.overlap_offset upper_pmos2_pos = self.upper_pmos1_pos + self.overlap_offset
self.upper_pmos2_inst=self.add_inst(name="upper_pmos2", self.upper_pmos2_inst=self.add_inst(name="upper_pmos2",
mod=self.pmos, mod=self.pmos,
offset=upper_pmos2_pos) offset=upper_pmos2_pos)
self.connect_inst(["br", "clk", "vdd", "vdd"]) self.connect_inst(["br", "en", "vdd", "vdd"])
def connect_poly(self): def connect_poly(self):
"""Connects the upper and lower pmos together""" """Connects the upper and lower pmos together"""
@ -109,16 +109,16 @@ class precharge(pgate.pgate):
width=xlength, width=xlength,
height=self.poly_width) height=self.poly_width)
def add_pclk(self): def add_en(self):
"""Adds the pclk input rail, pclk contact/vias, and connects to the pmos""" """Adds the en input rail, en contact/vias, and connects to the pmos"""
# adds the pclk contact to connect the gates to the pclk rail on metal1 # adds the en contact to connect the gates to the en rail on metal1
offset = self.lower_pmos_inst.get_pin("G").ul() + vector(0,0.5*self.poly_space) offset = self.lower_pmos_inst.get_pin("G").ul() + vector(0,0.5*self.poly_space)
self.add_contact_center(layers=("poly", "contact", "metal1"), self.add_contact_center(layers=("poly", "contact", "metal1"),
offset=offset, offset=offset,
rotate=90) rotate=90)
# adds the pclk rail on metal1 # adds the en rail on metal1
self.add_layout_pin_center_segment(text="clk", self.add_layout_pin_center_segment(text="en",
layer="metal1", layer="metal1",
start=offset.scale(0,1), start=offset.scale(0,1),
end=offset.scale(0,1)+vector(self.width,0)) end=offset.scale(0,1)+vector(self.width,0))

View File

@ -46,7 +46,7 @@ class precharge_array(design.design):
self.add_layout_pin(text="en", self.add_layout_pin(text="en",
layer="metal1", layer="metal1",
offset=self.pc_cell.get_pin("clk").ll(), offset=self.pc_cell.get_pin("en").ll(),
width=self.width, width=self.width,
height=drc["minwidth_metal1"]) height=drc["minwidth_metal1"])

View File

@ -11,11 +11,11 @@ from globals import OPTS
class replica_bitline(design.design): class replica_bitline(design.design):
""" """
Generate a module that simulates the delay of control logic Generate a module that simulates the delay of control logic
and bit line charging. Stages is the depth of the FO4 delay and bit line charging. Stages is the depth of the delay
line and rows is the height of the replica bit loads. line and rows is the height of the replica bit loads.
""" """
def __init__(self, FO4_stages, bitcell_loads, name="replica_bitline"): def __init__(self, delay_stages, delay_fanout, bitcell_loads, name="replica_bitline"):
design.design.__init__(self, name) design.design.__init__(self, name)
g = reload(__import__(OPTS.delay_chain)) g = reload(__import__(OPTS.delay_chain))
@ -30,7 +30,8 @@ class replica_bitline(design.design):
for pin in ["en", "out", "vdd", "gnd"]: for pin in ["en", "out", "vdd", "gnd"]:
self.add_pin(pin) self.add_pin(pin)
self.bitcell_loads = bitcell_loads self.bitcell_loads = bitcell_loads
self.FO4_stages = FO4_stages self.delay_stages = delay_stages
self.delay_fanout = delay_fanout
self.create_modules() self.create_modules()
self.calculate_module_offsets() self.calculate_module_offsets()
@ -83,7 +84,7 @@ class replica_bitline(design.design):
self.add_mod(self.rbl) self.add_mod(self.rbl)
# FIXME: The FO and depth of this should be tuned # FIXME: The FO and depth of this should be tuned
self.delay_chain = self.mod_delay_chain([4]*self.FO4_stages) self.delay_chain = self.mod_delay_chain([self.delay_fanout]*self.delay_stages)
self.add_mod(self.delay_chain) self.add_mod(self.delay_chain)
self.inv = pinv() self.inv = pinv()

View File

@ -14,116 +14,49 @@ import sys,os
import datetime import datetime
import re import re
import importlib import importlib
import globals from globals import *
(OPTS, args) = globals.parse_args() (OPTS, args) = parse_args()
# Check that we are left with a single configuration file as argument.
if len(args) != 1:
print(USAGE)
sys.exit(2)
def print_time(name, now_time, last_time=None):
if last_time:
time = round((now_time-last_time).total_seconds(),1)
else:
time = now_time
print("** {0}: {1} seconds".format(name,time))
return now_time
# These depend on arguments, so don't load them until now. # These depend on arguments, so don't load them until now.
import debug import debug
# required positional args for using openram main exe
if len(args) < 1:
print(globals.USAGE)
sys.exit(2)
globals.print_banner() init_openram(config_file=args[0], is_unit_test=False)
globals.init_openram(args[0]) # Only print banner here so it's not in unit tests
print_banner()
# Check if all arguments are integers for bits, size, banks # Output info about this run
if type(OPTS.word_size)!=int: report_status()
debug.error("{0} is not an integer in config file.".format(OPTS.word_size))
if type(OPTS.num_words)!=int:
debug.error("{0} is not an integer in config file.".format(OPTS.sram_size))
if type(OPTS.num_banks)!=int:
debug.error("{0} is not an integer in config file.".format(OPTS.num_banks))
if not OPTS.tech_name: # Start importing design modules after we have the config file
debug.error("Tech name must be specified in config file.")
word_size = OPTS.word_size
num_words = OPTS.num_words
num_banks = OPTS.num_banks
if (OPTS.output_name == ""):
OPTS.output_name = "sram_{0}_{1}_{2}_{3}".format(word_size,
num_words,
num_banks,
OPTS.tech_name)
print("Output files are " + OPTS.output_name + ".(sp|gds|v|lib|lef)")
print("Technology: {0}".format(OPTS.tech_name))
print("Word size: {0}\nWords: {1}\nBanks: {2}".format(word_size,num_words,num_banks))
# only start importing modules after we have the config file
import verify import verify
import sram import sram
print("Output files are " + OPTS.output_name + ".(sp|gds|v|lib|lef)")
# Keep track of running stats
start_time = datetime.datetime.now() start_time = datetime.datetime.now()
last_time = start_time print_time("Start",start_time)
print_time("Start",datetime.datetime.now())
if not OPTS.check_lvsdrc:
print("DRC/LVS/PEX checking is disabled.")
# import SRAM test generation # import SRAM test generation
s = sram.sram(word_size=word_size, s = sram.sram(word_size=OPTS.word_size,
num_words=num_words, num_words=OPTS.num_words,
num_banks=num_banks, num_banks=OPTS.num_banks,
name=OPTS.output_name) name=OPTS.output_name)
last_time=print_time("SRAM creation", datetime.datetime.now(), last_time)
# Output the files for the resulting SRAM # Output the files for the resulting SRAM
s.save_output()
spname = OPTS.output_path + s.name + ".sp" # Delete temp files etc.
print("SP: Writing to {0}".format(spname)) end_openram()
s.sp_write(spname)
last_time=print_time("Spice writing", datetime.datetime.now(), last_time)
# Output the extracted design
sram_file = spname
if OPTS.use_pex:
sram_file = OPTS.output_path + "temp_pex.sp"
verify.run_pex(s.name, gdsname, spname, output=sram_file)
# Characterize the design
from characterizer import lib
libname = OPTS.output_path + s.name + ".lib"
print("LIB: Writing to {0}".format(libname))
if OPTS.analytical_delay:
print("Using analytical delay models (no characterization)")
else:
if OPTS.spice_name!="":
print("Performing simulation-based characterization with {}".format(OPTS.spice_name))
if OPTS.trim_netlist:
print("Trimming netlist to speed up characterization.")
lib.lib(libname,s,sram_file)
last_time=print_time("Characterization", datetime.datetime.now(), last_time)
# Write the layout
gdsname = OPTS.output_path + s.name + ".gds"
print("GDS: Writing to {0}".format(gdsname))
s.gds_write(gdsname)
last_time=print_time("GDS", datetime.datetime.now(), last_time)
# Create a LEF physical model
lefname = OPTS.output_path + s.name + ".lef"
print("LEF: Writing to {0}".format(lefname))
s.lef_write(lefname)
last_time=print_time("LEF", datetime.datetime.now(), last_time)
# Write a verilog model
vname = OPTS.output_path + s.name + ".v"
print("Verilog: Writing to {0}".format(vname))
s.verilog_write(vname)
last_time=print_time("Verilog", datetime.datetime.now(), last_time)
globals.end_openram()
print_time("End",datetime.datetime.now(), start_time) print_time("End",datetime.datetime.now(), start_time)

View File

@ -39,17 +39,27 @@ class options(optparse.Values):
# Define the output file paths # Define the output file paths
output_path = "." output_path = "."
# Define the output file base name # Define the output file base name
output_name = "sram" output_name = ""
# Use analytical delay models by default rather than (slow) characterization # Use analytical delay models by default rather than (slow) characterization
analytical_delay = True analytical_delay = True
# Purge the temp directory after a successful run (doesn't purge on errors, anyhow) # Purge the temp directory after a successful run (doesn't purge on errors, anyhow)
purge_temp = True purge_temp = True
# These are the configuration parameters
rw_ports = 1
r_ports = 0
# These will get initialized by the the file
supply_voltages = ""
temperatures = ""
process_corners = ""
# These are the default modules that can be over-riden # These are the default modules that can be over-riden
decoder = "hierarchical_decoder" decoder = "hierarchical_decoder"
ms_flop = "ms_flop" ms_flop = "ms_flop"
ms_flop_array = "ms_flop_array" ms_flop_array = "ms_flop_array"
dff = "dff"
dff_array = "dff_array"
control_logic = "control_logic" control_logic = "control_logic"
bitcell_array = "bitcell_array" bitcell_array = "bitcell_array"
sense_amp = "sense_amp" sense_amp = "sense_amp"

View File

@ -8,7 +8,7 @@ from bank import bank
import datetime import datetime
import getpass import getpass
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS, print_time
class sram(design.design): class sram(design.design):
@ -45,6 +45,7 @@ class sram(design.design):
debug.info(2, "create sram of size {0} with {1} num of words".format(self.word_size, debug.info(2, "create sram of size {0} with {1} num of words".format(self.word_size,
self.num_words)) self.num_words))
start_time = datetime.datetime.now()
design.design.__init__(self, name) design.design.__init__(self, name)
@ -74,6 +75,10 @@ class sram(design.design):
self.DRC_LVS(final_verification=True) self.DRC_LVS(final_verification=True)
if not OPTS.is_unit_test:
print_time("SRAM creation", datetime.datetime.now(), start_time)
def compute_sizes(self): def compute_sizes(self):
""" Computes the organization of the memory using bitcell size by trying to make it square.""" """ Computes the organization of the memory using bitcell size by trying to make it square."""
@ -1009,3 +1014,60 @@ class sram(design.design):
def analytical_delay(self,slew,load): def analytical_delay(self,slew,load):
""" LH and HL are the same in analytical model. """ """ LH and HL are the same in analytical model. """
return self.bank.analytical_delay(slew,load) return self.bank.analytical_delay(slew,load)
def save_output(self):
""" Save all the output files while reporting time to do it as well. """
# Save the spice file
start_time = datetime.datetime.now()
spname = OPTS.output_path + self.name + ".sp"
print("SP: Writing to {0}".format(spname))
self.sp_write(spname)
print_time("Spice writing", datetime.datetime.now(), start_time)
# Save the extracted spice file
if OPTS.use_pex:
start_time = datetime.datetime.now()
# Output the extracted design if requested
sp_file = OPTS.output_path + "temp_pex.sp"
verify.run_pex(self.name, gdsname, spname, output=sp_file)
print_time("Extraction", datetime.datetime.now(), start_time)
else:
# Use generated spice file for characterization
sp_file = spname
# Characterize the design
start_time = datetime.datetime.now()
from characterizer import lib
print("LIB: Characterizing... ")
if OPTS.analytical_delay:
print("Using analytical delay models (no characterization)")
else:
if OPTS.spice_name!="":
print("Performing simulation-based characterization with {}".format(OPTS.spice_name))
if OPTS.trim_netlist:
print("Trimming netlist to speed up characterization.")
lib.lib(out_dir=OPTS.output_path, sram=self, sp_file=sp_file)
print_time("Characterization", datetime.datetime.now(), start_time)
# Write the layout
start_time = datetime.datetime.now()
gdsname = OPTS.output_path + self.name + ".gds"
print("GDS: Writing to {0}".format(gdsname))
self.gds_write(gdsname)
print_time("GDS", datetime.datetime.now(), start_time)
# Create a LEF physical model
start_time = datetime.datetime.now()
lefname = OPTS.output_path + self.name + ".lef"
print("LEF: Writing to {0}".format(lefname))
self.lef_write(lefname)
print_time("LEF", datetime.datetime.now(), start_time)
# Write a verilog model
start_time = datetime.datetime.now()
vname = OPTS.output_path + self.name + ".v"
print("Verilog: Writing to {0}".format(vname))
self.verilog_write(vname)
print_time("Verilog", datetime.datetime.now(), start_time)

View File

@ -35,6 +35,8 @@ class code_format_test(openram_test):
continue continue
if re.search("openram.py$", code): if re.search("openram.py$", code):
continue continue
if re.search("gen_stimulus.py$", code):
continue
errors += check_print_output(code) errors += check_print_output(code)
# fails if there are any tabs in any files # fails if there are any tabs in any files

View File

@ -0,0 +1,44 @@
#!/usr/bin/env python2.7
"""
Run a regresion test on a dff_array.
"""
import unittest
from testutils import header,openram_test
import sys,os
sys.path.append(os.path.join(sys.path[0],".."))
import globals
from globals import OPTS
import debug
class dff_array_test(openram_test):
def runTest(self):
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
global verify
import verify
OPTS.check_lvsdrc = False
import dff_array
debug.info(2, "Testing dff_array for 3x3")
a = dff_array.dff_array(rows=3, columns=3)
self.local_check(a)
debug.info(2, "Testing dff_array for 1x3")
a = dff_array.dff_array(rows=1, columns=3)
self.local_check(a)
debug.info(2, "Testing dff_array for 3x1")
a = dff_array.dff_array(rows=3, columns=1)
self.local_check(a)
OPTS.check_lvsdrc = True
globals.end_openram()
# instantiate a copdsay of the class to actually run the test
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main()

View File

@ -22,15 +22,16 @@ class replica_bitline_test(openram_test):
import replica_bitline import replica_bitline
stages=4 stages=4
fanout=4
rows=13 rows=13
debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows)) debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows))
a = replica_bitline.replica_bitline(stages,rows) a = replica_bitline.replica_bitline(stages,fanout,rows)
self.local_check(a) self.local_check(a)
stages=8 stages=8
rows=100 rows=100
debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows)) debug.info(2, "Testing RBL with {0} FO4 stages, {1} rows".format(stages,rows))
a = replica_bitline.replica_bitline(stages,rows) a = replica_bitline.replica_bitline(stages,fanout,rows)
self.local_check(a) self.local_check(a)
OPTS.check_lvsdrc = True OPTS.check_lvsdrc = True

View File

@ -27,7 +27,7 @@ class timing_sram_test(openram_test):
debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1) debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1)
import sram import sram
import tech
debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank") debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank")
s = sram.sram(word_size=OPTS.word_size, s = sram.sram(word_size=OPTS.word_size,
num_words=OPTS.num_words, num_words=OPTS.num_words,
@ -43,32 +43,35 @@ class timing_sram_test(openram_test):
probe_data = s.word_size - 1 probe_data = s.word_size - 1
debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data)) debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data))
d = delay.delay(s,tempspice) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
d = delay.delay(s,tempspice,corner)
import tech import tech
loads = [tech.spice["FF_in_cap"]*4] loads = [tech.spice["msflop_in_cap"]*4]
slews = [tech.spice["rise_time"]*2] slews = [tech.spice["rise_time"]*2]
data = d.analyze(probe_address, probe_data,slews,loads) data = d.analyze(probe_address, probe_data,slews,loads)
#print data #print data
if OPTS.tech_name == "freepdk45": if OPTS.tech_name == "freepdk45":
golden_data = {'read1_power': 0.0345742, golden_data = {'leakage_power': 0.0006964536000000001,
'read0_power': 0.03526189999999999, 'delay_lh': [0.0573055],
'write0_power': 0.0270014, 'read0_power': [0.0337812],
'delay1': [0.0573107], 'read1_power': [0.032946500000000004],
'delay0': [0.07055809999999998], 'write1_power': [0.0361529],
'min_period': 0.234, 'write0_power': [0.026179099999999997],
'write1_power': 0.0376625, 'slew_hl': [0.0285185],
'slew0': [0.0284344], 'min_period': 0.205,
'slew1': [0.0189185]} 'delay_hl': [0.070554],
'slew_lh': [0.0190073]}
elif OPTS.tech_name == "scn3me_subm": elif OPTS.tech_name == "scn3me_subm":
golden_data = {'read1_power': 11.2474, golden_data = {'leakage_power': 0.0004004581,
'read0_power': 11.3148, 'delay_lh': [0.6538954],
'write0_power': 6.9064, 'read0_power': [9.7622],
'delay1': [1.0298], 'read1_power': [9.589],
'delay0': [1.4102], 'write1_power': [10.2578],
'min_period': 4.063, 'write0_power': [6.928400000000001],
'write1_power': 11.6964, 'slew_hl': [0.8321625],
'slew0': [1.3118], 'min_period': 2.344,
'slew1': [0.9816656]} 'delay_hl': [0.9019090999999999],
'slew_lh': [0.5896232]}
else: else:
self.assertTrue(False) # other techs fail self.assertTrue(False) # other techs fail
# Check if no too many or too few results # Check if no too many or too few results

View File

@ -31,19 +31,20 @@ class timing_setup_test(openram_test):
import tech import tech
slews = [tech.spice["rise_time"]*2] slews = [tech.spice["rise_time"]*2]
sh = setup_hold.setup_hold() corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
sh = setup_hold.setup_hold(corner)
data = sh.analyze(slews,slews) data = sh.analyze(slews,slews)
#print data
if OPTS.tech_name == "freepdk45": if OPTS.tech_name == "freepdk45":
golden_data = {'setup_times_LH': [0.014648399999999999], golden_data = {'setup_times_LH': [0.014648399999999999],
'hold_times_LH': [0.0024414], 'hold_times_LH': [0.0024414],
'hold_times_HL': [-0.0036620999999999997], 'hold_times_HL': [-0.0036620999999999997],
'setup_times_HL': [0.0085449]} 'setup_times_HL': [0.0085449]}
elif OPTS.tech_name == "scn3me_subm": elif OPTS.tech_name == "scn3me_subm":
golden_data = {'setup_times_LH': [0.1000977], golden_data = {'setup_times_LH': [0.08178709999999999],
'hold_times_LH': [0.020751999999999996], 'hold_times_LH': [0.0024414],
'hold_times_HL': [-0.0830078], 'hold_times_HL': [-0.0646973],
'setup_times_HL': [0.020751999999999996]} 'setup_times_HL': [0.0390625]}
else: else:
self.assertTrue(False) # other techs fail self.assertTrue(False) # other techs fail

View File

@ -27,7 +27,7 @@ class timing_sram_test(openram_test):
debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1) debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1)
import sram import sram
import tech
debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank") debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank")
s = sram.sram(word_size=OPTS.word_size, s = sram.sram(word_size=OPTS.word_size,
num_words=OPTS.num_words, num_words=OPTS.num_words,
@ -41,32 +41,35 @@ class timing_sram_test(openram_test):
probe_data = s.word_size - 1 probe_data = s.word_size - 1
debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data)) debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data))
d = delay.delay(s,tempspice) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
d = delay.delay(s,tempspice,corner)
import tech import tech
loads = [tech.spice["FF_in_cap"]*4] loads = [tech.spice["msflop_in_cap"]*4]
slews = [tech.spice["rise_time"]*2] slews = [tech.spice["rise_time"]*2]
data = d.analyze(probe_address, probe_data,slews,loads) data = d.analyze(probe_address, probe_data,slews,loads)
#print data #print data
if OPTS.tech_name == "freepdk45": if OPTS.tech_name == "freepdk45":
golden_data = {'read1_power': 0.03308298, golden_data = {'leakage_power': 0.0007348262,
'read0_power': 0.03866541, 'delay_lh': [0.05799613],
'write0_power': 0.02695139, 'read0_power': [0.0384102],
'delay1': [0.05840294000000001], 'read1_power': [0.03279848],
'delay0': [0.40787249999999997], 'write1_power': [0.03693655],
'min_period': 0.781, 'write0_power': [0.02717752],
'write1_power': 0.037257830000000006, 'slew_hl': [0.03607912],
'slew0': [0.035826199999999996], 'min_period': 0.742,
'slew1': [0.02059459]} 'delay_hl': [0.3929995],
'slew_lh': [0.02160862]}
elif OPTS.tech_name == "scn3me_subm": elif OPTS.tech_name == "scn3me_subm":
golden_data = {'read1_power': 10.31395, golden_data = {'leakage_power': 0.00142014,
'read0_power': 10.0321, 'delay_lh': [0.8018421],
'write0_power': 6.072756, 'read0_power': [11.44908],
'delay1': [1.042564], 'read1_power': [11.416549999999999],
'delay0': [1.412224], 'write1_power': [11.718020000000001],
'min_period': 4.688, 'write0_power': [8.250219],
'write1_power': 10.53758, 'slew_hl': [0.8273725],
'slew0': [1.355812], 'min_period': 2.734,
'slew1': [1.03401]} 'delay_hl': [1.085861],
'slew_lh': [0.5730144]}
else: else:
self.assertTrue(False) # other techs fail self.assertTrue(False) # other techs fail

View File

@ -30,19 +30,20 @@ class timing_setup_test(openram_test):
import tech import tech
slews = [tech.spice["rise_time"]*2] slews = [tech.spice["rise_time"]*2]
sh = setup_hold.setup_hold() corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
sh = setup_hold.setup_hold(corner)
data = sh.analyze(slews,slews) data = sh.analyze(slews,slews)
#print data
if OPTS.tech_name == "freepdk45": if OPTS.tech_name == "freepdk45":
golden_data = {'setup_times_LH': [0.01464844], golden_data = {'setup_times_LH': [0.01464844],
'hold_times_LH': [0.0024414059999999997], 'hold_times_LH': [0.0024414059999999997],
'hold_times_HL': [-0.003662109], 'hold_times_HL': [-0.003662109],
'setup_times_HL': [0.008544922]} 'setup_times_HL': [0.008544922]}
elif OPTS.tech_name == "scn3me_subm": elif OPTS.tech_name == "scn3me_subm":
golden_data = {'setup_times_LH': [0.1000977], golden_data = {'setup_times_LH': [0.07568359],
'hold_times_LH': [0.02075195], 'hold_times_LH': [0.008544922],
'hold_times_HL': [-0.08300781], 'hold_times_HL': [-0.05859374999999999],
'setup_times_HL': [0.02075195]} 'setup_times_HL': [0.03295898]}
else: else:
self.assertTrue(False) # other techs fail self.assertTrue(False) # other techs fail

View File

@ -29,9 +29,9 @@ class sram_func_test(openram_test):
import sram import sram
debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank") debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank")
s = sram.sram(word_size=OPTS.word_size, s = sram.sram(word_size=1,
num_words=OPTS.num_words, num_words=16,
num_banks=OPTS.num_banks, num_banks=1,
name="sram_func_test") name="sram_func_test")
OPTS.check_lvsdrc = True OPTS.check_lvsdrc = True
@ -43,14 +43,15 @@ class sram_func_test(openram_test):
probe_data = s.word_size - 1 probe_data = s.word_size - 1
debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data)) debug.info(1, "Probe address {0} probe data {1}".format(probe_address, probe_data))
d = delay.delay(s,tempspice) corner = (OPTS.process_corners[0], OPTS.supply_voltages[0], OPTS.temperatures[0])
d = delay.delay(s,tempspice,corner)
d.set_probe(probe_address,probe_data) d.set_probe(probe_address,probe_data)
# This will exit if it doesn't find a feasible period # This will exit if it doesn't find a feasible period
import tech import tech
load = tech.spice["FF_in_cap"]*4 d.load = tech.spice["msflop_in_cap"]*4
slew = tech.spice["rise_time"]*2 d.slew = tech.spice["rise_time"]*2
feasible_period = d.find_feasible_period(load,slew) feasible_period = d.find_feasible_period()
os.remove(tempspice) os.remove(tempspice)
OPTS.analytical_delay = True OPTS.analytical_delay = True

View File

@ -5,7 +5,7 @@ Check the .lib file for an SRAM
import unittest import unittest
from testutils import header,openram_test from testutils import header,openram_test
import sys,os import sys,os,re
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
from globals import OPTS from globals import OPTS
@ -22,22 +22,28 @@ class lib_test(openram_test):
debug.info(1, "Testing timing for sample 2 bit, 16 words SRAM with 1 bank") debug.info(1, "Testing timing for sample 2 bit, 16 words SRAM with 1 bank")
s = sram.sram(word_size=2, s = sram.sram(word_size=2,
num_words=OPTS.num_words, num_words=16,
num_banks=OPTS.num_banks, num_banks=1,
name="sram_2_16_1_{0}".format(OPTS.tech_name)) name="sram_2_16_1_{0}".format(OPTS.tech_name))
OPTS.check_lvsdrc = True OPTS.check_lvsdrc = True
tempspice = OPTS.openram_temp + "temp.sp" tempspice = OPTS.openram_temp + "temp.sp"
s.sp_write(tempspice) s.sp_write(tempspice)
filename = s.name + "_analytical.lib" lib.lib(out_dir=OPTS.openram_temp, sram=s, sp_file=tempspice, use_model=True)
libname = OPTS.openram_temp + filename
lib.lib(libname=libname,sram=s,spfile=tempspice,use_model=True)
# let's diff the result with a golden model # get all of the .lib files generated
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),filename) files = os.listdir(OPTS.openram_temp)
self.isapproxdiff(libname,golden,0.15) nametest = re.compile("\.lib$", re.IGNORECASE)
lib_files = filter(nametest.search, files)
# and compare them with the golden model
for filename in lib_files:
newname = filename.replace(".lib","_analytical.lib")
libname = "{0}/{1}".format(OPTS.openram_temp,filename)
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),newname)
self.isapproxdiff(libname,golden,0.15)
globals.end_openram() globals.end_openram()
# instantiate a copdsay of the class to actually run the test # instantiate a copdsay of the class to actually run the test

View File

@ -5,7 +5,7 @@ Check the .lib file for an SRAM with pruning
import unittest import unittest
from testutils import header,openram_test from testutils import header,openram_test
import sys,os import sys,os,re
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
from globals import OPTS from globals import OPTS
@ -31,21 +31,27 @@ class lib_test(openram_test):
debug.info(1, "Testing timing for sample 2 bit, 16 words SRAM with 1 bank") debug.info(1, "Testing timing for sample 2 bit, 16 words SRAM with 1 bank")
s = sram.sram(word_size=2, s = sram.sram(word_size=2,
num_words=OPTS.num_words, num_words=16,
num_banks=OPTS.num_banks, num_banks=1,
name="sram_2_16_1_{0}".format(OPTS.tech_name)) name="sram_2_16_1_{0}".format(OPTS.tech_name))
OPTS.check_lvsdrc = True OPTS.check_lvsdrc = True
tempspice = OPTS.openram_temp + "temp.sp" tempspice = OPTS.openram_temp + "temp.sp"
s.sp_write(tempspice) s.sp_write(tempspice)
filename = s.name + "_pruned.lib" lib.lib(out_dir=OPTS.openram_temp, sram=s, sp_file=tempspice, use_model=False)
libname = OPTS.openram_temp + filename
lib.lib(libname=libname,sram=s,spfile=tempspice,use_model=False) # get all of the .lib files generated
files = os.listdir(OPTS.openram_temp)
# let's diff the result with a golden model nametest = re.compile("\.lib$", re.IGNORECASE)
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),filename) lib_files = filter(nametest.search, files)
self.isapproxdiff(libname,golden,0.30)
# and compare them with the golden model
for filename in lib_files:
newname = filename.replace(".lib","_pruned.lib")
libname = "{0}/{1}".format(OPTS.openram_temp,filename)
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),newname)
self.isapproxdiff(libname,golden,0.15)
OPTS.analytical_delay = True OPTS.analytical_delay = True
reload(characterizer) reload(characterizer)

View File

@ -5,7 +5,7 @@ Check the .lib file for an SRAM
import unittest import unittest
from testutils import header,openram_test from testutils import header,openram_test
import sys,os import sys,os,re
sys.path.append(os.path.join(sys.path[0],"..")) sys.path.append(os.path.join(sys.path[0],".."))
import globals import globals
from globals import OPTS from globals import OPTS
@ -31,21 +31,26 @@ class lib_test(openram_test):
debug.info(1, "Testing timing for sample 2 bit, 16 words SRAM with 1 bank") debug.info(1, "Testing timing for sample 2 bit, 16 words SRAM with 1 bank")
s = sram.sram(word_size=2, s = sram.sram(word_size=2,
num_words=OPTS.num_words, num_words=16,
num_banks=OPTS.num_banks, num_banks=1,
name="sram_2_16_1_{0}".format(OPTS.tech_name)) name="sram_2_16_1_{0}".format(OPTS.tech_name))
OPTS.check_lvsdrc = True OPTS.check_lvsdrc = True
tempspice = OPTS.openram_temp + "temp.sp" tempspice = OPTS.openram_temp + "temp.sp"
s.sp_write(tempspice) s.sp_write(tempspice)
filename = s.name + ".lib" lib.lib(out_dir=OPTS.openram_temp, sram=s, sp_file=tempspice, use_model=False)
libname = OPTS.openram_temp + filename
lib.lib(libname=libname,sram=s,spfile=tempspice,use_model=False) # get all of the .lib files generated
files = os.listdir(OPTS.openram_temp)
# let's diff the result with a golden model nametest = re.compile("\.lib$", re.IGNORECASE)
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),filename) lib_files = filter(nametest.search, files)
self.isapproxdiff(libname,golden,0.15)
# and compare them with the golden model
for filename in lib_files:
libname = "{0}/{1}".format(OPTS.openram_temp,filename)
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),filename)
self.isapproxdiff(libname,golden,0.15)
OPTS.analytical_delay = True OPTS.analytical_delay = True
OPTS.trim_netlist = True OPTS.trim_netlist = True

View File

@ -52,11 +52,16 @@ class openram_test(openram_test):
os.system(cmd) os.system(cmd)
# assert an error until we actually check a resul # assert an error until we actually check a resul
for extension in ["gds", "v", "lef", "lib", "sp"]: for extension in ["gds", "v", "lef", "sp"]:
filename = "{0}/{1}.{2}".format(out_path,out_file,extension) filename = "{0}/{1}.{2}".format(out_path,out_file,extension)
debug.info(1,"Checking for file: " + filename) debug.info(1,"Checking for file: " + filename)
self.assertEqual(os.path.exists(filename),True) self.assertEqual(os.path.exists(filename),True)
# Make sure there is any .lib file
import glob
files = glob.glob('{0}/*.lib'.format(out_path))
self.assertTrue(len(files)>0)
# grep any errors from the output # grep any errors from the output
output = open("{0}/output.log".format(out_path),"r").read() output = open("{0}/output.log".format(out_path),"r").read()
self.assertEqual(len(re.findall('ERROR',output)),0) self.assertEqual(len(re.findall('ERROR',output)),0)

View File

@ -3,5 +3,8 @@ num_words = 16
num_banks = 1 num_banks = 1
tech_name = "freepdk45" tech_name = "freepdk45"
process_corners = ["TT"]
supply_voltages = [1.0]
temperatures = [25]

View File

@ -3,4 +3,7 @@ num_words = 16
num_banks = 1 num_banks = 1
tech_name = "scn3me_subm" tech_name = "scn3me_subm"
process_corners = ["TT"]
supply_voltages = [5.0]
temperatures = [25]

View File

@ -7,11 +7,11 @@ UNITS
END UNITS END UNITS
SITE MacroSite SITE MacroSite
CLASS Core ; CLASS Core ;
SIZE 21695.0 by 42337.5 ; SIZE 24385.0 by 42337.5 ;
END MacroSite END MacroSite
MACRO sram_2_16_1_freepdk45 MACRO sram_2_16_1_freepdk45
CLASS BLOCK ; CLASS BLOCK ;
SIZE 21695.0 BY 42337.5 ; SIZE 24385.0 BY 42337.5 ;
SYMMETRY X Y R90 ; SYMMETRY X Y R90 ;
SITE MacroSite ; SITE MacroSite ;
PIN DATA[0] PIN DATA[0]
@ -4165,12 +4165,15 @@ MACRO sram_2_16_1_freepdk45
RECT 750.0 30905.0 685.0 30970.0 ; RECT 750.0 30905.0 685.0 30970.0 ;
RECT 32.5 30615.0 -32.5 31175.0 ; RECT 32.5 30615.0 -32.5 31175.0 ;
RECT 1377.5 30615.0 1312.5 31175.0 ; RECT 1377.5 30615.0 1312.5 31175.0 ;
RECT 1377.5 39337.5 1312.5 36955.0 ; RECT 1377.5 38217.5 1312.5 39645.0 ;
RECT 1312.5 33907.5 1025.0 33972.5 ; RECT 1312.5 33907.5 1025.0 33972.5 ;
RECT 1312.5 36317.5 1025.0 36382.5 ; RECT 1312.5 36317.5 1025.0 36382.5 ;
RECT 1312.5 36597.5 1025.0 36662.5 ;
RECT 1312.5 39007.5 1025.0 39072.5 ;
RECT 1377.5 31862.5 935.0 31927.5 ; RECT 1377.5 31862.5 935.0 31927.5 ;
RECT 935.0 31862.5 230.0 31927.5 ; RECT 935.0 31862.5 230.0 31927.5 ;
RECT 20.0 35112.5 935.0 35177.5 ; RECT 20.0 35112.5 935.0 35177.5 ;
RECT 20.0 37802.5 935.0 37867.5 ;
RECT 20.0 32422.5 935.0 32487.5 ; RECT 20.0 32422.5 935.0 32487.5 ;
RECT 2005.0 33435.0 1940.0 34135.0 ; RECT 2005.0 33435.0 1940.0 34135.0 ;
RECT 2005.0 33627.5 1940.0 33692.5 ; RECT 2005.0 33627.5 1940.0 33692.5 ;
@ -4210,11 +4213,11 @@ MACRO sram_2_16_1_freepdk45
RECT 2330.0 33497.5 2465.0 33562.5 ; RECT 2330.0 33497.5 2465.0 33562.5 ;
RECT 2330.0 33497.5 2465.0 33562.5 ; RECT 2330.0 33497.5 2465.0 33562.5 ;
RECT 2330.0 33307.5 2465.0 33372.5 ; RECT 2330.0 33307.5 2465.0 33372.5 ;
RECT 1312.5 39272.5 1377.5 39337.5 ; RECT 1312.5 38152.5 1377.5 38217.5 ;
RECT 4002.5 39272.5 4067.5 39337.5 ; RECT 4002.5 38152.5 4067.5 38217.5 ;
RECT 1312.5 39175.0 1377.5 39305.0 ; RECT 1312.5 38055.0 1377.5 38185.0 ;
RECT 1345.0 39272.5 4035.0 39337.5 ; RECT 1345.0 38152.5 4035.0 38217.5 ;
RECT 4002.5 39175.0 4067.5 39305.0 ; RECT 4002.5 38055.0 4067.5 38185.0 ;
RECT 2875.0 34562.5 2690.0 34627.5 ; RECT 2875.0 34562.5 2690.0 34627.5 ;
RECT 4035.0 34562.5 3850.0 34627.5 ; RECT 4035.0 34562.5 3850.0 34627.5 ;
RECT 3917.5 34202.5 4067.5 34267.5 ; RECT 3917.5 34202.5 4067.5 34267.5 ;
@ -4361,90 +4364,6 @@ MACRO sram_2_16_1_freepdk45
RECT 2722.5 37495.0 2657.5 38055.0 ; RECT 2722.5 37495.0 2657.5 38055.0 ;
RECT 4067.5 37495.0 4002.5 38055.0 ; RECT 4067.5 37495.0 4002.5 38055.0 ;
RECT 3340.0 37620.0 3475.0 37685.0 ; RECT 3340.0 37620.0 3475.0 37685.0 ;
RECT 2875.0 38482.5 2690.0 38547.5 ;
RECT 4035.0 38482.5 3850.0 38547.5 ;
RECT 3917.5 38122.5 4067.5 38187.5 ;
RECT 3032.5 38122.5 2657.5 38187.5 ;
RECT 3917.5 38312.5 3032.5 38377.5 ;
RECT 3032.5 38122.5 2897.5 38187.5 ;
RECT 3032.5 38312.5 2897.5 38377.5 ;
RECT 3032.5 38312.5 2897.5 38377.5 ;
RECT 3032.5 38122.5 2897.5 38187.5 ;
RECT 3917.5 38122.5 3782.5 38187.5 ;
RECT 3917.5 38312.5 3782.5 38377.5 ;
RECT 3917.5 38312.5 3782.5 38377.5 ;
RECT 3917.5 38122.5 3782.5 38187.5 ;
RECT 2942.5 38482.5 2807.5 38547.5 ;
RECT 3917.5 38482.5 3782.5 38547.5 ;
RECT 3475.0 38180.0 3340.0 38245.0 ;
RECT 3475.0 38180.0 3340.0 38245.0 ;
RECT 3440.0 38345.0 3375.0 38410.0 ;
RECT 2722.5 38055.0 2657.5 38615.0 ;
RECT 4067.5 38055.0 4002.5 38615.0 ;
RECT 3340.0 38180.0 3475.0 38245.0 ;
RECT 2875.0 39042.5 2690.0 39107.5 ;
RECT 4035.0 39042.5 3850.0 39107.5 ;
RECT 3917.5 38682.5 4067.5 38747.5 ;
RECT 3032.5 38682.5 2657.5 38747.5 ;
RECT 3917.5 38872.5 3032.5 38937.5 ;
RECT 3032.5 38682.5 2897.5 38747.5 ;
RECT 3032.5 38872.5 2897.5 38937.5 ;
RECT 3032.5 38872.5 2897.5 38937.5 ;
RECT 3032.5 38682.5 2897.5 38747.5 ;
RECT 3917.5 38682.5 3782.5 38747.5 ;
RECT 3917.5 38872.5 3782.5 38937.5 ;
RECT 3917.5 38872.5 3782.5 38937.5 ;
RECT 3917.5 38682.5 3782.5 38747.5 ;
RECT 2942.5 39042.5 2807.5 39107.5 ;
RECT 3917.5 39042.5 3782.5 39107.5 ;
RECT 3475.0 38740.0 3340.0 38805.0 ;
RECT 3475.0 38740.0 3340.0 38805.0 ;
RECT 3440.0 38905.0 3375.0 38970.0 ;
RECT 2722.5 38615.0 2657.5 39175.0 ;
RECT 4067.5 38615.0 4002.5 39175.0 ;
RECT 3340.0 38740.0 3475.0 38805.0 ;
RECT 2505.0 38187.5 2690.0 38122.5 ;
RECT 1345.0 38187.5 1530.0 38122.5 ;
RECT 1462.5 38547.5 1312.5 38482.5 ;
RECT 2347.5 38547.5 2722.5 38482.5 ;
RECT 1462.5 38357.5 2347.5 38292.5 ;
RECT 2347.5 38547.5 2482.5 38482.5 ;
RECT 2347.5 38357.5 2482.5 38292.5 ;
RECT 2347.5 38357.5 2482.5 38292.5 ;
RECT 2347.5 38547.5 2482.5 38482.5 ;
RECT 1462.5 38547.5 1597.5 38482.5 ;
RECT 1462.5 38357.5 1597.5 38292.5 ;
RECT 1462.5 38357.5 1597.5 38292.5 ;
RECT 1462.5 38547.5 1597.5 38482.5 ;
RECT 2437.5 38187.5 2572.5 38122.5 ;
RECT 1462.5 38187.5 1597.5 38122.5 ;
RECT 1905.0 38490.0 2040.0 38425.0 ;
RECT 1905.0 38490.0 2040.0 38425.0 ;
RECT 1940.0 38325.0 2005.0 38260.0 ;
RECT 2657.5 38615.0 2722.5 38055.0 ;
RECT 1312.5 38615.0 1377.5 38055.0 ;
RECT 1905.0 38425.0 2040.0 38490.0 ;
RECT 2505.0 37627.5 2690.0 37562.5 ;
RECT 1345.0 37627.5 1530.0 37562.5 ;
RECT 1462.5 37987.5 1312.5 37922.5 ;
RECT 2347.5 37987.5 2722.5 37922.5 ;
RECT 1462.5 37797.5 2347.5 37732.5 ;
RECT 2347.5 37987.5 2482.5 37922.5 ;
RECT 2347.5 37797.5 2482.5 37732.5 ;
RECT 2347.5 37797.5 2482.5 37732.5 ;
RECT 2347.5 37987.5 2482.5 37922.5 ;
RECT 1462.5 37987.5 1597.5 37922.5 ;
RECT 1462.5 37797.5 1597.5 37732.5 ;
RECT 1462.5 37797.5 1597.5 37732.5 ;
RECT 1462.5 37987.5 1597.5 37922.5 ;
RECT 2437.5 37627.5 2572.5 37562.5 ;
RECT 1462.5 37627.5 1597.5 37562.5 ;
RECT 1905.0 37930.0 2040.0 37865.0 ;
RECT 1905.0 37930.0 2040.0 37865.0 ;
RECT 1940.0 37765.0 2005.0 37700.0 ;
RECT 2657.5 38055.0 2722.5 37495.0 ;
RECT 1312.5 38055.0 1377.5 37495.0 ;
RECT 1905.0 37865.0 2040.0 37930.0 ;
RECT 2505.0 37067.5 2690.0 37002.5 ; RECT 2505.0 37067.5 2690.0 37002.5 ;
RECT 1345.0 37067.5 1530.0 37002.5 ; RECT 1345.0 37067.5 1530.0 37002.5 ;
RECT 1462.5 37427.5 1312.5 37362.5 ; RECT 1462.5 37427.5 1312.5 37362.5 ;
@ -4572,24 +4491,32 @@ MACRO sram_2_16_1_freepdk45
RECT 1312.5 34695.0 1377.5 34135.0 ; RECT 1312.5 34695.0 1377.5 34135.0 ;
RECT 1905.0 34505.0 2040.0 34570.0 ; RECT 1905.0 34505.0 2040.0 34570.0 ;
RECT 3340.0 34425.0 3475.0 34490.0 ; RECT 3340.0 34425.0 3475.0 34490.0 ;
RECT 3340.0 36665.0 3475.0 36730.0 ; RECT 3340.0 36105.0 3475.0 36170.0 ;
RECT 3340.0 38905.0 3475.0 38970.0 ; RECT 3340.0 37785.0 3475.0 37850.0 ;
RECT 1905.0 36580.0 2040.0 36645.0 ; RECT 1905.0 36020.0 2040.0 36085.0 ;
RECT 3340.0 34260.0 3475.0 34325.0 ; RECT 3340.0 34260.0 3475.0 34325.0 ;
RECT 1940.0 34135.0 2005.0 34340.0 ; RECT 1940.0 34135.0 2005.0 34340.0 ;
RECT 2657.5 34135.0 2722.5 39175.0 ; RECT 2657.5 34135.0 2722.5 38055.0 ;
RECT 1312.5 34135.0 1377.5 39175.0 ; RECT 1312.5 34135.0 1377.5 38055.0 ;
RECT 4002.5 34135.0 4067.5 39175.0 ; RECT 4002.5 34135.0 4067.5 38055.0 ;
RECT 935.0 33800.0 225.0 32455.0 ; RECT 935.0 33800.0 225.0 32455.0 ;
RECT 935.0 33800.0 230.0 35145.0 ; RECT 935.0 33800.0 230.0 35145.0 ;
RECT 935.0 36490.0 230.0 35145.0 ; RECT 935.0 36490.0 230.0 35145.0 ;
RECT 935.0 36490.0 230.0 37835.0 ;
RECT 935.0 39180.0 230.0 37835.0 ;
RECT 1025.0 33907.5 140.0 33972.5 ; RECT 1025.0 33907.5 140.0 33972.5 ;
RECT 1025.0 36317.5 140.0 36382.5 ; RECT 1025.0 36317.5 140.0 36382.5 ;
RECT 1025.0 36597.5 140.0 36662.5 ;
RECT 1025.0 39007.5 140.0 39072.5 ;
RECT 1025.0 35112.5 140.0 35177.5 ; RECT 1025.0 35112.5 140.0 35177.5 ;
RECT 1025.0 37802.5 140.0 37867.5 ;
RECT 1025.0 33767.5 140.0 33832.5 ; RECT 1025.0 33767.5 140.0 33832.5 ;
RECT 1025.0 36457.5 140.0 36522.5 ; RECT 1025.0 36457.5 140.0 36522.5 ;
RECT 1025.0 39147.5 140.0 39212.5 ;
RECT 1345.0 33872.5 1280.0 34007.5 ; RECT 1345.0 33872.5 1280.0 34007.5 ;
RECT 1345.0 36282.5 1280.0 36417.5 ; RECT 1345.0 36282.5 1280.0 36417.5 ;
RECT 1345.0 36562.5 1280.0 36697.5 ;
RECT 1345.0 38972.5 1280.0 39107.5 ;
RECT 1342.5 34135.0 1277.5 34270.0 ; RECT 1342.5 34135.0 1277.5 34270.0 ;
RECT 1377.5 31760.0 1312.5 31895.0 ; RECT 1377.5 31760.0 1312.5 31895.0 ;
RECT 867.5 31862.5 1002.5 31927.5 ; RECT 867.5 31862.5 1002.5 31927.5 ;
@ -4600,7 +4527,7 @@ MACRO sram_2_16_1_freepdk45
RECT 682.5 32030.0 817.5 32095.0 ; RECT 682.5 32030.0 817.5 32095.0 ;
RECT 3475.0 31335.0 3410.0 34260.0 ; RECT 3475.0 31335.0 3410.0 34260.0 ;
RECT 2005.0 31335.0 1940.0 32100.0 ; RECT 2005.0 31335.0 1940.0 32100.0 ;
RECT 20.0 31335.0 -45.0 36577.5 ; RECT 20.0 31335.0 -45.0 39267.5 ;
RECT 2722.5 31335.0 2657.5 34135.0 ; RECT 2722.5 31335.0 2657.5 34135.0 ;
RECT 1377.5 31335.0 1312.5 31895.0 ; RECT 1377.5 31335.0 1312.5 31895.0 ;
RECT 4067.5 31335.0 4002.5 34135.0 ; RECT 4067.5 31335.0 4002.5 34135.0 ;
@ -5439,29 +5366,25 @@ MACRO sram_2_16_1_freepdk45
RECT 1610.0 26387.5 1540.0 26252.5 ; RECT 1610.0 26387.5 1540.0 26252.5 ;
RECT 2315.0 25737.5 2245.0 25602.5 ; RECT 2315.0 25737.5 2245.0 25602.5 ;
RECT 2315.0 26387.5 2245.0 26252.5 ; RECT 2315.0 26387.5 2245.0 26252.5 ;
RECT 1380.0 31895.0 1310.0 36955.0 ; RECT 1380.0 31895.0 1310.0 39645.0 ;
RECT 970.0 31895.0 900.0 36645.0 ; RECT 970.0 31895.0 900.0 39335.0 ;
RECT 265.0 31895.0 195.0 36645.0 ; RECT 265.0 31895.0 195.0 39335.0 ;
RECT 1207.5 32062.5 1137.5 32660.0 ; RECT 1207.5 32062.5 1137.5 32660.0 ;
RECT 785.0 32062.5 715.0 32342.5 ; RECT 785.0 32062.5 715.0 32342.5 ;
RECT 3372.5 34457.5 3442.5 34852.5 ; RECT 3372.5 34457.5 3442.5 34852.5 ;
RECT 3372.5 34852.5 3442.5 35412.5 ; RECT 3372.5 34852.5 3442.5 35412.5 ;
RECT 3372.5 35412.5 3442.5 35972.5 ; RECT 3372.5 35412.5 3442.5 35972.5 ;
RECT 3372.5 35972.5 3442.5 36532.5 ; RECT 3372.5 36137.5 3442.5 36532.5 ;
RECT 3372.5 36697.5 3442.5 37092.5 ; RECT 3372.5 36532.5 3442.5 37092.5 ;
RECT 3372.5 37092.5 3442.5 37652.5 ; RECT 3372.5 37092.5 3442.5 37652.5 ;
RECT 3372.5 37652.5 3442.5 38212.5 ; RECT 2655.0 37782.5 2725.0 37852.5 ;
RECT 3372.5 38212.5 3442.5 38772.5 ; RECT 2655.0 37302.5 2725.0 37372.5 ;
RECT 2655.0 38902.5 2725.0 38972.5 ; RECT 2690.0 37782.5 3407.5 37852.5 ;
RECT 2655.0 38422.5 2725.0 38492.5 ; RECT 2655.0 37337.5 2725.0 37817.5 ;
RECT 2690.0 38902.5 3407.5 38972.5 ; RECT 1972.5 37302.5 2690.0 37372.5 ;
RECT 2655.0 38457.5 2725.0 38937.5 ;
RECT 1972.5 38422.5 2690.0 38492.5 ;
RECT 1937.5 37897.5 2007.5 38457.5 ;
RECT 1937.5 37337.5 2007.5 37897.5 ;
RECT 1937.5 36777.5 2007.5 37337.5 ; RECT 1937.5 36777.5 2007.5 37337.5 ;
RECT 1937.5 36217.5 2007.5 36612.5 ; RECT 1937.5 36217.5 2007.5 36777.5 ;
RECT 1937.5 35657.5 2007.5 36217.5 ; RECT 1937.5 35657.5 2007.5 36052.5 ;
RECT 1937.5 35097.5 2007.5 35657.5 ; RECT 1937.5 35097.5 2007.5 35657.5 ;
RECT 1937.5 34537.5 2007.5 35097.5 ; RECT 1937.5 34537.5 2007.5 35097.5 ;
RECT 3340.0 34817.5 3475.0 34887.5 ; RECT 3340.0 34817.5 3475.0 34887.5 ;
@ -5470,10 +5393,6 @@ MACRO sram_2_16_1_freepdk45
RECT 3340.0 36497.5 3475.0 36567.5 ; RECT 3340.0 36497.5 3475.0 36567.5 ;
RECT 3340.0 37057.5 3475.0 37127.5 ; RECT 3340.0 37057.5 3475.0 37127.5 ;
RECT 3340.0 37617.5 3475.0 37687.5 ; RECT 3340.0 37617.5 3475.0 37687.5 ;
RECT 3340.0 38177.5 3475.0 38247.5 ;
RECT 3340.0 38737.5 3475.0 38807.5 ;
RECT 1905.0 38422.5 2040.0 38492.5 ;
RECT 1905.0 37862.5 2040.0 37932.5 ;
RECT 1905.0 37302.5 2040.0 37372.5 ; RECT 1905.0 37302.5 2040.0 37372.5 ;
RECT 1905.0 36742.5 2040.0 36812.5 ; RECT 1905.0 36742.5 2040.0 36812.5 ;
RECT 1905.0 36182.5 2040.0 36252.5 ; RECT 1905.0 36182.5 2040.0 36252.5 ;
@ -5481,18 +5400,22 @@ MACRO sram_2_16_1_freepdk45
RECT 1905.0 35062.5 2040.0 35132.5 ; RECT 1905.0 35062.5 2040.0 35132.5 ;
RECT 1905.0 34502.5 2040.0 34572.5 ; RECT 1905.0 34502.5 2040.0 34572.5 ;
RECT 3340.0 34422.5 3475.0 34492.5 ; RECT 3340.0 34422.5 3475.0 34492.5 ;
RECT 3340.0 36662.5 3475.0 36732.5 ; RECT 3340.0 36102.5 3475.0 36172.5 ;
RECT 3340.0 38902.5 3475.0 38972.5 ; RECT 3340.0 37782.5 3475.0 37852.5 ;
RECT 1905.0 36577.5 2040.0 36647.5 ; RECT 1905.0 36017.5 2040.0 36087.5 ;
RECT 935.0 33800.0 225.0 32455.0 ; RECT 935.0 33800.0 225.0 32455.0 ;
RECT 935.0 33800.0 230.0 35145.0 ; RECT 935.0 33800.0 230.0 35145.0 ;
RECT 935.0 36490.0 230.0 35145.0 ; RECT 935.0 36490.0 230.0 35145.0 ;
RECT 785.0 33700.0 715.0 36645.0 ; RECT 935.0 36490.0 230.0 37835.0 ;
RECT 450.0 33700.0 380.0 36645.0 ; RECT 935.0 39180.0 230.0 37835.0 ;
RECT 970.0 33700.0 900.0 36645.0 ; RECT 785.0 33700.0 715.0 39335.0 ;
RECT 265.0 33700.0 195.0 36645.0 ; RECT 450.0 33700.0 380.0 39335.0 ;
RECT 970.0 33700.0 900.0 39335.0 ;
RECT 265.0 33700.0 195.0 39335.0 ;
RECT 1347.5 33872.5 1277.5 34007.5 ; RECT 1347.5 33872.5 1277.5 34007.5 ;
RECT 1347.5 36282.5 1277.5 36417.5 ; RECT 1347.5 36282.5 1277.5 36417.5 ;
RECT 1347.5 36562.5 1277.5 36697.5 ;
RECT 1347.5 38972.5 1277.5 39107.5 ;
RECT 1345.0 34135.0 1275.0 34270.0 ; RECT 1345.0 34135.0 1275.0 34270.0 ;
RECT 1380.0 31760.0 1310.0 31895.0 ; RECT 1380.0 31760.0 1310.0 31895.0 ;
RECT 867.5 31860.0 1002.5 31930.0 ; RECT 867.5 31860.0 1002.5 31930.0 ;

View File

@ -1,4 +1,4 @@
library (sram_2_16_1_freepdk45_lib){ library (sram_2_16_1_freepdk45_TT_1p0V_25C_lib){
delay_model : "table_lookup"; delay_model : "table_lookup";
time_unit : "1ns" ; time_unit : "1ns" ;
voltage_unit : "1v" ; voltage_unit : "1v" ;
@ -7,9 +7,10 @@ library (sram_2_16_1_freepdk45_lib){
capacitive_load_unit(1 ,fF) ; capacitive_load_unit(1 ,fF) ;
leakage_power_unit : "1mW" ; leakage_power_unit : "1mW" ;
pulling_resistance_unit :"1kohm" ; pulling_resistance_unit :"1kohm" ;
operating_conditions(TT){ operating_conditions(OC){
process : 1.0 ;
voltage : 1.0 ; voltage : 1.0 ;
temperature : 25.000 ; temperature : 25;
} }
input_threshold_pct_fall : 50.0 ; input_threshold_pct_fall : 50.0 ;
@ -21,6 +22,9 @@ library (sram_2_16_1_freepdk45_lib){
slew_lower_threshold_pct_rise : 10.0 ; slew_lower_threshold_pct_rise : 10.0 ;
slew_upper_threshold_pct_rise : 90.0 ; slew_upper_threshold_pct_rise : 90.0 ;
nom_voltage : 1.0;
nom_temperature : 25;
nom_process : 1.0;
default_cell_leakage_power : 0.0 ; default_cell_leakage_power : 0.0 ;
default_leakage_power_density : 0.0 ; default_leakage_power_density : 0.0 ;
default_input_pin_cap : 1.0 ; default_input_pin_cap : 1.0 ;
@ -45,7 +49,7 @@ library (sram_2_16_1_freepdk45_lib){
index_2("0.00125, 0.005, 0.04"); index_2("0.00125, 0.005, 0.04");
} }
default_operating_conditions : TT; default_operating_conditions : OC;
type (DATA){ type (DATA){
@ -74,12 +78,18 @@ cell (sram_2_16_1_freepdk45){
dont_use : true; dont_use : true;
map_only : true; map_only : true;
dont_touch : true; dont_touch : true;
area : 918.5120625; area : 1032.3999375;
leakage_power () {
when : "CSb";
value : 0.00088149731;
}
cell_leakage_power : 0;
bus(DATA){ bus(DATA){
bus_type : DATA; bus_type : DATA;
direction : inout; direction : inout;
max_capacitance : 1.6728; max_capacitance : 1.6728;
min_capacitance : 0.052275;
three_state : "!OEb & !clk"; three_state : "!OEb & !clk";
memory_write(){ memory_write(){
address : ADDR; address : ADDR;
@ -89,15 +99,6 @@ cell (sram_2_16_1_freepdk45){
address : ADDR; address : ADDR;
} }
pin(DATA[1:0]){ pin(DATA[1:0]){
internal_power(){
when : "OEb & !clk";
rise_power(scalar){
values("0.04024341");
}
fall_power(scalar){
values("0.029869287");
}
}
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk"; related_pin : "clk";
@ -126,15 +127,6 @@ cell (sram_2_16_1_freepdk45){
"-0.004, -0.004, -0.016"); "-0.004, -0.004, -0.016");
} }
} }
internal_power(){
when : "!OEb & !clk";
rise_power(scalar){
values("0.050563718");
}
fall_power(scalar){
values("0.055867096");
}
}
timing(){ timing(){
timing_sense : non_unate; timing_sense : non_unate;
related_pin : "clk"; related_pin : "clk";
@ -145,16 +137,16 @@ cell (sram_2_16_1_freepdk45){
"0.061, 0.062, 0.069"); "0.061, 0.062, 0.069");
} }
cell_fall(CELL_TABLE) { cell_fall(CELL_TABLE) {
values("0.442, 0.443, 0.452",\ values("0.429, 0.43, 0.439",\
"0.442, 0.443, 0.453",\ "0.429, 0.431, 0.439",\
"0.448, 0.449, 0.458"); "0.435, 0.436, 0.446");
} }
rise_transition(CELL_TABLE) { rise_transition(CELL_TABLE) {
values("0.013, 0.015, 0.026",\ values("0.013, 0.015, 0.026",\
"0.013, 0.015, 0.026",\ "0.013, 0.015, 0.026",\
"0.013, 0.015, 0.026"); "0.013, 0.015, 0.026");
} }
fall_transition(CELL_TABLE) { fall_transition(CELL_TABLE) {
values("0.029, 0.031, 0.044",\ values("0.029, 0.031, 0.044",\
"0.029, 0.031, 0.044",\ "0.029, 0.031, 0.044",\
"0.029, 0.031, 0.044"); "0.029, 0.031, 0.044");
@ -168,7 +160,6 @@ cell (sram_2_16_1_freepdk45){
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.2091;
max_transition : 0.04; max_transition : 0.04;
fanout_load : 1.000000;
pin(ADDR[3:0]){ pin(ADDR[3:0]){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
@ -304,24 +295,51 @@ cell (sram_2_16_1_freepdk45){
clock : true; clock : true;
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.2091;
internal_power(){
when : "!CSb & clk & !WEb";
rise_power(scalar){
values("0.0173748762222");
}
fall_power(scalar){
values("0.0173748762222");
}
}
internal_power(){
when : "!CSb & !clk & WEb";
rise_power(scalar){
values("0.0261209913889");
}
fall_power(scalar){
values("0.0261209913889");
}
}
internal_power(){
when : "CSb";
rise_power(scalar){
values("0");
}
fall_power(scalar){
values("0");
}
}
timing(){ timing(){
timing_type :"min_pulse_width"; timing_type :"min_pulse_width";
related_pin : clk; related_pin : clk;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0.449"); values("0.4295");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0.449"); values("0.4295");
} }
} }
timing(){ timing(){
timing_type :"minimum_period"; timing_type :"minimum_period";
related_pin : clk; related_pin : clk;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0.898"); values("0.859");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0.898"); values("0.859");
} }
} }
} }

View File

@ -1,4 +1,4 @@
library (sram_2_16_1_freepdk45_lib){ library (sram_2_16_1_freepdk45_TT_1p0V_25C_lib){
delay_model : "table_lookup"; delay_model : "table_lookup";
time_unit : "1ns" ; time_unit : "1ns" ;
voltage_unit : "1v" ; voltage_unit : "1v" ;
@ -7,9 +7,10 @@ library (sram_2_16_1_freepdk45_lib){
capacitive_load_unit(1 ,fF) ; capacitive_load_unit(1 ,fF) ;
leakage_power_unit : "1mW" ; leakage_power_unit : "1mW" ;
pulling_resistance_unit :"1kohm" ; pulling_resistance_unit :"1kohm" ;
operating_conditions(TT){ operating_conditions(OC){
process : 1.0 ;
voltage : 1.0 ; voltage : 1.0 ;
temperature : 25.000 ; temperature : 25;
} }
input_threshold_pct_fall : 50.0 ; input_threshold_pct_fall : 50.0 ;
@ -21,6 +22,9 @@ library (sram_2_16_1_freepdk45_lib){
slew_lower_threshold_pct_rise : 10.0 ; slew_lower_threshold_pct_rise : 10.0 ;
slew_upper_threshold_pct_rise : 90.0 ; slew_upper_threshold_pct_rise : 90.0 ;
nom_voltage : 1.0;
nom_temperature : 25;
nom_process : 1.0;
default_cell_leakage_power : 0.0 ; default_cell_leakage_power : 0.0 ;
default_leakage_power_density : 0.0 ; default_leakage_power_density : 0.0 ;
default_input_pin_cap : 1.0 ; default_input_pin_cap : 1.0 ;
@ -45,7 +49,7 @@ library (sram_2_16_1_freepdk45_lib){
index_2("0.00125, 0.005, 0.04"); index_2("0.00125, 0.005, 0.04");
} }
default_operating_conditions : TT; default_operating_conditions : OC;
type (DATA){ type (DATA){
@ -74,12 +78,18 @@ cell (sram_2_16_1_freepdk45){
dont_use : true; dont_use : true;
map_only : true; map_only : true;
dont_touch : true; dont_touch : true;
area : 918.5120625; area : 1032.3999375;
leakage_power () {
when : "CSb";
value : 0;
}
cell_leakage_power : 0;
bus(DATA){ bus(DATA){
bus_type : DATA; bus_type : DATA;
direction : inout; direction : inout;
max_capacitance : 1.6728; max_capacitance : 1.6728;
min_capacitance : 0.052275;
three_state : "!OEb & !clk"; three_state : "!OEb & !clk";
memory_write(){ memory_write(){
address : ADDR; address : ADDR;
@ -89,15 +99,6 @@ cell (sram_2_16_1_freepdk45){
address : ADDR; address : ADDR;
} }
pin(DATA[1:0]){ pin(DATA[1:0]){
internal_power(){
when : "OEb & !clk";
rise_power(scalar){
values("0");
}
fall_power(scalar){
values("0");
}
}
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk"; related_pin : "clk";
@ -126,15 +127,6 @@ cell (sram_2_16_1_freepdk45){
"0.001, 0.001, 0.001"); "0.001, 0.001, 0.001");
} }
} }
internal_power(){
when : "!OEb & !clk";
rise_power(scalar){
values("0");
}
fall_power(scalar){
values("0");
}
}
timing(){ timing(){
timing_sense : non_unate; timing_sense : non_unate;
related_pin : "clk"; related_pin : "clk";
@ -149,12 +141,12 @@ cell (sram_2_16_1_freepdk45){
"0.123, 0.124, 0.133",\ "0.123, 0.124, 0.133",\
"0.123, 0.124, 0.133"); "0.123, 0.124, 0.133");
} }
rise_transition(CELL_TABLE) { rise_transition(CELL_TABLE) {
values("0.006, 0.007, 0.018",\ values("0.006, 0.007, 0.018",\
"0.006, 0.007, 0.018",\ "0.006, 0.007, 0.018",\
"0.006, 0.007, 0.018"); "0.006, 0.007, 0.018");
} }
fall_transition(CELL_TABLE) { fall_transition(CELL_TABLE) {
values("0.006, 0.007, 0.018",\ values("0.006, 0.007, 0.018",\
"0.006, 0.007, 0.018",\ "0.006, 0.007, 0.018",\
"0.006, 0.007, 0.018"); "0.006, 0.007, 0.018");
@ -168,7 +160,6 @@ cell (sram_2_16_1_freepdk45){
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.2091;
max_transition : 0.04; max_transition : 0.04;
fanout_load : 1.000000;
pin(ADDR[3:0]){ pin(ADDR[3:0]){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
@ -304,6 +295,33 @@ cell (sram_2_16_1_freepdk45){
clock : true; clock : true;
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.2091;
internal_power(){
when : "!CSb & clk & !WEb";
rise_power(scalar){
values("0.0");
}
fall_power(scalar){
values("0.0");
}
}
internal_power(){
when : "!CSb & !clk & WEb";
rise_power(scalar){
values("0.0");
}
fall_power(scalar){
values("0.0");
}
}
internal_power(){
when : "CSb";
rise_power(scalar){
values("0");
}
fall_power(scalar){
values("0");
}
}
timing(){ timing(){
timing_type :"min_pulse_width"; timing_type :"min_pulse_width";
related_pin : clk; related_pin : clk;

View File

@ -1,4 +1,4 @@
library (sram_2_16_1_freepdk45_lib){ library (sram_2_16_1_freepdk45_TT_1p0V_25C_lib){
delay_model : "table_lookup"; delay_model : "table_lookup";
time_unit : "1ns" ; time_unit : "1ns" ;
voltage_unit : "1v" ; voltage_unit : "1v" ;
@ -7,9 +7,10 @@ library (sram_2_16_1_freepdk45_lib){
capacitive_load_unit(1 ,fF) ; capacitive_load_unit(1 ,fF) ;
leakage_power_unit : "1mW" ; leakage_power_unit : "1mW" ;
pulling_resistance_unit :"1kohm" ; pulling_resistance_unit :"1kohm" ;
operating_conditions(TT){ operating_conditions(OC){
process : 1.0 ;
voltage : 1.0 ; voltage : 1.0 ;
temperature : 25.000 ; temperature : 25;
} }
input_threshold_pct_fall : 50.0 ; input_threshold_pct_fall : 50.0 ;
@ -21,6 +22,9 @@ library (sram_2_16_1_freepdk45_lib){
slew_lower_threshold_pct_rise : 10.0 ; slew_lower_threshold_pct_rise : 10.0 ;
slew_upper_threshold_pct_rise : 90.0 ; slew_upper_threshold_pct_rise : 90.0 ;
nom_voltage : 1.0;
nom_temperature : 25;
nom_process : 1.0;
default_cell_leakage_power : 0.0 ; default_cell_leakage_power : 0.0 ;
default_leakage_power_density : 0.0 ; default_leakage_power_density : 0.0 ;
default_input_pin_cap : 1.0 ; default_input_pin_cap : 1.0 ;
@ -45,7 +49,7 @@ library (sram_2_16_1_freepdk45_lib){
index_2("0.00125, 0.005, 0.04"); index_2("0.00125, 0.005, 0.04");
} }
default_operating_conditions : TT; default_operating_conditions : OC;
type (DATA){ type (DATA){
@ -74,12 +78,18 @@ cell (sram_2_16_1_freepdk45){
dont_use : true; dont_use : true;
map_only : true; map_only : true;
dont_touch : true; dont_touch : true;
area : 918.5120625; area : 1032.3999375;
leakage_power () {
when : "CSb";
value : 0.00088149731;
}
cell_leakage_power : 0;
bus(DATA){ bus(DATA){
bus_type : DATA; bus_type : DATA;
direction : inout; direction : inout;
max_capacitance : 1.6728; max_capacitance : 1.6728;
min_capacitance : 0.052275;
three_state : "!OEb & !clk"; three_state : "!OEb & !clk";
memory_write(){ memory_write(){
address : ADDR; address : ADDR;
@ -89,15 +99,6 @@ cell (sram_2_16_1_freepdk45){
address : ADDR; address : ADDR;
} }
pin(DATA[1:0]){ pin(DATA[1:0]){
internal_power(){
when : "OEb & !clk";
rise_power(scalar){
values("0.0370166");
}
fall_power(scalar){
values("0.026622831");
}
}
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk"; related_pin : "clk";
@ -126,15 +127,6 @@ cell (sram_2_16_1_freepdk45){
"-0.004, -0.004, -0.016"); "-0.004, -0.004, -0.016");
} }
} }
internal_power(){
when : "!OEb & !clk";
rise_power(scalar){
values("0.034203045");
}
fall_power(scalar){
values("0.039377859");
}
}
timing(){ timing(){
timing_sense : non_unate; timing_sense : non_unate;
related_pin : "clk"; related_pin : "clk";
@ -145,16 +137,16 @@ cell (sram_2_16_1_freepdk45){
"0.06, 0.061, 0.067"); "0.06, 0.061, 0.067");
} }
cell_fall(CELL_TABLE) { cell_fall(CELL_TABLE) {
values("0.438, 0.439, 0.449",\ values("0.425, 0.426, 0.436",\
"0.439, 0.44, 0.449",\ "0.426, 0.427, 0.436",\
"0.445, 0.446, 0.455"); "0.432, 0.433, 0.442");
} }
rise_transition(CELL_TABLE) { rise_transition(CELL_TABLE) {
values("0.013, 0.014, 0.026",\ values("0.013, 0.014, 0.026",\
"0.013, 0.014, 0.026",\ "0.013, 0.014, 0.026",\
"0.013, 0.015, 0.026"); "0.013, 0.015, 0.026");
} }
fall_transition(CELL_TABLE) { fall_transition(CELL_TABLE) {
values("0.027, 0.029, 0.043",\ values("0.027, 0.029, 0.043",\
"0.027, 0.029, 0.043",\ "0.027, 0.029, 0.043",\
"0.027, 0.029, 0.043"); "0.027, 0.029, 0.043");
@ -168,7 +160,6 @@ cell (sram_2_16_1_freepdk45){
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.2091;
max_transition : 0.04; max_transition : 0.04;
fanout_load : 1.000000;
pin(ADDR[3:0]){ pin(ADDR[3:0]){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
@ -304,24 +295,51 @@ cell (sram_2_16_1_freepdk45){
clock : true; clock : true;
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.2091;
internal_power(){
when : "!CSb & clk & !WEb";
rise_power(scalar){
values("0.0158174252672");
}
fall_power(scalar){
values("0.0158174252672");
}
}
internal_power(){
when : "!CSb & !clk & WEb";
rise_power(scalar){
values("0.0181396362394");
}
fall_power(scalar){
values("0.0181396362394");
}
}
internal_power(){
when : "CSb";
rise_power(scalar){
values("0");
}
fall_power(scalar){
values("0");
}
}
timing(){ timing(){
timing_type :"min_pulse_width"; timing_type :"min_pulse_width";
related_pin : clk; related_pin : clk;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0.449"); values("0.4295");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0.449"); values("0.4295");
} }
} }
timing(){ timing(){
timing_type :"minimum_period"; timing_type :"minimum_period";
related_pin : clk; related_pin : clk;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0.898"); values("0.859");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0.898"); values("0.859");
} }
} }
} }

View File

@ -7,11 +7,11 @@ UNITS
END UNITS END UNITS
SITE MacroSite SITE MacroSite
CLASS Core ; CLASS Core ;
SIZE 277800.0 by 440700.0 ; SIZE 305400.0 by 440700.0 ;
END MacroSite END MacroSite
MACRO sram_2_16_1_scn3me_subm MACRO sram_2_16_1_scn3me_subm
CLASS BLOCK ; CLASS BLOCK ;
SIZE 277800.0 BY 440700.0 ; SIZE 305400.0 BY 440700.0 ;
SYMMETRY X Y R90 ; SYMMETRY X Y R90 ;
SITE MacroSite ; SITE MacroSite ;
PIN DATA[0] PIN DATA[0]
@ -4105,12 +4105,15 @@ MACRO sram_2_16_1_scn3me_subm
RECT 16050.0 358350.0 15150.0 359250.0 ; RECT 16050.0 358350.0 15150.0 359250.0 ;
RECT 8850.0 353400.0 7950.0 363000.0 ; RECT 8850.0 353400.0 7950.0 363000.0 ;
RECT 22650.0 353400.0 21750.0 363000.0 ; RECT 22650.0 353400.0 21750.0 363000.0 ;
RECT 22650.0 499050.0 21750.0 430200.0 ; RECT 22650.0 479850.0 21750.0 457800.0 ;
RECT 21750.0 397050.0 17400.0 397950.0 ; RECT 21750.0 397050.0 17400.0 397950.0 ;
RECT 21750.0 420450.0 17400.0 421350.0 ; RECT 21750.0 420450.0 17400.0 421350.0 ;
RECT 21750.0 424650.0 17400.0 425550.0 ;
RECT 21750.0 448050.0 17400.0 448950.0 ;
RECT 22650.0 371550.0 16800.0 372450.0 ; RECT 22650.0 371550.0 16800.0 372450.0 ;
RECT 16800.0 371550.0 6600.0 372450.0 ; RECT 16800.0 371550.0 6600.0 372450.0 ;
RECT 4500.0 408600.0 16800.0 409500.0 ; RECT 4500.0 408600.0 16800.0 409500.0 ;
RECT 4500.0 436200.0 16800.0 437100.0 ;
RECT 4500.0 381000.0 16800.0 381900.0 ; RECT 4500.0 381000.0 16800.0 381900.0 ;
RECT 29250.0 397800.0 28350.0 410400.0 ; RECT 29250.0 397800.0 28350.0 410400.0 ;
RECT 29250.0 392850.0 28350.0 393750.0 ; RECT 29250.0 392850.0 28350.0 393750.0 ;
@ -4150,11 +4153,11 @@ MACRO sram_2_16_1_scn3me_subm
RECT 32550.0 398400.0 33750.0 399600.0 ; RECT 32550.0 398400.0 33750.0 399600.0 ;
RECT 32550.0 398400.0 33750.0 399600.0 ; RECT 32550.0 398400.0 33750.0 399600.0 ;
RECT 32550.0 396000.0 33750.0 397200.0 ; RECT 32550.0 396000.0 33750.0 397200.0 ;
RECT 21750.0 498150.0 22650.0 499050.0 ; RECT 21750.0 478950.0 22650.0 479850.0 ;
RECT 49350.0 498150.0 50250.0 499050.0 ; RECT 49350.0 478950.0 50250.0 479850.0 ;
RECT 21750.0 496800.0 22650.0 498600.0 ; RECT 21750.0 477600.0 22650.0 479400.0 ;
RECT 22200.0 498150.0 49800.0 499050.0 ; RECT 22200.0 478950.0 49800.0 479850.0 ;
RECT 49350.0 496800.0 50250.0 498600.0 ; RECT 49350.0 477600.0 50250.0 479400.0 ;
RECT 37950.0 417000.0 36000.0 418200.0 ; RECT 37950.0 417000.0 36000.0 418200.0 ;
RECT 49800.0 417000.0 47850.0 418200.0 ; RECT 49800.0 417000.0 47850.0 418200.0 ;
RECT 48450.0 412200.0 50250.0 413400.0 ; RECT 48450.0 412200.0 50250.0 413400.0 ;
@ -4301,90 +4304,6 @@ MACRO sram_2_16_1_scn3me_subm
RECT 36450.0 468000.0 35550.0 477600.0 ; RECT 36450.0 468000.0 35550.0 477600.0 ;
RECT 50250.0 468000.0 49350.0 477600.0 ; RECT 50250.0 468000.0 49350.0 477600.0 ;
RECT 42600.0 470400.0 43800.0 471600.0 ; RECT 42600.0 470400.0 43800.0 471600.0 ;
RECT 37950.0 484200.0 36000.0 485400.0 ;
RECT 49800.0 484200.0 47850.0 485400.0 ;
RECT 48450.0 479400.0 50250.0 480600.0 ;
RECT 39150.0 479400.0 35550.0 480600.0 ;
RECT 48450.0 482100.0 39150.0 483000.0 ;
RECT 39150.0 479400.0 37950.0 480600.0 ;
RECT 39150.0 481800.0 37950.0 483000.0 ;
RECT 39150.0 481800.0 37950.0 483000.0 ;
RECT 39150.0 479400.0 37950.0 480600.0 ;
RECT 48450.0 479400.0 47250.0 480600.0 ;
RECT 48450.0 481800.0 47250.0 483000.0 ;
RECT 48450.0 481800.0 47250.0 483000.0 ;
RECT 48450.0 479400.0 47250.0 480600.0 ;
RECT 38550.0 484200.0 37350.0 485400.0 ;
RECT 48450.0 484200.0 47250.0 485400.0 ;
RECT 43800.0 480000.0 42600.0 481200.0 ;
RECT 43800.0 480000.0 42600.0 481200.0 ;
RECT 43650.0 482550.0 42750.0 483450.0 ;
RECT 36450.0 477600.0 35550.0 487200.0 ;
RECT 50250.0 477600.0 49350.0 487200.0 ;
RECT 42600.0 480000.0 43800.0 481200.0 ;
RECT 37950.0 493800.0 36000.0 495000.0 ;
RECT 49800.0 493800.0 47850.0 495000.0 ;
RECT 48450.0 489000.0 50250.0 490200.0 ;
RECT 39150.0 489000.0 35550.0 490200.0 ;
RECT 48450.0 491700.0 39150.0 492600.0 ;
RECT 39150.0 489000.0 37950.0 490200.0 ;
RECT 39150.0 491400.0 37950.0 492600.0 ;
RECT 39150.0 491400.0 37950.0 492600.0 ;
RECT 39150.0 489000.0 37950.0 490200.0 ;
RECT 48450.0 489000.0 47250.0 490200.0 ;
RECT 48450.0 491400.0 47250.0 492600.0 ;
RECT 48450.0 491400.0 47250.0 492600.0 ;
RECT 48450.0 489000.0 47250.0 490200.0 ;
RECT 38550.0 493800.0 37350.0 495000.0 ;
RECT 48450.0 493800.0 47250.0 495000.0 ;
RECT 43800.0 489600.0 42600.0 490800.0 ;
RECT 43800.0 489600.0 42600.0 490800.0 ;
RECT 43650.0 492150.0 42750.0 493050.0 ;
RECT 36450.0 487200.0 35550.0 496800.0 ;
RECT 50250.0 487200.0 49350.0 496800.0 ;
RECT 42600.0 489600.0 43800.0 490800.0 ;
RECT 34050.0 480600.0 36000.0 479400.0 ;
RECT 22200.0 480600.0 24150.0 479400.0 ;
RECT 23550.0 485400.0 21750.0 484200.0 ;
RECT 32850.0 485400.0 36450.0 484200.0 ;
RECT 23550.0 482700.0 32850.0 481800.0 ;
RECT 32850.0 485400.0 34050.0 484200.0 ;
RECT 32850.0 483000.0 34050.0 481800.0 ;
RECT 32850.0 483000.0 34050.0 481800.0 ;
RECT 32850.0 485400.0 34050.0 484200.0 ;
RECT 23550.0 485400.0 24750.0 484200.0 ;
RECT 23550.0 483000.0 24750.0 481800.0 ;
RECT 23550.0 483000.0 24750.0 481800.0 ;
RECT 23550.0 485400.0 24750.0 484200.0 ;
RECT 33450.0 480600.0 34650.0 479400.0 ;
RECT 23550.0 480600.0 24750.0 479400.0 ;
RECT 28200.0 484800.0 29400.0 483600.0 ;
RECT 28200.0 484800.0 29400.0 483600.0 ;
RECT 28350.0 482250.0 29250.0 481350.0 ;
RECT 35550.0 487200.0 36450.0 477600.0 ;
RECT 21750.0 487200.0 22650.0 477600.0 ;
RECT 28200.0 483600.0 29400.0 484800.0 ;
RECT 34050.0 471000.0 36000.0 469800.0 ;
RECT 22200.0 471000.0 24150.0 469800.0 ;
RECT 23550.0 475800.0 21750.0 474600.0 ;
RECT 32850.0 475800.0 36450.0 474600.0 ;
RECT 23550.0 473100.0 32850.0 472200.0 ;
RECT 32850.0 475800.0 34050.0 474600.0 ;
RECT 32850.0 473400.0 34050.0 472200.0 ;
RECT 32850.0 473400.0 34050.0 472200.0 ;
RECT 32850.0 475800.0 34050.0 474600.0 ;
RECT 23550.0 475800.0 24750.0 474600.0 ;
RECT 23550.0 473400.0 24750.0 472200.0 ;
RECT 23550.0 473400.0 24750.0 472200.0 ;
RECT 23550.0 475800.0 24750.0 474600.0 ;
RECT 33450.0 471000.0 34650.0 469800.0 ;
RECT 23550.0 471000.0 24750.0 469800.0 ;
RECT 28200.0 475200.0 29400.0 474000.0 ;
RECT 28200.0 475200.0 29400.0 474000.0 ;
RECT 28350.0 472650.0 29250.0 471750.0 ;
RECT 35550.0 477600.0 36450.0 468000.0 ;
RECT 21750.0 477600.0 22650.0 468000.0 ;
RECT 28200.0 474000.0 29400.0 475200.0 ;
RECT 34050.0 461400.0 36000.0 460200.0 ; RECT 34050.0 461400.0 36000.0 460200.0 ;
RECT 22200.0 461400.0 24150.0 460200.0 ; RECT 22200.0 461400.0 24150.0 460200.0 ;
RECT 23550.0 466200.0 21750.0 465000.0 ; RECT 23550.0 466200.0 21750.0 465000.0 ;
@ -4512,22 +4431,29 @@ MACRO sram_2_16_1_scn3me_subm
RECT 21750.0 420000.0 22650.0 410400.0 ; RECT 21750.0 420000.0 22650.0 410400.0 ;
RECT 28200.0 416400.0 29400.0 417600.0 ; RECT 28200.0 416400.0 29400.0 417600.0 ;
RECT 42600.0 415200.0 43800.0 416400.0 ; RECT 42600.0 415200.0 43800.0 416400.0 ;
RECT 42600.0 453600.0 43800.0 454800.0 ; RECT 42600.0 444000.0 43800.0 445200.0 ;
RECT 42600.0 492000.0 43800.0 493200.0 ; RECT 42600.0 472800.0 43800.0 474000.0 ;
RECT 28200.0 452400.0 29400.0 453600.0 ; RECT 28200.0 442800.0 29400.0 444000.0 ;
RECT 42600.0 412800.0 43800.0 414000.0 ; RECT 42600.0 412800.0 43800.0 414000.0 ;
RECT 28350.0 410400.0 29250.0 414150.0 ; RECT 28350.0 410400.0 29250.0 414150.0 ;
RECT 35550.0 410400.0 36450.0 496800.0 ; RECT 35550.0 410400.0 36450.0 477600.0 ;
RECT 21750.0 410400.0 22650.0 496800.0 ; RECT 21750.0 410400.0 22650.0 477600.0 ;
RECT 49350.0 410400.0 50250.0 496800.0 ; RECT 49350.0 410400.0 50250.0 477600.0 ;
RECT 16800.0 395400.0 6600.0 381600.0 ; RECT 16800.0 395400.0 6600.0 381600.0 ;
RECT 16800.0 395400.0 6600.0 409200.0 ; RECT 16800.0 395400.0 6600.0 409200.0 ;
RECT 16800.0 423000.0 6600.0 409200.0 ; RECT 16800.0 423000.0 6600.0 409200.0 ;
RECT 16800.0 423000.0 6600.0 436800.0 ;
RECT 16800.0 450600.0 6600.0 436800.0 ;
RECT 17400.0 396900.0 6000.0 398100.0 ; RECT 17400.0 396900.0 6000.0 398100.0 ;
RECT 17400.0 420300.0 6000.0 421500.0 ; RECT 17400.0 420300.0 6000.0 421500.0 ;
RECT 17400.0 424500.0 6000.0 425700.0 ;
RECT 17400.0 447900.0 6000.0 449100.0 ;
RECT 17400.0 408600.0 6000.0 409500.0 ; RECT 17400.0 408600.0 6000.0 409500.0 ;
RECT 17400.0 436200.0 6000.0 437100.0 ;
RECT 22350.0 396900.0 21150.0 398100.0 ; RECT 22350.0 396900.0 21150.0 398100.0 ;
RECT 22350.0 420300.0 21150.0 421500.0 ; RECT 22350.0 420300.0 21150.0 421500.0 ;
RECT 22350.0 424500.0 21150.0 425700.0 ;
RECT 22350.0 447900.0 21150.0 449100.0 ;
RECT 22200.0 410400.0 21000.0 411600.0 ; RECT 22200.0 410400.0 21000.0 411600.0 ;
RECT 22800.0 370800.0 21600.0 372000.0 ; RECT 22800.0 370800.0 21600.0 372000.0 ;
RECT 16200.0 371400.0 17400.0 372600.0 ; RECT 16200.0 371400.0 17400.0 372600.0 ;
@ -4538,7 +4464,7 @@ MACRO sram_2_16_1_scn3me_subm
RECT 12600.0 375600.0 13800.0 376800.0 ; RECT 12600.0 375600.0 13800.0 376800.0 ;
RECT 43800.0 362400.0 42900.0 412800.0 ; RECT 43800.0 362400.0 42900.0 412800.0 ;
RECT 29250.0 362400.0 28350.0 375750.0 ; RECT 29250.0 362400.0 28350.0 375750.0 ;
RECT 4500.0 362400.0 3600.0 425250.0 ; RECT 4500.0 362400.0 3600.0 452850.0 ;
RECT 36450.0 362400.0 35550.0 410400.0 ; RECT 36450.0 362400.0 35550.0 410400.0 ;
RECT 22650.0 362400.0 21750.0 372000.0 ; RECT 22650.0 362400.0 21750.0 372000.0 ;
RECT 50250.0 362400.0 49350.0 410400.0 ; RECT 50250.0 362400.0 49350.0 410400.0 ;
@ -5348,29 +5274,25 @@ MACRO sram_2_16_1_scn3me_subm
RECT 10800.0 288450.0 9600.0 287250.0 ; RECT 10800.0 288450.0 9600.0 287250.0 ;
RECT 31200.0 263100.0 30000.0 261900.0 ; RECT 31200.0 263100.0 30000.0 261900.0 ;
RECT 31200.0 288450.0 30000.0 287250.0 ; RECT 31200.0 288450.0 30000.0 287250.0 ;
RECT 22650.0 372000.0 21750.0 430200.0 ; RECT 22650.0 372000.0 21750.0 457800.0 ;
RECT 17250.0 372000.0 16350.0 425400.0 ; RECT 17250.0 372000.0 16350.0 453000.0 ;
RECT 7050.0 372000.0 6150.0 425400.0 ; RECT 7050.0 372000.0 6150.0 453000.0 ;
RECT 20400.0 376200.0 19500.0 384300.0 ; RECT 20400.0 376200.0 19500.0 384300.0 ;
RECT 13650.0 376200.0 12750.0 381000.0 ; RECT 13650.0 376200.0 12750.0 381000.0 ;
RECT 42750.0 415800.0 43650.0 423000.0 ; RECT 42750.0 415800.0 43650.0 423000.0 ;
RECT 42750.0 423000.0 43650.0 432600.0 ; RECT 42750.0 423000.0 43650.0 432600.0 ;
RECT 42750.0 432600.0 43650.0 442200.0 ; RECT 42750.0 432600.0 43650.0 442200.0 ;
RECT 42750.0 442200.0 43650.0 451800.0 ; RECT 42750.0 444600.0 43650.0 451800.0 ;
RECT 42750.0 454200.0 43650.0 461400.0 ; RECT 42750.0 451800.0 43650.0 461400.0 ;
RECT 42750.0 461400.0 43650.0 471000.0 ; RECT 42750.0 461400.0 43650.0 471000.0 ;
RECT 42750.0 471000.0 43650.0 480600.0 ; RECT 35550.0 472950.0 36450.0 473850.0 ;
RECT 42750.0 480600.0 43650.0 490200.0 ; RECT 35550.0 464550.0 36450.0 465450.0 ;
RECT 35550.0 492150.0 36450.0 493050.0 ; RECT 36000.0 472950.0 43200.0 473850.0 ;
RECT 35550.0 483750.0 36450.0 484650.0 ; RECT 35550.0 465000.0 36450.0 473400.0 ;
RECT 36000.0 492150.0 43200.0 493050.0 ; RECT 28800.0 464550.0 36000.0 465450.0 ;
RECT 35550.0 484200.0 36450.0 492600.0 ;
RECT 28800.0 483750.0 36000.0 484650.0 ;
RECT 28350.0 474600.0 29250.0 484200.0 ;
RECT 28350.0 465000.0 29250.0 474600.0 ;
RECT 28350.0 455400.0 29250.0 465000.0 ; RECT 28350.0 455400.0 29250.0 465000.0 ;
RECT 28350.0 445800.0 29250.0 453000.0 ; RECT 28350.0 445800.0 29250.0 455400.0 ;
RECT 28350.0 436200.0 29250.0 445800.0 ; RECT 28350.0 436200.0 29250.0 443400.0 ;
RECT 28350.0 426600.0 29250.0 436200.0 ; RECT 28350.0 426600.0 29250.0 436200.0 ;
RECT 28350.0 417000.0 29250.0 426600.0 ; RECT 28350.0 417000.0 29250.0 426600.0 ;
RECT 42600.0 422400.0 43800.0 423600.0 ; RECT 42600.0 422400.0 43800.0 423600.0 ;
@ -5379,10 +5301,6 @@ MACRO sram_2_16_1_scn3me_subm
RECT 42600.0 451200.0 43800.0 452400.0 ; RECT 42600.0 451200.0 43800.0 452400.0 ;
RECT 42600.0 460800.0 43800.0 462000.0 ; RECT 42600.0 460800.0 43800.0 462000.0 ;
RECT 42600.0 470400.0 43800.0 471600.0 ; RECT 42600.0 470400.0 43800.0 471600.0 ;
RECT 42600.0 480000.0 43800.0 481200.0 ;
RECT 42600.0 489600.0 43800.0 490800.0 ;
RECT 28200.0 483600.0 29400.0 484800.0 ;
RECT 28200.0 474000.0 29400.0 475200.0 ;
RECT 28200.0 464400.0 29400.0 465600.0 ; RECT 28200.0 464400.0 29400.0 465600.0 ;
RECT 28200.0 454800.0 29400.0 456000.0 ; RECT 28200.0 454800.0 29400.0 456000.0 ;
RECT 28200.0 445200.0 29400.0 446400.0 ; RECT 28200.0 445200.0 29400.0 446400.0 ;
@ -5390,18 +5308,22 @@ MACRO sram_2_16_1_scn3me_subm
RECT 28200.0 426000.0 29400.0 427200.0 ; RECT 28200.0 426000.0 29400.0 427200.0 ;
RECT 28200.0 416400.0 29400.0 417600.0 ; RECT 28200.0 416400.0 29400.0 417600.0 ;
RECT 42600.0 415200.0 43800.0 416400.0 ; RECT 42600.0 415200.0 43800.0 416400.0 ;
RECT 42600.0 453600.0 43800.0 454800.0 ; RECT 42600.0 444000.0 43800.0 445200.0 ;
RECT 42600.0 492000.0 43800.0 493200.0 ; RECT 42600.0 472800.0 43800.0 474000.0 ;
RECT 28200.0 452400.0 29400.0 453600.0 ; RECT 28200.0 442800.0 29400.0 444000.0 ;
RECT 16800.0 395400.0 6600.0 381600.0 ; RECT 16800.0 395400.0 6600.0 381600.0 ;
RECT 16800.0 395400.0 6600.0 409200.0 ; RECT 16800.0 395400.0 6600.0 409200.0 ;
RECT 16800.0 423000.0 6600.0 409200.0 ; RECT 16800.0 423000.0 6600.0 409200.0 ;
RECT 13800.0 396000.0 12600.0 426600.0 ; RECT 16800.0 423000.0 6600.0 436800.0 ;
RECT 10800.0 394800.0 9600.0 425400.0 ; RECT 16800.0 450600.0 6600.0 436800.0 ;
RECT 17400.0 394800.0 16200.0 425400.0 ; RECT 13800.0 396000.0 12600.0 454200.0 ;
RECT 7200.0 394800.0 6000.0 425400.0 ; RECT 10800.0 394800.0 9600.0 453000.0 ;
RECT 17400.0 394800.0 16200.0 453000.0 ;
RECT 7200.0 394800.0 6000.0 453000.0 ;
RECT 22350.0 396900.0 21150.0 398100.0 ; RECT 22350.0 396900.0 21150.0 398100.0 ;
RECT 22350.0 420300.0 21150.0 421500.0 ; RECT 22350.0 420300.0 21150.0 421500.0 ;
RECT 22350.0 424500.0 21150.0 425700.0 ;
RECT 22350.0 447900.0 21150.0 449100.0 ;
RECT 22200.0 410400.0 21000.0 411600.0 ; RECT 22200.0 410400.0 21000.0 411600.0 ;
RECT 22800.0 370800.0 21600.0 372000.0 ; RECT 22800.0 370800.0 21600.0 372000.0 ;
RECT 16200.0 371400.0 17400.0 372600.0 ; RECT 16200.0 371400.0 17400.0 372600.0 ;

View File

@ -0,0 +1,347 @@
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 : 134589.78;
leakage_power () {
when : "CSb";
value : 0.0011563287;
}
cell_leakage_power : 0;
bus(DATA){
bus_type : DATA;
direction : inout;
max_capacitance : 78.5936;
min_capacitance : 2.45605;
three_state : "!OEb & !clk";
memory_write(){
address : ADDR;
clocked_on : clk;
}
memory_read(){
address : ADDR;
}
pin(DATA[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.039, 0.039, 0.027",\
"0.039, 0.039, 0.027",\
"0.039, 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 : falling_edge;
cell_rise(CELL_TABLE) {
values("0.473, 0.519, 0.888",\
"0.476, 0.522, 0.891",\
"0.516, 0.56, 0.928");
}
cell_fall(CELL_TABLE) {
values("0.582, 0.655, 1.256",\
"0.585, 0.658, 1.259",\
"0.625, 0.697, 1.295");
}
rise_transition(CELL_TABLE) {
values("0.154, 0.233, 1.086",\
"0.155, 0.234, 1.086",\
"0.158, 0.237, 1.086");
}
fall_transition(CELL_TABLE) {
values("0.278, 0.359, 1.499",\
"0.278, 0.361, 1.499",\
"0.28, 0.367, 1.5");
}
}
}
}
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.039, 0.039, 0.027",\
"0.039, 0.039, 0.027",\
"0.039, 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.039, 0.039, 0.027",\
"0.039, 0.039, 0.027",\
"0.039, 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(OEb){
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.039, 0.039, 0.027",\
"0.039, 0.039, 0.027",\
"0.039, 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.039, 0.039, 0.027",\
"0.039, 0.039, 0.027",\
"0.039, 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("4.91866674167");
}
fall_power(scalar){
values("4.91866674167");
}
}
internal_power(){
when : "!CSb & !clk & WEb";
rise_power(scalar){
values("5.72315586111");
}
fall_power(scalar){
values("5.72315586111");
}
}
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("1.875");
}
fall_constraint(scalar) {
values("1.875");
}
}
timing(){
timing_type :"minimum_period";
related_pin : clk;
rise_constraint(scalar) {
values("3.75");
}
fall_constraint(scalar) {
values("3.75");
}
}
}
}
}

View File

@ -1,4 +1,4 @@
library (sram_2_16_1_scn3me_subm_lib){ library (sram_2_16_1_scn3me_subm_TT_5p0V_25C_lib){
delay_model : "table_lookup"; delay_model : "table_lookup";
time_unit : "1ns" ; time_unit : "1ns" ;
voltage_unit : "1v" ; voltage_unit : "1v" ;
@ -7,9 +7,10 @@ library (sram_2_16_1_scn3me_subm_lib){
capacitive_load_unit(1 ,fF) ; capacitive_load_unit(1 ,fF) ;
leakage_power_unit : "1mW" ; leakage_power_unit : "1mW" ;
pulling_resistance_unit :"1kohm" ; pulling_resistance_unit :"1kohm" ;
operating_conditions(TT){ operating_conditions(OC){
process : 1.0 ;
voltage : 5.0 ; voltage : 5.0 ;
temperature : 25.000 ; temperature : 25;
} }
input_threshold_pct_fall : 50.0 ; input_threshold_pct_fall : 50.0 ;
@ -21,6 +22,9 @@ library (sram_2_16_1_scn3me_subm_lib){
slew_lower_threshold_pct_rise : 10.0 ; slew_lower_threshold_pct_rise : 10.0 ;
slew_upper_threshold_pct_rise : 90.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_cell_leakage_power : 0.0 ;
default_leakage_power_density : 0.0 ; default_leakage_power_density : 0.0 ;
default_input_pin_cap : 1.0 ; default_input_pin_cap : 1.0 ;
@ -45,7 +49,7 @@ library (sram_2_16_1_scn3me_subm_lib){
index_2("0.0125, 0.05, 0.4"); index_2("0.0125, 0.05, 0.4");
} }
default_operating_conditions : TT; default_operating_conditions : OC;
type (DATA){ type (DATA){
@ -74,12 +78,18 @@ cell (sram_2_16_1_scn3me_subm){
dont_use : true; dont_use : true;
map_only : true; map_only : true;
dont_touch : true; dont_touch : true;
area : 122426.46; area : 134589.78;
leakage_power () {
when : "CSb";
value : 0;
}
cell_leakage_power : 0;
bus(DATA){ bus(DATA){
bus_type : DATA; bus_type : DATA;
direction : inout; direction : inout;
max_capacitance : 78.5936; max_capacitance : 78.5936;
min_capacitance : 2.45605;
three_state : "!OEb & !clk"; three_state : "!OEb & !clk";
memory_write(){ memory_write(){
address : ADDR; address : ADDR;
@ -89,15 +99,6 @@ cell (sram_2_16_1_scn3me_subm){
address : ADDR; address : ADDR;
} }
pin(DATA[1:0]){ pin(DATA[1:0]){
internal_power(){
when : "OEb & !clk";
rise_power(scalar){
values("0");
}
fall_power(scalar){
values("0");
}
}
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk"; related_pin : "clk";
@ -126,15 +127,6 @@ cell (sram_2_16_1_scn3me_subm){
"0.001, 0.001, 0.001"); "0.001, 0.001, 0.001");
} }
} }
internal_power(){
when : "!OEb & !clk";
rise_power(scalar){
values("0");
}
fall_power(scalar){
values("0");
}
}
timing(){ timing(){
timing_sense : non_unate; timing_sense : non_unate;
related_pin : "clk"; related_pin : "clk";
@ -149,12 +141,12 @@ cell (sram_2_16_1_scn3me_subm){
"0.556, 0.603, 1.044",\ "0.556, 0.603, 1.044",\
"0.556, 0.603, 1.044"); "0.556, 0.603, 1.044");
} }
rise_transition(CELL_TABLE) { rise_transition(CELL_TABLE) {
values("0.024, 0.081, 0.61",\ values("0.024, 0.081, 0.61",\
"0.024, 0.081, 0.61",\ "0.024, 0.081, 0.61",\
"0.024, 0.081, 0.61"); "0.024, 0.081, 0.61");
} }
fall_transition(CELL_TABLE) { fall_transition(CELL_TABLE) {
values("0.024, 0.081, 0.61",\ values("0.024, 0.081, 0.61",\
"0.024, 0.081, 0.61",\ "0.024, 0.081, 0.61",\
"0.024, 0.081, 0.61"); "0.024, 0.081, 0.61");
@ -168,7 +160,6 @@ cell (sram_2_16_1_scn3me_subm){
direction : input; direction : input;
capacitance : 9.8242; capacitance : 9.8242;
max_transition : 0.4; max_transition : 0.4;
fanout_load : 1.000000;
pin(ADDR[3:0]){ pin(ADDR[3:0]){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
@ -304,6 +295,33 @@ cell (sram_2_16_1_scn3me_subm){
clock : true; clock : true;
direction : input; direction : input;
capacitance : 9.8242; capacitance : 9.8242;
internal_power(){
when : "!CSb & clk & !WEb";
rise_power(scalar){
values("0.0");
}
fall_power(scalar){
values("0.0");
}
}
internal_power(){
when : "!CSb & !clk & WEb";
rise_power(scalar){
values("0.0");
}
fall_power(scalar){
values("0.0");
}
}
internal_power(){
when : "CSb";
rise_power(scalar){
values("0");
}
fall_power(scalar){
values("0");
}
}
timing(){ timing(){
timing_type :"min_pulse_width"; timing_type :"min_pulse_width";
related_pin : clk; related_pin : clk;

View File

@ -0,0 +1,347 @@
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 : 134589.78;
leakage_power () {
when : "CSb";
value : 0.0011563287;
}
cell_leakage_power : 0;
bus(DATA){
bus_type : DATA;
direction : inout;
max_capacitance : 78.5936;
min_capacitance : 2.45605;
three_state : "!OEb & !clk";
memory_write(){
address : ADDR;
clocked_on : clk;
}
memory_read(){
address : ADDR;
}
pin(DATA[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.039, 0.039, 0.027",\
"0.039, 0.039, 0.027",\
"0.039, 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 : falling_edge;
cell_rise(CELL_TABLE) {
values("0.458, 0.503, 0.87",\
"0.461, 0.505, 0.873",\
"0.5, 0.544, 0.911");
}
cell_fall(CELL_TABLE) {
values("0.573, 0.645, 1.246",\
"0.576, 0.648, 1.249",\
"0.616, 0.687, 1.286");
}
rise_transition(CELL_TABLE) {
values("0.153, 0.232, 1.084",\
"0.153, 0.233, 1.084",\
"0.156, 0.236, 1.084");
}
fall_transition(CELL_TABLE) {
values("0.277, 0.36, 1.499",\
"0.277, 0.362, 1.499",\
"0.278, 0.37, 1.5");
}
}
}
}
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.039, 0.039, 0.027",\
"0.039, 0.039, 0.027",\
"0.039, 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.039, 0.039, 0.027",\
"0.039, 0.039, 0.027",\
"0.039, 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(OEb){
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.039, 0.039, 0.027",\
"0.039, 0.039, 0.027",\
"0.039, 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.039, 0.039, 0.027",\
"0.039, 0.039, 0.027",\
"0.039, 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("4.39065104738");
}
fall_power(scalar){
values("4.39065104738");
}
}
internal_power(){
when : "!CSb & !clk & WEb";
rise_power(scalar){
values("5.00353945572");
}
fall_power(scalar){
values("5.00353945572");
}
}
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("1.875");
}
fall_constraint(scalar) {
values("1.875");
}
}
timing(){
timing_type :"minimum_period";
related_pin : clk;
rise_constraint(scalar) {
values("3.75");
}
fall_constraint(scalar) {
values("3.75");
}
}
}
}
}

View File

@ -103,7 +103,7 @@ def run_drc(cell_name, gds_name):
OPTS.openram_temp, OPTS.openram_temp,
errfile, errfile,
outfile) outfile)
debug.info(1, cmd) debug.info(2, cmd)
os.system(cmd) os.system(cmd)
os.chdir(cwd) os.chdir(cwd)
@ -191,7 +191,7 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False):
OPTS.openram_temp, OPTS.openram_temp,
errfile, errfile,
outfile) outfile)
debug.info(1, cmd) debug.info(2, cmd)
os.system(cmd) os.system(cmd)
os.chdir(cwd) os.chdir(cwd)

View File

@ -152,7 +152,7 @@ def run_drc(cell_name, gds_name, extract=False):
cmd = "{0}run_drc.sh 2> {1} 1> {2}".format(OPTS.openram_temp, cmd = "{0}run_drc.sh 2> {1} 1> {2}".format(OPTS.openram_temp,
errfile, errfile,
outfile) outfile)
debug.info(1, cmd) debug.info(2, cmd)
os.system(cmd) os.system(cmd)
os.chdir(cwd) os.chdir(cwd)
@ -204,7 +204,7 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False):
cmd = "{0}run_lvs.sh lvs 2> {1} 1> {2}".format(OPTS.openram_temp, cmd = "{0}run_lvs.sh lvs 2> {1} 1> {2}".format(OPTS.openram_temp,
errfile, errfile,
outfile) outfile)
debug.info(1, cmd) debug.info(2, cmd)
os.system(cmd) os.system(cmd)
os.chdir(cwd) os.chdir(cwd)

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -1,409 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.46"
sodipodi:docname="decoder_to _array.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lend"
style="overflow:visible;">
<path
id="path3229"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
transform="scale(0.8) rotate(180) translate(12.5,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Lstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Lstart"
style="overflow:visible">
<path
id="path3226"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
transform="scale(0.8) translate(12.5,0)" />
</marker>
<linearGradient
inkscape:collect="always"
id="linearGradient2461">
<stop
style="stop-color:#b3b3b3;stop-opacity:1;"
offset="0"
id="stop2463" />
<stop
style="stop-color:#b3b3b3;stop-opacity:0;"
offset="1"
id="stop2465" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient2451">
<stop
style="stop-color:#b3b3b3;stop-opacity:1;"
offset="0"
id="stop2453" />
<stop
style="stop-color:#b3b3b3;stop-opacity:0;"
offset="1"
id="stop2455" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient2445">
<stop
style="stop-color:#b3b3b3;stop-opacity:1;"
offset="0"
id="stop2447" />
<stop
style="stop-color:#b3b3b3;stop-opacity:0;"
offset="1"
id="stop2449" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2445"
id="linearGradient2443"
x1="370.17203"
y1="408.19574"
x2="372.40872"
y2="517.79352"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.7710419,0,0,0.8337292,8.1937292,7.8098171)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2451"
id="linearGradient2457"
x1="371.29037"
y1="409.31409"
x2="367.72989"
y2="523.38525"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.7712785,0,0,0.8337292,8.0871771,7.8098171)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2461"
id="linearGradient2467"
x1="551.34387"
y1="456.28641"
x2="551.34387"
y2="619.56287"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.5308865,0,114.74779)" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.1448286"
inkscape:cx="309.70169"
inkscape:cy="808.88914"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1600"
inkscape:window-height="1132"
inkscape:window-x="0"
inkscape:window-y="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:url(#linearGradient2467);fill-opacity:1"
id="rect2459"
width="354.07697"
height="193.31812"
x="391.42059"
y="246.19127" />
<rect
style="fill:url(#linearGradient2457);fill-opacity:1"
id="rect2433"
width="127.34832"
height="191.49203"
x="228.03519"
y="248.01219" />
<rect
style="fill:#ff6600"
id="rect2549"
width="518.00879"
height="37.828362"
x="227.68326"
y="302.75879" />
<rect
style="fill:#00ff00"
id="rect2547"
width="544.10468"
height="38.307152"
x="201.76241"
y="243.43471" />
<rect
style="fill:url(#linearGradient2443);fill-opacity:1"
id="rect2383"
width="192.29077"
height="392.53891"
x="35.787025"
y="46.97047" />
<text
xml:space="preserve"
style="font-size:19.24255753px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="94.222366"
y="-121.21298"
id="text2387"
transform="matrix(-6.8463303e-3,1.0398304,-0.9616465,-7.4029511e-3,0,0)"><tspan
sodipodi:role="line"
id="tspan2389"
x="94.222366"
y="-121.21298">Address Decoder</tspan><tspan
sodipodi:role="line"
x="94.222366"
y="-97.15979"
id="tspan2391" /></text>
<rect
style="fill:#ff0000"
id="rect2393"
width="159.23743"
height="17.715534"
x="202.95409"
y="254.21713" />
<rect
style="fill:#0000ff"
id="rect2399"
width="159.23741"
height="17.715534"
x="202.9501"
y="280.85464" />
<rect
style="fill:#008000"
id="rect2401"
width="159.40862"
height="17.715534"
x="202.94533"
y="310.23676" />
<text
xml:space="preserve"
style="font-size:14.67683983000000048px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="254.6263"
y="281.54678"
id="text2403"
transform="scale(1.0494184,0.9529088)"><tspan
sodipodi:role="line"
id="tspan2405"
x="254.6263"
y="281.54678">Vdd </tspan></text>
<text
xml:space="preserve"
style="font-size:14.9124279px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="278.65591"
y="268.46613"
id="text2407"
transform="scale(0.9095598,1.0994329)"><tspan
sodipodi:role="line"
id="tspan2409"
x="278.65591"
y="268.46613">Word Line</tspan></text>
<text
xml:space="preserve"
style="font-size:15.81832218px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="277.87473"
y="316.27682"
id="text2411"
transform="scale(0.9736983,1.0270121)"><tspan
sodipodi:role="line"
id="tspan2413"
x="277.87473"
y="316.27682">Vss</tspan></text>
<rect
style="fill:#ff0000"
id="rect2469"
width="362.56842"
height="17.715534"
x="382.1893"
y="254.20079" />
<rect
style="fill:#0000ff"
id="rect2471"
width="363.03949"
height="17.715534"
x="382.1853"
y="280.83832" />
<rect
style="fill:#008000"
id="rect2473"
width="361.6424"
height="17.715534"
x="383.1106"
y="310.22043" />
<text
xml:space="preserve"
style="font-size:14.67683983px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="445.56149"
y="281.52963"
id="text2475"
transform="scale(1.0494184,0.9529088)"><tspan
sodipodi:role="line"
id="tspan2477"
x="445.56149"
y="281.52963">Vdd </tspan></text>
<text
xml:space="preserve"
style="font-size:14.9124279px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="498.65213"
y="268.45126"
id="text2479"
transform="scale(0.9095598,1.0994329)"><tspan
sodipodi:role="line"
id="tspan2481"
x="498.65213"
y="268.45126">Word Line</tspan></text>
<text
xml:space="preserve"
style="font-size:15.81830978px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="485.32767"
y="315.46939"
id="text2483"
transform="scale(0.9736983,1.0270121)"><tspan
sodipodi:role="line"
id="tspan2485"
x="485.32767"
y="315.46939">Vss</tspan></text>
<rect
style="fill:#ffffff"
id="rect2551"
width="16.346491"
height="152.72293"
x="364.29324"
y="215.42181" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:18.10000038;stroke-dasharray:none;marker-start:url(#Arrow1Lstart);marker-end:url(#Arrow1Lend)"
d="M 382.1893,263.0691 L 362.19151,263.07027"
id="path2487"
inkscape:connector-type="polyline"
inkscape:connection-start="#rect2469"
inkscape:connection-end="#rect2393" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:18.10000038;stroke-dasharray:none;marker-start:url(#Arrow1Lstart);marker-end:url(#Arrow1Lend)"
d="M 362.35394,319.0899 L 383.1106,319.08869"
id="path2491"
inkscape:connector-type="polyline"
inkscape:connection-start="#rect2401"
inkscape:connection-end="#rect2473" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:18.10000038;stroke-dasharray:none;marker-start:url(#Arrow1Lstart);marker-end:url(#Arrow1Lend)"
d="M 382.1853,289.70663 L 362.18752,289.70779"
id="path2493"
inkscape:connector-type="polyline"
inkscape:connection-start="#rect2471"
inkscape:connection-end="#rect2399" />
<text
xml:space="preserve"
style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="533.82971"
y="239.70804"
id="text2543"><tspan
sodipodi:role="line"
id="tspan2545"
x="533.82971"
y="239.70804">Array</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:18.10000038;stroke-dasharray:none;marker-start:url(#Arrow1Lstart);marker-end:url(#Arrow1Lend)"
d="M 380.28173,247.63341 L 363.69741,247.63484"
id="path2553"
inkscape:connector-type="polyline" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:18.10000038;stroke-dasharray:none;marker-start:url(#Arrow1Lstart);marker-end:url(#Arrow1Lend)"
d="M 380.8161,335.38958 L 364.23178,335.39101"
id="path2563"
inkscape:connector-type="polyline" />
<text
xml:space="preserve"
style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="-238.96878"
y="379.59302"
id="text2583"
transform="matrix(0,-1,1,0,0,0)"><tspan
sodipodi:role="line"
id="tspan2585"
x="-238.96878"
y="379.59302">}</tspan></text>
<text
xml:space="preserve"
style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="345.11981"
y="380.30951"
id="text2587"
transform="matrix(0,1,1,0,0,0)"><tspan
sodipodi:role="line"
id="tspan2589"
x="345.11981"
y="380.30951">}</tspan></text>
<text
xml:space="preserve"
style="font-size:16.78106117px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="331.69421"
y="231.48781"
id="text2591"
transform="scale(1.0378936,0.9634899)"><tspan
sodipodi:role="line"
id="tspan2593"
x="331.69421"
y="231.48781">N-Well</tspan></text>
<text
xml:space="preserve"
style="font-size:16.01638031px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="354.27347"
y="370.5802"
id="text2595"
transform="scale(0.9905987,1.0094905)"><tspan
sodipodi:role="line"
id="tspan2597"
x="354.27347"
y="370.5802">P-Well</tspan></text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -25,13 +25,13 @@
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:zoom="1" inkscape:zoom="1"
inkscape:cx="161.5" inkscape:cx="20"
inkscape:cy="520" inkscape:cy="520"
inkscape:document-units="px" inkscape:document-units="px"
inkscape:current-layer="layer1" inkscape:current-layer="layer1"
showgrid="true" showgrid="true"
inkscape:window-width="1280" inkscape:window-width="3440"
inkscape:window-height="752" inkscape:window-height="1392"
inkscape:window-x="0" inkscape:window-x="0"
inkscape:window-y="0" inkscape:window-y="0"
inkscape:window-maximized="1"> inkscape:window-maximized="1">
@ -185,7 +185,7 @@
id="tspan4519" id="tspan4519"
x="184" x="184"
y="577.36218" y="577.36218"
style="font-size:16px;line-height:1.25;font-family:sans-serif">BL</tspan></text> style="font-size:16px;line-height:1.25;font-family:sans-serif">bl</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
@ -196,7 +196,7 @@
id="tspan4523" id="tspan4523"
x="336" x="336"
y="577.36218" y="577.36218"
style="font-size:16px;line-height:1.25;font-family:sans-serif">BL_bar</tspan></text> style="font-size:16px;line-height:1.25;font-family:sans-serif">br</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
@ -207,7 +207,7 @@
id="tspan4527" id="tspan4527"
x="287" x="287"
y="217.36218" y="217.36218"
style="font-size:16px;line-height:1.25;font-family:sans-serif">VDD</tspan></text> style="font-size:16px;line-height:1.25;font-family:sans-serif">vdd</tspan></text>
<path <path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 237,346.36218 77,0" d="m 237,346.36218 77,0"
@ -263,7 +263,7 @@
id="tspan4793" id="tspan4793"
x="271" x="271"
y="334.36218" y="334.36218"
style="font-size:16px;line-height:1.25;font-family:sans-serif">CLK</tspan></text> style="font-size:16px;line-height:1.25;font-family:sans-serif">en</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none" style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

View File

@ -13,8 +13,8 @@
height="1052.3622047" height="1052.3622047"
id="svg2" id="svg2"
version="1.1" version="1.1"
inkscape:version="0.48.3.1 r9886" inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="sense_amp.svg"> sodipodi:docname="sense_amp_schem.svg">
<defs <defs
id="defs4" /> id="defs4" />
<sodipodi:namedview <sodipodi:namedview
@ -24,16 +24,16 @@
borderopacity="1.0" borderopacity="1.0"
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:zoom="1" inkscape:zoom="1.4142136"
inkscape:cx="199" inkscape:cx="78.947962"
inkscape:cy="520" inkscape:cy="503.38478"
inkscape:document-units="px" inkscape:document-units="px"
inkscape:current-layer="layer1" inkscape:current-layer="layer1"
showgrid="true" showgrid="true"
inkscape:window-width="1855" inkscape:window-width="3440"
inkscape:window-height="1056" inkscape:window-height="1392"
inkscape:window-x="65" inkscape:window-x="0"
inkscape:window-y="24" inkscape:window-y="0"
inkscape:window-maximized="1"> inkscape:window-maximized="1">
<inkscape:grid <inkscape:grid
type="xygrid" type="xygrid"
@ -47,7 +47,7 @@
<dc:format>image/svg+xml</dc:format> <dc:format>image/svg+xml</dc:format>
<dc:type <dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title> <dc:title />
</cc:Work> </cc:Work>
</rdf:RDF> </rdf:RDF>
</metadata> </metadata>
@ -55,37 +55,6 @@
inkscape:label="Layer 1" inkscape:label="Layer 1"
inkscape:groupmode="layer" inkscape:groupmode="layer"
id="layer1"> id="layer1">
<g
id="g3496"
transform="translate(-148.99875,80.014073)">
<g
transform="matrix(1.25,0,0,1.25,240,223.19311)"
id="g3011">
<path
id="path3013"
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 31.199,119.324 29.539,0 0,-14.66 36.922,0 0,14.66 29.539,0"
inkscape:connector-curvature="0" />
</g>
<g
transform="matrix(1.25,0,0,1.25,240,223.19311)"
id="g3015">
<path
id="path3017"
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 61.09,100.621 36.57,0"
inkscape:connector-curvature="0" />
</g>
<g
transform="matrix(1.25,0,0,1.25,240,223.19311)"
id="g3019">
<path
id="path3021"
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 58.523,104.664 40.614,0"
inkscape:connector-curvature="0" />
</g>
</g>
<g <g
id="g3496-2" id="g3496-2"
transform="matrix(0,-1,1,0,-62.34811,791.36093)"> transform="matrix(0,-1,1,0,-62.34811,791.36093)">
@ -148,37 +117,6 @@
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
</g> </g>
</g> </g>
<g
id="g3496-7"
transform="translate(211.00125,80.014073)">
<g
transform="matrix(1.25,0,0,1.25,240,223.19311)"
id="g3011-9">
<path
id="path3013-2"
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 31.199,119.324 29.539,0 0,-14.66 36.922,0 0,14.66 29.539,0"
inkscape:connector-curvature="0" />
</g>
<g
transform="matrix(1.25,0,0,1.25,240,223.19311)"
id="g3015-8">
<path
id="path3017-9"
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 61.09,100.621 36.57,0"
inkscape:connector-curvature="0" />
</g>
<g
transform="matrix(1.25,0,0,1.25,240,223.19311)"
id="g3019-4">
<path
id="path3021-9"
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 58.523,104.664 40.614,0"
inkscape:connector-curvature="0" />
</g>
</g>
<g <g
id="g3496-8" id="g3496-8"
transform="matrix(0,-1,1,0,-2.34811,920.37376)"> transform="matrix(0,-1,1,0,-2.34811,920.37376)">
@ -357,18 +295,18 @@
id="path4592" id="path4592"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 610,452.36218 30,0 0,-120 0,230" d="m 604,452.36218 h 30 v -120 230"
id="path4594" id="path4594"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 190,432.36218 0,-20 0,-10" d="m 184,416.36218 v -20 -10"
id="path4598" id="path4598"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 550,432.36218 0,-30" d="m 544,416.36218 v -30"
id="path4600" id="path4600"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<path <path
@ -406,11 +344,11 @@
</g> </g>
<g <g
id="g3319-3" id="g3319-3"
transform="matrix(1.25,0,0,1,129,112.20718)"> transform="matrix(1.25,0,0,1,125,112.20718)">
<path <path
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
d="m 409.934,339.155 c 0,1.338 -0.864,2.417 -1.934,2.417 -1.07,0 -1.934,-1.079 -1.934,-2.417 0,-1.333 0.864,-2.417 1.934,-2.417 1.07,0 1.934,1.084 1.934,2.417 z" d="m 409.934,339.155 c 0,1.338 -0.864,2.417 -1.934,2.417 -1.07,0 -1.934,-1.079 -1.934,-2.417 0,-1.333 0.864,-2.417 1.934,-2.417 1.07,0 1.934,1.084 1.934,2.417 z"
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.93475199;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.93475199;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path3321-5" /> id="path3321-5" />
</g> </g>
<g <g
@ -466,85 +404,165 @@
</g> </g>
<text <text
xml:space="preserve" xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
x="390" x="390"
y="172.36218" y="172.36218"
id="text4691" id="text4691"><tspan
sodipodi:linespacing="125%"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4693" id="tspan4693"
x="390" x="390"
y="172.36218">VDD</tspan></text> y="172.36218"
style="font-size:16px;line-height:1.25;font-family:sans-serif">vdd</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
x="488" x="488"
y="297.36218" y="297.36218"
id="text4695" id="text4695"><tspan
sodipodi:linespacing="125%"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4697" id="tspan4697"
x="488" x="488"
y="297.36218">DATA</tspan></text> y="297.36218"
style="font-size:16px;line-height:1.25;font-family:sans-serif">DATA</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
x="615" x="621"
y="577.36218" y="577.36218"
id="text4699" id="text4699"><tspan
sodipodi:linespacing="125%"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4701" id="tspan4701"
x="615" x="621"
y="577.36218">BL_bar</tspan></text> y="577.36218"
style="font-size:16px;line-height:1.25;font-family:sans-serif">br</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
x="89" x="89"
y="580.36218" y="580.36218"
id="text4703" id="text4703"><tspan
sodipodi:linespacing="125%"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4705" id="tspan4705"
x="89" x="89"
y="580.36218">BL</tspan></text> y="580.36218"
style="font-size:16px;line-height:1.25;font-family:sans-serif">bl</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
x="295" x="295"
y="588.36218" y="588.36218"
id="text4707" id="text4707"><tspan
sodipodi:linespacing="125%"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4709" id="tspan4709"
x="295" x="295"
y="588.36218">EN</tspan></text> y="588.36218"
style="font-size:16px;line-height:1.25;font-family:sans-serif">en</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
x="540" x="538"
y="398.36218" y="382.36218"
id="text4711" id="text4711"><tspan
sodipodi:linespacing="125%"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4713" id="tspan4713"
x="540" x="538"
y="398.36218">EN</tspan></text> y="382.36218"
style="font-size:16px;line-height:1.25;font-family:sans-serif">en</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
x="180" x="177.87868"
y="399.36218" y="376.02765"
id="text4715" id="text4715"><tspan
sodipodi:linespacing="125%"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4717" id="tspan4717"
x="180" x="177.87868"
y="399.36218">EN</tspan></text> y="376.02765"
style="font-size:16px;line-height:1.25;font-family:sans-serif">en</tspan></text>
<path <path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0" style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0"
d="m 680,572.36218 0,-440 -620,0 0,610 620,0 z" d="m 680,572.36218 0,-440 -620,0 0,610 620,0 z"
id="path4738" id="path4738"
inkscape:connector-curvature="0" /> inkscape:connector-curvature="0" />
<g
transform="rotate(-90,322.13078,437.55515)"
id="g161">
<g
id="g147"
transform="matrix(1.25,0,0,1.25,-200,23.193113)">
<path
inkscape:connector-curvature="0"
d="m 434.398,221.727 c 0,2.207 -1.789,4 -4,4 -2.207,0 -4,-1.793 -4,-4 0,-2.211 1.793,-4 4,-4 2.211,0 4,1.789 4,4 z"
style="fill:none;stroke:#000000;stroke-width:1.30079997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path145" />
</g>
<g
id="g151"
transform="matrix(0,1.25,-1.25,0,-200,23.193113)">
<path
inkscape:connector-curvature="0"
d="m 175.324,-407.199 h 29.539 v -14.66 h 36.922 v 14.66 h 29.539"
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path149" />
</g>
<g
id="g155"
transform="matrix(0,1.25,-1.25,0,-200,23.193113)">
<path
inkscape:connector-curvature="0"
d="m 205.215,-425.902 h 36.57"
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path153" />
</g>
<g
id="g159"
transform="matrix(0,1.25,-1.25,0,-200,23.193113)">
<path
inkscape:connector-curvature="0"
d="m 202.648,-421.859 h 40.614"
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path157" />
</g>
</g>
<g
id="g179"
transform="rotate(-90,502.65766,258.08202)">
<g
transform="matrix(1.25,0,0,1.25,-200,23.193113)"
id="g165">
<path
id="path163"
style="fill:none;stroke:#000000;stroke-width:1.30079997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 434.398,221.727 c 0,2.207 -1.789,4 -4,4 -2.207,0 -4,-1.793 -4,-4 0,-2.211 1.793,-4 4,-4 2.211,0 4,1.789 4,4 z"
inkscape:connector-curvature="0" />
</g>
<g
transform="matrix(0,1.25,-1.25,0,-200,23.193113)"
id="g169">
<path
id="path167"
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 175.324,-407.199 h 29.539 v -14.66 h 36.922 v 14.66 h 29.539"
inkscape:connector-curvature="0" />
</g>
<g
transform="matrix(0,1.25,-1.25,0,-200,23.193113)"
id="g173">
<path
id="path171"
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 205.215,-425.902 h 36.57"
inkscape:connector-curvature="0" />
</g>
<g
transform="matrix(0,1.25,-1.25,0,-200,23.193113)"
id="g177">
<path
id="path175"
style="fill:none;stroke:#000000;stroke-width:1.60000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 202.648,-421.859 h 40.614"
inkscape:connector-curvature="0" />
</g>
</g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More