-- ****************************************************************************
--版权所有:www.eeleader.com------------------------------------------------------------
--设计日期:2010.3.4--------------------------------------------------------------------------------
--设计人 :eeleader------------------------------------------------------------------------------------
--文件名 : Crc_Gen.vhd-------------------------------------------------------------------------
--顶层模块:Crc_Gen.Vhd--------------------------------------------------------------------------------
--模块名称:Crc_Gen-----------------------------------------------------------------------------
--模块功能:对输入的数据进行CRC校验,校验等式X15+X13+1--------------------------------------------------
--模块说明:输入数据有效,通过Data_En 高脉冲(宽度一个系统时钟脉冲);输出数据,通过Crc_Rdy高脉冲(宽度一个系统时钟脉冲)
-- 参数说明:D_Width表示输入数据的位数,Byte_Num:表示输入数据的字节数
--修改记录:无
---**************************************************************************************************
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY Crc_Gen IS
GENERIC (D_Width: POSITIVE:=8;Byte_Num:POSITIVE:=8;Module_En:STRING:="Enable");
PORT
(
Clk : IN STD_LOGIC;
Rst : IN STD_LOGIC;
Data_In: IN STD_LOGIC_VECTOR (D_Width-1 DOWNTO 0);
Data_En: IN STD_LOGIC;
Crc_Out: OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
Crc_Rdy: OUT STD_LOGIC
);
END Crc_Gen;
ARCHITECTURE Arch_Crc_Gen OF Crc_Gen IS
TYPE Comp_Crc_State_Type IS (Idle,Crc_Comp,Shift);
SIGNAL Comp_Crc_State: Comp_Crc_State_Type;
SIGNAL Comp_Crc_Data_In_Reg :STD_LOGIC_VECTOR (D_Width-1 DOWNTO 0);
BEGIN
Crc_Gen:IF (Module_En="Enable")GENERATE
Comp_Crc: PROCESS (Clk,Rst)
VARIABLE Comp_Crc_Result:STD_LOGIC_VECTOR(15 DOWNTO 0);
VARIABLE Comp_Crc_Data_Reg:STD_LOGIC_VECTOR(7 DOWNTO 0);
VARIABLE Comp_Crc_Flag:STD_LOGIC;
VARIABLE Comp_Crc_Cnt: INTEGER RANGE 0 TO Byte_Num;
BEGIN
IF(Rst='1') THEN
Crc_Out<=(OTHERS=>'0') ;
Crc_Rdy<='0';
Comp_Crc_Data_In_Reg<=(OTHERS=>'0');
Comp_Crc_Result:=(OTHERS=>'1');
Comp_Crc_Data_Reg:=(OTHERS=>'1');
Comp_Crc_Flag:='0';
Comp_Crc_Cnt:=Byte_Num;
Comp_Crc_State<=Idle;
ELSIF Clk'EVENT AND Clk='1' THEN
CASE Comp_Crc_State IS
WHEN Idle=>
Crc_Rdy<='0';
Comp_Crc_Result:=(OTHERS=>'1');
IF (Data_En='1') THEN
Comp_Crc_State<=Crc_Comp;
Comp_Crc_Data_In_Reg<=Data_In;
END IF;
WHEN Crc_Comp=>
Comp_Crc_Data_Reg:=Comp_Crc_Data_In_Reg(7 DOWNTO 0);
Comp_Crc_Result:=Comp_Crc_Result XOR Comp_Crc_Data_Reg(7 DOWNTO 0);
FOR i IN 0 TO 7 LOOP
Comp_Crc_Flag:=Comp_Crc_Result(0);
Comp_Crc_Result:='0'& Comp_Crc_Result(15 DOWNTO 1);
IF (Comp_Crc_Flag='1') THEN
Comp_Crc_Result:=Comp_Crc_Result XOR x"a001";
END IF;
END LOOP;
Comp_Crc_Cnt:=Comp_Crc_Cnt-1;
Comp_Crc_State<=Shift;
WHEN Shift=>
IF (Comp_Crc_Cnt=0) THEN
Crc_Rdy<='1';
Comp_Crc_State<=Idle;
Crc_Out<=Comp_Crc_Result;
ELSE
Comp_Crc_State<=Crc_Comp;
Comp_Crc_Data_In_Reg<=X"00" & Comp_Crc_Data_In_Reg(D_Width-1 DOWNTO 8);
END IF;
WHEN OTHERS=>
Comp_Crc_State<=Idle;
Crc_Rdy<='0';
END CASE;
END IF;
END PROCESS Comp_Crc;
END GENERATE Crc_Gen;
END Arch_Crc_Gen;