Why a bus needs rules
Name the parts of a bus, say what a protocol has to fix, follow one request from an initiator through an interconnect to a target and back, and choose between a shared bus, point-to-point links and a network.
- Lesson
- P1.1
- Time
- 25 min
- Runs on
- Your browser
- Check
- 5 questions
Two teams built the two ends of a link from the same one-page spec: "the sender raises strobe and puts the byte on data". The sender's team drove both signals in the same cycle. The receiver's team read "raises" as an event and captured the byte one cycle after it. Every byte arrived as x, and both teams had the spec in front of them.
The byte flies while strobe is 1. The receiver reaches for it one cycle later.
- Cycle 1
The sender raises
strobewith 5a for one cycle. Done, as far as it knows. - Cycle 2
The receiver registered
strobeand capturesdatanow. The byte is gone: it captures x. - Cycle 5
The same again for 3c. Both blocks follow the sentence they read, and no byte ever lands.
The sentence named the signals and left out the timing. Each team filled the gap with a different rule.
A protocol is the set of rules both sides share
A bus is a set of wires that carries requests and responses between blocks. A protocol is the set of rules for using those wires, and both ends must hold the same rules. The wires alone are the interface: names, directions and widths. The protocol adds the timing, the order of events and the meaning of each value.
| Kind of rule | What it fixes | The one-page spec |
|---|---|---|
| Signals | Names, directions, widths | strobe out, data[7:0] out |
| Timing | When a value is sampled and how long it is held | Missing: same cycle or the cycle after? |
| Sequence | What may follow what | Missing: may two bytes come back to back? |
| Meaning | What the values stand for | data is one byte, most significant bit first |
Four kinds of rule. The two-wire spec fixed the first and the last and left the middle two to guesswork.
Three roles appear on every bus. An initiator starts a transaction: a processor, a DMA engine, a network controller. A target answers it: a memory, a register block, a peripheral. An interconnect sits between them, decides which target a request is for, and carries the response back. Some documents say master and slave, or manager and subordinate; the roles are the same.
One request through the interconnect
- The CPU asks
The CPU issues a read of address 0x1004. It does not know, and must not care, which block will answer.
Follow the calls, values and waits
- call read 0x1004: CPU → Interconnect
- Decode
The interconnect compares 0x1004 with its map. The window 0x1000 to 0x10FF belongs to the UART, so the request goes there. An address outside every window gets an error response instead.
Follow the calls, values and waits
- call read 0x1004: Interconnect → UART
- The UART answers
The UART returns the byte 0x41. The interconnect routes the response back to the initiator that asked.
Follow the calls, values and waits
- return byte 0x41: UART → Interconnect
- return byte 0x41: Interconnect → CPU
- A second initiator
Meanwhile the DMA engine writes to 0x0200. The interconnect decodes that to the memory and, where two requests share a path, decides who goes first.
Follow the calls, values and waits
- data write 0x0200: DMA engine → Interconnect
- data write 0x0200: Interconnect → Memory
Read the diagram as text
- CPU: initiator
- DMA engine: initiator
- Interconnect: decodes the address, picks a target, returns the response
- Memory: target, 0x0000 to 0x0FFF
- UART: target, 0x1000 to 0x10FF
- CPU → Interconnect: request and response
- DMA engine → Interconnect: request and response
- Interconnect → Memory: selected by address
- Interconnect → UART: selected by address
Address decoding in one picture: the map turns an address into a target, and the interconnect remembers who asked.
The address map is the table of windows the interconnect decodes against. The CPU writes 0x1004 and never names the UART. That is the point: a target can move to another address, or be replaced, and the initiator's code does not change. A request that hits no window is answered with a decode error, so a wrong address fails loudly instead of landing somewhere.
Shared bus, point-to-point links, or a network
The picture above can be wired three ways. A shared bus has one set of wires and carries one transfer at a time, with an arbiter deciding whose turn it is. A point-to-point design gives every link its own wires and uses a crossbar interconnect, so several transfers run at once. A network-on-chip cuts requests into packets with a header and routes them hop by hop, like a tiny internet on the die.
| Shape | Transfers at once | Cost | Fits |
|---|---|---|---|
| Shared bus | One; four initiators each get a quarter of the bandwidth | Few wires, simple arbiter | Small systems, peripherals, microcontrollers |
| Point-to-point links | One per link; a crossbar lets four pairs run together | More wires, a larger interconnect | Processors, memories, accelerators |
| Network-on-chip | Many; a few cycles of latency per router hop | Routers, buffers, packet logic | Large chips with dozens of blocks |
Pick by how much traffic must flow at the same time, and how far it has to travel.
The rules in this module hold for all three. Each of them still needs a handshake, a way to delimit transactions, flow control and an order for responses. Only the wiring and the arbitration change.
Where the named protocols sit
Every bus you will be asked about is one of those three shapes with its own set of names. None of the names below is required reading for this module, and all of them follow the rules taught here.
| Protocol | Shape | What it is for |
|---|---|---|
| AXI (AMBA) | Point-to-point channels, a crossbar interconnect | High-bandwidth memory and accelerator traffic |
| AHB (AMBA) | Shared, pipelined bus with one arbiter | Microcontrollers and simpler systems |
| APB (AMBA) | A fan-out register bus with no pipelining | Control registers of peripherals |
| AXI-Stream, Avalon-ST | Point-to-point, no addresses | Data streams between processing blocks |
| Wishbone, Avalon-MM, TileLink | Shared or point-to-point, open specifications | FPGA systems, RISC-V cores |
| PCIe | Packets over serial lanes, credits for flow control | Between chips and boards |
| Network-on-chip | Routers and packets | Large SoCs and GPUs |
The same roles, handshakes and transactions appear under every one of these names.
Asked in interviews: what a bus is
What is a bus protocol?
The rules both ends of a bus share: the signals, when each is sampled and held, what may follow what, and what the values mean. The wires are the interface; the protocol is how you may use them.
What does an interconnect do?
It decodes each request's address to pick the target, arbitrates when requests compete for a path, and routes every response back to the initiator that asked.
Shared bus or network-on-chip, when?
A shared bus when few blocks talk and one transfer at a time is enough. A network when dozens of blocks need many transfers in flight and can afford a few cycles per hop.
What happens on a request to an unmapped address?
The interconnect finds no window and answers with a decode error. The request never reaches a target, and the initiator learns that its address was wrong.
Why does the initiator never name the target?
It names an address, and the map decides the target. Blocks can then move or be replaced without changing a line of the initiator.
Try it
The sender holds each byte with strobe for one cycle, and the receiver takes it at the edge where strobe is 1. Run it: three bytes arrive.
Now change LATE(0) to LATE(1): the receiver's other reading of the sentence. Run again and every byte is x, because the receiver reaches for the byte one cycle after it was taken away. Nothing in the spec says which reading is right.
rx took 5a rx took 3c rx took ff rx: 3 bytesRead included file: two_wire_rx.sv
`timescale 1ns/1ps
// two_wire_rx.sv: the receiving end of a two-wire link (read-only in this lesson).
// The one-page spec says "the sender raises strobe and puts the byte on data".
// LATE = 0 reads that as "both in the same cycle": the byte is taken at an edge where strobe is 1.
// LATE = 1 reads "raises" as an event: strobe is registered first and the byte is taken one edge later.
module two_wire_rx #(parameter bit LATE = 0) (
input logic clk,
input logic rst_n,
input logic strobe,
input logic [7:0] data
);
logic seen = 0;
int bytes = 0;
always @(posedge clk) begin
seen <= strobe;
if (rst_n && (LATE ? seen : strobe)) begin
bytes++;
$display("rx took %02h", data);
end
end
final $display("rx: %0d bytes", bytes);
endmodule
Check yourself
Remember
- A protocol is the rules both ends share: signals, timing, sequence and meaning. The wires alone are the interface.
- An initiator starts a transaction, a target answers it, and the interconnect decodes the address, arbitrates and routes the response back.
- The initiator names an address, never a target. The address map turns the address into a target, and an unmapped address gets a decode error.
- A shared bus moves one transfer at a time, point-to-point links move one per link, and a network moves many packets with a few cycles per hop.
- AXI, AHB, APB, Wishbone, Avalon, TileLink and PCIe are all some mix of the rules in this module.