Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GSoC] Common Python Simulation module #226

Merged
merged 37 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
321806a
feat: added a simulation module
harshkhandeparkar Jul 27, 2023
5377c45
fix: fixed multiple bugs in simulation.py
harshkhandeparkar Jul 27, 2023
b7fae70
feat: multithreaded improvements for simulation module
harshkhandeparkar Jul 27, 2023
e0feb35
fix: many bug fixes
harshkhandeparkar Jul 27, 2023
f53736a
refactor: split simulation module into multiple files
harshkhandeparkar Jul 27, 2023
0d8571f
feat: allow different types of parameters in simulation
harshkhandeparkar Jul 28, 2023
3d82f29
feat: added numeric parameter (start, end, step)
harshkhandeparkar Aug 3, 2023
b1bdc1b
docs: added docs for the simulation module
harshkhandeparkar Aug 5, 2023
1667902
docs: added docs for simulation_run.py
harshkhandeparkar Aug 5, 2023
c653620
feat: added support for xyce and finesim
harshkhandeparkar Aug 5, 2023
54e8fcd
feat: remove existing run directories
harshkhandeparkar Aug 5, 2023
e5c86c5
feat: read simulation temp range from test.json
harshkhandeparkar Aug 5, 2023
5df02d9
fix: used rmtree instead of rmdir
harshkhandeparkar Aug 5, 2023
4592e19
feat: used the new simulation module in temp-sense-gen
harshkhandeparkar Aug 5, 2023
52a956e
refactor: simplified temp-sense-gen python code
harshkhandeparkar Aug 5, 2023
24a4c2e
refactor: simplified simulation.py
harshkhandeparkar Aug 5, 2023
6d5e0dd
refactor: removed unused modules in temp-sense-gen
harshkhandeparkar Aug 5, 2023
74a93bc
refactor: simplified temp-sense-gen.py
harshkhandeparkar Aug 5, 2023
e22a087
feat: gitignored simulations
harshkhandeparkar Aug 5, 2023
61e4336
feat: return the number of simulations run
harshkhandeparkar Aug 6, 2023
62257ab
fix: removed whitespace from sim log files
harshkhandeparkar Aug 6, 2023
3b1ffed
feat: changed temperature range back to original
harshkhandeparkar Aug 6, 2023
f9f7ed3
feat: fixed and updated simulation result generation
harshkhandeparkar Aug 6, 2023
1aae288
feat: print the average time per simulation
harshkhandeparkar Aug 6, 2023
adf0d88
fix: fixed errors in simulation_result.py
harshkhandeparkar Aug 6, 2023
f9367ff
docs: updated docstring for top level common module
harshkhandeparkar Aug 9, 2023
233e255
fix: fixed types in temp sensor simulations
harshkhandeparkar Aug 9, 2023
758ed4b
docs: fixed typo in simulation module
harshkhandeparkar Aug 9, 2023
4894285
docs: fixed the default sim tool typo
harshkhandeparkar Aug 9, 2023
70af3be
docs: added sphinx documentation for the simulation module
harshkhandeparkar Aug 9, 2023
661591b
test: added regression tests for the simulation module.
harshkhandeparkar Aug 14, 2023
5d82ae4
fix: replaced match case with if else statements
harshkhandeparkar Aug 16, 2023
e5e61d7
fix: keep track of failed simulations
harshkhandeparkar Aug 17, 2023
eb17120
fix: install ngspice for python unit tests
harshkhandeparkar Aug 17, 2023
e47d8db
fix: capture simulation output so it doesn't show in the terminal
harshkhandeparkar Aug 22, 2023
e8a3a8d
docs: added top-level docstrings for simulation module
harshkhandeparkar Sep 7, 2023
8297c83
refactor: renamed python test workflow
harshkhandeparkar Sep 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
name: Lint and Test
name: Lint and Test Python API
# https://docs.github.com/en/free-pro-team@latest/actions/guides/building-and-testing-python

on:
Expand Down Expand Up @@ -34,6 +34,7 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
sudo apt install -y ngspice
python -m pip install --upgrade pip
pip install -r requirements.txt
# pip install .
Expand Down
123 changes: 122 additions & 1 deletion docs/source/common-python-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,125 @@ Constants
^^^^^^^^^
1. ``COMMON_PLATFORMS_PREFIX_MAP``

This is a dictionary of common platforms (currently sky130) and their cell naming prefixes. See the ``cell()`` def in the ``generate_verilog()`` function for more information on how to use it.
This is a dictionary of common platforms (currently sky130) and their cell naming prefixes. See the ``cell()`` def in the ``generate_verilog()`` function for more information on how to use it.

