gencrc.v.txt
上传用户:saul_905
上传日期:2013-11-27
资源大小:184k
文件大小:10k
源码类别:
VHDL/FPGA/Verilog
开发平台:
Visual C++
- //
- // Behavioral Verilog for CRC16 and CRC32 for use in a testbench.
- //
- // The specific polynomials and conventions regarding bit-ordering etc.
- // are specific to the Cable Modem DOCSIS protocol, but the general scheme
- // should be reusable for other types of CRCs with some fiddling.
- //
- // This CRC code works for a specific type of network protocol, and it
- // must do certain byte swappings, etc. You may need to play with it
- // for your protocol. Also, make sure the polynomials are what you
- // really want. This is obviously, not synthesizable - I just used this
- // in a testbench at one point.
- //
- // These tasks are crude and rely on some global parameters. They should
- // also read from a file, yada yada yada. It is probably better to do this
- // with a PLI call, but here it is anyway..
- //
- // The test case includes a golden DOCSIS (Cable Modem) test message that
- // was captured in a lab.
- //
- // tom coonan, 1999.
- //
- module test_gencrc;
- // *** Buffer for the Golden Message ***
- reg [7:0] test_packet[0:54];
- // *** Global parameter block for the CRC32 calculator.
- //
- parameter CRC32_POLY = 32'h04C11DB7;
- reg [ 7:0] crc32_packet[0:255];
- integer crc32_length;
- reg [31:0] crc32_result;
- // *** Global parameter block for the CRC16 calculator.
- //
- parameter CRC16_POLY = 16'h1020;
- reg [ 7:0] crc16_packet[0:255];
- integer crc16_length;
- reg [15:0] crc16_result;
- `define TEST_GENCRC
- `ifdef TEST_GENCRC
- // Call the main test task and then quit.
- //
- initial begin
- main_test;
- $finish;
- end
- `endif
- // ****************************************************************
- // *
- // * GOLDEN MESSAGE
- // *
- // * The golden message is a DOCSIS frame that was captured off
- // * the Broadcom reference design. It is a MAP message. It
- // * includes a HCS (crc 16) and a CRC32.
- // *
- // *
- // ****************************************************************
- //
- task initialize_test_packet;
- begin
- test_packet[00] = 8'hC2; // FC. HCS coverage starts here.
- test_packet[01] = 8'h00; // MACPARAM
- test_packet[02] = 8'h00; // MAC LEN
- test_packet[03] = 8'h30; // MAC LEN. HCS Coverage includes this byte and ends here.
- test_packet[04] = 8'hF2; // CRC16 (also known as HCS)
- test_packet[05] = 8'hCF; // CRC16 cont..
- test_packet[06] = 8'h01; // Start of the IEEE payload. CRC32 covererage starts here. This is the DA field
- test_packet[07] = 8'hE0; // DA field cont..
- test_packet[08] = 8'h2F; // DA field cont..
- test_packet[09] = 8'h00; // DA field cont..
- test_packet[10] = 8'h00; // DA field cont..
- test_packet[11] = 8'h01; // DA field cont..
- test_packet[12] = 8'h00; // SA field
- test_packet[13] = 8'h80; // SA field cont..
- test_packet[14] = 8'h42; // SA field cont..
- test_packet[15] = 8'h42; // SA field cont..
- test_packet[16] = 8'h20; // SA field cont..
- test_packet[17] = 8'h9E; // SA field cont..
- test_packet[18] = 8'h00; // IEEE LEN field
- test_packet[19] = 8'h1E; // IEEE LEN field cont.
- test_packet[20] = 8'h00; // LLC field.
- test_packet[21] = 8'h00; // LLC field cont...
- test_packet[22] = 8'h03; // LLC field cont...
- test_packet[23] = 8'h01; // LLC field cont...
- test_packet[24] = 8'h03; // LLC field cont... This is also the TYPE, which indicates MAP.
- test_packet[25] = 8'h00; // LLC field cont...
- test_packet[26] = 8'h01; // Start of MAP message payload.
- test_packet[27] = 8'h01; // MAP message payload..
- test_packet[28] = 8'h02; // MAP message payload..
- test_packet[29] = 8'h00; // MAP message payload..
- test_packet[30] = 8'h00; // MAP message payload..
- test_packet[31] = 8'h18; // MAP message payload..
- test_packet[32] = 8'hAA; // MAP message payload..
- test_packet[33] = 8'h58; // MAP message payload..
- test_packet[34] = 8'h00; // MAP message payload..
- test_packet[35] = 8'h18; // MAP message payload..
- test_packet[36] = 8'hA8; // MAP message payload..
- test_packet[37] = 8'hA0; // MAP message payload..
- test_packet[38] = 8'h02; // MAP message payload..
- test_packet[39] = 8'h03; // MAP message payload..
- test_packet[40] = 8'h03; // MAP message payload..
- test_packet[41] = 8'h08; // MAP message payload..
- test_packet[42] = 8'hFF; // MAP message payload..
- test_packet[43] = 8'hFC; // MAP message payload..
- test_packet[44] = 8'h40; // MAP message payload..
- test_packet[45] = 8'h00; // MAP message payload..
- test_packet[46] = 8'h00; // MAP message payload..
- test_packet[47] = 8'h01; // MAP message payload..
- test_packet[48] = 8'hC0; // MAP message payload..
- test_packet[49] = 8'h14; // Last byte of MAP payload, last byte covered by CRC32.
- test_packet[50] = 8'hDD; // CRC32 Starts here
- test_packet[51] = 8'hBF; // CRC32 cont..
- test_packet[52] = 8'hC1; // CRC32 cont..
- test_packet[53] = 8'h2E; // Last byte of CRC32, last byte of DOCSIS.
- end
- endtask
- // *************************************************************************
- // *
- // * Main test task.
- // *
- // * Use our primary "golden packet". Copy into the generic global
- // * variables that the low-level 'gencrc16' and 'gencrc32' tasks use.
- // * Comare against the expected values and report SUCCESS or FAILURE.
- // *
- // *************************************************************************
- //
- task main_test;
- integer i, j;
- integer num_errors;
- reg [15:0] crc16_expected;
- reg [31:0] crc32_expected;
- begin
- num_errors = 0;
- // Initialize the Golden Message!
- //
- initialize_test_packet;
- // **** TEST CRC16
- //
- $display ("Testing CRC16:");
- //
- // Copy golden test_packet into the main crc16 buffer..
- for (i=0; i<4; i=i+1) begin
- crc16_packet[i] = test_packet[i];
- end
- crc16_expected = {test_packet[4], test_packet[5]};
- crc16_length = 4; // Must tell test function the length
- gencrc16; // Call main test function
- $display (" Actual crc16_result = %h, Expected = %h", crc16_result, crc16_expected);
- if (crc16_result == crc16_expected) begin
- $display (" Success.");
- end
- else begin
- $display (" ERROR!!!");
- num_errors = num_errors + 1;
- end
- // **** TEST CRC16
- //
- $display ("Testing CRC32:");
- j = 0;
- for (i=6; i<50; i=i+1) begin
- crc32_packet[j] = test_packet[i];
- j = j + 1;
- end
- crc32_expected = {test_packet[50], test_packet[51], test_packet[52], test_packet[53]};
- crc32_length = 44;
- gencrc32;
- $display (" Actual crc32_result = %h, Expected = %h", crc32_result, crc32_expected);
- if (crc32_result == crc32_expected) begin
- $display (" Success.");
- end
- else begin
- $display (" ERROR!!!");
- num_errors = num_errors + 1;
- end
- $display ("nDone. %0d Errors.", num_errors);
- $display ("n");
- end
- endtask
- // ****************************************************************
- // *
- // * Main working CRC tasks are: gencrc16, gencrc32.
- // *
- // * These tasks rely on some globals (see front of program).
- // *
- // ****************************************************************
- // Generate a (DOCSIS) CRC16.
- //
- // Uses the GLOBAL variables:
- //
- // Globals referenced:
- // parameter CRC16_POLY = 16'h1020;
- // reg [ 7:0] crc16_packet[0:255];
- // integer crc16_length;
- //
- // Globals modified:
- // reg [15:0] crc16_result;
- //
- task gencrc16;
- integer byte, bit;
- reg msb;
- reg [7:0] current_byte;
- reg [15:0] temp;
- begin
- crc16_result = 16'hffff;
- for (byte = 0; byte < crc16_length; byte = byte + 1) begin
- current_byte = crc16_packet[byte];
- for (bit = 0; bit < 8; bit = bit + 1) begin
- msb = crc16_result[15];
- crc16_result = crc16_result << 1;
- if (msb != current_byte[bit]) begin
- crc16_result = crc16_result ^ CRC16_POLY;
- crc16_result[0] = 1;
- end
- end
- end
- // Last step is to "mirror" every bit, swap the 2 bytes, and then complement each bit.
- //
- // Mirror:
- for (bit = 0; bit < 16; bit = bit + 1)
- temp[15-bit] = crc16_result[bit];
- // Swap and Complement:
- crc16_result = ~{temp[7:0], temp[15:8]};
- end
- endtask
- // Generate a (DOCSIS) CRC32.
- //
- // Uses the GLOBAL variables:
- //
- // Globals referenced:
- // parameter CRC32_POLY = 32'h04C11DB7;
- // reg [ 7:0] crc32_packet[0:255];
- // integer crc32_length;
- //
- // Globals modified:
- // reg [31:0] crc32_result;
- //
- task gencrc32;
- integer byte, bit;
- reg msb;
- reg [7:0] current_byte;
- reg [31:0] temp;
- begin
- crc32_result = 32'hffffffff;
- for (byte = 0; byte < crc32_length; byte = byte + 1) begin
- current_byte = crc32_packet[byte];
- for (bit = 0; bit < 8; bit = bit + 1) begin
- msb = crc32_result[31];
- crc32_result = crc32_result << 1;
- if (msb != current_byte[bit]) begin
- crc32_result = crc32_result ^ CRC32_POLY;
- crc32_result[0] = 1;
- end
- end
- end
- // Last step is to "mirror" every bit, swap the 4 bytes, and then complement each bit.
- //
- // Mirror:
- for (bit = 0; bit < 32; bit = bit + 1)
- temp[31-bit] = crc32_result[bit];
- // Swap and Complement:
- crc32_result = ~{temp[7:0], temp[15:8], temp[23:16], temp[31:24]};
- end
- endtask
- endmodule