|
| 1 | +module xorshift #( |
| 2 | + parameter int WIDTH, |
| 3 | + // By default, a polynomial from a table of known polynomials is picked. |
| 4 | + // You may want to specify your own if your polynomial is beyond the supported range |
| 5 | + parameter bit [WIDTH-1:0] POLYNOMIAL = WIDTH'(0) |
| 6 | +) ( |
| 7 | + input logic clk, |
| 8 | + input logic reset, |
| 9 | + input logic [WIDTH-1:0] seed, |
| 10 | + output logic [WIDTH-1:0] state |
| 11 | +); |
| 12 | + |
| 13 | +logic [WIDTH-1:0] polynomial; |
| 14 | +logic lfsr_xnor; |
| 15 | + |
| 16 | +integer i; |
| 17 | +always_comb |
| 18 | +begin |
| 19 | + lfsr_xnor = 1'b0; |
| 20 | + for (i = 0; i < WIDTH; i++) |
| 21 | + begin |
| 22 | + if (polynomial[i]) |
| 23 | + lfsr_xnor = lfsr_xnor ^~ state[i]; |
| 24 | + end |
| 25 | +end |
| 26 | + |
| 27 | +always_ff @(posedge clk) |
| 28 | +begin |
| 29 | + if (reset) |
| 30 | + state <= seed; |
| 31 | + else |
| 32 | + state <= {state[WIDTH-2:0], lfsr_xnor}; |
| 33 | +end |
| 34 | + |
| 35 | +generate |
| 36 | + if (POLYNOMIAL != WIDTH'(0)) |
| 37 | + assign polynomial = POLYNOMIAL; |
| 38 | + else |
| 39 | + case (WIDTH) |
| 40 | +// Special thanks to Philip Koopman for these maximal length LFSR feedback polynomials |
| 41 | +// for i in {4..64}; do echo -n $i': assign polynomial = '$i"'"'h'; curl 'http://users.ece.cmu.edu/~koopman/lfsr/'$i'.txt' 2>/dev/null | head -n 1 | tr -d '\n'; echo ';'; done |
| 42 | +4: assign polynomial = 4'h9; |
| 43 | +5: assign polynomial = 5'h12; |
| 44 | +6: assign polynomial = 6'h21; |
| 45 | +7: assign polynomial = 7'h41; |
| 46 | +8: assign polynomial = 8'h8E; |
| 47 | +9: assign polynomial = 9'h108; |
| 48 | +10: assign polynomial = 10'h204; |
| 49 | +11: assign polynomial = 11'h402; |
| 50 | +12: assign polynomial = 12'h829; |
| 51 | +13: assign polynomial = 13'h100D; |
| 52 | +14: assign polynomial = 14'h2015; |
| 53 | +15: assign polynomial = 15'h4001; |
| 54 | +16: assign polynomial = 16'h8016; |
| 55 | +17: assign polynomial = 17'h10004; |
| 56 | +18: assign polynomial = 18'h20013; |
| 57 | +19: assign polynomial = 19'h40013; |
| 58 | +20: assign polynomial = 20'h80004; |
| 59 | +21: assign polynomial = 21'h100002; |
| 60 | +22: assign polynomial = 22'h200001; |
| 61 | +23: assign polynomial = 23'h400010; |
| 62 | +24: assign polynomial = 24'h80000D; |
| 63 | +25: assign polynomial = 25'h1000004; |
| 64 | +26: assign polynomial = 26'h2000023; |
| 65 | +27: assign polynomial = 27'h4000013; |
| 66 | +28: assign polynomial = 28'h8000004; |
| 67 | +29: assign polynomial = 29'h10000002; |
| 68 | +30: assign polynomial = 30'h20000029; |
| 69 | +31: assign polynomial = 31'h40000004; |
| 70 | +32: assign polynomial = 32'h80000057; |
| 71 | +33: assign polynomial = 33'h100000029; |
| 72 | +34: assign polynomial = 34'h200000073; |
| 73 | +35: assign polynomial = 35'h400000002; |
| 74 | +36: assign polynomial = 36'h80000003B; |
| 75 | +37: assign polynomial = 37'h100000001F; |
| 76 | +38: assign polynomial = 38'h2000000031; |
| 77 | +39: assign polynomial = 39'h4000000008; |
| 78 | +40: assign polynomial = 40'h800000001C; |
| 79 | +41: assign polynomial = 41'h10000000004; |
| 80 | +42: assign polynomial = 42'h2000000001F; |
| 81 | +43: assign polynomial = 43'h4000000002C; |
| 82 | +44: assign polynomial = 44'h80000000032; |
| 83 | +45: assign polynomial = 45'h10000000000D; |
| 84 | +46: assign polynomial = 46'h200000000097; |
| 85 | +47: assign polynomial = 47'h400000000010; |
| 86 | +48: assign polynomial = 48'h80000000005B; |
| 87 | +49: assign polynomial = 49'h1000000000038; |
| 88 | +50: assign polynomial = 50'h200000000000E; |
| 89 | +51: assign polynomial = 51'h4000000000025; |
| 90 | +52: assign polynomial = 52'h8000000000004; |
| 91 | +53: assign polynomial = 53'h10000000000023; |
| 92 | +54: assign polynomial = 54'h2000000000003E; |
| 93 | +55: assign polynomial = 55'h40000000000023; |
| 94 | +56: assign polynomial = 56'h8000000000004A; |
| 95 | +57: assign polynomial = 57'h100000000000016; |
| 96 | +58: assign polynomial = 58'h200000000000031; |
| 97 | +59: assign polynomial = 59'h40000000000003D; |
| 98 | +60: assign polynomial = 60'h800000000000001; |
| 99 | +61: assign polynomial = 61'h1000000000000013; |
| 100 | +62: assign polynomial = 62'h2000000000000034; |
| 101 | +63: assign polynomial = 63'h4000000000000001; |
| 102 | +64: assign polynomial = 64'h800000000000000D; |
| 103 | + endcase |
| 104 | +endgenerate |
| 105 | + |
| 106 | +endmodule |
0 commit comments