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

VHDL/FPGA/Verilog

开发平台:

Visual C++

  1. //
  2. // Behavioral Verilog for CRC16 and CRC32 for use in a testbench.
  3. //
  4. // The specific polynomials and conventions regarding bit-ordering etc.
  5. // are specific to the Cable Modem DOCSIS protocol, but the general scheme
  6. // should be reusable for other types of CRCs with some fiddling.
  7. //
  8. // This CRC code works for a specific type of network protocol, and it
  9. // must do certain byte swappings, etc.  You may need to play with it 
  10. // for your protocol.  Also, make sure the polynomials are what you
  11. // really want.  This is obviously, not synthesizable - I just used this
  12. // in a testbench at one point.
  13. //
  14. // These tasks are crude and rely on some global parameters.  They should
  15. // also read from a file, yada yada yada.  It is probably better to do this 
  16. // with a PLI call, but here it is anyway..
  17. //
  18. // The test case includes a golden DOCSIS (Cable Modem) test message that 
  19. // was captured in a lab.
  20. //
  21. // tom coonan, 1999.
  22. //
  23. module test_gencrc;
  24. // *** Buffer for the Golden Message ***
  25. reg [7:0] test_packet[0:54];  
  26. // *** Global parameter block for the CRC32 calculator.
  27. //
  28. parameter CRC32_POLY = 32'h04C11DB7;
  29. reg [ 7:0] crc32_packet[0:255];
  30. integer crc32_length;
  31. reg [31:0] crc32_result;
  32. // *** Global parameter block for the CRC16 calculator.
  33. //
  34. parameter CRC16_POLY = 16'h1020;
  35. reg [ 7:0] crc16_packet[0:255];
  36. integer crc16_length;
  37. reg [15:0] crc16_result;
  38. `define TEST_GENCRC
  39. `ifdef TEST_GENCRC
  40. // Call the main test task and then quit.
  41. //
  42. initial begin
  43.    main_test;
  44.    $finish;
  45. end
  46. `endif
  47. // ****************************************************************
  48. // *
  49. // *   GOLDEN MESSAGE
  50. // *
  51. // *   The golden message is a DOCSIS frame that was captured off
  52. // *   the Broadcom reference design.  It is a MAP message.  It
  53. // *   includes a HCS (crc 16) and a CRC32.
  54. // *
  55. // *
  56. // ****************************************************************
  57. //
  58. task initialize_test_packet;
  59.    begin
  60.       test_packet[00] = 8'hC2; // FC.   HCS coverage starts here.
  61.       test_packet[01] = 8'h00; // MACPARAM
  62.       test_packet[02] = 8'h00; // MAC LEN
  63.       test_packet[03] = 8'h30; // MAC LEN.  HCS Coverage includes this byte and ends here.
  64.       test_packet[04] = 8'hF2; // CRC16 (also known as HCS)
  65.       test_packet[05] = 8'hCF; // CRC16 cont..
  66.       test_packet[06] = 8'h01; // Start of the IEEE payload.  CRC32 covererage starts here.  This is the DA field
  67.       test_packet[07] = 8'hE0; // DA field cont..
  68.       test_packet[08] = 8'h2F; // DA field cont..
  69.       test_packet[09] = 8'h00; // DA field cont..
  70.       test_packet[10] = 8'h00; // DA field cont..
  71.       test_packet[11] = 8'h01; // DA field cont..
  72.       test_packet[12] = 8'h00; // SA field
  73.       test_packet[13] = 8'h80; // SA field cont..
  74.       test_packet[14] = 8'h42; // SA field cont..
  75.       test_packet[15] = 8'h42; // SA field cont..
  76.       test_packet[16] = 8'h20; // SA field cont..
  77.       test_packet[17] = 8'h9E; // SA field cont..
  78.       test_packet[18] = 8'h00; // IEEE LEN field
  79.       test_packet[19] = 8'h1E; // IEEE LEN field cont.
  80.       test_packet[20] = 8'h00; // LLC field.
  81.       test_packet[21] = 8'h00; // LLC field cont...
  82.       test_packet[22] = 8'h03; // LLC field cont...
  83.       test_packet[23] = 8'h01; // LLC field cont...
  84.       test_packet[24] = 8'h03; // LLC field cont...  This is also the TYPE, which indicates MAP.
  85.       test_packet[25] = 8'h00; // LLC field cont...
  86.       test_packet[26] = 8'h01; // Start of MAP message payload.
  87.       test_packet[27] = 8'h01; // MAP message payload..
  88.       test_packet[28] = 8'h02; // MAP message payload..
  89.       test_packet[29] = 8'h00; // MAP message payload..
  90.       test_packet[30] = 8'h00; // MAP message payload..
  91.       test_packet[31] = 8'h18; // MAP message payload..
  92.       test_packet[32] = 8'hAA; // MAP message payload..
  93.       test_packet[33] = 8'h58; // MAP message payload..
  94.       test_packet[34] = 8'h00; // MAP message payload..
  95.       test_packet[35] = 8'h18; // MAP message payload..
  96.       test_packet[36] = 8'hA8; // MAP message payload..
  97.       test_packet[37] = 8'hA0; // MAP message payload..
  98.       test_packet[38] = 8'h02; // MAP message payload..
  99.       test_packet[39] = 8'h03; // MAP message payload..
  100.       test_packet[40] = 8'h03; // MAP message payload..
  101.       test_packet[41] = 8'h08; // MAP message payload..
  102.       test_packet[42] = 8'hFF; // MAP message payload..
  103.       test_packet[43] = 8'hFC; // MAP message payload..
  104.       test_packet[44] = 8'h40; // MAP message payload..
  105.       test_packet[45] = 8'h00; // MAP message payload..
  106.       test_packet[46] = 8'h00; // MAP message payload..
  107.       test_packet[47] = 8'h01; // MAP message payload..
  108.       test_packet[48] = 8'hC0; // MAP message payload..
  109.       test_packet[49] = 8'h14; // Last byte of MAP payload, last byte covered by CRC32.
  110.       test_packet[50] = 8'hDD; // CRC32 Starts here
  111.       test_packet[51] = 8'hBF; // CRC32 cont..
  112.       test_packet[52] = 8'hC1; // CRC32 cont..
  113.       test_packet[53] = 8'h2E; // Last byte of CRC32, last byte of DOCSIS.
  114.    end
  115. endtask
  116. // *************************************************************************
  117. // *
  118. // *   Main test task.
  119. // *
  120. // *   Use our primary "golden packet".  Copy into the generic global
  121. // *   variables that the low-level 'gencrc16' and 'gencrc32' tasks use.
  122. // *   Comare against the expected values and report SUCCESS or FAILURE.
  123. // *
  124. // *************************************************************************
  125. //
  126. task main_test;
  127.    integer i, j;
  128.    integer num_errors;
  129.    reg [15:0] crc16_expected;
  130.    reg [31:0] crc32_expected;
  131.    begin
  132.    
  133.    num_errors = 0;
  134.    
  135.    // Initialize the Golden Message!
  136.    //
  137.    initialize_test_packet;
  138.    
  139.    // **** TEST CRC16
  140.    //
  141.    $display ("Testing CRC16:");
  142.    //
  143.    // Copy golden test_packet into the main crc16 buffer..
  144.    for (i=0; i<4; i=i+1) begin
  145.       crc16_packet[i] = test_packet[i];
  146.    end
  147.    crc16_expected = {test_packet[4], test_packet[5]};
  148.    crc16_length = 4;  // Must tell test function the length
  149.    gencrc16;  // Call main test function
  150.    $display ("   Actual crc16_result = %h, Expected = %h", crc16_result, crc16_expected);
  151.    if (crc16_result == crc16_expected) begin
  152.       $display ("   Success.");
  153.    end
  154.    else begin
  155.       $display ("   ERROR!!!");
  156.       num_errors = num_errors + 1;
  157.    end
  158.    // **** TEST CRC16
  159.    //
  160.    $display ("Testing CRC32:");
  161.    j = 0;
  162.    for (i=6; i<50; i=i+1) begin
  163.       crc32_packet[j] = test_packet[i];
  164.       j = j + 1;
  165.    end
  166.    crc32_expected = {test_packet[50], test_packet[51], test_packet[52], test_packet[53]};
  167.    crc32_length = 44;
  168.    gencrc32;
  169.    $display ("   Actual crc32_result = %h, Expected = %h", crc32_result, crc32_expected);
  170.    if (crc32_result == crc32_expected) begin
  171.       $display ("   Success.");
  172.    end
  173.    else begin
  174.       $display ("   ERROR!!!");
  175.       num_errors = num_errors + 1;
  176.    end
  177.    
  178.    $display ("nDone.  %0d Errors.", num_errors);
  179.    $display ("n");
  180.    end
  181. endtask
  182. // ****************************************************************
  183. // *
  184. // *   Main working CRC tasks are: gencrc16, gencrc32.
  185. // *
  186. // *   These tasks rely on some globals (see front of program).
  187. // *
  188. // ****************************************************************
  189. // Generate a (DOCSIS) CRC16.
  190. //
  191. // Uses the GLOBAL variables:
  192. //
  193. //    Globals referenced:
  194. //       parameter CRC16_POLY = 16'h1020;
  195. //       reg [ 7:0] crc16_packet[0:255];
  196. //       integer crc16_length;
  197. //
  198. //    Globals modified:
  199. //       reg [15:0] crc16_result;
  200. //
  201. task gencrc16;
  202.    integer byte, bit;
  203.    reg msb;
  204.    reg [7:0] current_byte;
  205.    reg [15:0] temp;
  206.    begin
  207.       crc16_result = 16'hffff;
  208.       for (byte = 0; byte < crc16_length; byte = byte + 1) begin
  209.          current_byte = crc16_packet[byte];
  210.          for (bit = 0; bit < 8; bit = bit + 1) begin
  211.             msb = crc16_result[15];
  212.             crc16_result = crc16_result << 1;
  213.             if (msb != current_byte[bit]) begin
  214.                crc16_result = crc16_result ^ CRC16_POLY;
  215.                crc16_result[0] = 1;
  216.             end
  217.          end
  218.       end
  219.       
  220.       // Last step is to "mirror" every bit, swap the 2 bytes, and then complement each bit.
  221.       //
  222.       // Mirror:
  223.       for (bit = 0; bit < 16; bit = bit + 1)
  224.          temp[15-bit] = crc16_result[bit];
  225.          
  226.       // Swap and Complement:
  227.       crc16_result = ~{temp[7:0], temp[15:8]};
  228.    end
  229. endtask
  230. // Generate a (DOCSIS) CRC32.
  231. //
  232. // Uses the GLOBAL variables:
  233. //
  234. //    Globals referenced:
  235. //       parameter CRC32_POLY = 32'h04C11DB7;
  236. //       reg [ 7:0] crc32_packet[0:255];
  237. //       integer crc32_length;
  238. //
  239. //    Globals modified:
  240. //       reg [31:0] crc32_result;
  241. //
  242. task gencrc32;
  243.    integer byte, bit;
  244.    reg msb;
  245.    reg [7:0] current_byte;
  246.    reg [31:0] temp;
  247.    begin
  248.       crc32_result = 32'hffffffff;
  249.       for (byte = 0; byte < crc32_length; byte = byte + 1) begin
  250.          current_byte = crc32_packet[byte];
  251.          for (bit = 0; bit < 8; bit = bit + 1) begin
  252.             msb = crc32_result[31];
  253.             crc32_result = crc32_result << 1;
  254.             if (msb != current_byte[bit]) begin
  255.                crc32_result = crc32_result ^ CRC32_POLY;
  256.                crc32_result[0] = 1;
  257.             end
  258.          end
  259.       end
  260.       
  261.       // Last step is to "mirror" every bit, swap the 4 bytes, and then complement each bit.
  262.       //
  263.       // Mirror:
  264.       for (bit = 0; bit < 32; bit = bit + 1)
  265.          temp[31-bit] = crc32_result[bit];
  266.          
  267.       // Swap and Complement:
  268.       crc32_result = ~{temp[7:0], temp[15:8], temp[23:16], temp[31:24]};
  269.    end
  270. endtask
  271. endmodule