AN 539: Test Methodology of Error Detection and Recovery using CRC in Altera FPGA Devices
Test Methodology of Error Detection and Recovery using CRC in Altera FPGA Devices
This application note describes how to use the enhanced error detection cyclic redundancy check (CRC) feature in the Arria^{®} II, Stratix^{®} III, Stratix IV, Arria V, Cyclone^{®} V, and Stratix V devices. It also describes the test methodology you can use when testing the capability of this feature in the supported devices. Arria V, Cyclone V, and Stratix V devices also support error correction feature.
During FPGA configuration, the error detection CRC feature detects configuration bitstream corruption when the bitstream is transferred from an external device into the FPGA. In user mode, the error detection CRC feature detects a single event upset (SEU) and determines the error type and location. In addition, Arria V, Cyclone V, and Stratix V devices support internal scrubbing, an ability to correct errors detected in user mode.
Functional Description
The width of the CRC field is 16 bits in Arria II, Stratix III, and Stratix IV devices; 32 bits in Arria V, Cyclone V, and Stratix V devices.
 Applicable to the Arria II, Stratix III, and Stratix IV devices only.
 Applicable to the Arria V, Cyclone V, and Stratix V devices only.
Register  Description 

Syndrome Register  This register contains the CRC signature of the current frame through the error detection verification cycle. The CRC_ERROR signal is derived from the contents in this register. 
Error Message Register (EMR)  This register contains information about the error type, the location of the error, and the actual syndrome. The types of errors and location reported are single and doubleadjacent bit errors. For Arria V, Cyclone V, and Stratix V devices, the types of errors and location reported are single, double, triple, and quadrupleadjacent bit errors. The location bits for other types of errors are not identified by the EMR. You can shift the contents of this register through the SHIFT_EDERROR_REG JTAG instruction or to the core through the core interface. See related information for more information about error message register. 
JTAG Update Register  This register is automatically updated with the contents of the EMR one cycle after the EMR register content is validated. The JTAG update register includes a clock enable that must be asserted before being sampled into the JTAG shift register. This requirement ensures that the JTAG update register is not being written by the contents of the EMR at exactly the same time as the JTAG shift register is reading its contents. 
User Update Register  This register is automatically updated with the contents of the EMR one cycle after the EMR register content is validated. The user update register includes a clock enable that must be asserted before being sampled into the user shift register. This requirement ensures that the user update register is not being written by the contents of the EMR at exactly the same time as the user shift register is reading its contents. 
JTAG Shift Register  This register is accessible by the JTAG interface and allows the contents of the JTAG update register to be sampled and read out by the SHIFT_EDERROR_REG JTAG instruction. 
User Shift Register  This register is accessible by the core logic and allows the contents of the user update register to be sampled and read by user logic. 
JTAG Fault Injection Register  This register is fully controlled by the EDERROR_INJECT JTAG instruction. This register holds the information of the error injection that you want in the bitstream. 
Fault Injection Register  The contents of the JTAG fault injection register is loaded into this fault injection register when the JTAG fault injection register is being updated. 
Configuration Error Detection
When the Quartus^{®} II software generates the configuration bitstream, it also computes a CRC value for each data frame. The number of data frames and the length of the frames in a configuration bitstream vary in each device. Therefore, a configuration bitstream can contain more than one CRC values depending on the number of data frames in the bitstream.
When a data frame is loaded into the FPGA during configuration, the precomputed CRC value shifts into the CRC circuitry in the FPGA. At the same time, the CRC engine in the FPGA computes the CRC value for the data frame received, and stores the CRC value into the configuration RAM (CRAM). The precomputed CRC value is compared against the CRC value computed by the CRC engine. If the CRC values do not match, nSTATUS is set low to flag a configuration error.
You can test the capability of the configuration error detection feature by either modifying the configuration bitstream or intentionally corrupting the configuration bitstream during configuration.
User Mode Error Detection
During user mode, the contents of a configured CRAM bit may be affected by soft errors. User mode error detection allows you to determine the type of soft error and to identify the location of the affected bit.
After the configuration cycle is complete, the error detection feature computes the CRC value of the configured CRAM bits and compares the results with the precomputed CRC value. If both the CRC values match, the resulting CRC signature is set to 0 to indicate that no error was detected. The error detection process continues until the device is reset by setting nCONFIG low.
If CRC errors occur, the resulting signature is nonzero and the CRC_ERROR pin is set high to flag an error. When errors occur, the search engine in the error detection state machine identifies the error type and error location. All types of CRC errors can be detected in a frame. The results of the search engine are stored in the EMR. You can shift out the contents of this register through the JTAG instruction or core interface logics. You can shift out the contents while the error detection block is running.
Error Detection Pin
Error Message Register
The EMR contains information on the error type, the location of the error, and the actual syndrome. This register is 46 bits wide in Arria II, Stratix III, and Stratix IV devices; 67 bits wide in Arria V, Cyclone V, and Stratix V devices. Table 3 and Table 4 list the types of errors and locations reported. The EMR does not identify the location bits for other types of errors.
The location of the errors consist of the column frame number, byte location within the frame, and bit location in the byte. You can shift out the contents of the register through the SHIFT_EDERROR_REG JTAG instruction or to the core through the core interface.
JTAG Instruction  Instruction Code  Description 

