feat: init mlkem project with Verilator test framework

- sync_rtl/common/: skid_buffer, pipeline_reg, defines (valid/ready)
- sync_rtl/mod_add/: modular adder example with Verilator C++ TB
- test_framework/: Python-driven Verilator compile/sim/compare pipeline
- test_framework/modules/mod_add/: 50-vector test plan, full鏈路 PASS
- .trellis/spec/: RTL and test_framework conventions documented
This commit is contained in:
2026-06-24 19:43:29 +08:00
commit 8fdf944555
216 changed files with 24140 additions and 0 deletions

Binary file not shown.

View File

@@ -0,0 +1,12 @@
{
"verilator": {
"path": "verilator",
"compile_args": ["-Wall", "--cc", "--build", "--timing", "--exe"]
},
"clock_period_ns": 10.0,
"timeout_cycles": 100000,
"rtl_root": "sync_rtl",
"vector_root": "test_framework/modules/{module}/vectors",
"report_root": "test_framework/reports",
"keep_vectors": false
}

View File

View File

@@ -0,0 +1,130 @@
"""reporter.py - Formats and displays test results."""
import os
import time
from datetime import datetime
class Reporter:
"""Formats test results for terminal and HTML output."""
# ANSI color codes
GREEN = '\033[92m'
RED = '\033[91m'
YELLOW = '\033[93m'
CYAN = '\033[96m'
RESET = '\033[0m'
BOLD = '\033[1m'
def __init__(self, report_dir: str = 'test_framework/reports'):
self.report_dir = report_dir
os.makedirs(report_dir, exist_ok=True)
def print_summary(self, results: dict, total_elapsed: float = 0.0) -> bool:
"""Print formatted test summary to terminal.
Args:
results: Dict of module_name -> module_results.
total_elapsed: Total elapsed time in seconds.
Returns:
bool: True if all tests passed.
"""
total_pass = 0
total_fail = 0
all_pass = True
print()
print(f"{self.BOLD}{'='*60}{self.RESET}")
print(f"{self.BOLD} TEST RESULTS{self.RESET}")
print(f"{self.BOLD}{'='*60}{self.RESET}")
for module_name, module_result in results.items():
status = module_result.get('status', 'UNKNOWN')
num_pass = module_result.get('pass', 0)
num_fail = module_result.get('fail', 0)
elapsed = module_result.get('elapsed', 0.0)
total_pass += num_pass
total_fail += num_fail
if status == 'PASS':
color = self.GREEN
icon = ''
elif status == 'FAIL':
color = self.RED
icon = ''
all_pass = False
else:
color = self.YELLOW
icon = '?'
all_pass = False
print(f" {color}{icon} {module_name}{self.RESET}: "
f"{num_pass} pass, {num_fail} fail, "
f"{elapsed:.2f}s")
print(f"{self.BOLD}{'='*60}{self.RESET}")
total = total_pass + total_fail
if all_pass:
print(f" {self.GREEN}{self.BOLD}ALL TESTS PASSED{self.RESET} "
f"({total_pass}/{total} vectors, {total_elapsed:.2f}s)")
else:
print(f" {self.RED}{self.BOLD}SOME TESTS FAILED{self.RESET} "
f"({total_pass}/{total} pass, {total_fail}/{total} fail, "
f"{total_elapsed:.2f}s)")
print()
# Write HTML report
self._write_html_report(results, total_elapsed)
return all_pass
def _write_html_report(self, results: dict, total_elapsed: float) -> None:
"""Write an HTML test report."""
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
report_path = os.path.join(self.report_dir, f'report_{timestamp}.html')
total_pass = sum(r.get('pass', 0) for r in results.values())
total_fail = sum(r.get('fail', 0) for r in results.values())
all_pass = total_fail == 0
rows = ''
for module_name, module_result in results.items():
status = module_result.get('status', 'UNKNOWN')
color = '#4CAF50' if status == 'PASS' else '#F44336'
rows += f'''
<tr>
<td>{module_name}</td>
<td style="color:{color}">{status}</td>
<td>{module_result.get('pass', 0)}</td>
<td>{module_result.get('fail', 0)}</td>
<td>{module_result.get('elapsed', 0):.2f}s</td>
</tr>'''
html = f'''<!DOCTYPE html>
<html>
<head>
<title>ML-KEM Test Report</title>
<style>
body {{ font-family: monospace; background: #1e1e1e; color: #d4d4d4;
padding: 20px; }}
h1 {{ color: {'#4CAF50' if all_pass else '#F44336'}; }}
table {{ border-collapse: collapse; width: 100%; }}
th, td {{ border: 1px solid #444; padding: 8px; text-align: left; }}
th {{ background: #333; }}
</style>
</head>
<body>
<h1>{'ALL TESTS PASSED' if all_pass else 'SOME TESTS FAILED'}</h1>
<p>Generated: {timestamp}<br>
Total: {total_pass + total_fail} vectors ({total_pass} pass, {total_fail} fail)<br>
Elapsed: {total_elapsed:.2f}s</p>
<table>
<tr><th>Module</th><th>Status</th><th>Pass</th><th>Fail</th><th>Time</th></tr>
{rows}
</table>
</body>
</html>'''
with open(report_path, 'w') as f:
f.write(html)
print(f" Report saved to: {report_path}")

View File

@@ -0,0 +1,45 @@
"""result_checker.py - Compares simulation output against expected values."""
def check_results(got: list[str], expected_file: str) -> tuple[int, int]:
"""Compare Verilator output against expected values.
Args:
got: List of result strings from simulation (hex values).
expected_file: Path to file containing expected hex values, one per line.
Returns:
tuple[int, int]: (num_pass, num_fail).
"""
# Read expected values
expected = []
try:
with open(expected_file, 'r') as f:
for line in f:
line = line.strip()
if line and not line.startswith('#'):
expected.append(line)
except FileNotFoundError:
print(f"[ERROR] Expected file not found: {expected_file}")
return (0, len(got))
num_pass = 0
num_fail = 0
max_len = max(len(got), len(expected))
for i in range(max_len):
got_val = got[i].upper() if i < len(got) else 'MISSING'
exp_val = expected[i].upper() if i < len(expected) else 'MISSING'
if got_val == exp_val:
num_pass += 1
else:
num_fail += 1
if num_fail <= 5: # Only show first 5 failures
print(f" MISMATCH[{i}]: got={got_val}, expected={exp_val}")
if num_fail > 5:
print(f" ... and {num_fail - 5} more mismatches")
return (num_pass, num_fail)

View File

@@ -0,0 +1,134 @@
"""sim_controller.py - Verilator simulation controller.
Handles Verilator compilation and execution of RTL testbenches.
"""
import subprocess
import os
import time
class SimController:
"""Controls Verilator compilation and simulation."""
def __init__(self, config: dict):
"""Initialize with test framework configuration.
Args:
config: The loaded config.json dict.
"""
self.config = config
self.verilator_path = config.get('verilator', {}).get('path', 'verilator')
self.compile_args = config.get('verilator', {}).get('compile_args', [])
def compile(self, top_module: str, rtl_files: list[str], tb_cpp: str,
work_dir: str, inc_dirs: list[str] = None) -> str:
"""Compile RTL with Verilator and return path to executable.
Args:
top_module: Name of the top-level Verilog module.
rtl_files: List of Verilog source file paths.
tb_cpp: Path to C++ testbench file.
work_dir: Working directory for compilation output (-Mdir).
inc_dirs: List of include directories for `include directives.
Returns:
Path to the compiled executable.
Raises:
RuntimeError: If Verilator is not found or compilation fails.
"""
os.makedirs(work_dir, exist_ok=True)
# Build verilator command
cmd = [self.verilator_path]
cmd.extend(self.compile_args)
cmd.extend(['--top-module', top_module])
# No explicit -std= flag; let Verilator use its default (C++14+)
if inc_dirs:
for d in inc_dirs:
cmd.append(f'+incdir+{d}')
cmd.extend(rtl_files)
cmd.append(tb_cpp)
cmd.extend(['-Mdir', work_dir])
try:
result = subprocess.run(
cmd,
capture_output=True,
text=True,
timeout=120,
cwd=os.getcwd()
)
except subprocess.TimeoutExpired:
raise RuntimeError("Verilator compilation timed out.")
except FileNotFoundError:
raise RuntimeError(
f"Verilator not found at '{self.verilator_path}'."
)
if result.returncode != 0:
tail = result.stderr[-800:] if result.stderr else '(no stderr)'
raise RuntimeError(f"Verilator compilation failed:\n{tail}")
# Executable is at <work_dir>/V<top_module>
executable = os.path.join(work_dir, f'V{top_module}')
if not os.path.exists(executable):
raise RuntimeError(
f"Compilation succeeded but executable not found: {executable}"
)
return executable
def run(self, executable: str, vector_file: str,
timeout_s: int = 30) -> dict:
"""Run the compiled simulation executable.
Args:
executable: Path to the compiled executable.
vector_file: Path to the hex vector file.
timeout_s: Timeout in seconds.
Returns:
dict with keys: success, results, elapsed, stderr.
"""
if not os.path.exists(executable):
return {
'success': False,
'results': [],
'elapsed': 0.0,
'stderr': f'Executable not found: {executable}'
}
start_time = time.time()
try:
result = subprocess.run(
[executable, f'+VECTOR_FILE={vector_file}'],
capture_output=True,
text=True,
timeout=timeout_s
)
elapsed = time.time() - start_time
# Parse stdout for "RESULT: XXX" lines
results = []
for line in result.stdout.splitlines():
line = line.strip()
if line.startswith('RESULT:'):
hex_val = line.split(':', 1)[1].strip()
results.append(hex_val)
success = result.returncode == 0 and len(results) > 0
return {
'success': success,
'results': results,
'elapsed': elapsed,
'stderr': result.stderr
}
except subprocess.TimeoutExpired:
elapsed = time.time() - start_time
return {
'success': False,
'results': [],
'elapsed': elapsed,
'stderr': 'Simulation timed out.'
}

