//////////////////////////////////////////////////////////////////////////////// // Filename : CRC.bsv // Description : Generalized implementation of CRC algorithms //////////////////////////////////////////////////////////////////////////////// package CRC; // Notes : //////////////////////////////////////////////////////////////////////////////// /// Functions //////////////////////////////////////////////////////////////////////////////// function Bit#(a) reflect(Bool doIt, Bit#(a) data); return (doIt) ? reverseBits(data) : data; endfunction //////////////////////////////////////////////////////////////////////////////// /// Interfaces //////////////////////////////////////////////////////////////////////////////// interface CRC#(numeric type n); method Action add(Bit#(8) data); method Action clear(); method Bit#(n) result(); method ActionValue#(Bit#(n)) complete(); endinterface //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// /// Implementation of generalized CRC module /// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// module mkCRC#( Bit#(n) polynomial // the crc operation x^16 + x^12 + x^5 + 1 = 'h1021 , Bit#(n) initval // the initial CRC value , Bit#(n) finalXor // the result is xor'd with this value if desired , Bool reflectData // reverse the data bit order , Bool reflectRemainder // reverse the result bit order )(CRC#(n)) provisos( Add#(8, n8, n) // CRCs less than 8 bits are not permitted with this module ); //////////////////////////////////////////////////////////////////////////////// /// Design Elements //////////////////////////////////////////////////////////////////////////////// Reg#(Bit#(n)) rRemainder <- mkReg(initval); RWire#(Bit#(8)) rwAddIn <- mkRWire; PulseWire pwClear <- mkPulseWire; PulseWire pwComplete <- mkPulseWire; //////////////////////////////////////////////////////////////////////////////// /// Rules //////////////////////////////////////////////////////////////////////////////// (* fire_when_enabled *) rule update_crc; if (pwClear || pwComplete) rRemainder <= initval; else if (rwAddIn.wget matches tagged Valid .data) begin Bit#(n) remainder = rRemainder ^ (zeroExtend(reflect(reflectData, data)) << valueOf(n8)); for(Integer i = 0; i < 8; i = i + 1) begin if (msb(remainder) == 1) remainder = (remainder << 1) ^ polynomial; else remainder = (remainder << 1); end rRemainder <= remainder; end endrule //////////////////////////////////////////////////////////////////////////////// /// Interface Connections / Methods //////////////////////////////////////////////////////////////////////////////// method Action add(data); rwAddIn.wset(data); endmethod method Action clear(); pwClear.send; endmethod method Bit#(n) result(); return reflect(reflectRemainder, rRemainder) ^ finalXor; endmethod method ActionValue#(Bit#(n)) complete(); pwComplete.send; return reflect(reflectRemainder, rRemainder) ^ finalXor; endmethod endmodule //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// /// Implementation of the CRC-CCITT standard (x^16 + x^12 + x^5 + 1) /// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// (* synthesize *) module mkCRC_CCITT(CRC#(16)); (* hide *) let _m <- mkCRC('h1021, 'hFFFF, 'h0000, False, False); return _m; endmodule //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// /// Implementation of the CRC-16-ANSI standard (x^16 + x^15 + x^2 + 1) /// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// (* synthesize *) module mkCRC16(CRC#(16)); (* hide *) let _m <- mkCRC('h8005, 'h0000, 'h0000, True, True); return _m; endmodule //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// /// Implementation of the CRC-32 (IEEE 802.3) standard /// (x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1) /// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// (* synthesize *) module mkCRC32(CRC#(32)); (* hide *) let _m <- mkCRC('h04C11DB7, 'hFFFFFFFF, 'hFFFFFFFF, True, True); return _m; endmodule endpackage: CRC