SHIFT_EDERROR_REG  00 0001 0111  The JTAG instruction connects the EMR to the JTAG pin in the error detection block between the TDI and TDO pins. 
The contents of the EMR is updated when an error or errors occur. You must transfer the contents of the EMR out before they are overwritten by the next error message. The minimum interval time between two EMR updates is different for every device. For more information about the minimum update interval of the EMR, see related information below.
EMR for Arria II, Stratix III, and Stratix IV Devices
Error Type  Description  

Bit 1  Bit 0  
0  0  No CRC error is identified. 
0  1  Location of a single error is identified. 
1  0  Location of a doubleadjacent bit error is identified. 
1  1  There are more than two errors or two nonadjacent errors. 
EMR for Arria V, Cyclone V, and Stratix V Devices
Error Type  Description  

Bit 4  Bit 3  Bit 1  Bit 0  
0  0  0  0  No CRC error is identified. 
0  0  0  1  Location of a single error is identified. 
0  0  1  0  Location of a doubleadjacent bit error is identified. 
1  1  1  1  Uncorrectable errors. 
Others  Invalid. 
Error Detection Timing
The CRC_ERROR pin is always set low during CRC signature calculation for a minimum of 32 clock cycles. When errors occur, the CRC_ERROR pin is set high after the EMR has been updated, or after 32 cycles, whichever comes last. Therefore, you can start to unload the contents of the EMR at the rising edge of the CRC_ERROR pin. At the end of this cycle, the CRC_ERROR pin is set low again for a minimum of 32 clock cycles. If the next frame also contains error, the CRC_ERROR pin pulls high again and the EMR is updated with the new error information.
You can control the speed of the error detection process by setting the division factor of the clock frequency in the Quartus II software. The divisor is a power of two, in which n is between one and eight. The divisor ranges from two through 256.
Error Correction
In addition to error detection capability, Arria V, Cyclone V, and Stratix V devices also support internal scrubbing. Internal scrubbing has the ability to internally correct soft errors. This is done on a per frame basis. Internal scrubbing corrects errors without the need of reconfiguring the device. Internal scrubbing operates in user mode. Enable the internal scrubbing feature in the Quartus II software by turning on the Enable internal scrubbing option under the Error Detection CRC page in the Device & Pin Options dialog box.
Using the Error Detection CRC Feature
To determine the location of the CRC errors, unload the EMR. You can shift the contents of the EMR through the JTAG instruction or core interface.
Error Detection using User Logic
Detecting CRC Errors through the CRC_ERROR Output Signal
To detect CRC errors through the CRC_ERROR output signal, use the CRC_ERROR output signal. Check whether a CRC error has been found in the CRC calculation before unloading the contents of the EMR. To do this, route the crcerror port from the WYSIWYG atom to the dedicated CRC_ERROR pin or any user I/O. To route the crcerror port to a user I/O, you must insert a D flipflop (DFF) in between the crcerror port and the user I/O.
Unloading the EMR through User Logic
To unload the EMR through user logic, establish an interface between the user logic and the error detection circuit using the WYSIWYG atom. The WYSIWYG atom provides access to the error detection block. In addition, you must design a user logic control block to control the necessary control signals to access the WYSIWYG atom.
Accessing the Error Detection Block through User Logic
Use the <device>_crcblock WYSIWYG component to establish the interface from the user logic to the error detection circuit. The <device>_crcblock primitive atom contains the input and output ports that you must include in the atom. To access the logic array, insert the <device>_crcblock WYSIWYG atom into your design.
You cannot use the information provided by the EMR to detect soft errors. Instead, use the information provided by the CRC_ERROR output signal because it is not affected by soft errors.
To enable the <device>_crcblock WYSIWYG atom, name the atom for each device accordingly. For example, the WYSIWYG atom for the Stratix III device is stratixiii_crcblock and the Arria II device is arriaii_crcblock.
Port  Input/Output  Definition 

