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

Store simulation result file, return sim state from run #270

Merged
merged 30 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
a8e6f77
Add statement to dump simulation state to file
chetanyagoyal Nov 9, 2023
33956c5
Create prePEX_sim_result
chetanyagoyal Nov 9, 2023
33bff42
Update test_simulation.py
chetanyagoyal Nov 9, 2023
f7a5a8b
Update test_simulation.py
chetanyagoyal Nov 9, 2023
683c198
Update test_simulation.py
chetanyagoyal Nov 9, 2023
5786c54
Update test_simulation.py
chetanyagoyal Nov 9, 2023
211fec8
return sim_state dict instead of num_configs
chetanyagoyal Nov 9, 2023
539609c
fix return variables and dump sim state
chetanyagoyal Nov 9, 2023
21abaaf
return dictionary of simulation state instead of null
chetanyagoyal Nov 9, 2023
afe5a03
Update test_simulation.py to account for changes to return types
chetanyagoyal Nov 9, 2023
4e69c4b
Merge branch 'idea-fasoc:main' into main
chetanyagoyal Nov 9, 2023
09d7d49
Merge branch 'idea-fasoc:main' into main
chetanyagoyal Nov 11, 2023
368cb35
Change return type from int to dict
chetanyagoyal Nov 11, 2023
f2209fe
Update simulation_run.py
chetanyagoyal Nov 11, 2023
4959c07
Remove whitespace
chetanyagoyal Nov 11, 2023
6c4812e
Merge branch 'idea-fasoc:main' into main
chetanyagoyal Nov 15, 2023
36dfb27
commit latest changes to make sims work
chetanyagoyal Nov 15, 2023
32244e4
update ngspice version check statement
chetanyagoyal Nov 15, 2023
6ee4229
revise function to include ngspice version here
chetanyagoyal Nov 15, 2023
da4ad4e
Update parse_rpt.py
chetanyagoyal Nov 15, 2023
2b573cd
fix errors
chetanyagoyal Nov 15, 2023
604967d
Format file
chetanyagoyal Nov 15, 2023
7449c31
Fix indent errors in file
chetanyagoyal Nov 15, 2023
ac0f657
Merge branch 'idea-fasoc:main' into main
chetanyagoyal Nov 30, 2023
b869fe2
Separate ngspice version and result file check
chetanyagoyal Nov 30, 2023
f3abf5e
Merge branch 'idea-fasoc:main' into main
chetanyagoyal Dec 5, 2023
35dc71d
change dir structure, make new job for temp-sense sims
chetanyagoyal Dec 5, 2023
1116b6b
add new comparison function for sim results
chetanyagoyal Dec 5, 2023
548f577
Merge branch 'idea-fasoc:main' into main
chetanyagoyal Dec 6, 2023
0a8fcad
revert change to ngspice clone command
chetanyagoyal Dec 8, 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
8 changes: 8 additions & 0 deletions .github/scripts/expected_sim_outputs/prePEX_sim_result
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Temp Frequency Power Error
chetanyagoyal marked this conversation as resolved.
Show resolved Hide resolved
-20.0 129.13698399282515 0.0001395741 0.0
0.0 812.2374949945864 0.000216328 -1.2889568113520866
20.0 3726.282213709738 0.000308484 -1.905159990787503
40.0 13548.077588756503 0.0004135831 -2.0993284842505844
60.0 40753.5328218765 0.0005294722 -1.884757884614622
80.0 104972.69292852504 0.0006544346 -1.288956811352108
100.0 238491.19025467758 0.0007871842 -0.3737931886616934
45 changes: 42 additions & 3 deletions .github/scripts/parse_rpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@
import json
import os
import re, subprocess
import warnings

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from common.get_ngspice_version import check_ngspice_version
from common.check_gen_files import check_gen_files

sys.stdout.flush()
Expand Down Expand Up @@ -102,11 +105,47 @@

## Result File Check
if _generator_is['sky130hvl_ldo']:
json_filename = "spec.json"
json_filename = "spec.json"
else:
json_filename = "test.json"
json_filename = "test.json"

if check_gen_files(json_filename, _generator_is, cryo_library):
print("Flow check is clean!")
print("Flow check is clean!")
else:
print("Flow check failed!")

if len(sys.argv) == 1:
sim_state_filename = "work/sim_state_file.txt"
result_filename = "work/prePEX_sim_result"

template_filename = "../../../.github/scripts/expected_sim_outputs/prePEX_sim_result"
with open(result_filename) as f2, open(template_filename) as f1:
content1 = f2.readlines()
content2 = f1.readlines()
if content1 != content2:
warnings.warn("Simulation result file does not match! Please contact a maintainer of the repo!", DeprecationWarning)

if check_ngspice_version() == 0:
warnings.warn("The ngspice version does not match, "
"frequency results might not match! "
"Please contact a maintainer of the repo.", DeprecationWarning)

sim_state = json.load(open("work/sim_state_file.txt"))
if sim_state["failed_sims"] != 0:
raise ValueError("Simulations failed: Non zero failed simulations!")

for folder_num in range(1, sim_state["completed_sims"] + 1):
dir_path = r'simulations/run/'
pex_path = os.listdir(dir_path)

file_name = "simulations/run/" + str(pex_path[0]) + "/" + str(folder_num) + "/"
param_file = file_name + "parameters.txt"
log_file = file_name + "sim_" + str(folder_num) + ".log"
spice_file = file_name + "sim_" + str(folder_num) + ".sp"

if os.path.exists(log_file) and os.path.exists(log_file) and os.path.exists(spice_file):
pass
else:
raise ValueError("Simulations failed: required of run folders do not exist!")

print("Simulations are clean!")
2 changes: 1 addition & 1 deletion .github/workflows/tempSense_sky130hd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
cp ./.github/scripts/parse_rpt.py ./openfasoc/generators/temp-sense-gen/. &&\
pip3 install -r requirements.txt &&\
cd ./openfasoc/generators/temp-sense-gen &&\
make sky130hd_temp &&\
make sky130hd_temp_full &&\
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest keeping flow till drc/lvs checks and the full flow till simulation checks separately. It would be easy to understand which part is failing instead of digging into the log files.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean that I should have one job with make .. and another job with make ..full?

python3 parse_rpt.py
" && exit_code=$? | tee -a file.log
if [ $? -ne 0 ]; then exit 1; fi
Expand Down
2 changes: 1 addition & 1 deletion dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ source ~/.bashrc
if cat /etc/os-release | grep "ubuntu" >> /dev/null
then
apt install bison flex libx11-dev libx11-6 libxaw7-dev libreadline6-dev autoconf libtool automake -y
git clone http://git.code.sf.net/p/ngspice/ngspice
git clone https://git.code.sf.net/p/ngspice/ngspice
currentver="$(lsb_release -rs)"
requiredver="22.04"
if [ $currentver == $requiredver ]
Expand Down
2 changes: 1 addition & 1 deletion docker/conda/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ RUN strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so

COPY ./scripts /scripts

RUN git clone http://git.code.sf.net/p/ngspice/ngspice && \
RUN git clone https://git.code.sf.net/p/ngspice/ngspice && \
cd ngspice && \
./compile_linux.sh
20 changes: 20 additions & 0 deletions openfasoc/generators/common/get_ngspice_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import subprocess
import re

def check_ngspice_version() -> int:
last_known_version = "41+"
result = subprocess.run(["ngspice", "--version"], capture_output=True, text=True)

if result.returncode == 0:
data = result.stdout.strip()
match = re.search(r'ngspice-(\S+)', data)

if match:
ngspice_version = match.group(1)
return ngspice_version == last_known_version
else:
print("Error parsing ngspice version.")
else:
print("Error getting ngspice version:", result.stderr)

return 0
8 changes: 4 additions & 4 deletions openfasoc/generators/common/simulation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def run_simulations(
sim_tool: str = "ngspice",
num_concurrent_sims: int = 4,
netlist_path: str = "netlist.sp"
) -> int:
) -> dict:
"""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.
Expand Down Expand Up @@ -73,7 +73,7 @@ def run_simulations(
- `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.
Returns : A dictionary containing the number of ongoing (ideally 0), completed and failed simulations.
"""

