📄 recehdlc.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 + -