Why would these two clear on reads behave differently?
Device: Cyclone IV EP4CE15F17C8N
HDL: Verilog
We have a register (status_reg) in our FPGA that we want to clear when we read (IE push data it to SPI buffer). When we read this register, we & it with a bit pattern to clear the desired bits (example A). This has been working as expected, although we don’t know why.
We tried to add a second register (error_reg) and clear it upon being read, this time clearing every bit (example B). We even chose to & the register with zeros for consistency with how we handle the other register. However when we did this, the SPI would always read 0, even though the debugger showed us that the register was being set and reset. For some reason, the data is not coming through the SPI. Using different bit patterns did not change the behavior.
So why does example A work as expected, and example B does not? Why might the two give different behaviors despite using similar logics? Is there a race between setting and clearing the register?
...
output reg [15:0] spi_out,
output reg [15:0] status_reg,
output reg [15:0] error_reg,
...
// Example A: works as expected
A:
begin
spi_out <= status_reg;
status_reg <= (status_reg & 16'b1110000000110001);
end
// Example B: spi_out always returns zeros
B:
begin
spi_out <= error_reg;
error_reg <= (error_reg & 16'b0000000000000000);
end
Our concern is that for one register it works and the other it does not. It looks like it could be a timing issue with the clear happening before the data is actually sent out on the SPI bus. We enclosed the two non-blocking statements in a begin/end to make them sequential. And even tested out making them blocking to force the value transfer to the data bus before we clear the bits, but that had no effect either.
Well, that looks basically ok.
I would have to assume that input CS is only valid for a single clock cycle. Correct?
Or if CS is valid for more than one clock cycle then SPI_RD is only valid for one clock cycle.
Otherwise if CS and/or SPI_RD is present for two (or more cycles) the register will be read once, then cleared, then read again with the value zero.