Multi-agent MCTS + Evolutionary Algorithm framework for Verilog generation and PPA optimization.
MCEA-Verilog combines Monte Carlo Tree Search (MCTS) with Evolutionary Algorithms (EA) in a two-stage pipeline:
- Stage 1 (MCTS Forest): K parallel MCTS trees search for functionally correct Verilog designs using heterogeneous agents (Direct/C++/Python) with Chain-of-Thought reasoning.
- Stage 2 (EA-PPA): Evolutionary optimization of PPA (Power, Performance, Area) on graduated correct designs, with a Correctness Guard to repair functional regressions.
Two run modes are supported:
function_only: Evaluates functional correctness via Pass@k metric (n independent trials per problem).full: End-to-end pipeline producing Pareto-optimal designs across area, delay, and power.
- Python 3.9+
openaiPython package (for LLM API access)iverilogandvvp(Icarus Verilog, for functional simulation)- Full mode only: Yosys, OpenSTA, and optionally OpenROAD (for PPA evaluation)
pip install openai# Function-only mode with RTLLM dataset (uses code defaults)
python -m mcea_verilog.main \
--run_mode function_only \
--dataset rtllm \
--llm_model deepseek-r1 \
--llm_base_url https://api.deepseek.com/v1 \
--llm_api_key YOUR_KEY
# Function-only mode with VerilogEval
python -m mcea_verilog.main \
--run_mode function_only \
--dataset verilogeval \
--n_samples 5 --k_list 1,3,5
# Full mode with PPA optimization
python -m mcea_verilog.main \
--run_mode full \
--dataset rtllm \
--ppa_eval_level post_synth
# Run specific problems only
python -m mcea_verilog.main \
--run_mode function_only \
--dataset rtllm \
--problem_ids accu,adder_16bit \
--n_samples 3
# All parameters have code defaults — runs with no arguments:
python -m mcea_verilog.mainRTLLM — place under ./RTLLM/:
RTLLM/
├── accu/
│ ├── design_description.txt
│ ├── testbench.v
│ └── verified_accu.v
├── adder_8bit/
│ └── ...
VerilogEval — place under ./verilog-eval/dataset_spec-to-rtl/:
verilog-eval/dataset_spec-to-rtl/
├── Prob001_ref.sv
├── Prob001_test.sv
├── Prob002_ref.sv
├── Prob002_test.sv
└── ...
All parameters have code-level defaults in config.py. CLI arguments override them when provided. Key parameters:
| Parameter | Default | Description |
|---|---|---|
--run_mode |
function_only |
function_only or full |
--dataset |
rtllm |
rtllm or verilogeval |
--n_samples |
10 | Trials per problem (function_only) |
--k_list |
1,3,5 | Pass@k values to compute |
--L_max_1 |
300 | Max MCTS nodes per trial |
--forest_preset |
balanced |
balanced (K=3) / exploration (K=5) / focused (K=2) |
--llm_model |
deepseek-r1 |
LLM model name |
--ppa_eval_level |
post_synth |
post_synth (fast) or post_route (precise) |
--G_max |
20 | Max EA generations (full mode) |
--output_dir |
./output |
Report and result output directory |
mcea_verilog/
├── __init__.py # Package root (version info)
├── config.py # All configurable parameters + CLI parsing
├── data_structures.py # Core types: Node, Problem, SimResult, PPAResult
├── main.py # Entry point: function_only / full pipelines
│
├── dataset/
│ ├── adapter.py # Adapter interface + factory
│ ├── rtllm_adapter.py # RTLLM: 3-tier result parsing
│ ├── verilogeval_adapter.py # VerilogEval: continuous S_tb extraction
│ └── simulator.py # Unified compile + simulate (iverilog/vvp)
│
├── stage0/
│ ├── spec_formatter.py # Spec → 6-Section format (LLM, cached)
│ └── initializer.py # Forest root node generation
│
├── stage1/
│ ├── agents/
│ │ ├── __init__.py # Agent factory + adaptive selection (§6.3)
│ │ ├── base_agent.py # Shared CoT framework + code extraction
│ │ ├── direct_agent.py # 4-step CoT for direct Verilog editing
│ │ ├── cpp_agent.py # 5-step CoT via C++ intermediate
│ │ └── python_agent.py # 5-step CoT via Python intermediate
│ ├── mcts_tree.py # Single tree: UCT selection + expansion
│ └── mcts_forest.py # Forest: budget, pollination, graduation
│
├── stage2/
│ ├── __init__.py # Stage 2 entry point (wires up EA optimizer)
│ ├── strategies.py # 5 PPA strategies + UCB-Softmax selection
│ ├── correctness_guard.py # Mini-MCTS repair for regressions
│ └── ea_optimizer.py # EA loop: population, fitness, Pareto front
│
├── evaluation/
│ ├── compiler.py # Layer 0: static structural scoring
│ ├── consistency.py # Layer 2: Spec-Code consistency (LLM)
│ ├── composite_score.py # S_func composite + feedback assembly
│ └── ppa_evaluator.py # Yosys / OpenSTA / OpenROAD PPA
│
├── metrics/
│ ├── pass_at_k.py # Unbiased Pass@k estimator
│ └── reporter.py # Report generation (both modes)
│
├── knowledge_base/
│ └── __init__.py # Failure/success/PPA patterns + decay
│
└── llm/
└── __init__.py # OpenAI-compatible LLM client
function_only mode:
For each problem × n_samples trials:
Stage 0: Spec format (cached) + K root nodes
Stage 1: MCTS Forest search (early-stop at first S_func=1.0)
→ Pass@k report
full mode:
For each problem:
Stage 0: Spec format + K root nodes
Stage 1: MCTS Forest (collect diverse correct designs)
Stage 2: EA-PPA optimization (Pareto front over area/delay/power)
→ Pareto front report + optimized Verilog designs
Reports and results are saved to --output_dir (default ./output/):
report_func_only_*.txt/results_func_only_*.json— function_only modereport_full_*.txt/results_full_*.json— full mode (includes Verilog source)