View File

@@ -0,0 +1,243 @@
"""test_runner.py - Main test engine.
Discovers modules, loads test plans, generates vectors, runs simulations,
and collects results.
"""
import os
import json
import time
import importlib.util
import sys
from pathlib import Path
from .sim_controller import SimController
from .result_checker import check_results
class TestRunner:
"""Main test engine for the ML-KEM RTL test framework."""
def __init__(self, config_path: str = 'test_framework/config.json'):
"""Initialize with configuration.
Args:
config_path: Path to config.json.
"""
self.project_root = os.path.dirname(os.path.dirname(
os.path.dirname(os.path.abspath(__file__))))
self.config_path = os.path.join(self.project_root, config_path)
with open(self.config_path) as f:
self.config = json.load(f)
self.sim = SimController(self.config)
self.modules_dir = os.path.join(self.project_root,
'test_framework', 'modules')
self.rtl_root = os.path.join(self.project_root,
self.config.get('rtl_root', 'sync_rtl'))
def discover_modules(self) -> dict[str, dict]:
"""Scan test_framework/modules/*/test_plan.json and return plans.
Returns:
dict of module_name -> test_plan.
"""
modules = {}
if not os.path.isdir(self.modules_dir):
return modules
for entry in os.listdir(self.modules_dir):
mod_dir = os.path.join(self.modules_dir, entry)
plan_path = os.path.join(mod_dir, 'test_plan.json')
if os.path.isdir(mod_dir) and os.path.exists(plan_path):
with open(plan_path) as f:
plan = json.load(f)
modules[entry] = plan
return modules
def _get_rtl_files(self, plan: dict) -> list[str]:
"""Resolve RTL source file paths from a test plan.
Args:
plan: Test plan dict with 'rtl_top' and optional 'rtl_deps'.
Returns:
List of absolute paths: deps first, then top.
"""
rtl_top = os.path.join(self.project_root, plan['rtl_top'])
rtl_deps = [os.path.join(self.project_root, d)
for d in plan.get('rtl_deps', [])]
return rtl_deps + [rtl_top]
def run_module(self, module_name: str, quick: bool = False,
single_case: str = None) -> dict:
"""Run all test cases for a module.
Args:
module_name: Name of the module to test.
quick: If True, reduce vector count for faster testing.
single_case: If set, only run this case ID.
Returns:
dict with keys: pass, fail, cases, elapsed, status.
"""
modules = self.discover_modules()
if module_name not in modules:
return {
'pass': 0, 'fail': 0, 'cases': {},
'elapsed': 0.0, 'status': 'NOT_FOUND',
'error': f'Module "{module_name}" not found'
}
plan = modules[module_name]
mod_dir = os.path.join(self.modules_dir, module_name)
vectors_dir = os.path.join(mod_dir, 'vectors')
work_dir = os.path.join(mod_dir, 'obj_dir')
os.makedirs(vectors_dir, exist_ok=True)
# Import module's gen_vectors.py
gen_path = os.path.join(mod_dir, 'gen_vectors.py')
if not os.path.exists(gen_path):
return {
'pass': 0, 'fail': 0, 'cases': {},
'elapsed': 0.0, 'status': 'ERROR',
'error': f'gen_vectors.py not found for {module_name}'
}
spec = importlib.util.spec_from_file_location(
f'{module_name}_gen', gen_path)
gen_module = importlib.util.module_from_spec(spec)
sys.modules[f'{module_name}_gen'] = gen_module
spec.loader.exec_module(gen_module)
# Find generator class
generator = None
for name in dir(gen_module):
obj = getattr(gen_module, name)
if (isinstance(obj, type) and
hasattr(obj, 'generate_one') and
hasattr(obj, 'write_hex_file') and
name != 'VectorGenerator'):
generator = obj()
break
if generator is None:
return {
'pass': 0, 'fail': 0, 'cases': {},
'elapsed': 0.0, 'status': 'ERROR',
'error': f'No generator class found in {gen_path}'
}
# Resolve RTL files and top module name
rtl_files = self._get_rtl_files(plan)
tb_cpp = os.path.join(self.project_root, plan['tb_cpp'])
# Top module name derived from rtl_top filename (strip .v)
top_module = os.path.basename(plan['rtl_top']).replace('.v', '')
# Compile once for the module
print(f"\n Compiling {module_name} with Verilator...")
start_time = time.time()
try:
executable = self.sim.compile(
top_module=top_module,
rtl_files=rtl_files,
tb_cpp=tb_cpp,
work_dir=work_dir,
inc_dirs=[self.project_root]
)
except RuntimeError as e:
return {
'pass': 0, 'fail': 0, 'cases': {},
'elapsed': time.time() - start_time,
'status': 'COMPILE_ERROR',
'error': str(e)
}
case_results = {}
total_pass = 0
total_fail = 0
for case in plan.get('cases', []):
case_id = case['id']
# Filter by single case
if single_case and case_id != single_case:
continue
num_vectors = case.get('num_vectors', 10)
if quick:
num_vectors = max(1, num_vectors // 5)
params = case.get('params', {})
print(f" Case [{case_id}]: {case.get('description', '')} "
f"({num_vectors} vectors)")
# Generate vectors
vectors = []
for i in range(num_vectors):
vec = generator.generate_one(params)
vectors.append(vec)
# Write input vectors hex file
input_file = os.path.join(vectors_dir, f'{case_id}_input.hex')
generator.write_hex_file(vectors, input_file)
# Write expected output hex file
expected_file = os.path.join(vectors_dir, f'{case_id}_expected.hex')
generator.write_expected_file(vectors, expected_file)
# Run simulation
timeout_s = plan.get('timeout_s', 30)
run_result = self.sim.run(executable, input_file, timeout_s)
if not run_result['success']:
case_results[case_id] = {
'pass': 0, 'fail': num_vectors,
'elapsed': run_result['elapsed'],
'error': run_result.get('stderr', 'Simulation failed')
}
total_fail += num_vectors
continue
# Compare results
tolerance = case.get('tolerance', 'bit_exact')
if tolerance == 'bit_exact':
num_pass, num_fail = check_results(
run_result['results'], expected_file)
else:
# Delegate to generator for custom comparison
if hasattr(generator, 'compare_results'):
compare_ok = generator.compare_results(
run_result['results'], expected_file)
num_pass = num_vectors if compare_ok else 0
num_fail = 0 if compare_ok else num_vectors
else:
num_pass, num_fail = check_results(
run_result['results'], expected_file)
case_results[case_id] = {
'pass': num_pass,
'fail': num_fail,
'elapsed': run_result['elapsed']
}
total_pass += num_pass
total_fail += num_fail
# Clean up vectors unless keep_vectors is true
if not self.config.get('keep_vectors', False):
try:
os.remove(input_file)
os.remove(expected_file)
except OSError:
pass
elapsed = time.time() - start_time
return {
'pass': total_pass,
'fail': total_fail,
'cases': case_results,
'elapsed': elapsed,
'status': 'PASS' if total_fail == 0 else 'FAIL'
}

View File

@@ -0,0 +1,61 @@
"""vector_gen.py - Base class for vector generators.
Each module provides a gen_vectors.py that subclasses VectorGenerator.
The generate_one() method is abstract and must be overridden.
The write_hex_file() method writes vectors as hex-formatted files.
"""
import os
from abc import ABC, abstractmethod
class VectorGenerator(ABC):
"""Base class for test vector generators."""
@abstractmethod
def generate_one(self, params: dict) -> dict:
"""Generate a single test vector.
Args:
params: Module-specific parameters for vector generation.
Returns:
dict with 'input' and 'expected' keys, each containing a dict
of signal_name -> value.
"""
...
def write_hex_file(self, vectors: list[dict], filepath: str) -> None:
"""Write vectors to a hex file.
Subclasses should override this to match their module's input format.
Default: writes each vector on one line, hex values separated by spaces.
Args:
vectors: List of result dicts from generate_one().
filepath: Path to write the hex file.
"""
os.makedirs(os.path.dirname(filepath), exist_ok=True)
with open(filepath, 'w') as f:
for v in vectors:
# Default: write input values as space-separated hex
inputs = v.get('input', {})
hex_vals = [format(val, 'X') for val in inputs.values()]
f.write(' '.join(hex_vals) + '\n')
def write_expected_file(self, vectors: list[dict], filepath: str) -> None:
"""Write expected results to a hex file.
Subclasses should override this to match their module's expected format.
Default: writes each expected value on one line.
Args:
vectors: List of result dicts from generate_one().
filepath: Path to write the expected hex file.
"""
os.makedirs(os.path.dirname(filepath), exist_ok=True)
with open(filepath, 'w') as f:
for v in vectors:
expected = v.get('expected', {})
hex_vals = [format(val, 'X') for val in expected.values()]
f.write(' '.join(hex_vals) + '\n')

View File

@@ -0,0 +1,121 @@
"""gen_vectors.py - Test vector generator for mod_add module.
Generates (a, b) input pairs and computes expected (a + b) mod Q.
"""
import os
import random
import sys
# Add test_framework/lib to path for VectorGenerator base class
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'lib'))
from vector_gen import VectorGenerator
Q = 3329 # ML-KEM prime modulus
class ModAddVectorGenerator(VectorGenerator):
"""Generates test vectors for the mod_add_sync module."""
def generate_one(self, params: dict) -> dict:
"""Generate a single (a, b) pair with expected modular sum.
Uses random values covering:
- No overflow: a + b < Q
- With overflow: a + b >= Q
- Edge cases: a=0, b=0, a=Q-1, b=Q-1
Args:
params: Unused for mod_add basic case.
Returns:
dict with 'input' and 'expected' keys.
"""
# Mix of random and edge cases for coverage
roll = random.random()
if roll < 0.05:
# Both zero
a, b = 0, 0
elif roll < 0.10:
# a=0, b random
a = 0
b = random.randint(0, Q - 1)
elif roll < 0.15:
# b=0, a random
a = random.randint(0, Q - 1)
b = 0
elif roll < 0.20:
# Both Q-1 (max overflow)
a, b = Q - 1, Q - 1
elif roll < 0.25:
# a random, b = Q-1
a = random.randint(0, Q - 1)
b = Q - 1
elif roll < 0.65:
# No overflow: both small
a = random.randint(0, Q // 2 - 1)
b = random.randint(0, Q // 2 - 1)
else:
# Potential overflow
a = random.randint(0, Q - 1)
b = random.randint(0, Q - 1)
# Compute expected: (a + b) mod Q
expected_sum = (a + b) % Q
return {
'input': {'a': a, 'b': b},
'expected': {'sum': expected_sum}
}
def write_hex_file(self, vectors: list[dict], filepath: str) -> None:
"""Write input vectors as "AAA BBB" hex format.
Args:
vectors: List of vector dicts from generate_one().
filepath: Path to write the hex file.
"""
os.makedirs(os.path.dirname(filepath), exist_ok=True)
with open(filepath, 'w') as f:
for v in vectors:
a = v['input']['a']
b = v['input']['b']
f.write(f'{a:03X} {b:03X}\n')
def write_expected_file(self, vectors: list[dict], filepath: str) -> None:
"""Write expected output as "CCC" hex format.
Args:
vectors: List of vector dicts from generate_one().
filepath: Path to write the expected hex file.
"""
os.makedirs(os.path.dirname(filepath), exist_ok=True)
with open(filepath, 'w') as f:
for v in vectors:
s = v['expected']['sum']
f.write(f'{s:03X}\n')
def compare_results(self, got: list[str], expected_file: str) -> bool:
"""Compare RTL output against expected values.
Args:
got: List of hex result strings from simulation.
expected_file: Path to expected hex file.
Returns:
bool: True if all results match.
"""
with open(expected_file, 'r') as f:
expected = [line.strip() for line in f
if line.strip() and not line.startswith('#')]
if len(got) != len(expected):
return False
for i, (g, e) in enumerate(zip(got, expected)):
if g.upper() != e.upper():
return False
return True

Binary file not shown.

View File

@@ -0,0 +1,104 @@
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Model implementation (design independent parts)
#include "Vmod_add_sync__pch.h"
//============================================================
// Constructors
Vmod_add_sync::Vmod_add_sync(VerilatedContext* _vcontextp__, const char* _vcname__)
: VerilatedModel{*_vcontextp__}
, vlSymsp{new Vmod_add_sync__Syms(contextp(), _vcname__, this)}
, clk{vlSymsp->TOP.clk}
, rst_n{vlSymsp->TOP.rst_n}
, valid_i{vlSymsp->TOP.valid_i}
, ready_o{vlSymsp->TOP.ready_o}
, valid_o{vlSymsp->TOP.valid_o}
, ready_i{vlSymsp->TOP.ready_i}
, a{vlSymsp->TOP.a}
, b{vlSymsp->TOP.b}
, sum{vlSymsp->TOP.sum}
, rootp{&(vlSymsp->TOP)}
{
// Register model with the context
contextp()->addModel(this);
}
Vmod_add_sync::Vmod_add_sync(const char* _vcname__)
: Vmod_add_sync(Verilated::threadContextp(), _vcname__)
{
}
//============================================================
// Destructor
Vmod_add_sync::~Vmod_add_sync() {
delete vlSymsp;
}
//============================================================
// Evaluation function
#ifdef VL_DEBUG
void Vmod_add_sync___024root___eval_debug_assertions(Vmod_add_sync___024root* vlSelf);
#endif // VL_DEBUG
void Vmod_add_sync___024root___eval_static(Vmod_add_sync___024root* vlSelf);
void Vmod_add_sync___024root___eval_initial(Vmod_add_sync___024root* vlSelf);
void Vmod_add_sync___024root___eval_settle(Vmod_add_sync___024root* vlSelf);
void Vmod_add_sync___024root___eval(Vmod_add_sync___024root* vlSelf);
void Vmod_add_sync::eval_step() {
VL_DEBUG_IF(VL_DBG_MSGF("+++++TOP Evaluate Vmod_add_sync::eval_step\n"); );
#ifdef VL_DEBUG
// Debug assertions
Vmod_add_sync___024root___eval_debug_assertions(&(vlSymsp->TOP));
#endif // VL_DEBUG
vlSymsp->__Vm_deleter.deleteAll();
if (VL_UNLIKELY(!vlSymsp->__Vm_didInit)) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Initial\n"););
Vmod_add_sync___024root___eval_static(&(vlSymsp->TOP));
Vmod_add_sync___024root___eval_initial(&(vlSymsp->TOP));
Vmod_add_sync___024root___eval_settle(&(vlSymsp->TOP));
vlSymsp->__Vm_didInit = true;
}
VL_DEBUG_IF(VL_DBG_MSGF("+ Eval\n"););
Vmod_add_sync___024root___eval(&(vlSymsp->TOP));
// Evaluate cleanup
Verilated::endOfEval(vlSymsp->__Vm_evalMsgQp);
}
//============================================================
// Events and timing
bool Vmod_add_sync::eventsPending() { return false; }
uint64_t Vmod_add_sync::nextTimeSlot() {
VL_FATAL_MT(__FILE__, __LINE__, "", "No delays in the design");
return 0;
}
//============================================================
// Utilities
const char* Vmod_add_sync::name() const {
return vlSymsp->name();
}
//============================================================
// Invoke final blocks
void Vmod_add_sync___024root___eval_final(Vmod_add_sync___024root* vlSelf);
VL_ATTR_COLD void Vmod_add_sync::final() {
Vmod_add_sync___024root___eval_final(&(vlSymsp->TOP));
}
//============================================================
// Implementations of abstract methods from VerilatedModel
const char* Vmod_add_sync::hierName() const { return vlSymsp->name(); }
const char* Vmod_add_sync::modelName() const { return "Vmod_add_sync"; }
unsigned Vmod_add_sync::threads() const { return 1; }
void Vmod_add_sync::prepareClone() const { contextp()->prepareClone(); }
void Vmod_add_sync::atClone() const {
contextp()->threadPoolpOnClone();
}

View File

@@ -0,0 +1,96 @@
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Primary model header
//
// This header should be included by all source files instantiating the design.
// The class here is then constructed to instantiate the design.
// See the Verilator manual for examples.
#ifndef VERILATED_VMOD_ADD_SYNC_H_
#define VERILATED_VMOD_ADD_SYNC_H_ // guard
#include "verilated.h"
class Vmod_add_sync__Syms;
class Vmod_add_sync___024root;
// This class is the main interface to the Verilated model
class alignas(VL_CACHE_LINE_BYTES) Vmod_add_sync VL_NOT_FINAL : public VerilatedModel {
private:
// Symbol table holding complete model state (owned by this class)
Vmod_add_sync__Syms* const vlSymsp;
public:
// CONSTEXPR CAPABILITIES
// Verilated with --trace?
static constexpr bool traceCapable = false;
// PORTS
// The application code writes and reads these signals to
// propagate new values into/out from the Verilated model.
VL_IN8(&clk,0,0);
VL_IN8(&rst_n,0,0);
VL_IN8(&valid_i,0,0);
VL_OUT8(&ready_o,0,0);
VL_OUT8(&valid_o,0,0);
VL_IN8(&ready_i,0,0);
VL_IN16(&a,11,0);
VL_IN16(&b,11,0);
VL_OUT16(&sum,11,0);
// CELLS
// Public to allow access to /* verilator public */ items.
// Otherwise the application code can consider these internals.
// Root instance pointer to allow access to model internals,
// including inlined /* verilator public_flat_* */ items.
Vmod_add_sync___024root* const rootp;
// CONSTRUCTORS
/// Construct the model; called by application code
/// If contextp is null, then the model will use the default global context
/// If name is "", then makes a wrapper with a
/// single model invisible with respect to DPI scope names.
explicit Vmod_add_sync(VerilatedContext* contextp, const char* name = "TOP");
explicit Vmod_add_sync(const char* name = "TOP");
/// Destroy the model; called (often implicitly) by application code
virtual ~Vmod_add_sync();
private:
VL_UNCOPYABLE(Vmod_add_sync); ///< Copying not allowed
public:
// API METHODS
/// Evaluate the model. Application must call when inputs change.
void eval() { eval_step(); }
/// Evaluate when calling multiple units/models per time step.
void eval_step();
/// Evaluate at end of a timestep for tracing, when using eval_step().
/// Application must call after all eval() and before time changes.
void eval_end_step() {}
/// Simulation complete, run final blocks. Application must call on completion.
void final();
/// Are there scheduled events to handle?
bool eventsPending();
/// Returns time at next time slot. Aborts if !eventsPending()
uint64_t nextTimeSlot();
/// Trace signals in the model; called by application code
void trace(VerilatedTraceBaseC* tfp, int levels, int options = 0) { contextp()->trace(tfp, levels, options); }
/// Retrieve name of this model instance (as passed to constructor).
const char* name() const;
// Abstract methods from VerilatedModel
const char* hierName() const override final;
const char* modelName() const override final;
unsigned threads() const override final;
/// Prepare for cloning the model at the process level (e.g. fork in Linux)
/// Release necessary resources. Called before cloning.
void prepareClone() const;
/// Re-init after cloning the model at the process level (e.g. fork in Linux)
/// Re-allocate necessary resources. Called after cloning.
void atClone() const;
private:
// Internal functions - trace registration
void traceBaseModel(VerilatedTraceBaseC* tfp, int levels, int options);
};
#endif // guard

View File

@@ -0,0 +1,69 @@
# Verilated -*- Makefile -*-
# DESCRIPTION: Verilator output: Makefile for building Verilated archive or executable
#
# Execute this makefile from the object directory:
# make -f Vmod_add_sync.mk
default: Vmod_add_sync
### Constants...
# Perl executable (from $PERL, defaults to 'perl' if not set)
PERL = perl
# Python3 executable (from $PYTHON3, defaults to 'python3' if not set)
PYTHON3 = python3
# Path to Verilator kit (from $VERILATOR_ROOT)
VERILATOR_ROOT = /usr/share/verilator
# SystemC include directory with systemc.h (from $SYSTEMC_INCLUDE)
SYSTEMC_INCLUDE ?=
# SystemC library directory with libsystemc.a (from $SYSTEMC_LIBDIR)
SYSTEMC_LIBDIR ?=
### Switches...
# C++ code coverage 0/1 (from --prof-c)
VM_PROFC = 0
# SystemC output mode? 0/1 (from --sc)
VM_SC = 0
# Legacy or SystemC output mode? 0/1 (from --sc)
VM_SP_OR_SC = $(VM_SC)
# Deprecated
VM_PCLI = 1
# Deprecated: SystemC architecture to find link library path (from $SYSTEMC_ARCH)
VM_SC_TARGET_ARCH = linux
### Vars...
# Design prefix (from --prefix)
VM_PREFIX = Vmod_add_sync
# Module prefix (from --prefix)
VM_MODPREFIX = Vmod_add_sync
# User CFLAGS (from -CFLAGS on Verilator command line)
VM_USER_CFLAGS = \
# User LDLIBS (from -LDFLAGS on Verilator command line)
VM_USER_LDLIBS = \
# User .cpp files (from .cpp's on Verilator command line)
VM_USER_CLASSES = \
tb_mod_add \
# User .cpp directories (from .cpp's on Verilator command line)
VM_USER_DIR = \
../../../.. \
../../../../sync_rtl/mod_add/TB \
### Default rules...
# Include list of all generated classes
include Vmod_add_sync_classes.mk
# Include global rules
include $(VERILATOR_ROOT)/include/verilated.mk
### Executable rules... (from --exe)
VPATH += $(VM_USER_DIR)
tb_mod_add.o: /home/fallensigh/Dev/mlkem/sync_rtl/mod_add/TB/tb_mod_add.cpp
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
### Link rules... (from --exe)
Vmod_add_sync: $(VK_USER_OBJS) $(VK_GLOBAL_OBJS) $(VM_PREFIX)__ALL.a
$(LINK) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) $(LIBS) $(SC_LIBS) -o $@
# Verilated -*- Makefile -*-

View File

@@ -0,0 +1,7 @@
// DESCRIPTION: Generated by verilator_includer via makefile
#define VL_INCLUDE_OPT include
#include "Vmod_add_sync.cpp"
#include "Vmod_add_sync___024root__0.cpp"
#include "Vmod_add_sync___024root__Slow.cpp"
#include "Vmod_add_sync___024root__0__Slow.cpp"
#include "Vmod_add_sync__Syms__Slow.cpp"

View File

@@ -0,0 +1,9 @@
Vmod_add_sync__ALL.o: Vmod_add_sync__ALL.cpp Vmod_add_sync.cpp \
Vmod_add_sync__pch.h /usr/share/verilator/include/verilated.h \
/usr/share/verilator/include/verilated_config.h \
/usr/share/verilator/include/verilatedos.h \
/usr/share/verilator/include/verilated_types.h \
/usr/share/verilator/include/verilated_funcs.h Vmod_add_sync__Syms.h \
Vmod_add_sync.h Vmod_add_sync___024root.h Vmod_add_sync___024root__0.cpp \
Vmod_add_sync___024root__Slow.cpp Vmod_add_sync___024root__0__Slow.cpp \
Vmod_add_sync__Syms__Slow.cpp

View File

@@ -0,0 +1,38 @@
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Symbol table internal header
//
// Internal details; most calling programs do not need this header,
// unless using verilator public meta comments.
#ifndef VERILATED_VMOD_ADD_SYNC__SYMS_H_
#define VERILATED_VMOD_ADD_SYNC__SYMS_H_ // guard
#include "verilated.h"
// INCLUDE MODEL CLASS
#include "Vmod_add_sync.h"
// INCLUDE MODULE CLASSES
#include "Vmod_add_sync___024root.h"
// SYMS CLASS (contains all model state)
class alignas(VL_CACHE_LINE_BYTES) Vmod_add_sync__Syms final : public VerilatedSyms {
public:
// INTERNAL STATE
Vmod_add_sync* const __Vm_modelp;
VlDeleter __Vm_deleter;
bool __Vm_didInit = false;
// MODULE INSTANCE STATE
Vmod_add_sync___024root TOP;
// CONSTRUCTORS
Vmod_add_sync__Syms(VerilatedContext* contextp, const char* namep, Vmod_add_sync* modelp);
~Vmod_add_sync__Syms();
// METHODS
const char* name() const { return TOP.vlNamep; }
};
#endif // guard

View File

@@ -0,0 +1,28 @@
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Symbol table implementation internals
#include "Vmod_add_sync__pch.h"
Vmod_add_sync__Syms::Vmod_add_sync__Syms(VerilatedContext* contextp, const char* namep, Vmod_add_sync* modelp)
: VerilatedSyms{contextp}
// Setup internal state of the Syms class
, __Vm_modelp{modelp}
// Setup top module instance
, TOP{this, namep}
{
// Check resources
Verilated::stackCheck(250);
// Setup sub module instances
// Configure time unit / time precision
_vm_contextp__->timeunit(-12);
_vm_contextp__->timeprecision(-12);
// Setup each module's pointers to their submodules
// Setup each module's pointer back to symbol table (for public functions)
TOP.__Vconfigure(true);
// Setup scopes
}
Vmod_add_sync__Syms::~Vmod_add_sync__Syms() {
// Tear down scopes
// Tear down sub module instances
}

View File

@@ -0,0 +1,57 @@
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Design internal header
// See Vmod_add_sync.h for the primary calling header
#ifndef VERILATED_VMOD_ADD_SYNC___024ROOT_H_
#define VERILATED_VMOD_ADD_SYNC___024ROOT_H_ // guard
#include "verilated.h"
class Vmod_add_sync__Syms;
class alignas(VL_CACHE_LINE_BYTES) Vmod_add_sync___024root final {
public:
// DESIGN SPECIFIC STATE
VL_IN8(clk,0,0);
VL_IN8(rst_n,0,0);
VL_IN8(valid_i,0,0);
VL_OUT8(ready_o,0,0);
VL_OUT8(valid_o,0,0);
VL_IN8(ready_i,0,0);
CData/*0:0*/ mod_add_sync__DOT__u_pipe__DOT__valid_r;
CData/*0:0*/ __VstlFirstIteration;
CData/*0:0*/ __VstlPhaseResult;
CData/*0:0*/ __VicoFirstIteration;
CData/*0:0*/ __VicoPhaseResult;
CData/*0:0*/ __Vtrigprevexpr___TOP__clk__0;
CData/*0:0*/ __Vtrigprevexpr___TOP__rst_n__0;
CData/*0:0*/ __VactPhaseResult;
CData/*0:0*/ __VnbaPhaseResult;
VL_IN16(a,11,0);
VL_IN16(b,11,0);
VL_OUT16(sum,11,0);
SData/*12:0*/ mod_add_sync__DOT__add_raw;
SData/*11:0*/ mod_add_sync__DOT__u_pipe__DOT__data_r;
IData/*31:0*/ __VactIterCount;
VlUnpacked<QData/*63:0*/, 1> __VstlTriggered;
VlUnpacked<QData/*63:0*/, 1> __VicoTriggered;
VlUnpacked<QData/*63:0*/, 1> __VactTriggered;
VlUnpacked<QData/*63:0*/, 1> __VnbaTriggered;
// INTERNAL VARIABLES
Vmod_add_sync__Syms* vlSymsp;
const char* vlNamep;
// CONSTRUCTORS
Vmod_add_sync___024root(Vmod_add_sync__Syms* symsp, const char* namep);
~Vmod_add_sync___024root();
VL_UNCOPYABLE(Vmod_add_sync___024root);
// INTERNAL METHODS
void __Vconfigure(bool first);
};
#endif // guard

View File

@@ -0,0 +1,299 @@
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Design implementation internals
// See Vmod_add_sync.h for the primary calling header
#include "Vmod_add_sync__pch.h"
void Vmod_add_sync___024root___eval_triggers_vec__ico(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval_triggers_vec__ico\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Body
vlSelfRef.__VicoTriggered[0U] = ((0xfffffffffffffffeULL
& vlSelfRef.__VicoTriggered[0U])
| (IData)((IData)(vlSelfRef.__VicoFirstIteration)));
}
bool Vmod_add_sync___024root___trigger_anySet__ico(const VlUnpacked<QData/*63:0*/, 1> &in) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___trigger_anySet__ico\n"); );
// Locals
IData/*31:0*/ n;
// Body
n = 0U;
do {
if (in[n]) {
return (1U);
}
n = ((IData)(1U) + n);
} while ((1U > n));
return (0U);
}
void Vmod_add_sync___024root___ico_sequent__TOP__0(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___ico_sequent__TOP__0\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Body
vlSelfRef.mod_add_sync__DOT__add_raw = (0x00001fffU
& ((IData)(vlSelfRef.a)
+ (IData)(vlSelfRef.b)));
vlSelfRef.ready_o = (1U & ((~ (IData)(vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r))
| (IData)(vlSelfRef.ready_i)));
}
void Vmod_add_sync___024root___eval_ico(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval_ico\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Body
if ((1ULL & vlSelfRef.__VicoTriggered[0U])) {
vlSelfRef.mod_add_sync__DOT__add_raw = (0x00001fffU
& ((IData)(vlSelfRef.a)
+ (IData)(vlSelfRef.b)));
vlSelfRef.ready_o = (1U & ((~ (IData)(vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r))
| (IData)(vlSelfRef.ready_i)));
}
}
#ifdef VL_DEBUG
VL_ATTR_COLD void Vmod_add_sync___024root___dump_triggers__ico(const VlUnpacked<QData/*63:0*/, 1> &triggers, const std::string &tag);
#endif // VL_DEBUG
bool Vmod_add_sync___024root___eval_phase__ico(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval_phase__ico\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Locals
CData/*0:0*/ __VicoExecute;
// Body
Vmod_add_sync___024root___eval_triggers_vec__ico(vlSelf);
#ifdef VL_DEBUG
if (VL_UNLIKELY(vlSymsp->_vm_contextp__->debug())) {
Vmod_add_sync___024root___dump_triggers__ico(vlSelfRef.__VicoTriggered, "ico"s);
}
#endif
__VicoExecute = Vmod_add_sync___024root___trigger_anySet__ico(vlSelfRef.__VicoTriggered);
if (__VicoExecute) {
Vmod_add_sync___024root___eval_ico(vlSelf);
}
return (__VicoExecute);
}
void Vmod_add_sync___024root___eval_triggers_vec__act(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval_triggers_vec__act\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Body
vlSelfRef.__VactTriggered[0U] = (QData)((IData)(
((((~ (IData)(vlSelfRef.rst_n))
& (IData)(vlSelfRef.__Vtrigprevexpr___TOP__rst_n__0))
<< 1U)
| ((IData)(vlSelfRef.clk)
& (~ (IData)(vlSelfRef.__Vtrigprevexpr___TOP__clk__0))))));
vlSelfRef.__Vtrigprevexpr___TOP__clk__0 = vlSelfRef.clk;
vlSelfRef.__Vtrigprevexpr___TOP__rst_n__0 = vlSelfRef.rst_n;
}
bool Vmod_add_sync___024root___trigger_anySet__act(const VlUnpacked<QData/*63:0*/, 1> &in) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___trigger_anySet__act\n"); );
// Locals
IData/*31:0*/ n;
// Body
n = 0U;
do {
if (in[n]) {
return (1U);
}
n = ((IData)(1U) + n);
} while ((1U > n));
return (0U);
}
void Vmod_add_sync___024root___nba_sequent__TOP__0(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___nba_sequent__TOP__0\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Body
if (vlSelfRef.rst_n) {
if (((IData)(vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r)
& (IData)(vlSelfRef.ready_i))) {
vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r = 0U;
}
if (((IData)(vlSelfRef.valid_i) & (IData)(vlSelfRef.ready_o))) {
vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r = 1U;
vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__data_r
= (0x00000fffU & ((0x0d01U > (IData)(vlSelfRef.mod_add_sync__DOT__add_raw))
? (IData)(vlSelfRef.mod_add_sync__DOT__add_raw)
: ((IData)(vlSelfRef.mod_add_sync__DOT__add_raw)
- (IData)(0x0d01U))));
}
} else {
vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r = 0U;
vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__data_r = 0U;
}
vlSelfRef.valid_o = vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r;
vlSelfRef.ready_o = (1U & ((~ (IData)(vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r))
| (IData)(vlSelfRef.ready_i)));
vlSelfRef.sum = vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__data_r;
}
void Vmod_add_sync___024root___eval_nba(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval_nba\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Body
if ((3ULL & vlSelfRef.__VnbaTriggered[0U])) {
if (vlSelfRef.rst_n) {
if (((IData)(vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r)
& (IData)(vlSelfRef.ready_i))) {
vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r = 0U;
}
if (((IData)(vlSelfRef.valid_i) & (IData)(vlSelfRef.ready_o))) {
vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r = 1U;
vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__data_r
= (0x00000fffU & ((0x0d01U > (IData)(vlSelfRef.mod_add_sync__DOT__add_raw))
? (IData)(vlSelfRef.mod_add_sync__DOT__add_raw)
: ((IData)(vlSelfRef.mod_add_sync__DOT__add_raw)
- (IData)(0x0d01U))));
}
} else {
vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r = 0U;
vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__data_r = 0U;
}
vlSelfRef.valid_o = vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r;
vlSelfRef.ready_o = (1U & ((~ (IData)(vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r))
| (IData)(vlSelfRef.ready_i)));
vlSelfRef.sum = vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__data_r;
}
}
void Vmod_add_sync___024root___trigger_orInto__act_vec_vec(VlUnpacked<QData/*63:0*/, 1> &out, const VlUnpacked<QData/*63:0*/, 1> &in) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___trigger_orInto__act_vec_vec\n"); );
// Locals
IData/*31:0*/ n;
// Body
n = 0U;
do {
out[n] = (out[n] | in[n]);
n = ((IData)(1U) + n);
} while ((0U >= n));
}
#ifdef VL_DEBUG
VL_ATTR_COLD void Vmod_add_sync___024root___dump_triggers__act(const VlUnpacked<QData/*63:0*/, 1> &triggers, const std::string &tag);
#endif // VL_DEBUG
bool Vmod_add_sync___024root___eval_phase__act(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval_phase__act\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Body
Vmod_add_sync___024root___eval_triggers_vec__act(vlSelf);
#ifdef VL_DEBUG
if (VL_UNLIKELY(vlSymsp->_vm_contextp__->debug())) {
Vmod_add_sync___024root___dump_triggers__act(vlSelfRef.__VactTriggered, "act"s);
}
#endif
Vmod_add_sync___024root___trigger_orInto__act_vec_vec(vlSelfRef.__VnbaTriggered, vlSelfRef.__VactTriggered);
return (0U);
}
void Vmod_add_sync___024root___trigger_clear__act(VlUnpacked<QData/*63:0*/, 1> &out) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___trigger_clear__act\n"); );
// Locals
IData/*31:0*/ n;
// Body
n = 0U;
do {
out[n] = 0ULL;
n = ((IData)(1U) + n);
} while ((1U > n));
}
bool Vmod_add_sync___024root___eval_phase__nba(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval_phase__nba\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Locals
CData/*0:0*/ __VnbaExecute;
// Body
__VnbaExecute = Vmod_add_sync___024root___trigger_anySet__act(vlSelfRef.__VnbaTriggered);
if (__VnbaExecute) {
Vmod_add_sync___024root___eval_nba(vlSelf);
Vmod_add_sync___024root___trigger_clear__act(vlSelfRef.__VnbaTriggered);
}
return (__VnbaExecute);
}
void Vmod_add_sync___024root___eval(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Locals
IData/*31:0*/ __VicoIterCount;
IData/*31:0*/ __VnbaIterCount;
// Body
__VicoIterCount = 0U;
vlSelfRef.__VicoFirstIteration = 1U;
do {
if (VL_UNLIKELY(((0x00000064U < __VicoIterCount)))) {
#ifdef VL_DEBUG
Vmod_add_sync___024root___dump_triggers__ico(vlSelfRef.__VicoTriggered, "ico"s);
#endif
VL_FATAL_MT("/home/fallensigh/Dev/mlkem/sync_rtl/mod_add/mod_add_sync.v", 14, "", "DIDNOTCONVERGE: Input combinational region did not converge after '--converge-limit' of 100 tries");
}
__VicoIterCount = ((IData)(1U) + __VicoIterCount);
vlSelfRef.__VicoPhaseResult = Vmod_add_sync___024root___eval_phase__ico(vlSelf);
vlSelfRef.__VicoFirstIteration = 0U;
} while (vlSelfRef.__VicoPhaseResult);
__VnbaIterCount = 0U;
do {
if (VL_UNLIKELY(((0x00000064U < __VnbaIterCount)))) {
#ifdef VL_DEBUG
Vmod_add_sync___024root___dump_triggers__act(vlSelfRef.__VnbaTriggered, "nba"s);
#endif
VL_FATAL_MT("/home/fallensigh/Dev/mlkem/sync_rtl/mod_add/mod_add_sync.v", 14, "", "DIDNOTCONVERGE: NBA region did not converge after '--converge-limit' of 100 tries");
}
__VnbaIterCount = ((IData)(1U) + __VnbaIterCount);
vlSelfRef.__VactIterCount = 0U;
do {
if (VL_UNLIKELY(((0x00000064U < vlSelfRef.__VactIterCount)))) {
#ifdef VL_DEBUG
Vmod_add_sync___024root___dump_triggers__act(vlSelfRef.__VactTriggered, "act"s);
#endif
VL_FATAL_MT("/home/fallensigh/Dev/mlkem/sync_rtl/mod_add/mod_add_sync.v", 14, "", "DIDNOTCONVERGE: Active region did not converge after '--converge-limit' of 100 tries");
}
vlSelfRef.__VactIterCount = ((IData)(1U)
+ vlSelfRef.__VactIterCount);
vlSelfRef.__VactPhaseResult = Vmod_add_sync___024root___eval_phase__act(vlSelf);
} while (vlSelfRef.__VactPhaseResult);
vlSelfRef.__VnbaPhaseResult = Vmod_add_sync___024root___eval_phase__nba(vlSelf);
} while (vlSelfRef.__VnbaPhaseResult);
}
#ifdef VL_DEBUG
void Vmod_add_sync___024root___eval_debug_assertions(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval_debug_assertions\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Body
if (VL_UNLIKELY(((vlSelfRef.clk & 0xfeU)))) {
Verilated::overWidthError("clk");
}
if (VL_UNLIKELY(((vlSelfRef.rst_n & 0xfeU)))) {
Verilated::overWidthError("rst_n");
}
if (VL_UNLIKELY(((vlSelfRef.a & 0xf000U)))) {
Verilated::overWidthError("a");
}
if (VL_UNLIKELY(((vlSelfRef.b & 0xf000U)))) {
Verilated::overWidthError("b");
}
if (VL_UNLIKELY(((vlSelfRef.valid_i & 0xfeU)))) {
Verilated::overWidthError("valid_i");
}
if (VL_UNLIKELY(((vlSelfRef.ready_i & 0xfeU)))) {
Verilated::overWidthError("ready_i");
}
}
#endif // VL_DEBUG

View File

@@ -0,0 +1,210 @@
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Design implementation internals
// See Vmod_add_sync.h for the primary calling header
#include "Vmod_add_sync__pch.h"
VL_ATTR_COLD void Vmod_add_sync___024root___eval_static(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval_static\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Body
vlSelfRef.__Vtrigprevexpr___TOP__clk__0 = vlSelfRef.clk;
vlSelfRef.__Vtrigprevexpr___TOP__rst_n__0 = vlSelfRef.rst_n;
}
VL_ATTR_COLD void Vmod_add_sync___024root___eval_initial(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval_initial\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
}
VL_ATTR_COLD void Vmod_add_sync___024root___eval_final(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval_final\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
}
#ifdef VL_DEBUG
VL_ATTR_COLD void Vmod_add_sync___024root___dump_triggers__stl(const VlUnpacked<QData/*63:0*/, 1> &triggers, const std::string &tag);
#endif // VL_DEBUG
VL_ATTR_COLD bool Vmod_add_sync___024root___eval_phase__stl(Vmod_add_sync___024root* vlSelf);
VL_ATTR_COLD void Vmod_add_sync___024root___eval_settle(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval_settle\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Locals
IData/*31:0*/ __VstlIterCount;
// Body
__VstlIterCount = 0U;
vlSelfRef.__VstlFirstIteration = 1U;
do {
if (VL_UNLIKELY(((0x00000064U < __VstlIterCount)))) {
#ifdef VL_DEBUG
Vmod_add_sync___024root___dump_triggers__stl(vlSelfRef.__VstlTriggered, "stl"s);
#endif
VL_FATAL_MT("/home/fallensigh/Dev/mlkem/sync_rtl/mod_add/mod_add_sync.v", 14, "", "DIDNOTCONVERGE: Settle region did not converge after '--converge-limit' of 100 tries");
}
__VstlIterCount = ((IData)(1U) + __VstlIterCount);
vlSelfRef.__VstlPhaseResult = Vmod_add_sync___024root___eval_phase__stl(vlSelf);
vlSelfRef.__VstlFirstIteration = 0U;
} while (vlSelfRef.__VstlPhaseResult);
}
VL_ATTR_COLD void Vmod_add_sync___024root___eval_triggers_vec__stl(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval_triggers_vec__stl\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Body
vlSelfRef.__VstlTriggered[0U] = ((0xfffffffffffffffeULL
& vlSelfRef.__VstlTriggered[0U])
| (IData)((IData)(vlSelfRef.__VstlFirstIteration)));
}
VL_ATTR_COLD bool Vmod_add_sync___024root___trigger_anySet__stl(const VlUnpacked<QData/*63:0*/, 1> &in);
#ifdef VL_DEBUG
VL_ATTR_COLD void Vmod_add_sync___024root___dump_triggers__stl(const VlUnpacked<QData/*63:0*/, 1> &triggers, const std::string &tag) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___dump_triggers__stl\n"); );
// Body
if ((1U & (~ (IData)(Vmod_add_sync___024root___trigger_anySet__stl(triggers))))) {
VL_DBG_MSGS(" No '" + tag + "' region triggers active\n");
}
if ((1U & (IData)(triggers[0U]))) {
VL_DBG_MSGS(" '" + tag + "' region trigger index 0 is active: Internal 'stl' trigger - first iteration\n");
}
}
#endif // VL_DEBUG
VL_ATTR_COLD bool Vmod_add_sync___024root___trigger_anySet__stl(const VlUnpacked<QData/*63:0*/, 1> &in) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___trigger_anySet__stl\n"); );
// Locals
IData/*31:0*/ n;
// Body
n = 0U;
do {
if (in[n]) {
return (1U);
}
n = ((IData)(1U) + n);
} while ((1U > n));
return (0U);
}
VL_ATTR_COLD void Vmod_add_sync___024root___stl_sequent__TOP__0(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___stl_sequent__TOP__0\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Body
vlSelfRef.valid_o = vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r;
vlSelfRef.sum = vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__data_r;
vlSelfRef.mod_add_sync__DOT__add_raw = (0x00001fffU
& ((IData)(vlSelfRef.a)
+ (IData)(vlSelfRef.b)));
vlSelfRef.ready_o = (1U & ((~ (IData)(vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r))
| (IData)(vlSelfRef.ready_i)));
}
VL_ATTR_COLD void Vmod_add_sync___024root___eval_stl(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval_stl\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Body
if ((1ULL & vlSelfRef.__VstlTriggered[0U])) {
vlSelfRef.valid_o = vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r;
vlSelfRef.sum = vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__data_r;
vlSelfRef.mod_add_sync__DOT__add_raw = (0x00001fffU
& ((IData)(vlSelfRef.a)
+ (IData)(vlSelfRef.b)));
vlSelfRef.ready_o = (1U & ((~ (IData)(vlSelfRef.mod_add_sync__DOT__u_pipe__DOT__valid_r))
| (IData)(vlSelfRef.ready_i)));
}
}
VL_ATTR_COLD bool Vmod_add_sync___024root___eval_phase__stl(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___eval_phase__stl\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Locals
CData/*0:0*/ __VstlExecute;
// Body
Vmod_add_sync___024root___eval_triggers_vec__stl(vlSelf);
#ifdef VL_DEBUG
if (VL_UNLIKELY(vlSymsp->_vm_contextp__->debug())) {
Vmod_add_sync___024root___dump_triggers__stl(vlSelfRef.__VstlTriggered, "stl"s);
}
#endif
__VstlExecute = Vmod_add_sync___024root___trigger_anySet__stl(vlSelfRef.__VstlTriggered);
if (__VstlExecute) {
Vmod_add_sync___024root___eval_stl(vlSelf);
}
return (__VstlExecute);
}
bool Vmod_add_sync___024root___trigger_anySet__ico(const VlUnpacked<QData/*63:0*/, 1> &in);
#ifdef VL_DEBUG
VL_ATTR_COLD void Vmod_add_sync___024root___dump_triggers__ico(const VlUnpacked<QData/*63:0*/, 1> &triggers, const std::string &tag) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___dump_triggers__ico\n"); );
// Body
if ((1U & (~ (IData)(Vmod_add_sync___024root___trigger_anySet__ico(triggers))))) {
VL_DBG_MSGS(" No '" + tag + "' region triggers active\n");
}
if ((1U & (IData)(triggers[0U]))) {
VL_DBG_MSGS(" '" + tag + "' region trigger index 0 is active: Internal 'ico' trigger - first iteration\n");
}
}
#endif // VL_DEBUG
bool Vmod_add_sync___024root___trigger_anySet__act(const VlUnpacked<QData/*63:0*/, 1> &in);
#ifdef VL_DEBUG
VL_ATTR_COLD void Vmod_add_sync___024root___dump_triggers__act(const VlUnpacked<QData/*63:0*/, 1> &triggers, const std::string &tag) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___dump_triggers__act\n"); );
// Body
if ((1U & (~ (IData)(Vmod_add_sync___024root___trigger_anySet__act(triggers))))) {
VL_DBG_MSGS(" No '" + tag + "' region triggers active\n");
}
if ((1U & (IData)(triggers[0U]))) {
VL_DBG_MSGS(" '" + tag + "' region trigger index 0 is active: @(posedge clk)\n");
}
if ((1U & (IData)((triggers[0U] >> 1U)))) {
VL_DBG_MSGS(" '" + tag + "' region trigger index 1 is active: @(negedge rst_n)\n");
}
}
#endif // VL_DEBUG
VL_ATTR_COLD void Vmod_add_sync___024root___ctor_var_reset(Vmod_add_sync___024root* vlSelf) {
VL_DEBUG_IF(VL_DBG_MSGF("+ Vmod_add_sync___024root___ctor_var_reset\n"); );
Vmod_add_sync__Syms* const __restrict vlSymsp VL_ATTR_UNUSED = vlSelf->vlSymsp;
auto& vlSelfRef = std::ref(*vlSelf).get();
// Body
const uint64_t __VscopeHash = VL_MURMUR64_HASH(vlSelf->vlNamep);
vlSelf->clk = VL_SCOPED_RAND_RESET_I(1, __VscopeHash, 16707436170211756652ull);
vlSelf->rst_n = VL_SCOPED_RAND_RESET_I(1, __VscopeHash, 1638864771569018232ull);
vlSelf->a = VL_SCOPED_RAND_RESET_I(12, __VscopeHash, 510903276987443985ull);
vlSelf->b = VL_SCOPED_RAND_RESET_I(12, __VscopeHash, 16900879642891266615ull);
vlSelf->valid_i = VL_SCOPED_RAND_RESET_I(1, __VscopeHash, 550966959580451262ull);
vlSelf->ready_o = VL_SCOPED_RAND_RESET_I(1, __VscopeHash, 6223107695775132031ull);
vlSelf->sum = VL_SCOPED_RAND_RESET_I(12, __VscopeHash, 17823321413984766096ull);
vlSelf->valid_o = VL_SCOPED_RAND_RESET_I(1, __VscopeHash, 10854271546065566948ull);
vlSelf->ready_i = VL_SCOPED_RAND_RESET_I(1, __VscopeHash, 2487444212943817592ull);
vlSelf->mod_add_sync__DOT__add_raw = VL_SCOPED_RAND_RESET_I(13, __VscopeHash, 3056689789628782752ull);
vlSelf->mod_add_sync__DOT__u_pipe__DOT__valid_r = VL_SCOPED_RAND_RESET_I(1, __VscopeHash, 2581127527985639139ull);
vlSelf->mod_add_sync__DOT__u_pipe__DOT__data_r = VL_SCOPED_RAND_RESET_I(12, __VscopeHash, 895104528192337104ull);
for (int __Vi0 = 0; __Vi0 < 1; ++__Vi0) {
vlSelf->__VstlTriggered[__Vi0] = 0;
}
for (int __Vi0 = 0; __Vi0 < 1; ++__Vi0) {
vlSelf->__VicoTriggered[__Vi0] = 0;
}
for (int __Vi0 = 0; __Vi0 < 1; ++__Vi0) {
vlSelf->__VactTriggered[__Vi0] = 0;
}
vlSelf->__Vtrigprevexpr___TOP__clk__0 = 0;
vlSelf->__Vtrigprevexpr___TOP__rst_n__0 = 0;
for (int __Vi0 = 0; __Vi0 < 1; ++__Vi0) {
vlSelf->__VnbaTriggered[__Vi0] = 0;
}
}

