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

📄 recehdlc.vhd

📁 HDLC通信模块发送接收模块VHDL源码
💻 VHD
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity ReceHDLC is
	port (
		reset,clk			: in std_logic;
		DataIn				: in std_logic;
		DataByteValid		: buffer std_logic;		
		FrameEnd			: out std_logic;
		DataOut				: out std_logic_vector(7 downto 0);
		FrameLength			: buffer std_logic_vector(7 downto 0);	-- include CRC
		FrameQuality		: out std_logic_vector(2 downto 0)
	);
END ReceHDLC ;
architecture  ArchReceHDLC of ReceHDLC is
	signal DataSample					: std_logic;
	signal consecutive1Counter			: integer range 0 to 6;

	--count the number of bits in a byte
	signal DataBitCounter				: integer range 0 to 7;

	--count the number of bytes received
	signal DataByteCounter				: integer range 0 to 255;	

	signal DataBuffer					: std_logic_vector(7 downto 0);
	signal ProcessState					: std_logic_vector(2 downto 0);
	signal CounterBitSimple				: integer range 0 to 7;
	signal CRCData						: std_logic_vector(7 downto 0);
	signal CRCDataBitCounter			: integer range 0 to 8;
	signal CRCResult					: std_logic_vector(15 downto 0);
	
	constant CRC_Equ					: std_logic_vector(15 downto 0) :=TO_STDLOGICVECTOR(X"0810");
	begin
--*****************************************************************************************
-- clk'falling_edge  Sample Data
	process(reset,clk)	begin
		if(reset='0') then
			DataSample<='1';
		elsif falling_edge(clk) then
			DataSample<=DataIn;
		end if;
	end process;
--*****************************************************************************************
--shift data ,delete '0',count bits of a byte
	process(reset,clk) begin
		if(reset='0') then
			DataBitCounter<=0;
			DataBuffer<=TO_STDLOGICVECTOR(X"00");			
		elsif rising_edge(clk) then
			if(ProcessState="000") then
				DataBuffer<=TO_STDLOGICVECTOR(X"00");					
				DataBitCounter<=0;
			elsif(ProcessState="001") then
				if(consecutive1Counter=5 and DataSample='0') then
					DataBitCounter<=DataBitCounter; -- no change
				elsif(consecutive1Counter=6) then
					DataBitCounter<=0; -- when in "001"State,receive a flag
				elsif(consecutive1Counter/=6) then
					DataBuffer(7 downto 1)<=DataBuffer(6 downto 0);
					DataBuffer(0)<=DataSample;
					if(DataBitCounter=7) then
						DataBitCounter<=0;
					else DataBitCounter<=DataBitCounter+1;
					end if;
				end if;
			elsif(ProcessState="101") then
				DataBitCounter<=0;                     -- research
				DataBuffer(7 downto 1)<="0000000";			
				DataBuffer(0)<=DataSample;
			elsif(ProcessState="010") then
				if(consecutive1Counter=5 and DataSample='0') then
					DataBitCounter<=DataBitCounter; -- no change
				else
					DataBuffer(7 downto 1)<=DataBuffer(6 downto 0);
					DataBuffer(0)<=DataSample;
					if(DataBitCounter=7) then
						DataBitCounter<=0;
					else DataBitCounter<=DataBitCounter+1;
					end if;
				end if;
			end if;
		end if;
	end process;
--*****************************************************************************************
-- process state machine
	process(reset,clk) begin
		if(reset='0') then
			ProcessState<="000";
		elsif rising_edge(clk) then
			case ProcessState is
			when "000"=>
				if(consecutive1Counter=6 and DataSample='0') then
					ProcessState <="101";
				end if;
			when "101"=>
				ProcessState <="001";
			when "001"=>
				if(CounterBitSimple=6) then
					if((DataBuffer(6 downto 0)="0111111") and DataSample='0') then
						ProcessState <="101";
					elsif((DataBuffer(6 downto 0)="0111111") and DataSample='1') then
						ProcessState <="000";
					end if;
				elsif(CounterBitSimple=7) then
					if(DataBuffer(6 downto 0)=	"0111111") then
						if(DataSample='0' and consecutive1Counter=6) then --receive flag
							ProcessState <="101";
						elsif(DataSample='1' and consecutive1Counter=6) then  
							ProcessState <="000";	--receive abort sequence 
						elsif( DataSample='1'and consecutive1Counter=0 ) then 
							ProcessState <="000";	--7 consecutive '1' after flag
						elsif( DataSample='0'and consecutive1Counter=0 ) then 
							ProcessState <="101";	--6 consecutive '1'  and  '0 'after flag
						else
							ProcessState <="010";
						end if;
					else 	ProcessState <="010";
					end if;
				end if;
			when "010"=>
				if(consecutive1Counter=6) then
					if(DataSample ='0') then
						ProcessState <="011";
					else
						ProcessState <="100";		--receive abort sequence
					end if;
				elsif (DataByteCounter=255) then
						ProcessState <="110";		-- frame too long
				end if;
			when others =>
				ProcessState <="000";
			end case;
		end if;
	end process;
--*****************************************************************************************
--Output Data and DataByteValid
	process(reset,clk) begin
		if(reset='0') then
			DataOut<=TO_STDLOGICVECTOR(X"00");
			DataByteValid<=	'1';
		elsif rising_edge(clk) then
			if(ProcessState ="010") then
				if(DataBitCounter=7 and consecutive1Counter/=5) then
					for itemp in 7 downto 0 loop
						DataOut(itemp)<=DataBuffer(7-itemp);
					end loop;
					DataByteValid<='0';
				elsif(DataBitCounter=2) then
					DataByteValid<='1';
				end if;
			else 
				DataByteValid<='1';
			end if;
		end if;
	end process;
