1 ------------------------------------------------------------------------------- 2 -- File : EthMacTxPause.vhd 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2015-09-22 5 -- Last update: 2016-10-20 6 ------------------------------------------------------------------------------- 8 -- Generic pause frame generator for Ethernet MACs. This module as acts as 9 -- a gate keeper when the peer has requested a pause period. 10 ------------------------------------------------------------------------------- 11 -- This file is part of 'SLAC Firmware Standard Library'. 12 -- It is subject to the license terms in the LICENSE.txt file found in the 13 -- top-level directory of this distribution and at: 14 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 15 -- No part of 'SLAC Firmware Standard Library', including this file, 16 -- may be copied, modified, propagated, or distributed except according to 17 -- the terms contained in the LICENSE.txt file. 18 ------------------------------------------------------------------------------- 21 use ieee.std_logic_1164.
all;
22 use ieee.std_logic_arith.
all;
23 use ieee.std_logic_unsigned.
all;
30 --! @ingroup ethernet_EthMacCore 42 -- Incoming data from client 47 -- Outgoing data to MAC 52 -- Inputs from pause frame RX 55 -- Configuration and status 73 type RegType is record 74 locPauseCnt : slv(
15 downto 0);
75 remPauseCnt : slv(15 downto 0);
76 txCount : slv(1 downto 0);
77 locPreCnt : slv(CNT_BITS_C-1
downto 0);
78 remPreCnt : slv(CNT_BITS_C-1 downto 0);
85 constant REG_INIT_C : RegType := ( 86 locPauseCnt => (
others => '0'),
87 remPauseCnt => (others => '0'), 88 txCount => (others => '0'), 89 locPreCnt => (
others => '0'),
90 remPreCnt => (others => '0'), 96 signal r : RegType := REG_INIT_C;
105 -- attribute dont_touch : string; 106 -- attribute dont_touch of r : signal is "true"; 113 U_NoVlanGen : if (VLAN_EN_G = false) generate 115 rxMaster <= rxMasters(0);
116 rxSlaves(0) <= rxSlave;
121 U_VlanGen : if (VLAN_EN_G = true) generate 127 end generate GEN_VEC;
146 U_TxPauseGen : if (PAUSE_EN_G = true) generate 150 variable v : RegType;
152 -- Latch the current value 162 -- Pre-counter, 8 clocks ~= 512 bit times of 10G 163 v.remPreCnt := r.remPreCnt - 1;
164 v.locPreCnt := r.locPreCnt - 1;
166 -- Local pause count tracking 168 v.locPauseCnt := (others => '0');
171 v.locPreCnt := (others => '1');
172 elsif (r.locPauseCnt /= 0) and (r.locPreCnt = 0) then 173 v.locPauseCnt := r.locPauseCnt - 1;
176 -- Remote pause count tracking 177 if (r.remPauseCnt /= 0) and (r.remPreCnt = 0) then 178 v.remPauseCnt := r.remPauseCnt - 1;
183 ---------------------------------------------------------------------- 185 -- Check if we need to transmit pause 189 -- Transmit required and not paused by received pause count 190 elsif (rxMaster.tValid = '1') and (r.locPauseCnt = 0) then 194 ---------------------------------------------------------------------- 196 ---------------------------------------------------------------------------------------------------------- 197 -- Refer to https://www.safaribooksonline.com/library/view/ethernet-the-definitive/1565926609/ch04s02.html 198 ---------------------------------------------------------------------------------------------------------- 199 -- Check if ready to move data 201 -- Reset the bus to defaults 203 -- Performing a write operation 205 -- Increment the counter 206 v.txCount := r.txCount + 1;
208 if (r.txCount = 0) then 209 -- DST MAC (Pause MAC Address) 211 -- SRC MAC (local MAC address) 217 elsif (r.txCount = 1) then 223 elsif (r.txCount = 2) then 233 -- Latch the Pause time 235 v.remPreCnt := (others => '1');
238 v.txCount := (others => '0');
243 ---------------------------------------------------------------------- 245 -- Check if ready to move data 252 if (rxMaster.tLast = '1') then 257 ---------------------------------------------------------------------- 265 -- Register the variable for next clock cycle 269 rxSlave <= v.rxSlave;
277 if rising_edge(ethClk) then 278 r <= rin after TPD_G;
284 U_BypTxPause : if (PAUSE_EN_G = false) generate PAUSE_512BITS_Gnatural range 1 to 1024:= 8
in rxPauseValueslv( 15 downto 0)
out mAxisMasterAxiStreamMasterType
array(natural range <> ) of AxiStreamSlaveType AxiStreamSlaveArray
AxiStreamMasterType :=(tValid => '0',tData =>( others => '0'),tStrb =>( others => '1'),tKeep =>( others => '1'),tLast => '0',tDest =>( others => '0'),tId =>( others => '0'),tUser =>( others => '0')) AXI_STREAM_MASTER_INIT_C
in macAddressslv( 47 downto 0)
in sAxisMastersAxiStreamMasterArray( VLAN_SIZE_G- 1 downto 0)
in mAxisSlaveAxiStreamSlaveType
PAUSE_EN_Gboolean := true
out mAxisMasterAxiStreamMasterType
NUM_SLAVES_Ginteger range 1 to 32:= 4
AxiStreamSlaveType :=(tReady => '0') AXI_STREAM_SLAVE_INIT_C
in sAxisMastersAxiStreamMasterArray( NUM_SLAVES_G- 1 downto 0)
in pauseTimeslv( 15 downto 0)
array(natural range <> ) of AxiStreamMasterType AxiStreamMasterArray
out sAxisSlavesAxiStreamSlaveArray( NUM_SLAVES_G- 1 downto 0)
out sAxisSlaveAxiStreamSlaveType
VLAN_SIZE_Gpositive range 1 to 8:= 1
VLAN_EN_Gboolean := false
AxiStreamSlaveType :=(tReady => '1') AXI_STREAM_SLAVE_FORCE_C
out sAxisSlavesAxiStreamSlaveArray( VLAN_SIZE_G- 1 downto 0)
in mAxisSlaveAxiStreamSlaveType
in sAxisMasterAxiStreamMasterType