<crcblock_name>  Input  Unique identifier for the CRC block and represents any identifier name that is legal for the given description language, such as the Verilog HDL, VHDL, and Altera Hardware Description Language (AHDL). This is a required field. 
.clk(<clock source>)  Input  Designates the clock input of this cell. All operations of this cell are with respect to the rising edge of the clock. Whether loading data into the cell or out of the cell, this always occurs on the rising edge. This is a required port. 
.shiftnld (<shiftnld source>)  Input 

.crcerror (<crcerror out destination>)  Output 

.regout(<output destination>)  Output 

Example of the Input and Output Ports of a WYSIWYG Atom in a Stratix III Device
Example shows the input and output ports of a WYSIWYG atom in a Stratix III device.stratixiii_crcblock <crcblock_name> ( .clk(<clock source>), .shiftnld(<shiftnld source>), .crcerror(<crcerror out destination>), .regout(<output destination>) ); defparam crc_wysiwyg_atom.oscillator_divider = 2
User Logic Control Block
You define the user logic control block. A design example is provided with this application note. In this design example, the user logic control block controls the input port to the WYSIWYG atom to read out the contents of the user update register. The user update register is updated with the contents of the EMR. To read out the contents of the user update register, follow these steps:
 Drive the SHIFTnLD signal low.
 Wait at least two ED_CLK cycles.
 Clock Clk_in one cycle for one rising edge to load the contents of the user update register to the user shift register.
 Drive the SHIFTnLD signal high.
 Clock Clk_in 29 cycles to read out 30 bits of the error location information.
 Clock Clk_in an additional 16 cycles to read out the syndrome of the error.
User Logic Control Block Signals
Signal Name  Input/ Output  Description 

