⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crc16.vhd

📁 无线耳机通讯用CPLD的VHDL源码
💻 VHD
字号:
--  File: crc16.vhd
--{entity {crc16} architecture {crc16}}

library IEEE;
use IEEE.std_logic_1164.all;
use work.PCK_CRC16_D8.all;

entity CRC16 is										   
	port (
		DATA: in STD_LOGIC_VECTOR (7 downto 0);
		WR: in STD_LOGIC;
		RD: in STD_LOGIC;	
		ENABLE: in STD_LOGIC;
		WRITE_CRC_EN: in std_logic;			  -- tells CRC_OUT to reset result ready because tx finished reading the results
		CRC_OUT: buffer STD_LOGIC_VECTOR (15 downto 0);
		RESULT_READY: out std_logic;
		CLK: in STD_LOGIC;
		RX_TX: in STD_LOGIC;
		CRC_RX_RESULT : out STD_LOGIC_VECTOR (7 downto 0);
		IGNORE_DATA: out STD_LOGIC;
		RESET: in STD_LOGIC
	);
end CRC16;



architecture CRC16 of CRC16 is

signal data_in : std_logic_vector ( 7 downto 0);   -- data bus
signal tx_flag :std_logic; 						   -- '1' signal new write cycle begun
signal rx_flag :std_logic; 						   -- '1' signal new read cycle begun
signal tx_start_crc_flag  : std_logic; 			   -- '1' new Tx calculation begun
signal rx_start_crc_flag  : std_logic; 			   -- '1' new Rx calculation begun
signal preamble_skip :integer range 3 downto 0;	   -- '0' means we need to skeep the first write (it is preamble)
signal crc_count :integer range 7 downto 0;		   -- read  cycle counter 


begin 
	

 
   process (CLK, RESET)
   	  variable crc_state : std_logic_vector(1 downto 0);
   begin
	
	
	
   	if RESET='1' then	--asynchronous RESET active High
   		CRC_OUT <= (others => '0');
		data_in <= (others => '0'); 
		rx_flag <= '0';	 
		tx_flag <= '0';	
		result_ready <= '0'; 
		rx_start_crc_flag <= '0';
		tx_start_crc_flag <= '0';
		preamble_skip <= 0;
		crc_count <= 0;
		crc_rx_result <= (others => '0');
		IGNORE_DATA <= '0';
		
   	elsif (CLK'event and CLK='1') then 
 
-- when transmitter finished reading the Tx CRC_OUT result he clears write_crc_enable
-- for 1 clock period ,when it happens we clear CRC_OUT register and result ready 
	
		crc_state := enable & RX_TX;
	
 		if write_crc_en = '0' then	
			result_ready <= '0';
			CRC_OUT <= (others => '0');
		end if;

-- 	these states reflects the CRC_ENABLE and RECEIVE port of the logic
-- 	1.  "10"  in this state we perform CRC_OUT calaularion on transmitted data
--		and store the result in a 16 bit register.
--	2.	"00"  in this state if we came from the previous state we sets result ready
-- 		for the Tx block and clear all flags for the next time.
--	3.	"11" in this state we calculate CRC_OUT for incoming packet, every read cycle 
-- 		by the cpu generate a new check.and store the result in a 16 bit register.
-- 	4.	"01" 	in this state we transfer the result to the cpu, in two cycles
--		first the low CRC_OUT then the high CRC_OUT. we implement a read_cycle_counter that
-- 		help us to ignore the CRC_OUT data of the incoming packet from our CRC_OUT calculation,
--		and to put out on the bus our result in the apropriate time. to do so we need from the
--      cpu to clear the CRC_ENABLE before the CRC_OUT data of the incoming packet is 
--		loaded to the system, the cpu reads the result we clear the CRC_OUT register and the flags

		case crc_state is	
		  
		  when "11" => 
		  
		   	if tx_start_crc_flag ='0' then
			  	CRC_OUT <= (others => '0');
			  	tx_start_crc_flag <= '1';
			end if;
			
			if preamble_skip = 2 then
				
			  if (wr='1' and tx_flag='0') then 
					data_in <= data;
		   			tx_flag <= '1';
		   		elsif (wr='0' and tx_flag='1') then
					CRC_OUT <= nextcrc16_d8(data_in,CRC_OUT);
					tx_flag <= '0';
		   		end if;
				
			 	
			else 
				
				if (wr='1' and tx_flag='0') then	  
					tx_flag <= '1';   
				elsif (wr='0' and tx_flag='1') then
					preamble_skip <=preamble_skip+1;
					tx_flag <= '0';	
				end if;	
		 		
		 	end if;
			 
			 
		  when "01" =>	
		  
		  	if tx_start_crc_flag = '1' then
			  	result_ready <= '1';
		  		tx_start_crc_flag <= '0';
				tx_flag <= '0';
				preamble_skip <=0;
			end if;	
				
				
		  when "10" => 
		  
		  	if rx_start_crc_flag ='0' then
			  	CRC_OUT <= (others => '0');
			  	rx_start_crc_flag <= '1';
				crc_count <= 0;
				IGNORE_DATA <= '0';	
			end if;
		  
		  	if (rd='1' and rx_flag='0' ) then 
				data_in <= data;
		   		rx_flag <= '1';
		   	elsif (rd='0' and rx_flag='1') then
				CRC_OUT <= nextcrc16_d8(data_in,CRC_OUT);
				rx_flag <= '0';
		   	end if;
		  
		  		  
		   
		  when "00" =>
		  
		if(rd = '1' and crc_count =0 ) then 
			crc_count <= crc_count+1;	
		end if;
		
		if (rd = '0' and crc_count =1) then	  -- first read end	of crc-low of rcv pkt
			crc_count <= crc_count+1;
		end if;
		
		if (rd = '1' and crc_count =2) then
			crc_count <= crc_count+1;
		end if;	
		
		if (rd = '0' and crc_count =3) then	  -- second read end of crc-high of rcv pkt
			crc_count <= crc_count+1;
		
		end if;
		
		if(rd = '1' and crc_count =4 ) then 
			crc_count <= crc_count+1;	
		end if;
		
		if (rd = '0' and crc_count =5) then	  -- end of reading  of the low CRC_OUT result
			crc_count <= crc_count+1;
		end if;
		
		if (rd = '1' and crc_count =6) then	
			crc_count <= crc_count+1;
		end if;	
		
		if (rd = '0' and crc_count =7) then	  -- end of reading  of the high CRC_OUT result
			crc_count <= 0;	
			rx_flag <= '0';  
		  	rx_start_crc_flag <= '0';
			IGNORE_DATA <= '0';
			CRC_OUT <= (others => '0');
		end if;
		
		
		if (rx_start_crc_flag = '1')  then
			   			
				case crc_count is		
				   					
					 when 4 => 
					 	crc_rx_result	<= CRC_OUT( 7 downto 0);
					 	IGNORE_DATA <= '1';
					 when 6 => 
						 crc_rx_result	<= CRC_OUT( 15 downto 8);  
					 when others => null; 
				end case;	
	
		end if;
		
			when others => null; 
		  
		end case;
   	end if;
   end process;
end CRC16;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -