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_ldpc.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jcorley
`include "Codeword.sv"
2
`timescale 1ns/10ps
3
 
4
module tb_ldpc();
5
 
6
localparam CLK_PERIOD = 5ns;
7
localparam HOLD       = 1ns;
8
 
9
localparam SYMS_PER_EBN0 = 10;
10
localparam EBN0_MIN      = 3.8;
11
localparam EBN0_MAX      = 4.0;
12
localparam EBN0_STEP     = 0.2;
13
localparam CODE_TYPE     = "1_2";
14
 
15
localparam LLRWIDTH = 6;
16
 
17
//////////
18
// Clocks
19
//////////
20
logic clk;
21
logic rst;
22
 
23
initial
24
begin
25
  clk <= 1'b0;
26
  forever
27
    #(CLK_PERIOD /2) clk <= ~clk;
28
end
29
 
30
initial
31
begin
32
  rst <= 1'b1;
33
 
34
  repeat(3) @(posedge clk);
35
  rst <= #HOLD 1'b0;
36
end
37
 
38
/////////////
39
// Generator
40
/////////////
41
int    packet_number;
42
int    debug_level;
43
int    log_level;
44
string logfilename;
45
string name;
46
 
47
/* VCS doesn't support parameterized mailboxes, just use one Codeword
48
   throughout the testbench and one big initial block instead.
49
Codeword datapath_orig;
50
Codeword checkpath_orig;
51
 
52
mailbox #(Codeword) data_source;
53
mailbox #(Codeword) check_source;
54
semaphore check;
55
*/
56
Codeword  check_word;
57
 
58
//////////////
59
// Transactors
60
//////////////
61
// Load data into LLR
62
// LLR I/O
63
logic      llr_access;
64
logic[7:0] llr_addr;
65
logic      llr_din_we;
66
logic[360*LLRWIDTH-1:0]      llr_din;
67
bit signed[360*LLRWIDTH-1:0] llr_dout;
68
 
69
// start command; completion indicator
70
logic      start;
71
logic[4:0] mode;
72
logic[5:0] iter_limit;
73
bit        done;
74
 
75
localparam READ_LATENCY = 5;
76
 
77
initial
78
begin
79
  packet_number = 0;
80
  debug_level   = 0;
81
  log_level     = 1;
82
  logfilename   = "test_testbench.txt";
83
  name          = "CodewordSpecial";
84
 
85
  check_word = new( CODE_TYPE, debug_level, log_level, logfilename, packet_number, name );
86
 
87
  llr_access  <= 0;
88
  llr_addr    <= 0;
89
  llr_din_we  <= 0;
90
  llr_din     <= 0;
91
  start       <= 0;
92
  mode        <= 0;
93
  iter_limit  <= 20;
94
 
95
  @( posedge rst );
96
  repeat( 5 ) @( posedge clk );
97
 
98
  for( real ebn0dB=EBN0_MIN; ebn0dB<EBN0_MAX; ebn0dB+=EBN0_STEP )
99
    for( int symnum=0; symnum<SYMS_PER_EBN0; symnum++ )
100
    begin
101
      // create word
102
      check_word.create_random_msg();
103
      check_word.encode();
104
 
105
      check_word.AddNoise( ebn0dB );
106
      check_word.QuantizeLlr( LLRWIDTH );
107
 
108
      // begin testing DUT
109
      @(posedge clk);
110
 
111
      // write normal data bits
112
      for( int i=0; i<check_word.GetK()/360; i++ )
113
      begin
114
        int wr_val;
115
        int abs_wr_val;
116
 
117
        llr_addr   <= i;
118
        llr_access <= 1;
119
 
120
        for( int j=0; j<360; j++ )
121
        begin
122
          wr_val = check_word.GetVal(360*i +j);
123
          //wr_val = 360*i +j;
124
          abs_wr_val = wr_val < 0 ? -1*wr_val : wr_val;
125
 
126
          llr_din[(j+1)*LLRWIDTH-1 -: LLRWIDTH]
