Main Content

Using HDL Optimized CRC Library Blocks

This example shows how to use the General CRC Generator HDL Optimized and General CRC Syndrome Detector HDL Optimized Simulink® blocks and then configure these blocks to meet the CRC-CCITT used in the IEEE® 802.11 standard [ 1 ].

Model Architecture

The model in this example contains HDL Optimized CRC Generator and Detector Simulink blocks. These blocks support simulation and HDL code generation. The top-level subsystem CRC Generation Detection in this model contains HDL Optimized CRC Generator CRC Detector blocks connected back-to-back. The model uses the input according to the 802.11 standard. For more information about CRC generation and detection, see [ 2 ].

To open this example model, run the following commands:

modelname = 'commcrchdl';
open_system(modelname);

The subsystem also contains AddNoise subsystem, using which you can choose a signal _sel_to add noise to the generated CRC checksum. To open this subsystem, run the following commands:

systemname = [modelname '/CRC Generation Detection'];
open_system(systemname);

Set Input Parameters

Specify the following input parameters:

  • Polynomial The row vector [1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1] represents the polynomial:

crc_poly= [0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1];
crc_len = 16;

  • Initial state

The HDL optimized CRC Generator block in this example uses the Direct Method, to feed the message into the most significant bit (MSB) of the checksum shift register and processes the message without padding zeros. The Figure 15-2 in the 802.11 standard illustrates the IEEE 802.11 CRC implementation. Set the Initial state parameter to 1.

  • Final XOR value

Set the Final XOR value parameter to 0xFFFF to implement the one's complement of the CRC Checksum.

finalXOR = [ones(1,16)];

Generate Input Data

Generate random input test data. The test data padded with crc_len zeros is processed at 16 bits/sample in streaming mode. Variable dataIn_width, defines the data processing speed. mlen defines the period in the controls signals startIn, endIn, and validIn. dlen defines the pulse width of the validIn signal.

rng('default')
data = rand(1,48)>0.5;
% pad crc_len zero
msg = [data zeros(1,crc_len)];
dataIn_width = 16;
mlen = length(msg)/dataIn_width;
dlen = length(data)/dataIn_width;
startIn = [1 zeros(1,dlen)];
endIn = [zeros(1,dlen-1) 1 0];
validIn = [ones(1,dlen) 0];
sel = false;

To meet your design requirements, you can modify the dataIn_width to 8, 4, 2, or 1 bit(s) in this example. For example, if you are processing data with length 56, apart from padding 8 bit zeros and using dataIn_width 16, choose the dataIn_width to be 8 to ensure that mlen and dlen are all integer numbers.

To calculate the initial delays of the CRC generator and detector, use the following command:

initial_delay_gen =  crc_len/dataIn_width + 2;
initial_delay_det =  3*(crc_len/dataIn_width) + 2;

simTime = 2*dlen + initial_delay_gen + initial_delay_det;

Run Model

Run the model using the following command:

sim(modelname);

Compare Simulink Output with MATLAB Reference

Create a CRC Generator System object™. To align with the CRC-CCITT used in the IEEE® 802.11 standard, set the generator polynomial to ${z}^{16} + {z}^{12} + {z}^5+ 1$, initial states to 1, direct method and final XOR to 1.

crcgenerator = comm.CRCGenerator('Polynomial','z^16 + z^12 + z^5 + 1', ...
    'InitialConditions',1,'DirectMethod',true,'FinalXOR',finalXOR) %#ok<*NOPTS>

