Merge branch 'master' into router

This commit is contained in:
mguthaus 2017-04-24 12:17:21 -07:00
commit 8a185ffc1a
5 changed files with 65 additions and 52 deletions

48
README
View File

@ -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.

View File

@ -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",

View File

@ -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):

View File

@ -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")

View File

@ -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