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毫秒