Browse Source

cleaner docs, sim perf

main
stefan 3 weeks ago
parent
commit
5ba1f11d1d
  1. 15
      README.md
  2. 19
      main.py

15
README.md

@ -3,6 +3,8 @@
PPSFP (Parallel-Pattern Single-Fault Propagation) style fault simulators and other utility functions for use in various projects. PPSFP (Parallel-Pattern Single-Fault Propagation) style fault simulators and other utility functions for use in various projects.
These fault simulators are meant to be correct (ensured by unit-tests) and reasonably fast. These fault simulators are meant to be correct (ensured by unit-tests) and reasonably fast.
Fault simulation has $O(n^3)$ complexity. Every *fault* is simulated with every *pattern* involving every combinational *gate* in the circuit. We measure performance in terms of `gates * faults * patterns / second`. How fast can we make it?
## Quick Start ## Quick Start
This project has submodules. To ensure everything is up-to-date, run This project has submodules. To ensure everything is up-to-date, run
@ -15,9 +17,15 @@ This project manages reproducible programming environments with:
- [uv](https://docs.astral.sh/uv/) for managing python environments. - [uv](https://docs.astral.sh/uv/) for managing python environments.
- [nix](https://nixos.org) for managing non-python tools and benchmark designs. Follow [this guide](https://librelane.readthedocs.io/en/stable/installation/nix_installation/index.html) or [this guide](https://github.com/fossi-foundation/nix-eda/blob/main/docs/installation.md) to setup [nix-eda](https://github.com/fossi-foundation/nix-eda/tree/main) binary cache to avoid re-building EDA-related tools. - [nix](https://nixos.org) for managing non-python tools and benchmark designs. Follow [this guide](https://librelane.readthedocs.io/en/stable/installation/nix_installation/index.html) or [this guide](https://github.com/fossi-foundation/nix-eda/blob/main/docs/installation.md) to setup [nix-eda](https://github.com/fossi-foundation/nix-eda/tree/main) binary cache to avoid re-building EDA-related tools.
Smoke-test: `uv run pytest` Run all unit-tests: `uv run pytest`
Run a naive, baseline fault simulation with 1024 random patterns: `uv run main.py tests/c6288.bench`
For running Jupyter Notebooks in the reproducible programming environment, install a kernelspec with this command: Same on an 18k-gate circuit: `uv run main.py polito-itc99-b15-sky130`
`nix develop` makes [quaigh](https://github.com/coloquinte/quaigh) available, another simulator/atpg written in rust.
To run Jupyter Notebooks in the reproducible programming environment, install a kernelspec:
``` ```
uv run ipython kernel install --user --env VIRTUAL_ENV $(pwd)/.venv --env PATH ${PATH} --name=uv-env uv run ipython kernel install --user --env VIRTUAL_ENV $(pwd)/.venv --env PATH ${PATH} --name=uv-env
``` ```
@ -27,8 +35,7 @@ uv run jupyter lab
``` ```
Choose `uv-env` as kernel in Jupyter Lab. Choose `uv-env` as kernel in Jupyter Lab.
`uv run main.py <circuit>` runs a naive, baseline fault simulation.
`nix develop` makes [quaigh](https://github.com/coloquinte/quaigh) available, another simulator/atpg written in rust.

19
main.py

@ -2,6 +2,7 @@
import argparse import argparse
import subprocess import subprocess
from pathlib import Path from pathlib import Path
import time
import numpy as np import numpy as np
@ -13,11 +14,11 @@ from fsim.static import LineRoles, FaultSet
def main(): def main():
parser = argparse.ArgumentParser(description='Fault Stats') parser = argparse.ArgumentParser(description='A basic stuck-at fault simulator.')
parser.add_argument('-t', '--tlib', default='SKY130', help=f'techlib of circuit. default: SKY130, available: {sorted(techlib_by_name.keys())}.') parser.add_argument('-t', '--tlib', default='SKY130', help=f'Techlib for verilog circuit. Default: SKY130, available: {sorted(techlib_by_name.keys())}.')
parser.add_argument('-p', '--patterns', default=1024, help='Number of random patterns to simulate.') parser.add_argument('-p', '--patterns', default=1024, help='Number of random patterns to simulate. Default: 1024.')
parser.add_argument('--seed', type=int, default=42, help='Random seed for reproducibility (default: 42).') parser.add_argument('--seed', type=int, default=42, help='Random seed for reproducibility. Default: 42.')
parser.add_argument('circuit', help='gate-level verilog file or nix package to import. See "nix flake show github:s-holst/benchmark-circuits" for available packages.') parser.add_argument('circuit', help='Gate-level verilog, bench, or nix package to import. See available packages: "nix flake show github:s-holst/benchmark-circuits".')
args = parser.parse_args() args = parser.parse_args()
args.patterns = int(args.patterns) args.patterns = int(args.patterns)
args.tlib = techlib_by_name[args.tlib] args.tlib = techlib_by_name[args.tlib]
@ -75,6 +76,8 @@ def main():
undetected = set() undetected = set()
detected = set() detected = set()
start_time = time.perf_counter()
with log.progress() as p: with log.progress() as p:
for fidx, fault in enumerate(injection_faults): for fidx, fault in enumerate(injection_faults):
fault_site = fault//2 fault_site = fault//2
@ -91,7 +94,11 @@ def main():
else: else:
detected.add(fault) detected.add(fault)
log.info(f'detected by simulation: {len(detected)}/{len(injection_faults)} - {len(detected)/len(injection_faults)*100:.1f}%') sim_time = time.perf_counter() - start_time
log.info(f'fsim time: {sim_time:.2f}s')
sim_performance = stats['comb'] * len(injection_faults) * patterns.shape[1] / sim_time
log.info(f'fsim performance: {sim_performance:.2e} gfp/s')
log.info(f'detected by simulation: {len(detected)}/{len(injection_faults)} - {len(detected)/len(injection_faults)*100:.2f}%')
if __name__ == "__main__": if __name__ == "__main__":
main() main()
Loading…
Cancel
Save