descramble: Use lsfr counter for unlock_timer
The critical path often includes the unlock timer. Switch to an lfsr implementation. This saves around 20 LUTs and reduces the critical path from the carry chain (and the or reduction) to just the and reduction. Signed-off-by: Sean Anderson <seanga2@gmail.com>
This commit is contained in:
parent
3ec1f4d77d
commit
1b47635644
|
@ -34,14 +34,25 @@ module descramble (
|
||||||
initial idle_counter = CONSECUTIVE_IDLES;
|
initial idle_counter = CONSECUTIVE_IDLES;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* We use a LFSR for the unlock counter in order to relax the timing
|
||||||
|
* requirements. Although we could use a 16-bit register, we use
|
||||||
|
* a 17-bit one to reduce the number of taps we need. Values were
|
||||||
|
* generated with the following python script:
|
||||||
|
*
|
||||||
|
* lfsr = 0x1ffff
|
||||||
|
* for _ in range(2**17 - cycles - 1):
|
||||||
|
* lfsr = ((lfsr << 1) & 0x1ffff) | (((lfsr >> 16) & 1) ^ ((lfsr >> 13) & 1))
|
||||||
|
*
|
||||||
* The amount of time without recieving consecutive idles before we
|
* The amount of time without recieving consecutive idles before we
|
||||||
* unlock. This must be greater than 361us (7.2.3.3(f)). 2^16-1 works
|
* unlock. This must be greater than 361us (7.2.3.3(f)), which is
|
||||||
* out to around 524us at 125MHz.
|
* 45125 cycles at 125MHz.
|
||||||
*/
|
*/
|
||||||
localparam UNLOCK_TIME = 16'hffff;
|
localparam UNLOCK_VALUE = 17'h29fc;
|
||||||
/* 5us, or around one minimum-length packet plus some extra */
|
/* One 9000-byte jumbo frame plus an extra preamble */
|
||||||
localparam TEST_UNLOCK_TIME = 16'd625;
|
localparam JUMBO_UNLOCK_VALUE = 17'h12d84;
|
||||||
reg [15:0] unlock_counter, unlock_counter_next;
|
/* One minimum-length packet plus some extra (5us or 625 cycles) */
|
||||||
|
localparam TEST_UNLOCK_VALUE = 17'h11077;
|
||||||
|
reg [16:0] unlock_counter, unlock_counter_next;
|
||||||
|
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
ldd = { lfsr[8] ^ lfsr[10], lfsr[7] ^ lfsr[9] };
|
ldd = { lfsr[8] ^ lfsr[10], lfsr[7] ^ lfsr[9] };
|
||||||
|
@ -88,9 +99,10 @@ module descramble (
|
||||||
locked_next = 1;
|
locked_next = 1;
|
||||||
unlock_counter_next = unlock_counter;
|
unlock_counter_next = unlock_counter;
|
||||||
if (relock) begin
|
if (relock) begin
|
||||||
unlock_counter_next = test_mode ? TEST_UNLOCK_TIME : UNLOCK_TIME;
|
unlock_counter_next = test_mode ? TEST_UNLOCK_VALUE : UNLOCK_VALUE;
|
||||||
end else if (|unlock_counter) begin
|
end else if (!(&unlock_counter)) begin
|
||||||
unlock_counter_next = unlock_counter - 1;
|
unlock_counter_next[0] = unlock_counter[16] ^ unlock_counter[13];
|
||||||
|
unlock_counter_next[16:1] = unlock_counter[15:0];
|
||||||
end else begin
|
end else begin
|
||||||
locked_next = 0;
|
locked_next = 0;
|
||||||
end
|
end
|
||||||
|
@ -109,7 +121,7 @@ module descramble (
|
||||||
lfsr <= 0;
|
lfsr <= 0;
|
||||||
idle_counter <= CONSECUTIVE_IDLES;
|
idle_counter <= CONSECUTIVE_IDLES;
|
||||||
relock <= 0;
|
relock <= 0;
|
||||||
unlock_counter <= 0;
|
unlock_counter <= 17'h1ffff;
|
||||||
locked <= 0;
|
locked <= 0;
|
||||||
descrambled_valid <= 0;
|
descrambled_valid <= 0;
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue