mirror of https://github.com/VLSIDA/OpenRAM.git
Merge branch 'master' into router
This commit is contained in:
commit
8a185ffc1a
48
README
48
README
|
|
@ -3,7 +3,7 @@ BASIC SETUP
|
|||
|
||||
-The OpenRAM compiler has very few dependencies:
|
||||
|
||||
1) ngspice-25 or later or HSpice I-2013.12-1 or later
|
||||
1) ngspice-26 or later or HSpice I-2013.12-1 or later
|
||||
2) Python 2.7 and higher (currently excludes Python 3 and up)
|
||||
3) a setup script for each technology
|
||||
4) a technology directory for each technology with the base cells
|
||||
|
|
@ -13,11 +13,16 @@ the compiler source directory. OPENERAM_TECH should point to a root
|
|||
technology directory that contains subdirs of all other technologies.
|
||||
For example:
|
||||
|
||||
export OPENRAM_HOME="/Users/mrg/openram/compiler"
|
||||
export OPENRAM_TECH="/Users/mrg/openram/technology"
|
||||
export OPENRAM_HOME="$HOME/OpenRAM/compiler"
|
||||
export OPENRAM_TECH="$HOME/OpenRAM/technology"
|
||||
|
||||
- If you are using FreePDK, you should also have that set up and have the
|
||||
environment variable point to the PDK:
|
||||
|
||||
export FREEPDK45="/bsoe/software/design-kits/FreePDK45"
|
||||
|
||||
-All setup scripts should be in the setup_scripts directory under the
|
||||
technology directory. Please look at the following file for an
|
||||
$OPENRAM_TECH directory. Please look at the following file for an
|
||||
example of what is needed for OpenRAM:
|
||||
|
||||
$OPENRAM_TECH/setup_scripts/setup_openram_freepdk45.py
|
||||
|
|
@ -60,27 +65,11 @@ compiler - openram compiler itself (pointed to by OPENRAM_HOME)
|
|||
compiler/characterizer - timing characterization code
|
||||
compiler/gdsMill - gds reader/writer
|
||||
compiler/tests - unit tests
|
||||
technology - openram technology directory (pointed to by OPENRAM_TECH)
|
||||
technology/freepdk45 - example configuration library for freepdk45 technology node
|
||||
technology/scn3me_subm - example configuration library SCMOS technology node
|
||||
technology/setup_scripts - setup scripts to customize your PDKs and OpenRAM technologies
|
||||
|
||||
###############################################################################
|
||||
Example to output/input .gds layout files from/to Cadence
|
||||
|
||||
1) To create your component layouts, you should stream them to
|
||||
individual gds files using our provided layermap and flatten
|
||||
cells. For example,
|
||||
|
||||
strmout -layerMap layers.map -library sram -topCell $i -view layout -flattenVias -flattenPcells -strmFile ../gds_lib/$i.gds
|
||||
|
||||
2) To stream a layout back into Cadence, do this:
|
||||
|
||||
strmin -layerMap layers.map -attachTechFileOfLib NCSU_TechLib_FreePDK45 -library sram_4_32 -strmFile sram_4_32.gds
|
||||
|
||||
When you import a gds file, make sure to attach the correct tech lib
|
||||
or you will get incorrect layers in the resulting library.
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
UNIT TESTS
|
||||
|
|
@ -112,3 +101,20 @@ This updates a git repository, checks out code, and sends an email
|
|||
report with status information.
|
||||
|
||||
|
||||
|
||||
###############################################################################
|
||||
Example to output/input .gds layout files from/to Cadence
|
||||
|
||||
1) To create your component layouts, you should stream them to
|
||||
individual gds files using our provided layermap and flatten
|
||||
cells. For example,
|
||||
|
||||
strmout -layerMap layers.map -library sram -topCell $i -view layout -flattenVias -flattenPcells -strmFile ../gds_lib/$i.gds
|
||||
|
||||
2) To stream a layout back into Cadence, do this:
|
||||
|
||||
strmin -layerMap layers.map -attachTechFileOfLib NCSU_TechLib_FreePDK45 -library sram_4_32 -strmFile sram_4_32.gds
|
||||
|
||||
When you import a gds file, make sure to attach the correct tech lib
|
||||
or you will get incorrect layers in the resulting library.
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ A calibre DRC runset file contains, at the minimum, the following information:
|
|||
*drcLayoutPrimary: cell_6t
|
||||
*drcLayoutSystem: GDSII
|
||||
*drcResultsformat: ASCII
|
||||
*drcResultsFile: cell_6t.drc.results
|
||||
*drcResultsFile: cell_6t.drc.db
|
||||
*drcSummaryFile: cell_6t.drc.summary
|
||||
*cmnFDILayerMapFile: ./layer.map
|
||||
*cmnFDIUseLayerMap: 1
|
||||
|
|
@ -26,7 +26,12 @@ calibre -gui -drc example_drc_runset -batch
|
|||
|
||||
To open the results, you can do this:
|
||||
|
||||
calibre -rve cell_6t.drc.results
|
||||
calibredrv cell_6t.gds
|
||||
Select Verification->Start RVE.
|
||||
Select the cell_6t.drc.db file.
|
||||
Click on the errors and they will highlight in the design layout viewer.
|
||||
|
||||
For LVS:
|
||||
|
||||
*lvsRulesFile: /mada/software/techfiles/FreePDK45/ncsu_basekit/techfile/calibre/calibreLVS.rul
|
||||
*lvsRunDir: .
|
||||
|
|
@ -39,7 +44,7 @@ calibre -rve cell_6t.drc.results
|
|||
*lvsPowerNames: vdd
|
||||
*lvsGroundNames: vss
|
||||
*lvsIgnorePorts: 1
|
||||
*lvsERCDatabase: cell_6t.erc.results
|
||||
*lvsERCDatabase: cell_6t.erc.db
|
||||
*lvsERCSummaryFile: cell_6t.erc.summary
|
||||
*lvsReportFile: cell_6t.lvs.report
|
||||
*lvsMaskDBFile: cell_6t.maskdb
|
||||
|
|
@ -77,7 +82,7 @@ def run_drc(name, gds_name):
|
|||
'drcLayoutPrimary': name,
|
||||
'drcLayoutSystem': 'GDSII',
|
||||
'drcResultsformat': 'ASCII',
|
||||
'drcResultsFile': OPTS.openram_temp + name + ".drc.results",
|
||||
'drcResultsFile': OPTS.openram_temp + name + ".drc.db",
|
||||
'drcSummaryFile': OPTS.openram_temp + name + ".drc.summary",
|
||||
'cmnFDILayerMapFile': drc["layer_map"],
|
||||
'cmnFDIUseLayerMap': 1
|
||||
|
|
@ -148,7 +153,7 @@ def run_lvs(name, gds_name, sp_name):
|
|||
'lvsIncludeSVRFCmds': 1,
|
||||
'lvsSVRFCmds': '{VIRTUAL CONNECT NAME VDD? GND? ?}',
|
||||
'lvsIgnorePorts': 1,
|
||||
'lvsERCDatabase': OPTS.openram_temp + name + ".erc.results",
|
||||
'lvsERCDatabase': OPTS.openram_temp + name + ".erc.db",
|
||||
'lvsERCSummaryFile': OPTS.openram_temp + name + ".erc.summary",
|
||||
'lvsReportFile': OPTS.openram_temp + name + ".lvs.report",
|
||||
'lvsMaskDBFile': OPTS.openram_temp + name + ".maskdb",
|
||||
|
|
|
|||
|
|
@ -385,16 +385,16 @@ class delay():
|
|||
return None
|
||||
debug.info(1, "Min Period for high_to_low transistion: {0}n with a delay of {1}".format(min_period0, delay0))
|
||||
read_power=ch.convert_to_float(ch.parse_output("timing", "power_read"))
|
||||
write_power=ch.convert_to_float(ch.parse_output("timing", "power_write"))
|
||||
write_power=ch.convert_to_float(ch.parse_output("timing", "power_write"))
|
||||
|
||||
data = {"min_period1": min_period1, # period in ns
|
||||
data = {"min_period1": min_period1, # period in ns
|
||||
"delay1": delay1, # delay in s
|
||||
"min_period0": min_period0,
|
||||
"delay0": delay0,
|
||||
"read_power": read_power,
|
||||
"write_power": write_power
|
||||
}
|
||||
return data
|
||||
return data
|
||||
|
||||
|
||||
def obtain_cycle_times(self, slow_period, fast_period):
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ class lib:
|
|||
CONS2 = ["INPUT_BY_TRANS_FOR_CLOCK" , "INPUT_BY_TRANS_FOR_SIGNAL"]
|
||||
for i in CONS2:
|
||||
self.lib.write(" power_lut_template({0})".format(i))
|
||||
self.lib.write("{\n")
|
||||
self.lib.write("{\n")
|
||||
self.lib.write(" variable_1 : input_transition_time;\n")
|
||||
self.lib.write(" index_1 (\"0.5\");\n")
|
||||
self.lib.write(" }\n\n")
|
||||
|
|
@ -216,30 +216,30 @@ class lib:
|
|||
self.lib.write(" address : ADDR; \n")
|
||||
self.lib.write(" clocked_on : clk; \n")
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" internal_power(){\n")
|
||||
self.lib.write(" when : \"OEb & !clk\"; \n")
|
||||
self.lib.write(" rise_power(INPUT_BY_TRANS_FOR_SIGNAL){\n")
|
||||
self.lib.write(" values(\"{0}\");\n".format(data["write_power"]* 1e3))
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" fall_power(INPUT_BY_TRANS_FOR_SIGNAL){\n")
|
||||
self.lib.write(" values(\"{0}\");\n".format(data["write_power"]* 1e3))
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" internal_power(){\n")
|
||||
self.lib.write(" when : \"OEb & !clk\"; \n")
|
||||
self.lib.write(" rise_power(INPUT_BY_TRANS_FOR_SIGNAL){\n")
|
||||
self.lib.write(" values(\"{0}\");\n".format(data["write_power"]* 1e3))
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" fall_power(INPUT_BY_TRANS_FOR_SIGNAL){\n")
|
||||
self.lib.write(" values(\"{0}\");\n".format(data["write_power"]* 1e3))
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" }\n")
|
||||
self.write_timing(times)
|
||||
self.write_timing(times)
|
||||
|
||||
self.lib.write(" memory_read(){ \n")
|
||||
self.lib.write(" address : ADDR; \n")
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" internal_power(){\n")
|
||||
self.lib.write(" when : \"!OEb & !clk\"; \n")
|
||||
self.lib.write(" rise_power(INPUT_BY_TRANS_FOR_SIGNAL){\n")
|
||||
self.lib.write(" values(\"{0}\");\n".format(data["read_power"]* 1e3))
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" fall_power(INPUT_BY_TRANS_FOR_SIGNAL){\n")
|
||||
self.lib.write(" values(\"{0}\");\n".format(data["read_power"]* 1e3))
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" internal_power(){\n")
|
||||
self.lib.write(" when : \"!OEb & !clk\"; \n")
|
||||
self.lib.write(" rise_power(INPUT_BY_TRANS_FOR_SIGNAL){\n")
|
||||
self.lib.write(" values(\"{0}\");\n".format(data["read_power"]* 1e3))
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" fall_power(INPUT_BY_TRANS_FOR_SIGNAL){\n")
|
||||
self.lib.write(" values(\"{0}\");\n".format(data["read_power"]* 1e3))
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" }\n")
|
||||
self.lib.write(" timing(){ \n")
|
||||
self.lib.write(" timing(){ \n")
|
||||
self.lib.write(" timing_sense : non_unate; \n")
|
||||
self.lib.write(" related_pin : \"clk\"; \n")
|
||||
self.lib.write(" timing_type : rising_edge; \n")
|
||||
|
|
@ -295,8 +295,8 @@ class lib:
|
|||
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(data["min_period1"]) + ch.round_time(data["min_period0"]))/2.0
|
||||
min_period = ch.round_time(data["min_period1"]) + ch.round_time(data["min_period0"])
|
||||
min_pulse_width = (ch.round_time(data["min_period1"]) + ch.round_time(data["min_period0"]))/2.0
|
||||
min_period = ch.round_time(data["min_period1"]) + ch.round_time(data["min_period0"])
|
||||
self.lib.write(" timing(){ \n")
|
||||
self.lib.write(" timing_type :\"min_pulse_width\"; \n")
|
||||
self.lib.write(" related_pin : clk; \n")
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class code_format_test(unittest.TestCase):
|
|||
"Run a test to check for tabs instead of spaces in the all source files."
|
||||
|
||||
def runTest(self):
|
||||
source_code_dir = os.environ["OPENRAM_HOME"] + "/compiler"
|
||||
source_code_dir = os.environ["OPENRAM_HOME"]
|
||||
source_codes = setup_files(source_code_dir)
|
||||
errors = 0
|
||||
|
||||
|
|
@ -32,7 +32,9 @@ class code_format_test(unittest.TestCase):
|
|||
continue
|
||||
if re.search("debug.py$", code):
|
||||
continue
|
||||
if re.search("header.py$", code):
|
||||
if re.search("testutils.py$", code):
|
||||
continue
|
||||
if re.search("globals.py$", code):
|
||||
continue
|
||||
if re.search("openram.py$", code):
|
||||
continue
|
||||
|
|
|
|||
Loading…
Reference in New Issue