From 548bf79f551887a7c5953acc2e3ed26e7883d936 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Sun, 30 Oct 2022 20:53:18 -0400 Subject: [PATCH] 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 --- rtl/descramble.v | 54 +++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/rtl/descramble.v b/rtl/descramble.v index c4c5cfd..775122a 100644 --- a/rtl/descramble.v +++ b/rtl/descramble.v @@ -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;