This is an issue that has come up repeatedly over my career and I’ve never had much success understanding or fixing it, let’s see if this is the day
Basically I have an issue in a unit-test that I have traced back to a valid/ready handshake, which does not obey the required rules.
The handshake is part of an AXI-MemoryMapped interface, in the waveform viewer I see the following:
As you can see, araddr
changes (from 8 to 10) before it should. Data should remain stable while valid is high until ready is asserted and the handshake happens.
I immediately went searching for the peace of code driving those signals, which is a task in my TB:
task automatic read_rq(input logic [ADDR_WIDTH-1:0] addr);
s_arvalid <= 1'b1;
s_araddr <= addr;
@(posedge clk);
while (!s_arready) @(posedge clk);
s_arvalid <= 1'b0;
endtask
As I mentioned this is not the first time I find this issue. In the past I have always solved it by just changing the code a little, even thought I don’t really see the issue.
Basically we are putting the address on the bus and asserting valid, then we wait for one clock cycle, because even if ready is already high (which could happen) we will always hold the address one clock cycle. After that one cycle we check, if ready is not high we wait another and so on.
I assume there’s some race condition here, but I don’t fully understand what is causing it nor how to solve it.
If somebody understands what is going on here I would appreciate it 🙂