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

Subversion Repositories ca_prng

[/] [ca_prng/] [trunk/] [src/] [testbench/] [tb_ca_prng.v] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 joachim
//========================================================================
2
//
3
// tb_ca_prng.v
4
// ------------
5
// Testbench for the rule cellular automata based PRNG ca_prng.
6
// This version is for ca_prng with 32 bit pattern output.
7
// 
8
// 
9
// Author: Joachim Strombergson
10
// Copyright (c) 2008, InformAsic AB
11
// All rights reserved.
12
// 
13
// Redistribution and use in source and binary forms, with or without
14
// modification, are permitted provided that the following conditions
15
// are met:
16
//
17
//     * Redistributions of source code must retain the above copyright
18
//       notice, this list of conditions and the following disclaimer.
19
// 
20
//     * Redistributions in binary form must reproduce the above
21
//       copyright notice, this list of conditions and the following
22
//       disclaimer in the documentation and/or other materials
23
//       provided with the distribution.
24
// 
25
// THIS SOFTWARE IS PROVIDED BY InformAsic AB ''AS IS'' AND ANY EXPRESS
26
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28
// ARE DISCLAIMED. IN NO EVENT SHALL InformAsic AB BE LIABLE FOR ANY
29
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
31
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
// 
37
//========================================================================
38
 
