Skip to content

Commit

Permalink
util/sim: Extract simulation and elapsed time in Questa
Browse files Browse the repository at this point in the history
  • Loading branch information
colluca committed Feb 12, 2024
1 parent 0e06502 commit 65907a3
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
40 changes: 39 additions & 1 deletion util/sim/Simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ def launch(self, dry_run=None):
self.process = subprocess.Popen(self.cmd, stdout=f, stderr=subprocess.STDOUT,
cwd=self.run_dir, universal_newlines=True)

def launched(self):
"""Return whether the simulation was launched."""
if self.process:
return True
else:
return False

def completed(self):
"""Return whether the simulation completed."""
if self.dry_run:
Expand All @@ -96,6 +103,14 @@ def successful(self):
else:
return False

def get_simulation_time(self):
"""Return the execution time [ns] of the binary in simulation."""
return None

def get_elapsed_time(self):
"""Return the actual time [s] taken to run the simulation."""
return None

def print_log(self):
"""Print a log of the simulation to stdout."""
with open(self.log, 'r') as f:
Expand All @@ -112,8 +127,10 @@ def print_status(self):
cprint(f'{self.elf} test passed', 'green', attrs=['bold'], flush=True)
else:
cprint(f'{self.elf} test failed', 'red', attrs=['bold'], flush=True)
else:
elif self.launched():
cprint(f'{self.elf} test running', 'yellow', attrs=['bold'], flush=True)
else:
cprint(f'{self.elf} test not launched', 'yellow', attrs=['bold'], flush=True)


class RTLSimulation(Simulation):
Expand Down Expand Up @@ -183,6 +200,27 @@ def __init__(self, **kwargs):
super().__init__(**kwargs)
self.cmd += ['', '-batch']

def get_simulation_time(self):
# Extract the simulation time from the simulation log
with open(self.log, 'r') as f:
for line in f.readlines():
regex = r'Time: (\d+) ns'
match = re.search(regex, line)
if match:
return int(match.group(1))

def get_elapsed_time(self):
# Extract the simulation time from the simulation log
with open(self.log, 'r') as f:
for line in f.readlines():
regex = r'Elapsed time: (\d+):(\d+):(\d+)'
match = re.search(regex, line)
if match:
hours = int(match.group(1))
minutes = int(match.group(2))
seconds = int(match.group(3))
return hours*3600 + minutes*60 + seconds


class VCSSimulation(QuestaVCSSimulation):
"""An RTL simulation running on VCS."""
Expand Down
24 changes: 24 additions & 0 deletions util/sim/sim_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@
import yaml
import signal
import psutil
import pandas as pd

POLL_PERIOD = 0.2
REPORT_FILE = 'sim_report.csv'


def parser(default_simulator='vsim', simulator_choices=['vsim']):
Expand Down Expand Up @@ -200,6 +202,23 @@ def print_summary(sims, early_exit=False, dry_run=False):
print(f'{colored("All tests terminated and passed!", "green")}')


def dump_report(sims):
"""Print a detailed report on the simulation suite's execution.
Args:
sims: A list of simulations from the simulation suite.
"""
data = [{'elf': sim.elf,
'launched': sim.launched(),
'completed': sim.completed(),
'passed': sim.successful(),
'elapsed time [s]': sim.get_elapsed_time(),
'simulation time [ns]': sim.get_simulation_time()} for sim in sims]
df = pd.DataFrame(data)
df = df.set_index('elf')
df.to_csv(REPORT_FILE)


def terminate_processes():
print('Terminate processes')
# Get PID and PGID of parent process (current Python script)
Expand Down Expand Up @@ -250,6 +269,7 @@ def run_simulations(simulations, n_procs=1, dry_run=None, early_exit=False,
# Spawn a process for every test, wait for all running tests to terminate and check results
running_sims = []
failed_sims = []
successful_sims = []
early_exit_requested = False
try:
while (len(simulations) or len(running_sims)) and not early_exit_requested:
Expand All @@ -264,6 +284,7 @@ def run_simulations(simulations, n_procs=1, dry_run=None, early_exit=False,
# Check completed sims and report status
for sim in completed_sims:
if sim.successful():
successful_sims.append(sim)
sim.print_status()
else:
failed_sims.append(sim)
Expand All @@ -281,6 +302,9 @@ def run_simulations(simulations, n_procs=1, dry_run=None, early_exit=False,
# Print summary
print_summary(running_sims + failed_sims, early_exit_requested)

# Dump report
dump_report(simulations + running_sims + successful_sims + failed_sims)

# Clean up after early exit
if early_exit_requested:
terminate_processes()
Expand Down

0 comments on commit 65907a3

Please sign in to comment.