vip
Verification IP for Veryl
| Version | 0.1.0 |
|---|---|
| Repository | https://github.com/veryl-lang/vip |
| License | MIT OR Apache-2.0 |
Components
| axi3_checker | Passive AXI3 protocol checker on the `monitor` modport. It enforces the |
|---|---|
| axi3_master | Active AXI3 master. Connect to the `master` modport. It issues up to |
| axi3_ram | AXI3 slave memory. Connect to the `slave` modport. Unlike AXI4 it accepts |
| axi4_checker | Passive AXI4 protocol checker on the `monitor` modport. On top of the |
| axi4_lite_checker | Passive AXI4-Lite protocol checker. Connect to the `monitor` modport; |
| axi4_lite_master | `expect_read`/`expect_write` turn the master into a self-checking |
| axi4_lite_ram | Backdoor `poke`/`peek`/`load_hex`/`set_resp` methods let a testbench |
| axi4_master | Active AXI4 master. Connect to the `master` modport. Pipelines up to |
| axi4_ram | Burst-aware AXI4 slave memory. Connect to the `slave` modport. It accepts |
| axi4_stream_checker | Passive AXI4-Stream protocol checker. Connect to the `monitor` modport; |
| axi4_stream_sink | The `STALL` parameter randomly drops `TREADY` to backpressure the source. |
| axi4_stream_source | The `STALL` parameter randomly inserts idle cycles between beats (`TVALID` |
Modules
Module Prototypes
Interfaces
Packages
Components
| axi3_checker | Passive AXI3 protocol checker on the `monitor` modport. It enforces the |
|---|---|
| axi3_master | Active AXI3 master. Connect to the `master` modport. It issues up to |
| axi3_ram | AXI3 slave memory. Connect to the `slave` modport. Unlike AXI4 it accepts |
| axi4_checker | Passive AXI4 protocol checker on the `monitor` modport. On top of the |
| axi4_lite_checker | Passive AXI4-Lite protocol checker. Connect to the `monitor` modport; |
| axi4_lite_master | `expect_read`/`expect_write` turn the master into a self-checking |
| axi4_lite_ram | Backdoor `poke`/`peek`/`load_hex`/`set_resp` methods let a testbench |
| axi4_master | Active AXI4 master. Connect to the `master` modport. Pipelines up to |
| axi4_ram | Burst-aware AXI4 slave memory. Connect to the `slave` modport. It accepts |
| axi4_stream_checker | Passive AXI4-Stream protocol checker. Connect to the `monitor` modport; |
| axi4_stream_sink | The `STALL` parameter randomly drops `TREADY` to backpressure the source. |
| axi4_stream_source | The `STALL` parameter randomly inserts idle cycles between beats (`TVALID` |
axi3_checker
clocked component
Passive AXI3 protocol checker on the monitor modport. It enforces the
per-channel handshake-stability rules and burst legality, counts WLAST
per WID (write data may interleave), tracks B/R responses per ID (out of
order), validates the 2-bit AxLOCK and that EXOKAY only answers an
exclusive access, and reports coverage at $finish.
Parameters
| TIMEOUT | u64 | optional | Cycles a channel may stall without READY before a hang is reported. |
|---|---|---|---|
| REPORT | str | optional | If set, the end-of-test coverage summary is written to this path. |
Ports
| clk | input | clock | Bus clock. |
|---|---|---|---|
| rst | input | reset | Bus reset; while asserted all VALIDs must stay low. |
| axi | modport | $std::axi3_if.monitor |
Requires
| file |
|---|
Usage
inst u0: $comp::axi3_checker (clk, rst, axi: );
axi3_master
clocked component
Active AXI3 master. Connect to the master modport. It issues up to
MAX_OUTSTANDING write bursts with distinct IDs and interleaves their W
beats by driving WID, exercising a slave’s write-data-interleaving path
(the AXI3-only feature dropped in AXI4). Reads pipeline out-of-order by ID
and are self-checked. exclusive_read / exclusive_write drive the 2-bit
AxLOCK and exclusive_ok reports the last exclusive write’s outcome.
Parameters
| STALL | u64 | optional | 0..=255 weight for randomly delaying BREADY/RREADY. |
|---|---|---|---|
| MAX_OUTSTANDING | u64 | optional | Maximum outstanding transactions per direction; unset means 4. |
Ports
| clk | input | clock | Bus clock. |
|---|---|---|---|
| rst | input | reset | Bus reset; drops in-flight bursts and clears the queues. |
| axi | modport | $std::axi3_if.master |
Methods
burst_write_fill(addr: u64, len: u64)
Queues a burst write whose beat values equal their addresses, recording
them for verify_all. Queue several to see their W data interleave.
random_burst_writes(count: u64, addr_bits: u64, max_len: u64)
Queues count random INCR burst writes (lengths up to max_len, capped
at the AXI3 16-beat limit) into a 2^addr_bits-byte window.
verify_all() -> u64
Queues a single-beat checked read of every written address. Returns how many; a read-back mismatch fails the test.
write(addr: u64, data: value)
Queues a single-beat normal write of data to addr.
read_burst(addr: u64, len: u64)
Queues an INCR burst read of len + 1 beats; drain with pop_read.
pop_read() -> value[axi.DATA_WIDTH_BYTES * 8]
Pops the oldest read beat at full bus width, erroring if none.
exclusive_read(addr: u64)
Queues a single-beat exclusive read of addr (2-bit ARLOCK = 0b01).
Its data drains through pop_read like any other read, sharing the same
FIFO — pop it before issuing later reads if you need the value.
exclusive_write(addr: u64, data: value)
Queues a single-beat exclusive write of data to addr (AWLOCK =
0b01); check the outcome with exclusive_ok once it has drained.
exclusive_ok() -> u64
1 if the most recent exclusive write got EXOKAY (succeeded), else 0.
idle() -> u64
1 when every queued and in-flight transaction has completed, else 0.
Usage
inst u0: $comp::axi3_master (clk, rst, axi: );
axi3_ram
clocked component
AXI3 slave memory. Connect to the slave modport. Unlike AXI4 it accepts
interleaved write data: each W beat carries a WID that selects which
outstanding write burst it belongs to, so up to MAX_OUTSTANDING writes
can stream concurrently. It keeps an exclusive-access monitor (2-bit
AxLOCK, 0b01 = exclusive), interleaves reads out-of-order, and answers
DECERR past SIZE or an injected SLVERR/DECERR (set_resp).
Parameters
| STALL | u64 | optional | 0..=255 weight for randomly dropping the ready outputs. |
|---|---|---|---|
| MAX_OUTSTANDING | u64 | optional | Concurrent writes / reads / buffered responses; unset means 4. |
| SIZE | u64 | optional | Memory size in bytes; accesses at or above it answer DECERR. Unset means unbounded. |
Ports
| clk | input | clock | Bus clock. |
|---|---|---|---|
| rst | input | reset | Bus reset; clears in-flight bursts but keeps memory. |
| axi | modport | $std::axi3_if.slave |
Methods
poke(addr: u64, data: value)
Backdoor write of one aligned word at full bus width.
peek(addr: u64) -> value[axi.DATA_WIDTH_BYTES * 8]
Backdoor read of one aligned word at full bus width.
set_resp(addr: u64, code: u64)
Makes accesses to addr answer code (0 OKAY, 2 SLVERR, 3 DECERR);
OKAY clears any injected error. Errored writes do not modify memory.
Usage
inst u0: $comp::axi3_ram (clk, rst, axi: );
axi4_checker
clocked component
Passive AXI4 protocol checker on the monitor modport. On top of the
per-channel handshake-stability rules it enforces burst legality:
WLAST/RLAST aligning with AxLEN, bursts staying inside a 4 KiB page,
legal AxBURST/AxSIZE. It tracks responses per ID, so it accepts
interleaved out-of-order reads and out-of-order write responses, and
flags a BID/RID with no outstanding request. Exclusive transactions
(AxLOCK) must be power-of-two, ≤ 16 beats, ≤ 128 bytes and size-aligned,
and EXOKAY may only answer an exclusive access.
Parameters
| TIMEOUT | u64 | optional | Cycles a channel may stall without READY before a hang is reported. |
|---|---|---|---|
| REPORT | str | optional | If set, the end-of-test coverage summary is written to this path. |
Ports
| clk | input | clock | Bus clock. |
|---|---|---|---|
| rst | input | reset | Bus reset; while asserted all VALIDs must stay low. |
| axi | modport | $std::axi4_if.monitor |
Requires
| file |
|---|
Usage
inst u0: $comp::axi4_checker (clk, rst, axi: );
axi4_lite_checker
clocked component
Passive AXI4-Lite protocol checker. Connect to the monitor modport;
it drives nothing and fails the test on any handshake or response
violation it sees. Works at any bus width (payloads compare as values).
Parameters
| TIMEOUT | u64 | optional | Cycles a channel may stay stalled (VALID without READY) before it is reported as a hang. Left unset the timeout is disabled. |
|---|---|---|---|
| LIVENESS | u64 | optional | Cycles the bus may show no handshake at all while a response is outstanding before it is reported as a deadlock. Unset disables it. |
| REPORT | str | optional | If set, the end-of-test coverage summary is also written to this path. |
Ports
| clk | input | clock | Bus clock; every edge samples the monitored signals. |
|---|---|---|---|
| rst | input | reset | Bus reset; while asserted all VALIDs must stay low and handshake history is cleared. |
| axi | modport | $std::axi4_lite_if.monitor |
Requires
| file |
|---|
Usage
inst u0: $comp::axi4_lite_checker (clk, rst, axi: );
axi4_lite_master
clocked component
expect_read/expect_write turn the master into a self-checking
scoreboard: it compares the read data (or checks the write response)
itself and fails the test on a mismatch. The STALL parameter randomly
delays READY to stress the slave.
Parameters
| STALL | u64 | optional | 0..=255 weight for randomly delaying BREADY/RREADY; unset never stalls. |
|---|---|---|---|
| MAX_OUTSTANDING | u64 | optional | Maximum responses in flight per direction; unset means unbounded. |
| W_DELAY | u64 | optional | Cycles to hold WVALID back after AWVALID, to skew the write address and data channels and stress the slave. Unset asserts them together. |
Ports
| clk | input | clock | Bus clock. |
|---|---|---|---|
| rst | input | reset | Bus reset; drops in-flight transactions and clears the queues. |
| axi | modport | $std::axi4_lite_if.master |
Methods
write(addr: u64, data: value)
Queues a full-width write.
write_strb(addr: u64, data: value, strb: value)
Queues a write with an explicit byte-strobe.
expect_write(addr: u64, data: value)
Queues a self-checking write: the response must be OKAY or the test fails.
read(addr: u64)
Queues a read; retrieve its data later with pop_read.
expect_read(addr: u64, data: value)
Queues a self-checking read: the returned data is compared against
data and a mismatch fails the test. No result is queued for
pop_read.
rmw(addr: u64, mask: value, value: value)
Queues an atomic read-modify-write: reads addr, replaces the bits
selected by mask with those from value, and writes it back. The
two accesses stay ordered on the bus by the hazard control.
random_writes(count: u64, addr_bits: u64)
Queues count self-checking writes of random data to random
word-aligned addresses within a 2^addr_bits-byte window, recording
each value. Drain them, then call verify_all to read them back and
check every location. Works at any bus width. Deterministic per seed.
random_strobed_writes(count: u64, addr_bits: u64)
Like random_writes but with a random partial byte-strobe on each
write, so partial-lane writes are exercised. The shadow copy is
merged byte-wise to match, then checked back by verify_all.
random_traffic(count: u64, addr_bits: u64, read_percent: u64)
Queues count random self-checking transactions to a
2^addr_bits-byte window, each a read with probability
read_percent/100 (checked against the value last written) or else a
write of random data. Same-address accesses are serialized on the bus
so reads always observe the intended value. Works at any bus width.
verify_all() -> u64
Queues a self-checking read of every address written by
random_writes, returning how many. Call after the writes have
drained; a read-back mismatch fails the test.
pop_read() -> value[axi.DATA_WIDTH_BYTES * 8]
Pops the oldest completed read at full bus width, erroring if none is ready.
num_reads() -> u64
Number of completed reads waiting in the result queue.
idle() -> u64
1 when every queued transaction has completed, else 0.
last_bresp() -> u64
Response code of the most recent write (0 = OKAY, 2 = SLVERR).
Usage
inst u0: $comp::axi4_lite_master (clk, rst, axi: );
axi4_lite_ram
clocked component
Backdoor poke/peek/load_hex/set_resp methods let a testbench
preload memory, inspect it, and inject error responses in zero time.
Parameters
| READ_LATENCY | u64 | optional | Extra cycles before a read response. |
|---|---|---|---|
| WRITE_LATENCY | u64 | optional | Extra cycles before a write response. |
| STALL | u64 | optional | 0..=255 weight for randomly dropping READY; unset means never. |
| SIZE | u64 | optional | Memory size in bytes; accesses at or above it answer DECERR. Unset means unbounded. |
Ports
| clk | input | clock | Bus clock. |
|---|---|---|---|
| rst | input | reset | Bus reset; clears in-flight transactions but keeps memory contents. |
| axi | modport | $std::axi4_lite_if.slave |
Methods
poke(addr: u64, data: value)
Backdoor write of one aligned word at full bus width.
peek(addr: u64) -> value[axi.DATA_WIDTH_BYTES * 8]
Backdoor read of one aligned word at full bus width.
set_resp(addr: u64, code: u64)
Makes the slave answer a given address with a response code
(0 OKAY, 2 SLVERR, 3 DECERR). OKAY clears any injected error.
set_readonly(start: u64, len: u64)
Marks the [start, start + len) byte range write-protected: writes
there answer SLVERR while reads still succeed (models a ROM region).
dump_hex(path: str)
Writes the memory contents (the low 64 bits of each written word) out
as addr data hex pairs, sorted by address — the load_hex format.
load_hex(path: str)
Loads addr data hex pairs, one per line, into memory. Lines that
are blank or start with # are ignored.
Requires
| file |
|---|
Usage
inst u0: $comp::axi4_lite_ram (clk, rst, axi: );
axi4_master
clocked component
Active AXI4 master. Connect to the master modport. Pipelines up to
MAX_OUTSTANDING reads and writes with distinct IDs and matches each
response to its transaction by ID, so it handles a slave’s interleaved
out-of-order read data. Read data is self-checked. random_burst_writes /
random_bursts + verify_all give a randomized burst regression.
exclusive_read / exclusive_write exercise the locked read-modify-write
path; exclusive_ok reports whether the last exclusive write got EXOKAY.
Parameters
| STALL | u64 | optional | 0..=255 weight for randomly delaying BREADY/RREADY. |
|---|---|---|---|
| MAX_OUTSTANDING | u64 | optional | Maximum outstanding transactions per direction; unset means 4. |
Ports
| clk | input | clock | Bus clock. |
|---|---|---|---|
| rst | input | reset | Bus reset; drops in-flight bursts and clears the queues. |
| axi | modport | $std::axi4_if.master |
Methods
random_burst_writes(count: u64, addr_bits: u64, max_len: u64)
Queues count random INCR burst writes into a 2^addr_bits-byte
window (lengths up to max_len), recording each beat for verify_all.
random_bursts(count: u64, addr_bits: u64, max_len: u64)
Queues count random self-checking bursts with random type
(INCR/FIXED/WRAP) and random narrow size, per-beat byte strobes.
verify_all() -> u64
Queues a single-beat checked read of every written address; the reads pipeline (multiple outstanding). Returns how many.
read_check_incr(addr: u64, len: u64)
Queues an INCR burst read of len + 1 beats whose data is checked
against fill (each word equals its address). Interleaves with other
outstanding reads.
read_burst(addr: u64, len: u64)
Queues an INCR burst read of len + 1 beats; drain with pop_read.
pop_read() -> value[axi.DATA_WIDTH_BYTES * 8]
Pops the oldest read beat at full bus width, erroring if none.
idle() -> u64
1 when every queued and in-flight transaction has completed, else 0.
last_bresp() -> u64
Response code of the most recent write burst.
write(addr: u64, data: value)
Queues a single-beat normal write of data to addr.
exclusive_read(addr: u64)
Queues a single-beat exclusive read of addr (ARLOCK), arming the
slave’s monitor. Its data drains through pop_read like any other read,
sharing the same FIFO — pop it before issuing later reads if you need
the read-modify-write value.
exclusive_write(addr: u64, data: value)
Queues a single-beat exclusive write of data to addr (AWLOCK). It
succeeds (EXOKAY) only if the address is still reserved; check the
outcome with exclusive_ok once the write has drained.
exclusive_ok() -> u64
1 if the most recent exclusive write got EXOKAY (succeeded), else 0.
Usage
inst u0: $comp::axi4_master (clk, rst, axi: );
axi4_ram
clocked component
Burst-aware AXI4 slave memory. Connect to the slave modport. It accepts
INCR / FIXED / WRAP bursts, applies byte strobes per beat and echoes the
transaction ID. Up to MAX_OUTSTANDING reads run concurrently and their
beats are interleaved (out-of-order), so it stresses a master’s
reorder handling. It implements an exclusive-access monitor: an exclusive
read (ARLOCK) reserves its address, an exclusive write (AWLOCK) to a
still-reserved address succeeds with EXOKAY, and any intervening normal
write clears the reservation so the exclusive write fails with OKAY and
leaves memory untouched. Accesses past SIZE answer DECERR and set_resp
injects a per-address SLVERR/DECERR; errored writes leave memory
untouched. STALL backpressures the ready lines.
Parameters
| STALL | u64 | optional | 0..=255 weight for randomly dropping the ready outputs. |
|---|---|---|---|
| MAX_OUTSTANDING | u64 | optional | Concurrent reads (and buffered write responses); unset means 4. |
| SIZE | u64 | optional | Memory size in bytes; accesses at or above it answer DECERR. Unset means unbounded. |
Ports
| clk | input | clock | Bus clock. |
|---|---|---|---|
| rst | input | reset | Bus reset; clears in-flight bursts but keeps memory. |
| axi | modport | $std::axi4_if.slave |
Methods
poke(addr: u64, data: value)
Backdoor write of one aligned word at full bus width.
peek(addr: u64) -> value[axi.DATA_WIDTH_BYTES * 8]
Backdoor read of one aligned word at full bus width.
set_resp(addr: u64, code: u64)
Makes accesses to addr answer code (0 OKAY, 2 SLVERR, 3 DECERR);
OKAY clears any injected error. Errored writes do not modify memory.
fill(base: u64, count: u64)
Backdoor fill: sets count consecutive words starting at base to
their own address, so a master can predict read data without writing.
Usage
inst u0: $comp::axi4_ram (clk, rst, axi: );
axi4_stream_checker
clocked component
Passive AXI4-Stream protocol checker. Connect to the monitor modport;
it drives nothing and fails the test on any handshake violation. Works at
any bus width (payloads compare as values).
Parameters
| TIMEOUT | u64 | optional | Cycles TVALID may stay high without TREADY before a hang is reported. |
|---|---|---|---|
| REPORT | str | optional | If set, the end-of-test coverage summary is written to this path. |
Ports
| clk | input | clock | Bus clock. |
|---|---|---|---|
| rst | input | reset | Bus reset; while asserted TVALID must stay low. |
| axi | modport | $std::axi4_stream_if.monitor |
Requires
| file |
|---|
Usage
inst u0: $comp::axi4_stream_checker (clk, rst, axi: );
axi4_stream_sink
clocked component
The STALL parameter randomly drops TREADY to backpressure the source.
Parameters
| STALL | u64 | optional | 0..=255 weight for randomly dropping TREADY; unset is always ready. |
|---|
Ports
| clk | input | clock | Bus clock. |
|---|---|---|---|
| rst | input | reset | Bus reset; clears the receive and expect queues. |
| axi | modport | $std::axi4_stream_if.receiver |
Methods
recv() -> value[axi.TDATA_WIDTH]
Pops the oldest received beat at full bus width, erroring if none.
expect(data: value)
Self-checks the next received beat against data; a mismatch fails
the test.
num_received() -> u64
Number of received beats not yet drained by recv.
beats() -> u64
Total beats accepted so far.
packets() -> u64
Total packets (TLAST beats) accepted so far.
idle() -> u64
1 when no self-check is still pending, else 0.
Usage
inst u0: $comp::axi4_stream_sink (clk, rst, axi: );
axi4_stream_source
clocked component
The STALL parameter randomly inserts idle cycles between beats (TVALID
itself is never dropped mid-beat, as AXI4-Stream requires).
Parameters
| STALL | u64 | optional | 0..=255 weight for randomly gapping the stream between beats. |
|---|
Ports
| clk | input | clock | Bus clock. |
|---|---|---|---|
| rst | input | reset | Bus reset; drops in-flight beats and clears the queue. |
| axi | modport | $std::axi4_stream_if.transmitter |
Methods
send(data: value)
Queues a beat (not the last of a packet).
send_last(data: value)
Queues the last beat of a packet (asserts TLAST).
random_traffic(count: u64, packet_len: u64)
Queues count random beats forming packets of about packet_len
beats (a TLAST roughly every packet_len). Deterministic per seed.
idle() -> u64
1 when every queued beat has been accepted, else 0.
Usage
inst u0: $comp::axi4_stream_source (clk, rst, axi: );