8000 fix xorshift getting stuck at 0 because of always_comb · hdl-util/rand@f0df597 · GitHub
[go: up one dir, main page]

Skip to content

Commit f0df597

Browse files
committed
fix xorshift getting stuck at 0 because of always_comb
1 parent 761e23e commit f0df597

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

src/xorshift.sv

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ module xorshift #(
55
parameter bit [WIDTH-1:0] POLYNOMIAL = WIDTH'(0)
66
) (
77
input logic clk,
8+
// Synchronous reset
89
input logic reset,
10+
// An optional seed used to set the initial state upon reset
911
input logic [WIDTH-1:0] seed,
10-
output logic [WIDTH-1:0] state
12+
output logic [WIDTH-1:0] state = WIDTH'(0)
1113
);
1214

1315
logic [WIDTH-1:0] polynomial;
@@ -16,12 +18,16 @@ logic lfsr_xnor;
1618
integer i;
1719
always_comb
1820
begin
19-
lfsr_xnor = 1'b0;
21+
lfsr_xnor = 0;
2022
for (i = 0; i < WIDTH; i++)
2123
begin
2224
if (polynomial[i])
2325
lfsr_xnor = lfsr_xnor ^~ state[i];
2426
end
27+
// Trick to negate the fact that it's initially set to 0. It should be synthesized away.
28+
// This works because the maximal length polynomials all have an even number of terms.
29+
// Have confirmed it works for a few values, but I may be wrong.
30+
lfsr_xnor = lfsr_xnor ^~ 0;
2531
end
2632

2733
always_ff @(posedge clk)

test/xorshift_tb.sv

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,23 @@ module xorshift_tb;
77
#1;
88
clk <= ~clk;
99
end
10-
localparam int WIDTH = 12;
11-
logic reset = 1'b1;
12-
logic [WIDTH-1:0] seed = WIDTH'(1), state;
13-
xorshift #(.WIDTH(WIDTH)) xorshift(.clk(clk), .reset(reset), .seed(seed), .state(state));
10+
localparam int WIDTH = 4;
11+
logic reset = 1'b0;
12+
logic [WIDTH-1:0] state;
13+
xorshift #(.WIDTH(WIDTH)) xorshift(.clk(clk), .reset(reset), .state(state));
1414

1515
logic [WIDTH-1:0] seen [0:2**WIDTH-1];
16-
integer i, current = -1;
16+
integer i, current = 0;
1717
always_ff @(posedge clk)
1818
begin
19-
if (current == -1)
20-
reset <= 1'b0;
21-
else if (current == 2**WIDTH - 1)
19+
if (current == 3 * 2**WIDTH)
2220
$finish;
2321
else
2422
begin
25-
seen[current] <= state;
26-
for (i = 0; i < current; i++)
23+
seen[current % (2**WIDTH - 1)] <= state;
24+
for (i = 0; i < current % (2**WIDTH - 1); i++)
2725
begin
28-
assert(seen[i] != state) else $fatal(1, "Encountered a repeat of %d at %d %d", state, i, current);
26+
assert(seen[i] != state) else $fatal(1, "Encountered a repeat of %d at %d %d %d %p", state, i, current % (2**WIDTH - 1), seen);
2927
end
3028
end
3129
current <= current + 1'd1;

0 commit comments

Comments
 (0)
0