View File

@@ -0,0 +1,23 @@
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Design implementation internals
// See Vmod_add_sync.h for the primary calling header
#include "Vmod_add_sync__pch.h"
void Vmod_add_sync___024root___ctor_var_reset(Vmod_add_sync___024root* vlSelf);
Vmod_add_sync___024root::Vmod_add_sync___024root(Vmod_add_sync__Syms* symsp, const char* namep)
{
vlSymsp = symsp;
vlNamep = strdup(namep);
// Reset structure values
Vmod_add_sync___024root___ctor_var_reset(this);
}
void Vmod_add_sync___024root::__Vconfigure(bool first) {
(void)first; // Prevent unused variable warning
}
Vmod_add_sync___024root::~Vmod_add_sync___024root() {
VL_DO_DANGLING(std::free(const_cast<char*>(vlNamep)), vlNamep);
}

View File

@@ -0,0 +1,27 @@
// Verilated -*- C++ -*-
// DESCRIPTION: Verilator output: Precompiled header
//
// Internal details; most user sources do not need this header,
// unless using verilator public meta comments.
// Suggest use Vmod_add_sync.h instead.
#ifndef VERILATED_VMOD_ADD_SYNC__PCH_H_
#define VERILATED_VMOD_ADD_SYNC__PCH_H_ // guard
// GCC and Clang only will precompile headers (PCH) for the first header.
// So, make sure this is the one and only PCH.
// If multiple module's includes are needed, use individual includes.
#ifdef VL_PCH_INCLUDED
# error "Including multiple precompiled header files"
#endif
#define VL_PCH_INCLUDED
#include "verilated.h"
#include "Vmod_add_sync__Syms.h"
#include "Vmod_add_sync.h"
// Additional include files added using '--compiler-include'
#endif // guard

View File

@@ -0,0 +1 @@
/home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync.cpp /home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync.h /home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync.mk /home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync__Syms.h /home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync__Syms__Slow.cpp /home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync___024root.h /home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync___024root__0.cpp /home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync___024root__0__Slow.cpp /home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync___024root__Slow.cpp /home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync__pch.h /home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync__ver.d /home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync_classes.mk : /usr/bin/verilator_bin /home/fallensigh/Dev/mlkem/sync_rtl/common/defines.vh /home/fallensigh/Dev/mlkem/sync_rtl/common/pipeline_reg.v /home/fallensigh/Dev/mlkem/sync_rtl/mod_add/mod_add_sync.v /usr/bin/verilator_bin /usr/share/verilator/include/verilated_std.sv /usr/share/verilator/include/verilated_std_waiver.vlt

View File

@@ -0,0 +1,21 @@
# DESCRIPTION: Verilator output: Timestamp data for --skip-identical. Delete at will.
C "-Wall --cc --build --timing --exe --top-module mod_add_sync +incdir+/home/fallensigh/Dev/mlkem /home/fallensigh/Dev/mlkem/sync_rtl/common/pipeline_reg.v /home/fallensigh/Dev/mlkem/sync_rtl/mod_add/mod_add_sync.v /home/fallensigh/Dev/mlkem/sync_rtl/mod_add/TB/tb_mod_add.cpp -Mdir /home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir"
S 175 4850124 1782295073 570083907 1782295073 570083907 "xrUlJO6R6GcXgqHQvRrBsxDVjbRsCwGdWjBVaFOJ" "/home/fallensigh/Dev/mlkem/sync_rtl/common/defines.vh"
S 1425 4850211 1782295084 627669761 1782295084 627669761 "dyCBNlzlULhx5fbud3BxlMAYl0N8KUs44LFK6UdD" "/home/fallensigh/Dev/mlkem/sync_rtl/common/pipeline_reg.v"
S 1346 4850217 1782295089 653481527 1782295089 653481527 "j8yBA3CTiFqtcJsMBC17M1w9KeLigVAWfAWkviCd" "/home/fallensigh/Dev/mlkem/sync_rtl/mod_add/mod_add_sync.v"
T 3507 4852471 1782301214 673354776 1782301214 673354776 "unhashed" "/home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync.cpp"
T 3718 4852470 1782301214 673257614 1782301214 673257614 "unhashed" "/home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync.h"
T 2074 4852478 1782301214 674594463 1782301214 674594463 "unhashed" "/home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync.mk"
T 1001 4852469 1782301214 673151113 1782301214 673151113 "unhashed" "/home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync__Syms.h"
T 906 4852468 1782301214 673020995 1782301214 673020995 "unhashed" "/home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync__Syms__Slow.cpp"
T 1668 4852473 1782301214 673490013 1782301214 673490013 "unhashed" "/home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync___024root.h"
T 13550 4852476 1782301214 674320105 1782301214 674320105 "unhashed" "/home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync___024root__0.cpp"
T 10280 4852475 1782301214 673849208 1782301214 673849208 "unhashed" "/home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync___024root__0__Slow.cpp"
T 731 4852474 1782301214 673556783 1782301214 673556783 "unhashed" "/home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync___024root__Slow.cpp"
T 790 4852472 1782301214 673406518 1782301214 673406518 "unhashed" "/home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync__pch.h"
T 1411 4852479 1782301214 674594463 1782301214 674594463 "unhashed" "/home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync__ver.d"
T 0 0 1782301214 674594463 1782301214 674594463 "unhashed" "/home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync__verFiles.dat"
T 1669 4852477 1782301214 674493042 1782301214 674493042 "unhashed" "/home/fallensigh/Dev/mlkem/test_framework/modules/mod_add/obj_dir/Vmod_add_sync_classes.mk"
S 11443816 4098390 1782293569 546470124 1775088000 0 "unhashed" "/usr/bin/verilator_bin"
S 7907 4098454 1782293569 567160683 1772288519 0 "sXuDUu38NDUbFZnNSJ9miREFRbcKSVZXW2nyoVrW" "/usr/share/verilator/include/verilated_std.sv"
S 3224 4098455 1782293569 567160683 1772288519 0 "Hydzkv9X77JH03JyZeFi7tBFnQaHV7yknXQxBZFr" "/usr/share/verilator/include/verilated_std_waiver.vlt"

View File

@@ -0,0 +1,51 @@
# Verilated -*- Makefile -*-
# DESCRIPTION: Verilator output: Make include file with class lists
#
# This file lists generated Verilated files, for including in higher level makefiles.
# See Vmod_add_sync.mk for the caller.
### Switches...
# C11 constructs required? 0/1 (always on now)
VM_C11 = 1
# Timing enabled? 0/1
VM_TIMING = 0
# Coverage output mode? 0/1 (from --coverage)
VM_COVERAGE = 0
# Parallel builds? 0/1 (from --output-split)
VM_PARALLEL_BUILDS = 0
# Tracing output mode? 0/1 (from --trace-fst/--trace-saif/--trace-vcd)
VM_TRACE = 0
# Tracing output mode in FST format? 0/1 (from --trace-fst)
VM_TRACE_FST = 0
# Tracing output mode in SAIF format? 0/1 (from --trace-saif)
VM_TRACE_SAIF = 0
# Tracing output mode in VCD format? 0/1 (from --trace-vcd)
VM_TRACE_VCD = 0
### Object file lists...
# Generated module classes, fast-path, compile with highest optimization
VM_CLASSES_FAST += \
Vmod_add_sync \
Vmod_add_sync___024root__0 \
# Generated module classes, non-fast-path, compile with low/medium optimization
VM_CLASSES_SLOW += \
Vmod_add_sync___024root__Slow \
Vmod_add_sync___024root__0__Slow \
# Generated support classes, fast-path, compile with highest optimization
VM_SUPPORT_FAST += \
# Generated support classes, non-fast-path, compile with low/medium optimization
VM_SUPPORT_SLOW += \
Vmod_add_sync__Syms__Slow \
# Global classes, need linked once per executable, fast-path, compile with highest optimization
VM_GLOBAL_FAST += \
verilated \
verilated_threads \
# Global classes, need linked once per executable, non-fast-path, compile with low/medium optimization
VM_GLOBAL_SLOW += \
# Verilated -*- Makefile -*-

View File

@@ -0,0 +1,7 @@
tb_mod_add.o: \
/home/fallensigh/Dev/mlkem/sync_rtl/mod_add/TB/tb_mod_add.cpp \
Vmod_add_sync.h /usr/share/verilator/include/verilated.h \
/usr/share/verilator/include/verilated_config.h \
/usr/share/verilator/include/verilatedos.h \
/usr/share/verilator/include/verilated_types.h \
/usr/share/verilator/include/verilated_funcs.h

Binary file not shown.

View File

@@ -0,0 +1,12 @@
verilated.o: /usr/share/verilator/include/verilated.cpp \
/usr/share/verilator/include/verilated_config.h \
/usr/share/verilator/include/verilatedos.h \
/usr/share/verilator/include/verilated_imp.h \
/usr/share/verilator/include/verilated.h \
/usr/share/verilator/include/verilated_types.h \
/usr/share/verilator/include/verilated_funcs.h \
/usr/share/verilator/include/verilated_syms.h \
/usr/share/verilator/include/verilated_sym_props.h \
/usr/share/verilator/include/verilated_threads.h \
/usr/share/verilator/include/verilated_trace.h \
/usr/share/verilator/include/verilatedos_c.h

Binary file not shown.

View File

@@ -0,0 +1,7 @@
verilated_threads.o: /usr/share/verilator/include/verilated_threads.cpp \
/usr/share/verilator/include/verilatedos.h \
/usr/share/verilator/include/verilated_threads.h \
/usr/share/verilator/include/verilated.h \
/usr/share/verilator/include/verilated_config.h \
/usr/share/verilator/include/verilated_types.h \
/usr/share/verilator/include/verilated_funcs.h

View File

@@ -0,0 +1,17 @@
{
"module": "mod_add",
"rtl_top": "sync_rtl/mod_add/mod_add_sync.v",
"rtl_deps": ["sync_rtl/common/pipeline_reg.v"],
"tb_cpp": "sync_rtl/mod_add/TB/tb_mod_add.cpp",
"simulator": "verilator",
"timeout_s": 30,
"cases": [
{
"id": "basic",
"description": "Random (a+b) mod Q pairs, no overflow, with overflow, edge cases",
"params": {},
"num_vectors": 50,
"tolerance": "bit_exact"
}
]
}

View File

@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<title>ML-KEM Test Report</title>
<style>
body { font-family: monospace; background: #1e1e1e; color: #d4d4d4;
padding: 20px; }
h1 { color: #4CAF50; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #444; padding: 8px; text-align: left; }
th { background: #333; }
</style>
</head>
<body>
<h1>ALL TESTS PASSED</h1>
<p>Generated: 20260624_193336<br>
Total: 0 vectors (0 pass, 0 fail)<br>
Elapsed: 0.65s</p>
<table>
<tr><th>Module</th><th>Status</th><th>Pass</th><th>Fail</th><th>Time</th></tr>
<tr>
<td>mod_add</td>
<td style="color:#F44336">COMPILE_ERROR</td>
<td>0</td>
<td>0</td>
<td>0.65s</td>
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<title>ML-KEM Test Report</title>
<style>
body { font-family: monospace; background: #1e1e1e; color: #d4d4d4;
padding: 20px; }
h1 { color: #F44336; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #444; padding: 8px; text-align: left; }
th { background: #333; }
</style>
</head>
<body>
<h1>SOME TESTS FAILED</h1>
<p>Generated: 20260624_194016<br>
Total: 50 vectors (0 pass, 50 fail)<br>
Elapsed: 1.92s</p>
<table>
<tr><th>Module</th><th>Status</th><th>Pass</th><th>Fail</th><th>Time</th></tr>
<tr>
<td>mod_add</td>
<td style="color:#F44336">FAIL</td>
<td>0</td>
<td>50</td>
<td>1.92s</td>
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<title>ML-KEM Test Report</title>
<style>
body { font-family: monospace; background: #1e1e1e; color: #d4d4d4;
padding: 20px; }
h1 { color: #F44336; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #444; padding: 8px; text-align: left; }
th { background: #333; }
</style>
</head>
<body>
<h1>SOME TESTS FAILED</h1>
<p>Generated: 20260624_194123<br>
Total: 50 vectors (0 pass, 50 fail)<br>
Elapsed: 1.04s</p>
<table>
<tr><th>Module</th><th>Status</th><th>Pass</th><th>Fail</th><th>Time</th></tr>
<tr>
<td>mod_add</td>
<td style="color:#F44336">FAIL</td>
<td>0</td>
<td>50</td>
<td>1.03s</td>
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<title>ML-KEM Test Report</title>
<style>
body { font-family: monospace; background: #1e1e1e; color: #d4d4d4;
padding: 20px; }
h1 { color: #4CAF50; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #444; padding: 8px; text-align: left; }
th { background: #333; }
</style>
</head>
<body>
<h1>ALL TESTS PASSED</h1>
<p>Generated: 20260624_194216<br>
Total: 50 vectors (50 pass, 0 fail)<br>
Elapsed: 1.09s</p>
<table>
<tr><th>Module</th><th>Status</th><th>Pass</th><th>Fail</th><th>Time</th></tr>
<tr>
<td>mod_add</td>
<td style="color:#4CAF50">PASS</td>
<td>50</td>
<td>0</td>
<td>1.09s</td>
</tr>
</table>
</body>
</html>

110
test_framework/run_all.py Executable file
View File

@@ -0,0 +1,110 @@
#!/usr/bin/env python3
"""run_all.py - CLI entry point for the ML-KEM RTL test framework.
Usage:
python3 run_all.py # Run all modules
python3 run_all.py --module mod_add # Run specific module
python3 run_all.py --list # List all registered modules
python3 run_all.py --module mod_add --case basic # Run single case
python3 run_all.py --quick # Quick mode (reduced vectors)
"""
import os
import sys
import time
import argparse
from pathlib import Path
# Ensure test_framework/lib is on the path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from lib.test_runner import TestRunner
from lib.reporter import Reporter
def main():
parser = argparse.ArgumentParser(
description='ML-KEM RTL Test Framework'
)
parser.add_argument('--module', '-m', type=str, default=None,
help='Run specific module only')
parser.add_argument('--case', '-c', type=str, default=None,
help='Run specific test case only')
parser.add_argument('--list', '-l', action='store_true',
help='List all registered modules')
parser.add_argument('--quick', '-q', action='store_true',
help='Quick mode (reduced vectors)')
parser.add_argument('--config', type=str, default='test_framework/config.json',
help='Path to config.json')
args = parser.parse_args()
# Change to project root (parent of test_framework/)
script_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.dirname(script_dir)
os.chdir(project_root)
runner = TestRunner(config_path=args.config)
modules = runner.discover_modules()
if args.list:
print("\nRegistered test modules:")
if not modules:
print(" (none found)")
for name, plan in sorted(modules.items()):
num_cases = len(plan.get('cases', []))
print(f" {name}: {num_cases} case(s)")
for case in plan.get('cases', []):
print(f" - {case['id']}: {case.get('description', '')}")
print()
return 0
if not modules:
print("No test modules found in test_framework/modules/")
return 1
# Determine which modules to run
if args.module:
if args.module not in modules:
print(f"Error: Module '{args.module}' not found.")
print(f"Available: {', '.join(sorted(modules.keys()))}")
return 1
to_run = [args.module]
else:
to_run = sorted(modules.keys())
# Run tests
results = {}
total_start = time.time()
reporter = Reporter(runner.config.get('report_root', 'test_framework/reports'))
for module_name in to_run:
print(f"\n{'='*50}")
print(f" Testing: {module_name}")
print(f"{'='*50}")
result = runner.run_module(
module_name,
quick=args.quick,
single_case=args.case
)
results[module_name] = result
if result['status'] == 'COMPILE_ERROR':
print(f" ERROR: Verilator compilation failed for {module_name}")
elif result['status'] == 'ERROR':
print(f" ERROR: {result.get('error', 'Unknown error')}")
elif result['status'] == 'NOT_FOUND':
print(f" ERROR: {result.get('error', 'Module not found')}")
total_elapsed = time.time() - total_start
# Print summary
all_pass = reporter.print_summary(results, total_elapsed)
return 0 if all_pass else 1
if __name__ == '__main__':
sys.exit(main())