-- top level MODULE "CRC32". It pairs with CRC16 which is optional. -- Written for Altera's appnote, and utilized in HDLC DS3 controller. -- The code below builds CRC byte wide input data path to 32 bit CRC generator. -- The data is latched on an input byte strobe. Every fourth strobe the CRC -- register holds new CRC value. -- Generator also outputs a valid CRC flag. It's purpose is to test integrity -- of received data. The data, followed by CRC32 has to be fed into the -- generator byte at a time, the CRC flag on the last byte strobe indicates -- coherent data. -- -- Written by Peter Szymanski -- rev 0 7/1/95 -- rev 1 7/26/95 ; fixed an off by 1 bug in term calc -- rev 2 8/23/95 ; reversed the polynomial per software emulator -- -- Input bytes on their LSB hold data received first, x32 is first term. -- The polynomial is: -- x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x1+x0 -- where x32 xors with shift regs bit0, x0 feeds bit31, x26 xors with bit6 and feeds bit5 -- left column are shift regs bit positions, next current contents with '-' signs -- indicating XOR gate outputs. m(n) = c(n) xor d(n), c-reg contents, d-input data -- -- after first shift -- d0 @ x0| -- | -- c0 | c1 -- c1 | c2 -- c2 | c3 -- c3 | c4 -- c4 | c5 -- c5 |- c6 m0 -- c6 | c7 -- c7 | c8 -- c8 |- c9 m0 -- c9 |- c10 m0 -- c10 | c11 -- c11 | c12 -- c12 | c13 -- c13 | c14 -- c14 | c15 -- c15 |- c16 m0 -- c16 | c17 -- c17 | c18 -- c18 | c19 -- c19 |- c20 m0 -- c20 |- c21 m0 -- c21 |- c22 m0 -- c22 | c23 -- c23 |- c24 m0 -- c24 |- c25 m0 -- c25 | c26 -- c26 |- c27 m0 -- c27 |- c28 m0 -- c28 | c29 -- c29 |- c30 m0 -- c30 |- c31 m0 -- c31 |- m0 -- --- -------------------------------------------------------------- -- s0 s1 -- -- second -- d1 @ x1| -- | -- c0 | c2 -- c1 | c3 -- c2 | c4 -- c3 | c5 -- c4 | c6 m0 -- c5 |- c7 m1 -- c6 | c8 -- c7 | c9 m0 -- c8 |- c10 m0 m1 -- c9 |- c11 m1 -- c10 | c12 -- c11 | c13 -- c12 | c14 -- c13 | c15 -- c14 | c16 m0 -- c15 |- c17 m1 -- c16 | c18 -- c17 | c19 -- c18 | c20 m0 -- c19 |- c21 m0 m1 -- c20 |- c22 m0 m1 -- c21 |- c23 m1 -- c22 | c24 m0 -- c23 |- c25 m0 m1 -- c24 |- c26 m1 -- c25 | c27 m0 -- c26 |- c28 m0 m1 -- c27 |- c29 m1 -- c28 | c30 m0 -- c29 |- c31 m0 m1 -- c30 |- m0 m1 -- c31 |- m1 -- --- -------------------------------------------------------------- -- s0 s1 -- third shift -- | -- c0 | c3 -- c1 | c4 -- c2 | c5 -- c3 | c6 m0 -- c4 | c7 m1 -- c5 |- c8 m2 -- c6 | c9 m0 -- c7 | c10 m0 m1 -- c8 |- c11 m1 m2 -- c9 |- c12 m2 -- c10 | c13 -- c11 | c14 -- c12 | c15 -- c13 | c16 m0 -- c14 | c17 m1 -- c15 |- c18 m2 -- c16 | c19 -- c17 | c20 m0 -- c18 | c21 m0 m1 -- c19 |- c22 m0 m1 m2 -- c20 |- c23 m1 m2 -- c21 |- c24 m0 m2 -- c22 | c25 m0 m1 -- c23 |- c26 m1 m2 -- c24 |- c27 m0 m2 -- c25 | c28 m0 m1 -- c26 |- c29 m1 m2 -- c27 |- c30 m0 m2 -- c28 | c31 m0 m1 -- c29 |- m0 m1 m2 -- c30 |- m1 m2 -- c31 |- m2 -- --- -------------------------------------------------------------- -- fourth shift -- | -- c0 | c4 -- c1 | c5 -- c2 | c6 m0 -- c3 | c7 m1 -- c4 | c8 m2 -- c5 |- c9 m0 m3 -- c6 | c10 m0 m1 -- c7 | c11 m1 m2 -- c8 |- c12 m2 m3 -- c9 |- c13 m3 -- c10 | c14 -- c11 | c15 -- c12 | c16 m0 -- c13 | c17 m1 -- c14 | c18 m2 -- c15 |- c19 m3 -- c16 | c20 m0 -- c17 | c21 m0 m1 -- c18 | c22 m0 m1 m2 -- c19 |- c23 m1 m2 m3 -- c20 |- c24 m0 m2 m3 -- c21 |- c25 m0 m1 m3 -- c22 | c26 m1 m2 -- c23 |- c27 m0 m2 m3 -- c24 |- c28 m0 m1 m3 -- c25 | c29 m1 m2 -- c26 |- c30 m0 m2 m3 -- c27 |- c31 m0 m1 m3 -- c28 | m0 m1 m2 -- c29 |- m1 m2 m3 -- c30 |- m2 m3 -- c31 |- m3 -- --- -------------------------------------------------------------- -- s0 s4 -- fifth shift -- c0 | c5 -- c1 | c6 m0 -- c2 | c7 m1 -- c3 | c8 m2 -- c4 | c9 m0 m3 -- c5 |- c10 m0 m1 m4 -- c6 | c11 m1 m2 -- c7 | c12 m2 m3 -- c8 |- c13 m3 m4 -- c9 |- c14 m4 -- c10 | c15 -- c11 | c16 m0 -- c12 | c17 m1 -- c13 | c18 m2 -- c14 | c19 m3 -- c15 |- c20 m0 m4 -- c16 | c21 m0 m1 -- c17 | c22 m0 m1 m2 -- c18 | c23 m1 m2 m3 -- c19 |- c24 m0 m2 m3 m4 -- c20 |- c25 m0 m1 m3 m4 -- c21 |- c26 m1 m2 m4 -- c22 | c27 m0 m2 m3 -- c23 |- c28 m0 m1 m3 m4 -- c24 |- c29 m1 m2 m4 -- c25 | c30 m0 m2 m3 -- c26 |- c31 m0 m1 m3 m4 -- c27 |- m0 m1 m2 m4 -- c28 | m1 m2 m3 -- c29 |- m2 m3 m4 -- c30 |- m3 m4 -- c31 |- m4 -- --- -------------------------------------------------------------- -- s0 s5 -- sixth shift -- c0 | c6 m0 -- c1 | c7 m1 -- c2 | c8 m2 -- c3 | c9 m0 m3 -- c4 | c10 m0 m1 m4 -- c5 |- c11 m1 m2 m5 -- c6 | c12 m2 m3 -- c7 | c13 m3 m4 -- c8 |- c14 m4 m5 -- c9 |- c15 m5 -- c10 | c16 m0 -- c11 | c17 m1 -- c12 | c18 m2 -- c13 | c19 m3 -- c14 | c20 m0 m4 -- c15 |- c21 m0 m1 m5 -- c16 | c22 m0 m1 m2 -- c17 | c23 m1 m2 m3 -- c18 | c24 m0 m2 m3 m4 -- c19 |- c25 m0 m1 m3 m4 m5 -- c20 |- c26 m1 m2 m4 m5 -- c21 |- c27 m0 m2 m3 m5 -- c22 | c28 m0 m1 m3 m4 -- c23 |- c29 m1 m2 m4 m5 -- c24 |- c30 m0 m2 m3 m5 -- c25 | c31 m0 m1 m3 m4 -- c26 |- m0 m1 m2 m4 m5 -- c27 |- m1 m2 m3 m5 -- c28 | m2 m3 m4 -- c39 |- m3 m4 m5 -- c30 |- m4 m5 -- c31 |- m5 -- --- -------------------------------------------------------------- -- -- seventh shift -- c0 | c7 m1 -- c1 | c8 m2 -- c2 | c9 m0 m3 -- c3 | c10 m0 m1 m4 -- c4 | c11 m1 m2 m5 -- c5 |- c12 m2 m3 m6 m0 -- c6 | c13 m3 m4 -- c7 | c14 m4 m5 -- c8 |- c15 m5 m6 m0 -- c9 |- c16 m0 m6 m0 -- c10 | c17 m1 -- c11 | c18 m2 -- c12 | c19 m3 -- c13 | c20 m0 m4 -- c14 | c21 m0 m1 m5 -- c15 |- c22 m0 m1 m2 m6 m0 -- c16 | c23 m1 m2 m3 -- c17 | c24 m0 m2 m3 m4 -- c18 | c25 m0 m1 m3 m4 m5 -- c19 |- c26 m1 m2 m4 m5 m6 m0 -- c20 |- c27 m0 m2 m3 m5 m6 m0 -- c21 |- c28 m0 m1 m3 m4 m6 m0 -- c22 | c29 m1 m2 m4 m5 -- c23 |- c30 m0 m2 m3 m5 m6 m0 -- c24 |- c31 m0 m1 m3 m4 m6 m0 -- c25 | m0 m1 m2 m4 m5 -- c26 |- m1 m2 m3 m5 m6 m0 -- c27 |- m2 m3 m4 m6 m0 -- c28 | m3 m4 m5 -- c29 |- m4 m5 m6 m0 -- c30 |- m5 m6 m0 -- c31 |- m6 m0 -- --- -------------------------------------------------------------- -- s0 s7 -- eighth shift -- c0 | c8 m2 -- c1 | c9 m0 m3 -- c2 | c10 m0 m1 m4 -- c3 | c11 m1 m2 m5 -- c4 | c12 m2 m3 m6 m0 -- c5 |- c13 m3 m4 m7 m1 -- c6 | c14 m4 m5 -- c7 | c15 m5 m6 m0 -- c8 |- c16 m0 m6 m7 m0 m1 -- c9 |- c17 m1 m7 m1 -- c10 | c18 m2 -- c11 | c19 m3 -- c12 | c20 m0 m4 -- c13 | c21 m0 m1 m5 -- c14 | c22 m0 m1 m2 m6 m0 -- c15 |- c23 m1 m2 m3 m7 m1 -- c16 | c24 m0 m2 m3 m4 -- c17 | c25 m0 m1 m3 m4 m5 -- c18 | c26 m1 m2 m4 m5 m6 m0 -- c19 |- c27 m0 m2 m3 m5 m6 m7 m0 m1 -- c20 |- c28 m0 m1 m3 m4 m6 m7 m0 m1 -- c21 |- c29 m1 m2 m4 m5 m7 m1 -- c22 | c30 m0 m2 m3 m5 m6 m0 -- c23 |- c31 m0 m1 m3 m4 m6 m7 m0 m1 -- c24 |- m0 m1 m2 m4 m5 m7 m1 -- c25 | m1 m2 m3 m5 m6 m0 -- c26 |- m2 m3 m4 m6 m7 m0 m1 -- c27 |- m3 m4 m5 m7 m1 -- c28 | m4 m5 m6 m0 -- c29 |- m5 m6 m7 m0 m1 -- c30 |- m6 m7 m0 m1 -- c31 |- m7 m1 -- --- -------------------------------------------------------------- -- s0 s8 -- -- these are the contents of the shift register on the eights shift -- -- -- -- -- entity CRC32 is port( RST: in vlbit; -- HDLC controller generated reset -- derived from bit 8 of status byte BYTE_CLK: in vlbit; -- HDLC controller byte clock DATA_BYTE: in vlbit_1d(7 downto 0); -- data octets EN: in vlbit; -- CRC enable synched to BYTE_CLK CRC_OK: out vlbit; -- hi of CRC equals to "0" LW_STB: out vlbit -- BYTE_CLK wide LW strobe ); -- end CRC32; architecture RTL_CRC32 of CRC32 is CONSTANT hex_0: vlbit_1d(15 downto 0) := "0000000000000000"; -- sixteen zeros CONSTANT Lhex_0: vlbit_1d(31 downto 0) := "00000000000000000000000000000000"; -- 32 zeros CONSTANT Lhex_1: vlbit_1d(31 downto 0) := "11111111111111111111111111111111"; -- 32 ones CONSTANT GEN_32: vlbit_1d(31 downto 0) := "00000100110000010001110110110111"; -- 04C11DB7 generator polynomial -- x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x1+x0 --CONSTANT residue: vlbit_1d(31 downto 0) := "11000111000001001101110101111011"; -- C704DD7B residue bit flip CONSTANT residue: vlbit_1d(31 downto 0) := "11011110101110110010000011100011"; -- DEBB20E3 residue -- ---------------------------------------------- Local Signals ------------------------------------ signal CRC_Reg: vlbit_1d(31 downto 0); -- holds current CRC value signal IX: vlbit_1d(7 downto 0); -- intermediate XOR terms signal byte_cnt: vlbit_1d(1 downto 0); -- local byte count signal Last_W: vlbit_1d(31 downto 0); -- holds last long word -- begin --------------------------------------------------------------------------------------------------- -- compute interim terms for the first byte. -- IX(0) <= CRC_Reg(0) xor DATA_BYTE(0); -- compute interm. byte product 0 first bit of a byte IX(1) <= CRC_Reg(1) xor DATA_BYTE(1); -- compute interm. byte product IX(2) <= CRC_Reg(2) xor DATA_BYTE(2); -- compute interm. byte product IX(3) <= CRC_Reg(3) xor DATA_BYTE(3); -- compute interm. byte product IX(4) <= CRC_Reg(4) xor DATA_BYTE(4); -- compute interm. byte product IX(5) <= CRC_Reg(5) xor DATA_BYTE(5); -- compute interm. byte product IX(6) <= CRC_Reg(6) xor DATA_BYTE(6); -- compute interm. byte product IX(7) <= CRC_Reg(7) xor DATA_BYTE(7); -- compute interm. byte product 7 last bit of a byte -- -- Gen_Rx_CRC32: process begin wait until ((BYTE_CLK'event and BYTE_CLK='1') or (RST = '1')); if RST = '1' then CRC_Reg <= Lhex_1; -- stat byte, clear reg else -- CRC_REG(0) <= not EN or (CRC_REG(8) xor IX(2) ); CRC_REG(1) <= not EN or (CRC_REG(9) xor IX(0) xor IX(3) ); CRC_REG(2) <= not EN or (CRC_REG(10) xor IX(0) xor IX(1) xor IX(4) ); CRC_REG(3) <= not EN or (CRC_REG(11) xor IX(1) xor IX(2) xor IX(5) ); CRC_REG(4) <= not EN or (CRC_REG(12) xor IX(0) xor IX(2) xor IX(3) xor IX(6) ); CRC_REG(5) <= not EN or (CRC_REG(13) xor IX(1) xor IX(3) xor IX(4) xor IX(7) ); CRC_REG(6) <= not EN or (CRC_REG(14) xor IX(4) xor IX(5) ); CRC_REG(7) <= not EN or (CRC_REG(15) xor IX(0) xor IX(5) xor IX(6) ); CRC_REG(8) <= not EN or (CRC_REG(16) xor IX(1) xor IX(6) xor IX(7) ); CRC_REG(9) <= not EN or (CRC_REG(17) xor IX(7) ); CRC_REG(10) <=not EN or (CRC_REG(18) xor IX(2) ); CRC_REG(11) <=not EN or (CRC_REG(19) xor IX(3) ); CRC_REG(12) <=not EN or (CRC_REG(20) xor IX(0) xor IX(4) ); CRC_REG(13) <=not EN or (CRC_REG(21) xor IX(0) xor IX(1) xor IX(5) ); CRC_REG(14) <=not EN or (CRC_REG(22) xor IX(1) xor IX(2) xor IX(6) ); CRC_REG(15) <=not EN or (CRC_REG(23) xor IX(2) xor IX(3) xor IX(7) ); CRC_REG(16) <=not EN or (CRC_REG(24) xor IX(0) xor IX(2) xor IX(3) xor IX(4) ); CRC_REG(17) <=not EN or (CRC_REG(25) xor IX(0) xor IX(1) xor IX(3) xor IX(4) xor IX(5) ); CRC_REG(18) <=not EN or (CRC_REG(26) xor IX(0) xor IX(1) xor IX(2) xor IX(4) xor IX(5) xor IX(6) ); CRC_REG(19) <=not EN or (CRC_REG(27) xor IX(1) xor IX(2) xor IX(3) xor IX(5) xor IX(6) xor IX(7) ); CRC_REG(20) <=not EN or (CRC_REG(28) xor IX(3) xor IX(4) xor IX(6) xor IX(7) ); CRC_REG(21) <=not EN or (CRC_REG(29) xor IX(2) xor IX(4) xor IX(5) xor IX(7) ); CRC_REG(22) <=not EN or (CRC_REG(30) xor IX(2) xor IX(3) xor IX(5) xor IX(6) ); CRC_REG(23) <=not EN or (CRC_REG(31) xor IX(3) xor IX(4) xor IX(6) xor IX(7) ); CRC_REG(24) <=not EN or ( IX(0) xor IX(2) xor IX(4) xor IX(5) xor IX(7) ); CRC_REG(25) <=not EN or ( IX(0) xor IX(1) xor IX(2) xor IX(3) xor IX(5) xor IX(6) ); CRC_REG(26) <=not EN or ( IX(0) xor IX(1) xor IX(2) xor IX(3) xor IX(4) xor IX(6) xor IX(7)); CRC_REG(27) <=not EN or ( IX(1) xor IX(3) xor IX(4) xor IX(5) xor IX(7) ); CRC_REG(28) <=not EN or ( IX(0) xor IX(4) xor IX(5) xor IX(6) ); CRC_REG(29) <=not EN or ( IX(0) xor IX(1) xor IX(5) xor IX(6) xor IX(7) ); CRC_REG(30) <=not EN or ( IX(0) xor IX(1) xor IX(6) xor IX(7) ); CRC_REG(31) <=not EN or ( IX(1) xor IX(7) ); -- end if; -- end process; -- -- -- -- Gen_CRC_OK: process(CRC_REG) begin if CRC_REG = residue then CRC_OK <= '1'; else CRC_OK <= '0'; end if; end process; -- Gen_Byte_Count: process -- set the strobe to even byte VARIABLE byte_cnt_tmp: vlbit_1d(2 downto 0); begin wait until ((BYTE_CLK'event and BYTE_CLK='1') or RST = '1'); byte_cnt_tmp := b"000"; if RST = '1' then -- SPARC reset byte_cnt <= b"00"; else -- if EN = '1' then -- past offset byte_cnt_tmp := ADDUM(byte_cnt, b"01"); byte_cnt <= byte_cnt_tmp(1 downto 0); end if; end if; end process; -- Gen_LW_STB: process(byte_cnt) -- this decodes the forth byte, registered output begin -- wait until (BYTE_CLK'event and BYTE_CLK='1'); if byte_cnt = b"11" then LW_STB <= '1'; else LW_STB <= '0'; end if; end process; -- -- end RTL_CRC32;