I²C · Module 6
The Address Byte — Seven Address Bits and the R/W Bit
The first byte after a START is not an address followed by a direction bit. It is one eight-bit field that the bus, the slave and the datasheet all treat as a unit — and treating it as two things is the single most common source of I²C address confusion.
Module 5 ended with a bus that can be claimed, released and held between phases, and with a framing event that tells every device on the segment that a transfer has begun. What it could not tell them is who the transfer is for.
Every chapter of that module referred to "the address byte that follows the START" and left it at that. This one opens it.
1. The Definition, and the Trap Inside It
UM10204 §3.1.10:
After the START condition (S), a slave address is sent. This address is seven bits long followed by an eighth bit which is a data direction bit (R/W) — a 'zero' indicates a transmission (WRITE), a 'one' indicates a request for data (READ).
Read carefully, that sentence describes one byte, transmitted like any other byte on the bus: eight bits, most significant first, one bit per SCL pulse. Seven of them happen to carry an address and the eighth happens to carry a direction, but nothing about the transmission distinguishes them. The bus does not know it is carrying an address; it carries eight bits.
That is the whole chapter, and the trap is what happens when an engineer treats it as two fields instead of one.
One byte: seven address bits then R/W
8 cycles2. Why the Datasheet and the Driver Disagree
Here is the confusion, and it is worth meeting head-on because it costs real hours.
A device's datasheet says its address is 0x48. A driver writes 0x90 to the peripheral and it works. Another driver writes 0x48 to a different peripheral and that works too. Both are correct, and neither number is wrong.
The reason is that 0x48 is the seven-bit address and 0x90 is the byte on the wire — the same seven bits shifted up one position to make room for the direction bit:
seven-bit address 0x48 = 100 1000
^^^^^^^
seven bits, as the datasheet states it
byte on the wire, WRITE: 1001000 0 = 1001_0000 = 0x90
byte on the wire, READ: 1001000 1 = 1001_0001 = 0x91
^^^^^^^ ^
address direction
so: wire_byte = (addr << 1) | rw
addr = wire_byte >> 1
rw = wire_byte & 1
0x48 << 1 = 0x90 (write)
(0x48 << 1) | 1 = 0x91 (read)
The trap: 0x90 and 0x91 are the SAME DEVICE. A table listing them as two
devices at two addresses describes one device and two directions.Both conventions are in wide use, and neither is going away:
| convention | what the number is | 0x48 appears as | who uses it |
|---|---|---|---|
| seven-bit address | the address alone, right-aligned | 0x48 | datasheets, the specification, most modern driver APIs, i2cdetect output |
| eight-bit / "shifted" | the whole byte, write direction | 0x90 | many vendor headers, some register maps, a great deal of legacy driver code |
The rule that resolves it in practice: a seven-bit address is at most 0x7F. If a number presented as an I²C address exceeds 0x7F, it is a wire byte and the address is that number shifted right by one. It is a two-second check and it prevents an afternoon.
3. MSB First, and Why That Matters Here More Than Elsewhere
The address bits go out most significant first. That is the same convention every byte on this bus follows, and Chapter 7.1 establishes it as the general rule.
It matters more for the address byte than for a data byte, for a practical reason: the address is the field engineers most often construct by hand, in a driver, in a bring-up script, or on a bench. A data byte usually comes from a variable; an address usually comes from a person reading a datasheet. Getting the bit order wrong on data produces obviously wrong values; getting it wrong on the address produces silence, because the device simply never sees its own address and never answers.
The direction follows from the transmission order. Because the address bits arrive first and the direction bit last, a device cannot know whether a transfer is a read or a write until the eighth bit — by which time it has already matched its address on the first seven. This is why the decoder in Chapter 6.5 latches the direction at the end of the byte rather than deciding anything early, and why the byte has to be captured whole before any decision is made.
4. Capturing the Byte in Hardware
The requirement is to collect eight bits from a serial line and split them at the end. Derive it rather than presenting it.
When is a bit valid? On SCL's rising edge. Chapter 4.2 established that SDA must be stable while SCL is high and may only change while SCL is low, so the rising edge is the instant the data-valid rule protects. Sampling anywhere else reads a line that is permitted to be moving.
What holds the bits? An eight-bit shift register, shifting left, because the first bit to arrive is the most significant. After eight shifts the register holds the byte exactly as it appeared on the wire.
When is the byte complete? After exactly eight shifts. Not seven, and not nine — and the count is what makes "exactly" testable.
Where does the split happen? At the very end, and only there:
After 7 shifts the register holds, in its low seven bits, the seven bits that
have arrived so far -- which are exactly the address:
shifter = 0 b7 b6 b5 b4 b3 b2 b1 shifter[6:0] = the address
(b7 is the address MSB)
The eighth bit arriving on the wire is b0 -- the direction. So at the moment
of the eighth shift:
addr <= shifter[6:0] the seven bits already collected
rw <= sda_in the bit arriving right now
No shifted copy, no second register, no arithmetic. The split is a WIRING
decision made once, at one instant, and the rest of the design treats the
byte as a byte.That last point is the design consequence of §1. A capture block that split the byte early — keeping an address register and a direction register updated as bits arrive — would have to decide, on every bit, which field that bit belonged to. Collecting eight bits and splitting once is both simpler and less wrong.
5. The Capture Block in Three Languages
One shift register, one bit counter, one SCL edge detector, and the framing inputs from Module 5.
module i2c_address_byte_capture (
input logic clk,
input logic rst_n,
input logic scl_in, // observed bus level, not drive intent
input logic sda_in, // observed bus level, not drive intent
input logic frame_start, // pulse: S or Sr observed (Module 5)
input logic frame_stop, // pulse: P observed (Module 5)
output logic [6:0] addr, // the seven address bits
output logic rw, // 1 = master READS, 0 = master WRITES
output logic addr_valid, // single-cycle pulse: all eight bits captured
output logic capturing
);
logic [7:0] shifter;
logic [3:0] bit_count;
logic scl_q;
// A bit is valid on SCL's RISING edge -- that is the instant the data-valid
// rule protects. Sampling anywhere else reads a line that is permitted to move.
logic scl_rise;
always_comb scl_rise = !scl_q && scl_in;
always_ff @(posedge clk) begin
if (!rst_n) begin
shifter <= 8'h00;
bit_count <= 4'd0;
addr <= 7'h00;
rw <= 1'b0;
addr_valid <= 1'b0;
capturing <= 1'b0;
scl_q <= 1'b1; // idle bus: SCL released, therefore high
end else begin
addr_valid <= 1'b0;
scl_q <= scl_in;
// A STOP ends everything, and it wins over a bit in flight.
if (frame_stop) begin
capturing <= 1'b0;
bit_count <= 4'd0;
// A framing START -- first OR repeated -- restarts the capture
// unconditionally, even part way through a byte. Module 5 established
// that a START resets every device's protocol state; this is that rule
// implemented, and it is why frame_start is tested before scl_rise.
end else if (frame_start) begin
capturing <= 1'b1;
bit_count <= 4'd0;
shifter <= 8'h00;
end else if (capturing && scl_rise) begin
shifter <= {shifter[6:0], sda_in}; // MSB first, so shift left
if (bit_count == 4'd7) begin
// Seven shifts have already happened, so shifter[6:0] IS the
// seven address bits, and the bit arriving now is the eighth --
// the direction bit. Address and direction are ONE field on the
// wire and are only split here, at the end.
addr <= shifter[6:0];
rw <= sda_in;
addr_valid <= 1'b1;
capturing <= 1'b0;
bit_count <= 4'd0;
end else begin
bit_count <= bit_count + 4'd1;
end
end
end
end
endmodule module i2c_address_byte_capture_tb;
logic clk = 1'b0, rst_n, scl_in, sda_in, frame_start, frame_stop;
logic [6:0] addr;
logic rw, addr_valid, capturing;
int errors = 0;
int n_valid = 0;
// Module scope on purpose: an initialised declaration inside a loop block is
// static in SystemVerilog, which silently breaks a per-iteration value.
logic [6:0] decoy_pat;
i2c_address_byte_capture dut (.*);
always #5 clk = ~clk;
initial begin #40000; $display("FAIL: watchdog expired"); $finish; end
always @(posedge clk) if (rst_n && addr_valid) n_valid++;
// One SCL pulse carrying one bit. SDA is prepared during the LOW phase and
// held through the HIGH phase, exactly as the data-valid rule requires.
task automatic send_bit(input logic b);
scl_in = 1'b0; repeat (2) @(negedge clk);
sda_in = b; repeat (2) @(negedge clk);
scl_in = 1'b1; repeat (2) @(negedge clk);
scl_in = 1'b0; repeat (1) @(negedge clk);
endtask
task automatic pulse_start();
frame_start = 1'b1; @(negedge clk); frame_start = 1'b0;
endtask
task automatic pulse_stop();
frame_stop = 1'b1; @(negedge clk); frame_stop = 1'b0;
endtask
// Send a whole address byte MSB first: seven address bits then the R/W bit.
task automatic send_addr_byte(input logic [6:0] a, input logic dir);
for (int i = 6; i >= 0; i--) send_bit(a[i]);
send_bit(dir);
endtask
task automatic expect_capture(input logic [6:0] a, input logic dir, input int step);
if (addr !== a || rw !== dir) begin
$display("FAIL: step %0d -- captured addr=0x%02h rw=%0b, expected 0x%02h %0b",
step, addr, rw, a, dir);
errors++;
end
endtask
initial begin
rst_n = 1'b0; scl_in = 1'b1; sda_in = 1'b1;
frame_start = 1'b0; frame_stop = 1'b0;
repeat (3) @(negedge clk);
if (capturing !== 1'b0) begin $display("FAIL: capturing asserted out of reset"); errors++; end
if (addr_valid !== 1'b0) begin $display("FAIL: addr_valid asserted out of reset"); errors++; end
rst_n = 1'b1; @(negedge clk);
// 1 -- no capture happens without a START. Bits on the bus before any
// framing must be ignored entirely.
send_bit(1'b1); send_bit(1'b0);
if (n_valid != 0) begin $display("FAIL: captured a byte with no preceding START"); errors++; end
// 2 -- a READ address. 0x52 with R/W=1 is the byte 0xA5 on the wire.
pulse_start();
if (capturing !== 1'b1) begin $display("FAIL: START did not begin a capture"); errors++; end
send_addr_byte(7'h52, 1'b1);
if (n_valid != 1) begin $display("FAIL: expected exactly 1 addr_valid, saw %0d", n_valid); errors++; end
expect_capture(7'h52, 1'b1, 2);
if (capturing !== 1'b0) begin $display("FAIL: still capturing after eight bits"); errors++; end
// 3 -- a WRITE address, and one whose bits differ in every position from
// the previous one, so a stuck shifter cannot pass both.
pulse_start();
send_addr_byte(7'h2D, 1'b0);
expect_capture(7'h2D, 1'b0, 3);
if (n_valid != 2) begin $display("FAIL: expected 2 addr_valid pulses, saw %0d", n_valid); errors++; end
// 4 -- EXACTLY eight bits. A ninth bit arriving without a new START must
// not produce a second capture, because the address field is over.
send_bit(1'b1);
if (n_valid != 2) begin $display("FAIL: a ninth bit produced another capture"); errors++; end
// 5 -- SDA moving during the LOW phase must not be sampled. This drives
// SDA to the WRONG value during low and the right one before the rise.
decoy_pat = 7'h7F;
pulse_start();
for (int i = 6; i >= 0; i--) begin
scl_in = 1'b0; repeat (1) @(negedge clk);
sda_in = ~decoy_pat[i]; repeat (1) @(negedge clk); // decoy
sda_in = decoy_pat[i]; repeat (1) @(negedge clk); // real
scl_in = 1'b1; repeat (2) @(negedge clk);
scl_in = 1'b0; repeat (1) @(negedge clk);
end
send_bit(1'b0);
expect_capture(7'h7F, 1'b0, 5);
// 6 -- a STOP part way through a byte ABANDONS it. No capture, and the
// next byte must not inherit the abandoned bits.
pulse_start();
send_bit(1'b1); send_bit(1'b1); send_bit(1'b0);
pulse_stop();
if (capturing !== 1'b0) begin $display("FAIL: STOP did not abandon the capture"); errors++; end
send_bit(1'b1); send_bit(1'b1);
if (n_valid != 3) begin $display("FAIL: bits after a STOP were captured"); errors++; end
// 7 -- a repeated START part way through a byte RESTARTS it. This is the
// unconditional-reset rule from Module 5, and a shifter that was not
// cleared would fold the abandoned bits into the new address.
pulse_start();
send_bit(1'b1); send_bit(1'b1); send_bit(1'b1); // three bits, then...
pulse_start(); // ...Sr restarts it
send_addr_byte(7'h00, 1'b1); // all-zero address
expect_capture(7'h00, 1'b1, 7);
if (n_valid != 4) begin $display("FAIL: expected 4 captures, saw %0d", n_valid); errors++; end
if (errors == 0)
$display("PASS: eight bits MSB-first, split into address and direction; framing respected");
else $display("FAIL: %0d error(s)", errors);
$finish;
end
endmodule module i2c_address_byte_capture (
input wire clk,
input wire rst_n,
input wire scl_in, // observed bus level, not drive intent
input wire sda_in, // observed bus level, not drive intent
input wire frame_start, // pulse: S or Sr observed (Module 5)
input wire frame_stop, // pulse: P observed (Module 5)
output reg [6:0] addr, // the seven address bits
output reg rw, // 1 = master READS, 0 = master WRITES
output reg addr_valid, // single-cycle pulse: all eight bits captured
output reg capturing
);
reg [7:0] shifter;
reg [3:0] bit_count;
reg scl_q;
// A bit is valid on SCL's RISING edge -- the instant the data-valid rule
// protects. Sampling elsewhere reads a line permitted to move.
wire scl_rise = ~scl_q & scl_in;
always @(posedge clk) begin
if (!rst_n) begin
shifter <= 8'h00;
bit_count <= 4'd0;
addr <= 7'h00;
rw <= 1'b0;
addr_valid <= 1'b0;
capturing <= 1'b0;
scl_q <= 1'b1; // idle bus: SCL released, therefore high
end else begin
addr_valid <= 1'b0;
scl_q <= scl_in;
if (frame_stop) begin
capturing <= 1'b0;
bit_count <= 4'd0;
end else if (frame_start) begin
// A framing START -- first OR repeated -- restarts the capture
// unconditionally, even part way through a byte.
capturing <= 1'b1;
bit_count <= 4'd0;
shifter <= 8'h00;
end else if (capturing & scl_rise) begin
shifter <= {shifter[6:0], sda_in}; // MSB first, so shift left
if (bit_count == 4'd7) begin
// Seven shifts have already happened, so shifter[6:0] IS the
// address and the bit arriving now is the direction bit.
addr <= shifter[6:0];
rw <= sda_in;
addr_valid <= 1'b1;
capturing <= 1'b0;
bit_count <= 4'd0;
end else begin
bit_count <= bit_count + 4'd1;
end
end
end
end
endmodule module i2c_address_byte_capture_tb;
reg clk, rst_n, scl_in, sda_in, frame_start, frame_stop;
wire [6:0] addr;
wire rw, addr_valid, capturing;
integer errors, n_valid, i;
reg [6:0] decoy_pat;
i2c_address_byte_capture dut (.clk(clk), .rst_n(rst_n), .scl_in(scl_in), .sda_in(sda_in),
.frame_start(frame_start), .frame_stop(frame_stop),
.addr(addr), .rw(rw), .addr_valid(addr_valid), .capturing(capturing));
initial clk = 1'b0;
always #5 clk = ~clk;
initial begin #40000; $display("FAIL: watchdog expired"); $finish; end
always @(posedge clk) if (rst_n && addr_valid) n_valid = n_valid + 1;
task send_bit; input b; begin
scl_in = 1'b0; repeat (2) @(negedge clk);
sda_in = b; repeat (2) @(negedge clk);
scl_in = 1'b1; repeat (2) @(negedge clk);
scl_in = 1'b0; repeat (1) @(negedge clk);
end endtask
task pulse_start; begin frame_start = 1'b1; @(negedge clk); frame_start = 1'b0; end endtask
task pulse_stop; begin frame_stop = 1'b1; @(negedge clk); frame_stop = 1'b0; end endtask
task send_addr_byte; input [6:0] a; input dir; integer k; begin
for (k = 6; k >= 0; k = k - 1) send_bit(a[k]);
send_bit(dir);
end endtask
task expect_capture; input [6:0] a; input dir; input integer step; begin
if (addr !== a || rw !== dir) begin
$display("FAIL: step %0d -- captured addr=0x%02h rw=%0b, expected 0x%02h %0b",
step, addr, rw, a, dir);
errors = errors + 1;
end
end endtask
initial begin
errors = 0; n_valid = 0;
rst_n = 1'b0; scl_in = 1'b1; sda_in = 1'b1;
frame_start = 1'b0; frame_stop = 1'b0;
repeat (3) @(negedge clk);
if (capturing !== 1'b0) begin $display("FAIL: capturing asserted out of reset"); errors = errors + 1; end
if (addr_valid !== 1'b0) begin $display("FAIL: addr_valid asserted out of reset"); errors = errors + 1; end
rst_n = 1'b1; @(negedge clk);
send_bit(1'b1); send_bit(1'b0);
if (n_valid != 0) begin $display("FAIL: captured a byte with no preceding START"); errors = errors + 1; end
pulse_start();
if (capturing !== 1'b1) begin $display("FAIL: START did not begin a capture"); errors = errors + 1; end
send_addr_byte(7'h52, 1'b1);
if (n_valid != 1) begin $display("FAIL: expected exactly 1 addr_valid, saw %0d", n_valid); errors = errors + 1; end
expect_capture(7'h52, 1'b1, 2);
if (capturing !== 1'b0) begin $display("FAIL: still capturing after eight bits"); errors = errors + 1; end
pulse_start();
send_addr_byte(7'h2D, 1'b0);
expect_capture(7'h2D, 1'b0, 3);
if (n_valid != 2) begin $display("FAIL: expected 2 addr_valid pulses, saw %0d", n_valid); errors = errors + 1; end
send_bit(1'b1);
if (n_valid != 2) begin $display("FAIL: a ninth bit produced another capture"); errors = errors + 1; end
// SDA moving during the LOW phase must not be sampled.
decoy_pat = 7'h7F;
pulse_start();
for (i = 6; i >= 0; i = i - 1) begin
scl_in = 1'b0; repeat (1) @(negedge clk);
sda_in = ~decoy_pat[i]; repeat (1) @(negedge clk); // decoy
sda_in = decoy_pat[i]; repeat (1) @(negedge clk); // real
scl_in = 1'b1; repeat (2) @(negedge clk);
scl_in = 1'b0; repeat (1) @(negedge clk);
end
send_bit(1'b0);
expect_capture(7'h7F, 1'b0, 5);
pulse_start();
send_bit(1'b1); send_bit(1'b1); send_bit(1'b0);
pulse_stop();
if (capturing !== 1'b0) begin $display("FAIL: STOP did not abandon the capture"); errors = errors + 1; end
send_bit(1'b1); send_bit(1'b1);
if (n_valid != 3) begin $display("FAIL: bits after a STOP were captured"); errors = errors + 1; end
pulse_start();
send_bit(1'b1); send_bit(1'b1); send_bit(1'b1);
pulse_start();
send_addr_byte(7'h00, 1'b1);
expect_capture(7'h00, 1'b1, 7);
if (n_valid != 4) begin $display("FAIL: expected 4 captures, saw %0d", n_valid); errors = errors + 1; end
if (errors == 0)
$display("PASS: eight bits MSB-first, split into address and direction; framing respected");
else $display("FAIL: %0d error(s)", errors);
$finish;
end
endmodule library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity i2c_address_byte_capture is
port (
clk : in std_logic;
rst_n : in std_logic;
scl_in : in std_logic; -- observed bus level
sda_in : in std_logic; -- observed bus level
frame_start : in std_logic; -- pulse: S or Sr (Module 5)
frame_stop : in std_logic; -- pulse: P (Module 5)
addr : out std_logic_vector(6 downto 0); -- the seven address bits
rw : out std_logic; -- 1 = master READS
addr_valid : out std_logic; -- single-cycle pulse
capturing : out std_logic
);
end entity;
architecture rtl of i2c_address_byte_capture is
signal shifter : std_logic_vector(7 downto 0) := (others => '0');
signal bit_count : natural range 0 to 7 := 0;
signal scl_q : std_logic := '1'; -- idle bus: SCL released, therefore high
signal cap : std_logic := '0';
signal scl_rise : std_logic;
begin
-- A bit is valid on SCL's RISING edge -- the instant the data-valid rule
-- protects. Sampling elsewhere reads a line permitted to move.
scl_rise <= (not scl_q) and scl_in;
process (clk)
begin
if rising_edge(clk) then
if rst_n = '0' then
shifter <= (others => '0');
bit_count <= 0;
addr <= (others => '0');
rw <= '0';
addr_valid <= '0';
cap <= '0';
scl_q <= '1';
else
addr_valid <= '0';
scl_q <= scl_in;
if frame_stop = '1' then
cap <= '0';
bit_count <= 0;
elsif frame_start = '1' then
-- A framing START -- first OR repeated -- restarts the capture
-- unconditionally, even part way through a byte.
cap <= '1';
bit_count <= 0;
shifter <= (others => '0');
elsif cap = '1' and scl_rise = '1' then
shifter <= shifter(6 downto 0) & sda_in; -- MSB first
if bit_count = 7 then
-- Seven shifts have already happened, so shifter(6 downto 0)
-- IS the address and the bit arriving now is the direction.
addr <= shifter(6 downto 0);
rw <= sda_in;
addr_valid <= '1';
cap <= '0';
bit_count <= 0;
else
bit_count <= bit_count + 1;
end if;
end if;
end if;
end if;
end process;
capturing <= cap;
end architecture; library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity i2c_address_byte_capture_tb is
end entity;
architecture sim of i2c_address_byte_capture_tb is
signal clk : std_logic := '0';
signal rst_n : std_logic := '0';
signal scl_in : std_logic := '1';
signal sda_in : std_logic := '1';
signal frame_start : std_logic := '0';
signal frame_stop : std_logic := '0';
signal addr : std_logic_vector(6 downto 0);
signal rw, addr_valid, capturing : std_logic;
-- Driven by the counting process, read by the checker (one driver per signal).
signal n_valid : natural := 0;
-- Set by the checker before it suspends, so the watchdog can tell a finished
-- run from a stalled one.
signal test_done : std_logic := '0';
begin
dut : entity work.i2c_address_byte_capture
port map (clk => clk, rst_n => rst_n, scl_in => scl_in, sda_in => sda_in,
frame_start => frame_start, frame_stop => frame_stop,
addr => addr, rw => rw, addr_valid => addr_valid, capturing => capturing);
clk <= not clk after 5 ns;
-- Watchdog. A broken design must produce a REPORTED FAILURE, not a silent stop.
watchdog : process
begin
wait for 40 us;
if test_done = '0' then
report "watchdog expired -- the design never reached the expected state"
severity failure;
end if;
wait;
end process;
count : process (clk)
begin
if rising_edge(clk) then
if rst_n = '1' and addr_valid = '1' then n_valid <= n_valid + 1; end if;
end if;
end process;
stim : process
variable errs : natural := 0;
constant DECOY : std_logic_vector(6 downto 0) := "1111111";
procedure waitn (n : in positive) is
begin
for i in 1 to n loop wait until falling_edge(clk); end loop;
end procedure;
procedure send_bit (b : in std_logic) is
begin
scl_in <= '0'; waitn(2);
sda_in <= b; waitn(2);
scl_in <= '1'; waitn(2);
scl_in <= '0'; waitn(1);
end procedure;
procedure pulse_start is
begin
frame_start <= '1'; waitn(1); frame_start <= '0';
end procedure;
procedure pulse_stop is
begin
frame_stop <= '1'; waitn(1); frame_stop <= '0';
end procedure;
procedure send_addr_byte (a : in std_logic_vector(6 downto 0); dir : in std_logic) is
begin
for k in 6 downto 0 loop send_bit(a(k)); end loop;
send_bit(dir);
end procedure;
procedure expect_capture (a : in std_logic_vector(6 downto 0);
dir : in std_logic; step : in natural) is
begin
if addr /= a or rw /= dir then
report "step " & integer'image(step) & ": captured addr/rw mismatch"
severity error;
errs := errs + 1;
end if;
end procedure;
begin
waitn(3);
if capturing /= '0' then
report "capturing asserted out of reset" severity error; errs := errs + 1; end if;
if addr_valid /= '0' then
report "addr_valid asserted out of reset" severity error; errs := errs + 1; end if;
rst_n <= '1'; waitn(1);
send_bit('1'); send_bit('0');
if n_valid /= 0 then
report "captured a byte with no preceding START" severity error; errs := errs + 1; end if;
pulse_start;
if capturing /= '1' then
report "START did not begin a capture" severity error; errs := errs + 1; end if;
send_addr_byte("1010010", '1'); -- 0x52, read
if n_valid /= 1 then
report "expected exactly 1 addr_valid" severity error; errs := errs + 1; end if;
expect_capture("1010010", '1', 2);
if capturing /= '0' then
report "still capturing after eight bits" severity error; errs := errs + 1; end if;
pulse_start;
send_addr_byte("0101101", '0'); -- 0x2D, write
expect_capture("0101101", '0', 3);
if n_valid /= 2 then
report "expected 2 addr_valid pulses" severity error; errs := errs + 1; end if;
send_bit('1');
if n_valid /= 2 then
report "a ninth bit produced another capture" severity error; errs := errs + 1; end if;
-- SDA moving during the LOW phase must not be sampled.
pulse_start;
for k in 6 downto 0 loop
scl_in <= '0'; waitn(1);
sda_in <= not DECOY(k); waitn(1); -- decoy
sda_in <= DECOY(k); waitn(1); -- real
scl_in <= '1'; waitn(2);
scl_in <= '0'; waitn(1);
end loop;
send_bit('0');
expect_capture("1111111", '0', 5);
pulse_start;
send_bit('1'); send_bit('1'); send_bit('0');
pulse_stop;
if capturing /= '0' then
report "STOP did not abandon the capture" severity error; errs := errs + 1; end if;
send_bit('1'); send_bit('1');
if n_valid /= 3 then
report "bits after a STOP were captured" severity error; errs := errs + 1; end if;
pulse_start;
send_bit('1'); send_bit('1'); send_bit('1');
pulse_start;
send_addr_byte("0000000", '1');
expect_capture("0000000", '1', 7);
if n_valid /= 4 then
report "expected 4 captures" severity error; errs := errs + 1; end if;
if errs = 0 then
report "i2c_address_byte_capture self-check complete: eight bits MSB-first, "
& "split into address and direction; framing respected" severity note;
else
report "i2c_address_byte_capture self-check FAILED" severity error;
end if;
test_done <= '1';
wait;
end process;
end architecture;5a. Two Behaviours That Come Straight From Module 5
The framing inputs are not decoration, and the order in which they are tested is deliberate.
A STOP abandons a byte in flight. If a STOP arrives half way through the address byte, those bits are not an address and never will be. The capture stops and the partial byte is discarded. This follows from Chapter 5.3: a STOP releases every device unconditionally.
A framing START restarts the capture, even mid-byte. This is Chapter 5.2 §3's unconditional-reset rule implemented. A repeated START can arrive at any point, including three bits into what the device thought was an address, and the correct response is to throw those bits away and start counting from zero. Note that frame_start is tested before the shift, so a START arriving in the same cycle as an SCL rising edge wins — which is the safe precedence, because a START means "whatever you thought was happening, stop".
Verified execution. All three testbenches run, and all three complete at the same simulated time:
| language | simulator | result | completes at |
|---|---|---|---|
| SystemVerilog | Icarus Verilog, -g2012 | PASS | 3050 ns |
| Verilog-2005 | Icarus Verilog, -g2005 | PASS | 3050 ns |
| VHDL | nvc 1.23.0 | PASS | 3050 ns |
i2c_address_byte_capture — the eighth bit and addr_valid
10 cycles6. What the Testbench Has To Prove
Seven cases, and the interesting ones are not the happy path.
| step | stimulus | required result | why it is in the suite |
|---|---|---|---|
| 1 | bits with no preceding START | nothing captured | the bus is always carrying something; only framing makes it an address |
| 2 | 0x52 with R/W = 1 | addr = 0x52, rw = 1, one pulse | the split, and that the pulse is an event |
| 3 | 0x2D with R/W = 0 | addr = 0x2D, rw = 0 | a value differing in every bit from step 2, so a stuck shifter fails |
| 4 | a ninth bit, no new START | still two captures | exactly eight bits — the address field is over |
| 5 | SDA driven wrong during SCL low, right before the rise | 0x7F captured | proves sampling is on the rising edge, not "whenever" |
| 6 | STOP three bits into a byte | nothing captured, no inheritance | a partial byte is not an address |
| 7 | Sr three bits into a byte, then a full address | the new address, cleanly | the unconditional-reset rule |
Step 5 is the one that earns its place. It drives SDA to the inverse of the intended bit during the low phase and then to the correct value before the rising edge. A design that sampled on the falling edge, or on any internal-clock cycle while SCL was low, captures the inverted pattern and fails. A design that samples on the rising edge captures 0x7F. Nothing else in the suite distinguishes those two designs, because in every other step SDA is stable for the whole bit.
Step 3's choice of value matters. 0x52 is 1010010 and 0x2D is 0101101 — the bitwise complement. Two consecutive captures of complementary values cannot both be satisfied by a shifter that is stuck, that fails to shift on some bits, or that inverts.
7. Mutation Testing
Seven faults were injected into the verified RTL and the testbench run against each.
| mutation | what it breaks | result |
|---|---|---|
| sample on SCL's falling edge | reads the line while it may be moving | FAIL — no capture at all |
| stop after seven bits | the direction bit becomes an address bit | FAIL — captured 0x29 / 0 |
| stop after nine bits | the byte never completes | FAIL — no addr_valid |
take shifter[7:1] as the address | off-by-one on the split | FAIL — captured 0x29 |
| a STOP does not abandon the byte | a partial byte becomes an address | FAIL — step 6 |
addr_valid is a level, not a pulse | consumers double-count | FAIL — two pulses seen |
| a framing START does not clear the shifter | see below | survived — and provably equivalent |
Six caught. The seventh is worth the space precisely because it did not need a new test.
A mutation that survives is not automatically a coverage hole. Removing shifter <= 8'h00 from the frame_start branch left the whole suite passing, and adding tests would not change that — because the mutation cannot be detected by any stimulus. The argument:
- the shifter is eight bits deep, and
addris read only at the eighth shift, andbit_countis still cleared byframe_start, so eight fresh bits always arrive before the read.
Eight shifts of an eight-bit register overwrite it completely. The initial value is therefore unobservable at the outputs, under every possible input sequence. The clear is defensive, not functional — it keeps the register deterministic for waveform debugging and avoids carrying an X into a partially-shifted view, and both are good reasons to keep it, neither of which is a behaviour a testbench can check.
Reporting this as "6 of 7 caught, one coverage gap" would be wrong. It is 6 caught and one equivalent mutant, and distinguishing the two is the difference between mutation testing that improves a suite and mutation testing that manufactures busywork.
8. Verification Connection — The Address Is Where a Scoreboard Starts
A protocol monitor's first job after framing is to publish the address and direction, because everything downstream is conditioned on them.
// The transaction carries the SEVEN-BIT address, not the wire byte, because
// that is what a test writer and a datasheet both mean by "the address".
// Storing the wire byte and shifting at every comparison is how the 0x48 /
// 0x90 confusion of section 2 gets into a testbench.
class i2c_addr_phase extends uvm_sequence_item;
`uvm_object_utils(i2c_addr_phase)
rand bit [6:0] addr; // as the datasheet states it
rand bit read; // 1 = master reads
bit ten_bit; // set by the monitor, not by the test
bit acked; // filled in by the monitor, Module 7
// A convenience for driving, kept in ONE place so the shift appears once
// in the whole environment rather than at every call site.
function bit [7:0] wire_byte(); return {addr, read}; endfunction
function string convert2string();
return $sformatf("addr=0x%02h %s (wire 0x%02h)",
addr, read ? "READ" : "WRITE", wire_byte());
endfunction
endclassTwo things in that sketch are the lesson rather than the syntax.
The transaction stores the seven-bit address and derives the wire byte. The alternative — storing the byte and shifting wherever a comparison happens — puts the same >> 1 in a dozen places, and the bug is always the one place it was forgotten. Deriving it in one method means a mismatch is a mismatch, not an ambiguity about which representation was being compared.
convert2string prints both. A log line reading addr=0x48 READ (wire 0x91) ends the entire class of confusion in §2 at the moment somebody reads the log, which is considerably cheaper than ending it in a debug session.
9. FPGA and ASIC Implications
The bus lines must be synchronised before this block sees them. SDA and SCL are driven by other devices and have no relationship to the internal clock. The design as written assumes scl_in and sda_in are already-synchronised signals; sampling raw pads into a shift register invites metastability, and the failure mode is an occasional wrong address bit, which presents as a device that "sometimes does not respond". Module 19 owns the synchroniser.
The internal clock must be fast enough to see every SCL edge. This is a sampled design, so the internal clock has to be comfortably faster than the bus. Chapter 5.1 quoted the specification's floor of sampling SDA at least twice per clock period for software implementations; hardware normally has far more margin, but a deeply-filtered input or a slow internal clock brings the two numbers closer together than expected.
The shift register is the cheapest thing in the design, and the edge detector is the part that gets reviewed. Eight flip-flops plus a four-bit counter is nothing. The scl_q history bit is where a design gets it wrong — either by omitting it and testing the level instead of the edge, or by sampling SDA and SCL in different clock domains so their relationship is no longer trustworthy.
On an ASIC the last-address register is usually software-visible. last_addr exists so a driver or a debugger can see what the peripheral actually observed, which is the difference between diagnosing an address mismatch in one register read and diagnosing it with a logic analyser. Chapter 3.4 established the register-interface conventions this would follow.
10. Debugging — The Device at Half Its Address
A sensor that answered at 0x24 when its datasheet said 0x48
Pitfall — a driver API that takes a seven-bit address, handed a wire byte
// A vendor header, written against an eight-bit convention:
//
// #define TMP_SENSOR_ADDR 0x90 // "TMP sensor, write address"
//
// A driver for a different SoC, whose HAL takes a SEVEN-BIT address and does the
// shift internally:
//
// i2c_write(bus, TMP_SENSOR_ADDR, reg, val); // HAL shifts left by 1
//
// The HAL dutifully shifts: 0x90 << 1 = 0x120, truncated to seven bits by the
// peripheral's address register = 0x20. So the byte on the wire addresses 0x20,
// and the sensor at 0x48 never hears its name.
//
// Nothing in the code looks wrong. The constant is named ADDR, the HAL parameter
// is named addr, the datasheet mentions 0x90, and every layer is internally
// consistent. The two layers simply disagree about what "addr" means.The sensor never acknowledges. Every transfer NACKs on the address byte.
The first thing anyone does is run an address scan, and the scan makes it WORSE, because the scan finds a device -- at 0x48, exactly where the datasheet said it would be. So the hardware is present, correctly wired, correctly powered, and answering. The driver still cannot reach it.
That combination sends the investigation towards the driver's transfer logic, its clock configuration, its interrupt handling -- everything except the address constant, which has already been "verified" against the datasheet by eye.
A capture shows a clean START, a clean address byte, and a NACK. Reading the address off the capture is the moment it resolves, and it is also the step most people skip, because the address is the one field everybody is sure about.
Two conventions for the same field, and a boundary where nobody converted.
The seven-bit address is 0x48. The wire byte for a write is 0x90. Both numbers describe the same device, and section 2's rule -- a seven-bit address is at most 0x7F -- identifies 0x90 as a wire byte at a glance. The vendor header stored a wire byte in a constant named ADDR; the HAL expected a seven-bit address; the shift therefore happened twice.
Shifting twice is not a small error. 0x48 shifted once is 0x90, which is the correct wire byte. Shifted again it is 0x120, and the peripheral's seven-bit address field keeps only the low seven bits: 0x20. So the transfer went to address 0x20, which on this board is nothing at all -- hence a clean NACK rather than a wrong device responding, which would have been a much louder clue.
Note what the address scan actually proved. A scan iterates over SEVEN-BIT addresses and reports the ones that answer, so it reported 0x48 -- the truth about the bus, and no information at all about what the driver was transmitting. It confirmed the device and was mistaken for confirming the driver.
// State the convention in the NAME, at every boundary:
//
// #define TMP_SENSOR_ADDR7 0x48 // seven-bit, as the datasheet states
// #define TMP_SENSOR_WIRE_WR 0x90 // (ADDR7 << 1) | 0
//
// and do the shift in exactly one place -- the same discipline as section 8's
// transaction object, for the same reason.
//
// The diagnostic that finds it in seconds, and is worth making a habit:
//
// READ THE ADDRESS OFF THE CAPTURE. Not off the source. Take the first eight
// bits after the START, drop the last one, and compare the remaining seven to
// the datasheet. The address is the field engineers are most confident about
// and therefore the field they check last, which is exactly backwards.
//
// And note what an address scan does and does not tell you: it reports which
// addresses ANSWER. It says nothing about which address your driver SENDS.
// Those are different questions, and a scan that finds the device can coexist
// with a driver that never reaches it.
//
// The review habit: any constant or parameter holding an I²C address gets a 7 or
// an 8 in its name. "addr" is not a specification. Two layers that both use the
// unqualified word will eventually disagree about it, and the disagreement is
// silent -- because both numbers are valid bytes and neither looks wrong.
//
// The sanity check for a whole table at a glance: if every address in a list is
// even, it is a list of write wire bytes, because bit 0 is the direction bit.11. Common Misconceptions
"The address byte is an address field and a direction field." It is one byte. Seven of its bits carry an address and the eighth carries a direction, but it is transmitted, sampled and captured as a unit, and the split is a wiring decision made once at the end.
"0x90 and 0x91 are two devices." They are one device and two directions — the same seven-bit address 0x48 with R/W = 0 and R/W = 1.
"A number presented as an I²C address is a seven-bit address." Not reliably. A seven-bit address is at most 0x7F; anything larger is a wire byte. Both conventions are in wide use and neither is wrong.
"A slave knows immediately whether it is being read or written." It knows on the eighth bit. The direction arrives last, after the address it has already matched, which is why a decoder latches direction at the end of the byte.
"Sampling SDA anywhere during the bit is fine, since it is stable." It is stable only while SCL is high. During the low phase it is explicitly permitted to move, and step 5 of §6 is built to fail any design that samples there.
"An address scan that finds the device proves the driver's address is right." A scan reports which addresses answer. It says nothing about which address the driver transmits, and §10 is an entire failure resting on conflating the two.
"A surviving mutation means the testbench has a hole." Sometimes, and not always. §7's surviving mutation is provably undetectable by any stimulus, because an eight-deep shift register read after exactly eight shifts cannot expose its initial value.
12. Reason It Through
A datasheet says 0x68. A colleague's driver uses 0xD0 and works. Who is wrong?
Nobody. 0x68 is the seven-bit address; 0xD0 is (0x68 << 1) | 0, the wire byte for a write. The read wire byte would be 0xD1. The check that settles it instantly is that 0xD0 exceeds 0x7F and therefore cannot be a seven-bit address.
Why does the capture block sample SDA on SCL's rising edge rather than its falling edge?
Because the rising edge is the start of the window in which the data-valid rule guarantees SDA is stable. During SCL's low phase SDA is explicitly permitted to change — that is where the transmitter prepares the next bit — so a sample taken there may catch the line mid-transition or catch the previous bit. §6's step 5 constructs exactly that trap and fails any design that falls into it.
Why is the address not split as the bits arrive?
Because splitting early requires deciding, per bit, which field the bit belongs to — which means the design has to know the bit index anyway, and now has two registers to keep consistent instead of one. Collecting eight bits and taking shifter[6:0] and sda_in once, at the eighth shift, is both smaller and has one place to be wrong instead of eight.
A repeated START arrives three bits into an address byte. What must the capture do, and why does frame_start take precedence over the SCL edge?
It must discard the three bits and begin counting from zero, because Chapter 5.2 established that a START unconditionally resets every device's protocol state. The precedence matters because both events can land in the same internal clock cycle, and a START means "whatever you thought was happening, stop" — resolving it the other way would fold one stale bit into the new address.
Two consecutive test captures use 0x52 and 0x2D. Why those two values rather than, say, 0x52 twice?
They are bitwise complements. A shifter that is stuck, that fails to shift on particular bit positions, or that inverts cannot produce both correct results. Repeating one value would let several broken designs through, because a design only has to be right about the bits that happen to differ from whatever it is holding.
13. Understanding Check
14. Summary
The first byte after a START is one byte, not two fields. Eight bits, MSB first, one per SCL pulse — seven carrying an address and the eighth a direction, transmitted identically.
Two conventions exist for writing the address down, and both are in wide use: the seven-bit address as the datasheet states it, and the wire byte with the direction bit in place. wire = (addr << 1) | rw, and a seven-bit address never exceeds 0x7F.
0x90 and 0x91 are one device, not two.
The direction arrives last. A slave matches its address on seven bits and only learns the direction on the eighth, which is why decoders latch direction at the end of the byte.
A bit is valid on SCL's rising edge. The low phase is where SDA is permitted to move, so sampling there is sampling a line in motion — and §6's decoy test fails any design that does.
The split happens once, at the eighth shift: addr from the seven bits already collected, rw from the bit arriving now. No second register and no arithmetic.
Framing wins over data. A STOP abandons a partial byte; a repeated START discards it and restarts the count — and frame_start is tested before the shift, because a START means stop whatever you were doing.
Not every surviving mutation is a gap. §7's survivor is provably undetectable, and calling it a coverage hole would have produced tests that cannot distinguish anything.
15. What Comes Next
Seven bits of address reach 128 devices, sixteen of which the bus has spoken for — a limit this chapter has not examined and the next two do, from opposite directions.
Chapter 6.2 takes the extension: a two-byte addressing mode that expands the space to 1024, coexists with seven-bit devices on the same bus, and is built entirely out of the reserved space — which is why understanding it requires knowing what is reserved and why.
Browse the full path on the I²C tutorials index. For the framing this byte follows, see The START Condition; for the rule that makes each bit readable, The Data-Valid Rule.
Continue learning
Related tutorials
- Related topic
I²C Byte and Bit Transmission — MSB First, Nine Clocks
Every byte on this bus costs nine clock pulses, not eight. Eight carry data most-significant-bit first, and the ninth belongs to somebody else — which makes the transmitter's most important job in that slot to stop driving.
- Related topic
Repeated START — Holding the Bus Between Phases
A repeated START is not a new waveform. It is the START edge again, and what makes it a different event is that the bus was already busy. That single fact is why a classifier needs state and why a monitor that joins late cannot classify what it sees.
- Related topic
START/STOP Timing and Malformed Framing
Three framing margins, each with two anchor events, all of them minimums: the hold after a START, the setup before a repeated START, and the setup before a STOP. Build a sequencer that generates all three and refuses an illegal configuration, then catalogue the malformed framing the margins exist to prevent.
- Related topic
The START Condition
START is SDA falling while SCL is high, it is generated only by the controller, and it makes the bus busy. Derive what every device must do in response, then build a detector in three languages and find out why its two guard terms and its reset value are all load-bearing.
