OpenCores
URL https://opencores.org/ocsvn/dvb_s2_ldpc_decoder/dvb_s2_ldpc_decoder/trunk

Subversion Repositories dvb_s2_ldpc_decoder

[/] [dvb_s2_ldpc_decoder/] [trunk/] [tb/] [tb_shuffle.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jcorley
`timescale 1ns/10ps
2
 
3
module tb_shuffle();
4
 
5
localparam CLK_PERIOD = 10ns;
6
localparam HOLD  = 1ns;
7
 
8
localparam FOLDFACTOR     = 4;
9
localparam NUMINSTANCES   = 360 / FOLDFACTOR;
10
localparam LOG2INSTANCES = (FOLDFACTOR==1) ? 9 :
11
                           (FOLDFACTOR==2) ? 8 :
12
                           (FOLDFACTOR==3) ? 7 :
13
                           /* 4 */           7;
14
localparam LLRWIDTH       = 4;
15
 
16
localparam LASTSHIFTDIST = (FOLDFACTOR==1) ? 11 :
17
                           (FOLDFACTOR==2) ? 5  :
18
                           (FOLDFACTOR==3) ? 3  :
19
                           /* 4 */           2;
20
localparam LASTSHIFTWIDTH  = (FOLDFACTOR==1) ? 4 :
21
                             (FOLDFACTOR==2) ? 3 :
22
                             (FOLDFACTOR==3) ? 2 :
23
                             /* 4 */           2;
24
reg clk;
25
reg rst;
26
 
27
initial
28
begin
29
  clk <= 0;
30
  rst <= 1;
31
  #0;
32
 
33
  #(CLK_PERIOD/2) clk <= ~clk;
34
  #(CLK_PERIOD/2)clk <= ~clk;
35
  #(CLK_PERIOD/2)clk <= ~clk;
36
 
37
  rst <= 0;
38
 
39
  forever
40
    #(CLK_PERIOD/2) clk <= ~clk;
41
end
42
 
43
////////////////////
44
reg                       vnmsg0_cnmsg1;
45
reg                       first_half;
46
integer                   shiftval;
47
integer                   shiftval_del1;
48
integer                   shiftval_del2;
49
wire[1:0]                 shift0;
50
wire[2:0]                 shift1;
51
wire[LASTSHIFTWIDTH-1:0]  shift2;
52
 
53
 
54
reg[LLRWIDTH-1:0] vn_2d[NUMINSTANCES-1:0];
55
reg[LLRWIDTH-1:0] cn_2d[NUMINSTANCES-1:0];
56
reg[LLRWIDTH-1:0] vn_pipe[0:2][NUMINSTANCES-1:0];
57
reg[LLRWIDTH-1:0] cn_pipe[0:2][NUMINSTANCES-1:0];
58
 
59
reg[NUMINSTANCES*LLRWIDTH-1:0]  vn_concat;
60
reg[NUMINSTANCES*LLRWIDTH-1:0]  cn_concat;
61
wire[NUMINSTANCES*LLRWIDTH-1:0] sh_concat;
62
////////////////////
63
 
64
localparam SHIFTFACTOR0 = FOLDFACTOR==1 ? 90 :
65
                          FOLDFACTOR==2 ? 45 :
66
                          FOLDFACTOR==3 ? 30 :
67
                                          23;
68
localparam SHIFTFACTOR1 = (FOLDFACTOR==1) ? 12 :
69
                          (FOLDFACTOR==2) ? 6  :
70
                          (FOLDFACTOR==3) ? 4  :
71
                          /* 4 */           3;
72
 
73
assign shift0 = shiftval / SHIFTFACTOR0;
74
assign shift1 = (shiftval_del1 % SHIFTFACTOR0) / SHIFTFACTOR1;
75
assign shift2 = (shiftval_del2 % SHIFTFACTOR0) % SHIFTFACTOR1;
76
 
77
always @( posedge clk, posedge rst )
78
  if( rst )
79
  begin
80
    shiftval_del1 <= 0;
81
    shiftval_del2 <= 0;
82
  end
83
  else
84
  begin
85
    shiftval_del1 <= #HOLD shiftval;
86
    shiftval_del2 <= #HOLD shiftval_del1;
87
  end
88
 
89
// shift random distances (1 million iterations)
90
initial
91
begin
92
  first_half <= 1;
93
  shiftval   <= 0;
94
 
95
  for( int j=0; j<NUMINSTANCES; j++ )
96
  begin
97
    vn_2d[j] <= #HOLD 0;
98
    cn_2d[j] <= #HOLD 0;
99
  end
100
 
101
  @( negedge rst );
102
  @( posedge clk );
103
 
104
  // a few corner cases
105
  for( int j=0; j<NUMINSTANCES; j++ )
106
  begin
107
    vn_2d[j] <= #HOLD j % (2**LLRWIDTH);
108
    cn_2d[j] <= #HOLD j % (2**LLRWIDTH);
109
  end
110
 
111
  shiftval <= #HOLD NUMINSTANCES - 1;
112
  @( posedge clk );
113
  shiftval <= #HOLD 0;
114
  @( posedge clk );
115
  shiftval <= #HOLD 1;
116
  @( posedge clk );
117
  shiftval <= #HOLD NUMINSTANCES/8 - 1;
118
  @( posedge clk );
119
  shiftval <= #HOLD NUMINSTANCES/8;
120
  @( posedge clk );
121
  shiftval <= #HOLD NUMINSTANCES/8 + 1;
122
  @( posedge clk );
123
  shiftval <= #HOLD NUMINSTANCES/4 - 1;
124
  @( posedge clk );
125
  shiftval <= #HOLD NUMINSTANCES/4;
126
  @( posedge clk );
127
  shiftval <= #HOLD NUMINSTANCES/4 + 1;
128
  @( posedge clk );
129
  shiftval <= #HOLD NUMINSTANCES/2 - 1;
130
  @( posedge clk );
131
  shiftval <= #HOLD NUMINSTANCES/2;
132
  @( posedge clk );
133
  shiftval <= #HOLD NUMINSTANCES/2 + 1;
134
  @( posedge clk );
135
 
136
  for( int i=0; i<1000000; i++ )
137
  begin
138
    // random shift
139
    shiftval = #HOLD {$random()} % NUMINSTANCES;
140
 
141
    // random data
142
    for( int j=0; j<NUMINSTANCES; j++ )
143
    begin
144
      vn_2d[j] <= #HOLD $random();
145
      cn_2d[j] <= #HOLD $random();
146
    end
147
 
148
    @( posedge clk );
149
  end
150
 
151
  $stop();
152
end
153
 
154
generate
155
  genvar inst;
156
 
157
  for( inst=0; inst<NUMINSTANCES; inst=inst+1 )
158
  begin: twodto1d
159
    assign vn_concat[inst*LLRWIDTH+LLRWIDTH-1:inst*LLRWIDTH] = vn_2d[inst];
160
    assign cn_concat[inst*LLRWIDTH+LLRWIDTH-1:inst*LLRWIDTH] = cn_2d[inst];
161
  end
162
endgenerate
163
 
164
task rotate_ldpc( output reg[LLRWIDTH-1:0] out_array[NUMINSTANCES-1:0],
165
                  input  reg[LLRWIDTH-1:0] inp_array[NUMINSTANCES-1:0],
166
                  input  int               shift_distance );
167
begin
168
  for( int inst=0; inst<NUMINSTANCES; inst++ )
169
    out_array[(NUMINSTANCES+inst+shift_distance) % NUMINSTANCES] = inp_array[inst];
170
end
171
endtask
172
 
173
// simulate shuffle behavior
174
int shift_pipe[0:2];
175
reg[LLRWIDTH-1:0] shuffle_result[NUMINSTANCES-1:0];
176
 
177
initial
178
begin
179
  for( int i=0; i<4; i++ )
180
  begin
181
    shift_pipe[i] <= 0;
182
    for( int j=0; j<NUMINSTANCES; j++ )
183
    begin
184
      vn_pipe[i][j] <= 0;
185
      cn_pipe[i][j] <= 0;
186
    end
187
  end
188
 
189
  @(negedge rst);
190
  @(posedge clk);
191
 
192
  forever
193
  begin
194
    shift_pipe[0] <= shiftval;
195
    shift_pipe[1] <= shift_pipe[0];
196
    shift_pipe[2] <= shift_pipe[1];
197
 
198
    vn_pipe[0] <= vn_2d;
199
    vn_pipe[1] <= vn_pipe[0];
200
    rotate_ldpc( shuffle_result, vn_pipe[1], shift_pipe[1] );
201
    vn_pipe[2] <= shuffle_result;
202
 
203
    cn_pipe[0] <= cn_2d;
204
    cn_pipe[1] <= cn_pipe[0];
205
    rotate_ldpc( shuffle_result, cn_pipe[1], NUMINSTANCES - shift_pipe[1] );
206
    cn_pipe[2] <= shuffle_result;
207
    @(posedge clk);
208
  end
209
end
210
 
211
// assert that shuffler always returns correct result
212
logic[LLRWIDTH-1:0] local_result;
213
 
214
initial
215
begin
216
  @(negedge rst);
217
  repeat( 3 ) @(posedge clk);
218
 
219
  forever
220
  begin
221
    for( int i=NUMINSTANCES-1; i>=0; i-- )
222
    begin
223
      local_result = sh_concat[(i+1)*LLRWIDTH-1 -: LLRWIDTH];
224
 
225
      if( first_half )
226
      begin
227
        if( local_result!=vn_pipe[2][i] )
228
          $display( "%0t: Shuffle mismatch: position %0d: expected %0h: result %0h", $time, i, local_result, vn_pipe[2][i] );
229
      end
230
      else
231
        if( local_result!=cn_pipe[2][i] )
232
          $display( "%0t: Shuffle mismatch: position %0d: expected %0h: result %0h", $time, i, local_result, cn_pipe[2][i] );
233
    end
234
    @( posedge clk );
235
  end
236
end
237
 
238
ldpc_shuffle #( .FOLDFACTOR(FOLDFACTOR),
239
                .NUMINSTANCES(NUMINSTANCES),
240
                .LOG2INSTANCES(LOG2INSTANCES),
241
                .LLRWIDTH(LLRWIDTH),
242
                .LASTSHIFTWIDTH(LASTSHIFTWIDTH),
243
                .LASTSHIFTDIST(LASTSHIFTDIST)
244
 ) ldpc_shufflei(
245
  .clk          (clk),
246
  .rst          (rst),
247
  .first_half   (first_half),
248
  .shift0       (shift0),
249
  .shift1       (shift1),
250
  .shift2       (shift2),
251
  .incpoint     (incpoint),
252
  .vn_concat    (vn_concat),
253
  .cn_concat    (cn_concat),
254
  .sh_concat    (sh_concat),
255
  .increment    (increment)
256
);
257
 
258
endmodule
259
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.