clk_in  Input  Clock source to the user logic control block. 
Start_write  Input  This input triggers the user logic control block to start driving the SHIFTnLD and ED_CLK output signals. When this input is high, the user logic control block starts to run the mechanism to unload the user update register. This input is usually tied to the crcerror output port from the WYSIWYG atom because the EMR is unloaded at the rising edge of the crcerror port. 
SHIFTnLD  Output  Output to the WYSIWYG atom. Use this signal to drive the shiftnld port of the WYSIWYG atom. 
ED_CLK  Output  Output clock to the WYSIWYG atom. Use this clock as the clock source for the WYSIWYG atom. This clock is connected to the clk port of the WYSIWYG atom. The source of this clock comes from the clk_in input signal. 
Error Detection using an External Host
Detecting a CRC Error through the CRC_ERROR Output Signal
Before unloading the contents of the EMR, use the CRC_ERROR output signal to check whether a CRC error has been found throughout the CRC calculation. To do this, enable the error detection CRC feature in the Device & Pin Options dialog box in the Quartus II software and observe the dedicated CRC_ERROR pin.
Unloading the EMR using an External Host
To unload the contents of the EMR using an external host, such as a JTAG port, use the SHIFT_EDERROR_REG JTAG instruction. This JTAG instruction connects the EMR to the JTAG pin in the error detection block between the TDI and TDO pins. You can execute the instruction whenever the CRC_ERROR pin goes high.
You must unload the contents of the EMR before the register is overwritten by the information of the next CRC error.
The following examples show the Jam™ Standard Test and Programming Language (STAPL) Format File (.jam) used to execute the SHIFT_EDERROR_REG JTAG instruction to unload the contents of the EMR.
Example of .jam File to Unload the Contents of the EMR for Arria II, Stratix III, and Stratix IV Devices
ACTION UNLOAD_EMR = EXECUTE; DATA EMR_DATA; BOOLEAN out[46]; BOOLEAN in[46]=$3FFFFFFFFFFF; ENDDATA; PROCEDURE EXECUTE USES EMR_DATA; DRSTOP IDLE; IRSTOP IDLE; STATE IDLE; IRSCAN 10, $017; WAIT IDLE, 10 CYCLES, 1 USEC, IDLE; DRSCAN 46, in[45..0], CAPTURE out[45..0]; WAIT IDLE, 10 CYCLES, 25 USEC, IDLE; PRINT " "; PRINT "Data read out from the EMR Register: ", out[45], out[44], out[43], out[42], out[41], out[40], out[39], out[38], out[37], out[36], out[35], out[34], out[33], out[32], out[31], out[30]," ", out[29], out[28], out[27], out[26], out[25], out[24], out[23], out[22], out[21], out[20], out[19], out[18], out[17], out[16]," ", out[15], out[14], out[13], out[12], out[11], out[10], out[9], out[8], out[7], out[6], out[5]," ", out[4], out[3], out[2]," ", out[1], out[0]; PRINT " "; PRINT "Syndrome:", out[45], out[44], out[43], out[42], out[41], out[40], out[39], out[38], out[37], out[36], out[35], out[34], out[33], out[32], out[31], out[30]; PRINT "Frame Address:", out[29], out[28], out[27], out[26], out[25], out[24], out[23], out[22], out[21], out[20], out[19], out[18], out[17], out[16]; PRINT "Byte Location:", out[15], out[14], out[13], out[12], out[11], out[10], out[9], out[8], out[7], out[6], out[5]; PRINT "Bit Location:", out[4], out[3], out[2]; PRINT "Error Type:", out[1], out[0]; STATE IDLE; EXIT 0; ENDPROC;
Example of .jam File to Unload the Contents of the EMR for Arria V, Cyclone V, and Stratix V Devices
ACTION UNLOAD_EMR = EXECUTE; DATA EMR_DATA; BOOLEAN out[67]; BOOLEAN in[67]=$7FFFFFFFFFFFFFFFF; INTEGER i; ENDDATA; PROCEDURE EXECUTE USES EMR_DATA; DRSTOP IDLE; IRSTOP IDLE; STATE IDLE; IRSCAN 10, $017; WAIT IDLE, 10 CYCLES, 1 USEC, IDLE; DRSCAN 67, in[66..0], CAPTURE out[66..0]; WAIT IDLE, 10 CYCLES, 25 USEC, IDLE; PRINT " "; PRINT "Data read out from the "; PRINT "EMR_Register ::", out[66], out[65], out[64], out[63], out[62], out[61], out[60], out[59], out[58], out[57], out[56], out[55], out[54], out[53], out[52], out[51], out[50], out[49], out[48], out[47], out[46], out[45], out[44], out[43], out[42], out[41], out[40], out[39], out[38], out[37], out[36], out[35]," ", out[34], out[33], out[32], out[31], out[30], out[29], out[28], out[27], out[26], out[25], out[24], out[23], out[22], out[21], out[20], out[19]," ", out[18], out[17], out[16], out[15], out[14], out[13], out[12], out[11], out[10], out[9]," ", out[8], out[7]," ", out[6], out[5], out[4]," ", out[3], out[2], out[1], out[0]; 'PRINT " "; PRINT "Syndrome ::", out[66], out[65], out[64], out[63], out[62], out[61], out[60], out[59], out[58], out[57], out[56], out[55], out[54], out[53], out[52], out[51], out[50], out[49], out[48], out[47], out[46], out[45], out[44], out[43], out[42], out[41], out[40], out[39], out[38], out[37], out[36], out[35]; PRINT "Frame Address ::", out[34], out[33], out[32], out[31], out[30], out[29], out[28], out[27], out[26], out[25], out[24], out[23], out[22], out[21], out[20], out[19]; PRINT "Double Word Location ::", out[18], out[17], out[16], out[15], out[14], out[13], out[12], out[11], out[10], out[9]; PRINT "Byte Offset ::", out[8], out[7]; PRINT "Bit Offset ::", out[6], out[5], out[4]; PRINT "Error Type ::", out[3], out[2], out[1], out[0]; STATE IDLE; EXIT 0; ENDPROC;
Error Injection
To test the error detection block, you can intentionally inject errors. This error injection methodology provides design verification and system fault tolerance characterization. Using the EDERROR_INJECT JTAG instruction, you can inject a single error, double errors, or doubleadjacent errors to the configuration memory.
JTAG Instruction  Instruction Code  Description 