runs_dir_path = path.join(simulation_dir, runs_dir)
Expand All @@ -94,11 +94,11 @@ def run_simulations(
print(f"Number of configurations: {config_number}")
print(f"Number of concurrent simulations: {num_concurrent_sims}")

_run_simulations(
sim_state = _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
return sim_state
5 changes: 4 additions & 1 deletion openfasoc/generators/common/simulation/simulation_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ def _run_simulations(
- `num_concurrent_sims` (int): The maximum number of concurrent simulations.
- `sim_tool` (str): Path to the directory in which the simulation runs will be generated.
- `runs_dir_path` (str): Path to the directory in which the simulation runs will be generated.

Returns: `simulation_state`, the number of ongoing, completed and failed sims.
"""

simulation_state = {
Expand Down Expand Up @@ -68,6 +70,7 @@ def thread_on_exit(exit_status: int, state=simulation_state):
time.sleep(1)

_print_progress(num_configs, simulation_state['completed_sims'], simulation_state['failed_sims'], start_time, end='\n')
return simulation_state

def _run_config(
sim_tool: str,
Expand Down Expand Up @@ -148,4 +151,4 @@ def _threaded_run(
except:
return on_exit(1)

on_exit(0)
on_exit(0)
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ vVSS VSS 0 dc

c0 lc_out 0 1f

.if (temp_var <= 20)
.TRAN 1u 'sim_end'
.else
.TRAN 10n 'sim_end'
.endif

.meas tran period TRIG v(lc_out) td=10p val=1.0 rise=2
+ TARG v(lc_out) td=10p val=1.0 rise=3
Expand Down
12 changes: 8 additions & 4 deletions openfasoc/generators/temp-sense-gen/tools/simulation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import os
import os, json
import re
import shutil
import sys
Expand Down Expand Up @@ -57,7 +57,7 @@ def generate_runs(

update_netlist(srcNetlist, dstNetlist, jsonConfig["simMode"])

num_simulations = run_simulations(
sim_state = run_simulations(
parameters={
'temp': {'start': tempStart, 'end': tempStop, 'step': tempStep},
'model_file': model_file,
Expand All @@ -75,7 +75,7 @@ def generate_runs(

# Calculating simulation results and error
with open(os.path.join(runDirPath, 'sim_output'), 'w') as sim_output_file:
for i in range(num_simulations):
for i in range(sim_state["completed_sims"]):
log_file_path = os.path.join(runDirPath, f"{i + 1}", f"sim_{i + 1}.log")
sim_results = get_sim_results(open(log_file_path, "r").read())

Expand All @@ -86,6 +86,10 @@ def generate_runs(
error_data = calculate_sim_error(sim_output_lines=sim_output_file.readlines())
all_result_file.write("\n".join(error_data))

# dump final simulation state to log file called sim_state_file
with open(spiceDir + "/sim_state_file.txt", 'w') as sim_state_file:
json.dump(sim_state, sim_state_file)
chetanyagoyal marked this conversation as resolved.
Show resolved Hide resolved

return runDirPath

def matchNetlistCell(cell_instantiation):
Expand Down Expand Up @@ -169,4 +173,4 @@ def update_netlist(srcNetlist, dstNetlist, simMode):
"""
netlist = netlist.replace(toplevel_pinout.split(" ", 2)[2], standardized_pinout)
with open(dstNetlist, "w") as wf:
wf.write(netlist)
wf.write(netlist)
6 changes: 3 additions & 3 deletions tests/common_api/test_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def run_before_and_after_tests():
rmtree(RUNS_DIR)

def test_simulations():
num_runs = run_simulations(
sim_state = run_simulations(
parameters=PARAMS,
platform = "",
simulation_dir = TEST_SIMULATION_DIR,
Expand All @@ -69,7 +69,7 @@ def test_simulations():
)

# Check if the correct number of configurations are generated
assert num_runs == EXPECTED_NUM_CONFIGS, "The number of runs does not match the expected number."
assert sim_state["completed_sims"] == EXPECTED_NUM_CONFIGS, "The number of runs does not match the expected number."
assert len(os.listdir(RUNS_DIR)) == EXPECTED_NUM_CONFIGS, "The number of generated configurations does not match the expected number."


Expand Down Expand Up @@ -99,4 +99,4 @@ def test_simulations():
irms_value = get_value(log_file_text, 'irms')

assert vrms_value != "NOT_FOUND", f"`vrms` value not found in the simulation output for config #{i}"
assert irms_value != "NOT_FOUND", f"`irms` value not found in the simulation output for config #{i}"
assert irms_value != "NOT_FOUND", f"`irms` value not found in the simulation output for config #{i}"
Loading