39
//------------------------------------------------------------------
40
// Simulator directives
41
//
42
// Timescale etc.
43
//------------------------------------------------------------------
44
`timescale 1ns / 1ps
45
 
46
 
47
//------------------------------------------------------------------
48
// tb_rule30
49
//
50
// The self contained testbench module.
51
//------------------------------------------------------------------
52
module tb_ca_prng();
53
 
54
  //----------------------------------------------------------------
55
  // Parameter declarations
56
  //----------------------------------------------------------------
57
  // CLK_HALF_PERIOD
58
  // Half period (assuming 50/50 duty cycle) in ns.
59
  parameter CLK_HALF_PERIOD = 5;
60
 
61
  // RULE_2
62
  // This rule generates a single angled line. 
63
  // See the following link for more info:
64
  // http://mathworld.wolfram.com/ElementaryCellularAutomaton.html
65
  parameter [7 : 0] RULE_2 = 8'b00000010;
66
 
67
  // RULE_90
68
  // This rule generates Pascals triangle from a single
69
  // bit input. See the following link for more info:
70
  // http://mathworld.wolfram.com/ElementaryCellularAutomaton.html
71
  parameter [7 : 0] RULE_90 = 8'b01011010;
72
 
73
  // MIDDLE_BIT_INIT_PATTERN
74
  // An initial bgit pattern with a single bit set in the middle
75
  // of the 32 bit word.
76
  parameter  [31 : 0] MIDDLE_BIT_INIT_PATTERN = 32'b00000000000000010000000000000000;
77
 
78
  // COMPLEX_INIT_PATTERN
79
  // A more complex init pattern.
80
  parameter  [31 : 0] COMPLEX_INIT_PATTERN = 32'b01011000000000010000111000001100;
81
 
82
  // TC1_RESPONSE
83
  // Expected PRNG pattern response after TC1.
84
  parameter  [31 : 0] TC1_RESPONSE = 32'b01110001010110000000111010001001;
85
 
86
  // TC2_RESPONSE
87
  // Expected PRNG pattern response after TC2.
88
  parameter  [31 : 0] TC2_RESPONSE = 32'b10111101001101000001100001101001;
89
 
90
  // TC3_RESPONSE
91
  // Expected PRNG pattern response after TC3.
92
  parameter  [31 : 0] TC3_RESPONSE = 32'b00000000000000000001000000000000;
93
 
94
  // TC4_RESPONSE
95
  // Expected PRNG pattern response after TC4.
96
  parameter  [31 : 0] TC4_RESPONSE = 32'b10101010101010101010101010101010;
97
 
98
 
99
  //----------------------------------------------------------------
100
  // Wire declarations.
101
  //----------------------------------------------------------------
102
  // Wires needed to connect the DUT.
103
  reg           tb_clk;
104
  reg           tb_reset_n;
105
  reg [31 : 0]  tb_init_pattern_data;
106
  reg           tb_load_init_pattern;
107
  reg           tb_next_pattern;
108
  reg [7 : 0]   tb_update_rule;
109
  reg           tb_load_update_rule;
110
  wire [31 : 0] tb_prng_data;
111
 
112
 
113
  //----------------------------------------------------------------
114
  // Testbench variables.
115
  //----------------------------------------------------------------
116
  // num_errors
117
  // Number of errors detected.
118
  integer num_errors;
119
 
120
 
121
  //----------------------------------------------------------------
122
  // ca_prng_dut
123
  // 
124
  // Instantiation of the ca_prng core as device under test.
125
  //----------------------------------------------------------------
126
  ca_prng ca_prng_dut(
127
                      .clk(tb_clk),
128
                      .reset_n(tb_reset_n),
129
                      .init_pattern_data(tb_init_pattern_data),
130
                      .load_init_pattern(tb_load_init_pattern),
131
                      .next_pattern(tb_next_pattern),
132
 
133
                      .update_rule(tb_update_rule),
134
                      .load_update_rule(tb_load_update_rule),
135
 
136
                      .prng_data(tb_prng_data)
137
                     );
138
 
139
 
140
  //----------------------------------------------------------------
141
  // check_pattern
142
  //
143
  // Check that the reusult pattern matches the expected pattern.
144
  // If the patterns don't match increase the error counter.
145
  //----------------------------------------------------------------
146
  task check_pattern;
147
    input [31 : 0] expected_pattern;
148
    input [31 : 0] result_pattern;
149
 
150
    begin
151
      if (expected_pattern != result_pattern)
152
        begin
153
          $display("Error: Expected %b, got: %b",
154
                   expected_pattern, result_pattern);
155
          num_errors = num_errors + 1;
156
        end
157
    end
158
  endtask // check_pattern
159
 
160
 
161
  //----------------------------------------------------------------
162
  // init_sim
163
  //
164
  // Initialize all DUT inputs variables, testbench variables etc 
165
  // to defined values.
166
  //----------------------------------------------------------------
167
  task init_sim;
168
    begin
169
      tb_clk               = 0;
170
      tb_reset_n           = 0;
171
      tb_init_pattern_data = MIDDLE_BIT_INIT_PATTERN;
172
      tb_load_init_pattern = 1'b0;
173
      tb_next_pattern      = 1'b0;
174
      tb_update_rule       = 8'b00000000;
175
      tb_load_update_rule  = 1'b0;
176
      num_errors           = 0;
177
    end
178
  endtask // init_sim 
179
 
180
 
181
  //----------------------------------------------------------------
182
  // end_sim
183
  //
184
  // Perform any clean up as needed and check the simulation 
185
  // results from the test cases, reporting number of errors etc.
186
  //----------------------------------------------------------------
187
  task end_sim;
188
    begin
189
      if (num_errors == 0)
190
        begin
191
          $display("Simulation completed ok.");
192
        end
193
      else
194
        begin
195
          $display("Simulation completed, but %d test cases had errors.", num_errors);
196
        end
197
    end
198
  endtask // end_sim 
199
 
200
 
201
  //----------------------------------------------------------------
202
  // release_reset
203
  //
204
  // Wait a few cycles and then release the reset in sync
205
  // with the clock.
206
  //----------------------------------------------------------------
207
  task release_reset;
208
    begin
209
      #(20 * CLK_HALF_PERIOD);
210
      @(negedge tb_clk)
211
        tb_reset_n = 1'b1;
212
    end
213
  endtask // release_reset 
214
 
215
 
216
  //----------------------------------------------------------------
217
  // test_tc1
218
  //
219
  // Verify that the default rule30 update rule uns ok from the 
220
  // start using a simple init pattern.
221
  //----------------------------------------------------------------
222
  task test_tc1;
223
    begin
224
      $display("TC1: Default rule30 update rule with simple init pattern.");
225
      // Load the init pattern into the dut and then
226
      // start asserting the next pattern pin for a while.
227
      #(4 * CLK_HALF_PERIOD);
228
      @(negedge tb_clk)
229
        tb_load_init_pattern = 1'b1;
230
      @(negedge tb_clk)
231
        tb_load_init_pattern = 1'b0;
232
      @(negedge tb_clk)
233
        tb_next_pattern      = 1'b1;
234
 
235
      // Run the DUT for a number of cycles.
236
      #(100 * CLK_HALF_PERIOD);
237
 
238
      // Drop the next pattern signal and check the results.
239
      @(negedge tb_clk)
240
        tb_next_pattern = 1'b0;
241
      check_pattern(TC1_RESPONSE, tb_prng_data);
242
    end
243
  endtask // test_tc1
244
 
245
 
246
  //----------------------------------------------------------------
247
  // test_tc2
248
  //
249
  // Verify that we can change state by changing the init pattern
250
  // and get a new set of PRNG data.
251
  //----------------------------------------------------------------
252
  task test_tc2;
253
    begin
254
      $display("TC2: Default rule30 update rule with complex init pattern.");
255
      // Load a new init pattern and run that pattern
256
      @(negedge tb_clk)
257
      tb_init_pattern_data = COMPLEX_INIT_PATTERN;
258
      tb_load_init_pattern = 1'b1;
259
      @(negedge tb_clk)
260
      tb_load_init_pattern = 1'b0;
261
      tb_next_pattern      = 1'b1;
262
 
263
      // Run the DUT for a number of cycles.
264
      #(200 * CLK_HALF_PERIOD);
265
 
266
      // Drop the next pattern signal and check the results.
267
      @(negedge tb_clk)
268
        tb_next_pattern = 1'b0;
269
      check_pattern(TC2_RESPONSE, tb_prng_data);
270
    end
271
  endtask // test_tc2
272
 
273
 
274
  //----------------------------------------------------------------
275
  // test_tc3
276
  //
277
  // Verify that the we can change the rule and get another set
278
  // of PRNG data.
279
  //----------------------------------------------------------------
280
  task test_tc3;
281
    begin
282
      $display("TC3: rule2 update rule with simple init pattern.");
283
      // Change update rule to RULE_2 and the simple init pattern.
284
      @(negedge tb_clk)
285
      tb_update_rule       = RULE_2;
286
      tb_load_update_rule  = 1'b1;
287
      tb_init_pattern_data = MIDDLE_BIT_INIT_PATTERN;
288
      tb_load_init_pattern = 1'b1;
289
      @(negedge tb_clk)
290
      tb_load_update_rule  = 1'b0;
291
      tb_load_init_pattern = 1'b0;
292
      tb_next_pattern      = 1'b1;
293
 
294
      // Run the DUT for a number of cycles.
295
      #(200 * CLK_HALF_PERIOD);
296
 
297
      // Drop the next pattern signal and check the results.
298
      @(negedge tb_clk)
299
        tb_next_pattern = 1'b0;
300
      check_pattern(TC3_RESPONSE, tb_prng_data);
301
    end
302
  endtask // test_tc3
303
 
304
 
305
  //----------------------------------------------------------------
306
  // test_tc4
307
  //
308
  // Verify that the we can generate Pascals triangle.
309
  //----------------------------------------------------------------
310
  task test_tc4;
311
    begin
312
      $display("TC4: rule90 (Pascals triangle) update rule with simple init pattern.");
313
      // Change update rule to RULE_90 and the simple init pattern.
314
      @(negedge tb_clk)
315
      tb_update_rule       = RULE_90;
316
      tb_load_update_rule  = 1'b1;
317
      tb_init_pattern_data = MIDDLE_BIT_INIT_PATTERN;
318
      tb_load_init_pattern = 1'b1;
319
      @(negedge tb_clk)
320
      tb_load_update_rule  = 1'b0;
321
      tb_load_init_pattern = 1'b0;
322
      tb_next_pattern      = 1'b1;
323
 
324
      // Run the DUT for a number of cycles.
325
      #(30 * CLK_HALF_PERIOD);
326
 
327
      // Drop the next pattern signal and check the results.
328
      @(negedge tb_clk)
329
        tb_next_pattern = 1'b0;
330
      check_pattern(TC4_RESPONSE, tb_prng_data);
331
    end
332
  endtask // test_tc4
333
 
334
 
335
  //----------------------------------------------------------------
336
  // clk_gen
337
  //
338
  // Clock generator process. 50/50 duty cycle.
339
  //----------------------------------------------------------------
340
  always
341
    begin : clk_gen
342
      #CLK_HALF_PERIOD tb_clk = !tb_clk;
343
    end // clk_gen
344
 
345
 
346
  //--------------------------------------------------------------------
347
  // dut_monitor
348
  //
349
  // Monitor for observing the inputs and outputs to the dut.
350
  //--------------------------------------------------------------------
351
  always @ (posedge tb_clk)
352
    begin : dut_monitor
353
      $display("reset = %b, init_pattern = %b, load_init_pattern = %b, next_pattern = %b, prng_data = %b",
354
               tb_reset_n, tb_init_pattern_data, tb_load_init_pattern, tb_next_pattern, tb_prng_data);
355
    end // dut_monitor
356
 
357
 
358
  //----------------------------------------------------------------
359
  // ca_prng_test
360
  //
361
  // The main test logic. Basically calls the tasks to init the
362
  // simulation, all test cases and finish the simulation.
363
  //----------------------------------------------------------------
364
  initial
365
    begin : ca_prng_test
366
      $display("   -- Testbench for for ca_prng module started --");
367
 
368
      // Call tasks as needed to init and executing test cases.
369
      init_sim;
370
      release_reset;
371
 
372
      test_tc1;
373
      test_tc2;
374
      test_tc3;
375
      test_tc4;
376
 
377
      end_sim;
378
 
379
      $display("   -- Testbench for for ca_prng module stopped --");
380
      $finish;
381
    end // ca_prng_test
382
endmodule // tb_ca_prng
383
 
384
//========================================================================
385
// EOF tb_ca_prng.v
386
//========================================================================

powered by: WebSVN 2.1.0

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