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

📄 mii_proc.vhd

📁 MII接口1转2处理
💻 VHD
字号:
--Ethernet processing module for H9mo60B
-- by xikang
-- 2003-6-6

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;


entity MII_Proc is
port
(
      MII_ParDat_out : out std_logic_vector(7 downto 0) ;
      MII_ParEN_out : out std_logic ;
      MII_ParClk_out : out std_logic ;					-- use rising_edge to send the data
      MII_ParDat_in : in std_logic_vector(7 downto 0) ;
      MII_ParEN_in : in std_logic ;
      MII_SerDat_in : in std_logic_vector(3 downto 0) ;
      MII_SerEN_in : in std_logic ;
      MII_SerClk_in : out std_logic ;
	  MII_SerERR_in : in std_logic ;
      MII_SerDat_out : out std_logic_vector(3 downto 0) ;
      MII_SerEN_out : out std_logic ;
      MII_SerClk_out : out std_logic ;
	  MII_SerERR_out : out std_logic ;
	  MII_crs : out std_logic ;
	  MII_col : out std_logic ;
	  MII_link : out std_logic ;
	  Serdes_syn : in std_logic ;
	  Opt_LOS : in std_logic ;
      clk_50M : in std_logic ;
	  clk_25M : in std_logic ;
	  rxclken	: in std_logic;
	  clk_12m5 : in std_logic ;
	  rate		: in std_logic_vector( 6 downto 0 );
	  test		: in std_logic;
	  err		: out std_logic;
	  rxpkcnt 	: out std_logic_vector(15 downto 0) ;
	  txpkcnt 	: out std_logic_vector(15 downto 0) ;
	  clr_rxpkcnt : in std_logic;
	  clr_txpkcnt : in std_logic;
	  reset : in std_logic 
);
end MII_Proc;

architecture MII_Proc_Arch of MII_Proc is

signal wren			: std_logic;
signal byte_in		: std_logic_vector(7 downto 0);
signal part2		: std_logic;
signal MII_SerEn_in_d : std_logic;
signal iMII_ParDat_out : std_logic_vector(7 downto 0) ;

signal gapcnt		: integer range 0 to 31;

signal irxpkcnt 	: std_logic_vector(15 downto 0) ;
signal itxpkcnt 	: std_logic_vector(15 downto 0) ;

component bucket IS
	port 
	( 	reset 	: in std_logic;
		clk 	: in std_logic;
		rate	: in std_logic_vector( 6 downto 0 );
		usage	: in std_logic;
		nocredit: out std_logic
	);
END component;

component myfifo
	PORT
	(
		data		: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
		wrreq		: IN STD_LOGIC ;
		rdreq		: IN STD_LOGIC ;
		clk			: IN STD_LOGIC ;
		aclr		: IN STD_LOGIC ;
		full		: out STD_LOGIC ;
		empty		: out STD_LOGIC ;
		usedw		: out STD_LOGIC_VECTOR( 4 downto 0 );
		q		: OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
	);
end component;

component ethtest
	PORT
	(
		reset		: IN STD_LOGIC ;
		clk			: IN STD_LOGIC ;
		txclken		: IN STD_LOGIC ;
		txdat		: out STD_LOGIC_VECTOR (7 DOWNTO 0);
		txen		: out STD_LOGIC ;
		rxclken		: IN STD_LOGIC ;
		rxen		: IN STD_LOGIC ;
		rxdat		: in STD_LOGIC_VECTOR (7 DOWNTO 0);
		err			: out STD_LOGIC 
	);
end component;

signal wrfifo	: std_logic;
signal nearfull : std_logic;
signal paren_in1: std_logic;
signal pardat_in1: std_logic_vector(7 downto 0);
signal rdfifo	: std_logic;
signal rdfifo1	: std_logic;
signal rdfifo2	: std_logic;
signal aclr		: std_logic;
signal full		: std_logic;
signal empty	: std_logic;
signal byte_out	: std_logic_vector( 7 downto 0 );
signal usedw	: std_logic_vector( 4 downto 0 );
signal rdts		: std_logic;
signal seren_out: std_logic;
signal serdat_out: std_logic_vector( 3 downto 0 );
signal paren_out: std_logic;
signal fifo_ready : std_logic;
signal pklen	: std_logic_vector( 2 downto 0 );

