t27.aiEnglish

Капстоун: проверить модуль целиком

Вы научитесь

Провести один модуль от spec до платы со всем проверочным стеком за спиной.

Один модуль, весь стек. Проведите дизайн через плеер (spec чист), тестбенч (проверки исполнены, а не пропущены), векторы (ответы рядом со входами), косимуляцию (spec, симулятор и плата сходятся на стенде Artix-7 XC7A200T), покрытие (строки, переключения, дуги, запретные дуги холодны), формальные методы (ассерты проверены ограниченно, индукция попытана честно), мутации (счёт убитых на посаженных неисправностях) и приёмку (одна команда, все квитанции). Виджет — этот поток по-настоящему: размещение, трассировка, загруженный битстрим, такт на экране. Ничто в этом курсе — не шаг, который вы перерастёте.

Попробуйте

Выберите собственный модуль и запишите его план проверки: векторы, проверки тестбенча, цели покрытия, ассерты, мутанты, приёмка; затем прогоните виджет потока от начала до конца и отметьте, где ваш план остановил бы настоящий баг.

Открыть интерактивный урок →

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;
        }
    }
}

Открыть spec урока в плеере ↗

Все уроки