2. Simulation (``common.simulation``)
#####################################################
This module exports functions used to simulate SPICE testbenches with multiple parameters.

This module supports the use of `Mako <https://www.makotemplates.org/>`_ templating library to insert parameters into SPICE templates.

Functions
^^^^^^^^^
1. ``run_simulations(parameters: dict, platform: str, simulation_dir: str, template_path: str, runs_dir: str, sim_tool: str, num_concurrent_sims: int, netlist_path: str) -> int``

Generates configurations of all combinations of the given ``parameters`` and runs simulations for each case. The testbench SPICE file, configuration parameters, and the ouptut for each run are generated in ``{simulation_dir}/{runs_dir}``.

The testbench SPICE file given by ``template_path`` follows the `Mako <https://makotemplates.org>`_ templating syntax. Use the ``${parameter}`` syntax for inserting parameters in the file. The following parameters are automatically inserted during each run.

- ``run_number`` (int): The number/index of the run/configuration.
- ``sim_tool`` (str): Command for the simulation tool used.
- ``platform`` (str): The platform/PDK.
- ``template`` (str): Path to the SPICE testbench template.
- ``netlist_path`` (str): Absolute path to the SPICE netlist of the design to be simulated.

Example SPICE template: (From the `Temperature Sensor Generator <flow-tempsense.html>`_)
.. code-block:: spice

.lib '${model_file}' ${model_corner}
.include '${netlist_path}'

.param temp_var = ${temp}
.param vvdd = 1.8
.param sim_end = '800m/exp(0.04*temp_var)'

Each configuration is run/simulated in a directory in the ``runs_dir``. Each run directory contains the final SPICE testbench with the parameters inserted, a ``parameters.txt`` file containing the values of each parameter, and the output log file.

``parameters`` is a dict with keys corresponding to the parameter's name and the values of one of the following types.

1. A constant value.
The value of this parameter will be the same for every configuration/run.
.. code-block:: python

{'param': 'value'}

2. Array of integer/float/string constants.
Each of the values in the array will be swept.
.. code-block:: python

{'param': [1, 2, 3, 8]}
# OR
{
'param': {
'values': [1, 2, 3, 8]
}
}

3. Increments.
All values starting from ``start`` (included) and ending at ``end`` (included if it is ``start + n * step``) will be swept with a step of ``step``. The default value for ``step`` is ``1``.
.. code-block:: python

{'param': {
'start': 10,
'end': 50,
'step': 10
}}
# param will take values 10, 20, 30, 40, 50

Example parameters:
.. code-block:: python

# Runs 10 total simulations
# Sweeps through all temperatures from 10 to 100 (both included) with increments of 10.
example1 = {
'temp': {'start': 10, 'end': 100, 'step': 10}
}

# Runs 9 total simulations
# Sweeps through all the 3 input voltages as well as all the 3 temperatures
example2 = {
'input_voltage': [1, 2, 3],
'temp': [20, 30, 40]
}

# Runs 4 total simulations
# Duty cycle and aux_spice_path remain the same in all simulations
# input_voltage is swept
example3 = {
'duty_cycle': 10,
'aux_spice_path': 'auxcell.cdl',
'input_voltage': [1, 2, 3]
}

See the generators' Python files in ``tools/`` for more examples.

