Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3 | lvd | 1 | module rnd_vec_gen( |
2 | |||
3 | clk, |
||
4 | |||
5 | init, |
||
6 | |||
7 | save, |
||
8 | restore, |
||
9 | next, |
||
10 | |||
11 | |||
12 | out |
||
13 | ); |
||
14 | |||
15 | parameter OUT_SIZE = 16; // size of output port, independent of LFSR register size |
||
16 | |||
17 | parameter LFSR_LENGTH = 55; // LFSR |
||
18 | parameter LFSR_FEEDBACK = 24; // definition |
||
19 | |||
20 | |||
21 | input clk; |
||
22 | |||
23 | input init; // positive initialization strobe, synchronous to clock, its length will determine initial state |
||
24 | |||
25 | input save,restore,next; // strobes for required events: positive, one clock cycle long |
||
26 | |||
27 | |||
28 | reg init2; |
||
29 | |||
30 | |||
31 | output [OUT_SIZE-1:0] out; |
||
32 | wire [OUT_SIZE-1:0] out; |
||
33 | |||
34 | |||
35 | reg [OUT_SIZE-1:0] rndbase_main [0:LFSR_LENGTH-1]; |
||
36 | reg [OUT_SIZE-1:0] rndbase_store [0:LFSR_LENGTH-1]; |
||
37 | |||
38 | |||
39 | |||
40 | |||
41 | assign out = rndbase_main[0]; |
||
42 | |||
43 | |||
44 | |||
55 | lvd | 45 | initial |
46 | begin : clr_arrays_for_sim |
||
47 | integer i; |
||
48 | |||
49 | for(i=0;i<LFSR_LENGTH;i=i+1) |
||
50 | begin |
||
51 | rndbase_main [i] = 'd0; |
||
52 | rndbase_store[i] = 'd0; |
||
53 | end |
||
54 | end |
||
55 | |||
56 | |||
57 | |||
58 | |||
3 | lvd | 59 | always @(posedge clk) |
60 | begin |
||
61 | |||
62 | init2 <= init; |
||
63 | |||
64 | if( init && !init2 ) // begin of initialization |
||
65 | begin |
||
66 | rndbase_main[0][0] <= 1'b1; // any non-zero init possible |
||
67 | end |
||
68 | else if( init && init2 ) // continue of initialization |
||
69 | begin |
||
70 | shift_lfsr; |
||
71 | end |
||
72 | else // no init, normal work |
||
73 | begin |
||
74 | |||
75 | if( restore ) // restore event: higher priority |
||
55 | lvd | 76 | begin : blk1 |
3 | lvd | 77 | integer i; |
78 | for(i=0;i<LFSR_LENGTH;i=i+1) |
||
79 | rndbase_main[i] <= rndbase_store[i]; |
||
80 | end |
||
81 | else |
||
82 | begin |
||
83 | if( next ) // step to next value |
||
84 | begin |
||
85 | shift_lfsr; |
||
86 | end |
||
87 | |||
88 | if( save ) // save current state |
||
55 | lvd | 89 | begin : blk2 |
3 | lvd | 90 | integer j; |
91 | for(j=0;j<LFSR_LENGTH;j=j+1) |
||
92 | rndbase_store[j] <= rndbase_main[j]; |
||
93 | end |
||
94 | end |
||
95 | end |
||
96 | end |
||
97 | |||
98 | |||
99 | |||
100 | /* function [LFSR_LENGTH-1:0] shift_lfsr; |
||
101 | |||
102 | input [LFSR_LENGTH-1:0] old_lfsr; |
||
103 | |||
104 | begin |
||
105 | if( |old_lfsr ) // prevent spurious stalls if all LFSR is zeros |
||
106 | shift_lfsr[LFSR_LENGTH-1:0] = { old_lfsr[LFSR_LENGTH-2:0], old_lfsr[LFSR_LENGTH-1]^old_lfsr[LFSR_FEEDBACK-1] }; |
||
107 | else |
||
108 | shift_lfsr[LFSR_LENGTH-1:0] = 2'd1; |
||
109 | end |
||
110 | endfunction |
||
111 | */ |
||
112 | |||
113 | task shift_lfsr; |
||
55 | lvd | 114 | begin : blk3 |
3 | lvd | 115 | reg [OUT_SIZE-1:0] sum; |
116 | reg [LFSR_LENGTH-1:0] lsbs; |
||
117 | |||
118 | integer i; |
||
119 | |||
120 | for(i=0;i<LFSR_LENGTH;i=i+1) |
||
121 | lsbs[i] = rndbase_main[i][0]; |
||
122 | |||
123 | sum = rndbase_main[LFSR_LENGTH-1] + rndbase_main[LFSR_FEEDBACK-1]; |
||
124 | |||
125 | // integer j; |
||
126 | for(i=1;i<LFSR_LENGTH;i=i+1) |
||
127 | rndbase_main[i] <= rndbase_main[i-1]; |
||
128 | |||
129 | rndbase_main[0] <= { sum[OUT_SIZE-1:1], (|lsbs)?sum[0]:1'b1 }; |
||
130 | end |
||
131 | endtask |
||
132 | |||
133 | |||
134 | endmodule |
||
135 | |||
136 | |||
137 | |||
138 | |||
139 |