{"slug": "verifrog-a-verilog-systemverilog-testing-framework-an-ai-agent-can-drive", "title": "Verifrog – a Verilog/SystemVerilog testing framework an AI agent can drive", "summary": "Verifrog, an open-source Verilog/SystemVerilog testing and debugging framework written in F#, has been released, enabling AI agents to drive RTL simulations through Verilator and Icarus Verilog via a Model Context Protocol (MCP) server. The framework provides type-safe signal access, checkpoint/restore, fork-based hypothesis testing, and signal forcing, allowing agents to pinpoint bugs such as an ALU SUB operation failure. It supports structured tests in F# that run under `dotnet test`, with features like VCD waveform analysis and comparison/sweep utilities.", "body_md": "An open-source Verilog/SystemVerilog testing and debugging framework in F#. Drive your RTL through [Verilator](https://verilator.org) and [Icarus Verilog](http://iverilog.icarus.com/) with type-safe, structured access to every signal, memory, and register — and let an AI agent debug it for you over MCP.\n\nTraditional Verilog testbenches are tedious and inexpressive; UVM is powerful but heavyweight. Verifrog gives you Verilator's speed with the ergonomics of a modern language — tests that read like specifications, checkpoint/restore and fork-based hypothesis testing, and an MCP server so an agent can open your design, step it, force signals, and pinpoint a bug on its own.\n\nVerifrog ships an MCP server, so an AI agent can drive your RTL simulation directly — opening a design, stepping cycles, reading and forcing signals, and checkpointing state to test hypotheses. In this demo, a failing test leads the agent to investigate, checkpoint, force signals, and pinpoint a bug in the ALU's SUB operation:\n\n## verifrog-debugging-demo-2x.mp4\n\nWrite structured, readable tests in F# that compile and run your RTL through Verilator. Read and write any signal, memory, or register by name. Assert values with clear failure messages. Run Verilator and Icarus Verilog tests side-by-side under a single `dotnet test`\n\n.\n\nVerifrog's simulation model is fully controllable from code — you can pause at any point, inspect every signal in the design, and step forward cycle-by-cycle. But the real power is in the tools built on top of this:\n\n-\n**Checkpoint/Restore**— Snapshot the entire simulation state (every register, every memory cell) and restore it later in microseconds. Hit a bug at cycle 50,000? Save a checkpoint before the failure, then repeatedly restore and probe different signals without re-running the simulation from scratch. -\n**Fork**— Explore a what-if scenario and automatically snap back. \"What would happen if I forced this signal high?\" Fork runs your experiment, captures the result, and restores the original state — so you can try multiple hypotheses from the same point without manual save/restore. -\n**Compare and Sweep**— Run two configurations side-by-side from the same state (`Compare`\n\n), or sweep a parameter across many values (`Sweep`\n\n). Both use checkpoints internally to ensure each scenario starts from identical state. -\n**Signal forcing**— Override any internal signal and hold it across clock cycles. Inject faults, disable clock gating, force a bus value — then release and watch the design recover. -\n**Tracing and RunUntil**— Record signal values over a window of cycles (`Trace`\n\n), or advance the simulation until a condition is met (`RunUntil`\n\n,`RunUntilSignal`\n\n). No more guessing how many cycles to step. -\n**VCD waveform analysis**— Parse simulation waveform dumps and query them programmatically: find when a signal first changed, count pulses, check timing relationships, verify FSM state coverage. Available as both a library (`Verifrog.Vcd`\n\n) for use in tests and a command-line tool (`verifrog-vcd`\n\n) for quick analysis.\n\n| Verifrog | Raw Verilator (C++) | cocotb | UVM | |\n|---|---|---|---|---|\nTestbench language |\nF# (Expecto) + declarative `.verifrog` |\nC++ | Python | SystemVerilog |\nSimulation engine |\nVerilator / Icarus | Verilator | any VPI simulator | any SV simulator |\nCheckpoint / restore |\nBuilt in (state snapshot in µs) | Hand-rolled | No | No |\nFork / compare / sweep |\nBuilt in | Hand-rolled | No | Manual |\nSignal forcing |\nBy name, held across cycles | Manual pointer writes | `.value` assignment |\n`uvm_hdl_force` |\nNamed memory / register access |\nTOML-driven, by name | Manual | Manual | Config DB / RAL |\nAI agent debugging (MCP) |\nBuilt in | No | No | No |\nLearning curve |\nLow | Medium | Low | High |\n\nVerifrog leans on Verilator for raw speed, so it inherits Verilator's two-state limitation — for timing-accurate, four-state (X/Z) testbenches it can also drive Icarus Verilog under the same test suite. If you need cycle-accurate X-propagation as the default, a VPI-based flow like cocotb may fit better; if you want fast checkpoint/fork-driven debugging with an agent in the loop, that's where Verifrog is aimed.\n\n[.NET 8+ SDK](https://dotnet.microsoft.com/download)[Verilator 5+](https://verilator.org/guide/latest/install.html)- clang++ (macOS, included with Xcode) or g++ (Linux)\n[Icarus Verilog](http://iverilog.icarus.com/)(optional, for timing-accurate testbenches)\n\n```\ngit clone https://github.com/bryancostanich/verifrog.git\ncd verifrog\n./install.sh     # Symlinks verifrog to /usr/local/bin\n```\n\nOr add `bin/`\n\nto your PATH manually: `export PATH=\"/path/to/verifrog/bin:$PATH\"`\n\n```\nverifrog build samples/counter\nverifrog test samples/counter\ncd your-project\nverifrog init .\n\n# Edit verifrog.toml with your design, then:\nverifrog build\nverifrog test\n```\n\nSee the full [Getting Started Guide](/bryancostanich/verifrog/blob/main/docs/getting-started.md) for a step-by-step walkthrough.\n\nMost hardware tests are just \"set signals, step, check.\" Write those declaratively in a `.verifrog`\n\nfile — no F# needed:\n\n```\ntest \"counts to 10 when enabled\" [Smoke]:\n  write enable = 1\n  step 10\n  expect count == 10\n\ntest \"load then count\" [Unit]:\n  write load_value = 42, load_en = 1\n  step 1\n  write load_en = 0, enable = 1\n  step 5\n  expect count == 47\n```\n\nOr in F# when you need more control:\n\n``` js\nopen Verifrog.Sim\nopen Verifrog.Runner\n\nlet tests = testList \"counter\" [\n    test \"counts to 10 when enabled\" {\n        use sim = SimFixture.create ()\n        sim.Write(\"enable\", 1L) |> ignore\n        sim.Step(10)\n        Expect.signal sim \"count\" 10L \"count should reach 10\"\n    }\n]\n```\n\nBoth run in the same test suite — same categories, same `--report`\n\n, same `verifrog test`\n\n.\n\nSave simulation state, run forward, restore, try something different — all in code:\n\n```\ntest \"investigate overflow behavior\" {\n    use sim = SimFixture.create ()\n    sim.Write(\"enable\", 1L) |> ignore\n    sim.Step(200)\n\n    // Save state right before the interesting part\n    let cp = sim.SaveCheckpoint(\"before_overflow\")\n\n    // Run forward and observe\n    sim.Step(60)\n    let count = sim.ReadOrFail(\"count\")\n    let overflowed = sim.ReadOrFail(\"overflow\")\n    printfn \"After 60 more cycles: count=%d overflow=%d\" count overflowed\n\n    // Restore and try a different approach\n    sim.RestoreCheckpoint(\"before_overflow\")\n\n    // What if we load a value near the limit?\n    let result = sim.Fork(fun s ->\n        s.Write(\"load_en\", 1L) |> ignore\n        s.Write(\"load_value\", 250L) |> ignore\n        s.Step(1)\n        s.Write(\"load_en\", 0L) |> ignore\n        s.Step(10)\n        s.ReadOrFail(\"overflow\"))\n    // sim is back to \"before_overflow\" — Fork restored automatically\n\n    // Sweep across multiple load values to find the boundary\n    let results = sim.Sweep(\n        [248L; 249L; 250L; 251L; 252L],\n        fun loadVal s ->\n            s.Write(\"load_en\", 1L) |> ignore\n            s.Write(\"load_value\", loadVal) |> ignore\n            s.Step(1)\n            s.Write(\"load_en\", 0L) |> ignore\n            s.Step(10)\n            s.ReadOrFail(\"overflow\"))\n\n    for (loadVal, overflow) in results do\n        printfn \"  load=%d -> overflow=%d\" loadVal overflow\n}\ntest \"verify timing with VCD analysis\" {\n    use sim = SimFixture.create ()\n    // ... run stimulus ...\n\n    let vcd = VcdParser.parseAll \"output/sim.vcd\"\n\n    // When did the FSM first enter state 5?\n    let t = VcdParser.firstTimeAtValue vcd \"fsm_state\" 5\n    // How many times did overflow pulse?\n    let pulses = VcdParser.highPulseCount vcd \"counter.overflow\"\n    // What states did the FSM visit?\n    let states = VcdParser.uniqueValues vcd \"fsm_state\"\n}\n```\n\nVerifrog provides hardware-domain test categories so you can run the right tests at the right time:\n\n```\nverifrog test --category Smoke          # Quick sanity — design is alive (seconds)\nverifrog test --category Unit           # Focused signal/block tests\nverifrog test --category Integration    # Multi-block data flow\nverifrog test --category Parametric     # Sweeps and value ranges\nverifrog test                           # Everything\n```\n\nCategories are lightweight `testList`\n\nwrappers — just group your tests:\n\n``` js\nopen Verifrog.Runner.Category\n\nlet tests = testList \"MySoC\" [\n    smoke [\n        test \"comes out of reset\" { ... }\n    ]\n    unit [\n        test \"counter increments\" { ... }\n    ]\n    golden [\n        test \"matches reference output\" { ... }\n    ]\n]\n```\n\nAlso available: `stress`\n\n(long-running), `golden`\n\n(reference outputs), `regression`\n\n(bug-fix coverage).\n\n```\nYour Test Project (Expecto)\n  |\n  v\nVerifrog.Runner   — SimFixture, Iverilog backend, Expect helpers\n  |\n  v\nVerifrog.Sim      — Sim type, Memory/Register accessors, TOML config\n  |\n  v\nlibverifrog_sim   — Generic Verilator C++ wrapper (built per-design)\n  |\n  v\nVerilator         — Your compiled RTL\n```\n\n| Library | What it does |\n|---|---|\nVerifrog.Sim |\nCore simulation API: create, step, read/write signals, checkpoint/restore, force, fork/sweep, memory/register access |\nVerifrog.Runner |\nTest infrastructure: SimFixture lifecycle, Iverilog backend, Expect assertions, test categories (Smoke/Unit/Parametric/Integration/Stress/Golden/Regression) |\nVerifrog.Vcd |\nStandalone VCD waveform parser: parse files, query signals, value-at-time, transitions, timing analysis |\nVerifrog.Vcd.Cli |\nCommand-line VCD analysis tool with text and JSON output |\nverifrog CLI |\nBuild tool: `init` , `build` , `clean` , `test` , `debug` (interactive REPL), `debug-server` (JSON), `mcp-server` (MCP for Claude) |\nlibverifrog_sim |\nDesign-agnostic C++ shim: signal discovery, direct-pointer access, checkpoint via memcpy |\nVS Code Extension |\nSyntax highlighting for `.verifrog` files, signals panel, checkpoints panel, debug toolbar (experimental) |\n\nAll project configuration lives in `verifrog.toml`\n\n:\n\n```\n[design]\ntop = \"my_module\"\nsources = [\"rtl/*.v\"]\n\n[test]\noutput = \"build\"\n\n[memories.data_ram]\npath = \"u_ram.mem\"\nbanks = 1\ndepth = 1024\nwidth = 32\n\n[registers]\npath = \"u_regfile.regs\"\nwidth = 8\n\n[registers.map]\nCTRL   = 0x00\nSTATUS = 0x01\nDATA   = 0x02\n```\n\nSee the full [Configuration Reference](/bryancostanich/verifrog/blob/main/docs/config-reference.md).\n\n| Sample | What it demonstrates |\n|---|---|\n|\n\n[alu_regfile](/bryancostanich/verifrog/blob/main/samples/alu_regfile)[sram](/bryancostanich/verifrog/blob/main/samples/sram)[iverilog_tb](/bryancostanich/verifrog/blob/main/samples/iverilog_tb)`dotnet test`\n\n[i2c_bfm](/bryancostanich/verifrog/blob/main/samples/i2c_bfm)Multiple ways to debug your simulations:\n\n**Interactive REPL** — the fastest path. Step the simulation, read/write signals, set checkpoints, force values, all from the command line:\n\n```\nverifrog debug\nsim> write enable 1\nsim> step 10\nsim> read count\n  count = 10\nsim> checkpoint before_overflow\nsim> step 300\nsim> restore before_overflow    # Back to cycle 10 instantly\n```\n\n**JSON debug server** — for programmatic access. Reads JSON commands from stdin, writes JSON responses to stdout:\n\n```\necho '{\"cmd\":\"read\",\"signals\":[\"count\",\"enable\"]}' | verifrog debug-server\n```\n\n**MCP server** — exposes simulation tools directly to Claude:\n\n```\nverifrog mcp-server    # Speaks MCP protocol (JSON-RPC 2.0 over stdio)\n```\n\n**VS Code extension** — syntax highlighting for `.verifrog`\n\nfiles, signals panel, test running. VS Code step-through debugging of F# test code is experimental and has [known limitations](/bryancostanich/verifrog/blob/main/docs/debug-guide.md#debugging-experimental).\n\nSee the full [Debug Guide](/bryancostanich/verifrog/blob/main/docs/debug-guide.md) for all options.\n\n| Guide | For |\n|---|---|\n|\n\n[Core Concepts](/bryancostanich/verifrog/blob/main/docs/concepts.md)[Debug Guide](/bryancostanich/verifrog/blob/main/docs/debug-guide.md)[API Reference](/bryancostanich/verifrog/blob/main/docs/api-reference.md)[VCD Parser Guide](/bryancostanich/verifrog/blob/main/docs/vcd-guide.md)[VCD CLI Reference](/bryancostanich/verifrog/blob/main/docs/vcd-cli.md)[CLI Reference](/bryancostanich/verifrog/blob/main/docs/cli-reference.md)`verifrog init`\n\n, `build`\n\n, `clean`\n\n, `test`\n\n, `debug`\n\n, `results`\n\n[Configuration Reference](/bryancostanich/verifrog/blob/main/docs/config-reference.md)`verifrog.toml`\n\nsection and key[Declarative Tests](/bryancostanich/verifrog/blob/main/docs/declarative-tests.md)`.verifrog`\n\nfiles without F# code[Cookbook](/bryancostanich/verifrog/blob/main/docs/cookbook.md)[CI Integration Guide](/bryancostanich/verifrog/blob/main/docs/ci-guide.md)[Extension Guide](/bryancostanich/verifrog/blob/main/docs/extension-guide.md)[Architecture](/bryancostanich/verifrog/blob/main/docs/architecture.md)[Architecture Decisions](/bryancostanich/verifrog/blob/main/docs/ARCHITECTURE_DECISIONS.md)[Troubleshooting](/bryancostanich/verifrog/blob/main/docs/troubleshooting.md)Apache 2.0", "url": "https://wpnews.pro/news/verifrog-a-verilog-systemverilog-testing-framework-an-ai-agent-can-drive", "canonical_source": "https://github.com/bryancostanich/verifrog", "published_at": "2026-08-11 17:08:12+00:00", "updated_at": "2026-08-11 17:12:14.944094+00:00", "lang": "en", "topics": ["developer-tools", "ai-agents", "ai-tools", "artificial-intelligence"], "entities": ["Verifrog", "Verilator", "Icarus Verilog", "F#", "MCP", "UVM", "cocotb"], "alternates": {"html": "https://wpnews.pro/news/verifrog-a-verilog-systemverilog-testing-framework-an-ai-agent-can-drive", "markdown": "https://wpnews.pro/news/verifrog-a-verilog-systemverilog-testing-framework-an-ai-agent-can-drive.md", "text": "https://wpnews.pro/news/verifrog-a-verilog-systemverilog-testing-framework-an-ai-agent-can-drive.txt", "jsonld": "https://wpnews.pro/news/verifrog-a-verilog-systemverilog-testing-framework-an-ai-agent-can-drive.jsonld"}}