plugins/gateflow/skills/gf-cocotb/SKILL.md
Python-based testbench generation using Cocotb. Alternative to SystemVerilog testbenches for Python-native hardware engineers. Example: "create a cocotb test for the FIFO", "write Python testbench"
npx skillsauth add codejunkie99/gateflow-plugin gf-cocotbInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Generate Cocotb testbenches as an alternative to SystemVerilog TBs.
python3 -c "import cocotb" 2>/dev/null
If not found, return GATEFLOW-RESULT ERROR with: pip install cocotb
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge
@cocotb.test()
async def test_reset(dut):
clock = Clock(dut.clk, 10, units="ns")
cocotb.start_soon(clock.start())
dut.rst_n.value = 0
for _ in range(3):
await RisingEdge(dut.clk)
dut.rst_n.value = 1
await RisingEdge(dut.clk)
assert dut.count.value == 0
| Cocotb | SV Testbench | |--------|-------------| | Python (lower barrier) | SystemVerilog | | Complex stimulus (Python libs) | Protocol + coverage | | Slower (co-simulation) | Faster (native) |
SIM ?= icarus
TOPLEVEL_LANG ?= verilog
VERILOG_SOURCES += $(PWD)/rtl/$(DUT).sv
TOPLEVEL = $(DUT)
MODULE = test_$(DUT)
COCOTB_HDL_TIMEUNIT = 1ns
COCOTB_HDL_TIMEPRECISION = 1ps
ifeq ($(SIM),verilator)
EXTRA_ARGS += --trace --trace-structs
endif
SIM_BUILD = sim_build/$(SIM)
include $(shell cocotb-config --makefiles)/Makefile.sim
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge, ClockCycles
import random
async def reset_fifo(dut):
dut.rst.value = 1
dut.wr_en.value = 0
dut.rd_en.value = 0
await ClockCycles(dut.clk, 5)
dut.rst.value = 0
await RisingEdge(dut.clk)
@cocotb.test()
async def test_fifo_write_read(dut):
clock = Clock(dut.clk, 10, units="ns")
cocotb.start_soon(clock.start())
await reset_fifo(dut)
assert dut.empty.value == 1
written = []
for i in range(16):
data = random.randint(0, 255)
written.append(data)
dut.din.value = data
dut.wr_en.value = 1
await RisingEdge(dut.clk)
dut.wr_en.value = 0
await RisingEdge(dut.clk)
assert dut.full.value == 1
read = []
for i in range(16):
dut.rd_en.value = 1
await RisingEdge(dut.clk)
read.append(int(dut.dout.value))
dut.rd_en.value = 0
assert read == written
@cocotb.test()
async def test_handshake(dut):
clock = Clock(dut.clk, 10, units="ns")
cocotb.start_soon(clock.start())
# ... reset ...
async def driver():
for data in range(20):
dut.s_data.value = data
dut.s_valid.value = 1
while True:
await RisingEdge(dut.clk)
if dut.s_ready.value == 1:
break
dut.s_valid.value = 0
async def backpressure():
while True:
dut.m_ready.value = random.randint(0, 1)
await ClockCycles(dut.clk, random.randint(1, 4))
cocotb.start_soon(driver())
cocotb.start_soon(backpressure())
await ClockCycles(dut.clk, 200)
from enum import IntEnum
class State(IntEnum):
IDLE = 0
ACTIVE = 1
DONE = 2
@cocotb.test()
async def test_fsm(dut):
clock = Clock(dut.clk, 10, units="ns")
cocotb.start_soon(clock.start())
# reset...
assert int(dut.state.value) == State.IDLE
dut.start.value = 1
await RisingEdge(dut.clk)
dut.start.value = 0
await RisingEdge(dut.clk)
assert int(dut.state.value) == State.ACTIVE
import os
from pathlib import Path
from cocotb_tools.runner import get_runner
def test_module():
sim = os.getenv("SIM", "icarus")
runner = get_runner(sim)
runner.build(
sources=[Path("rtl/my_module.sv")],
hdl_toplevel="my_module",
)
runner.test(
hdl_toplevel="my_module",
test_module="test_my_module",
)
| Package | Protocol | Install |
|---|---|---|
| cocotbext-axi | AXI4, AXI-Lite, AXI-Stream | pip install cocotbext-axi |
| cocotbext-wishbone | Wishbone B4 | pip install cocotbext-wishbone |
| cocotbext-spi | SPI | pip install cocotbext-spi |
| cocotbext-uart | UART | pip install cocotbext-uart |
| cocotbext-eth | Ethernet | pip install cocotbext-eth |
| cocotbext-pcie | PCIe | pip install cocotbext-pcie |
from cocotbext.axi import AxiLiteBus, AxiLiteMaster
axil = AxiLiteMaster(AxiLiteBus.from_prefix(dut, "s_axi"), dut.clk, dut.rst)
await axil.write(0x0000, b'\x42\x00\x00\x00')
data = await axil.read(0x0000, 4)
| Factor | Use Cocotb | Use SV/UVM | |---|---|---| | Team knows Python | Yes | - | | FPGA project | Yes | - | | Large ASIC with UVM infra | - | Yes | | Need open-source CI | Yes | - | | Standard protocols (AXI, SPI) | Yes (cocotbext) | - | | Deep constrained random | - | Yes | | Rapid iteration | Yes | - |
---GATEFLOW-RESULT---
STATUS: PASS | FAIL | ERROR
ERRORS: <count>
WARNINGS: <count>
FILES: <test files>
DETAILS: <summary>
---END-GATEFLOW-RESULT---
tools
GateFlow release readiness workflow. Validates plugin manifests, marketplace metadata, docs index coverage, root mirrors, release notes, and component counts before a version tag is created. Use when preparing, checking, or cutting a GateFlow plugin release.
testing
Testbench verification best practices and patterns. This skill should be used when the user needs testbench architecture guidance, verification methodology, or wants to write professional-quality testbenches. Example requests: "testbench best practices", "how to structure TB", "verification patterns"
testing
Primary SystemVerilog/RTL orchestrator for GateFlow. Routes to specialist agents, runs verification, and iterates until working. Use when the user wants to create, test, fix, or implement any RTL design — FIFO, UART, AXI, state machines, or any digital hardware module.
development
Terminal visualization for GateFlow codebase maps. Renders module hierarchies, FSM state diagrams, and module detail cards as interactive ASCII/Unicode art. Example requests: "visualize the codebase", "show hierarchy", "show FSM", "show module detail"