entity crc_v4 is
Port ( clk,crc_send,busy : in std_logic; --crc_send is signal to give o/p
b_cnt_in : in integer range 0 to 256; --byte count of modbus frame
b_cnt_rqs,crc_done,read : out std_logic;--b_cnt_rqs is used to indicate to other module for byte count
data_in : in std_logic_vector(7 downto 0);
data_out : out std_logic_vector(7 downto 0));
end crc_v4;
architecture Behavioral of crc_v4 is
signal out_cnt : BIT := '0'; --to indicate sending of 2 bytes to output
signal newframe : BIT := '0'; --used to indicate a newframe 0-new 1-old frame
signal byte_count : integer range 0 to 256; -- stores byte count of the frame
type state_type is (s1,s2,s3,s4,s5,s6,s7);
signal state : state_type := s1;
begin
process(clk)
variable data : std_logic_vector(7 downto 0); --to store present byte
variable count : integer range 0 to 7:=0;--to count the shifts
variable CRC : std_logic_vector(15 downto 0) :=x"FFFF";--to store CRC value
variable new_byte : BIT :='0';
variable done : BIT :='0'; -- used to indicate that processing on 1 byte has been done
begin
case state is
when s1=>
if(busy = '0') then
b_cnt_rqs <='1';
newframe <= '1';
CRC := x"FFFF";
crc_done <='0';
state <= s2;
else
state <= s1;
end if;
when s2=>
if(busy='0') then
byte_count <= b_cnt_in;
b_cnt_rqs <= '0';
state <= s2;
else
state <= s3;
end if;
when s3 =>
if(byte_count =0) then
state <= s6;
else
if(busy ='0') then
read <='1';
state <= s4;
else
state <= s3;
end if;
end if;
when s4 =>
if(busy='0') then
data := data_in;
read <='0';
byte_count <= byte_count-1;
new_byte :='1';
done := '0';
CRC(15 downto 8) := CRC(15 downto 8);
CRC := CRC(7 downto 0) xor data;
state <= s5;
else
state <= s4;
end if;
when s5 =>
if(clk='1' and clk'event) then
if(count < 7) then
state <= s5;
CRC := '0' & CRC(15 downto 1);
if(CRC(0) = '1') then
CRC := CRC xor x"A001";
end if;
count := count+1;
elsif(count = 7) then
CRC := '0' & CRC(15 downto 1);
if(CRC(0) = '1') then
CRC := CRC xor x"A001";
end if;
done :='1';
count := 0;
new_byte := '0';
state <= s3;
end if;
end if;
when s6 =>
crc_done <='1';
if(crc_send ='1') then
state <= s7;
else
state <=s6;
end if;
when s7 =>
crc_done <= '0';
if(clk='1' and clk'event) then
if(out_cnt ='0') then
data_out <= CRC(7 downto 0);
out_cnt <= '1';
state <= s7;
else
data_out <= CRC(15 downto 8);
out_cnt <= '0';
newframe <= '0';
state <= s1;
end if;
end if;
when others =>
state <= s1;
end case;
end process;
end Behavioral;