EDERROR_INJECT  00 0001 0101  This instruction controls the 21bit JTAG fault injection register that is used for error injection. 
Fault Injection Register
The EDERROR_INJECT JTAG instruction controls the contents of the JTAG fault injection register. The register holds the information of the error that you want to inject into the configuration memory.
You can scan the location of the error or errors into the 21bit (46bit for Arria V, Cyclone V, and Stratix V devices) JTAG fault injection register at any time. The contents of the JTAG fault injection register is loaded into the fault injection register when the last and first data frame is being processed. In other words, you can only inject the error into the first frame of the configuration data but you can monitor the error information at any time.ister holds the information of the error that you want to inject into the configuration memory.
Fault Injection for Arria II, Stratix III, and Stratix IV Devices
Error Type  Description  

Bit 20  Bit 19  
0  0  No error injection. 
0  1  Single byte error injection. 
1  0  Doubleadjacent error injection. 
1  1  Invalid error injection. 
Fault Injection for Arria V, Cyclone V, and Stratix V Devices
Error Type  Description  

Bit 45  Bit 44  Bit 43  Bit 42  
0  0  0  0  No error injection. 
0  0  0  1  Single byte error injection. 
0  0  1  0  Doubleadjacent error injection. 
Others  Invalid error injection. 
Error Injection using the EDERROR_INJECT JTAG Instruction
This section describes the testing process. When using a .jam file to automate the testing process, you can test and verify the functionality of the error detection block without having to reconfigure the device. Use the EDERROR_INJECT JTAG instruction to control the contents of the JTAG fault injection register to flip the readback bits of a particular location in the first data frame as specified in the JTAG fault injection register.
Injecting SingleBit Error for Arria II, Stratix III, and Stratix IV
If you want to inject a singlebit error into the 7th bit of the 5th byte in the first data frame, you must shift in the data that contains the information of the injected error into the fault injection register.
The following figure shows the binary bit sequence 0 1000 0000 0100 0100 0000 is shifted into the fault injection register. Because bit 19 and bit 20 of the fault injection register is 01, a singlebit error is injected. The byte location of the injected error is defined as 000 0000 0100, thus the singlebit error is injected into the 5th byte of the data frame. The error byte location value is 0100 0000, which indicates the 7th bit of the 5th byte data is the specific location in which the singlebit error is injected.
The following example shows the .jam file that you must execute in the EDERROR_INJECT JTAG instruction to inject the singlebit error into the first data frame for Arria II, Stratix III, and Stratix IV devices.
Example of .jam File to Inject SingleBit Error for Arria II, Stratix III, and Stratix IV Devices
ACTION ERROR_INJECT = EXECUTE; DATA DEVICE_DATA; BOOLEAN out[21]; BOOLEAN in[21] = $080440; ENDDATA; PROCEDURE EXECUTE USES DEVICE_DATA; BOOLEAN X = 0; DRSTOP IDLE; IRSTOP IDLE; STATE IDLE; IRSCAN 10, $015; WAIT IDLE, 10 CYCLES, 1 USEC, IDLE; DRSCAN 21, in[20..0], CAPTURE out[20..0]; WAIT IDLE, 10 CYCLES, 25 USEC, IDLE; PRINT " "; PRINT "Data read out from the FIR Register: ", out[20], out[19], " " ,out[18], out[17], out[16], out[15], out[14], out[13], out[12], out[11], out[10], out[9], out[8], " " , out[7], out[6], out[5], out[4], out[3], out[2], " ", out[1], out[0]; PRINT " "; PRINT "Error Type:", out[20], out[19]; PRINT " "; PRINT "Byte Location:", out[18], out[17], out[16], out[15], out[14], out[13], out[12], out[11], out[10], out[9], out[8]; PRINT " "; PRINT "Error Byte Value:", out[7], out[6], out[5], out[4], out[3], out[2], out[1], out[0]; STATE IDLE; EXIT 0; ENDPROC;
Injecting SingleBit Error for Arria V, Stratix V, and Cyclone V Devices
If you want to inject a singlebit error into the 15th bit of the 7th byte in the first data frame, you must shift in the data that contains the information of the injected error into the fault injection register.
The following figure shows the binary bit sequence 00 0100 0000 0110 0000 0000 0000 0000 0100 0000 0000 0000 is shifted into the fault injection register. Because bits 45, 44, 43, and 42 of the fault injection register is 0001, a singlebit error is injected. The byte location of the injected error is defined as 00 0000 0110, thus the singlebit error is injected into the 7th byte of the data frame. The error byte location value is 0000 0000 0000 000 0100 0000 0000 0000, which indicates the 15th bit of the 7th byte data is the specific location in which the singlebit error is injected.
The following example shows the .jam file that you must execute in the EDERROR_INJECT JTAG instruction to inject the singlebit error into the first data frame for Arria V, Cyclone V, and Stratix V devices.
ACTION ERROR_INJECT = EXECUTE; DATA DEVICE_DATA; BOOLEAN out[46]; BOOLEAN in[46] = $040600004000; ENDDATA; PROCEDURE EXECUTE USES DEVICE_DATA; BOOLEAN X = 0; DRSTOP IDLE; IRSTOP IDLE; STATE IDLE; IRSCAN 10, $015; WAIT IDLE, 10 CYCLES, 1 USEC, IDLE; DRSCAN 46, in[45..0], CAPTURE out[45..0]; WAIT IDLE, 10 CYCLES, 50 USEC, IDLE; PRINT " "; PRINT "Data read out from the FIR Register: ", out[45], out[44], out[43], out[42], " ", out[41], out[40], out[39], out[38], out[37], out[36], out[35], out[34], out[33], out[32], " ", out[31], out[30], out[29], out[28], out[27], out[26], out[25], out[24], out[23], out[22], out[21], out[20], out[19], out[18], out[17], out[16], out[15], out[14], out[13], out[12], out[11], out[10], out[9], out[8], out[7], out[6], out[5], out[4], out[3], out[2], out[1], out[0]; PRINT " "; PRINT "Error Type:", out[45], out[44], out[43], out[42]; PRINT " "; PRINT "Byte Location:", out[41], out[40], out[39], out[38], out[37], out[36], out[35], out[34], out[33], out[32]; PRINT " "; PRINT "Error Byte Value:", out[31], out[30], out[29], out[28], out[27], out[26], out[25], out[24], out[23], out[22], out[21], out[20], out[19], out[18], out[17], out[16], out[15], out[14], out[13], out[12], out[11], out[10], out[9], out[8], out[7], out[6], out[5], out[4], out[3], out[2], out[1], out[0]; STATE IDLE; EXIT 0; ENDPROC;
Clearing Fault Injection Register
After completing the test process, clear the contents of the fault injection register or start a reconfiguration by pulling the nCONFIG signal low to disable the error that you injected. To clear the contents of the fault injection register, scan all zero data into the register.
The following example shows a .jam file used to clear the contents of the fault injection register.
Example of .jam File to Clear the Contents of the Fault Injection Register
ACTION ERROR_INJECT_DISABLE = EXECUTE; DATA DEVICE_DATA; BOOLEAN out[21]; BOOLEAN in[21] = $000000; ENDDATA; PROCEDURE EXECUTE USES DEVICE_DATA; BOOLEAN X = 0; DRSTOP IDLE; IRSTOP IDLE; STATE IDLE; IRSCAN 10, $015; WAIT IDLE, 10 CYCLES, 1 USEC, IDLE; DRSCAN 21, in[20..0], CAPTURE out[20..0]; WAIT IDLE, 10 CYCLES, 25 USEC, IDLE; PRINT " "; PRINT "Data read out from the FIR Register: ", out[20], out[19]," " , out[18], out[17], out[16], out[15], out[14], out[13], out[12], out[11], out[10], out[9], out[8], " ", out[7], out[6], out[5], out[4], out[3], out[2], out[1], out[0]; PRINT " "; PRINT "Error Type:", out[20], out[19]; PRINT " "; PRINT "Byte Location:", out[18], out[17], out[16], out[15], out[14], out[13], out[12], out[11], out[10], out[9], out[8]; PRINT " "; PRINT "Error Byte Value:", out[7], out[6], out[5], out[4], out[3], out[2], out[1], out[0]; STATE IDLE; EXIT 0; ENDPROC;
Document Revision History
Date  Version  Changes 

June 2017  2017.06.14  Corrected Example 5. 
August 2016  2016.08.03 

August 2015  2015.08.20 

May 2015  2015.05.04 

December 2014  2014.12.15 

April 2014  3.0 

June 2011  2.0 

April 2009  1.1 

December 2008  1.0  Initial release. 