Difficulty: Easy · Puzzle 2 of 6 · Topic: APB Protocol Puzzles
The APB slave below inserts WAIT=2 wait states (PREADY low for the first two access cycles). The master starts one write of 0xAB to address 0x10 whose SETUP phase is cycle 1. How many cycles does the transfer take (setup through completion), in which cycle does the slave write memory, and what must the master do with PWDATA meanwhile?
`timescale 1ns/1ns
module apb_slave #(parameter int WAIT = 2) (
input bit clk, input bit psel, input bit penable, input bit pwrite,
input bit [7:0] paddr, input bit [7:0] pwdata, output bit pready);
bit [7:0] mem [256];
int wcnt = 0;
assign pready = psel && penable && (wcnt == 0);
always @(posedge clk) begin
if (psel && !penable) wcnt <= WAIT;
else if (psel && penable && wcnt != 0) wcnt <= wcnt - 1;
if (pready && pwrite) mem[paddr] <= pwdata;
end
endmodule
module tb;
bit clk = 0;
always #5 clk = ~clk;
bit psel = 0, penable = 0, pwrite = 0;
bit [7:0] paddr = 0, pwdata = 0;
wire pready;
int cyc = 0, start = -1;
apb_slave #(.WAIT(2)) s(clk, psel, penable, pwrite, paddr, pwdata, pready);
always @(posedge clk) begin
cyc <= cyc + 1;
if (psel && !penable) begin $display("cycle %0d: SETUP", cyc); penable <= 1; end
else if (psel && penable) begin
if (pready) begin
$display("cycle %0d: ACCESS complete (PREADY=1), transfer took %0d cycles", cyc, cyc - start + 1);
psel <= 0; penable <= 0;
end else $display("cycle %0d: ACCESS wait state (PREADY=0)", cyc);
end
if (cyc == 0) begin psel <= 1; pwrite <= 1; paddr <= 8'h10; pwdata <= 8'hAB; start = 1; end
end
initial begin
#(10*8);
$display("mem[0x10] = 0x%0h", s.mem[8'h10]);
$finish;
end
endmoduleThe slave only writes in a cycle where PREADY is high.
1) Cycle 1: SETUP (PSEL=1, PENABLE=0). The slave loads its wait counter with 2.
2) Cycles 2 and 3: ACCESS, PREADY=0 -> two wait states. The counter counts down.
3) Cycle 4: ACCESS, PREADY=1 -> transfer completes. The slave writes mem[0x10]=0xAB at the end of this cycle.
4) Total = 1 setup + 2 wait + 1 completing access = 4 cycles. The master holds PADDR, PWRITE and PWDATA stable throughout.Answer: 4 cycles (cycle 1 to cycle 4). The write to mem[0x10] happens at the completing access cycle (cycle 4); PWDATA must not change until then.
Checked by running the code in Verilator 5; the printed output supports the answer above. A real master/slave pair with WAIT=2: the transfer takes four cycles and the write lands at the completion cycle.
The data is not stored in the first access cycle: the slave must not commit before PREADY. A bridge model that samples PWDATA or updates its shadow register at the first PENABLE cycle is one wait state too early (invisible with a zero-wait slave).
Total cycles as a function of the wait states W? Model answer: 2 + W (one setup, W waiting access cycles, one completing access cycle).