Arguments:
- ``parameters`` (dict): Dictionary of parameters. Explained above.
- ``platform`` (str): Platform/PDK. (eg: ``sky130hd```)
- ``simulation_dir`` (str): Path to the directory where the simulation source files are placed and the outputs will be generated. (Default: ``simulations``)
- ``template_path`` (str): Path to the SPICE template file for the testbench. (Default: ``templates/template.sp``)
- ``runs_dir`` (str): Path to a directory inside the ``simulation_dir`` directory where the outputs for the simulations will be generated. (Default: ``runs``)
- ``sim_tool`` (str): Command for the simulation tool. ``ngspice``, ``xyce``, and ``finesim`` are supported. (Default: ``ngspice``)
- ``num_concurrent_sims`` (int): The maximum number of concurrent simulations. (Default: ``4``)
- ``netlist_path`` (str): Path to the SPICE netlist inside the ``simulation_dir`` of the design to be simulated. (Default: ``netlist.sp``)

**Returns (int)**: The total number of simulations run.

Overall example: (From the `Temperature Sensor Generator <flow-tempsense.html>`_)
.. code-block:: python

run_simulations(
parameters={
'temp': {'start': tempStart, 'end': tempStop, 'step': tempStep},
'model_file': model_file,
'model_corner': platformConfig['model_corner'],
'nominal_voltage': platformConfig['nominal_voltage'],
'design_name': designName
},
platform="sky130hd",
simulation_dir="simulations",
template_path=os.path.join("templates", f"tempsenseInst_{simTool}.sp"),
runs_dir=f"run/prePEX_inv{num_inv}_header{num_header}/",
sim_tool=simTool,
netlist_path=dstNetlist
)
2 changes: 2 additions & 0 deletions openfasoc/generators/common/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
- `common.verilog_generation`
1. `generate_verilog(parameters: dict, src_dir: str, out_dir: str) -> None`: Used to generate synthesizable Verilog files (for OpenROAD flow) from source Mako-based Verilog templates.
2. `COMMON_PLATFORMS_PREFIX_MAP` (dict): This is a dictionary of common platforms (currently sky130) and their cell naming prefixes.
- `common.simulation`
1. `run_simulations()`: Used to run SPICE testbenches with multiple parameters.

See individual function documentation for more information on a particular function.
"""
104 changes: 104 additions & 0 deletions openfasoc/generators/common/simulation/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
"""A common simulation used in OpenFASOC generators.

Sweeps all combinations of given parameters and runs parallel SPICE simulations with different configurations based on the parameters.

Exported functions:
- `run_simulations()`
"""

from os import path, makedirs
from common.simulation.simulation_config import _generate_configs
from common.simulation.simulation_run import _run_simulations

def run_simulations(
parameters: dict,
platform: str,
simulation_dir: str = "simulations",
template_path: str = path.join("templates", "template.sp"),
runs_dir: str = "runs",
sim_tool: str = "ngspice",
num_concurrent_sims: int = 4,
netlist_path: str = "netlist.sp"
) -> int:
"""Runs SPICE simulations.

Generates configurations of all combinations of the given `parameters` and simulates each case. The testbench SPICE file, configuration parameters, and the output for each run are generated in the `simulation_dir/runs_dir` directory.

The testbench SPICE file given by `template_path` follows the [Mako](https://makotemplates.org) templating syntax. Use the `${parameter}` syntax for inserting parameters in the file. The following parameters are automatically inserted during each run.
- `run_number` (int): The number/index of the run/configuration.
- `sim_tool` (str): Command for the simulation tool used.
- `platform` (str): The platform/PDK.
- `template` (str): Path to the SPICE testbench template.
- `netlist_path` (str): Absolute path to the SPICE netlist of the design to be simulated.

Each configuration is run/simulated in a directory in the `runs_dir`. Each run directory contains the final SPICE testbench with the parameters inserted, a `parameters.txt` file containing the values of each parameter, and the output log file.

`parameters` is a dict with keys corresponding to the parameter's name and the values of one of the following types.
1. A constant value.
The value of this parameter will be the same for every configuration/run.
```
{'param': 'value'}
```

2. Array of integer/float/string constants.
Each of the values in the array will be swept.
```
{'param': [1, 2, 3, 8]}
# OR
{
'param': {
'values': [1, 2, 3, 8]
}
}
```

3. Increments.
All values starting from `start` and ending at `end` will be swept with a step of `step`. The default value for `step` is `1`.
```
{'param': {
'start': 10,
'end': 50,
'step': 10
}}
# param will take values 10, 20, 30, 40, 50
```

Arguments:
- `parameters` (dict): Parameters used to generate the runs.
- `platform` (str): Platform/PDK.
- `simulation_dir` (str = "simulations"): Path to the directory where the simulation source files are placed and the outputs will be generated.
- `template_path` (str = "templates/template.sp"): Path to the SPICE template file for the testbench. (The template is a SPICE file with [Mako](https://makotemplates.org) templating syntax)
- `runs_dir` (str = "runs"): Path to a directory inside the `simulation_dir` directory where the outputs for the simulations will be generated.
- `sim_tool` (str = "ngspice"): Command for the simulation tool.
- `num_concurrent_sims` (int = 4): The maximum number of concurrent simulations.
- `netlist_path` (str = "netlist.sp"): Path to the SPICE netlist of the design to be simulated.

Returns (int): The number of simulations run.
"""

runs_dir_path = path.join(simulation_dir, runs_dir)
template = path.join(simulation_dir, template_path)

if not path.exists(runs_dir_path):
makedirs(runs_dir_path)

config_number = _generate_configs(
parameters=parameters,
sim_tool=sim_tool,
platform=platform,
template=template,
netlist_path=netlist_path,
runs_dir_path=runs_dir_path
)

print(f"Number of configurations: {config_number}")
print(f"Number of concurrent simulations: {num_concurrent_sims}")

_run_simulations(
num_configs=config_number,
num_concurrent_sims=num_concurrent_sims,
sim_tool=sim_tool,
runs_dir_path=runs_dir_path
)

return config_number
Loading
Loading