Inside a chip, blocks talk to each other through buses: bundles of wires, together with rules for using them, that carry reads and writes from one block to another. Every exchange is a transaction, started by a block such as a processor and answered by another such as a memory. This article explains what a bus is made of, the roles of managers and subordinates, what a read and a write consist of, how the valid/ready handshake paces every transfer, and what happens when an address belongs to nobody, all shown on real transactions of a small SoC.
14 min read | Beginner
What You'll Learn
- Explain what a bus is and the roles of managers and subordinates
- Describe the parts of a read and a write transaction and their channels
- Read a valid/ready handshake on a waveform
- Explain bus responses and what happens on an access to an unowned address
What a Bus Is
Two blocks on a chip exchange information through wires. To send a 32-bit value from a processor to a memory takes 32 wires, one per bit, plus wires for the address that says where the value should go, plus a few control wires that say when the wires carry something meaningful. Such a group of wires is a bus. In the simplest case several blocks share the same wires, which is where the name comes from: like a bus route, one set of wires visits every stop.
Wires alone are not enough. The two sides must agree on what each wire means, when a value is valid, how the receiver says it has taken it, and what happens if it is busy. That agreement is the bus protocol. Most SoCs use standard protocols, so that blocks from different teams and vendors can be connected without redesign. The most widely used family is Arm's AMBA, which includes APB for simple peripherals, AHB, and AXI for high-performance blocks; the Bus Protocols tutorial covers APB, AHB and AXI in depth.
A physical shared bus is common only in small systems. Larger chips connect blocks through switches, crossbars or networks-on-chip that let many transfers travel at once. The word "bus" stuck anyway, and engineers still speak of "the bus" for whatever connects the blocks.
Managers and Subordinates
Every transfer has a side that starts it and a side that answers. The block that starts a transfer is the manager (also called master or initiator): a CPU core executing a load or a store, a DMA engine copying data, a display controller fetching pixels. The block that answers is the subordinate (slave or target): a memory, or the registers of a peripheral such as a UART or a timer. Some blocks are both: a DMA engine is a subordinate when the CPU programs it, and a manager when it then moves data.
Each transfer carries an address. Part of it says which subordinate the transfer is for, and the rest says which location inside that subordinate. The table that assigns address ranges to subordinates is the system's memory map, introduced in What Is in an SoC. The interconnect between managers and subordinates reads the address and delivers the transfer to the right one.
In a small SoC there may be one manager, the CPU subsystem, and two subordinates on its AXI4-Lite interconnect: the system SRAM, and a bridge to the simpler APB bus, which in turn serves the UART, timer, GPIO and simulation control blocks.
Reads and Writes
A complete exchange, from the manager's request to the subordinate's answer, is a transaction. There are two kinds.
A read has two parts. The manager sends the address it wants to read. The subordinate sends back the data stored there, together with a response code that says whether the read worked.
A write has three parts in AXI. The manager sends the address and, separately, the data with its byte strobes: one bit per byte of the data that says which bytes to write, so that a single-byte store changes only one byte of the word. Once the write is done, the subordinate sends a response. Memory, Addresses and Endianness explains why stores need these byte enables.
The response matters even for a write. A write is only complete, and its effect visible to other blocks, when the response has come back. Until then the manager cannot know whether the value is in place, or whether something went wrong.
Channels
AXI, and its simplified version AXI4-Lite, give each part of a transaction its own group of wires, a channel:
| Channel | Direction | Carries |
|---|---|---|
| AW, write address | manager to subordinate | the address of a write |
| W, write data | manager to subordinate | 32 bits of data and 4 byte strobes |
| B, write response | subordinate to manager | a 2-bit response code |
| AR, read address | manager to subordinate | the address of a read |
| R, read data | subordinate to manager | 32 bits of data and a 2-bit response code |
Separate channels allow parts to travel at the same time: the address and data of a write can be sent together, and reads and writes need not wait for each other. Full AXI adds bursts, several data transfers for one address, and transaction IDs that let many transactions be in flight at once. AXI4-Lite leaves these out: every transaction moves exactly one 32-bit word, which is all a small processor and its peripherals need.
Quick Check
Q: A processor executes sb (store byte) to address 0x2000_0102. Which AXI channels carry what, and which byte strobes are set?
Show Answer
AW carries the address 0x2000_0102 (byte 2 of the word at 0x2000_0100), W carries the data with only strobe bit 2 set (4'b0100), and B brings back the response. AR and R are not used.
The Valid/Ready Handshake
The sender and receiver on a channel may not be ready at the same moment. A memory may be busy, or a manager may have nothing to send. Every AXI channel solves this with the same two control signals. The sender drives VALID high when the channel's wires hold something to send. The receiver drives READY high when it can accept it. The transfer, called a handshake, happens on the clock edge where both are high. Two rules make it safe:
- Once the sender raises VALID, it must keep VALID high, and the information on the channel unchanged, until the handshake happens.
- The receiver may raise or lower READY as it likes, so it can slow the sender down for as long as it needs.
Here is one write by a small program to a system SRAM, recorded cycle by cycle from a simulation. "core ready" is the signal that tells the processor's memory stage it may continue:
| Cycle | What happens |
|---|---|
| 1547 | the store reaches the CPU subsystem's bus port; the address is not in the local memory, so core ready drops and the core waits |
| 1548 | the port raises AWVALID and WVALID with the address and data; the SRAM has READY high on both: two handshakes in one cycle |
| 1549 | the SRAM has written the word and raises BVALID with response OKAY; BREADY is high, so the response is taken |
| 1550 | core ready rises and the processor continues with its next instruction |
From the cycle the store needed the bus to the cycle the core moved on, the write took 4 cycles. A read goes the same way: an AR handshake with the address, then an R handshake with the data and the response.
A simple CPU subsystem has at most one transaction outstanding, meaning in progress, at a time: it waits for each response before sending the next request. That is simple, and it is why every bus access stalls the core for its full latency. Larger managers keep many transactions outstanding to hide the wait, which Latency and Bandwidth explains.
Where Is This Used?
Valid/ready handshakes appear on almost every on-chip interface, not only buses: data streams between accelerator stages, FIFOs and network-on-chip links all use them. The same two-signal rule lets any producer and consumer run at their own pace without losing or duplicating data, which is why bus verification checks it on every channel.
Responses and Errors
Every AXI read and write ends with a 2-bit response:
| Code | Name | Meaning |
|---|---|---|
| 00 | OKAY | the access worked |
| 10 | SLVERR | subordinate error: the subordinate was reached but could not do the access |
| 11 | DECERR | decode error: no subordinate owns the address |
(Code 01, EXOKAY, belongs to exclusive accesses, which AXI4-Lite does not have.) An address that no block owns must still get an answer, or the manager would wait forever and the system would hang. The interconnect therefore answers such accesses itself with DECERR, and an APB bridge answers SLVERR for an empty peripheral slot.
Imagine a test program that reads three addresses that belong to nobody: 0x2000_4000, just past the end of the 16 KB system SRAM; 0x3000_0000, in a gap of the memory map; and 0x4000_3000, an unused peripheral slot.
In one test, all three reads completed, each with an error response and the data 0, and the program went on to finish. What a processor does with an error response is a system decision. A large core raises an exception, so that the operating system can stop the faulty program. A very small core may have no exceptions, so the CPU subsystem just records the error in a status bit and returns 0. Either way, the important property is that the system did not hang.
Quick Check
Q: A subordinate holds READY low for three cycles while the manager holds VALID high. When does the transfer happen, and what must the manager do meanwhile?
Show Answer
In the first cycle where READY rises while VALID is still high. Meanwhile the manager must keep VALID high and the address or data unchanged. The three waiting cycles add to the transaction's latency.
Shared Buses, Crossbars and Networks
How the managers and subordinates are wired together is the topology of the interconnect, and it decides how many transfers can happen at once.
On a shared bus, all blocks use the same wires, so only one transfer can be in progress at a time. When two managers want the bus in the same cycle, an arbiter decides who goes first, for example by fixed priority or in turn (round robin), and the other waits. A shared bus is small and simple, and it is enough when there is one busy manager, as in a small microcontroller.
A crossbar gives every manager its own path to every subordinate. Two managers can then talk to two different subordinates at the same time; they only wait for each other when both want the same subordinate. An interconnect with one manager and two subordinates is a crossbar too, the smallest possible case, which makes it little more than an address decoder and a set of multiplexers. Crossbars grow quickly, though: the wiring grows with the number of managers times the number of subordinates.
A network-on-chip (NoC) breaks transfers into packets and sends them through small routers connected by links, the way a computer network does. It scales to the dozens of managers and subordinates of a large SoC, at the cost of more latency per hop. Buses, Crossbars and Networks-on-Chip compares the three in detail.
Bridges: From AXI4-Lite to APB
Not every block needs a high-performance protocol. A UART register is written a few times per character; giving it five AXI channels would waste area. Simple peripherals therefore sit on APB, the Advanced Peripheral Bus, and a bridge translates between the two protocols. On the AXI4-Lite side the bridge is a subordinate; on the APB side it is the manager.
APB has no separate channels and handles one transfer at a time. Every transfer has two phases. In the setup phase the manager drives the address, the direction (PWRITE) and, for a write, the data, and raises the select line PSEL of the chosen peripheral. In the following access phase it also raises PENABLE, and the transfer ends in the cycle where the peripheral answers with PREADY high, returning read data on PRDATA and an error flag on PSLVERR. A peripheral that needs more time simply keeps PREADY low.
A simple bridge takes one AXI4-Lite read or write, runs it as one APB transfer, setup then access, and returns the result as an AXI4-Lite response. It selects the peripheral from address bits 15 to 12, so each of up to 16 peripherals gets a 4 KB window. The extra protocol step is why, in one small SoC, a peripheral access costs 6 cycles where an SRAM access costs 4. For registers that are touched rarely, that is a good trade: APB logic in each peripheral is tiny.
Common Mistakes
Mistake #1: Dropping VALID before the handshake
A sender that lowers VALID, or changes the data, before READY has been seen loses or corrupts the transfer. Once VALID is raised, it and the information it carries must stay stable until the handshake.
Mistake #2: Treating a write as done when the data is sent
The write is complete only when its response returns. Hardware or software that assumes the new value is visible right after sending the data can read stale values, especially in large interconnects where writes take many cycles.
Mistake #3: Leaving holes in the memory map unanswered
If no block responds to an unowned address, the first stray pointer hangs the whole chip, and nothing tells software why. Every interconnect needs a default subordinate that returns an error response.
Practice Exercise
Challenge: How Many Bus Transactions?
A small test program produced this data traffic. Accesses to the TCM stay inside the CPU subsystem; every other access is one bus transaction. (a) How many bus transactions did the program make? (b) What share of them went to the UART? (c) How many cycles did the SRAM transactions cost in total?
target base reads writes cycles/access TCM 0x0000_0000 57 5 1.00 SRAM 0x2000_0000 256 256 4.00 UART 0x4000_0000 835 71 6.00 TIMER 0x4000_1000 2 0 6.00 GPIO 0x4000_2000 1 1 6.00 SIMCTRL 0x4000_F000 0 1 6.00 unmapped - 0 0 -
Hint
Skip the TCM row and add the reads and writes of every other row. Each SRAM access costs 4 cycles.
Solution
(a) SRAM 512, UART 906, timer 2, GPIO 2 and simulation control 1: 1,423 bus transactions. (b) The UART's 906 are 64 percent of them, mostly reads of its status register while the program waits for room to send, which Polling, Interrupts and DMA explains. (c) 512 x 4 = 2,048 cycles.
Summary
- A bus is a set of wires plus a protocol; managers start transactions, subordinates answer, and the address picks the subordinate.
- A read is address, then data with a response; an AXI write is address, data with byte strobes, then a response.
- AXI uses five channels, each with a VALID/READY handshake: a transfer happens when both are high.
- One simple SRAM write took 4 cycles: request, address and data handshakes, response, continue.
- Unowned addresses get DECERR or SLVERR instead of hanging the system: three reads of unowned addresses all completed with an error response.