AHB – Advanced High-performance Bus
AHB (Advanced High-performance Bus) is the AMBA 2 pipelined on-chip bus that bridges the gap between the simple APB and the full AXI4. Its overlapping address-and-data pipeline, burst support, and multi-master arbitration make it the standard interconnect for mid-performance SoC subsystems — processor-to-memory paths, DMA controllers, and on-chip ROM/SRAM interfaces.
Overview & Pipeline
The key performance advantage of AHB over APB is its two-stage pipeline. While the data phase of one transfer is in progress, the address phase of the next transfer is already being presented. This keeps the bus active every cycle rather than spending idle cycles re-presenting addresses.
Because address and data overlap, a slave must register the address signals on the cycle they appear (the address phase) and use them during the following cycle (the data phase) when HWDATA or HRDATA is valid.
AHB vs APB vs AXI4: APB is non-pipelined (3-cycle minimum per transfer, no burst). AHB is pipelined with a central shared bus and burst up to 16. AXI4 uses 5 independent channels and supports bursts up to 256 — but at the cost of much greater complexity. AHB sits naturally between them in both bandwidth and complexity.
Signal Reference
| Signal | Dir | Width | Phase | Description |
|---|---|---|---|---|
| HCLK | – | 1 | – | Bus clock. All signals sampled on rising edge. |
| HRESETn | – | 1 | – | Active-low bus reset. |
| HADDR[31:0] | M→S | 32 | Address | Transfer address. Presented one cycle before data. |
| HTRANS[1:0] | M→S | 2 | Address | Transfer type: IDLE, BUSY, NONSEQ, SEQ. |
| HWRITE | M→S | 1 | Address | 1 = write, 0 = read. |
| HSIZE[2:0] | M→S | 3 | Address | Transfer size: 0=byte, 1=halfword, 2=word, 3=doubleword … |
| HBURST[2:0] | M→S | 3 | Address | Burst type: SINGLE, INCR, WRAP4/8/16, INCR4/8/16. |
| HPROT[3:0] | M→S | 4 | Address | Protection: [0] privileged, [1] bufferable, [2] cacheable, [3] allocate. |
| HSEL | decoder→S | 1 | Address | Slave select from address decoder. Indicates this slave is targeted. |
| HWDATA[31:0] | M→S | 32+ | Data | Write data. Valid one cycle after address phase. |
| HRDATA[31:0] | S→M | 32+ | Data | Read data returned by slave during data phase. |
| HREADY | mux→M/S | 1 | Data | Bus ready signal (multiplexed from all slaves). LOW extends the data phase. |
| HREADYOUT | S→mux | 1 | Data | Slave's own ready output, fed into the bus multiplexer. |
| HRESP[1:0] | S→M | 1 or 2 | Data | Transfer response: OKAY / ERROR (+ RETRY / SPLIT in full AHB). |
HTRANS — Transfer Types
HTRANS tells the slave what kind of transfer is currently on the address bus.
| HTRANS[1:0] | Name | Meaning |
|---|---|---|
| 2'b00 | IDLE | No transfer. Master has nothing to send. Slave must respond OKAY but ignore the access. |
| 2'b01 | BUSY | Master is mid-burst but needs to insert a wait (e.g., waiting for data from cache). Slave ignores this beat but the burst continues. |
| 2'b10 | NONSEQ | Start of a new burst, or a single transfer. Address and control signals are unrelated to any previous transfer. |
| 2'b11 | SEQ | Subsequent beat of an ongoing burst. Address is derived from the previous beat's address + transfer size. |
A slave only needs to act on NONSEQ and SEQ. IDLE and BUSY are informational — a well-designed slave ignores them and always returns OKAY with HREADYOUT=1 during those phases.
HBURST — Burst Types
| HBURST[2:0] | Name | Beats | Address | Use Case |
|---|---|---|---|---|
| 3'b000 | SINGLE | 1 | Fixed | Single non-burst transfer |
| 3'b001 | INCR | Undefined | Incrementing | Undefined-length incremental burst (master decides when to stop) |
| 3'b010 | WRAP4 | 4 | Wrap at 4-beat boundary | Cache-line fill (4-word cache) |
| 3'b011 | INCR4 | 4 | Incrementing | 4-beat sequential burst |
| 3'b100 | WRAP8 | 8 | Wrap at 8-beat boundary | Cache-line fill (8-word cache) |
| 3'b101 | INCR8 | 8 | Incrementing | 8-beat sequential burst |
| 3'b110 | WRAP16 | 16 | Wrap at 16-beat boundary | Cache-line fill (16-word cache) |
| 3'b111 | INCR16 | 16 | Incrementing | 16-beat sequential burst |
WRAP bursts are used for cache-line fills: the processor requests the critical word first, then the burst wraps around the cache-line boundary so all words are fetched in the minimum number of cycles. INCR bursts are general-purpose sequential accesses with no boundary constraint.
Write Transfer Timing
A 3-beat INCR3 write burst. The address of beat N+1 appears on the bus during the data phase of beat N.
Read Transfer Timing
For a read, the slave presents HRDATA during the data phase. The master samples HRDATA on the rising edge when HREADY is HIGH.
Wait States (HREADY)
A slave extends its data phase by driving HREADYOUT LOW. The bus multiplexer propagates this as HREADY LOW to the master. The master must hold all address-phase signals stable (HADDR, HTRANS, HWRITE, HSIZE, HBURST) and not advance to the next transfer until HREADY returns HIGH.
Multiple wait states can be inserted by keeping HREADY LOW for additional cycles. There is no protocol-defined maximum, but practical designs limit wait states to avoid starving other masters.
HRESP — Response Codes
| HRESP | Name | Availability | Meaning |
|---|---|---|---|
| 1'b0 / 2'b00 | OKAY | AHB & AHB-Lite | Transfer completed successfully. |
| 1'b1 / 2'b01 | ERROR | AHB & AHB-Lite | Transfer failed. Slave must drive HREADY LOW for one extra cycle before ERROR, giving the master time to sample it cleanly. |
| 2'b10 | RETRY | Full AHB only | Slave cannot complete the transfer now — master should retry. Typically used for split transactions while the slave fetches data. |
| 2'b11 | SPLIT | Full AHB only | Slave releases the bus and will signal the arbiter when it is ready to resume. Allows other masters to use the bus during a long memory access. |
ERROR response protocol: When a slave needs to signal ERROR, it first drives HREADY LOW and HRESP=ERROR for one cycle, then drives HREADY HIGH and HRESP=ERROR for the second cycle. The two-cycle sequence ensures the master has a full cycle to sample the response before the bus moves on.
AHB vs AHB-Lite
AHB-Lite (defined in AMBA 3) is a single-master subset of full AHB. It removes the arbiter, multi-master bus grant signals, and RETRY/SPLIT responses. It is the version used in the vast majority of modern Cortex-M based SoCs because most embedded designs have a single bus master (the CPU) plus a DMA controller that can be handled separately.
| Feature | Full AHB | AHB-Lite |
|---|---|---|
| Masters | Multiple (arbiter required) | Single |
| Arbiter signals | HBUSREQ, HGRANT, HLOCK, HMASTER | Not present |
| HRESP width | 2-bit (OKAY/ERROR/RETRY/SPLIT) | 1-bit (OKAY=0 / ERROR=1) |
| SPLIT response | Supported | Not supported |
| RETRY response | Supported | Not supported |
| Complexity | Higher | Lower |
| Typical use | High-end multi-master SoCs | Cortex-M microcontrollers, embedded SoCs |
Verilog RTL — AHB-Lite Slave (Register File)
A minimal AHB-Lite slave with a 4×32-bit register file. The key detail is latching address-phase signals at the end of the address phase so they are available during the data phase.
module ahb_lite_slave ( input wire HCLK, input wire HRESETn, // Address phase inputs (registered on rising edge when HREADY=1) input wire HSEL, input wire [31:0] HADDR, input wire HWRITE, input wire [1:0] HTRANS, input wire [2:0] HSIZE, input wire HREADY, // bus HREADY in // Data phase input wire [31:0] HWDATA, output reg [31:0] HRDATA, output wire HREADYOUT, // slave ready (1 = no wait) output wire HRESP // 0=OKAY 1=ERROR (AHB-Lite) ); // Always ready, always OKAY for this simple slave assign HREADYOUT = 1'b1; assign HRESP = 1'b0; // Latch address-phase signals at end of address phase reg lat_sel, lat_write; reg [31:0] lat_addr; reg [1:0] lat_trans; always @(posedge HCLK) begin if (!HRESETn) begin lat_sel <= 1'b0; lat_write <= 1'b0; lat_addr <= 32'h0; lat_trans <= 2'b00; end else if (HREADY) begin // sample only when bus is free lat_sel <= HSEL; lat_write <= HWRITE; lat_addr <= HADDR; lat_trans <= HTRANS; end end // 4-register file reg [31:0] regs [0:3]; wire [1:0] reg_idx = lat_addr[3:2]; wire valid = lat_sel && (lat_trans[1] == 1'b1); // NONSEQ or SEQ // Write — data phase integer i; always @(posedge HCLK) begin if (!HRESETn) begin for (i = 0; i < 4; i = i + 1) regs[i] <= 32'h0; end else if (valid && lat_write && HREADY) regs[reg_idx] <= HWDATA; end // Read — combinational always @(*) begin if (valid && !lat_write) HRDATA = regs[reg_idx]; else HRDATA = 32'h0; end endmodule
Critical design rule: Always latch HSEL, HADDR, HWRITE, and HTRANS at the end of the address phase (when HREADY is HIGH). These signals change to the next transfer's values in the following cycle, but HWDATA for the current write arrives later — so you must remember what the address was.