|
|
@@ -0,0 +1,151 @@
|
|
|
+import tempfile
|
|
|
+import time
|
|
|
+import pandas as pd
|
|
|
+import pickle
|
|
|
+
|
|
|
+from imc_utils.pps_e36311a import PPS_E36311A
|
|
|
+from imc_utils.build_config.cortex_m33 import BuildConfigM33
|
|
|
+from imc_utils.build_config.test_env import TestEnv
|
|
|
+import imc_utils.serial_device
|
|
|
+
|
|
|
+WORKSPACE_ROOT = "/home/ybkim/workspace/imc/imc_freertos_app_m33"
|
|
|
+NVM_RESET_BIN = f"{WORKSPACE_ROOT}/imc/utils/nvm_reset.elf"
|
|
|
+OPENOCD_SCRIPT = f"{WORKSPACE_ROOT}/imc_freertos_app_m33.cfg"
|
|
|
+
|
|
|
+def main():
|
|
|
+ pps = PPS_E36311A()
|
|
|
+ config = get_default_build_config()
|
|
|
+
|
|
|
+ benchmarks = [
|
|
|
+ "vBasicMath", "vCrc", "vFFT", "vSha"
|
|
|
+ # "vSha"
|
|
|
+ ]
|
|
|
+
|
|
|
+ for benchmark in benchmarks:
|
|
|
+ config.bench_name = benchmark
|
|
|
+ config.insert_compiler_checkpoints = True
|
|
|
+ config.use_checkpoint_pass_counter = False
|
|
|
+ config.use_checkpoint_voltage_check = True
|
|
|
+ config.checkpoint_pass_count = 100
|
|
|
+ config.bench_infinite_loop = True
|
|
|
+
|
|
|
+ pps.set_voltage(3.3, 1)
|
|
|
+ pps.set_current(0.1, 1)
|
|
|
+ pps.output_on(1)
|
|
|
+
|
|
|
+ env = TestEnv(WORKSPACE_ROOT, NVM_RESET_BIN, OPENOCD_SCRIPT)
|
|
|
+
|
|
|
+ with tempfile.TemporaryDirectory() as build_dir:
|
|
|
+ binary = env.build_binary(config, build_dir)
|
|
|
+ env.clear_nvm_and_load_binary(binary, resume=True)
|
|
|
+
|
|
|
+ pps.set_current(0.015, 1)
|
|
|
+ time.sleep(1)
|
|
|
+
|
|
|
+ total_iterations = 5
|
|
|
+ records = measure_execution_time(benchmark, total_iterations)
|
|
|
+ df = pd.DataFrame(records)
|
|
|
+ save_records(benchmark, df)
|
|
|
+ print(df)
|
|
|
+
|
|
|
+
|
|
|
+def measure_execution_time(bench_nanme, total_iterations):
|
|
|
+ ser = imc_utils.serial_device.get_serial()
|
|
|
+
|
|
|
+ num_finished = 0
|
|
|
+ start_detected = False
|
|
|
+ time_takens = []
|
|
|
+ time_total = 0
|
|
|
+ outputs = []
|
|
|
+ records = []
|
|
|
+ num_recovery = 0
|
|
|
+
|
|
|
+ ser.reset_input_buffer()
|
|
|
+
|
|
|
+ while num_finished < total_iterations:
|
|
|
+ if ser.readable():
|
|
|
+ res = ser.readline()
|
|
|
+ try:
|
|
|
+ line = res.decode()[: len(res) - 1]
|
|
|
+ except:
|
|
|
+ print("readline() exception")
|
|
|
+ continue
|
|
|
+
|
|
|
+ if line.startswith("hardfault"):
|
|
|
+ print("\nHARD FAULT")
|
|
|
+
|
|
|
+ if not start_detected:
|
|
|
+ if line.startswith("Start benchmark"):
|
|
|
+ print("\nbenchmark start detected")
|
|
|
+ t_start = time.time()
|
|
|
+ start_detected = True
|
|
|
+ else:
|
|
|
+ if line.startswith("End benchmark"):
|
|
|
+ t_end = time.time()
|
|
|
+ t_diff = t_end - t_start
|
|
|
+ time_takens.append(t_diff)
|
|
|
+ time_total += t_diff
|
|
|
+ num_finished += 1
|
|
|
+ print(
|
|
|
+ f"\nbenchmark end detected, time: {t_diff:.2f} secs, finished: {num_finished}, average: {time_total/num_finished:.2f} secs"
|
|
|
+ )
|
|
|
+ start_detected = False
|
|
|
+ record = {
|
|
|
+ "bench_name": bench_nanme,
|
|
|
+ "start": t_start,
|
|
|
+ "end": t_end,
|
|
|
+ "time_taken": t_diff,
|
|
|
+ "recovery": num_recovery,
|
|
|
+ "outputs": outputs,
|
|
|
+ "is_correct": check_output_is_correct(bench_nanme, outputs)
|
|
|
+ }
|
|
|
+ records.append(record)
|
|
|
+ outputs = []
|
|
|
+ num_recovery = 0
|
|
|
+
|
|
|
+ elif line.startswith("(OUT)"):
|
|
|
+ print(line)
|
|
|
+ outputs.append(line[6:].strip())
|
|
|
+
|
|
|
+ elif line.startswith("Start recovery"):
|
|
|
+ num_recovery += 1
|
|
|
+ print(f"recovery: #{num_recovery}", end="\r")
|
|
|
+
|
|
|
+ return records
|
|
|
+
|
|
|
+
|
|
|
+def get_default_build_config():
|
|
|
+ config = BuildConfigM33()
|
|
|
+ config.bench_name = "vBasicMath"
|
|
|
+ config.insert_compiler_checkpoints = True
|
|
|
+ config.enable_extension = True
|
|
|
+ config.use_checkpoint_pass_counter = False
|
|
|
+ config.use_checkpoint_voltage_check = True
|
|
|
+ config.bench_infinite_loop = True
|
|
|
+ config.checkpoint_pass_count = 100
|
|
|
+ config.print_recovery_message = True
|
|
|
+ return config
|
|
|
+
|
|
|
+
|
|
|
+correct_outputs = {
|
|
|
+ "vBasicMath": "Sum: -9313",
|
|
|
+ "vCrc": "210692533",
|
|
|
+ "vFFT": "2807, 915",
|
|
|
+ "vSha": "4926a88d 0ca714f4 a9ebc1eb def37b8e 3911ee0f",
|
|
|
+}
|
|
|
+
|
|
|
+def check_output_is_correct(bench_name, outputs):
|
|
|
+ if len(outputs) == 0 or bench_name not in correct_outputs:
|
|
|
+ return False
|
|
|
+ is_single_output = len(outputs) == 1
|
|
|
+ is_output_correct = correct_outputs[bench_name] == outputs[0]
|
|
|
+ return is_single_output and is_output_correct
|
|
|
+
|
|
|
+
|
|
|
+def save_records(bench_name, df):
|
|
|
+ with open(f"output/{bench_name}.pickle", "wb") as f:
|
|
|
+ pickle.dump(df, f)
|
|
|
+
|
|
|
+
|
|
|
+if __name__ == "__main__":
|
|
|
+ main()
|