MyHDL Quick Reference

Hardware in Python: signals, clocked and combinational logic, simulation and conversion, in one page.

Try any of this live in the MyHDL playground.

Block skeleton

A hardware block is a function decorated with @block that returns every generator it defines.

from myhdl import (block, Signal, intbv, modbv, always_seq, always_comb,
                   always, instance, delay, StopSimulation)

@block
def counter(clk, rst, en, count):
    @always_seq(clk.posedge, reset=rst)
    def logic():
        if en:
            count.next = count + 1
    return logic          # return the generator(s), or nothing runs

The generators that matter

@always_seq(clk.posedge, reset=rst)   # clocked flip-flops, with reset
def seq():
    q.next = d

@always_comb                          # combinational, sensitivity inferred
def comb():
    y.next = a & b

@always(clk.posedge, rst.negedge)     # explicit sensitivity list
def proc():
    ...

@instance                             # free-running process (testbenches)
def stim():
    yield delay(10)
    ...

Signals and types

clk = Signal(bool(0))                 # 1-bit
bus = Signal(intbv(0)[8:])            # 8-bit unsigned; [8:] sets the width
sig = Signal(intbv(0, min=-128, max=128))   # signed, from its range
cnt = Signal(modbv(0)[4:])            # modbv wraps around (no overflow error)

bus.next = 5                          # schedule an update (applies next delta)
v = int(bus)                          # read the current value
hi = bus[7]                           # index a bit
nib = bus[8:4]                        # slice bits [7:4]

Simulation

@block
def bench():
    clk   = Signal(bool(0))
    count = Signal(intbv(0)[4:])
    dut = counter(clk, rst, en, count)

    @always(delay(5))                 # a clock: toggles every 5 time units
    def clkgen():
        clk.next = not clk

    @instance
    def stim():
        yield delay(100)
        raise StopSimulation          # end the run, or it never stops

    return dut, clkgen, stim

bench().config_sim(trace=True)        # writes bench.vcd for the waveform
bench().run_sim()

Convert to Verilog or VHDL

The same block both simulates and converts to synthesizable HDL:

counter(clk, rst, en, count).convert(hdl='Verilog')   # -> counter.v
counter(clk, rst, en, count).convert(hdl='VHDL')       # -> counter.vhd

Gotchas