Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations36
  • Combinational Design25
  • Sequential Design27
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
  • Memory & Buses57
    • SRAM and ROM
    • Register Files
    • Valid/Ready Handshake
    • AXI-Lite
    • AXI-Stream
      • Core AXI-Stream Signals
      • A Stream Pipeline Register
      • Packets, TLAST, TKEEP and Monitors
    • Bus Integration
    • Synchronous FIFO
    • Register-Map and CSR RTL
    • Memory Reliability
    • Peripheral RTL Integration
    • Full AXI4: RTL Roadmap
  • Advanced RTL28
  • Senior & Interview76
  • Glossary and Notation
Loading lesson

‹AXI-Stream
  1. Topics
  2. RTL Design
  3. Memory & Buses
  4. AXI-Stream
  5. Packets, TLAST, TKEEP and Monitors

Part 7 · Memory & Buses · Intermediate

Packets, TLAST, TKEEP and Monitors

Packet framing with TLAST, partial beats with TKEEP, and a monitor that counts transfers, with a testbench.

On this page

    Why this matters

    An 18-byte packet on a 64-bit bus takes three beats, and the last carries only two valid bytes. A monitor that counts on TVALID alone, or ignores TKEEP, gets both packet and byte counts wrong.

    After this lesson you can: work out the beats and TKEEP of a packet, and write a monitor that counts only accepted beats and flags changes during a stall.

    Packets end with TLAST

    A packet is the run of beats up to and including the beat with TLAST = 1. Packets can follow back to back with no gap.

    TLAST alone ends nothing. Only an accepted beat, one with TVALID and TREADY both 1, can close a packet.

    TKEEP on the final beat

    TKEEP marks which bytes of TDATA must be transported. Bit i covers byte i. This packed-packet example uses contiguous low bits on its partial final beat; general AXI-Stream also permits sparse masks and all-zero TKEEP, including a zero-byte TLAST transfer.

    An 18-byte packet on a 64-bit bus needs three beats. The first two carry 8 bytes each, and the last carries bytes 16 and 17.

    Beat

    Bytes

    TKEEP

    TLAST

    0

    Bytes 0 to 7

    8'hFF

    0

    1

    Bytes 8 to 15

    8'hFF

    0

    2

    Bytes 16 and 17

    8'h03

    1

    The 18-byte packet as three beats of 8 byte lanes: beats 0 and 1 are full (TKEEP FF), beat 2 carries bytes 16 and 17 in lanes 1 and 0 (TKEEP 03) and has TLAST 1

    Read each row as one accepted beat and each column as one byte lane. A filled cell is a byte the sink must keep; its TKEEP bit is 1.

    • Beats 0 and 1: all eight lanes carry data, so TKEEP is FF.

    • Beat 2: only lanes 1 and 0 carry data, bytes 17 and 16. TKEEP is 03 (binary 0000_0011) and TLAST marks the end.

    • Byte order: byte i of a beat sits in lane i, so packet byte 8 is lane 0 of beat 1.

    The diagram shows that packet shape with a one-cycle stall on the middle beat.

    • Slot 1: idle, with tvalid 0 and tready 1.

    • Slot 2: the first beat fires, with tdata a0 and tkeep ff.

    • Slot 3: the second beat waits through a stall, with tready 0 and tdata held at b1.

    • Slot 4: the stall releases and the second beat fires.

    • Slot 5: the partial final beat fires, with tdata c2, tkeep 03 and tlast 1.

    • Slot 6: the link idles with tvalid 0 while tdata and tkeep hold their last values.

    A monitor that counts transfers

    The monitor counts beats and packets. Both counters advance only on tvalid && tready, and a sticky flag records protocol violations.

    The monitor flags unknown TKEEP on a transfer and violations of an outstanding stalled offer: VALID must stay asserted, and TKEEP, TLAST and the valid data bytes must hold through the acceptance edge. Null-byte data is ignored. All-zero TKEEP is legal; a transferred TLAST still closes the packet even when no bytes are carried.

    The TKEEP test uses $isunknown, because an ordinary equality involving X can be treated as false by an if. Stall comparisons use !== to detect changes in four-state control and valid-byte data, including known-to-X changes. They do not establish known values: identical X data or TLAST held through a stall compares unchanged and passes. Only accepted TKEEP has an explicit unknown-value check here. Add separate known-value checks for meaningful data bytes and TLAST if the verification contract requires them.

    The full listing sits with its testbench under Testbench below.

    Common mistakes

    Common pitfall

    Mask every beat with TKEEP, including sparse and zero-byte transfers. Rejecting zero TKEEP is an application restriction, not a generic AXI-Stream protocol check. Preserve TLAST even when no bytes are valid.

    Interview

    Likely question: “how do you verify a stream”. Answer: count beats and packets gated on tvalid && tready, check TLAST framing, and flag payload changes during stalls.

    Check yourself An 18-byte packet crosses a 64-bit stream. What are TKEEP and TLAST on each beat?

    Beats 0 and 1 carry 8 bytes each with TKEEP 8'hFF and TLAST 0. Beat 2 carries bytes 16 and 17 with TKEEP 8'h03 and TLAST 1.

    Check yourself TLAST is 1 with TVALID 1 while TREADY is 0. Does the packet end?

    No. TLAST counts only on a transfer, so the packet ends when the final beat is accepted.

    Check yourself The monitor reports beat_count 5 and pkt_count 2. What does that mean?

    Five beats transferred, closing two packets. The testbench below checks exactly that case.

    Testbench

    The monitor plus directed checks for packet counts, partial and zero-byte transfers, unknown KEEP, acceptance-edge payload changes, and withdrawn VALID. Each negative case starts from a reset monitor so its sticky error cannot hide another missed violation.

    axis_monitor.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    module axis_monitor #(
      parameter int DW = 64,
      parameter int KW = DW / 8
    )(
      input  logic          clk,
      input  logic          rst_n,
      input  logic          m_tvalid,
      input  logic          m_tready,
      input  logic [DW-1:0] m_tdata,
      input  logic [KW-1:0] m_tkeep,
      input  logic          m_tlast,
      output logic [15:0]   beat_count,
      output logic [15:0]   pkt_count,
      output logic          proto_err
    );
      wire fire = m_tvalid && m_tready;
      logic stalled_q;
      logic [DW-1:0] data_q;
      logic [KW-1:0] keep_q;
      logic last_q;
    
      always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
          beat_count <= '0;
          pkt_count  <= '0;
          proto_err  <= 1'b0;
          stalled_q  <= 1'b0;
          data_q     <= '0;
          keep_q     <= '0;
          last_q     <= 1'b0;
        end else begin
          if (fire) begin
            beat_count <= beat_count + 16'd1;
            if (m_tlast)
              pkt_count <= pkt_count + 16'd1;
          end
          if (fire && $isunknown(m_tkeep))
            proto_err <= 1'b1;
          if (stalled_q) begin
            if (m_tvalid !== 1'b1 || m_tkeep !== keep_q || m_tlast !== last_q)
              proto_err <= 1'b1;
            for (int b = 0; b < KW; b++)
              if (keep_q[b] === 1'b1 && m_tdata[b*8 +: 8] !== data_q[b*8 +: 8])
                proto_err <= 1'b1;
          end
          stalled_q <= m_tvalid && !m_tready;
          data_q <= m_tdata; keep_q <= m_tkeep; last_q <= m_tlast;
        end
      end
    endmodule
    

    Remember

    • A packet is the run of beats up to and including TLAST. Only an accepted beat can close it.

    • TKEEP bit i covers byte i. General AXI-Stream allows sparse and all-zero TKEEP, and a zero-byte TLAST beat still ends the packet.

    • Check stalls with !== so a known-to-X change is caught, and use $isunknown on TKEEP.

    Keep going

    • Code lab: AXI stream payload

    • Interview: run a mock interview on this topic

    Related topics

    • Core AXI-Stream Signals

    • A Stream Pipeline Register

    Previous

    209 / 350

    Next: Bus Integration

    Up next

    Up nextBus Integration

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Core AXI-Stream Signals
    clktvalidtreadytdata0a0b1c2tkeepff3tlast
    A 3-beat packet with a mid-packet stall and a partial final beat