descramble: Determine relock_next from idle_counter directly

When writing this initially, I tried to remove some duplicate
conditionals by working with idle_counter_next. However, yosys isn't
smart enough to rewrite the calculation in terms of idle_counter, so do
it ourselves. This breaks up the critical path.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
This commit is contained in:
Sean Anderson 2022-10-30 20:53:18 -04:00
parent 1b47635644
commit 548bf79f55
1 changed files with 33 additions and 21 deletions

View File

@ -71,29 +71,41 @@ module descramble (
else if (scrambled_valid[1])
lfsr_next = { lfsr[8:0], locked ? ldd : ~scrambled };
idle_counter_next = idle_counter;
if (scrambled_valid[1]) begin
if (descrambled_next[1] && descrambled_next[0])
idle_counter_next = idle_counter - 2;
else if (descrambled_next[0])
idle_counter_next = idle_counter - 1;
else
idle_counter_next = CONSECUTIVE_IDLES;
end else if (scrambled_valid[0]) begin
if (descrambled_next[1])
idle_counter_next = idle_counter - 1;
else
idle_counter_next = CONSECUTIVE_IDLES;
end
/*
* Reset the counter to 2 to ensure we can always subtract
* idles without underflowing. This clause is made to depend
* on idle_counter (and not idle_counter_next) to reduce the critical
* path. The actual condition is idle_counter_next <= 1 (aka
* we are about to underflow, and have gotten at least 28
* consecutive 1s).
*/
`define RELOCK begin \
idle_counter_next = 2; \
relock_next = 1; \
end
idle_counter_next = idle_counter;
relock_next = 0;
if (!idle_counter_next[4:1]) begin
/*
* Reset the counter to 2 to ensure we can always
* subtract idles without underflowing
*/
idle_counter_next = 2;
relock_next = 1;
if (scrambled_valid[1]) begin
if (descrambled_next[1] && descrambled_next[0]) begin
idle_counter_next = idle_counter - 2;
if (!idle_counter[4:2])
`RELOCK
end else if (descrambled_next[0]) begin
idle_counter_next = idle_counter - 1;
if (!idle_counter[4:2] && idle_counter[1:0] != 2'b11)
`RELOCK
end else begin
idle_counter_next = CONSECUTIVE_IDLES;
end
end else if (scrambled_valid[0]) begin
if (descrambled_next[1]) begin
idle_counter_next = idle_counter - 1;
if (!idle_counter[4:2] && idle_counter[1:0] != 2'b11)
`RELOCK
end else begin
idle_counter_next = CONSECUTIVE_IDLES;
end
end
locked_next = 1;