library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
package crc_package is
function crc_shift
-- Mike Treseler
-- parallel data version
(constant X_load : in unsigned (15 downto 0);
constant D_vec : in unsigned (15 downto 0);
constant Poly : in unsigned := x"3223") --Poly_16_12_5)
return unsigned (15 downto 0);
end package crc_package;
package body crc_package is
function crc_shift0
-- Mike Treseler
-- serial data version, see overload for parallel data below
-- Purpose : Single bit shift for a CRC register using any polynomial.
-- Inputs : X_load : Current CRC vector.
-- D_bit : Data to shift into CRC vector.
-- Poly : CRC polynomial. Default is Frame Relay.
--
-- Outputs : CRC vector after CRC shift.
(
constant X_load : in unsigned; -- register start value
constant D_bit : in std_ulogic := '0'; -- input bit
constant Poly : in unsigned := x"3223" --Poly_16_12_5 -- poly bits
)
return unsigned is
variable X_out : unsigned(X_load'range); -- CRC register
begin ----------------------------------------------------------------------
-- we assume that X and Poly are in downto format
-- to match the textbook definition of LSFR
-- and to match the CCITT FCS bit assigments
-- for frame relay, note that X(15) becomes the lsb of octet n-2
-- and that X(7 ) becomes the lsb of octet n-1
----------------------------------------------------------------------
-- Procedure: Left shift a '0' into the current X0
-- and the previous X(14) into the current X15 etc.
-- if the original X15 is '1' or the data is '1'
-- but not both, then invert the poly bit locations
----------------------------------------------------------------------
-- Sample Invocation:
-- crc_shift( "0001000100010001", '1'));
-- SLL 0010001000100010 -- shift the variable
-- D (not X15) [ ! ! !] -- invert poly locations?
-- expect("shift1 0011001000000011"); -- expected result
----------------------------------------------------------------------
assert X_load'length = Poly'length
report "crc_shift: Vectors X_load and Poly must be of equal length."
severity error;
X_out := X_load sll 1;
if (X_load(X_load'left) xor D_bit) = '1' then
X_out := X_out xor Poly;
end if;
return unsigned(X_out); -- returns each shift
end function crc_shift0;
-----------------------------------------------
function crc_shift
-- Mike Treseler
-- parallel data version
(constant X_load : in unsigned (15 downto 0);
constant D_vec : in unsigned (15 downto 0);
constant Poly : in unsigned := x"3223") --Poly_16_12_5)
return unsigned is
variable X_out : unsigned(X_load'range);
begin
X_out := X_load;
for I in D_vec'range loop -- call serial version for each bit
X_out := crc_shift0(X_out, D_vec(I), Poly);
end loop;
return X_out;
end function crc_shift;
end package body crc_package;
library IEEE;
use IEEE.std_logic_1164.all;
use WORK.crc_package.all;
entity tb is
end tb;
architecture structural of tb is
signal internal_carry : std_logic;
signal sum1: unsigned (15 downto 0);