127
            <= (wr_val<0) ? { 1'b1, abs_wr_val[LLRWIDTH-2:0] }
128
                          : { 1'b0, abs_wr_val[LLRWIDTH-2:0] };
129
        end
130
 
131
        llr_din_we <= 1;
132
        @( posedge clk );
133
      end
134
 
135
      // write parity bits
136
      for( int i=0; i<(check_word.GetN()-check_word.GetK())/360; i++ )
137
      begin
138
        int rotate_pos;
139
        int wr_val;
140
        int abs_wr_val;
141
 
142
        llr_addr <= check_word.GetK()/360 + i;
143
 
144
        for( int j=0; j<360; j++ )
145
        begin
146
          rotate_pos = check_word.GetK() + i + j*check_word.GetQ();
147
          wr_val     = check_word.GetVal(rotate_pos);
148
          //wr_val     = rotate_pos;
149
          abs_wr_val = wr_val < 0 ? -1*wr_val : wr_val;
150
 
151
          llr_din[j*LLRWIDTH+LLRWIDTH-1 -: LLRWIDTH]
152
            <= (wr_val<0) ? { 1'b1, abs_wr_val[LLRWIDTH-2:0] }
153
                          : { 1'b0, abs_wr_val[LLRWIDTH-2:0] };
154
        end
155
 
156
        llr_din_we <= 1;
157
        @( posedge clk );
158
      end
159
 
160
      llr_din_we <= 0;
161
      llr_access <= 0;
162
      @( posedge clk );
163
 
164
      //controls
165
      start <= 1;
166
 
167
      case( CODE_TYPE )
168
        "1_4":    mode <= 0;
169
        "1_3":    mode <= 1;
170
        "2_5":    mode <= 2;
171
        "1_2":    mode <= 3;
172
        "3_5":    mode <= 4;
173
        "2_3":    mode <= 5;
174
        "3_4":    mode <= 6;
175
        "4_5":    mode <= 7;
176
        "5_6":    mode <= 8;
177
        "8_9":    mode <= 9;
178
        "9_10":   mode <= 10;
179
        "1_5s":   mode <= 11;
180
        "1_3s":   mode <= 12;
181
        "2_5s":   mode <= 13;
182
        "4_9s":   mode <= 14;
183
        "3_5s":   mode <= 15;
184
        "2_3s":   mode <= 16;
185
        "11_15s": mode <= 17;
186
        "7_9s":   mode <= 18;
187
        "37_45s": mode <= 19;
188
        "8_9s":   mode <= 20;
189
        default: $stop( "Illegal code type!" );
190
      endcase
191
      @( posedge clk );
192
      start <= 0;
193
      @( posedge clk );
194
 
195
      // read data out
196
      @(posedge done);
197
      @(posedge clk);
198
 
199
      llr_access <= 1;
200
      llr_addr   <= 0;
201
      @(posedge clk);
202
 
203
      // read normal data bits
204
      for( int i=0; i<(check_word.GetK()/360)+READ_LATENCY; i++ )
205
      begin
206
        int result;
207
 
208
        llr_addr <= i;
209
        llr_din  <= { LLRWIDTH{1'bX} };
210
        @( posedge clk );
211
 
212
        if( i>=READ_LATENCY )
213
          for( int j=0; j<360; j++ )
214
          begin
215
            result = llr_dout[j*LLRWIDTH+LLRWIDTH-1]
216
              ? -1 * { 1'b0, llr_dout[j*LLRWIDTH+LLRWIDTH-2 -: LLRWIDTH-1] }
217
              : { 1'b0, llr_dout[j*LLRWIDTH+LLRWIDTH-2 -: LLRWIDTH-1] };
218
 
219
            check_word.SetDecoded( 360*(i-READ_LATENCY) +j, result );
220
          end
221
      end
222
 
223
      // read parity bits
224
      for( int i=0; i<((check_word.GetN()-check_word.GetK())/360)+READ_LATENCY; i++ )
225
      begin
226
        int result;
227
        int rotate_pos;
228
 
229
        llr_addr <= check_word.GetK()/360 + i;
230
        @(posedge clk);
231
 
232
        if( i>=READ_LATENCY )
233
          for( int j=0; j<360; j++ )
234
          begin
235
            rotate_pos = check_word.GetK() + i-READ_LATENCY + j*check_word.GetQ();
236
 
237
            result = llr_dout[j*LLRWIDTH+LLRWIDTH-1]
238
              ? -1 * { 1'b0, llr_dout[j*LLRWIDTH+LLRWIDTH-2 -: LLRWIDTH-1] }
239
              : { 1'b0, llr_dout[j*LLRWIDTH+LLRWIDTH-2 -: LLRWIDTH-1] };
240
 
241
            check_word.SetDecoded( rotate_pos, result );
242
          end
243
      end
244
 
245
      llr_access <= 0;
246
      @( posedge clk );
247
 
248
      $display( "EbN0 = %0fdB", ebn0dB );
249
      $display( "Orig had    %0d errors", check_word.CountOrigErrs() );
250
      $display( "Decoded had %0d errors", check_word.CountDecodedErrs() );
251
 
252
      check_word.inc(); // increment packet number
253
    end
254
 
255
  check_word.delete();
256
  $stop();
257
end
258
 
259
///////////
260
// Checker
261
///////////
262
 
263
////////////
264
// Instance
265
////////////
266
ldp_top #(
267
  .FOLDFACTOR  (1),
268
  .NUMINSTANCES(360),
269
  .LLRWIDTH    (LLRWIDTH)
270
) ldp_top_i(
271
  .clk(clk),
272
  .rst(rst),
273
 
274
  .llr_access (llr_access),
275
  .llr_addr   (llr_addr),
276
  .llr_din_we (llr_din_we),
277
  .llr_din    (llr_din),
278
  .llr_dout   (llr_dout),
279
 
280
  .start     (start),
281
  .mode      (mode),
282
  .iter_limit(iter_limit),
283
  .done      (done)
284
);
285
 
286
endmodule
287
 

powered by: WebSVN 2.1.0

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