mirror of https://github.com/VLSIDA/OpenRAM.git
Merge branch 'dev' into elmore_model_tuning
This commit is contained in:
commit
c308dd34a4
|
|
@ -0,0 +1,55 @@
|
||||||
|
name: ci
|
||||||
|
on: [push]
|
||||||
|
jobs:
|
||||||
|
scn4me_subm:
|
||||||
|
runs-on: self-hosted
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
- name: SCMOS test
|
||||||
|
run: |
|
||||||
|
. /home/github-runner/setup-paths.sh
|
||||||
|
export OPENRAM_HOME="`pwd`/compiler"
|
||||||
|
export OPENRAM_TECH="`pwd`/technology:/software/PDKs/skywater-tech"
|
||||||
|
export OPENRAM_TMP="`pwd`/scn4me_subm"
|
||||||
|
python3-coverage run -p $OPENRAM_HOME/tests/regress.py -j 48 -t scn4m_subm
|
||||||
|
- name: Archive
|
||||||
|
if: ${{ failure() }}
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: scn4me_subm Archives
|
||||||
|
path: $OPENRAM_TMP/
|
||||||
|
freepdk45:
|
||||||
|
runs-on: self-hosted
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
- name: FreePDK45 test
|
||||||
|
run: |
|
||||||
|
. /home/github-runner/setup-paths.sh
|
||||||
|
export OPENRAM_HOME="`pwd`/compiler"
|
||||||
|
export OPENRAM_TECH="`pwd`/technology:/software/PDKs/skywater-tech"
|
||||||
|
export OPENRAM_TMP="`pwd`/freepdk45"
|
||||||
|
python3-coverage run -p $OPENRAM_HOME/tests/regress.py -j 48 -t freepdk45
|
||||||
|
- name: Archive
|
||||||
|
if: ${{ failure() }}
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: FreePDK45 Archives
|
||||||
|
path: $OPENRAM_TMP/
|
||||||
|
coverage:
|
||||||
|
if: ${{ always() }}
|
||||||
|
needs: [scn4me_subm, freepdk45]
|
||||||
|
runs-on: self-hosted
|
||||||
|
steps:
|
||||||
|
- name: Coverage stats
|
||||||
|
run: |
|
||||||
|
python3-coverage combine
|
||||||
|
python3-coverage report
|
||||||
|
python3-coverage html -d coverage_html
|
||||||
|
- name: Archive coverage
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: code-coverage-report
|
||||||
|
path: coverage_html/
|
||||||
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
before_script:
|
|
||||||
- . /home/gitlab-runner/setup-paths.sh
|
|
||||||
- export OPENRAM_HOME="`pwd`/compiler"
|
|
||||||
- export OPENRAM_TECH="`pwd`/technology:/home/PDKs/skywater-tech"
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- test
|
|
||||||
- coverage
|
|
||||||
|
|
||||||
freepdk45:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- coverage run -p $OPENRAM_HOME/tests/regress.py -t freepdk45
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- .coverage.*
|
|
||||||
expire_in: 1 week
|
|
||||||
|
|
||||||
scn4m_subm:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- coverage run -p $OPENRAM_HOME/tests/regress.py -t scn4m_subm
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- .coverage.*
|
|
||||||
expire_in: 1 week
|
|
||||||
|
|
||||||
# s8:
|
|
||||||
# stage: test
|
|
||||||
# script:
|
|
||||||
# - coverage run -p $OPENRAM_HOME/tests/regress.py -t s8
|
|
||||||
# artifacts:
|
|
||||||
# paths:
|
|
||||||
# - .coverage.*
|
|
||||||
# expire_in: 1 week
|
|
||||||
|
|
||||||
coverage:
|
|
||||||
stage: coverage
|
|
||||||
script:
|
|
||||||
- coverage combine
|
|
||||||
- coverage report
|
|
||||||
- coverage html -d coverage_html
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- coverage_html
|
|
||||||
expire_in: 1 week
|
|
||||||
coverage: '/TOTAL.+ ([0-9]{1,3}%)/'
|
|
||||||
|
|
||||||
26
README.md
26
README.md
|
|
@ -4,13 +4,9 @@
|
||||||
[](./LICENSE)
|
[](./LICENSE)
|
||||||
|
|
||||||
Master:
|
Master:
|
||||||
[](https://github.com/VLSIDA/OpenRAM/commits/master)
|
|
||||||

|
|
||||||
[](https://github.com/VLSIDA/OpenRAM/archive/master.zip)
|
[](https://github.com/VLSIDA/OpenRAM/archive/master.zip)
|
||||||
|
|
||||||
Dev:
|
Dev:
|
||||||
[](https://github.com/VLSIDA/OpenRAM/commits/dev)
|
|
||||||

|
|
||||||
[](https://github.com/VLSIDA/OpenRAM/archive/dev.zip)
|
[](https://github.com/VLSIDA/OpenRAM/archive/dev.zip)
|
||||||
|
|
||||||
An open-source static random access memory (SRAM) compiler.
|
An open-source static random access memory (SRAM) compiler.
|
||||||
|
|
@ -43,12 +39,12 @@ The OpenRAM compiler has very few dependencies:
|
||||||
|
|
||||||
If you want to perform DRC and LVS, you will need either:
|
If you want to perform DRC and LVS, you will need either:
|
||||||
+ Calibre (for [FreePDK45])
|
+ Calibre (for [FreePDK45])
|
||||||
+ [Magic] 8.3.27 or higher (for [SCMOS])
|
+ [Magic] 8.3.130 or newer
|
||||||
+ [Netgen] 1.5 (for [SCMOS])
|
+ [Netgen] 1.5.164 or newer
|
||||||
|
|
||||||
You must set two environment variables:
|
You must set two environment variables:
|
||||||
+ OPENRAM\_HOME should point to the compiler source directory.
|
+ OPENRAM\_HOME should point to the compiler source directory.
|
||||||
+ OPENERAM\_TECH should point to a root technology directory.
|
+ OPENERAM\_TECH should point to one or more root technology directories (colon separated).
|
||||||
|
|
||||||
## Environment
|
## Environment
|
||||||
|
|
||||||
|
|
@ -65,11 +61,11 @@ You may also wish to add OPENRAM\_HOME to your PYTHONPATH:
|
||||||
export PYTHONPATH="$PYTHONPATH:$OPENRAM_HOME"
|
export PYTHONPATH="$PYTHONPATH:$OPENRAM_HOME"
|
||||||
```
|
```
|
||||||
|
|
||||||
We include the tech files necessary for [SCMOS]
|
We include the tech files necessary for [SCMOS] SCN4M_SUBM. The
|
||||||
SCN4M_SUBM. The [SCMOS] spice models, however, are generic and should
|
[SCMOS] spice models, however, are generic and should be replaced with
|
||||||
be replaced with foundry models. If you are using [FreePDK45], you
|
foundry models. If you are using [FreePDK45], you should also have
|
||||||
should also have that set up and have the environment variable point
|
that set up and have the environment variable point to the PDK. For
|
||||||
to the PDK. For example add this to your .bashrc:
|
example add this to your .bashrc:
|
||||||
|
|
||||||
```
|
```
|
||||||
export FREEPDK45="/bsoe/software/design-kits/FreePDK45"
|
export FREEPDK45="/bsoe/software/design-kits/FreePDK45"
|
||||||
|
|
@ -160,9 +156,9 @@ specific technology (e.g., [FreePDK45]) should be a subdirectory
|
||||||
* dff.gds
|
* dff.gds
|
||||||
* sense_amp.gds
|
* sense_amp.gds
|
||||||
* write_driver.gds
|
* write_driver.gds
|
||||||
* cell_6t.gds
|
* cell_1rw.gds
|
||||||
* replica\_cell\_6t.gds
|
* replica\_cell\_1rw.gds
|
||||||
* dummy\_cell\_6t.gds
|
* dummy\_cell\_1rw.gds
|
||||||
* sp_lib folder with all the .sp (premade) library netlists for the above cells.
|
* sp_lib folder with all the .sp (premade) library netlists for the above cells.
|
||||||
* layers.map
|
* layers.map
|
||||||
* A valid tech Python module (tech directory with \_\_init\_\_.py and tech.py) with:
|
* A valid tech Python module (tech directory with \_\_init\_\_.py and tech.py) with:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
@ -57,6 +57,12 @@ class design(hierarchy_design):
|
||||||
self.cell_name,
|
self.cell_name,
|
||||||
GDS["unit"])
|
GDS["unit"])
|
||||||
|
|
||||||
|
# Convert names back to the original names
|
||||||
|
# so that copying will use the new names
|
||||||
|
for pin_name in self.pin_map:
|
||||||
|
for index1, pin in enumerate(self.pin_map[pin_name]):
|
||||||
|
self.pin_map[pin_name][index1].name = self.get_original_pin_name(pin.name)
|
||||||
|
|
||||||
self.width = width
|
self.width = width
|
||||||
self.height = height
|
self.height = height
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
@ -1235,7 +1235,6 @@ class layout():
|
||||||
self.add_power_pin(new_name, pin.center(), start_layer=start_layer)
|
self.add_power_pin(new_name, pin.center(), start_layer=start_layer)
|
||||||
|
|
||||||
def add_power_pin(self, name, loc, directions=None, start_layer="m1"):
|
def add_power_pin(self, name, loc, directions=None, start_layer="m1"):
|
||||||
|
|
||||||
# Hack for min area
|
# Hack for min area
|
||||||
if OPTS.tech_name == "sky130":
|
if OPTS.tech_name == "sky130":
|
||||||
min_area = drc["minarea_{}".format(self.pwr_grid_layer)]
|
min_area = drc["minarea_{}".format(self.pwr_grid_layer)]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,26 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
import os
|
import os
|
||||||
import debug
|
import debug
|
||||||
import globals
|
from globals import OPTS, find_exe, get_tool
|
||||||
from globals import OPTS,find_exe,get_tool
|
|
||||||
from .lib import *
|
from .lib import *
|
||||||
from .delay import *
|
from .delay import *
|
||||||
|
from .elmore import *
|
||||||
|
from .linear_regression import *
|
||||||
from .setup_hold import *
|
from .setup_hold import *
|
||||||
from .functional import *
|
from .functional import *
|
||||||
from .simulation import *
|
from .simulation import *
|
||||||
from .measurements import *
|
from .measurements import *
|
||||||
from .model_check import *
|
from .model_check import *
|
||||||
|
from .analytical_util import *
|
||||||
|
from .regression_model import *
|
||||||
|
|
||||||
debug.info(1,"Initializing characterizer...")
|
debug.info(1, "Initializing characterizer...")
|
||||||
OPTS.spice_exe = ""
|
OPTS.spice_exe = ""
|
||||||
|
|
||||||
if not OPTS.analytical_delay:
|
if not OPTS.analytical_delay:
|
||||||
|
|
@ -26,17 +29,17 @@ if not OPTS.analytical_delay:
|
||||||
if OPTS.spice_name != "":
|
if OPTS.spice_name != "":
|
||||||
OPTS.spice_exe=find_exe(OPTS.spice_name)
|
OPTS.spice_exe=find_exe(OPTS.spice_name)
|
||||||
if OPTS.spice_exe=="" or OPTS.spice_exe==None:
|
if OPTS.spice_exe=="" or OPTS.spice_exe==None:
|
||||||
debug.error("{0} not found. Unable to perform characterization.".format(OPTS.spice_name),1)
|
debug.error("{0} not found. Unable to perform characterization.".format(OPTS.spice_name), 1)
|
||||||
else:
|
else:
|
||||||
(OPTS.spice_name,OPTS.spice_exe) = get_tool("spice",["hspice", "ngspice", "ngspice.exe", "xa"])
|
(OPTS.spice_name, OPTS.spice_exe) = get_tool("spice", ["ngspice", "ngspice.exe", "hspice", "xa"])
|
||||||
|
|
||||||
# set the input dir for spice files if using ngspice
|
# set the input dir for spice files if using ngspice
|
||||||
if OPTS.spice_name == "ngspice":
|
if OPTS.spice_name == "ngspice":
|
||||||
os.environ["NGSPICE_INPUT_DIR"] = "{0}".format(OPTS.openram_temp)
|
os.environ["NGSPICE_INPUT_DIR"] = "{0}".format(OPTS.openram_temp)
|
||||||
|
|
||||||
if OPTS.spice_exe == "":
|
if OPTS.spice_exe == "":
|
||||||
debug.error("No recognizable spice version found. Unable to perform characterization.",1)
|
debug.error("No recognizable spice version found. Unable to perform characterization.", 1)
|
||||||
else:
|
else:
|
||||||
debug.info(1,"Analytical model enabled.")
|
debug.info(1, "Analytical model enabled.")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,310 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
||||||
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
import debug
|
||||||
|
|
||||||
|
import csv
|
||||||
|
import math
|
||||||
|
import numpy as np
|
||||||
|
import os
|
||||||
|
|
||||||
|
process_transform = {'SS':0.0, 'TT': 0.5, 'FF':1.0}
|
||||||
|
|
||||||
|
def get_data_names(file_name):
|
||||||
|
"""
|
||||||
|
Returns just the data names in the first row of the CSV
|
||||||
|
"""
|
||||||
|
|
||||||
|
with open(file_name, newline='') as csvfile:
|
||||||
|
csv_reader = csv.reader(csvfile, delimiter=' ', quotechar='|')
|
||||||
|
row_iter = 0
|
||||||
|
# reader is iterable not a list, probably a better way to do this
|
||||||
|
for row in csv_reader:
|
||||||
|
# Return names from first row
|
||||||
|
return row[0].split(',')
|
||||||
|
|
||||||
|
def get_data(file_name):
|
||||||
|
"""
|
||||||
|
Returns data in CSV as lists of features
|
||||||
|
"""
|
||||||
|
|
||||||
|
with open(file_name, newline='') as csvfile:
|
||||||
|
csv_reader = csv.reader(csvfile, delimiter=' ', quotechar='|')
|
||||||
|
row_iter = 0
|
||||||
|
for row in csv_reader:
|
||||||
|
row_iter += 1
|
||||||
|
if row_iter == 1:
|
||||||
|
feature_names = row[0].split(',')
|
||||||
|
input_list = [[] for _ in feature_names]
|
||||||
|
scaled_list = [[] for _ in feature_names]
|
||||||
|
|
||||||
|
try:
|
||||||
|
process_ind = feature_names.index('process')
|
||||||
|
except:
|
||||||
|
debug.error('Process not included as a feature.')
|
||||||
|
continue
|
||||||
|
|
||||||
|
data = []
|
||||||
|
split_str = row[0].split(',')
|
||||||
|
for i in range(len(split_str)):
|
||||||
|
if i == process_ind:
|
||||||
|
data.append(process_transform[split_str[i]])
|
||||||
|
else:
|
||||||
|
data.append(float(split_str[i]))
|
||||||
|
|
||||||
|
data[0] = math.log(data[0], 2)
|
||||||
|
|
||||||
|
for i in range(len(data)):
|
||||||
|
input_list[i].append(data[i])
|
||||||
|
|
||||||
|
return input_list
|
||||||
|
|
||||||
|
def apply_samples_to_data(all_data, algo_samples):
|
||||||
|
# Take samples from algorithm and match them to samples in data
|
||||||
|
data_samples, unused_data = [], []
|
||||||
|
sample_positions = set()
|
||||||
|
for sample in algo_samples:
|
||||||
|
sample_positions.add(find_sample_position_with_min_error(all_data, sample))
|
||||||
|
|
||||||
|
for i in range(len(all_data)):
|
||||||
|
if i in sample_positions:
|
||||||
|
data_samples.append(all_data[i])
|
||||||
|
else:
|
||||||
|
unused_data.append(all_data[i])
|
||||||
|
|
||||||
|
return data_samples, unused_data
|
||||||
|
|
||||||
|
def find_sample_position_with_min_error(data, sampled_vals):
|
||||||
|
min_error = 0
|
||||||
|
sample_pos = 0
|
||||||
|
count = 0
|
||||||
|
for data_slice in data:
|
||||||
|
error = squared_error(data_slice, sampled_vals)
|
||||||
|
if min_error == 0 or error < min_error:
|
||||||
|
min_error = error
|
||||||
|
sample_pos = count
|
||||||
|
count += 1
|
||||||
|
return sample_pos
|
||||||
|
|
||||||
|
def squared_error(list_a, list_b):
|
||||||
|
error_sum = 0;
|
||||||
|
for a,b in zip(list_a, list_b):
|
||||||
|
error_sum+=(a-b)**2
|
||||||
|
return error_sum
|
||||||
|
|
||||||
|
|
||||||
|
def get_max_min_from_datasets(dir):
|
||||||
|
if not os.path.isdir(dir):
|
||||||
|
debug.warning("Input Directory not found:{}".format(dir))
|
||||||
|
return [], [], []
|
||||||
|
|
||||||
|
# Assuming all files are CSV
|
||||||
|
data_files = [f for f in os.listdir(dir) if os.path.isfile(os.path.join(dir, f))]
|
||||||
|
maxs,mins,sums,total_count = [],[],[],0
|
||||||
|
for file in data_files:
|
||||||
|
data = get_data(os.path.join(dir, file))
|
||||||
|
# Get max, min, sum, and count from every file
|
||||||
|
data_max, data_min, data_sum, count = [],[],[], 0
|
||||||
|
for feature_list in data:
|
||||||
|
data_max.append(max(feature_list))
|
||||||
|
data_min.append(min(feature_list))
|
||||||
|
data_sum.append(sum(feature_list))
|
||||||
|
count = len(feature_list)
|
||||||
|
|
||||||
|
# Aggregate the data
|
||||||
|
if not maxs or not mins or not sums:
|
||||||
|
maxs,mins,sums,total_count = data_max,data_min,data_sum,count
|
||||||
|
else:
|
||||||
|
for i in range(len(maxs)):
|
||||||
|
maxs[i] = max(data_max[i], maxs[i])
|
||||||
|
mins[i] = min(data_min[i], mins[i])
|
||||||
|
sums[i] = data_sum[i]+sums[i]
|
||||||
|
total_count+=count
|
||||||
|
|
||||||
|
avgs = [s/total_count for s in sums]
|
||||||
|
return maxs,mins,avgs
|
||||||
|
|
||||||
|
def get_max_min_from_file(path):
|
||||||
|
if not os.path.isfile(path):
|
||||||
|
debug.warning("Input file not found: {}".format(path))
|
||||||
|
return [], [], []
|
||||||
|
|
||||||
|
|
||||||
|
data = get_data(path)
|
||||||
|
# Get max, min, sum, and count from every file
|
||||||
|
data_max, data_min, data_sum, count = [],[],[], 0
|
||||||
|
for feature_list in data:
|
||||||
|
data_max.append(max(feature_list))
|
||||||
|
data_min.append(min(feature_list))
|
||||||
|
data_sum.append(sum(feature_list))
|
||||||
|
count = len(feature_list)
|
||||||
|
|
||||||
|
avgs = [s/count for s in data_sum]
|
||||||
|
return data_max, data_min, avgs
|
||||||
|
|
||||||
|
def get_data_and_scale(file_name, sample_dir):
|
||||||
|
maxs,mins,avgs = get_max_min_from_datasets(sample_dir)
|
||||||
|
|
||||||
|
# Get data
|
||||||
|
all_data = get_data(file_name)
|
||||||
|
|
||||||
|
# Scale data from file
|
||||||
|
self_scaled_data = [[] for _ in range(len(all_data[0]))]
|
||||||
|
self_maxs,self_mins = [],[]
|
||||||
|
for feature_list, cur_max, cur_min in zip(all_data,maxs, mins):
|
||||||
|
for i in range(len(feature_list)):
|
||||||
|
self_scaled_data[i].append((feature_list[i]-cur_min)/(cur_max-cur_min))
|
||||||
|
|
||||||
|
return np.asarray(self_scaled_data)
|
||||||
|
|
||||||
|
def rescale_data(data, old_maxs, old_mins, new_maxs, new_mins):
|
||||||
|
# unscale from old values, rescale by new values
|
||||||
|
data_new_scaling = []
|
||||||
|
for data_row in data:
|
||||||
|
scaled_row = []
|
||||||
|
for val, old_max,old_min, cur_max, cur_min in zip(data_row, old_maxs,old_mins, new_maxs, new_mins):
|
||||||
|
unscaled_data = val*(old_max-old_min) + old_min
|
||||||
|
scaled_row.append((unscaled_data-cur_min)/(cur_max-cur_min))
|
||||||
|
|
||||||
|
data_new_scaling.append(scaled_row)
|
||||||
|
|
||||||
|
return data_new_scaling
|
||||||
|
|
||||||
|
def sample_from_file(num_samples, file_name, sample_dir=None):
|
||||||
|
"""
|
||||||
|
Get a portion of the data from CSV file and scale it based on max/min of dataset.
|
||||||
|
Duplicate samples are trimmed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if sample_dir:
|
||||||
|
maxs,mins,avgs = get_max_min_from_datasets(sample_dir)
|
||||||
|
else:
|
||||||
|
maxs,mins,avgs = [], [], []
|
||||||
|
|
||||||
|
# Get data
|
||||||
|
all_data = get_data(file_name)
|
||||||
|
|
||||||
|
# Get algorithms sample points, assuming hypercube for now
|
||||||
|
num_labels = 1
|
||||||
|
inp_dims = len(all_data) - num_labels
|
||||||
|
samples = np.random.rand(num_samples, inp_dims)
|
||||||
|
|
||||||
|
|
||||||
|
# Scale data from file
|
||||||
|
self_scaled_data = [[] for _ in range(len(all_data[0]))]
|
||||||
|
self_maxs,self_mins = [],[]
|
||||||
|
for feature_list in all_data:
|
||||||
|
max_val = max(feature_list)
|
||||||
|
self_maxs.append(max_val)
|
||||||
|
min_val = min(feature_list)
|
||||||
|
self_mins.append(min_val)
|
||||||
|
for i in range(len(feature_list)):
|
||||||
|
self_scaled_data[i].append((feature_list[i]-min_val)/(max_val-min_val))
|
||||||
|
# Apply algorithm sampling points to available data
|
||||||
|
sampled_data, unused_data = apply_samples_to_data(self_scaled_data,samples)
|
||||||
|
|
||||||
|
#unscale values and rescale using all available data (both sampled and unused points rescaled)
|
||||||
|
if len(maxs)!=0 and len(mins)!=0:
|
||||||
|
sampled_data = rescale_data(sampled_data, self_maxs,self_mins, maxs, mins)
|
||||||
|
unused_new_scaling = rescale_data(unused_data, self_maxs,self_mins, maxs, mins)
|
||||||
|
|
||||||
|
return np.asarray(sampled_data), np.asarray(unused_new_scaling)
|
||||||
|
|
||||||
|
def get_scaled_data(file_name):
|
||||||
|
"""Get data from CSV file and scale it based on max/min of dataset"""
|
||||||
|
|
||||||
|
if file_name:
|
||||||
|
maxs,mins,avgs = get_max_min_from_file(file_name)
|
||||||
|
else:
|
||||||
|
maxs,mins,avgs = [], [], []
|
||||||
|
|
||||||
|
# Get data
|
||||||
|
all_data = get_data(file_name)
|
||||||
|
|
||||||
|
# Data is scaled by max/min and data format is changed to points vs feature lists
|
||||||
|
self_scaled_data = scale_data_and_transform(all_data)
|
||||||
|
samples = np.asarray(self_scaled_data)
|
||||||
|
features, labels = samples[:, :-1], samples[:,-1:]
|
||||||
|
return features, labels
|
||||||
|
|
||||||
|
def scale_data_and_transform(data):
|
||||||
|
"""
|
||||||
|
Assume data is a list of features, change to a list of points and max/min scale
|
||||||
|
"""
|
||||||
|
|
||||||
|
scaled_data = [[] for _ in range(len(data[0]))]
|
||||||
|
for feature_list in data:
|
||||||
|
max_val = max(feature_list)
|
||||||
|
min_val = min(feature_list)
|
||||||
|
|
||||||
|
for i in range(len(feature_list)):
|
||||||
|
if max_val == min_val:
|
||||||
|
scaled_data[i].append(0.0)
|
||||||
|
else:
|
||||||
|
scaled_data[i].append((feature_list[i]-min_val)/(max_val-min_val))
|
||||||
|
return scaled_data
|
||||||
|
|
||||||
|
def scale_input_datapoint(point, file_path):
|
||||||
|
"""
|
||||||
|
Input data has no output and needs to be scaled like the model inputs during
|
||||||
|
training.
|
||||||
|
"""
|
||||||
|
maxs, mins, avgs = get_max_min_from_file(file_path)
|
||||||
|
debug.info(3, "maxs={}".format(maxs))
|
||||||
|
debug.info(3, "mins={}".format(mins))
|
||||||
|
debug.info(3, "point={}".format(point))
|
||||||
|
|
||||||
|
scaled_point = []
|
||||||
|
for feature, mx, mn in zip(point, maxs, mins):
|
||||||
|
if mx == mn:
|
||||||
|
scaled_point.append(0.0)
|
||||||
|
else:
|
||||||
|
scaled_point.append((feature-mn)/(mx-mn))
|
||||||
|
return scaled_point
|
||||||
|
|
||||||
|
def unscale_data(data, file_path, pos=None):
|
||||||
|
if file_path:
|
||||||
|
maxs,mins,avgs = get_max_min_from_file(file_path)
|
||||||
|
else:
|
||||||
|
debug.error("Must provide reference data to unscale")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Hard coded to only convert the last max/min (i.e. the label of the data)
|
||||||
|
if pos == None:
|
||||||
|
maxs,mins,avgs = [maxs[-1]],[mins[-1]],[avgs[-1]]
|
||||||
|
else:
|
||||||
|
maxs,mins,avgs = [maxs[pos]],[mins[pos]],[avgs[pos]]
|
||||||
|
unscaled_data = []
|
||||||
|
for data_row in data:
|
||||||
|
unscaled_row = []
|
||||||
|
for val, cur_max, cur_min in zip(data_row, maxs, mins):
|
||||||
|
unscaled_val = val*(cur_max-cur_min) + cur_min
|
||||||
|
unscaled_row.append(unscaled_val)
|
||||||
|
unscaled_data.append(unscaled_row)
|
||||||
|
|
||||||
|
return unscaled_data
|
||||||
|
|
||||||
|
def abs_error(labels, preds):
|
||||||
|
total_error = 0
|
||||||
|
for label_i, pred_i in zip(labels, preds):
|
||||||
|
cur_error = abs(label_i[0]-pred_i[0])/label_i[0]
|
||||||
|
total_error += cur_error
|
||||||
|
return total_error/len(labels)
|
||||||
|
|
||||||
|
def max_error(labels, preds):
|
||||||
|
mx_error = 0
|
||||||
|
for label_i, pred_i in zip(labels, preds):
|
||||||
|
cur_error = abs(label_i[0]-pred_i[0])/label_i[0]
|
||||||
|
mx_error = max(cur_error, mx_error)
|
||||||
|
return mx_error
|
||||||
|
|
||||||
|
def min_error(labels, preds):
|
||||||
|
mn_error = 1
|
||||||
|
for label_i, pred_i in zip(labels, preds):
|
||||||
|
cur_error = abs(label_i[0]-pred_i[0])/label_i[0]
|
||||||
|
mn_error = min(cur_error, mn_error)
|
||||||
|
return mn_error
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
@ -52,21 +52,6 @@ class delay(simulation):
|
||||||
self.create_signal_names()
|
self.create_signal_names()
|
||||||
self.add_graph_exclusions()
|
self.add_graph_exclusions()
|
||||||
|
|
||||||
def create_measurement_names(self):
|
|
||||||
""" Create measurement names. The names themselves currently define the type of measurement """
|
|
||||||
|
|
||||||
self.delay_meas_names = ["delay_lh", "delay_hl", "slew_lh", "slew_hl"]
|
|
||||||
self.power_meas_names = ["read0_power",
|
|
||||||
"read1_power",
|
|
||||||
"write0_power",
|
|
||||||
"write1_power",
|
|
||||||
"disabled_read0_power",
|
|
||||||
"disabled_read1_power",
|
|
||||||
"disabled_write0_power",
|
|
||||||
"disabled_write1_power"]
|
|
||||||
# self.voltage_when_names = ["volt_bl", "volt_br"]
|
|
||||||
# self.bitline_delay_names = ["delay_bl", "delay_br"]
|
|
||||||
|
|
||||||
def create_measurement_objects(self):
|
def create_measurement_objects(self):
|
||||||
""" Create the measurements used for read and write ports """
|
""" Create the measurements used for read and write ports """
|
||||||
|
|
||||||
|
|
@ -525,7 +510,7 @@ class delay(simulation):
|
||||||
elif delay_obj.meta_str == sram_op.READ_ONE:
|
elif delay_obj.meta_str == sram_op.READ_ONE:
|
||||||
meas_cycle_delay = self.cycle_times[self.measure_cycles[port][delay_obj.meta_str]]
|
meas_cycle_delay = self.cycle_times[self.measure_cycles[port][delay_obj.meta_str]]
|
||||||
else:
|
else:
|
||||||
debug.error("Unrecognised delay Index={}".format(delay_obj.meta_str),1)
|
debug.error("Unrecognized delay Index={}".format(delay_obj.meta_str),1)
|
||||||
|
|
||||||
# These measurements have there time further delayed to the neg. edge of the clock.
|
# These measurements have there time further delayed to the neg. edge of the clock.
|
||||||
if delay_obj.meta_add_delay:
|
if delay_obj.meta_add_delay:
|
||||||
|
|
@ -1037,29 +1022,11 @@ class delay(simulation):
|
||||||
"""
|
"""
|
||||||
Probe address and data can be set separately to utilize other
|
Probe address and data can be set separately to utilize other
|
||||||
functions in this characterizer besides analyze.
|
functions in this characterizer besides analyze.
|
||||||
|
Netlist reduced for simulation.
|
||||||
"""
|
"""
|
||||||
|
super().set_probe(probe_address, probe_data)
|
||||||
self.probe_address = probe_address
|
|
||||||
self.probe_data = probe_data
|
|
||||||
self.bitline_column = self.get_data_bit_column_number(probe_address, probe_data)
|
|
||||||
self.wordline_row = self.get_address_row_number(probe_address)
|
|
||||||
self.prepare_netlist()
|
self.prepare_netlist()
|
||||||
|
|
||||||
def get_data_bit_column_number(self, probe_address, probe_data):
|
|
||||||
"""Calculates bitline column number of data bit under test using bit position and mux size"""
|
|
||||||
|
|
||||||
if self.sram.col_addr_size>0:
|
|
||||||
col_address = int(probe_address[0:self.sram.col_addr_size], 2)
|
|
||||||
else:
|
|
||||||
col_address = 0
|
|
||||||
bl_column = int(self.sram.words_per_row * probe_data + col_address)
|
|
||||||
return bl_column
|
|
||||||
|
|
||||||
def get_address_row_number(self, probe_address):
|
|
||||||
"""Calculates wordline row number of data bit under test using address and column mux size"""
|
|
||||||
|
|
||||||
return int(probe_address[self.sram.col_addr_size:], 2)
|
|
||||||
|
|
||||||
def prepare_netlist(self):
|
def prepare_netlist(self):
|
||||||
""" Prepare a trimmed netlist and regular netlist. """
|
""" Prepare a trimmed netlist and regular netlist. """
|
||||||
|
|
||||||
|
|
@ -1303,89 +1270,6 @@ class delay(simulation):
|
||||||
# Add test cycle of read/write port pair. One port could have been used already, but the other has not.
|
# Add test cycle of read/write port pair. One port could have been used already, but the other has not.
|
||||||
self.gen_test_cycles_one_port(cur_read_port, cur_write_port)
|
self.gen_test_cycles_one_port(cur_read_port, cur_write_port)
|
||||||
|
|
||||||
def sum_delays(self, delays):
|
|
||||||
"""Adds the delays (delay_data objects) so the correct slew is maintained"""
|
|
||||||
|
|
||||||
delay = delays[0]
|
|
||||||
for i in range(1, len(delays)):
|
|
||||||
delay+=delays[i]
|
|
||||||
return delay
|
|
||||||
|
|
||||||
def analytical_delay(self, slews, loads):
|
|
||||||
"""
|
|
||||||
Return the analytical model results for the SRAM.
|
|
||||||
"""
|
|
||||||
if OPTS.num_rw_ports > 1 or OPTS.num_w_ports > 0 and OPTS.num_r_ports > 0:
|
|
||||||
debug.warning("In analytical mode, all ports have the timing of the first read port.")
|
|
||||||
|
|
||||||
# Probe set to 0th bit, does not matter for analytical delay.
|
|
||||||
self.set_probe('0' * self.addr_size, 0)
|
|
||||||
self.create_graph()
|
|
||||||
self.set_internal_spice_names()
|
|
||||||
self.create_measurement_names()
|
|
||||||
|
|
||||||
port = self.read_ports[0]
|
|
||||||
self.graph.get_all_paths('{}{}'.format("clk", port),
|
|
||||||
'{}{}_{}'.format(self.dout_name, port, self.probe_data))
|
|
||||||
|
|
||||||
# Select the path with the bitline (bl)
|
|
||||||
bl_name, br_name = self.get_bl_name(self.graph.all_paths, port)
|
|
||||||
bl_path = [path for path in self.graph.all_paths if bl_name in path][0]
|
|
||||||
|
|
||||||
# Set delay/power for slews and loads
|
|
||||||
port_data = self.get_empty_measure_data_dict()
|
|
||||||
power = self.analytical_power(slews, loads)
|
|
||||||
debug.info(1, 'Slew, Load, Delay(ns), Slew(ns)')
|
|
||||||
max_delay = 0.0
|
|
||||||
for slew in slews:
|
|
||||||
for load in loads:
|
|
||||||
# Calculate delay based on slew and load
|
|
||||||
path_delays = self.graph.get_timing(bl_path, self.corner, slew, load)
|
|
||||||
|
|
||||||
total_delay = self.sum_delays(path_delays)
|
|
||||||
max_delay = max(max_delay, total_delay.delay)
|
|
||||||
debug.info(1,
|
|
||||||
'{}, {}, {}, {}'.format(slew,
|
|
||||||
load,
|
|
||||||
total_delay.delay / 1e3,
|
|
||||||
total_delay.slew / 1e3))
|
|
||||||
|
|
||||||
# Delay is only calculated on a single port and replicated for now.
|
|
||||||
for port in self.all_ports:
|
|
||||||
for mname in self.delay_meas_names + self.power_meas_names:
|
|
||||||
if "power" in mname:
|
|
||||||
port_data[port][mname].append(power.dynamic)
|
|
||||||
elif "delay" in mname and port in self.read_ports:
|
|
||||||
port_data[port][mname].append(total_delay.delay / 1e3)
|
|
||||||
elif "slew" in mname and port in self.read_ports:
|
|
||||||
port_data[port][mname].append(total_delay.slew / 1e3)
|
|
||||||
else:
|
|
||||||
debug.error("Measurement name not recognized: {}".format(mname), 1)
|
|
||||||
|
|
||||||
# Margin for error in period. Calculated by averaging required margin for a small and large
|
|
||||||
# memory. FIXME: margin is quite large, should be looked into.
|
|
||||||
period_margin = 1.85
|
|
||||||
sram_data = {"min_period": (max_delay / 1e3) * 2 * period_margin,
|
|
||||||
"leakage_power": power.leakage}
|
|
||||||
|
|
||||||
debug.info(2, "SRAM Data:\n{}".format(sram_data))
|
|
||||||
debug.info(2, "Port Data:\n{}".format(port_data))
|
|
||||||
|
|
||||||
return (sram_data, port_data)
|
|
||||||
|
|
||||||
def analytical_power(self, slews, loads):
|
|
||||||
"""Get the dynamic and leakage power from the SRAM"""
|
|
||||||
|
|
||||||
# slews unused, only last load is used
|
|
||||||
load = loads[-1]
|
|
||||||
power = self.sram.analytical_power(self.corner, load)
|
|
||||||
# convert from nW to mW
|
|
||||||
power.dynamic /= 1e6
|
|
||||||
power.leakage /= 1e6
|
|
||||||
debug.info(1, "Dynamic Power: {0} mW".format(power.dynamic))
|
|
||||||
debug.info(1, "Leakage Power: {0} mW".format(power.leakage))
|
|
||||||
return power
|
|
||||||
|
|
||||||
def gen_data(self):
|
def gen_data(self):
|
||||||
""" Generates the PWL data inputs for a simulation timing test. """
|
""" Generates the PWL data inputs for a simulation timing test. """
|
||||||
|
|
||||||
|
|
@ -1412,11 +1296,3 @@ class delay(simulation):
|
||||||
self.stim.gen_pwl("CSB{0}".format(port), self.cycle_times, self.csb_values[port], self.period, self.slew, 0.05)
|
self.stim.gen_pwl("CSB{0}".format(port), self.cycle_times, self.csb_values[port], self.period, self.slew, 0.05)
|
||||||
if port in self.readwrite_ports:
|
if port in self.readwrite_ports:
|
||||||
self.stim.gen_pwl("WEB{0}".format(port), self.cycle_times, self.web_values[port], self.period, self.slew, 0.05)
|
self.stim.gen_pwl("WEB{0}".format(port), self.cycle_times, self.web_values[port], self.period, self.slew, 0.05)
|
||||||
|
|
||||||
def get_empty_measure_data_dict(self):
|
|
||||||
"""Make a dict of lists for each type of delay and power measurement to append results to"""
|
|
||||||
|
|
||||||
measure_names = self.delay_meas_names + self.power_meas_names
|
|
||||||
# Create list of dicts. List lengths is # of ports. Each dict maps the measurement names to lists.
|
|
||||||
measure_data = [{mname: [] for mname in measure_names} for i in self.all_ports]
|
|
||||||
return measure_data
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
# See LICENSE for licensing information.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
||||||
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
from .simulation import simulation
|
||||||
|
from globals import OPTS
|
||||||
|
import debug
|
||||||
|
|
||||||
|
class elmore(simulation):
|
||||||
|
"""
|
||||||
|
Delay model for the SRAM which calculates Elmore delays along the SRAM critical path.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, sram, spfile, corner):
|
||||||
|
super().__init__(sram, spfile, corner)
|
||||||
|
|
||||||
|
# self.targ_read_ports = []
|
||||||
|
# self.targ_write_ports = []
|
||||||
|
# self.period = 0
|
||||||
|
# if self.write_size:
|
||||||
|
# self.num_wmasks = int(math.ceil(self.word_size / self.write_size))
|
||||||
|
# else:
|
||||||
|
# self.num_wmasks = 0
|
||||||
|
#self.set_load_slew(0, 0)
|
||||||
|
self.set_corner(corner)
|
||||||
|
self.create_signal_names()
|
||||||
|
self.add_graph_exclusions()
|
||||||
|
|
||||||
|
def get_lib_values(self, slews, loads):
|
||||||
|
"""
|
||||||
|
Return the analytical model results for the SRAM.
|
||||||
|
"""
|
||||||
|
if OPTS.num_rw_ports > 1 or OPTS.num_w_ports > 0 and OPTS.num_r_ports > 0:
|
||||||
|
debug.warning("In analytical mode, all ports have the timing of the first read port.")
|
||||||
|
|
||||||
|
# Probe set to 0th bit, does not matter for analytical delay.
|
||||||
|
self.set_probe('0' * self.addr_size, 0)
|
||||||
|
self.create_graph()
|
||||||
|
self.set_internal_spice_names()
|
||||||
|
self.create_measurement_names()
|
||||||
|
|
||||||
|
port = self.read_ports[0]
|
||||||
|
self.graph.get_all_paths('{}{}'.format("clk", port),
|
||||||
|
'{}{}_{}'.format(self.dout_name, port, self.probe_data))
|
||||||
|
|
||||||
|
# Select the path with the bitline (bl)
|
||||||
|
bl_name, br_name = self.get_bl_name(self.graph.all_paths, port)
|
||||||
|
bl_path = [path for path in self.graph.all_paths if bl_name in path][0]
|
||||||
|
|
||||||
|
# Set delay/power for slews and loads
|
||||||
|
port_data = self.get_empty_measure_data_dict()
|
||||||
|
power = self.analytical_power(slews, loads)
|
||||||
|
debug.info(1, 'Slew, Load, Delay(ns), Slew(ns)')
|
||||||
|
max_delay = 0.0
|
||||||
|
for slew in slews:
|
||||||
|
for load in loads:
|
||||||
|
# Calculate delay based on slew and load
|
||||||
|
path_delays = self.graph.get_timing(bl_path, self.corner, slew, load)
|
||||||
|
|
||||||
|
total_delay = self.sum_delays(path_delays)
|
||||||
|
max_delay = max(max_delay, total_delay.delay)
|
||||||
|
debug.info(1,
|
||||||
|
'{}, {}, {}, {}'.format(slew,
|
||||||
|
load,
|
||||||
|
total_delay.delay / 1e3,
|
||||||
|
total_delay.slew / 1e3))
|
||||||
|
|
||||||
|
# Delay is only calculated on a single port and replicated for now.
|
||||||
|
for port in self.all_ports:
|
||||||
|
for mname in self.delay_meas_names + self.power_meas_names:
|
||||||
|
if "power" in mname:
|
||||||
|
port_data[port][mname].append(power.dynamic)
|
||||||
|
elif "delay" in mname and port in self.read_ports:
|
||||||
|
port_data[port][mname].append(total_delay.delay / 1e3)
|
||||||
|
elif "slew" in mname and port in self.read_ports:
|
||||||
|
port_data[port][mname].append(total_delay.slew / 1e3)
|
||||||
|
else:
|
||||||
|
debug.error("Measurement name not recognized: {}".format(mname), 1)
|
||||||
|
|
||||||
|
# Margin for error in period. Calculated by averaging required margin for a small and large
|
||||||
|
# memory. FIXME: margin is quite large, should be looked into.
|
||||||
|
period_margin = 1.85
|
||||||
|
sram_data = {"min_period": (max_delay / 1e3) * 2 * period_margin,
|
||||||
|
"leakage_power": power.leakage}
|
||||||
|
|
||||||
|
debug.info(2, "SRAM Data:\n{}".format(sram_data))
|
||||||
|
debug.info(2, "Port Data:\n{}".format(port_data))
|
||||||
|
|
||||||
|
return (sram_data, port_data)
|
||||||
|
|
||||||
|
def analytical_power(self, slews, loads):
|
||||||
|
"""Get the dynamic and leakage power from the SRAM"""
|
||||||
|
|
||||||
|
# slews unused, only last load is used
|
||||||
|
load = loads[-1]
|
||||||
|
power = self.sram.analytical_power(self.corner, load)
|
||||||
|
# convert from nW to mW
|
||||||
|
power.dynamic /= 1e6
|
||||||
|
power.leakage /= 1e6
|
||||||
|
debug.info(1, "Dynamic Power: {0} mW".format(power.dynamic))
|
||||||
|
debug.info(1, "Leakage Power: {0} mW".format(power.leakage))
|
||||||
|
return power
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
@ -74,26 +74,38 @@ class lib:
|
||||||
|
|
||||||
self.corners = []
|
self.corners = []
|
||||||
self.lib_files = []
|
self.lib_files = []
|
||||||
|
|
||||||
# Nominal corner
|
if OPTS.use_specified_corners == None:
|
||||||
corner_set = set()
|
# Nominal corner
|
||||||
nom_corner = (nom_process, nom_supply, nom_temperature)
|
corner_tuples = set()
|
||||||
corner_set.add(nom_corner)
|
if OPTS.only_use_config_corners:
|
||||||
if not OPTS.nominal_corner_only:
|
if OPTS.nominal_corner_only:
|
||||||
# Temperature corners
|
debug.warning("Nominal corner only option ignored if use only config corners is set.")
|
||||||
corner_set.add((nom_process, nom_supply, min_temperature))
|
# Generate a powerset of input PVT lists
|
||||||
corner_set.add((nom_process, nom_supply, max_temperature))
|
for p in self.process_corners:
|
||||||
# Supply corners
|
for v in self.supply_voltages:
|
||||||
corner_set.add((nom_process, min_supply, nom_temperature))
|
for t in self.temperatures:
|
||||||
corner_set.add((nom_process, max_supply, nom_temperature))
|
corner_tuples.add((p, v, t))
|
||||||
# Process corners
|
else:
|
||||||
corner_set.add((min_process, nom_supply, nom_temperature))
|
nom_corner = (nom_process, nom_supply, nom_temperature)
|
||||||
corner_set.add((max_process, nom_supply, nom_temperature))
|
corner_tuples.add(nom_corner)
|
||||||
|
if not OPTS.nominal_corner_only:
|
||||||
# Enforce that nominal corner is the first to be characterized
|
# Temperature corners
|
||||||
self.add_corner(*nom_corner)
|
corner_tuples.add((nom_process, nom_supply, min_temperature))
|
||||||
corner_set.remove(nom_corner)
|
corner_tuples.add((nom_process, nom_supply, max_temperature))
|
||||||
for corner_tuple in corner_set:
|
# Supply corners
|
||||||
|
corner_tuples.add((nom_process, min_supply, nom_temperature))
|
||||||
|
corner_tuples.add((nom_process, max_supply, nom_temperature))
|
||||||
|
# Process corners
|
||||||
|
corner_tuples.add((min_process, nom_supply, nom_temperature))
|
||||||
|
corner_tuples.add((max_process, nom_supply, nom_temperature))
|
||||||
|
# Enforce that nominal corner is the first to be characterized
|
||||||
|
self.add_corner(*nom_corner)
|
||||||
|
corner_tuples.remove(nom_corner)
|
||||||
|
else:
|
||||||
|
corner_tuples = OPTS.use_specified_corners
|
||||||
|
|
||||||
|
for corner_tuple in corner_tuples:
|
||||||
self.add_corner(*corner_tuple)
|
self.add_corner(*corner_tuple)
|
||||||
|
|
||||||
def add_corner(self, proc, volt, temp):
|
def add_corner(self, proc, volt, temp):
|
||||||
|
|
@ -581,18 +593,28 @@ class lib:
|
||||||
|
|
||||||
def compute_delay(self):
|
def compute_delay(self):
|
||||||
"""Compute SRAM delays for current corner"""
|
"""Compute SRAM delays for current corner"""
|
||||||
self.d = delay(self.sram, self.sp_file, self.corner)
|
|
||||||
if self.use_model:
|
if self.use_model:
|
||||||
char_results = self.d.analytical_delay(self.slews,self.loads)
|
model_name_lc = OPTS.model_name.lower()
|
||||||
self.char_sram_results, self.char_port_results = char_results
|
if model_name_lc == "linear_regression":
|
||||||
|
from .linear_regression import linear_regression as model
|
||||||
|
elif model_name_lc == "elmore":
|
||||||
|
from .elmore import elmore as model
|
||||||
|
else:
|
||||||
|
debug.error("{} model not recognized. See options.py for available models.".format(OPTS.model_name))
|
||||||
|
import math
|
||||||
|
|
||||||
|
m = model(self.sram, self.sp_file, self.corner)
|
||||||
|
char_results = m.get_lib_values(self.slews,self.loads)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
self.d = delay(self.sram, self.sp_file, self.corner)
|
||||||
if (self.sram.num_spare_rows == 0):
|
if (self.sram.num_spare_rows == 0):
|
||||||
probe_address = "1" * self.sram.addr_size
|
probe_address = "1" * self.sram.addr_size
|
||||||
else:
|
else:
|
||||||
probe_address = "0" + "1" * (self.sram.addr_size - 1)
|
probe_address = "0" + "1" * (self.sram.addr_size - 1)
|
||||||
probe_data = self.sram.word_size - 1
|
probe_data = self.sram.word_size - 1
|
||||||
char_results = self.d.analyze(probe_address, probe_data, self.slews, self.loads)
|
char_results = self.d.analyze(probe_address, probe_data, self.slews, self.loads)
|
||||||
self.char_sram_results, self.char_port_results = char_results
|
self.char_sram_results, self.char_port_results = char_results
|
||||||
|
|
||||||
def compute_setup_hold(self):
|
def compute_setup_hold(self):
|
||||||
""" Do the analysis if we haven't characterized a FF yet """
|
""" Do the analysis if we haven't characterized a FF yet """
|
||||||
|
|
@ -607,6 +629,79 @@ class lib:
|
||||||
|
|
||||||
def parse_info(self,corner,lib_name):
|
def parse_info(self,corner,lib_name):
|
||||||
""" Copies important characterization data to datasheet.info to be added to datasheet """
|
""" Copies important characterization data to datasheet.info to be added to datasheet """
|
||||||
|
if OPTS.output_datasheet_info:
|
||||||
|
datasheet_path = OPTS.output_path
|
||||||
|
else:
|
||||||
|
datasheet_path = OPTS.openram_temp
|
||||||
|
datasheet = open(datasheet_path +'/datasheet.info', 'a+')
|
||||||
|
|
||||||
|
self.write_inp_params_datasheet(datasheet, corner, lib_name)
|
||||||
|
self.write_signal_from_ports(datasheet,
|
||||||
|
"din{1}[{0}:0]".format(self.sram.word_size - 1, '{}'),
|
||||||
|
self.write_ports,
|
||||||
|
"setup_times_LH",
|
||||||
|
"setup_times_HL",
|
||||||
|
"hold_times_LH",
|
||||||
|
"hold_times_HL")
|
||||||
|
|
||||||
|
# self.write_signal_from_ports(datasheet,
|
||||||
|
# "dout{1}[{0}:0]".format(self.sram.word_size - 1, '{}'),
|
||||||
|
# self.read_ports,
|
||||||
|
# "delay_lh",
|
||||||
|
# "delay_hl",
|
||||||
|
# "slew_lh",
|
||||||
|
# "slew_hl")
|
||||||
|
for port in self.all_ports:
|
||||||
|
#dout timing
|
||||||
|
if port in self.read_ports:
|
||||||
|
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
|
||||||
|
"dout{1}[{0}:0]".format(self.sram.word_size - 1, port),
|
||||||
|
min(list(map(round_time,self.char_port_results[port]["delay_lh"]))),
|
||||||
|
max(list(map(round_time,self.char_port_results[port]["delay_lh"]))),
|
||||||
|
|
||||||
|
min(list(map(round_time,self.char_port_results[port]["delay_hl"]))),
|
||||||
|
max(list(map(round_time,self.char_port_results[port]["delay_hl"]))),
|
||||||
|
|
||||||
|
min(list(map(round_time,self.char_port_results[port]["slew_lh"]))),
|
||||||
|
max(list(map(round_time,self.char_port_results[port]["slew_lh"]))),
|
||||||
|
|
||||||
|
min(list(map(round_time,self.char_port_results[port]["slew_hl"]))),
|
||||||
|
max(list(map(round_time,self.char_port_results[port]["slew_hl"])))
|
||||||
|
))
|
||||||
|
|
||||||
|
self.write_signal_from_ports(datasheet,
|
||||||
|
"csb{}",
|
||||||
|
self.all_ports,
|
||||||
|
"setup_times_LH",
|
||||||
|
"setup_times_HL",
|
||||||
|
"hold_times_LH",
|
||||||
|
"hold_times_HL")
|
||||||
|
|
||||||
|
self.write_signal_from_ports(datasheet,
|
||||||
|
"addr{1}[{0}:0]".format(self.sram.addr_size - 1, '{}'),
|
||||||
|
self.all_ports,
|
||||||
|
"setup_times_LH",
|
||||||
|
"setup_times_HL",
|
||||||
|
"hold_times_LH",
|
||||||
|
"hold_times_HL")
|
||||||
|
|
||||||
|
self.write_signal_from_ports(datasheet,
|
||||||
|
"web{}",
|
||||||
|
self.readwrite_ports,
|
||||||
|
"setup_times_LH",
|
||||||
|
"setup_times_HL",
|
||||||
|
"hold_times_LH",
|
||||||
|
"hold_times_HL")
|
||||||
|
|
||||||
|
self.write_power_datasheet(datasheet)
|
||||||
|
|
||||||
|
self.write_model_params(datasheet)
|
||||||
|
|
||||||
|
datasheet.write("END\n")
|
||||||
|
datasheet.close()
|
||||||
|
|
||||||
|
def write_inp_params_datasheet(self, datasheet, corner, lib_name):
|
||||||
|
|
||||||
if OPTS.is_unit_test:
|
if OPTS.is_unit_test:
|
||||||
git_id = 'FFFFFFFFFFFFFFFFFFFF'
|
git_id = 'FFFFFFFFFFFFFFFFFFFF'
|
||||||
|
|
||||||
|
|
@ -624,11 +719,9 @@ class lib:
|
||||||
# check if git id is valid
|
# check if git id is valid
|
||||||
if len(git_id) != 40:
|
if len(git_id) != 40:
|
||||||
debug.warning("Failed to retrieve git id")
|
debug.warning("Failed to retrieve git id")
|
||||||
git_id = 'Failed to retruieve'
|
git_id = 'Failed to retrieve'
|
||||||
|
|
||||||
datasheet = open(OPTS.openram_temp +'/datasheet.info', 'a+')
|
|
||||||
|
|
||||||
current_time = datetime.date.today()
|
current_time = datetime.date.today()
|
||||||
|
|
||||||
# write static information to be parser later
|
# write static information to be parser later
|
||||||
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16},".format(
|
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16},".format(
|
||||||
OPTS.output_name,
|
OPTS.output_name,
|
||||||
|
|
@ -656,104 +749,26 @@ class lib:
|
||||||
|
|
||||||
# write area
|
# write area
|
||||||
datasheet.write(str(self.sram.width * self.sram.height) + ',')
|
datasheet.write(str(self.sram.width * self.sram.height) + ',')
|
||||||
|
|
||||||
# write timing information for all ports
|
def write_signal_from_ports(self, datasheet, signal, ports, time_pos_1, time_pos_2, time_pos_3, time_pos_4):
|
||||||
for port in self.all_ports:
|
for port in ports:
|
||||||
#din timings
|
|
||||||
if port in self.write_ports:
|
|
||||||
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
|
|
||||||
"din{1}[{0}:0]".format(self.sram.word_size - 1, port),
|
|
||||||
min(list(map(round_time,self.times["setup_times_LH"]))),
|
|
||||||
max(list(map(round_time,self.times["setup_times_LH"]))),
|
|
||||||
|
|
||||||
min(list(map(round_time,self.times["setup_times_HL"]))),
|
|
||||||
max(list(map(round_time,self.times["setup_times_HL"]))),
|
|
||||||
|
|
||||||
min(list(map(round_time,self.times["hold_times_LH"]))),
|
|
||||||
max(list(map(round_time,self.times["hold_times_LH"]))),
|
|
||||||
|
|
||||||
min(list(map(round_time,self.times["hold_times_HL"]))),
|
|
||||||
max(list(map(round_time,self.times["hold_times_HL"])))
|
|
||||||
|
|
||||||
))
|
|
||||||
|
|
||||||
for port in self.all_ports:
|
|
||||||
#dout timing
|
|
||||||
if port in self.read_ports:
|
|
||||||
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
|
|
||||||
"dout{1}[{0}:0]".format(self.sram.word_size - 1, port),
|
|
||||||
min(list(map(round_time,self.char_port_results[port]["delay_lh"]))),
|
|
||||||
max(list(map(round_time,self.char_port_results[port]["delay_lh"]))),
|
|
||||||
|
|
||||||
min(list(map(round_time,self.char_port_results[port]["delay_hl"]))),
|
|
||||||
max(list(map(round_time,self.char_port_results[port]["delay_hl"]))),
|
|
||||||
|
|
||||||
min(list(map(round_time,self.char_port_results[port]["slew_lh"]))),
|
|
||||||
max(list(map(round_time,self.char_port_results[port]["slew_lh"]))),
|
|
||||||
|
|
||||||
min(list(map(round_time,self.char_port_results[port]["slew_hl"]))),
|
|
||||||
max(list(map(round_time,self.char_port_results[port]["slew_hl"])))
|
|
||||||
|
|
||||||
|
|
||||||
))
|
|
||||||
|
|
||||||
for port in self.all_ports:
|
|
||||||
#csb timings
|
|
||||||
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
|
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
|
||||||
"csb{0}".format(port),
|
signal.format(port),
|
||||||
min(list(map(round_time,self.times["setup_times_LH"]))),
|
min(list(map(round_time,self.times[time_pos_1]))),
|
||||||
max(list(map(round_time,self.times["setup_times_LH"]))),
|
max(list(map(round_time,self.times[time_pos_1]))),
|
||||||
|
|
||||||
min(list(map(round_time,self.times["setup_times_HL"]))),
|
min(list(map(round_time,self.times[time_pos_2]))),
|
||||||
max(list(map(round_time,self.times["setup_times_HL"]))),
|
max(list(map(round_time,self.times[time_pos_2]))),
|
||||||
|
|
||||||
min(list(map(round_time,self.times["hold_times_LH"]))),
|
min(list(map(round_time,self.times[time_pos_3]))),
|
||||||
max(list(map(round_time,self.times["hold_times_LH"]))),
|
max(list(map(round_time,self.times[time_pos_3]))),
|
||||||
|
|
||||||
min(list(map(round_time,self.times["hold_times_HL"]))),
|
min(list(map(round_time,self.times[time_pos_4]))),
|
||||||
max(list(map(round_time,self.times["hold_times_HL"])))
|
max(list(map(round_time,self.times[time_pos_4])))
|
||||||
|
|
||||||
))
|
))
|
||||||
|
|
||||||
for port in self.all_ports:
|
def write_power_datasheet(self, datasheet):
|
||||||
#addr timings
|
|
||||||
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
|
|
||||||
"addr{1}[{0}:0]".format(self.sram.addr_size - 1, port),
|
|
||||||
min(list(map(round_time,self.times["setup_times_LH"]))),
|
|
||||||
max(list(map(round_time,self.times["setup_times_LH"]))),
|
|
||||||
|
|
||||||
min(list(map(round_time,self.times["setup_times_HL"]))),
|
|
||||||
max(list(map(round_time,self.times["setup_times_HL"]))),
|
|
||||||
|
|
||||||
min(list(map(round_time,self.times["hold_times_LH"]))),
|
|
||||||
max(list(map(round_time,self.times["hold_times_LH"]))),
|
|
||||||
|
|
||||||
min(list(map(round_time,self.times["hold_times_HL"]))),
|
|
||||||
max(list(map(round_time,self.times["hold_times_HL"])))
|
|
||||||
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
for port in self.all_ports:
|
|
||||||
if port in self.readwrite_ports:
|
|
||||||
|
|
||||||
#web timings
|
|
||||||
datasheet.write("{0},{1},{2},{3},{4},{5},{6},{7},{8},".format(
|
|
||||||
"web{0}".format(port),
|
|
||||||
min(list(map(round_time,self.times["setup_times_LH"]))),
|
|
||||||
max(list(map(round_time,self.times["setup_times_LH"]))),
|
|
||||||
|
|
||||||
min(list(map(round_time,self.times["setup_times_HL"]))),
|
|
||||||
max(list(map(round_time,self.times["setup_times_HL"]))),
|
|
||||||
|
|
||||||
min(list(map(round_time,self.times["hold_times_LH"]))),
|
|
||||||
max(list(map(round_time,self.times["hold_times_LH"]))),
|
|
||||||
|
|
||||||
min(list(map(round_time,self.times["hold_times_HL"]))),
|
|
||||||
max(list(map(round_time,self.times["hold_times_HL"])))
|
|
||||||
|
|
||||||
))
|
|
||||||
|
|
||||||
# write power information
|
# write power information
|
||||||
for port in self.all_ports:
|
for port in self.all_ports:
|
||||||
name = ''
|
name = ''
|
||||||
|
|
@ -792,7 +807,31 @@ class lib:
|
||||||
control_str += ' & csb{0}'.format(i)
|
control_str += ' & csb{0}'.format(i)
|
||||||
|
|
||||||
datasheet.write("{0},{1},{2},".format('leak', control_str, self.char_sram_results["leakage_power"]))
|
datasheet.write("{0},{1},{2},".format('leak', control_str, self.char_sram_results["leakage_power"]))
|
||||||
|
|
||||||
|
def write_model_params(self, datasheet):
|
||||||
datasheet.write("END\n")
|
"""Write values which will be used in the analytical model as inputs"""
|
||||||
datasheet.close()
|
datasheet.write("{0},{1},".format('words_per_row', OPTS.words_per_row))
|
||||||
|
datasheet.write("{0},{1},".format('slews', list(self.slews)))
|
||||||
|
datasheet.write("{0},{1},".format('loads', list(self.loads)))
|
||||||
|
|
||||||
|
for port in self.read_ports:
|
||||||
|
datasheet.write("{0},{1},".format('cell_rise_{}'.format(port), self.char_port_results[port]["delay_lh"]))
|
||||||
|
datasheet.write("{0},{1},".format('cell_fall_{}'.format(port), self.char_port_results[port]["delay_hl"]))
|
||||||
|
datasheet.write("{0},{1},".format('rise_transition_{}'.format(port), self.char_port_results[port]["slew_lh"]))
|
||||||
|
datasheet.write("{0},{1},".format('fall_transition_{}'.format(port), self.char_port_results[port]["slew_hl"]))
|
||||||
|
|
||||||
|
for port in self.write_ports:
|
||||||
|
write1_power = np.mean(self.char_port_results[port]["write1_power"])
|
||||||
|
write0_power = np.mean(self.char_port_results[port]["write0_power"])
|
||||||
|
datasheet.write("{0},{1},".format('write_rise_power_{}'.format(port), write1_power))
|
||||||
|
#FIXME: should be write_fall_power
|
||||||
|
datasheet.write("{0},{1},".format('read_fall_power_{}'.format(port), write0_power))
|
||||||
|
|
||||||
|
for port in self.read_ports:
|
||||||
|
read1_power = np.mean(self.char_port_results[port]["read1_power"])
|
||||||
|
read0_power = np.mean(self.char_port_results[port]["read0_power"])
|
||||||
|
datasheet.write("{0},{1},".format('read_rise_power_{}'.format(port), read1_power))
|
||||||
|
#FIXME: should be read_fall_power
|
||||||
|
datasheet.write("{0},{1},".format('write_fall_power_{}'.format(port), read0_power))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
# See LICENSE for licensing information.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
||||||
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
from .regression_model import regression_model
|
||||||
|
from globals import OPTS
|
||||||
|
import debug
|
||||||
|
|
||||||
|
from sklearn.linear_model import LinearRegression
|
||||||
|
|
||||||
|
|
||||||
|
class linear_regression(regression_model):
|
||||||
|
|
||||||
|
def __init__(self, sram, spfile, corner):
|
||||||
|
super().__init__(sram, spfile, corner)
|
||||||
|
|
||||||
|
def generate_model(self, features, labels):
|
||||||
|
"""
|
||||||
|
Supervised training of model.
|
||||||
|
"""
|
||||||
|
|
||||||
|
model = LinearRegression()
|
||||||
|
model.fit(features, labels)
|
||||||
|
return model
|
||||||
|
|
||||||
|
def model_prediction(self, model, features):
|
||||||
|
"""
|
||||||
|
Have the model perform a prediction and unscale the prediction
|
||||||
|
as the model is trained with scaled values.
|
||||||
|
"""
|
||||||
|
|
||||||
|
pred = model.predict(features)
|
||||||
|
return pred
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
# See LICENSE for licensing information.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
||||||
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
from .regression_model import regression_model
|
||||||
|
from globals import OPTS
|
||||||
|
import debug
|
||||||
|
|
||||||
|
from tensorflow import keras
|
||||||
|
from tensorflow.keras import layers
|
||||||
|
import tensorflow as tf
|
||||||
|
|
||||||
|
|
||||||
|
class neural_network(regression_model):
|
||||||
|
|
||||||
|
def __init__(self, sram, spfile, corner):
|
||||||
|
super().__init__(sram, spfile, corner)
|
||||||
|
|
||||||
|
def generate_model(self, features, labels):
|
||||||
|
"""
|
||||||
|
Supervised training of model.
|
||||||
|
"""
|
||||||
|
|
||||||
|
model = keras.Sequential([
|
||||||
|
layers.Dense(32, activation=tf.nn.relu, input_shape=[features.shape[1]]),
|
||||||
|
layers.Dense(32, activation=tf.nn.relu),
|
||||||
|
layers.Dense(32, activation=tf.nn.relu),
|
||||||
|
layers.Dense(1)
|
||||||
|
])
|
||||||
|
|
||||||
|
optimizer = keras.optimizers.RMSprop(0.0099)
|
||||||
|
model.compile(loss='mean_squared_error', optimizer=optimizer)
|
||||||
|
model.fit(features, labels, epochs=100, verbose=0)
|
||||||
|
return model
|
||||||
|
|
||||||
|
def model_prediction(self, model, features):
|
||||||
|
"""
|
||||||
|
Have the model perform a prediction and unscale the prediction
|
||||||
|
as the model is trained with scaled values.
|
||||||
|
"""
|
||||||
|
|
||||||
|
pred = model.predict(features)
|
||||||
|
return pred
|
||||||
|
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
# See LICENSE for licensing information.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
||||||
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
|
||||||
|
from .analytical_util import *
|
||||||
|
from .simulation import simulation
|
||||||
|
from globals import OPTS
|
||||||
|
import debug
|
||||||
|
|
||||||
|
import math
|
||||||
|
|
||||||
|
relative_data_path = "/sim_data"
|
||||||
|
data_fnames = ["rise_delay.csv",
|
||||||
|
"fall_delay.csv",
|
||||||
|
"rise_slew.csv",
|
||||||
|
"fall_slew.csv",
|
||||||
|
"write1_power.csv",
|
||||||
|
"write0_power.csv",
|
||||||
|
"read1_power.csv",
|
||||||
|
"read0_power.csv",
|
||||||
|
"leakage_data.csv"]
|
||||||
|
# Positions must correspond to data_fname list
|
||||||
|
lib_dnames = ["delay_lh",
|
||||||
|
"delay_hl",
|
||||||
|
"slew_lh",
|
||||||
|
"slew_hl",
|
||||||
|
"write1_power",
|
||||||
|
"write0_power",
|
||||||
|
"read1_power",
|
||||||
|
"read0_power",
|
||||||
|
"leakage_power"]
|
||||||
|
# Check if another data dir was specified
|
||||||
|
if OPTS.sim_data_path == None:
|
||||||
|
data_dir = OPTS.openram_tech+relative_data_path
|
||||||
|
else:
|
||||||
|
data_dir = OPTS.sim_data_path
|
||||||
|
|
||||||
|
data_paths = {dname:data_dir +'/'+fname for dname, fname in zip(lib_dnames, data_fnames)}
|
||||||
|
|
||||||
|
class regression_model(simulation):
|
||||||
|
|
||||||
|
def __init__(self, sram, spfile, corner):
|
||||||
|
super().__init__(sram, spfile, corner)
|
||||||
|
self.set_corner(corner)
|
||||||
|
|
||||||
|
def get_lib_values(self, slews, loads):
|
||||||
|
"""
|
||||||
|
A model and prediction is created for each output needed for the LIB
|
||||||
|
"""
|
||||||
|
|
||||||
|
debug.info(1, "Characterizing SRAM using linear regression models.")
|
||||||
|
log_num_words = math.log(OPTS.num_words, 2)
|
||||||
|
model_inputs = [log_num_words,
|
||||||
|
OPTS.word_size,
|
||||||
|
OPTS.words_per_row,
|
||||||
|
self.sram.width * self.sram.height,
|
||||||
|
process_transform[self.process],
|
||||||
|
self.vdd_voltage,
|
||||||
|
self.temperature]
|
||||||
|
|
||||||
|
self.create_measurement_names()
|
||||||
|
models = self.train_models()
|
||||||
|
|
||||||
|
# Set delay/power for slews and loads
|
||||||
|
port_data = self.get_empty_measure_data_dict()
|
||||||
|
debug.info(1, 'Slew, Load, Port, Delay(ns), Slew(ns)')
|
||||||
|
max_delay = 0.0
|
||||||
|
for slew in slews:
|
||||||
|
for load in loads:
|
||||||
|
# List returned with value order being delay, power, leakage, slew
|
||||||
|
sram_vals = self.get_predictions(model_inputs+[slew, load], models)
|
||||||
|
# Delay is only calculated on a single port and replicated for now.
|
||||||
|
for port in self.all_ports:
|
||||||
|
port_data[port]['delay_lh'].append(sram_vals['delay_lh'])
|
||||||
|
port_data[port]['delay_hl'].append(sram_vals['delay_hl'])
|
||||||
|
port_data[port]['slew_lh'].append(sram_vals['slew_lh'])
|
||||||
|
port_data[port]['slew_hl'].append(sram_vals['slew_hl'])
|
||||||
|
|
||||||
|
port_data[port]['write1_power'].append(sram_vals['write1_power'])
|
||||||
|
port_data[port]['write0_power'].append(sram_vals['write0_power'])
|
||||||
|
port_data[port]['read1_power'].append(sram_vals['read1_power'])
|
||||||
|
port_data[port]['read0_power'].append(sram_vals['read0_power'])
|
||||||
|
|
||||||
|
# Disabled power not modeled. Copied from other power predictions
|
||||||
|
port_data[port]['disabled_write1_power'].append(sram_vals['write1_power'])
|
||||||
|
port_data[port]['disabled_write0_power'].append(sram_vals['write0_power'])
|
||||||
|
port_data[port]['disabled_read1_power'].append(sram_vals['read1_power'])
|
||||||
|
port_data[port]['disabled_read0_power'].append(sram_vals['read0_power'])
|
||||||
|
|
||||||
|
debug.info(1, '{}, {}, {}, {}, {}'.format(slew,
|
||||||
|
load,
|
||||||
|
port,
|
||||||
|
sram_vals['delay_lh'],
|
||||||
|
sram_vals['slew_lh']))
|
||||||
|
# Estimate the period as double the delay with margin
|
||||||
|
period_margin = 0.1
|
||||||
|
sram_data = {"min_period": sram_vals['delay_lh'] * 2,
|
||||||
|
"leakage_power": sram_vals["leakage_power"]}
|
||||||
|
|
||||||
|
debug.info(2, "SRAM Data:\n{}".format(sram_data))
|
||||||
|
debug.info(2, "Port Data:\n{}".format(port_data))
|
||||||
|
|
||||||
|
return (sram_data, port_data)
|
||||||
|
|
||||||
|
def get_predictions(self, model_inputs, models):
|
||||||
|
"""
|
||||||
|
Generate a model and prediction for LIB output
|
||||||
|
"""
|
||||||
|
|
||||||
|
#Scaled the inputs using first data file as a reference
|
||||||
|
data_name = lib_dnames[0]
|
||||||
|
scaled_inputs = np.asarray([scale_input_datapoint(model_inputs, data_paths[data_name])])
|
||||||
|
|
||||||
|
predictions = {}
|
||||||
|
for dname in data_paths.keys():
|
||||||
|
path = data_paths[dname]
|
||||||
|
m = models[dname]
|
||||||
|
|
||||||
|
features, labels = get_scaled_data(path)
|
||||||
|
scaled_pred = self.model_prediction(m, scaled_inputs)
|
||||||
|
pred = unscale_data(scaled_pred.tolist(), path)
|
||||||
|
debug.info(2,"Unscaled Prediction = {}".format(pred))
|
||||||
|
predictions[dname] = pred[0][0]
|
||||||
|
return predictions
|
||||||
|
|
||||||
|
def train_models(self):
|
||||||
|
"""
|
||||||
|
Generate and return models
|
||||||
|
"""
|
||||||
|
models = {}
|
||||||
|
for dname, dpath in data_paths.items():
|
||||||
|
features, labels = get_scaled_data(dpath)
|
||||||
|
model = self.generate_model(features, labels)
|
||||||
|
models[dname] = model
|
||||||
|
return models
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
@ -39,6 +39,21 @@ class simulation():
|
||||||
else:
|
else:
|
||||||
self.num_wmasks = 0
|
self.num_wmasks = 0
|
||||||
|
|
||||||
|
def create_measurement_names(self):
|
||||||
|
""" Create measurement names. The names themselves currently define the type of measurement """
|
||||||
|
|
||||||
|
self.delay_meas_names = ["delay_lh", "delay_hl", "slew_lh", "slew_hl"]
|
||||||
|
self.power_meas_names = ["read0_power",
|
||||||
|
"read1_power",
|
||||||
|
"write0_power",
|
||||||
|
"write1_power",
|
||||||
|
"disabled_read0_power",
|
||||||
|
"disabled_read1_power",
|
||||||
|
"disabled_write0_power",
|
||||||
|
"disabled_write1_power"]
|
||||||
|
# self.voltage_when_names = ["volt_bl", "volt_br"]
|
||||||
|
# self.bitline_delay_names = ["delay_bl", "delay_br"]
|
||||||
|
|
||||||
def set_corner(self, corner):
|
def set_corner(self, corner):
|
||||||
""" Set the corner values """
|
""" Set the corner values """
|
||||||
self.corner = corner
|
self.corner = corner
|
||||||
|
|
@ -92,6 +107,32 @@ class simulation():
|
||||||
self.cycle_comments = []
|
self.cycle_comments = []
|
||||||
self.fn_cycle_comments = []
|
self.fn_cycle_comments = []
|
||||||
|
|
||||||
|
def set_probe(self, probe_address, probe_data):
|
||||||
|
"""
|
||||||
|
Probe address and data can be set separately to utilize other
|
||||||
|
functions in this characterizer besides analyze.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.probe_address = probe_address
|
||||||
|
self.probe_data = probe_data
|
||||||
|
self.bitline_column = self.get_data_bit_column_number(probe_address, probe_data)
|
||||||
|
self.wordline_row = self.get_address_row_number(probe_address)
|
||||||
|
|
||||||
|
def get_data_bit_column_number(self, probe_address, probe_data):
|
||||||
|
"""Calculates bitline column number of data bit under test using bit position and mux size"""
|
||||||
|
|
||||||
|
if self.sram.col_addr_size>0:
|
||||||
|
col_address = int(probe_address[0:self.sram.col_addr_size], 2)
|
||||||
|
else:
|
||||||
|
col_address = 0
|
||||||
|
bl_column = int(self.sram.words_per_row * probe_data + col_address)
|
||||||
|
return bl_column
|
||||||
|
|
||||||
|
def get_address_row_number(self, probe_address):
|
||||||
|
"""Calculates wordline row number of data bit under test using address and column mux size"""
|
||||||
|
|
||||||
|
return int(probe_address[self.sram.col_addr_size:], 2)
|
||||||
|
|
||||||
def add_control_one_port(self, port, op):
|
def add_control_one_port(self, port, op):
|
||||||
"""Appends control signals for operation to a given port"""
|
"""Appends control signals for operation to a given port"""
|
||||||
# Determine values to write to port
|
# Determine values to write to port
|
||||||
|
|
@ -544,6 +585,21 @@ class simulation():
|
||||||
for i in range(len(bl_names)):
|
for i in range(len(bl_names)):
|
||||||
bl_names[i] = bl_names[i].split('.')[-1]
|
bl_names[i] = bl_names[i].split('.')[-1]
|
||||||
return bl_names[0], bl_names[1]
|
return bl_names[0], bl_names[1]
|
||||||
|
|
||||||
|
def get_empty_measure_data_dict(self):
|
||||||
|
"""Make a dict of lists for each type of delay and power measurement to append results to"""
|
||||||
|
|
||||||
|
measure_names = self.delay_meas_names + self.power_meas_names
|
||||||
|
# Create list of dicts. List lengths is # of ports. Each dict maps the measurement names to lists.
|
||||||
|
measure_data = [{mname: [] for mname in measure_names} for i in self.all_ports]
|
||||||
|
return measure_data
|
||||||
|
|
||||||
|
def sum_delays(self, delays):
|
||||||
|
"""Adds the delays (delay_data objects) so the correct slew is maintained"""
|
||||||
|
|
||||||
|
delay = delays[0]
|
||||||
|
for i in range(1, len(delays)):
|
||||||
|
delay+=delays[i]
|
||||||
|
return delay
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
@ -312,12 +312,12 @@ class stimuli():
|
||||||
cmd = "{0} {1} -c {2}xa.cfg -o {2}xa -mt {3}".format(OPTS.spice_exe,
|
cmd = "{0} {1} -c {2}xa.cfg -o {2}xa -mt {3}".format(OPTS.spice_exe,
|
||||||
temp_stim,
|
temp_stim,
|
||||||
OPTS.openram_temp,
|
OPTS.openram_temp,
|
||||||
OPTS.num_threads)
|
OPTS.num_sim_threads)
|
||||||
valid_retcode=0
|
valid_retcode=0
|
||||||
elif OPTS.spice_name == "hspice":
|
elif OPTS.spice_name == "hspice":
|
||||||
# TODO: Should make multithreading parameter a configuration option
|
# TODO: Should make multithreading parameter a configuration option
|
||||||
cmd = "{0} -mt {1} -i {2} -o {3}timing".format(OPTS.spice_exe,
|
cmd = "{0} -mt {1} -i {2} -o {3}timing".format(OPTS.spice_exe,
|
||||||
OPTS.num_threads,
|
OPTS.num_sim_threads,
|
||||||
temp_stim,
|
temp_stim,
|
||||||
OPTS.openram_temp)
|
OPTS.openram_temp)
|
||||||
valid_retcode=0
|
valid_retcode=0
|
||||||
|
|
@ -326,7 +326,7 @@ class stimuli():
|
||||||
# Measurements can't be made with a raw file set in ngspice
|
# Measurements can't be made with a raw file set in ngspice
|
||||||
# -r {2}timing.raw
|
# -r {2}timing.raw
|
||||||
ng_cfg = open("{}.spiceinit".format(OPTS.openram_temp), "w")
|
ng_cfg = open("{}.spiceinit".format(OPTS.openram_temp), "w")
|
||||||
ng_cfg.write("set num_threads={}\n".format(OPTS.num_threads))
|
ng_cfg.write("set num_threads={}\n".format(OPTS.num_sim_threads))
|
||||||
ng_cfg.close()
|
ng_cfg.close()
|
||||||
|
|
||||||
cmd = "{0} -b -o {2}timing.lis {1}".format(OPTS.spice_exe,
|
cmd = "{0} -b -o {2}timing.lis {1}".format(OPTS.spice_exe,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
@ -28,7 +28,11 @@ class datasheet():
|
||||||
# css styling is kept in a seperate file
|
# css styling is kept in a seperate file
|
||||||
self.html += datasheet_css.read()
|
self.html += datasheet_css.read()
|
||||||
|
|
||||||
with open(OPTS.openram_temp + "/datasheet.info") as info:
|
if OPTS.output_datasheet_info:
|
||||||
|
datasheet_path = OPTS.output_path
|
||||||
|
else:
|
||||||
|
datasheet_path = OPTS.openram_temp
|
||||||
|
with open(datasheet_path + "/datasheet.info") as info:
|
||||||
self.html += '<!--'
|
self.html += '<!--'
|
||||||
for row in info:
|
for row in info:
|
||||||
self.html += row
|
self.html += row
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
@ -633,13 +633,16 @@ def parse_characterizer_csv(f, pages):
|
||||||
class datasheet_gen():
|
class datasheet_gen():
|
||||||
def datasheet_write(name):
|
def datasheet_write(name):
|
||||||
"""writes the datasheet to a file"""
|
"""writes the datasheet to a file"""
|
||||||
in_dir = OPTS.openram_temp
|
if OPTS.output_datasheet_info:
|
||||||
|
datasheet_path = OPTS.output_path
|
||||||
|
else:
|
||||||
|
datasheet_path = OPTS.openram_temp
|
||||||
|
|
||||||
if not (os.path.isdir(in_dir)):
|
if not (os.path.isdir(datasheet_path)):
|
||||||
os.mkdir(in_dir)
|
os.mkdir(datasheet_path)
|
||||||
|
|
||||||
datasheets = []
|
datasheets = []
|
||||||
parse_characterizer_csv(in_dir + "/datasheet.info", datasheets)
|
parse_characterizer_csv(datasheet_path + "/datasheet.info", datasheets)
|
||||||
|
|
||||||
for sheets in datasheets:
|
for sheets in datasheets:
|
||||||
with open(name, 'w+') as f:
|
with open(name, 'w+') as f:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ word_size = 32
|
||||||
num_words = 256
|
num_words = 256
|
||||||
write_size = 8
|
write_size = 8
|
||||||
|
|
||||||
local_array_size = 16
|
#local_array_size = 16
|
||||||
|
|
||||||
num_rw_ports = 1
|
num_rw_ports = 1
|
||||||
num_r_ports = 1
|
num_r_ports = 1
|
||||||
|
|
@ -11,9 +11,9 @@ num_w_ports = 0
|
||||||
tech_name = "sky130"
|
tech_name = "sky130"
|
||||||
nominal_corner_only = True
|
nominal_corner_only = True
|
||||||
|
|
||||||
route_supplies = False
|
#route_supplies = False
|
||||||
check_lvsdrc = True
|
check_lvsdrc = True
|
||||||
perimeter_pins = False
|
#perimeter_pins = False
|
||||||
#netlist_only = True
|
#netlist_only = True
|
||||||
#analytical_delay = False
|
#analytical_delay = False
|
||||||
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
|
output_name = "sram_{0}rw{1}r{2}w_{3}_{4}_{5}".format(num_rw_ports,
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
@ -18,6 +18,9 @@ import sys
|
||||||
import re
|
import re
|
||||||
import copy
|
import copy
|
||||||
import importlib
|
import importlib
|
||||||
|
import getpass
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
VERSION = "1.1.9"
|
VERSION = "1.1.9"
|
||||||
NAME = "OpenRAM v{}".format(VERSION)
|
NAME = "OpenRAM v{}".format(VERSION)
|
||||||
|
|
@ -133,8 +136,9 @@ def print_banner():
|
||||||
debug.print_raw("|=========" + user_info.center(60) + "=========|")
|
debug.print_raw("|=========" + user_info.center(60) + "=========|")
|
||||||
dev_info = "Development help: openram-dev-group@ucsc.edu"
|
dev_info = "Development help: openram-dev-group@ucsc.edu"
|
||||||
debug.print_raw("|=========" + dev_info.center(60) + "=========|")
|
debug.print_raw("|=========" + dev_info.center(60) + "=========|")
|
||||||
temp_info = "Temp dir: {}".format(OPTS.openram_temp)
|
if OPTS.openram_temp:
|
||||||
debug.print_raw("|=========" + temp_info.center(60) + "=========|")
|
temp_info = "Temp dir: {}".format(OPTS.openram_temp)
|
||||||
|
debug.print_raw("|=========" + temp_info.center(60) + "=========|")
|
||||||
debug.print_raw("|=========" + "See LICENSE for license info".center(60) + "=========|")
|
debug.print_raw("|=========" + "See LICENSE for license info".center(60) + "=========|")
|
||||||
debug.print_raw("|==============================================================================|")
|
debug.print_raw("|==============================================================================|")
|
||||||
|
|
||||||
|
|
@ -154,6 +158,17 @@ def check_versions():
|
||||||
# or, this could be done in each module (e.g. verify, characterizer, etc.)
|
# or, this could be done in each module (e.g. verify, characterizer, etc.)
|
||||||
global OPTS
|
global OPTS
|
||||||
|
|
||||||
|
def cmd_exists(cmd):
|
||||||
|
return subprocess.call("type " + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0
|
||||||
|
|
||||||
|
if cmd_exists("coverage"):
|
||||||
|
OPTS.coverage_exe = "coverage run -p "
|
||||||
|
elif cmd_exists("python3-coverage"):
|
||||||
|
OPTS.coverage_exe = "python3-coverage run -p "
|
||||||
|
else:
|
||||||
|
OPTS.coverage_exe = ""
|
||||||
|
debug.warning("Failed to find coverage installation. This can be installed with pip3 install coverage")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import coverage
|
import coverage
|
||||||
OPTS.coverage = 1
|
OPTS.coverage = 1
|
||||||
|
|
@ -406,7 +421,7 @@ def setup_paths():
|
||||||
# Add all of the subdirs to the python path
|
# Add all of the subdirs to the python path
|
||||||
# These subdirs are modules and don't need
|
# These subdirs are modules and don't need
|
||||||
# to be added: characterizer, verify
|
# to be added: characterizer, verify
|
||||||
subdirlist = [ item for item in os.listdir(OPENRAM_HOME) if os.path.isdir(os.path.join(OPENRAM_HOME, item)) ]
|
subdirlist = [item for item in os.listdir(OPENRAM_HOME) if os.path.isdir(os.path.join(OPENRAM_HOME, item))]
|
||||||
for subdir in subdirlist:
|
for subdir in subdirlist:
|
||||||
full_path = "{0}/{1}".format(OPENRAM_HOME, subdir)
|
full_path = "{0}/{1}".format(OPENRAM_HOME, subdir)
|
||||||
debug.check(os.path.isdir(full_path),
|
debug.check(os.path.isdir(full_path),
|
||||||
|
|
@ -414,6 +429,10 @@ def setup_paths():
|
||||||
if "__pycache__" not in full_path:
|
if "__pycache__" not in full_path:
|
||||||
sys.path.append("{0}".format(full_path))
|
sys.path.append("{0}".format(full_path))
|
||||||
|
|
||||||
|
# Use a unique temp subdirectory
|
||||||
|
OPTS.openram_temp += "/openram_{0}_{1}_temp/".format(getpass.getuser(),
|
||||||
|
os.getpid())
|
||||||
|
|
||||||
if not OPTS.openram_temp.endswith('/'):
|
if not OPTS.openram_temp.endswith('/'):
|
||||||
OPTS.openram_temp += "/"
|
OPTS.openram_temp += "/"
|
||||||
debug.info(1, "Temporary files saved in " + OPTS.openram_temp)
|
debug.info(1, "Temporary files saved in " + OPTS.openram_temp)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California
|
# Copyright (c) 2016-2021 Regents of the University of California
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
from bitcell_base_array import bitcell_base_array
|
from bitcell_base_array import bitcell_base_array
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2016-2019 Regents of the University of California and The Board
|
# Copyright (c) 2016-2021 Regents of the University of California and The Board
|
||||||
# of Regents for the Oklahoma Agricultural and Mechanical College
|
# of Regents for the Oklahoma Agricultural and Mechanical College
|
||||||
# (acting for and on behalf of Oklahoma State University)
|
# (acting for and on behalf of Oklahoma State University)
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue