GF-Cocotb -- Python Testbench Generation
SkillDev toolsPython-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"
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the GF-Cocotb -- Python Testbench Generation skill
What this skill tells your AI
The instructions your AI receives, as published by codejunkie99/gateflow-plugin in skills/gf-cocotb/SKILL.md and read by ahel’s review.
Generate Cocotb testbenches as an alternative to SystemVerilog TBs.
Tool Detection
python3 -c "import cocotb" 2>/dev/null
If not found, return GATEFLOW-RESULT ERROR with: pip install cocotb
Test Template
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
When to Use
| Cocotb | SV Testbench |
|---|---|
| Python (lower barrier) | SystemVerilog |
| Complex stimulus (Python libs) | Protocol + coverage |
| Slower (co-simulation) | Faster (native) |
Makefile Template
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
Test Templates
FIFO Test
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
Valid/Ready Handshake Test
@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)
FSM Test
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
Python Runner (pytest)
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",
)
cocotbext Protocol Libraries
| 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 |
AXI-Lite Example
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)
Decision Matrix: Cocotb vs SV TB
| 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 Integration
---GATEFLOW-RESULT---
STATUS: PASS | FAIL | ERROR
ERRORS: <count>
WARNINGS: <count>
FILES: <test files>
DETAILS: <summary>
---END-GATEFLOW-RESULT---
Signals
- GitHub stars
- 112
- Forks
- 14
- Last commit
- May 2026
Advanced
- Catalog kind
- skill
- Gateway key
gf-cocotb- Source
- github.com/codejunkie99/gateflow-plugin