Electronics 版 (精华区)

发信人: Scout (沙丘魔堡), 信区: Electronics
标  题: 正式发布HDLC的VHDL源代码.
发信站: 哈工大紫丁香 (Wed Apr 21 21:55:40 2004), 站内信件

前半部分是encoder,
后半部分是decoder.
好好享用吧.
--===========================================================================-
-
-- Design units : HDLC encoder (Entity and architecture)
--
-- File name    : hdlcenc.vhd
--
-- Purpose      : HDLC encoder (bitstuffing and flag generation)
--
-- Note         : NON-COMMERCIAL USAGE ONLY
--
-- Limitations  :
--
-- Errors       :
--
-- Library      :
--
-- Dependencies :
--
-- Author       : Juergen Hasch, hasch@t-online.de
--                Meisenstr. 23
--                73066 Uhingen
--                Germany
--
-- Synthesis    : Xilinx foundation F1.4
------------------------------------------------------------------------------
-
-- Revision list
-- Version Author Date       Changes
-- 1.0     JH     28 Mar 98  File created
-- 1.1     JH     29 Mar 98  Stripped HDLC encoding, only raw data is output n
ow
-- 1.2     JH     11 Apr 98  added ram access control
-- 
------------------------------------------------------------------------------
-

Library ieee;
Use ieee.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
--use IEEE.converters.all;

entity hdlc_enc is
  port(
    reset:    in  std_logic;
    din:      in  std_logic_vector(7 downto 0);     -- data input
    clock:    in  std_logic;                        -- bit clock
    clock2:   in  std_logic;                        -- master clock
    dataout:  out std_logic;                        -- data output
    empty:    in  std_logic;
    rdok:     in  std_logic;
    rdreq:    out std_logic);                      -- flag to get new data
end hdlc_enc;


architecture behaviour of hdlc_enc is
  signal counter: std_logic_vector(2 downto 0);
  signal shift_reg: std_logic_vector(7 downto 0);
  signal data: std_logic_vector(7 downto 0);
  signal clrreq: std_logic;
begin

