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