Difficulty: Medium · Puzzle 5 of 6 · Topic: APB Protocol Puzzles
APB write with wait states. The trace below shows PADDR constant at 0x10 and PWDATA = A5, A5, 5A, 5A in cycles 1-4 (cycle 1 is SETUP, PREADY goes high in cycle 4). A stability checker compares each cycle of a running transfer with the previous one. What does it report and what value does the slave store?
`timescale 1ns/1ns
module tb;
localparam int N = 6;
// cycle: 012345
localparam bit [0:N-1] PSEL = 6'b011110;
localparam bit [0:N-1] PENABLE = 6'b001110;
localparam bit [0:N-1] PREADY = 6'b000010;
localparam bit [47:0] PADDR = {8'h00, 8'h10, 8'h10, 8'h10, 8'h10, 8'h00};
localparam bit [47:0] PWDATA = {8'h00, 8'hA5, 8'hA5, 8'h5A, 8'h5A, 8'h00};
bit clk = 0;
int cyc = 0, bad = 0;
bit p_busy = 0; // previous cycle was SETUP or a waiting ACCESS
bit [7:0] p_addr = 0, p_wdata = 0;
always #5 clk = ~clk;
wire psel = PSEL[cyc], penable = PENABLE[cyc], pready = PREADY[cyc];
wire [7:0] paddr = PADDR [(N-1-cyc)*8 +: 8];
wire [7:0] pwdata = PWDATA[(N-1-cyc)*8 +: 8];
always @(posedge clk) begin
if (psel && p_busy) begin
if (paddr !== p_addr) begin bad++; $display("VIOLATION cycle %0d: PADDR changed 0x%0h -> 0x%0h", cyc, p_addr, paddr); end
if (pwdata !== p_wdata) begin bad++; $display("VIOLATION cycle %0d: PWDATA changed 0x%0h -> 0x%0h", cyc, p_wdata, pwdata); end
end
if (psel && penable && pready) $display("cycle %0d: write completes with PWDATA=0x%0h", cyc, pwdata);
p_busy <= psel && !(penable && pready);
p_addr <= paddr; p_wdata <= pwdata;
if (cyc == N-1) $display("violations = %0d", bad);
cyc <= cyc + 1;
end
initial #(10*N) $finish;
endmoduleThe master must hold the controls from setup until completion. Find where the value differs from the previous cycle of the same transfer.
1) Cycle 1 SETUP: addr 0x10, data 0xA5. Cycle 2 ACCESS (wait): unchanged.
2) Cycle 3 ACCESS (wait): PWDATA is 0x5A, different from the previous cycle of the same transfer -> violation.
3) Cycle 4 ACCESS completes with PWDATA 0x5A. It equals cycle 3, so the checker does not report it again.
4) The slave stores whatever is on the bus at completion: 0x5A, not the 0xA5 announced in setup.Answer: One violation, at cycle 3 (PWDATA 0xA5 -> 0x5A during a wait state). PADDR is stable. The write completes in cycle 4 with 0x5A, so the slave stores the corrupted value.
Checked by running the code in Verilator 5; the printed output supports the answer above. A previous-cycle comparison flags the single change at cycle 3; the completion carries the corrupted value.
A change is reported once, where it happens, not on every later cycle: counting 'violations' as the number of bad cycles gives 2 here and is not what a diff-against-previous checker reports. Also the SETUP to ACCESS step is covered by the rule: only the completion cycle ends the obligation.
Which APB signals must a master hold from SETUP until the transfer completes? Model answer: PSEL, PADDR, PWRITE, PPROT, and for writes PWDATA and PSTRB (APB4), plus PENABLE staying high once raised. The slave can sample them at any access cycle, so they are all part of the stability contract.