t27.aiРусский

Capstone: verify a module whole

You will learn

Carry one module from spec to board with the whole verification stack behind it.

One module, the whole stack. Take a design through the player (spec clean), the testbench (checks executed, not skipped), the vectors (answers beside inputs), cosimulation (spec, simulator, board agreeing on the bench Artix-7 XC7A200T), coverage (lines, toggles, arcs, illegal arcs cold), formal (assertions bounded, induction attempted, honestly), mutation (kill count on planted faults), and sign-off (one command, every receipt). The widget is the flow running for real: place, route, a loaded bitstream, the clock on screen. Nothing in this course is a step you outgrow.

Try it

Choose a module of your own and write its verification plan: vectors, tb checks, coverage targets, assertions, mutants, sign-off; then run the flow widget end to end and mark where your plan would have stopped a real bug.

Open the interactive lesson →

Place and route to a loaded bitstream, timed
Place and route to a loaded bitstream, timed ↗

router1, bitwalk, xc7frames2bit, SRAM load: 19.06 s here, on a laptop at load average ~110.

specs/fpga/testbench/integration_tb.t27

// SPDX-License-Identifier: Apache-2.0
// t27/specs/fpga/testbench/integration_tb.t27
// Full FPGA Integration Testbench
// Tests top-level connectivity: MAC + UART + SPI + Memory + Bridge
// phi^2 + 1/phi^2 = 3 | TRINITY

module Integration_Testbench {
    const CLK_PERIOD : u32 = 20;
    const SIM_TIMEOUT : u32 = 20_000_000;
    const NUM_MODULES : u32 = 5;

    var clk : bool = false;
    var rst_n : bool = false;
    var mac_busy : bool = false;
    var uart_tx_ready : bool = false;
    var spi_done : bool = false;
    var mem_ready : bool = false;
    var bridge_busy : bool = false;
    var all_modules_idle : bool = false;
    var integration_passed : bool = false;

    var test_passed : u32 = 0;
    var test_failed : u32 = 0;

    fn tick() {
        clk = false;
        clk = true;
    }

    fn reset() {
        rst_n = false;
        tick();
        tick();
        rst_n = true;
        tick();
    }

    fn check_all_idle() -> bool {
        return !mac_busy && uart_tx_ready && spi_done && mem_ready && !bridge_busy;
    }

    test test_reset_all_modules {
        reset();
        all_modules_idle = check_all_idle();
        invariant all_modules_idle == true;
    }

    test test_module_count {
        invariant NUM_MODULES == 5;
    }

    test test_mac_uart_pipeline {
        reset();
        mac_busy = true;
        tick();
        tick();
        mac_busy = false;
        uart_tx_ready = true;
        tick();
        invariant uart_tx_ready == true;
    }

    test test_spi_memory_pipeline {
        reset();
        spi_done = false;
        tick();
        tick();
        spi_done = true;
        mem_ready = true;
        tick();
        invariant mem_ready == true;
    }

    test test_full_pipeline {
        reset();
        mac_busy = true;
        tick();
        mac_busy = false;
        uart_tx_ready = true;
        tick();
        spi_done = true;
        mem_ready = true;
        bridge_busy = true;
        tick();
        bridge_busy = false;
        all_modules_idle = check_all_idle();
        invariant all_modules_idle == true;
        integration_passed = true;
    }

    test test_stress_pipeline {
        reset();
        var i : u32 = 0;
        while i < 10 {
            mac_busy = true;
            tick();
            mac_busy = false;
            uart_tx_ready = true;
            tick();
            spi_done = true;
            mem_ready = true;
            bridge_busy = true;
            tick();
            bridge_busy = false;
            i = i + 1;
        }
        all_modules_idle = check_all_idle();
        invariant all_modules_idle == true;
    }

    invariant num_modules_positive : NUM_MODULES > 0;

    test test_tick_function {
        reset();
        var initial_clk : bool = clk;
        tick();
        invariant clk == !initial_clk;
    }

    bench bench_integration_throughput {
        reset();
        var i : u32 = 0;
        while i < 50 {
            mac_busy = true;
            tick();
            mac_busy = false;
            uart_tx_ready = true;
            tick();
            i = i + 1;
        }
    }
}

Open the lesson's spec in the player ↗

All lessons