signal nocredit	: std_logic;

signal txdat_test : std_logic_vector( 7 downto 0 );
signal txen_test : std_logic;
signal tmperr	 : std_logic;

begin

rxpkcnt		    <= ( others => '0' ) when test = '1' else irxpkcnt;	
txpkcnt		    <= ( others => '0' ) when test = '1' else itxpkcnt;	
MII_ParDat_out	<= txdat_test when test = '1' else iMII_ParDat_out;
MII_ParEn_out	<= txen_test  when test = '1' else paren_out;
err 			<= tmperr and test;

U_ETHTEST : ethtest port map
(	
		reset		=> reset,
		clk			=> clk_25m,
		txclken		=> clk_12m5,
		txdat		=> txdat_test,
		txen		=> txen_test,
		rxclken		=> rxclken,
		rxdat		=> MII_ParDat_in, 
		rxen		=> MII_ParEN_in, 
		err			=> tmperr
);


MII_link 		<= Opt_LOS ;
MII_crs   		<= seren_out; --not Opt_LOS ;
MII_col 		<= '0' ;
MII_SerERR_out 	<= '0' ;
MII_ParClk_out 	<= clk_12m5;

----------------------------------------------------------------------------
-- MII ==> Optical Channel

MII_SerClk_in		<= clk_25M;
proc_tx_to_Optical: process( clk_25M, reset ) 
begin
	if( rising_edge( clk_25M ) ) then

		if( clr_rxpkcnt = '1' ) then
			irxpkcnt <= ( others => '0' );
		elsif( MII_SerEn_in_d = '0' ) and ( MII_SerEn_in = '1' ) then
			irxpkcnt <= irxpkcnt + '1';
		end if;

		MII_SerEn_in_d <= MII_SerEn_in;

		if( MII_SerEN_in = '1' ) then
			part2 <= not part2;
			if( part2 = '1' ) then
				if( clk_12m5 = '1' ) then
					iMII_ParDat_out( 7 downto 4 ) <= byte_in( 7 downto 4 );
					iMII_ParDat_out( 3 downto 0 ) <= MII_SerDat_in(0) & MII_SerDat_in(1) & MII_SerDat_in(2) & MII_SerDat_in(3);
					paren_out <= '1';
				end if;
				
				byte_in( 3 downto 0 ) <= MII_SerDat_in(0) & MII_SerDat_in(1) & MII_SerDat_in(2) & MII_SerDat_in(3);
			else
				if( clk_12m5 = '1' ) then
					iMII_ParDat_out <= byte_in;
					paren_out 		<= MII_SerEn_in_d;
				end if;

				byte_in( 7 downto 4 ) <= MII_SerDat_in(0) & MII_SerDat_in(1) & MII_SerDat_in(2) & MII_SerDat_in(3);
			end if;
		else
			if( clk_12m5 = '1' ) then
				iMII_ParDat_out <= byte_in;
				paren_out 		<= MII_SerEn_in_d;
			end if;
			part2 <= '0';
		end if;
	end if;

	if( reset = '0' ) then
		iMII_ParDat_out	<= ( others => '0' );
		irxpkcnt		<= ( others => '0' );
		byte_in			<= ( others => '0' );
		paren_out		<= '0';
		part2			<= '0';
	end if;
end process;

----------------------------------------------------------------------------
-- Optical Channel ==> MII 


U_FIFO: myfifo port map 
	(
		data 	=> pardat_in1,
		wrreq	=> wrfifo,
		rdreq	=> rdfifo,
		clk		=> clk_25M,
		aclr	=> aclr,	
		full	=> full,
		empty	=> empty,
		usedw	=> usedw,
		q		=> byte_out
	);