refGenData = crcgenerator(data');
xsim_dataOut_gen = squeeze(sim_dataOut_gen);
xsim_dataIn_det = squeeze(sim_dataIn_det);
xsim_validOut_gen = squeeze(sim_validOut_gen);
if dataIn_width == 1
    actGenData = reshape(xsim_dataOut_gen(xsim_validOut_gen),[],1);
else
    actGenData = reshape(xsim_dataOut_gen(:,xsim_validOut_gen),[],1);
end
errCRCGen = nnz(refGenData - actGenData);
fprintf('CRC encoded Frame: Behavioral and HDL simulation differ by %d bits\n',errCRCGen);
crcgenerator = 

  comm.CRCGenerator with properties:

           Polynomial: 'z^16 + z^12 + z^5 + 1'
    InitialConditions: 1
         DirectMethod: true
    ReflectInputBytes: false
     ReflectChecksums: false
             FinalXOR: [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
    ChecksumsPerFrame: 1

CRC encoded Frame: Behavioral and HDL simulation differ by 0 bits

Create a CRC Detector System object™. To align with the CRC-CCITT used in the IEEE® 802.11 standard, set the generator polynomial to ${z}^16 + {z}^12 + {z}^5+ 1$, initial states to 1, direct method and final XOR to 1.

crcdetector = comm.CRCDetector('Polynomial','z^16 + z^12 + z^5 + 1', ...
    'InitialConditions',1,'DirectMethod',true,'FinalXOR',finalXOR)

if dataIn_width == 1
    crcdata = reshape(xsim_dataIn_det(xsim_validOut_gen),[],1);
else
    crcdata = reshape(xsim_dataIn_det(:,xsim_validOut_gen),[],1);
end
[refDetData, refErr] = crcdetector(crcdata);
xsim_dataOut_det = squeeze(sim_dataOut_det);
xsim_validOut_det = squeeze(sim_validOut_det);
if dataIn_width == 1
    actDetData = reshape(xsim_dataOut_det(xsim_validOut_det),[],1);
else
    actDetData = reshape(xsim_dataOut_det(:,xsim_validOut_det),[],1);
end
errCRCGDet = nnz(refDetData - actDetData);
errCheckSum = nnz(refErr - sim_err(sim_endOut_det));
fprintf(['CRC Decoded Frame: Behavioral and HDL simulation differ by %d bits and %d'...
    ' checksum bits\n'],errCRCGDet,errCheckSum);
crcdetector = 

  comm.CRCDetector with properties:

           Polynomial: 'z^16 + z^12 + z^5 + 1'
    InitialConditions: 1
         DirectMethod: true
    ReflectInputBytes: false
     ReflectChecksums: false
             FinalXOR: [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
    ChecksumsPerFrame: 1

CRC Decoded Frame: Behavioral and HDL simulation differ by 0 bits and 0 checksum bits

You can view the key signals in Logic Analyzer. The function commcrchdl_plot shows how to set the Logic Analyzer display. For more information on the Logic Analyzer System object™, see dsp.LogicAnalyzer.

h = commcrchdl_plot(dataIn,startIn,endIn,validIn,...
    sim_dataOut_gen,sim_startOut_gen,sim_endOut_gen,sim_validOut_gen,...
    sim_dataOut_det,sim_startOut_det,sim_endOut_det,sim_validOut_det,sim_err,dataIn_width);

dataIn, startIn, endIn, and validIn are input data and control signals to the HDL CRC generator. The output of CRC generator, sim_dataOut_gen, displays the message with the checksum appended for every dataIn_width bits per sample. You can read the checksum when the sim_endOut_gen is high in the output waveform. sim_dataIn_det shows the message with the corrupted checksum. sim_dataOut_det displays the message output of the CRC detector. When the err signal is high it indicates that some error is detected. sim_err is valid when the sim_endOut_det is active.

Generate HDL Code

To generate HDL code of this example, you must have an HDL Coder™ license.

To generate the HDL code and testbench for the subsystems, use the commands makehdl(subsystemname) and makehdltb(subsystemname).

Specify the subsystem name as 'commcrchdl/CRC Generation Detection/HDL CRC in Transmitter' or 'commcrchdl/CRC Generation Detection/HDL CRC in Receiver'.

References

  1. IEEE 802.11: Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications. (2007 revision). IEEE-SA. 12 June 2007.

  2. Giuseppe Campobello, Giuseppe Patane, Marco Russo. "Parallel CRC Realization," IEEE Transactions on Computers, vol. 52, no. 10, pp. 1312-1319, October, 2003.