myrand.c.txt
上传用户:saul_905
上传日期:2013-11-27
资源大小:184k
文件大小:5k
源码类别:

VHDL/FPGA/Verilog

开发平台:

Visual C++

  1. // RANDOM Number generator (hardware friendly)
  2. //
  3. // LFSR Register for a maximal length P/N sequence of 2^32:
  4. //
  5. // Taken from XILINX App Note XAPP 052.
  6. //
  7. // Taps for 32-bit sequence are at:
  8. //    31,21,1,0
  9. //
  10. // Feed XNOR of tapped bits into LSB of left-shifted register.
  11. //
  12. // Ideas for testing:
  13. //
  14. //    For example, for the 8-bit sequence,
  15. //       1. myrand FFF >! myrand.out
  16. //
  17. //          This write 4096 numbers to the file.  The 256 element sequence should
  18. //          repeat 16 times.  Confirm this by grepping for random values.
  19. //
  20. //       2. grep -c 0000001A myrand.out
  21. //
  22. //          Should print '16'.  Do this for as many values as you can think of.
  23. //          Searching for 000000FF should yield ZERO, however.
  24. //   For the 32-bit seqence, you don't want to generate 4 billion values.  Instead,
  25. //   generate as many as you can (e.g. myrand 000FFFFF, which will generate 1 million).
  26. //   Open the file in an editor, randomly pick values, and then do the grep for that
  27. //   same value.  Grep should print exactly '1' for each such example.
  28. // 
  29. #include <stdio.h>
  30. // Generate a constant array specifying where the TAPs are.
  31. // Fill this in from some LFSR Maximal Sequence table, such
  32. // as is found in the XILINX app note.
  33. //
  34. // This particular program is limitied to 32-bit sequences since we are
  35. // using simple unsigned long int variable, but can be extended.  The XAPP
  36. // Note's table goes up to 168 bits.
  37. //
  38. // TAPS.  Select the one you want.  See XAPP 052 for more possibilities.
  39. // 
  40. const int taps[] = {31,21,1,0,  -1}; // TAPS For 32-bit sequence.  (Use -1 to end list)
  41. //const int taps[] = {7,5,4,3,    -1}; // TAPS For  8-bit sequence.  (Use -1 to end list)
  42. //const int taps[] = {3,2,        -1}; // TAPS For  4-bit sequence.  (Use -1 to end list)
  43. // Indicate width.  Specify 32 if you want 2^32 - 1 Maximal Length Sequence.
  44. #define WIDTH 32
  45. // XILINX App Note says to use zero.  It says that the All-1s value is the LOCK-up value
  46. // and should never be reached.
  47. //
  48. #define SEED 0
  49. int main (int argc, char *argv[])
  50. {
  51.    unsigned long int x;
  52.    int i, j;
  53.    unsigned long int masks[32];
  54.    unsigned long int feedback;
  55.    unsigned long int n_points;
  56.    unsigned long int width;
  57.    
  58.    if (argc == 1) {
  59.       printf ("n");
  60.       printf ("Usage:n");
  61.       printf ("   myrand <# points in hex>n");
  62.       printf ("n");
  63.       printf ("Example:n");
  64.       printf ("   myrand FFF     ; Generate 4096 pointsn");
  65.       printf ("n");
  66.       printf ("Notes:n");
  67.       printf ("   At this time, you must change source code for different lengths..n");
  68.       printf ("n");
  69.       printf ("Currently, Taps are:n");
  70.       for (j = 0; taps[j] != -1; j++) {
  71.          printf ("%ld ", taps[j]);
  72.       }
  73.       printf ("n");
  74.       return 1;
  75.    }
  76.    
  77.    // Use command line argument to specify how many points.
  78.    //
  79.    n_points = 0;
  80.    sscanf (argv[1], "%lx", &n_points);
  81.    if (n_points == 0) {
  82.       printf ("nERROR: Must specify (in hex) how many points!n");
  83.       return 1;
  84.    }
  85.    
  86.    // Generate the bit masks.  Generate all 32.
  87.    //
  88.    for (i = 0; i < 32; i++) {
  89.       masks[i] = 1 << i;
  90.    }
  91.    
  92.    width = (1 << WIDTH) - 1;
  93.    //printf ("width = %lxn", width);
  94.    
  95.    x = SEED;
  96.    
  97.    // For the number of points requested..
  98.    while (n_points--) {
  99.       // Based on the taps array, generate each XOR term. Remember, -1 signifies the end.
  100.       feedback = 0;
  101.       for (j = 0; taps[j] != -1; j++) {
  102. // FOR Debug:
  103. //         printf ("x = %08lx, taps[j] = %ld, masks[taps[j]] = %08lx, (x & masks[taps[j]]) = %l08xn",
  104. //            x, taps[j], masks[taps[j]], (x & masks[taps[j]]) );
  105.          feedback ^= (x & masks[taps[j]]) ? 0x00000001 : 0x00000000;
  106.       }
  107.       // Do the XNOR (so, just complement BIT 0 of our feedback term)
  108.       feedback ^= 0x00000001;
  109.       
  110.       // In hardware, this'll be more straight-forward, e.g. for the 32-bit case:
  111.       //    assign feedback = ~^{x[31],x[21],x[1],x[0]};
  112.       //    always @(posedge clk) ... x <= {x[30:0], feedback}; 
  113.       //
  114.       
  115.       // Shift X to the left.  We'll OR in our feedback term in a moment.
  116.       x <<= 1;
  117.       
  118.       // OR feedback bit into bit 0.
  119.       x |= feedback;
  120.       
  121.       x &= width;
  122.       
  123. //    printf ("%08lX %08lXn", feedback, x);
  124.       printf ("%08lXn", x);
  125.    }
  126. }
  127. /*
  128.          Here's the Verilog for reference...
  129.       // Random Number Generator, 8-bit
  130.       //
  131.       // See companion program myrand.c
  132.       //
  133.       // (to verify, do the GREP trick described in myrand.c on verilog.out)
  134.       //
  135.       module myrand;
  136.       
  137.       reg clk, reset;
  138.       reg [7:0] x;
  139.       wire      feedback;
  140.       
  141.       // Use TAPS table from XACT 052 to make whatever length sequence you need.
  142.       assign feedback = ~^{x[7],x[5],x[4],x[3]};
  143.       // Shift and input feedback term.  That's it!
  144.       always @(posedge clk) begin
  145.          if (reset) x <= 0;
  146.          else       x <= {x[6:0], feedback};
  147.       end
  148.       
  149.       // remaining code just testbench...
  150.       initial begin
  151.          clk = 0;
  152.          forever begin
  153.             #10 clk = ~clk;
  154.          end
  155.       end
  156.       
  157.       initial begin
  158.          reset = 0;
  159.          #1 reset = 1;
  160.          #35 reset = 0;
  161.       end
  162.       
  163.       initial begin
  164.          @(negedge reset);
  165.          repeat (1024) begin
  166.             @(posedge clk) #1;
  167.             $display ("%h", x);
  168.          end
  169.          $finish;
  170.       end
  171.       endmodule
  172.    
  173.       
  174. */