MII_SerClk_out		<= clk_25M;
MII_SerEn_out		<= seren_out;
MII_SerDat_out		<= serdat_out;
nearfull			<= '1' when usedw(4 downto 1) = "1111" else '0';

U_BUCKET : bucket 
	port map
	( 	reset 	=> reset,
		clk 	=> clk_25M, 
		rate	=> rate, 
		usage	=> rdfifo, 
		nocredit=> nocredit
	);

proc_rx_from_optical: process( clk_25M, reset )
begin
	if rising_edge( clk_25M ) then
		
		------------------------------------------------------------------
		--- fifo write control
		aclr <= '0';

		if( rxclken = '1' ) then

			paren_in1	<= MII_ParEn_in;
			pardat_in1	<= MII_ParDat_in;
			if( MII_ParEn_in = '1' ) then
				if( pklen /= "100" ) then
					pklen <= pklen + 1;
				end if;
				if( paren_in1 = '0' ) then
					-- packet head
					if( empty = '0' ) or ( Serdes_syn = '1' ) or ( Opt_LOS = '1' ) then
						wrfifo <= '0';
						wren   <= '0';
					else
						wrfifo <= '1';
						wren   <= '1';
					end if;
				else
					-- packet middle
					if( nearfull = '1' ) or ( Serdes_syn = '1' ) or ( Opt_LOS = '1' ) then
						wrfifo <= '0';
						wren   <= '0';
						aclr   <= '1';
					else
						wrfifo <= wren;
					end if;
				end if;
			else
				if( wren = '1' ) and ( pklen /= "100" ) then
					aclr <= '1';
				end if;
				pklen		<= "000";
				wrfifo 		<= '0';
				wren		<= '0';
			end if;
		else
			wrfifo <= '0';
		end if;

		if( clr_txpkcnt = '1' ) then
			itxpkcnt <= ( others => '0' );
		end if;

		------------------------------------------------------------------
		--- fifo read control

		rdts		<= not rdts;
		rdfifo1		<= rdfifo;
		rdfifo2		<= rdfifo1;
		if( empty = '0' ) and ( usedw( 4 downto 1 ) /= "0000" ) and ( gapcnt = 0 ) and ( nocredit = '0' ) then
			fifo_ready <= '1';
		elsif( empty = '1' ) then
			fifo_ready <= '0';
		end if;

		if( rdts = '0' ) and ( empty = '0' ) then
			rdfifo	<= fifo_ready;
		else
			rdfifo	<= '0';
		end if;

		------------------------------------------------------------------
		--- tx to MII
		if( rdfifo2 = '0' ) and ( rdfifo = '1' ) then
			itxpkcnt <= itxpkcnt + '1';
		end if;

		if( rdfifo1 = '1' ) then
			serdat_out	<= byte_out(4) & byte_out(5) & byte_out(6) & byte_out(7);
			seren_out  		<= '1';
		elsif( rdfifo2 = '1' ) then
			serdat_out	<= byte_out(0) & byte_out(1) & byte_out(2) & byte_out(3);
			seren_out		<= '1';
		else
			seren_out		<= '0';
		end if;

		------------------------------------------------------------------
		--- gap counter
		if( rdfifo = '0' ) and ( rdfifo1 = '0' ) then
			if( gapcnt /= 0 ) then
				gapcnt <= gapcnt - 1;
			end if;
		else
			gapcnt <= 22;
		end if;
	end if;

	if( reset = '0' ) then
		aclr		<= '1';
		wrfifo		<= '0';
		wren		<= '0';
		paren_in1	<= '0';
		pardat_in1	<= ( others => '0' );
		serdat_out <= ( others => '0' );
		rdfifo		<= '0';
		rdfifo1		<= '0';
		rdfifo2		<= '0';
		rdts		<= '0';
		gapcnt		<= 0;
		seren_out	<= '0';
		fifo_ready	<= '0';
		itxpkcnt	<= ( others => '0' );

	end if;
end process;

end;

⌨️ 快捷键说明

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