Merge branch 'master' of https://github.com/mguthaus/OpenRAM into multiport
|
|
@ -0,0 +1 @@
|
|||
*.sp linguist-vendored
|
||||
|
|
@ -1,4 +1,7 @@
|
|||
.DS_Store
|
||||
*~
|
||||
*.pyc
|
||||
*.log
|
||||
*.aux
|
||||
*.out
|
||||
*.toc
|
||||
*.synctex.gz
|
||||
|
|
|
|||
|
|
@ -96,15 +96,14 @@ the tests on your contributions before they will be accepted.
|
|||
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,
|
||||
push your branch to YOUR repository:
|
||||
|
||||
10. After a final rebase and your code is working, push your branch to YOUR repository:
|
||||
```
|
||||
git rebase dev
|
||||
git push -u origin useful-branch-name
|
||||
```
|
||||
Remember origin is your copy on github and useful-branch-name is the
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ def parse_output(filename, key):
|
|||
|
||||
if val != None:
|
||||
debug.info(4, "Key = " + key + " Val = " + val.group(1))
|
||||
return val.group(1)
|
||||
return convert_to_float(val.group(1))
|
||||
else:
|
||||
return "Failed"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import os,sys,re,shutil
|
||||
import os,sys,re
|
||||
import debug
|
||||
import math
|
||||
import setup_hold
|
||||
|
|
@ -6,40 +6,31 @@ import delay
|
|||
import charutils as ch
|
||||
import tech
|
||||
import numpy as np
|
||||
from trim_spice import trim_spice
|
||||
from globals import OPTS
|
||||
|
||||
class lib:
|
||||
""" 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.sp_file = spfile
|
||||
self.sp_file = sp_file
|
||||
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
|
||||
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.prepare_tables()
|
||||
|
||||
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
|
||||
#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])
|
||||
self.load = tech.spice["FF_in_cap"]
|
||||
self.load = tech.spice["dff_in_cap"]
|
||||
self.loads = self.load_scales*self.load
|
||||
debug.info(1,"Loads: {0}".format(self.loads))
|
||||
|
||||
|
|
@ -49,9 +40,48 @@ class lib:
|
|||
self.slew = tech.spice["rise_time"]
|
||||
self.slews = self.slew_scales*self.slew
|
||||
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()
|
||||
|
||||
|
|
@ -62,12 +92,17 @@ class lib:
|
|||
self.write_control_pins()
|
||||
|
||||
self.write_clk()
|
||||
|
||||
self.write_footer()
|
||||
|
||||
|
||||
self.lib.close()
|
||||
def write_footer(self):
|
||||
""" Write the footer """
|
||||
self.lib.write("}\n")
|
||||
|
||||
def write_header(self):
|
||||
""" 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(" delay_model : \"table_lookup\";\n")
|
||||
|
||||
|
|
@ -75,22 +110,29 @@ class lib:
|
|||
self.write_defaults()
|
||||
self.write_LUT_templates()
|
||||
|
||||
self.lib.write(" default_operating_conditions : TT; \n")
|
||||
self.lib.write(" default_operating_conditions : OC; \n")
|
||||
|
||||
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(" memory(){ \n")
|
||||
self.lib.write(" type : ram;\n")
|
||||
self.lib.write(" address_width : {0};\n".format(self.addr_size))
|
||||
self.lib.write(" word_width : {0};\n".format(self.word_size))
|
||||
self.lib.write(" address_width : {};\n".format(self.sram.addr_size))
|
||||
self.lib.write(" word_width : {};\n".format(self.sram.word_size))
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" interface_timing : true;\n")
|
||||
self.lib.write(" dont_use : true;\n")
|
||||
self.lib.write(" map_only : 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):
|
||||
|
|
@ -103,9 +145,10 @@ class lib:
|
|||
self.lib.write(" capacitive_load_unit(1 ,fF) ;\n")
|
||||
self.lib.write(" leakage_power_unit : \"1mW\" ;\n")
|
||||
self.lib.write(" pulling_resistance_unit :\"1kohm\" ;\n")
|
||||
self.lib.write(" operating_conditions(TT){\n")
|
||||
self.lib.write(" voltage : {0} ;\n".format(tech.spice["supply_voltage"]))
|
||||
self.lib.write(" temperature : 25.000 ;\n")
|
||||
self.lib.write(" operating_conditions(OC){\n")
|
||||
self.lib.write(" process : {} ;\n".format(1.0)) # How to use TT, FF, SS?
|
||||
self.lib.write(" voltage : {} ;\n".format(self.voltage))
|
||||
self.lib.write(" temperature : {};\n".format(self.temperature))
|
||||
self.lib.write(" }\n\n")
|
||||
|
||||
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_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_leakage_power_density : 0.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(" base_type : array;\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_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(" type (ADDR){\n")
|
||||
self.lib.write(" base_type : array;\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_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")
|
||||
|
||||
|
||||
def write_FF_setuphold(self):
|
||||
""" Adds Setup and Hold timing results"""
|
||||
|
||||
self.compute_setup_hold()
|
||||
|
||||
self.lib.write(" timing(){ \n")
|
||||
self.lib.write(" timing_type : setup_rising; \n")
|
||||
self.lib.write(" related_pin : \"clk\"; \n")
|
||||
|
|
@ -255,12 +300,12 @@ class lib:
|
|||
def write_data_bus(self):
|
||||
""" Adds data bus timing results."""
|
||||
|
||||
self.compute_delay()
|
||||
|
||||
self.lib.write(" bus(DATA){\n")
|
||||
self.lib.write(" bus_type : DATA; \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(" memory_write(){ \n")
|
||||
self.lib.write(" address : ADDR; \n")
|
||||
|
|
@ -269,53 +314,29 @@ class lib:
|
|||
self.lib.write(" memory_read(){ \n")
|
||||
self.lib.write(" address : ADDR; \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.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_sense : non_unate; \n")
|
||||
self.lib.write(" related_pin : \"clk\"; \n")
|
||||
self.lib.write(" timing_type : falling_edge; \n")
|
||||
self.lib.write(" cell_rise(CELL_TABLE) {\n")
|
||||
rounded_values = map(ch.round_time,self.delay["delay1"])
|
||||
self.write_values(rounded_values,len(self.loads)," ")
|
||||
self.lib.write(" }\n")
|
||||
self.write_values(self.char_results["delay_lh"],len(self.loads)," ")
|
||||
self.lib.write(" }\n") # rise delay
|
||||
self.lib.write(" cell_fall(CELL_TABLE) {\n")
|
||||
rounded_values = map(ch.round_time,self.delay["delay0"])
|
||||
self.write_values(rounded_values,len(self.loads)," ")
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" rise_transition(CELL_TABLE) {\n")
|
||||
rounded_values = map(ch.round_time,self.delay["slew1"])
|
||||
self.write_values(rounded_values,len(self.loads)," ")
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" fall_transition(CELL_TABLE) {\n")
|
||||
rounded_values = map(ch.round_time,self.delay["slew0"])
|
||||
self.write_values(rounded_values,len(self.loads)," ")
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" }\n\n")
|
||||
self.write_values(self.char_results["delay_hl"],len(self.loads)," ")
|
||||
self.lib.write(" }\n") # fall delay
|
||||
self.lib.write(" rise_transition(CELL_TABLE) {\n")
|
||||
self.write_values(self.char_results["slew_lh"],len(self.loads)," ")
|
||||
self.lib.write(" }\n") # rise trans
|
||||
self.lib.write(" fall_transition(CELL_TABLE) {\n")
|
||||
self.write_values(self.char_results["slew_hl"],len(self.loads)," ")
|
||||
self.lib.write(" }\n") # fall trans
|
||||
self.lib.write(" }\n") # timing
|
||||
self.lib.write(" }\n") # pin
|
||||
self.lib.write(" }\n\n") # bus
|
||||
|
||||
|
||||
def write_addr_bus(self):
|
||||
|
|
@ -324,10 +345,9 @@ class lib:
|
|||
self.lib.write(" bus(ADDR){\n")
|
||||
self.lib.write(" bus_type : ADDR; \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(" fanout_load : 1.000000;\n")
|
||||
self.lib.write(" pin(ADDR[{0}:0])".format(self.addr_size - 1))
|
||||
self.lib.write(" pin(ADDR[{0}:0])".format(self.sram.addr_size - 1))
|
||||
self.lib.write("{\n")
|
||||
|
||||
self.write_FF_setuphold()
|
||||
|
|
@ -343,7 +363,7 @@ class lib:
|
|||
self.lib.write(" pin({0})".format(i))
|
||||
self.lib.write("{\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.lib.write(" }\n\n")
|
||||
|
||||
|
|
@ -351,14 +371,50 @@ class lib:
|
|||
def write_clk(self):
|
||||
""" Adds clk pin timing results."""
|
||||
|
||||
self.compute_delay()
|
||||
|
||||
self.lib.write(" pin(clk){\n")
|
||||
self.lib.write(" clock : true;\n")
|
||||
self.lib.write(" direction : input; \n")
|
||||
self.lib.write(" capacitance : {0}; \n".format(tech.spice["FF_in_cap"]))
|
||||
min_pulse_width = ch.round_time(self.delay["min_period"])/2.0
|
||||
min_period = ch.round_time(self.delay["min_period"])
|
||||
# This should actually be a min inverter cap, but ok...
|
||||
self.lib.write(" capacitance : {0}; \n".format(tech.spice["dff_in_cap"]))
|
||||
|
||||
# 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_type :\"min_pulse_width\"; \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")
|
||||
|
||||
def compute_delay(self):
|
||||
""" Do the analysis if we haven't characterized the SRAM yet """
|
||||
try:
|
||||
self.d
|
||||
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:
|
||||
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:
|
||||
probe_address = "1" * self.addr_size
|
||||
probe_data = self.word_size - 1
|
||||
# We must trim based on a specific address and data bit
|
||||
if OPTS.trim_netlist:
|
||||
self.trimsp.trim(probe_address,probe_data)
|
||||
self.delay = self.d.analyze(probe_address, probe_data, self.slews, self.loads)
|
||||
probe_address = "1" * self.sram.addr_size
|
||||
probe_data = self.sram.word_size - 1
|
||||
self.char_results = self.d.analyze(probe_address, probe_data, self.slews, self.loads)
|
||||
|
||||
|
||||
def compute_setup_hold(self):
|
||||
""" Do the analysis if we haven't characterized a FF yet """
|
||||
|
|
@ -405,9 +458,9 @@ class lib:
|
|||
try:
|
||||
self.sh
|
||||
except AttributeError:
|
||||
self.sh = setup_hold.setup_hold()
|
||||
self.sh = setup_hold.setup_hold(self.corner)
|
||||
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:
|
||||
self.times = self.sh.analyze(self.slews,self.slews)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,18 +13,23 @@ class setup_hold():
|
|||
(Bisection Methodology)
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, corner):
|
||||
# This must match the spice model order
|
||||
self.pins = ["data", "dout", "dout_bar", "clk", "vdd", "gnd"]
|
||||
self.model_name = "ms_flop"
|
||||
self.model_location = OPTS.openram_tech + "sp_lib/ms_flop.sp"
|
||||
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))
|
||||
|
||||
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):
|
||||
|
|
@ -33,14 +38,14 @@ class setup_hold():
|
|||
# creates and opens the stimulus file for writing
|
||||
temp_stim = OPTS.openram_temp + "stim.sp"
|
||||
self.sf = open(temp_stim, "w")
|
||||
self.stim = stimuli.stimuli(self.sf, self.corner)
|
||||
|
||||
self.write_header(correct_value)
|
||||
|
||||
# instantiate the master-slave d-flip-flop
|
||||
self.sf.write("\n* Instantiation of the Master-Slave D-flip-flop\n")
|
||||
stimuli.inst_model(stim_file=self.sf,
|
||||
pins=self.pins,
|
||||
model_name=self.model_name)
|
||||
self.stim.inst_model(pins=self.pins,
|
||||
model_name=self.model_name)
|
||||
|
||||
self.write_data(mode=mode,
|
||||
target_time=target_time,
|
||||
|
|
@ -52,7 +57,7 @@ class setup_hold():
|
|||
correct_value=correct_value)
|
||||
|
||||
|
||||
stimuli.write_control(self.sf,4*self.period)
|
||||
self.stim.write_control(4*self.period)
|
||||
|
||||
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))
|
||||
|
||||
# include files in stimulus file
|
||||
self.model_list = tech.spice["fet_models"] + [self.model_location]
|
||||
stimuli.write_include(stim_file=self.sf,
|
||||
models=self.model_list)
|
||||
self.stim.write_include(self.model_location)
|
||||
|
||||
# add vdd/gnd statements
|
||||
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):
|
||||
|
|
@ -77,7 +80,7 @@ class setup_hold():
|
|||
|
||||
"""
|
||||
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":
|
||||
init_value = incorrect_value
|
||||
start_value = correct_value
|
||||
|
|
@ -87,29 +90,27 @@ class setup_hold():
|
|||
start_value = incorrect_value
|
||||
end_value = correct_value
|
||||
|
||||
stimuli.gen_pwl(stim_file=self.sf,
|
||||
sig_name="data",
|
||||
clk_times=[0, self.period, target_time],
|
||||
data_values=[init_value, start_value, end_value],
|
||||
period=target_time,
|
||||
slew=self.constrained_input_slew,
|
||||
setup=0)
|
||||
self.stim.gen_pwl(sig_name="data",
|
||||
clk_times=[0, self.period, target_time],
|
||||
data_values=[init_value, start_value, end_value],
|
||||
period=target_time,
|
||||
slew=self.constrained_input_slew,
|
||||
setup=0)
|
||||
|
||||
def write_clock(self):
|
||||
""" Create the clock signal for setup/hold analysis. First period initializes the FF
|
||||
while the second is used for characterization."""
|
||||
|
||||
stimuli.gen_pwl(stim_file=self.sf,
|
||||
sig_name="clk",
|
||||
# initial clk edge is right after the 0 time to initialize a flop
|
||||
# without using .IC on an internal node.
|
||||
# Return input to value after one period.
|
||||
# The second pulse is the characterization one at 2*period
|
||||
clk_times=[0, 0.1*self.period,self.period,2*self.period],
|
||||
data_values=[0, 1, 0, 1],
|
||||
period=2*self.period,
|
||||
slew=self.constrained_input_slew,
|
||||
setup=0)
|
||||
self.stim.gen_pwl(sig_name="clk",
|
||||
# initial clk edge is right after the 0 time to initialize a flop
|
||||
# without using .IC on an internal node.
|
||||
# Return input to value after one period.
|
||||
# The second pulse is the characterization one at 2*period
|
||||
clk_times=[0, 0.1*self.period,self.period,2*self.period],
|
||||
data_values=[0, 1, 0, 1],
|
||||
period=2*self.period,
|
||||
slew=self.constrained_input_slew,
|
||||
setup=0)
|
||||
|
||||
|
||||
|
||||
|
|
@ -135,32 +136,30 @@ class setup_hold():
|
|||
self.sf.write("\n* Measure statements for pass/fail verification\n")
|
||||
trig_name = "clk"
|
||||
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
|
||||
stimuli.gen_meas_delay(stim_file=self.sf,
|
||||
meas_name="clk2q_delay",
|
||||
trig_name=trig_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=trig_val,
|
||||
targ_val=targ_val,
|
||||
trig_dir="RISE",
|
||||
targ_dir=dout_rise_or_fall,
|
||||
trig_td=1.9*self.period,
|
||||
targ_td=1.9*self.period)
|
||||
|
||||
self.stim.gen_meas_delay(meas_name="clk2q_delay",
|
||||
trig_name=trig_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=trig_val,
|
||||
targ_val=targ_val,
|
||||
trig_dir="RISE",
|
||||
targ_dir=dout_rise_or_fall,
|
||||
trig_td=1.9*self.period,
|
||||
targ_td=1.9*self.period)
|
||||
|
||||
targ_name = "data"
|
||||
# Start triggers right after initialize value is returned to normal
|
||||
# at one period
|
||||
stimuli.gen_meas_delay(stim_file=self.sf,
|
||||
meas_name="setup_hold_time",
|
||||
trig_name=trig_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=trig_val,
|
||||
targ_val=targ_val,
|
||||
trig_dir="RISE",
|
||||
targ_dir=din_rise_or_fall,
|
||||
trig_td=1.2*self.period,
|
||||
targ_td=1.2*self.period)
|
||||
self.stim.gen_meas_delay(meas_name="setup_hold_time",
|
||||
trig_name=trig_name,
|
||||
targ_name=targ_name,
|
||||
trig_val=trig_val,
|
||||
targ_val=targ_val,
|
||||
trig_dir="RISE",
|
||||
targ_dir=din_rise_or_fall,
|
||||
trig_td=1.2*self.period,
|
||||
targ_td=1.2*self.period)
|
||||
|
||||
|
||||
|
||||
|
|
@ -186,7 +185,7 @@ class setup_hold():
|
|||
self.write_stimulus(mode=mode,
|
||||
target_time=feasible_bound,
|
||||
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"))
|
||||
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))
|
||||
|
|
@ -219,7 +218,7 @@ class setup_hold():
|
|||
feasible_bound))
|
||||
|
||||
|
||||
stimuli.run_sim()
|
||||
self.stim.run_sim()
|
||||
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"))
|
||||
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
|
||||
|
||||
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.
|
||||
"""
|
||||
LH_setup = []
|
||||
|
|
|
|||
|
|
@ -12,290 +12,302 @@ import sys
|
|||
import numpy as np
|
||||
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):
|
||||
""" Function to instatiate an SRAM subckt. """
|
||||
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))
|
||||
class stimuli():
|
||||
""" Class for providing stimuli functions """
|
||||
|
||||
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):
|
||||
""" 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.sf = stim_file
|
||||
|
||||
(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):
|
||||
""" 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(vdd_name) + ")*I(v" + str(vdd_name) + "))')"
|
||||
stim_file.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(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 inst_sram(self, abits, dbits, sram_name):
|
||||
""" Function to instatiate an SRAM subckt. """
|
||||
self.sf.write("Xsram ")
|
||||
for i in range(dbits):
|
||||
self.sf.write("D[{0}] ".format(i))
|
||||
for i in range(abits):
|
||||
self.sf.write("A[{0}] ".format(i))
|
||||
for i in tech.spice["control_signals"]:
|
||||
self.sf.write("{0} ".format(i))
|
||||
self.sf.write("{0} ".format(tech.spice["clk"]))
|
||||
self.sf.write("{0} {1} ".format(self.vdd_name, self.gnd_name))
|
||||
self.sf.write("{0}\n".format(sram_name))
|
||||
|
||||
|
||||
def write_include(stim_file, models):
|
||||
"""Writes include statements, inputs are lists of model files"""
|
||||
for item in list(models):
|
||||
if os.path.isfile(item):
|
||||
stim_file.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 inst_model(self, pins, model_name):
|
||||
""" Function to instantiate a generic model with a set of pins """
|
||||
self.sf.write("X{0} ".format(model_name))
|
||||
for pin in pins:
|
||||
self.sf.write("{0} ".format(pin))
|
||||
self.sf.write("{0}\n".format(model_name))
|
||||
|
||||
|
||||
def write_supply(stim_file):
|
||||
""" Writes supply voltage statements """
|
||||
stim_file.write("V{0} {0} 0.0 {1}\n".format(vdd_name, vdd_voltage))
|
||||
stim_file.write("V{0} {0} 0.0 {1}\n".format(gnd_name, gnd_voltage))
|
||||
# This is for the test power supply
|
||||
stim_file.write("V{0} {0} 0.0 {1}\n".format("test"+vdd_name, vdd_voltage))
|
||||
stim_file.write("V{0} {0} 0.0 {1}\n".format("test"+gnd_name, gnd_voltage))
|
||||
def create_inverter(self, size=1, beta=2.5):
|
||||
""" Generates inverter for the top level signals (only for sim purposes) """
|
||||
self.sf.write(".SUBCKT test_inv in out {0} {1}\n".format(self.vdd_name, self.gnd_name))
|
||||
self.sf.write("mpinv out in {0} {0} {1} w={2}u l={3}u\n".format(self.vdd_name,
|
||||
self.pmos_name,
|
||||
beta * size * self.tx_width,
|
||||
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():
|
||||
""" 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:
|
||||
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
|
||||
def create_buffer(self, 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.
|
||||
"""
|
||||
|
||||
self.sf.write(".SUBCKT test_{2} in out {0} {1}\n".format(self.vdd_name,
|
||||
self.gnd_name,
|
||||
buffer_name))
|
||||
self.sf.write("mpinv1 out_inv in {0} {0} {1} w={2}u l={3}u\n".format(self.vdd_name,
|
||||
self.pmos_name,
|
||||
beta * size[0] * self.tx_width,
|
||||
self.tx_length))
|
||||
self.sf.write("mninv1 out_inv in {0} {0} {1} w={2}u l={3}u\n".format(self.gnd_name,
|
||||
self.nmos_name,
|
||||
size[0] * self.tx_width,
|
||||
self.tx_length))
|
||||
self.sf.write("mpinv2 out out_inv {0} {0} {1} w={2}u l={3}u\n".format(self.vdd_name,
|
||||
self.pmos_name,
|
||||
beta * size[1] * self.tx_width,
|
||||
self.tx_length))
|
||||
self.sf.write("mninv2 out out_inv {0} {0} {1} w={2}u l={3}u\n".format(self.gnd_name,
|
||||
self.nmos_name,
|
||||
size[1] * self.tx_width,
|
||||
self.tx_length))
|
||||
self.sf.write(".ENDS test_{0}\n\n".format(buffer_name))
|
||||
|
||||
|
||||
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')
|
||||
spice_stderr = open("{0}spice_stderr.log".format(OPTS.openram_temp), 'w')
|
||||
def inst_accesstx(self, dbits):
|
||||
""" 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)
|
||||
retcode = subprocess.call(cmd, stdout=spice_stdout, stderr=spice_stderr, shell=True)
|
||||
def gen_pulse(self, sig_name, v1, v2, offset, period, t_rise, t_fall):
|
||||
"""
|
||||
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):
|
||||
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))
|
||||
# shift signal times earlier for setup time
|
||||
times = np.array(clk_times) - setup*period
|
||||
values = np.array(data_values) * self.voltage
|
||||
half_slew = 0.5 * slew
|
||||
self.sf.write("* (time, data): {}\n".format(zip(clk_times, data_values)))
|
||||
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))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
word_size = 2
|
||||
num_words = 128
|
||||
num_words = 16
|
||||
num_banks = 1
|
||||
|
||||
tech_name = "freepdk45"
|
||||
process_corners = ["TT"]
|
||||
supply_voltages = [1.0]
|
||||
temperatures = [25]
|
||||
|
||||
output_path = "temp"
|
||||
output_name = "sram_2_16_1_freepdk45"
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@ num_words = 16
|
|||
num_banks = 1
|
||||
|
||||
tech_name = "scn3me_subm"
|
||||
process_corners = ["TT"]
|
||||
supply_voltages = [ 5.0 ]
|
||||
temperatures = [ 25 ]
|
||||
|
||||
|
||||
output_path = "temp"
|
||||
output_name = "sram_2_16_1_scn3me_subm"
|
||||
|
|
|
|||
|
|
@ -772,29 +772,36 @@ class VlsiLayout:
|
|||
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
|
||||
that the label coordinates are inside.
|
||||
"""
|
||||
StructureName=Structure[0]
|
||||
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]]
|
||||
|
||||
# check if this is a rectangle
|
||||
structureName=structure[0]
|
||||
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 = []
|
||||
|
||||
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:
|
||||
left_bottom=boundary.coordinates[0]
|
||||
right_top=boundary.coordinates[2]
|
||||
MetalBoundary=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]]
|
||||
MetalBoundary=self.transformRectangle(MetalBoundary,StructureuVector,StructurevVector)
|
||||
MetalBoundary=[MetalBoundary[0]+StructureOrigin[0],MetalBoundary[1]+StructureOrigin[1],
|
||||
MetalBoundary[2]+StructureOrigin[0],MetalBoundary[3]+StructureOrigin[1]]
|
||||
# Rectangle is [leftx, bottomy, rightx, topy].
|
||||
boundaryRect=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]]
|
||||
boundaryRect=self.transformRectangle(boundaryRect,structureuVector,structurevVector)
|
||||
boundaryRect=[boundaryRect[0]+structureOrigin[0],boundaryRect[1]+structureOrigin[1],
|
||||
boundaryRect[2]+structureOrigin[0],boundaryRect[3]+structureOrigin[1]]
|
||||
|
||||
if self.labelInRectangle(coordinates,MetalBoundary):
|
||||
boundaries.append(MetalBoundary)
|
||||
if self.labelInRectangle(coordinates,boundaryRect):
|
||||
boundaries.append(boundaryRect)
|
||||
|
||||
return boundaries
|
||||
|
||||
|
|
@ -829,7 +836,7 @@ class VlsiLayout:
|
|||
|
||||
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_y_range=(coordinate[1]>=int(rectangle[1]))&(coordinate[1]<=int(rectangle[3]))
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
@ -16,12 +16,6 @@ USAGE = "Usage: openram.py [options] <config file>\nUse -h for help.\n"
|
|||
# Anonymous object that will be the 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():
|
||||
""" Parse the optional arguments for OpenRAM """
|
||||
|
||||
|
|
@ -36,8 +30,6 @@ def parse_args():
|
|||
help="Output file(s) location"),
|
||||
optparse.make_option("-n", "--nocheck", action="store_false",
|
||||
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",
|
||||
help="Increase the verbosity level"),
|
||||
optparse.make_option("-t", "--tech", dest="tech_name",
|
||||
|
|
@ -66,13 +58,13 @@ def parse_args():
|
|||
# Alias SCMOS to AMI 0.5um
|
||||
if OPTS.tech_name == "scmos":
|
||||
OPTS.tech_name = "scn3me_subm"
|
||||
|
||||
|
||||
return (options, args)
|
||||
|
||||
def print_banner():
|
||||
""" Conditionally print the banner to stdout """
|
||||
global OPTS
|
||||
if not OPTS.print_banner:
|
||||
if OPTS.is_unit_test:
|
||||
return
|
||||
|
||||
print("|==============================================================================|")
|
||||
|
|
@ -85,22 +77,41 @@ def print_banner():
|
|||
print("|=========" + "VLSI Computer Architecture Research Group".center(60) + "=========|")
|
||||
print("|=========" + "Oklahoma State University ECE Department".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("|==============================================================================|")
|
||||
|
||||
|
||||
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."""
|
||||
check_versions()
|
||||
|
||||
debug.info(1,"Initializing OpenRAM...")
|
||||
|
||||
setup_paths()
|
||||
|
||||
read_config(config_file)
|
||||
read_config(config_file, is_unit_test)
|
||||
|
||||
import_tech()
|
||||
|
||||
|
||||
|
||||
def get_tool(tool_type, preferences):
|
||||
"""
|
||||
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
|
||||
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('/'):
|
||||
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)
|
||||
|
||||
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!
|
||||
# make the directory if it doesn't exist
|
||||
try:
|
||||
|
|
@ -173,6 +196,7 @@ def read_config(config_file):
|
|||
def end_openram():
|
||||
""" Clean up openram for a proper exit """
|
||||
cleanup_paths()
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -197,16 +221,14 @@ def setup_paths():
|
|||
except:
|
||||
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+"/gdsMill"),
|
||||
"$OPENRAM_HOME/gdsMill does not exist: {0}".format(OPENRAM_HOME+"/gdsMill"))
|
||||
sys.path.append("{0}/gdsMill".format(OPENRAM_HOME))
|
||||
debug.check(os.path.isdir(OPENRAM_HOME+"/tests"),
|
||||
"$OPENRAM_HOME/tests does not exist: {0}".format(OPENRAM_HOME+"/tests"))
|
||||
sys.path.append("{0}/tests".format(OPENRAM_HOME))
|
||||
debug.check(os.path.isdir(OPENRAM_HOME+"/router"),
|
||||
"$OPENRAM_HOME/router does not exist: {0}".format(OPENRAM_HOME+"/router"))
|
||||
sys.path.append("{0}/router".format(OPENRAM_HOME))
|
||||
|
||||
# Add all of the subdirs to the python path
|
||||
# These subdirs are modules and don't need to be added: characterizer, verify
|
||||
for subdir in ["gdsMill", "tests", "router", "modules", "base", "pgates"]:
|
||||
full_path = "{0}/{1}".format(OPENRAM_HOME,subdir)
|
||||
debug.check(os.path.isdir(full_path),
|
||||
"$OPENRAM_HOME/{0} does not exist: {1}".format(subdir,full_path))
|
||||
sys.path.append("{0}".format(full_path))
|
||||
|
||||
if not OPTS.openram_temp.endswith('/'):
|
||||
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.
|
||||
OPTS.tech_name = OPTS.tech_name
|
||||
|
||||
|
||||
# environment variable should point to the technology dir
|
||||
|
||||
# environment variable should point to the technology dir
|
||||
try:
|
||||
OPENRAM_TECH = os.path.abspath(os.environ.get("OPENRAM_TECH"))
|
||||
except:
|
||||
|
|
@ -270,3 +291,42 @@ def import_tech():
|
|||
debug.error("Nonexistent technology_setup_file: {0}.py".format(filename))
|
||||
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.")
|
||||
|
||||
|
|
|
|||
|
|
@ -69,9 +69,10 @@ class control_logic(design.design):
|
|||
c = reload(__import__(OPTS.replica_bitline))
|
||||
replica_bitline = getattr(c, OPTS.replica_bitline)
|
||||
# FIXME: These should be tuned according to the size!
|
||||
FO4_stages = 4
|
||||
bitcell_loads = int(math.ceil(self.num_rows / 10.0))
|
||||
self.replica_bitline = replica_bitline(FO4_stages, bitcell_loads)
|
||||
delay_stages = 4 # This should be even so that the delay line is inverting!
|
||||
delay_fanout = 3
|
||||
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)
|
||||
|
||||
|
||||
|
|
@ -8,7 +8,8 @@ from globals import OPTS
|
|||
|
||||
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.
|
||||
"""
|
||||
|
||||
|
|
@ -19,6 +20,9 @@ class delay_chain(design.design):
|
|||
# and there should be functions to get
|
||||
# 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.
|
||||
self.fanout_list = fanout_list
|
||||
self.num_inverters = 1 + sum(fanout_list)
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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)
|
||||
|
|
@ -29,13 +29,13 @@ class precharge(pgate.pgate):
|
|||
self.DRC_LVS()
|
||||
|
||||
def add_pins(self):
|
||||
self.add_pin_list(["bl", "br", "clk", "vdd"])
|
||||
self.add_pin_list(["bl", "br", "en", "vdd"])
|
||||
|
||||
def create_layout(self):
|
||||
self.create_ptx()
|
||||
self.add_ptx()
|
||||
self.connect_poly()
|
||||
self.add_pclk()
|
||||
self.add_en()
|
||||
self.add_nwell_and_contact()
|
||||
self.add_vdd_rail()
|
||||
self.add_bitlines()
|
||||
|
|
@ -74,7 +74,7 @@ class precharge(pgate.pgate):
|
|||
self.lower_pmos_inst=self.add_inst(name="lower_pmos",
|
||||
mod=self.pmos,
|
||||
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
|
||||
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",
|
||||
mod=self.pmos,
|
||||
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
|
||||
self.upper_pmos2_inst=self.add_inst(name="upper_pmos2",
|
||||
mod=self.pmos,
|
||||
offset=upper_pmos2_pos)
|
||||
self.connect_inst(["br", "clk", "vdd", "vdd"])
|
||||
self.connect_inst(["br", "en", "vdd", "vdd"])
|
||||
|
||||
def connect_poly(self):
|
||||
"""Connects the upper and lower pmos together"""
|
||||
|
|
@ -109,16 +109,16 @@ class precharge(pgate.pgate):
|
|||
width=xlength,
|
||||
height=self.poly_width)
|
||||
|
||||
def add_pclk(self):
|
||||
"""Adds the pclk input rail, pclk contact/vias, and connects to the pmos"""
|
||||
# adds the pclk contact to connect the gates to the pclk rail on metal1
|
||||
def add_en(self):
|
||||
"""Adds the en input rail, en contact/vias, and connects to the pmos"""
|
||||
# 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)
|
||||
self.add_contact_center(layers=("poly", "contact", "metal1"),
|
||||
offset=offset,
|
||||
rotate=90)
|
||||
|
||||
# adds the pclk rail on metal1
|
||||
self.add_layout_pin_center_segment(text="clk",
|
||||
# adds the en rail on metal1
|
||||
self.add_layout_pin_center_segment(text="en",
|
||||
layer="metal1",
|
||||
start=offset.scale(0,1),
|
||||
end=offset.scale(0,1)+vector(self.width,0))
|
||||
|
|
@ -46,7 +46,7 @@ class precharge_array(design.design):
|
|||
|
||||
self.add_layout_pin(text="en",
|
||||
layer="metal1",
|
||||
offset=self.pc_cell.get_pin("clk").ll(),
|
||||
offset=self.pc_cell.get_pin("en").ll(),
|
||||
width=self.width,
|
||||
height=drc["minwidth_metal1"])
|
||||
|
||||
|
|
@ -11,11 +11,11 @@ from globals import OPTS
|
|||
class replica_bitline(design.design):
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
|
||||
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)
|
||||
|
||||
g = reload(__import__(OPTS.delay_chain))
|
||||
|
|
@ -30,7 +30,8 @@ class replica_bitline(design.design):
|
|||
for pin in ["en", "out", "vdd", "gnd"]:
|
||||
self.add_pin(pin)
|
||||
self.bitcell_loads = bitcell_loads
|
||||
self.FO4_stages = FO4_stages
|
||||
self.delay_stages = delay_stages
|
||||
self.delay_fanout = delay_fanout
|
||||
|
||||
self.create_modules()
|
||||
self.calculate_module_offsets()
|
||||
|
|
@ -83,7 +84,7 @@ class replica_bitline(design.design):
|
|||
self.add_mod(self.rbl)
|
||||
|
||||
# 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.inv = pinv()
|
||||
|
|
@ -14,116 +14,49 @@ import sys,os
|
|||
import datetime
|
||||
import re
|
||||
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.
|
||||
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
|
||||
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))
|
||||
# Output info about this run
|
||||
report_status()
|
||||
|
||||
if not OPTS.tech_name:
|
||||
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
|
||||
# Start importing design modules after we have the config file
|
||||
import verify
|
||||
import sram
|
||||
|
||||
print("Output files are " + OPTS.output_name + ".(sp|gds|v|lib|lef)")
|
||||
|
||||
# Keep track of running stats
|
||||
start_time = datetime.datetime.now()
|
||||
last_time = start_time
|
||||
print_time("Start",datetime.datetime.now())
|
||||
if not OPTS.check_lvsdrc:
|
||||
print("DRC/LVS/PEX checking is disabled.")
|
||||
print_time("Start",start_time)
|
||||
|
||||
# import SRAM test generation
|
||||
s = sram.sram(word_size=word_size,
|
||||
num_words=num_words,
|
||||
num_banks=num_banks,
|
||||
s = sram.sram(word_size=OPTS.word_size,
|
||||
num_words=OPTS.num_words,
|
||||
num_banks=OPTS.num_banks,
|
||||
name=OPTS.output_name)
|
||||
last_time=print_time("SRAM creation", datetime.datetime.now(), last_time)
|
||||
|
||||
# Output the files for the resulting SRAM
|
||||
s.save_output()
|
||||
|
||||
spname = OPTS.output_path + s.name + ".sp"
|
||||
print("SP: Writing to {0}".format(spname))
|
||||
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()
|
||||
# Delete temp files etc.
|
||||
end_openram()
|
||||
print_time("End",datetime.datetime.now(), start_time)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -39,17 +39,27 @@ class options(optparse.Values):
|
|||
# Define the output file paths
|
||||
output_path = "."
|
||||
# Define the output file base name
|
||||
output_name = "sram"
|
||||
output_name = ""
|
||||
# Use analytical delay models by default rather than (slow) characterization
|
||||
analytical_delay = True
|
||||
# Purge the temp directory after a successful run (doesn't purge on errors, anyhow)
|
||||
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
|
||||
decoder = "hierarchical_decoder"
|
||||
ms_flop = "ms_flop"
|
||||
ms_flop_array = "ms_flop_array"
|
||||
dff = "dff"
|
||||
dff_array = "dff_array"
|
||||
control_logic = "control_logic"
|
||||
bitcell_array = "bitcell_array"
|
||||
sense_amp = "sense_amp"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from bank import bank
|
|||
import datetime
|
||||
import getpass
|
||||
from vector import vector
|
||||
from globals import OPTS
|
||||
from globals import OPTS, print_time
|
||||
|
||||
|
||||
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,
|
||||
self.num_words))
|
||||
start_time = datetime.datetime.now()
|
||||
|
||||
design.design.__init__(self, name)
|
||||
|
||||
|
|
@ -74,6 +75,10 @@ class sram(design.design):
|
|||
|
||||
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):
|
||||
""" 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):
|
||||
""" LH and HL are the same in analytical model. """
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ class code_format_test(openram_test):
|
|||
continue
|
||||
if re.search("openram.py$", code):
|
||||
continue
|
||||
if re.search("gen_stimulus.py$", code):
|
||||
continue
|
||||
errors += check_print_output(code)
|
||||
|
||||
# fails if there are any tabs in any files
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
@ -22,15 +22,16 @@ class replica_bitline_test(openram_test):
|
|||
import replica_bitline
|
||||
|
||||
stages=4
|
||||
fanout=4
|
||||
rows=13
|
||||
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)
|
||||
|
||||
stages=8
|
||||
rows=100
|
||||
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)
|
||||
|
||||
OPTS.check_lvsdrc = True
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class timing_sram_test(openram_test):
|
|||
debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1)
|
||||
|
||||
import sram
|
||||
|
||||
import tech
|
||||
debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank")
|
||||
s = sram.sram(word_size=OPTS.word_size,
|
||||
num_words=OPTS.num_words,
|
||||
|
|
@ -43,32 +43,35 @@ class timing_sram_test(openram_test):
|
|||
probe_data = s.word_size - 1
|
||||
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
|
||||
loads = [tech.spice["FF_in_cap"]*4]
|
||||
loads = [tech.spice["msflop_in_cap"]*4]
|
||||
slews = [tech.spice["rise_time"]*2]
|
||||
data = d.analyze(probe_address, probe_data,slews,loads)
|
||||
#print data
|
||||
if OPTS.tech_name == "freepdk45":
|
||||
golden_data = {'read1_power': 0.0345742,
|
||||
'read0_power': 0.03526189999999999,
|
||||
'write0_power': 0.0270014,
|
||||
'delay1': [0.0573107],
|
||||
'delay0': [0.07055809999999998],
|
||||
'min_period': 0.234,
|
||||
'write1_power': 0.0376625,
|
||||
'slew0': [0.0284344],
|
||||
'slew1': [0.0189185]}
|
||||
golden_data = {'leakage_power': 0.0006964536000000001,
|
||||
'delay_lh': [0.0573055],
|
||||
'read0_power': [0.0337812],
|
||||
'read1_power': [0.032946500000000004],
|
||||
'write1_power': [0.0361529],
|
||||
'write0_power': [0.026179099999999997],
|
||||
'slew_hl': [0.0285185],
|
||||
'min_period': 0.205,
|
||||
'delay_hl': [0.070554],
|
||||
'slew_lh': [0.0190073]}
|
||||
elif OPTS.tech_name == "scn3me_subm":
|
||||
golden_data = {'read1_power': 11.2474,
|
||||
'read0_power': 11.3148,
|
||||
'write0_power': 6.9064,
|
||||
'delay1': [1.0298],
|
||||
'delay0': [1.4102],
|
||||
'min_period': 4.063,
|
||||
'write1_power': 11.6964,
|
||||
'slew0': [1.3118],
|
||||
'slew1': [0.9816656]}
|
||||
golden_data = {'leakage_power': 0.0004004581,
|
||||
'delay_lh': [0.6538954],
|
||||
'read0_power': [9.7622],
|
||||
'read1_power': [9.589],
|
||||
'write1_power': [10.2578],
|
||||
'write0_power': [6.928400000000001],
|
||||
'slew_hl': [0.8321625],
|
||||
'min_period': 2.344,
|
||||
'delay_hl': [0.9019090999999999],
|
||||
'slew_lh': [0.5896232]}
|
||||
else:
|
||||
self.assertTrue(False) # other techs fail
|
||||
# Check if no too many or too few results
|
||||
|
|
|
|||
|
|
@ -31,19 +31,20 @@ class timing_setup_test(openram_test):
|
|||
import tech
|
||||
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)
|
||||
|
||||
#print data
|
||||
if OPTS.tech_name == "freepdk45":
|
||||
golden_data = {'setup_times_LH': [0.014648399999999999],
|
||||
'hold_times_LH': [0.0024414],
|
||||
'hold_times_HL': [-0.0036620999999999997],
|
||||
'setup_times_HL': [0.0085449]}
|
||||
elif OPTS.tech_name == "scn3me_subm":
|
||||
golden_data = {'setup_times_LH': [0.1000977],
|
||||
'hold_times_LH': [0.020751999999999996],
|
||||
'hold_times_HL': [-0.0830078],
|
||||
'setup_times_HL': [0.020751999999999996]}
|
||||
golden_data = {'setup_times_LH': [0.08178709999999999],
|
||||
'hold_times_LH': [0.0024414],
|
||||
'hold_times_HL': [-0.0646973],
|
||||
'setup_times_HL': [0.0390625]}
|
||||
else:
|
||||
self.assertTrue(False) # other techs fail
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class timing_sram_test(openram_test):
|
|||
debug.error("Could not find {} simulator.".format(OPTS.spice_name),-1)
|
||||
|
||||
import sram
|
||||
|
||||
import tech
|
||||
debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank")
|
||||
s = sram.sram(word_size=OPTS.word_size,
|
||||
num_words=OPTS.num_words,
|
||||
|
|
@ -41,32 +41,35 @@ class timing_sram_test(openram_test):
|
|||
probe_data = s.word_size - 1
|
||||
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
|
||||
loads = [tech.spice["FF_in_cap"]*4]
|
||||
loads = [tech.spice["msflop_in_cap"]*4]
|
||||
slews = [tech.spice["rise_time"]*2]
|
||||
data = d.analyze(probe_address, probe_data,slews,loads)
|
||||
#print data
|
||||
if OPTS.tech_name == "freepdk45":
|
||||
golden_data = {'read1_power': 0.03308298,
|
||||
'read0_power': 0.03866541,
|
||||
'write0_power': 0.02695139,
|
||||
'delay1': [0.05840294000000001],
|
||||
'delay0': [0.40787249999999997],
|
||||
'min_period': 0.781,
|
||||
'write1_power': 0.037257830000000006,
|
||||
'slew0': [0.035826199999999996],
|
||||
'slew1': [0.02059459]}
|
||||
golden_data = {'leakage_power': 0.0007348262,
|
||||
'delay_lh': [0.05799613],
|
||||
'read0_power': [0.0384102],
|
||||
'read1_power': [0.03279848],
|
||||
'write1_power': [0.03693655],
|
||||
'write0_power': [0.02717752],
|
||||
'slew_hl': [0.03607912],
|
||||
'min_period': 0.742,
|
||||
'delay_hl': [0.3929995],
|
||||
'slew_lh': [0.02160862]}
|
||||
elif OPTS.tech_name == "scn3me_subm":
|
||||
golden_data = {'read1_power': 10.31395,
|
||||
'read0_power': 10.0321,
|
||||
'write0_power': 6.072756,
|
||||
'delay1': [1.042564],
|
||||
'delay0': [1.412224],
|
||||
'min_period': 4.688,
|
||||
'write1_power': 10.53758,
|
||||
'slew0': [1.355812],
|
||||
'slew1': [1.03401]}
|
||||
golden_data = {'leakage_power': 0.00142014,
|
||||
'delay_lh': [0.8018421],
|
||||
'read0_power': [11.44908],
|
||||
'read1_power': [11.416549999999999],
|
||||
'write1_power': [11.718020000000001],
|
||||
'write0_power': [8.250219],
|
||||
'slew_hl': [0.8273725],
|
||||
'min_period': 2.734,
|
||||
'delay_hl': [1.085861],
|
||||
'slew_lh': [0.5730144]}
|
||||
else:
|
||||
self.assertTrue(False) # other techs fail
|
||||
|
||||
|
|
|
|||
|
|
@ -30,19 +30,20 @@ class timing_setup_test(openram_test):
|
|||
import tech
|
||||
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)
|
||||
|
||||
#print data
|
||||
if OPTS.tech_name == "freepdk45":
|
||||
golden_data = {'setup_times_LH': [0.01464844],
|
||||
'hold_times_LH': [0.0024414059999999997],
|
||||
'hold_times_HL': [-0.003662109],
|
||||
'setup_times_HL': [0.008544922]}
|
||||
elif OPTS.tech_name == "scn3me_subm":
|
||||
golden_data = {'setup_times_LH': [0.1000977],
|
||||
'hold_times_LH': [0.02075195],
|
||||
'hold_times_HL': [-0.08300781],
|
||||
'setup_times_HL': [0.02075195]}
|
||||
golden_data = {'setup_times_LH': [0.07568359],
|
||||
'hold_times_LH': [0.008544922],
|
||||
'hold_times_HL': [-0.05859374999999999],
|
||||
'setup_times_HL': [0.03295898]}
|
||||
else:
|
||||
self.assertTrue(False) # other techs fail
|
||||
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ class sram_func_test(openram_test):
|
|||
import sram
|
||||
|
||||
debug.info(1, "Testing timing for sample 1bit, 16words SRAM with 1 bank")
|
||||
s = sram.sram(word_size=OPTS.word_size,
|
||||
num_words=OPTS.num_words,
|
||||
num_banks=OPTS.num_banks,
|
||||
s = sram.sram(word_size=1,
|
||||
num_words=16,
|
||||
num_banks=1,
|
||||
name="sram_func_test")
|
||||
|
||||
OPTS.check_lvsdrc = True
|
||||
|
|
@ -43,14 +43,15 @@ class sram_func_test(openram_test):
|
|||
probe_data = s.word_size - 1
|
||||
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)
|
||||
|
||||
# This will exit if it doesn't find a feasible period
|
||||
import tech
|
||||
load = tech.spice["FF_in_cap"]*4
|
||||
slew = tech.spice["rise_time"]*2
|
||||
feasible_period = d.find_feasible_period(load,slew)
|
||||
d.load = tech.spice["msflop_in_cap"]*4
|
||||
d.slew = tech.spice["rise_time"]*2
|
||||
feasible_period = d.find_feasible_period()
|
||||
|
||||
os.remove(tempspice)
|
||||
OPTS.analytical_delay = True
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Check the .lib file for an SRAM
|
|||
|
||||
import unittest
|
||||
from testutils import header,openram_test
|
||||
import sys,os
|
||||
import sys,os,re
|
||||
sys.path.append(os.path.join(sys.path[0],".."))
|
||||
import globals
|
||||
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")
|
||||
s = sram.sram(word_size=2,
|
||||
num_words=OPTS.num_words,
|
||||
num_banks=OPTS.num_banks,
|
||||
num_words=16,
|
||||
num_banks=1,
|
||||
name="sram_2_16_1_{0}".format(OPTS.tech_name))
|
||||
OPTS.check_lvsdrc = True
|
||||
|
||||
tempspice = OPTS.openram_temp + "temp.sp"
|
||||
s.sp_write(tempspice)
|
||||
|
||||
filename = s.name + "_analytical.lib"
|
||||
libname = OPTS.openram_temp + filename
|
||||
lib.lib(libname=libname,sram=s,spfile=tempspice,use_model=True)
|
||||
lib.lib(out_dir=OPTS.openram_temp, sram=s, sp_file=tempspice, use_model=True)
|
||||
|
||||
# let's diff the result with a golden model
|
||||
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),filename)
|
||||
self.isapproxdiff(libname,golden,0.15)
|
||||
# get all of the .lib files generated
|
||||
files = os.listdir(OPTS.openram_temp)
|
||||
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()
|
||||
|
||||
# instantiate a copdsay of the class to actually run the test
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Check the .lib file for an SRAM with pruning
|
|||
|
||||
import unittest
|
||||
from testutils import header,openram_test
|
||||
import sys,os
|
||||
import sys,os,re
|
||||
sys.path.append(os.path.join(sys.path[0],".."))
|
||||
import globals
|
||||
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")
|
||||
s = sram.sram(word_size=2,
|
||||
num_words=OPTS.num_words,
|
||||
num_banks=OPTS.num_banks,
|
||||
num_words=16,
|
||||
num_banks=1,
|
||||
name="sram_2_16_1_{0}".format(OPTS.tech_name))
|
||||
OPTS.check_lvsdrc = True
|
||||
|
||||
tempspice = OPTS.openram_temp + "temp.sp"
|
||||
s.sp_write(tempspice)
|
||||
|
||||
filename = s.name + "_pruned.lib"
|
||||
libname = OPTS.openram_temp + filename
|
||||
lib.lib(libname=libname,sram=s,spfile=tempspice,use_model=False)
|
||||
|
||||
# let's diff the result with a golden model
|
||||
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),filename)
|
||||
self.isapproxdiff(libname,golden,0.30)
|
||||
lib.lib(out_dir=OPTS.openram_temp, sram=s, sp_file=tempspice, use_model=False)
|
||||
|
||||
# get all of the .lib files generated
|
||||
files = os.listdir(OPTS.openram_temp)
|
||||
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","_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
|
||||
reload(characterizer)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Check the .lib file for an SRAM
|
|||
|
||||
import unittest
|
||||
from testutils import header,openram_test
|
||||
import sys,os
|
||||
import sys,os,re
|
||||
sys.path.append(os.path.join(sys.path[0],".."))
|
||||
import globals
|
||||
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")
|
||||
s = sram.sram(word_size=2,
|
||||
num_words=OPTS.num_words,
|
||||
num_banks=OPTS.num_banks,
|
||||
num_words=16,
|
||||
num_banks=1,
|
||||
name="sram_2_16_1_{0}".format(OPTS.tech_name))
|
||||
OPTS.check_lvsdrc = True
|
||||
|
||||
tempspice = OPTS.openram_temp + "temp.sp"
|
||||
s.sp_write(tempspice)
|
||||
|
||||
filename = s.name + ".lib"
|
||||
libname = OPTS.openram_temp + filename
|
||||
lib.lib(libname=libname,sram=s,spfile=tempspice,use_model=False)
|
||||
|
||||
# let's diff the result with a golden model
|
||||
golden = "{0}/golden/{1}".format(os.path.dirname(os.path.realpath(__file__)),filename)
|
||||
self.isapproxdiff(libname,golden,0.15)
|
||||
lib.lib(out_dir=OPTS.openram_temp, sram=s, sp_file=tempspice, use_model=False)
|
||||
|
||||
# get all of the .lib files generated
|
||||
files = os.listdir(OPTS.openram_temp)
|
||||
nametest = re.compile("\.lib$", re.IGNORECASE)
|
||||
lib_files = filter(nametest.search, files)
|
||||
|
||||
# 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.trim_netlist = True
|
||||
|
|
|
|||
|
|
@ -52,11 +52,16 @@ class openram_test(openram_test):
|
|||
os.system(cmd)
|
||||
|
||||
# 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)
|
||||
debug.info(1,"Checking for file: " + filename)
|
||||
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
|
||||
output = open("{0}/output.log".format(out_path),"r").read()
|
||||
self.assertEqual(len(re.findall('ERROR',output)),0)
|
||||
|
|
|
|||
|
|
@ -3,5 +3,8 @@ num_words = 16
|
|||
num_banks = 1
|
||||
|
||||
tech_name = "freepdk45"
|
||||
process_corners = ["TT"]
|
||||
supply_voltages = [1.0]
|
||||
temperatures = [25]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,4 +3,7 @@ num_words = 16
|
|||
num_banks = 1
|
||||
|
||||
tech_name = "scn3me_subm"
|
||||
process_corners = ["TT"]
|
||||
supply_voltages = [5.0]
|
||||
temperatures = [25]
|
||||
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ UNITS
|
|||
END UNITS
|
||||
SITE MacroSite
|
||||
CLASS Core ;
|
||||
SIZE 21695.0 by 42337.5 ;
|
||||
SIZE 24385.0 by 42337.5 ;
|
||||
END MacroSite
|
||||
MACRO sram_2_16_1_freepdk45
|
||||
CLASS BLOCK ;
|
||||
SIZE 21695.0 BY 42337.5 ;
|
||||
SIZE 24385.0 BY 42337.5 ;
|
||||
SYMMETRY X Y R90 ;
|
||||
SITE MacroSite ;
|
||||
PIN DATA[0]
|
||||
|
|
@ -4165,12 +4165,15 @@ MACRO sram_2_16_1_freepdk45
|
|||
RECT 750.0 30905.0 685.0 30970.0 ;
|
||||
RECT 32.5 30615.0 -32.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 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 935.0 31862.5 230.0 31927.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 2005.0 33435.0 1940.0 34135.0 ;
|
||||
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 33307.5 2465.0 33372.5 ;
|
||||
RECT 1312.5 39272.5 1377.5 39337.5 ;
|
||||
RECT 4002.5 39272.5 4067.5 39337.5 ;
|
||||
RECT 1312.5 39175.0 1377.5 39305.0 ;
|
||||
RECT 1345.0 39272.5 4035.0 39337.5 ;
|
||||
RECT 4002.5 39175.0 4067.5 39305.0 ;
|
||||
RECT 1312.5 38152.5 1377.5 38217.5 ;
|
||||
RECT 4002.5 38152.5 4067.5 38217.5 ;
|
||||
RECT 1312.5 38055.0 1377.5 38185.0 ;
|
||||
RECT 1345.0 38152.5 4035.0 38217.5 ;
|
||||
RECT 4002.5 38055.0 4067.5 38185.0 ;
|
||||
RECT 2875.0 34562.5 2690.0 34627.5 ;
|
||||
RECT 4035.0 34562.5 3850.0 34627.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 4067.5 37495.0 4002.5 38055.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 1345.0 37067.5 1530.0 37002.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 1905.0 34505.0 2040.0 34570.0 ;
|
||||
RECT 3340.0 34425.0 3475.0 34490.0 ;
|
||||
RECT 3340.0 36665.0 3475.0 36730.0 ;
|
||||
RECT 3340.0 38905.0 3475.0 38970.0 ;
|
||||
RECT 1905.0 36580.0 2040.0 36645.0 ;
|
||||
RECT 3340.0 36105.0 3475.0 36170.0 ;
|
||||
RECT 3340.0 37785.0 3475.0 37850.0 ;
|
||||
RECT 1905.0 36020.0 2040.0 36085.0 ;
|
||||
RECT 3340.0 34260.0 3475.0 34325.0 ;
|
||||
RECT 1940.0 34135.0 2005.0 34340.0 ;
|
||||
RECT 2657.5 34135.0 2722.5 39175.0 ;
|
||||
RECT 1312.5 34135.0 1377.5 39175.0 ;
|
||||
RECT 4002.5 34135.0 4067.5 39175.0 ;
|
||||
RECT 2657.5 34135.0 2722.5 38055.0 ;
|
||||
RECT 1312.5 34135.0 1377.5 38055.0 ;
|
||||
RECT 4002.5 34135.0 4067.5 38055.0 ;
|
||||
RECT 935.0 33800.0 225.0 32455.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 37835.0 ;
|
||||
RECT 935.0 39180.0 230.0 37835.0 ;
|
||||
RECT 1025.0 33907.5 140.0 33972.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 37802.5 140.0 37867.5 ;
|
||||
RECT 1025.0 33767.5 140.0 33832.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 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 1377.5 31760.0 1312.5 31895.0 ;
|
||||
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 3475.0 31335.0 3410.0 34260.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 1377.5 31335.0 1312.5 31895.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 2315.0 25737.5 2245.0 25602.5 ;
|
||||
RECT 2315.0 26387.5 2245.0 26252.5 ;
|
||||
RECT 1380.0 31895.0 1310.0 36955.0 ;
|
||||
RECT 970.0 31895.0 900.0 36645.0 ;
|
||||
RECT 265.0 31895.0 195.0 36645.0 ;
|
||||
RECT 1380.0 31895.0 1310.0 39645.0 ;
|
||||
RECT 970.0 31895.0 900.0 39335.0 ;
|
||||
RECT 265.0 31895.0 195.0 39335.0 ;
|
||||
RECT 1207.5 32062.5 1137.5 32660.0 ;
|
||||
RECT 785.0 32062.5 715.0 32342.5 ;
|
||||
RECT 3372.5 34457.5 3442.5 34852.5 ;
|
||||
RECT 3372.5 34852.5 3442.5 35412.5 ;
|
||||
RECT 3372.5 35412.5 3442.5 35972.5 ;
|
||||
RECT 3372.5 35972.5 3442.5 36532.5 ;
|
||||
RECT 3372.5 36697.5 3442.5 37092.5 ;
|
||||
RECT 3372.5 36137.5 3442.5 36532.5 ;
|
||||
RECT 3372.5 36532.5 3442.5 37092.5 ;
|
||||
RECT 3372.5 37092.5 3442.5 37652.5 ;
|
||||
RECT 3372.5 37652.5 3442.5 38212.5 ;
|
||||
RECT 3372.5 38212.5 3442.5 38772.5 ;
|
||||
RECT 2655.0 38902.5 2725.0 38972.5 ;
|
||||
RECT 2655.0 38422.5 2725.0 38492.5 ;
|
||||
RECT 2690.0 38902.5 3407.5 38972.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 2655.0 37782.5 2725.0 37852.5 ;
|
||||
RECT 2655.0 37302.5 2725.0 37372.5 ;
|
||||
RECT 2690.0 37782.5 3407.5 37852.5 ;
|
||||
RECT 2655.0 37337.5 2725.0 37817.5 ;
|
||||
RECT 1972.5 37302.5 2690.0 37372.5 ;
|
||||
RECT 1937.5 36777.5 2007.5 37337.5 ;
|
||||
RECT 1937.5 36217.5 2007.5 36612.5 ;
|
||||
RECT 1937.5 35657.5 2007.5 36217.5 ;
|
||||
RECT 1937.5 36217.5 2007.5 36777.5 ;
|
||||
RECT 1937.5 35657.5 2007.5 36052.5 ;
|
||||
RECT 1937.5 35097.5 2007.5 35657.5 ;
|
||||
RECT 1937.5 34537.5 2007.5 35097.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 37057.5 3475.0 37127.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 36742.5 2040.0 36812.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 34502.5 2040.0 34572.5 ;
|
||||
RECT 3340.0 34422.5 3475.0 34492.5 ;
|
||||
RECT 3340.0 36662.5 3475.0 36732.5 ;
|
||||
RECT 3340.0 38902.5 3475.0 38972.5 ;
|
||||
RECT 1905.0 36577.5 2040.0 36647.5 ;
|
||||
RECT 3340.0 36102.5 3475.0 36172.5 ;
|
||||
RECT 3340.0 37782.5 3475.0 37852.5 ;
|
||||
RECT 1905.0 36017.5 2040.0 36087.5 ;
|
||||
RECT 935.0 33800.0 225.0 32455.0 ;
|
||||
RECT 935.0 33800.0 230.0 35145.0 ;
|
||||
RECT 935.0 36490.0 230.0 35145.0 ;
|
||||
RECT 785.0 33700.0 715.0 36645.0 ;
|
||||
RECT 450.0 33700.0 380.0 36645.0 ;
|
||||
RECT 970.0 33700.0 900.0 36645.0 ;
|
||||
RECT 265.0 33700.0 195.0 36645.0 ;
|
||||
RECT 935.0 36490.0 230.0 37835.0 ;
|
||||
RECT 935.0 39180.0 230.0 37835.0 ;
|
||||
RECT 785.0 33700.0 715.0 39335.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 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 1380.0 31760.0 1310.0 31895.0 ;
|
||||
RECT 867.5 31860.0 1002.5 31930.0 ;
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1v" ;
|
||||
|
|
@ -7,9 +7,10 @@ library (sram_2_16_1_freepdk45_lib){
|
|||
capacitive_load_unit(1 ,fF) ;
|
||||
leakage_power_unit : "1mW" ;
|
||||
pulling_resistance_unit :"1kohm" ;
|
||||
operating_conditions(TT){
|
||||
operating_conditions(OC){
|
||||
process : 1.0 ;
|
||||
voltage : 1.0 ;
|
||||
temperature : 25.000 ;
|
||||
temperature : 25;
|
||||
}
|
||||
|
||||
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_upper_threshold_pct_rise : 90.0 ;
|
||||
|
||||
nom_voltage : 1.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 ;
|
||||
|
|
@ -45,7 +49,7 @@ library (sram_2_16_1_freepdk45_lib){
|
|||
index_2("0.00125, 0.005, 0.04");
|
||||
}
|
||||
|
||||
default_operating_conditions : TT;
|
||||
default_operating_conditions : OC;
|
||||
|
||||
|
||||
type (DATA){
|
||||
|
|
@ -74,12 +78,18 @@ cell (sram_2_16_1_freepdk45){
|
|||
dont_use : true;
|
||||
map_only : true;
|
||||
dont_touch : true;
|
||||
area : 918.5120625;
|
||||
area : 1032.3999375;
|
||||
|
||||
leakage_power () {
|
||||
when : "CSb";
|
||||
value : 0.00088149731;
|
||||
}
|
||||
cell_leakage_power : 0;
|
||||
bus(DATA){
|
||||
bus_type : DATA;
|
||||
direction : inout;
|
||||
max_capacitance : 1.6728;
|
||||
min_capacitance : 0.052275;
|
||||
three_state : "!OEb & !clk";
|
||||
memory_write(){
|
||||
address : ADDR;
|
||||
|
|
@ -89,15 +99,6 @@ cell (sram_2_16_1_freepdk45){
|
|||
address : ADDR;
|
||||
}
|
||||
pin(DATA[1:0]){
|
||||
internal_power(){
|
||||
when : "OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("0.04024341");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0.029869287");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
|
|
@ -126,15 +127,6 @@ cell (sram_2_16_1_freepdk45){
|
|||
"-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_sense : non_unate;
|
||||
related_pin : "clk";
|
||||
|
|
@ -145,16 +137,16 @@ cell (sram_2_16_1_freepdk45){
|
|||
"0.061, 0.062, 0.069");
|
||||
}
|
||||
cell_fall(CELL_TABLE) {
|
||||
values("0.442, 0.443, 0.452",\
|
||||
"0.442, 0.443, 0.453",\
|
||||
"0.448, 0.449, 0.458");
|
||||
values("0.429, 0.43, 0.439",\
|
||||
"0.429, 0.431, 0.439",\
|
||||
"0.435, 0.436, 0.446");
|
||||
}
|
||||
rise_transition(CELL_TABLE) {
|
||||
rise_transition(CELL_TABLE) {
|
||||
values("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",\
|
||||
"0.029, 0.031, 0.044",\
|
||||
"0.029, 0.031, 0.044");
|
||||
|
|
@ -168,7 +160,6 @@ cell (sram_2_16_1_freepdk45){
|
|||
direction : input;
|
||||
capacitance : 0.2091;
|
||||
max_transition : 0.04;
|
||||
fanout_load : 1.000000;
|
||||
pin(ADDR[3:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
|
|
@ -304,24 +295,51 @@ cell (sram_2_16_1_freepdk45){
|
|||
clock : true;
|
||||
direction : input;
|
||||
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_type :"min_pulse_width";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("0.449");
|
||||
values("0.4295");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0.449");
|
||||
values("0.4295");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"minimum_period";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("0.898");
|
||||
values("0.859");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0.898");
|
||||
values("0.859");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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";
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1v" ;
|
||||
|
|
@ -7,9 +7,10 @@ library (sram_2_16_1_freepdk45_lib){
|
|||
capacitive_load_unit(1 ,fF) ;
|
||||
leakage_power_unit : "1mW" ;
|
||||
pulling_resistance_unit :"1kohm" ;
|
||||
operating_conditions(TT){
|
||||
operating_conditions(OC){
|
||||
process : 1.0 ;
|
||||
voltage : 1.0 ;
|
||||
temperature : 25.000 ;
|
||||
temperature : 25;
|
||||
}
|
||||
|
||||
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_upper_threshold_pct_rise : 90.0 ;
|
||||
|
||||
nom_voltage : 1.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 ;
|
||||
|
|
@ -45,7 +49,7 @@ library (sram_2_16_1_freepdk45_lib){
|
|||
index_2("0.00125, 0.005, 0.04");
|
||||
}
|
||||
|
||||
default_operating_conditions : TT;
|
||||
default_operating_conditions : OC;
|
||||
|
||||
|
||||
type (DATA){
|
||||
|
|
@ -74,12 +78,18 @@ cell (sram_2_16_1_freepdk45){
|
|||
dont_use : true;
|
||||
map_only : true;
|
||||
dont_touch : true;
|
||||
area : 918.5120625;
|
||||
area : 1032.3999375;
|
||||
|
||||
leakage_power () {
|
||||
when : "CSb";
|
||||
value : 0;
|
||||
}
|
||||
cell_leakage_power : 0;
|
||||
bus(DATA){
|
||||
bus_type : DATA;
|
||||
direction : inout;
|
||||
max_capacitance : 1.6728;
|
||||
min_capacitance : 0.052275;
|
||||
three_state : "!OEb & !clk";
|
||||
memory_write(){
|
||||
address : ADDR;
|
||||
|
|
@ -89,15 +99,6 @@ cell (sram_2_16_1_freepdk45){
|
|||
address : ADDR;
|
||||
}
|
||||
pin(DATA[1:0]){
|
||||
internal_power(){
|
||||
when : "OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
|
|
@ -126,15 +127,6 @@ cell (sram_2_16_1_freepdk45){
|
|||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
internal_power(){
|
||||
when : "!OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_sense : non_unate;
|
||||
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");
|
||||
}
|
||||
rise_transition(CELL_TABLE) {
|
||||
rise_transition(CELL_TABLE) {
|
||||
values("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",\
|
||||
"0.006, 0.007, 0.018",\
|
||||
"0.006, 0.007, 0.018");
|
||||
|
|
@ -168,7 +160,6 @@ cell (sram_2_16_1_freepdk45){
|
|||
direction : input;
|
||||
capacitance : 0.2091;
|
||||
max_transition : 0.04;
|
||||
fanout_load : 1.000000;
|
||||
pin(ADDR[3:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
|
|
@ -304,6 +295,33 @@ cell (sram_2_16_1_freepdk45){
|
|||
clock : true;
|
||||
direction : input;
|
||||
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_type :"min_pulse_width";
|
||||
related_pin : clk;
|
||||
|
|
@ -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";
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1v" ;
|
||||
|
|
@ -7,9 +7,10 @@ library (sram_2_16_1_freepdk45_lib){
|
|||
capacitive_load_unit(1 ,fF) ;
|
||||
leakage_power_unit : "1mW" ;
|
||||
pulling_resistance_unit :"1kohm" ;
|
||||
operating_conditions(TT){
|
||||
operating_conditions(OC){
|
||||
process : 1.0 ;
|
||||
voltage : 1.0 ;
|
||||
temperature : 25.000 ;
|
||||
temperature : 25;
|
||||
}
|
||||
|
||||
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_upper_threshold_pct_rise : 90.0 ;
|
||||
|
||||
nom_voltage : 1.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 ;
|
||||
|
|
@ -45,7 +49,7 @@ library (sram_2_16_1_freepdk45_lib){
|
|||
index_2("0.00125, 0.005, 0.04");
|
||||
}
|
||||
|
||||
default_operating_conditions : TT;
|
||||
default_operating_conditions : OC;
|
||||
|
||||
|
||||
type (DATA){
|
||||
|
|
@ -74,12 +78,18 @@ cell (sram_2_16_1_freepdk45){
|
|||
dont_use : true;
|
||||
map_only : true;
|
||||
dont_touch : true;
|
||||
area : 918.5120625;
|
||||
area : 1032.3999375;
|
||||
|
||||
leakage_power () {
|
||||
when : "CSb";
|
||||
value : 0.00088149731;
|
||||
}
|
||||
cell_leakage_power : 0;
|
||||
bus(DATA){
|
||||
bus_type : DATA;
|
||||
direction : inout;
|
||||
max_capacitance : 1.6728;
|
||||
min_capacitance : 0.052275;
|
||||
three_state : "!OEb & !clk";
|
||||
memory_write(){
|
||||
address : ADDR;
|
||||
|
|
@ -89,15 +99,6 @@ cell (sram_2_16_1_freepdk45){
|
|||
address : ADDR;
|
||||
}
|
||||
pin(DATA[1:0]){
|
||||
internal_power(){
|
||||
when : "OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("0.0370166");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0.026622831");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
|
|
@ -126,15 +127,6 @@ cell (sram_2_16_1_freepdk45){
|
|||
"-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_sense : non_unate;
|
||||
related_pin : "clk";
|
||||
|
|
@ -145,16 +137,16 @@ cell (sram_2_16_1_freepdk45){
|
|||
"0.06, 0.061, 0.067");
|
||||
}
|
||||
cell_fall(CELL_TABLE) {
|
||||
values("0.438, 0.439, 0.449",\
|
||||
"0.439, 0.44, 0.449",\
|
||||
"0.445, 0.446, 0.455");
|
||||
values("0.425, 0.426, 0.436",\
|
||||
"0.426, 0.427, 0.436",\
|
||||
"0.432, 0.433, 0.442");
|
||||
}
|
||||
rise_transition(CELL_TABLE) {
|
||||
rise_transition(CELL_TABLE) {
|
||||
values("0.013, 0.014, 0.026",\
|
||||
"0.013, 0.014, 0.026",\
|
||||
"0.013, 0.015, 0.026");
|
||||
}
|
||||
fall_transition(CELL_TABLE) {
|
||||
}
|
||||
fall_transition(CELL_TABLE) {
|
||||
values("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;
|
||||
capacitance : 0.2091;
|
||||
max_transition : 0.04;
|
||||
fanout_load : 1.000000;
|
||||
pin(ADDR[3:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
|
|
@ -304,24 +295,51 @@ cell (sram_2_16_1_freepdk45){
|
|||
clock : true;
|
||||
direction : input;
|
||||
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_type :"min_pulse_width";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("0.449");
|
||||
values("0.4295");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0.449");
|
||||
values("0.4295");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type :"minimum_period";
|
||||
related_pin : clk;
|
||||
rise_constraint(scalar) {
|
||||
values("0.898");
|
||||
values("0.859");
|
||||
}
|
||||
fall_constraint(scalar) {
|
||||
values("0.898");
|
||||
values("0.859");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,11 +7,11 @@ UNITS
|
|||
END UNITS
|
||||
SITE MacroSite
|
||||
CLASS Core ;
|
||||
SIZE 277800.0 by 440700.0 ;
|
||||
SIZE 305400.0 by 440700.0 ;
|
||||
END MacroSite
|
||||
MACRO sram_2_16_1_scn3me_subm
|
||||
CLASS BLOCK ;
|
||||
SIZE 277800.0 BY 440700.0 ;
|
||||
SIZE 305400.0 BY 440700.0 ;
|
||||
SYMMETRY X Y R90 ;
|
||||
SITE MacroSite ;
|
||||
PIN DATA[0]
|
||||
|
|
@ -4105,12 +4105,15 @@ MACRO sram_2_16_1_scn3me_subm
|
|||
RECT 16050.0 358350.0 15150.0 359250.0 ;
|
||||
RECT 8850.0 353400.0 7950.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 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 16800.0 371550.0 6600.0 372450.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 29250.0 397800.0 28350.0 410400.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 396000.0 33750.0 397200.0 ;
|
||||
RECT 21750.0 498150.0 22650.0 499050.0 ;
|
||||
RECT 49350.0 498150.0 50250.0 499050.0 ;
|
||||
RECT 21750.0 496800.0 22650.0 498600.0 ;
|
||||
RECT 22200.0 498150.0 49800.0 499050.0 ;
|
||||
RECT 49350.0 496800.0 50250.0 498600.0 ;
|
||||
RECT 21750.0 478950.0 22650.0 479850.0 ;
|
||||
RECT 49350.0 478950.0 50250.0 479850.0 ;
|
||||
RECT 21750.0 477600.0 22650.0 479400.0 ;
|
||||
RECT 22200.0 478950.0 49800.0 479850.0 ;
|
||||
RECT 49350.0 477600.0 50250.0 479400.0 ;
|
||||
RECT 37950.0 417000.0 36000.0 418200.0 ;
|
||||
RECT 49800.0 417000.0 47850.0 418200.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 50250.0 468000.0 49350.0 477600.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 22200.0 461400.0 24150.0 460200.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 28200.0 416400.0 29400.0 417600.0 ;
|
||||
RECT 42600.0 415200.0 43800.0 416400.0 ;
|
||||
RECT 42600.0 453600.0 43800.0 454800.0 ;
|
||||
RECT 42600.0 492000.0 43800.0 493200.0 ;
|
||||
RECT 28200.0 452400.0 29400.0 453600.0 ;
|
||||
RECT 42600.0 444000.0 43800.0 445200.0 ;
|
||||
RECT 42600.0 472800.0 43800.0 474000.0 ;
|
||||
RECT 28200.0 442800.0 29400.0 444000.0 ;
|
||||
RECT 42600.0 412800.0 43800.0 414000.0 ;
|
||||
RECT 28350.0 410400.0 29250.0 414150.0 ;
|
||||
RECT 35550.0 410400.0 36450.0 496800.0 ;
|
||||
RECT 21750.0 410400.0 22650.0 496800.0 ;
|
||||
RECT 49350.0 410400.0 50250.0 496800.0 ;
|
||||
RECT 35550.0 410400.0 36450.0 477600.0 ;
|
||||
RECT 21750.0 410400.0 22650.0 477600.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 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 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 436200.0 6000.0 437100.0 ;
|
||||
RECT 22350.0 396900.0 21150.0 398100.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 22800.0 370800.0 21600.0 372000.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 43800.0 362400.0 42900.0 412800.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 22650.0 362400.0 21750.0 372000.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 31200.0 263100.0 30000.0 261900.0 ;
|
||||
RECT 31200.0 288450.0 30000.0 287250.0 ;
|
||||
RECT 22650.0 372000.0 21750.0 430200.0 ;
|
||||
RECT 17250.0 372000.0 16350.0 425400.0 ;
|
||||
RECT 7050.0 372000.0 6150.0 425400.0 ;
|
||||
RECT 22650.0 372000.0 21750.0 457800.0 ;
|
||||
RECT 17250.0 372000.0 16350.0 453000.0 ;
|
||||
RECT 7050.0 372000.0 6150.0 453000.0 ;
|
||||
RECT 20400.0 376200.0 19500.0 384300.0 ;
|
||||
RECT 13650.0 376200.0 12750.0 381000.0 ;
|
||||
RECT 42750.0 415800.0 43650.0 423000.0 ;
|
||||
RECT 42750.0 423000.0 43650.0 432600.0 ;
|
||||
RECT 42750.0 432600.0 43650.0 442200.0 ;
|
||||
RECT 42750.0 442200.0 43650.0 451800.0 ;
|
||||
RECT 42750.0 454200.0 43650.0 461400.0 ;
|
||||
RECT 42750.0 444600.0 43650.0 451800.0 ;
|
||||
RECT 42750.0 451800.0 43650.0 461400.0 ;
|
||||
RECT 42750.0 461400.0 43650.0 471000.0 ;
|
||||
RECT 42750.0 471000.0 43650.0 480600.0 ;
|
||||
RECT 42750.0 480600.0 43650.0 490200.0 ;
|
||||
RECT 35550.0 492150.0 36450.0 493050.0 ;
|
||||
RECT 35550.0 483750.0 36450.0 484650.0 ;
|
||||
RECT 36000.0 492150.0 43200.0 493050.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 35550.0 472950.0 36450.0 473850.0 ;
|
||||
RECT 35550.0 464550.0 36450.0 465450.0 ;
|
||||
RECT 36000.0 472950.0 43200.0 473850.0 ;
|
||||
RECT 35550.0 465000.0 36450.0 473400.0 ;
|
||||
RECT 28800.0 464550.0 36000.0 465450.0 ;
|
||||
RECT 28350.0 455400.0 29250.0 465000.0 ;
|
||||
RECT 28350.0 445800.0 29250.0 453000.0 ;
|
||||
RECT 28350.0 436200.0 29250.0 445800.0 ;
|
||||
RECT 28350.0 445800.0 29250.0 455400.0 ;
|
||||
RECT 28350.0 436200.0 29250.0 443400.0 ;
|
||||
RECT 28350.0 426600.0 29250.0 436200.0 ;
|
||||
RECT 28350.0 417000.0 29250.0 426600.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 460800.0 43800.0 462000.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 454800.0 29400.0 456000.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 416400.0 29400.0 417600.0 ;
|
||||
RECT 42600.0 415200.0 43800.0 416400.0 ;
|
||||
RECT 42600.0 453600.0 43800.0 454800.0 ;
|
||||
RECT 42600.0 492000.0 43800.0 493200.0 ;
|
||||
RECT 28200.0 452400.0 29400.0 453600.0 ;
|
||||
RECT 42600.0 444000.0 43800.0 445200.0 ;
|
||||
RECT 42600.0 472800.0 43800.0 474000.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 409200.0 ;
|
||||
RECT 16800.0 423000.0 6600.0 409200.0 ;
|
||||
RECT 13800.0 396000.0 12600.0 426600.0 ;
|
||||
RECT 10800.0 394800.0 9600.0 425400.0 ;
|
||||
RECT 17400.0 394800.0 16200.0 425400.0 ;
|
||||
RECT 7200.0 394800.0 6000.0 425400.0 ;
|
||||
RECT 16800.0 423000.0 6600.0 436800.0 ;
|
||||
RECT 16800.0 450600.0 6600.0 436800.0 ;
|
||||
RECT 13800.0 396000.0 12600.0 454200.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 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 22800.0 370800.0 21600.0 372000.0 ;
|
||||
RECT 16200.0 371400.0 17400.0 372600.0 ;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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";
|
||||
time_unit : "1ns" ;
|
||||
voltage_unit : "1v" ;
|
||||
|
|
@ -7,9 +7,10 @@ library (sram_2_16_1_scn3me_subm_lib){
|
|||
capacitive_load_unit(1 ,fF) ;
|
||||
leakage_power_unit : "1mW" ;
|
||||
pulling_resistance_unit :"1kohm" ;
|
||||
operating_conditions(TT){
|
||||
operating_conditions(OC){
|
||||
process : 1.0 ;
|
||||
voltage : 5.0 ;
|
||||
temperature : 25.000 ;
|
||||
temperature : 25;
|
||||
}
|
||||
|
||||
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_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 ;
|
||||
|
|
@ -45,7 +49,7 @@ library (sram_2_16_1_scn3me_subm_lib){
|
|||
index_2("0.0125, 0.05, 0.4");
|
||||
}
|
||||
|
||||
default_operating_conditions : TT;
|
||||
default_operating_conditions : OC;
|
||||
|
||||
|
||||
type (DATA){
|
||||
|
|
@ -74,12 +78,18 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
dont_use : true;
|
||||
map_only : true;
|
||||
dont_touch : true;
|
||||
area : 122426.46;
|
||||
area : 134589.78;
|
||||
|
||||
leakage_power () {
|
||||
when : "CSb";
|
||||
value : 0;
|
||||
}
|
||||
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;
|
||||
|
|
@ -89,15 +99,6 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
address : ADDR;
|
||||
}
|
||||
pin(DATA[1:0]){
|
||||
internal_power(){
|
||||
when : "OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
related_pin : "clk";
|
||||
|
|
@ -126,15 +127,6 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
"0.001, 0.001, 0.001");
|
||||
}
|
||||
}
|
||||
internal_power(){
|
||||
when : "!OEb & !clk";
|
||||
rise_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
fall_power(scalar){
|
||||
values("0");
|
||||
}
|
||||
}
|
||||
timing(){
|
||||
timing_sense : non_unate;
|
||||
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");
|
||||
}
|
||||
rise_transition(CELL_TABLE) {
|
||||
rise_transition(CELL_TABLE) {
|
||||
values("0.024, 0.081, 0.61",\
|
||||
"0.024, 0.081, 0.61",\
|
||||
"0.024, 0.081, 0.61");
|
||||
}
|
||||
fall_transition(CELL_TABLE) {
|
||||
}
|
||||
fall_transition(CELL_TABLE) {
|
||||
values("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;
|
||||
capacitance : 9.8242;
|
||||
max_transition : 0.4;
|
||||
fanout_load : 1.000000;
|
||||
pin(ADDR[3:0]){
|
||||
timing(){
|
||||
timing_type : setup_rising;
|
||||
|
|
@ -304,6 +295,33 @@ cell (sram_2_16_1_scn3me_subm){
|
|||
clock : true;
|
||||
direction : input;
|
||||
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_type :"min_pulse_width";
|
||||
related_pin : clk;
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ def run_drc(cell_name, gds_name):
|
|||
OPTS.openram_temp,
|
||||
errfile,
|
||||
outfile)
|
||||
debug.info(1, cmd)
|
||||
debug.info(2, cmd)
|
||||
os.system(cmd)
|
||||
os.chdir(cwd)
|
||||
|
||||
|
|
@ -191,7 +191,7 @@ def run_lvs(cell_name, gds_name, sp_name, final_verification=False):
|
|||
OPTS.openram_temp,
|
||||
errfile,
|
||||
outfile)
|
||||
debug.info(1, cmd)
|
||||
debug.info(2, cmd)
|
||||
os.system(cmd)
|
||||
os.chdir(cwd)
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
errfile,
|
||||
outfile)
|
||||
debug.info(1, cmd)
|
||||
debug.info(2, cmd)
|
||||
os.system(cmd)
|
||||
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,
|
||||
errfile,
|
||||
outfile)
|
||||
debug.info(1, cmd)
|
||||
debug.info(2, cmd)
|
||||
os.system(cmd)
|
||||
os.chdir(cwd)
|
||||
|
||||
|
|
|
|||
1475
docs/figs/Array.svg
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
|
@ -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 |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
|
@ -25,13 +25,13 @@
|
|||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="161.5"
|
||||
inkscape:cx="20"
|
||||
inkscape:cy="520"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="752"
|
||||
inkscape:window-width="3440"
|
||||
inkscape:window-height="1392"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1">
|
||||
|
|
@ -185,7 +185,7 @@
|
|||
id="tspan4519"
|
||||
x="184"
|
||||
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
|
||||
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"
|
||||
|
|
@ -196,7 +196,7 @@
|
|||
id="tspan4523"
|
||||
x="336"
|
||||
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
|
||||
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"
|
||||
|
|
@ -207,7 +207,7 @@
|
|||
id="tspan4527"
|
||||
x="287"
|
||||
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
|
||||
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"
|
||||
|
|
@ -263,7 +263,7 @@
|
|||
id="tspan4793"
|
||||
x="271"
|
||||
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
|
||||
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"
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
|
@ -13,8 +13,8 @@
|
|||
height="1052.3622047"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.3.1 r9886"
|
||||
sodipodi:docname="sense_amp.svg">
|
||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
|
||||
sodipodi:docname="sense_amp_schem.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
|
|
@ -24,16 +24,16 @@
|
|||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="199"
|
||||
inkscape:cy="520"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="78.947962"
|
||||
inkscape:cy="503.38478"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1855"
|
||||
inkscape:window-height="1056"
|
||||
inkscape:window-x="65"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-width="3440"
|
||||
inkscape:window-height="1392"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
|
|
@ -47,7 +47,7 @@
|
|||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
|
|
@ -55,37 +55,6 @@
|
|||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
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
|
||||
id="g3496-2"
|
||||
transform="matrix(0,-1,1,0,-62.34811,791.36093)">
|
||||
|
|
@ -148,37 +117,6 @@
|
|||
inkscape:connector-curvature="0" />
|
||||
</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
|
||||
id="g3496-8"
|
||||
transform="matrix(0,-1,1,0,-2.34811,920.37376)">
|
||||
|
|
@ -357,18 +295,18 @@
|
|||
id="path4592"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 610,452.36218 30,0 0,-120 0,230"
|
||||
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 604,452.36218 h 30 v -120 230"
|
||||
id="path4594"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
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 190,432.36218 0,-20 0,-10"
|
||||
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 184,416.36218 v -20 -10"
|
||||
id="path4598"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
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 550,432.36218 0,-30"
|
||||
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 544,416.36218 v -30"
|
||||
id="path4600"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
|
|
@ -406,11 +344,11 @@
|
|||
</g>
|
||||
<g
|
||||
id="g3319-3"
|
||||
transform="matrix(1.25,0,0,1,129,112.20718)">
|
||||
transform="matrix(1.25,0,0,1,125,112.20718)">
|
||||
<path
|
||||
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"
|
||||
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" />
|
||||
</g>
|
||||
<g
|
||||
|
|
@ -466,85 +404,165 @@
|
|||
</g>
|
||||
<text
|
||||
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"
|
||||
y="172.36218"
|
||||
id="text4691"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
id="text4691"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4693"
|
||||
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
|
||||
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"
|
||||
y="297.36218"
|
||||
id="text4695"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
id="text4695"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4697"
|
||||
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
|
||||
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"
|
||||
x="615"
|
||||
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="621"
|
||||
y="577.36218"
|
||||
id="text4699"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
id="text4699"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4701"
|
||||
x="615"
|
||||
y="577.36218">BL_bar</tspan></text>
|
||||
x="621"
|
||||
y="577.36218"
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">br</tspan></text>
|
||||
<text
|
||||
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"
|
||||
y="580.36218"
|
||||
id="text4703"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
id="text4703"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4705"
|
||||
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
|
||||
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"
|
||||
y="588.36218"
|
||||
id="text4707"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
id="text4707"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4709"
|
||||
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
|
||||
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"
|
||||
x="540"
|
||||
y="398.36218"
|
||||
id="text4711"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
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="538"
|
||||
y="382.36218"
|
||||
id="text4711"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4713"
|
||||
x="540"
|
||||
y="398.36218">EN</tspan></text>
|
||||
x="538"
|
||||
y="382.36218"
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">en</tspan></text>
|
||||
<text
|
||||
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"
|
||||
x="180"
|
||||
y="399.36218"
|
||||
id="text4715"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
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="177.87868"
|
||||
y="376.02765"
|
||||
id="text4715"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4717"
|
||||
x="180"
|
||||
y="399.36218">EN</tspan></text>
|
||||
x="177.87868"
|
||||
y="376.02765"
|
||||
style="font-size:16px;line-height:1.25;font-family:sans-serif">en</tspan></text>
|
||||
<path
|
||||
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"
|
||||
id="path4738"
|
||||
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>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 25 KiB |