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

AboutRoadmapCareersInternshipsFAQContactPrivacyTerms
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
      • Channel Overview
      • A Minimal AXI-Lite Slave
      • Responses, Strobes and Errors
      • Throughput and Backpressure
      • AXI-Lite End to End into a CSR
    • AXI-Stream
    • 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-Lite
  1. Topics
  2. RTL Design
  3. Memory & Buses
  4. AXI-Lite
  5. Channel Overview
On this page

    Part 7 of 9, lesson 14 of 57Part 7 of 9/Memory & Buses/Lesson 14 of 57Intermediate

    Channel Overview

    The five AXI-Lite channels, their signals, and the rules that pair writes and complete transactions.

    An AXI-Lite write is two halves, address and data, that can arrive in either order. A slave that commits on the address alone writes a register with data no master sent.

    After this lesson you can: name the five channels, explain pairing before commit, and say when a write or a read is finished.

    The five channels

    Each channel is an independent valid/ready handshake: a transfer happens on a rising edge where both valid and ready are high. Write traffic uses three channels (AW, W, B) and read traffic uses two (AR, R).

    Channel

    Signals

    Purpose

    AW

    AWVALID, AWREADY, AWADDR, AWPROT

    Carries the write address; the handshake accepts it

    W

    WVALID, WREADY, WDATA, WSTRB

    Carries the write data with one strobe bit per byte lane

    B

    BVALID, BREADY, BRESP[1:0]

    Returns the write response after address and data are paired

    AR

    ARVALID, ARREADY, ARADDR, ARPROT

    Carries the read address; the handshake accepts it

    R

    RVALID, RREADY, RDATA, RRESP[1:0]

    Returns the read data with its response

    AWPROT and ARPROT carry protection attributes such as privileged versus normal access. Simple slaves often tie them off or ignore them and decode the address only.

    Pairing before commit

    AW and W may arrive in any order: address first, data first, or both together. The slave latches whichever half arrives first and waits for the other; only the pair commits to a register.

    While a channel asserts valid without ready, it must hold its payload stable: the address, data and strobes cannot change until the handshake edge. Counting transfers means counting valid && ready edges, not signal levels.

    Each slot is one clock cycle, and slot numbers match the cycle numbers in the text. The AW xfer and W xfer lanes are valid && ready for that channel, so a high slot means the beat transfers at the edge that ends it. reg0 is the register the write targets.

    • Cycle 1: AW transfers. The address is held, but reg0 and BVALID do not move, because half a write is not a write.

    • Cycles 2 to 3: only AW has arrived. Nothing commits until W transfers at the end of cycle 3.

    • Cycle 5: this slave commits one edge after the second half is held, so reg0 takes its new value and BVALID rises together. The register never updates before cycle 3.

    • Cycles 5 to 6: BVALID stays high while BREADY is low. The write closes only when BREADY is high in cycle 7 and the B handshake completes.

    Responses complete the transaction

    A write ends with the B response and a read ends with the R beat. The master must wait for that closing handshake before treating the transaction as done, for example before reading back a status register it just wrote.

    The minimal slave in this topic accepts one outstanding transaction per channel: it deasserts AWREADY and WREADY while a write response is pending, and ARREADY while read data is pending.

    Common mistakes

    Updating state when AW arrives, before W is captured, commits half a transaction. If W never comes or carries different strobes, the register holds a value no master wrote. Always pair first, then commit once.

    Likely question: “How does a slave handle W arriving before AW?” Expected shape: separate seen-flags per channel, latch each half on its own handshake, commit when both flags are set, clear both with the B response.

    Check yourself AW is accepted in cycle 1 and W is accepted in cycle 3. In which cycle may the register update, and what closes the write?

    No earlier than cycle 3, after both halves are captured. The B handshake closes the write.

    Check yourself A master changes WDATA while WVALID is high and WREADY is low. What breaks?

    The stability rule. The slave may capture either the old or the new data, so the written byte lanes become unpredictable. Payload must hold until the handshake edge.

    Testbench

    The bench below exercises the rules on this page with a write-only sketch of the pairing logic (the full slave, with reads and byte strobes, is on the next page). It sends AW first, W first, and both in the same cycle. While only one half is held it checks that nothing commits and B stays idle. Then it stalls B for two cycles and checks that BVALID and BRESP hold, that no new half is accepted while B is pending, and that each write takes exactly one AW, one W and one B handshake. A final write to an unimplemented offset must answer SLVERR and leave the register unchanged.

    axil_write_pair.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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    // A write-only sketch of the pairing rule. The full slave, with reads and
    // byte strobes, is on the next page.
    module axil_write_pair (
      input  logic        clk,
      input  logic        rst_n,
      input  logic        awvalid,
      output logic        awready,
      input  logic [3:0]  awaddr,
      input  logic        wvalid,
      output logic        wready,
      input  logic [31:0] wdata,
      output logic        bvalid,
      input  logic        bready,
      output logic [1:0]  bresp,
      output logic [31:0] reg0
    );
      timeunit 1ns; timeprecision 1ps;
      logic        aw_seen, w_seen;
      logic [3:0]  awaddr_q;
      logic [31:0] wdata_q;
    
      // One write at a time: no new half is accepted while B is pending.
      assign awready = !aw_seen && !bvalid;
      assign wready  = !w_seen  && !bvalid;
    
      always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
          aw_seen  <= 1'b0;
          w_seen   <= 1'b0;
          awaddr_q <= '0;
          wdata_q  <= '0;
          bvalid   <= 1'b0;
          bresp    <= 2'b00;
          reg0     <= '0;
        end else begin
          if (awvalid && awready) begin
            aw_seen  <= 1'b1;
            awaddr_q <= awaddr;
          end
          if (wvalid && wready) begin
            w_seen  <= 1'b1;
            wdata_q <= wdata;
          end
          if (aw_seen && w_seen && !bvalid) begin   // pair first, then commit once
            if (awaddr_q[3:2] == 2'd0) begin
              reg0  <= wdata_q;
              bresp <= 2'b00;                       // OKAY
            end else begin
              bresp <= 2'b10;                       // SLVERR: no register at this offset
            end
            bvalid  <= 1'b1;
            aw_seen <= 1'b0;
            w_seen  <= 1'b0;
          end
          if (bvalid && bready)
            bvalid <= 1'b0;                         // the B handshake closes the write
        end
      end
    endmodule
    
    Check yourself In the AW-first case, the bench checks reg0 for two cycles after the AW handshake. Which slave bug does that catch?

    Committing on the address alone. A slave that writes when aw_seen is set, before w_seen, changes the register with stale data before W arrives, and the check fails.

    • Writes use AW, W and B. Reads use AR and R. Each is its own valid/ready handshake.

    • Latch whichever write half arrives first, wait for the other, and commit once when both are held.

    • A write ends with the B handshake and a read with the R beat. Valid and payload stay stable until the handshake edge.

    How this was checked

    Write-only sketch of the pairing logic, run with Icarus Verilog 13.0 (2026-10-16): prints PASS. It sends AW first, W first and both in the same cycle, stalls B for two cycles, and answers SLVERR for a write to an unimplemented offset.

    • Practice: AXI4-Lite slave interface with read/write register access

    • Code lab: AXI-lite write channel stub

    • Interview: run a mock interview on this topic

    Related topics

    • A Minimal AXI-Lite Slave

    Previous

    202 / 350

    Next: A Minimal AXI-Lite Slave

    Up next

    Up nextA Minimal AXI-Lite Slave

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Responses, Strobes and Errors
    • Throughput and Backpressure
    • AXI-Lite End to End into a CSR
    ACLKAW_xferW_xferBVALIDBREADYreg00a5
    An address-first write: AW is accepted in cycle 1, W in cycle 3, and the register changes only after both halves are held