--
-- request new data
--
process(reset,rdok,empty,clock,clrreq)
begin
  if (clrreq='1') then
    rdreq <= '0'; 
  elsif (clock'event and clock='1' ) then
    if (counter="110" and empty='0') then
      rdreq <= '1';
    end if;  
  end if;
end process;

--
-- clear data request
--
process(reset,rdok,empty,clock,clock2,counter)
begin
  if (counter="100") then
    clrreq <= '0'; 
  elsif (clock2'event and clock2='1' ) then
    if (rdok='1') then
      clrreq<='1';
      data <= din;
    end if;
  end if;
end process;
 
--
-- put data in shift register and shift out register
--
process(reset,clock,clock2,shift_reg,counter,rdok,din)
begin

  if (reset='1') then
    shift_reg <= (others => '0');
    dataout <='0';
  elsif (clock'event and clock='1') then
    dataout <= shift_reg(0); 
    if (counter = "111" ) then
      shift_reg <= data;
    else    
      shift_reg(0) <= shift_reg(1);
      shift_reg(1) <= shift_reg(2);
      shift_reg(2) <= shift_reg(3);
      shift_reg(3) <= shift_reg(4);
      shift_reg(4) <= shift_reg(5);
      shift_reg(5) <= shift_reg(6);
      shift_reg(6) <= shift_reg(7);
      shift_reg(7) <= shift_reg(0);
    end if;
  end if;
end process;

--
-- tx bit counter
--
process(reset,counter,clock)
  begin
  if (reset='1') then
      counter <= "000";
  elsif (clock'event and clock='1') then
    counter <=counter+1;
  end if;
end process;

end behaviour;
--========================= End of rxctrl ================================--



--===========================================================================-
-
-- Design units : HDLC decoder (Entity and architecture)
--
-- File name    : hdlcdec.vhd
--
-- Purpose      : HDLC decode (bitstuffing and flag detection)
--                write data to ram, add frame length
--
-- Note         :
--
-- Limitations  :
--
-- Errors       :
--
-- Library      :
--
-- Dependencies :
--
-- Author       : Juergen Hasch, hasch@t-online.de
--                Meisenstr. 23
--                73066 Uhingen
--                Germany
--
-- Synthesis    : Xilinx Foundation 1.4
------------------------------------------------------------------------------
-
-- Revision list
-- Version Author Date       Changes
-- 1.0     JH     28 Dec 97  File created
-- 1.1     JH     19 Apr 98  included rx controller
-- 1.2     JH     24 May 98  simplified hdlc decoding
-- 1.3     JH     31 Jul 98  partial redesign
------------------------------------------------------------------------------
-

Library ieee;
Use ieee.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

entity hdlcdec is
  port(
      mclk:     in     std_logic;                     -- master clock (64*bit 
clock)
      frameavl: out    std_logic;                     -- frame available
      wrreq:    buffer std_logic;                     -- ram write request
      wrok:     in     std_logic;                     -- write finished
      dataout:  out    std_logic_vector(7 downto 0);  -- data output
      rxaddr:   buffer std_logic_vector(11 downto 0); -- ram address
      eppaddr:  in     std_logic_vector(11 downto 0); -- epp read address
      dcd:      in     std_logic;                     -- dcd signal from dpll

      data_in:  in     std_logic;                     -- data input
      clock:    in     std_logic;                     -- bit clock
      dcd_clr:  buffer std_logic);                    -- clear dcd for 8 recei
ved ones
end hdlcdec;

architecture behaviour of HDLCDEC is
  signal crc: std_logic;                              -- 1 for rx crc ok
  signal flag_received: std_logic;                    -- hdlc flag received
  signal abort_received: std_logic;                   -- hdlc abort received

  signal raw_shift:  std_logic_vector(7 downto 0);    -- shift register for ra
w data
  signal X:  std_logic_vector(15 downto 0);           -- crc shift register
  signal address: std_logic_vector(11 downto 0);    -- msb frame start pointer

  signal rx_counter: std_logic_vector(8 downto 0);    -- received bytes in fra
me, truncates more than 512 byte
  signal bit_counter: std_logic_vector(2 downto 0);   -- count until one rx by
te complete
  signal disable_transfer: std_logic;  
  signal crc_shift : std_logic_vector( 7 downto 0);
  
signal tmp: std_logic;
begin

frameavl <= '1' when ( (address+1) = eppaddr) else '0';    -- frame available 
flag

--
-- shift in serial rx data
--
process(dcd,clock,data_in,flag_received,bit_counter)
begin
    if (clock'event and clock='1') then
      dataout <= raw_shift;
      raw_shift(7) <= data_in;
      raw_shift(6) <= raw_shift(7);
      raw_shift(5) <= raw_shift(6);
      raw_shift(4) <= raw_shift(5);
      raw_shift(3) <= raw_shift(4);
      raw_shift(2) <= raw_shift(3);
      raw_shift(1) <= raw_shift(2);
      raw_shift(0) <= raw_shift(1);
    end if;
end process;

--
-- check for HDLC flag ( 6 ones, 2 zeroes)
--
process(raw_shift,mclk)
begin
  if(mclk='1' and mclk'event) then
    if ( raw_shift = "01111110") then
      flag_received <= '1';
    else
      flag_received <= '0';
    end if;
  end if;
end process;

--
-- check for ABORT flag (7 ones, 1 zero)
--
process(raw_shift,mclk)
begin
  if(mclk='1' and mclk'event) then
    if ( raw_shift = "11111110") then
      abort_received <= '1';
    else
      abort_received <= '0';
    end if;
  end if;
end process;

--
-- check for 8 trailing ones (illegal state, clear DCD)
--
process(raw_shift,mclk)
begin
  if(mclk='1' and mclk'event) then
    if ( raw_shift = "11111111" and dcd_clr <='0') then
      dcd_clr <= '1';
    else
      dcd_clr <= '0';
    end if;
  end if;
end process;

--
-- compute CRC
--
process(clock,data_in,raw_shift,flag_received)
begin
   if (flag_received = '1') then
     X <= (others => '1');
   elsif (clock'event and clock='1') then
     if (not(raw_shift(7 downto 3)="11111") ) then     -- remove bitstuffing f
or 5 trailing ones
       tmp <= data_in; --raw_shift(3);
       X(0) <= tmp xor X(15);
       X(1) <= X(0);
       X(2) <= X(1);
       X(3) <= X(2);
       X(4) <= X(3);
       X(5) <= X(4) xor tmp xor X(15);
       X(6) <= X(5);
       X(7) <= X(6);
       X(8) <= X(7);
       X(9) <= X(8);
       X(10) <= X(9);
       X(11) <= X(10);
       X(12) <= X(11) xor tmp xor X(15);
       X(13) <= X(12);
       X(14) <= X(13);
       X(15) <= X(14);
     end if;
   end if;
end process;

--
-- compare crc register to crc value of a correct received frame
--
process(X,clock,dcd,mclk,wrok)
  begin
  if ( dcd='0') then
    crc <= '0';
  elsif (clock'event and clock='1' ) then
    if  X = "0001110100001111" then
      crc_shift(0) <= '1';
    else
      crc_shift(0) <= '0';
    end if;
      crc <= crc_shift(5);
      crc_shift(7) <= crc_shift(6);
      crc_shift(6) <= crc_shift(5);
      crc_shift(5) <= crc_shift(4);
      crc_shift(4) <= crc_shift(3);
      crc_shift(3) <= crc_shift(2);
      crc_shift(2) <= crc_shift(1);
      crc_shift(1) <= crc_shift(0);
  end if;
end process;

--
-- received bits counter (count from 0..7)
--
process(clock,flag_received)
begin
--  if (flag_received = '1') then
--    bit_counter <= (others => '0');
  if (clock'event and clock='1') then
    if (flag_received = '1') then
      bit_counter <= (others => '0');    
    else  
      bit_counter <= bit_counter+1;
    end if;
  end if;
end process;

--
-- initiate transfer to ram
--
process(bit_counter,disable_transfer,clock)
begin
  if (disable_transfer='1') then
    wrreq <= '0';
  elsif (clock'event and clock='0' ) then
    if (bit_counter = 0 ) then
      wrreq <='1';
    else
      wrreq <='0';
    end if;
  end if;
end process;

--
-- stop transfer to ram
--
process(wrok,mclk,dcd)
begin
  if (dcd='0') then
    disable_transfer <='1';  -- no data transfer when no rx signal
  elsif (mclk'event and mclk='1' ) then
    disable_transfer <= wrok; -- stop transfer as soon as ram controller ackno
wledges
  end if;
end process;

--
-- increase frame byte counter
--
process(clock,rx_counter,flag_received,bit_counter)
begin
--  if (flag_received='1') then 
--      rx_counter <= (others => '0');  
  if (clock'event and clock='1' ) then
    if (flag_received = '1') then
      rx_counter <= (others => '0');
    elsif (bit_counter=0) then
      rx_counter <= rx_counter+1;
    end if;
  end if;
end process;

--
-- set rx address
--
process(mclk,address,rx_counter)
begin
  if (mclk'event and mclk='1' ) then
--    rxaddr <= (address(11 downto 9) & ( address(8 downto 0) + rx_counter));

    rxaddr <= address + rx_counter;        
  end if;
end process;

--
-- calculate new address after frame received
--
process(clock,crc,flag_received)
begin
  if (clock'event and clock='1' ) then
    if (flag_received ='1' and crc = '1') then
      address <= rxaddr;
    end if;
  end if;
end process;

end behaviour;
--========================= End of hdlc_dec ================================--




--
只见工大主楼咔咔几下变身成为一个巨大的机器人,
骂了一句"丫的",拍拍屁股走了.
http://www.pofen.com/UploadFiles/20043190827471.jpg

※ 来源:.哈工大紫丁香 bbs.hit.edu.cn [FROM: 218.7.28.35]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:203.683毫秒