--*****************************************************************************************
--Calculate byte number and set frame end.
	process(reset,clk) begin
		if(reset='0') then
			DataByteCounter<=0;
			FrameEnd<='1';			
		elsif rising_edge(clk) then
			if(ProcessState ="010") then
				if(DataBitCounter=7) then
					if(consecutive1Counter=5 and DataSample='0') then	
					-- if data, five consecutive '1' followed by '0'
						DataByteCounter<=DataByteCounter;
					elsif(DataByteCounter=255) then
						DataByteCounter<=0;
					else 
						DataByteCounter<=DataByteCounter+1;
					end if;
				end if;
			else DataByteCounter<=0;
			end if;
			if(ProcessState="011" or ProcessState="100" or ProcessState="110" or ProcessState="000") then
				FrameEnd<='1';
			elsif(ProcessState="010") then
				FrameEnd<='0';
			end if;
		end if;
	end process;
--*****************************************************************************************
--calculate consecutive 1 number
	process(reset,clk)	begin
		if(reset='0') then
			consecutive1Counter<=0;
		elsif rising_edge(clk) then
			if(DataSample='1') then
				if(consecutive1Counter=6) then
					consecutive1Counter<=0;
				else consecutive1Counter<=consecutive1Counter+1;
				end if;
			else consecutive1Counter<=0;
			end if;
		end if;
	end process;
--*****************************************************************************************
--simply calculate  consecutive 1 number,not delete '0'
	process(reset,clk)	begin
		if(reset='0') then
			CounterBitSimple<=0;
		elsif rising_edge(clk) then
			if(CounterBitSimple=6) then
				if((DataBuffer(6 downto 0)="0111111") and DataSample='0') then
					CounterBitSimple<=0;
				else CounterBitSimple<=CounterBitSimple+1; 
				end if;
			elsif(CounterBitSimple =7 or ProcessState="000" or ProcessState="010") then
				CounterBitSimple <=0;
			elsif(ProcessState="101" or ProcessState="001" ) then
				CounterBitSimple <=CounterBitSimple+1;
			end if;
		end if;
	end process;
--*****************************************************************************************
--	Get Frame Length
	process(reset,clk)	begin
		if(reset='0') then
			FrameLength<=to_stdlogicvector(X"00");
		elsif falling_edge(clk) then
			if(ProcessState="011") then
				FrameLength<=conv_std_logic_vector(DataByteCounter,8);
			end if;
		end if;
	end process;
--*****************************************************************************************
-- Get source data to do CRC
	process(reset,clk) begin
		if(reset='0') then
			CRCData<=TO_STDLOGICVECTOR(X"00");	
			CRCDataBitCounter<=8;	
		elsif rising_edge(clk) then
			if(ProcessState ="010") then
				if( DataBitCounter=7 and consecutive1Counter/=5) then
					CRCData<=DataBuffer;
					CRCDataBitCounter<=0;
				elsif(CRCDataBitCounter/=8) then
					CRCDataBitCounter<=CRCDataBitCounter+1;
				end if;
			elsif(ProcessState ="101") then
				CRCData<=TO_STDLOGICVECTOR(X"00");		
				CRCDataBitCounter<=8;
			else 
				CRCDataBitCounter<=8;
			end if;
		end if;
	end process;
--*****************************************************************************************
--DO CRC work,and if CRC is not 0x1d0f, then take defeat
	process(reset,clk) 
		variable CRCDataTemp	:std_logic_vector(15 downto 0);
		variable iTemp			:std_logic;		
		variable i1				: integer range 0 to 7 ;
		--the lower bit which received is at DataBuffer high position ,so exchange
	begin
		if(reset='0') then
			CRCDataTemp	:=TO_STDLOGICVECTOR(X"ffff");
			iTemp	:='0';
			i1		:=0;
			CRCResult<=TO_STDLOGICVECTOR(X"0000");
		elsif falling_edge(clk) then
			if(ProcessState ="010" or ProcessState ="011") then
				if(CRCDataBitCounter<8) then
					i1:=7-CRCDataBitCounter;
					iTemp:=CRCData(i1) XOR CRCDataTemp(15);
					if(iTemp='1') then
						CRCDataTemp(15 downto 0):=CRCDataTemp(15 downto 0) XOR CRC_EQU(15 downto 0);
						CRCDataTemp	(15 downto 1):=CRCDataTemp	(14 downto 0);
						CRCDataTemp	(0):=iTemp;
						CRCResult<=CRCDataTemp;
					else
						CRCDataTemp	(15 downto 1):=CRCDataTemp	(14 downto 0);
						CRCDataTemp	(0):=iTemp	;
						CRCResult<=CRCDataTemp;
					end if;
				end if;
			elsif(ProcessState ="101") then
				CRCDataTemp	:=TO_STDLOGICVECTOR(X"ffff");
				iTemp	:='0';
				CRCResult<=TO_STDLOGICVECTOR(X"0000");
				i1:=0;
			end if;
		end if;
	end process;
--*****************************************************************************************
--Set Frame quality
	process(reset,clk) begin
		if(Reset='0') then
			FrameQuality<="000";
		elsif rising_edge(clk) then
			if(ProcessState="011") then
				if(FrameLength<to_stdlogicvector(X"06")) then
					FrameQuality<="001";
				elsif(FrameLength>=to_stdlogicvector(X"81")) then
					FrameQuality<="010";					
				elsif(CRCResult/=TO_STDLOGICVECTOR(X"1d0f")) then
					FrameQuality<="011";
				else
					FrameQuality<="000";
				end if;
			end if;
		end if;
	end process;
end  ArchReceHDLC ;

⌨️ 快捷键说明

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