View Single Post
  #7 (permalink)  
Old 05-26-2009, 09:40 PM
Mike Treseler
Guest
 
Posts: n/a
Default Re: Online tool that generates parallel CRC and Scrambler

Andreas Ehliar wrote:

> It is straight forward in Verilog as well.


I agree, other than filling in
that ... and so on... part.

Thanks for the posting.
You have cracked the code and discovered verilog variables.
I won't tell anyone

> This is taken from an Ethernet
> CRC32 module I wrote a long time ago:


I did it in vhdl with a compile time
constant table and a serial crc_shift function
overloaded for the parallel case something like:

begin
crc_v := crc; -- starting value
for i in data'range loop -- call serial shift below for each bit
-- left to right
crc_v := crc_shift(data(i), crc_v, crc_type);
end loop;
return crc_v;
end function crc_shift;


-- Mike Treseler








__________________________________________________
constant crc_table : crc_table_t := (
ppp32 => -- ethernet, hdlc, ppp, AAL5, fddi,
(
crc_len => 32,
poly_vec =>
(26|23|22|16|12|11|10|8|7|5|4|2|1|0 => '1', others => '0'),
crc_init => (others => '1'),
remainder => x"c704_dd7b"
), ...
__________________________________________________ ___
-- Base serial shifter, all of the other crc_shifts end up here
-- This gets called n times for the parallel versions above
function crc_shift -- Serial in, unsigned return
( data : in std_ulogic; -- input bit
crc : in unsigned; -- crc starting value
crc_type : in crc_t
)
return unsigned is
variable crc_v : unsigned(crc'range); -- CRC register
constant reg_len : natural :=
crc_table(crc_type).crc_len; -- look up length
subtype crc_vec is unsigned(reg_len-1 downto 0);
-- chop table poly to length
constant mask : crc_vec :=
crc_table(crc_type).poly_vec(crc_vec'range);
begin
crc_v := crc sll 1; -- shift it
if (crc(crc'left) xor data) = '1' then
-- maybe invert mask bits
crc_v := crc_v xor mask;
end if;
return unsigned(crc_v);
-- returns whole register each shift
end function crc_shift;

Reply With Quote