SURF  1.0
EthMacTxPause.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : EthMacTxPause.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2015-09-22
5 -- Last update: 2016-10-20
6 -------------------------------------------------------------------------------
7 -- Description:
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 -------------------------------------------------------------------------------
19 
20 library ieee;
21 use ieee.std_logic_1164.all;
22 use ieee.std_logic_arith.all;
23 use ieee.std_logic_unsigned.all;
24 
25 use work.AxiStreamPkg.all;
26 use work.StdRtlPkg.all;
27 use work.EthMacPkg.all;
28 
29 --! @see entity
30  --! @ingroup ethernet_EthMacCore
31 entity EthMacTxPause is
32  generic (
33  TPD_G : time := 1 ns;
34  PAUSE_EN_G : boolean := true;
35  PAUSE_512BITS_G : natural range 1 to 1024 := 8;
36  VLAN_EN_G : boolean := false;
37  VLAN_SIZE_G : positive range 1 to 8 := 1);
38  port (
39  -- Clock and Reset
40  ethClk : in sl;
41  ethRst : in sl;
42  -- Incoming data from client
47  -- Outgoing data to MAC
50  -- Flow control input
52  -- Inputs from pause frame RX
53  rxPauseReq : in sl;
54  rxPauseValue : in slv(15 downto 0);
55  -- Configuration and status
56  phyReady : in sl;
58  pauseTime : in slv(15 downto 0);
59  macAddress : in slv(47 downto 0);
60  pauseTx : out sl);
61 end EthMacTxPause;
62 
63 architecture rtl of EthMacTxPause is
64 
65  constant CNT_BITS_C : integer := bitSize(PAUSE_512BITS_G);
66  constant SIZE_C : natural := ite(VLAN_EN_G, (VLAN_SIZE_G+1), 1);
67 
68  type StateType is (
69  IDLE_S,
70  PAUSE_S,
71  PASS_S);
72 
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);
79  pauseTx : sl;
81  rxSlave : AxiStreamSlaveType;
82  state : StateType;
83  end record RegType;
84 
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'),
91  pauseTx => '0',
93  rxSlave => AXI_STREAM_SLAVE_INIT_C,
94  state => IDLE_S);
95 
96  signal r : RegType := REG_INIT_C;
97  signal rin : RegType;
98 
99  signal rxMasters : AxiStreamMasterArray(SIZE_C-1 downto 0);
100  signal rxSlaves : AxiStreamSlaveArray(SIZE_C-1 downto 0);
101 
102  signal rxMaster : AxiStreamMasterType;
103  signal rxSlave : AxiStreamSlaveType;
104 
105  -- attribute dont_touch : string;
106  -- attribute dont_touch of r : signal is "true";
107 
108 begin
109 
110  rxMasters(0) <= sAxisMaster;
111  sAxisSlave <= rxSlaves(0);
112 
113  U_NoVlanGen : if (VLAN_EN_G = false) generate
114 
115  rxMaster <= rxMasters(0);
116  rxSlaves(0) <= rxSlave;
117  sAxisSlaves <= (others => AXI_STREAM_SLAVE_FORCE_C);
118 
119  end generate;
120 
121  U_VlanGen : if (VLAN_EN_G = true) generate
122 
123  GEN_VEC :
124  for i in (VLAN_SIZE_G-1) downto 0 generate
125  rxMasters(i+1) <= sAxisMasters(i);
126  sAxisSlaves(i) <= rxSlaves(i+1);
127  end generate GEN_VEC;
128 
129  U_AxiStreamMux : entity work.AxiStreamMux
130  generic map (
131  TPD_G => TPD_G,
132  NUM_SLAVES_G => SIZE_C)
133  port map (
134  -- Clock and reset
135  axisClk => ethClk,
136  axisRst => ethRst,
137  -- Slaves
138  sAxisMasters => rxMasters,
139  sAxisSlaves => rxSlaves,
140  -- Master
141  mAxisMaster => rxMaster,
142  mAxisSlave => rxSlave);
143 
144  end generate;
145 
146  U_TxPauseGen : if (PAUSE_EN_G = true) generate
147 
149  r, rxMaster, rxPauseReq, rxPauseValue) is
150  variable v : RegType;
151  begin
152  -- Latch the current value
153  v := r;
154 
155  -- Reset the flags
156  v.pauseTx := '0';
157  v.rxSlave := AXI_STREAM_SLAVE_INIT_C;
158  if (mAxisSlave.tReady = '1') then
159  v.mAxisMaster.tValid := '0';
160  end if;
161 
162  -- Pre-counter, 8 clocks ~= 512 bit times of 10G
163  v.remPreCnt := r.remPreCnt - 1;
164  v.locPreCnt := r.locPreCnt - 1;
165 
166  -- Local pause count tracking
167  if (pauseEnable = '0') then
168  v.locPauseCnt := (others => '0');
169  elsif (rxPauseReq = '1') then
170  v.locPauseCnt := rxPauseValue;
171  v.locPreCnt := (others => '1');
172  elsif (r.locPauseCnt /= 0) and (r.locPreCnt = 0) then
173  v.locPauseCnt := r.locPauseCnt - 1;
174  end if;
175 
176  -- Remote pause count tracking
177  if (r.remPauseCnt /= 0) and (r.remPreCnt = 0) then
178  v.remPauseCnt := r.remPauseCnt - 1;
179  end if;
180 
181  -- State Machine
182  case r.state is
183  ----------------------------------------------------------------------
184  when IDLE_S =>
185  -- Check if we need to transmit pause
186  if (clientPause = '1') and (r.remPauseCnt = 0) and (pauseEnable = '1') and (phyReady = '1') then
187  -- Next state
188  v.state := PAUSE_S;
189  -- Transmit required and not paused by received pause count
190  elsif (rxMaster.tValid = '1') and (r.locPauseCnt = 0) then
191  -- Next state
192  v.state := PASS_S;
193  end if;
194  ----------------------------------------------------------------------
195  when PAUSE_S =>
196  ----------------------------------------------------------------------------------------------------------
197  -- Refer to https://www.safaribooksonline.com/library/view/ethernet-the-definitive/1565926609/ch04s02.html
198  ----------------------------------------------------------------------------------------------------------
199  -- Check if ready to move data
200  if (v.mAxisMaster.tValid = '0') then
201  -- Reset the bus to defaults
203  -- Performing a write operation
204  v.mAxisMaster.tValid := '1';
205  -- Increment the counter
206  v.txCount := r.txCount + 1;
207  -- Check the flag
208  if (r.txCount = 0) then
209  -- DST MAC (Pause MAC Address)
210  v.mAxisMaster.tData(47 downto 0) := x"010000C28001";
211  -- SRC MAC (local MAC address)
212  v.mAxisMaster.tData(95 downto 48) := macAddress;
213  -- MAC Control Type
214  v.mAxisMaster.tData(111 downto 96) := x"0888";
215  -- Pause Op-code
216  v.mAxisMaster.tData(127 downto 112) := x"0100"; -- 2 bytes
217  elsif (r.txCount = 1) then
218  -- Pause length
219  v.mAxisMaster.tData(7 downto 0) := pauseTime(15 downto 8); -- 1 bytes
220  v.mAxisMaster.tData(15 downto 8) := pauseTime(7 downto 0); -- 1 bytes
221  -- Zero Padding
222  v.mAxisMaster.tData(127 downto 16) := (others => '0'); -- 14 bytes
223  elsif (r.txCount = 2) then
224  -- Zero Padding
225  v.mAxisMaster.tData := (others => '0');
226  v.mAxisMaster.tKeep := x"FFFF"; -- 16 bytes
227  else
228  -- Zero Padding
229  v.mAxisMaster.tData := (others => '0');
230  v.mAxisMaster.tKeep := x"0FFF"; -- 12 bytes (Fixed frame size = 46 bytes)
231  -- Set EOF
232  v.mAxisMaster.tLast := '1';
233  -- Latch the Pause time
234  v.remPauseCnt := pauseTime;
235  v.remPreCnt := (others => '1');
236  v.pauseTx := '1';
237  -- Reset the counter
238  v.txCount := (others => '0');
239  -- Next state
240  v.state := IDLE_S;
241  end if;
242  end if;
243  ----------------------------------------------------------------------
244  when PASS_S =>
245  -- Check if ready to move data
246  if (v.mAxisMaster.tValid = '0') and (rxMaster.tValid = '1') then
247  -- Accept the data
248  v.rxSlave.tReady := '1';
249  -- Move the data
250  v.mAxisMaster := rxMaster;
251  -- Check for EOF
252  if (rxMaster.tLast = '1') then
253  -- Next state
254  v.state := IDLE_S;
255  end if;
256  end if;
257  ----------------------------------------------------------------------
258  end case;
259 
260  -- Reset
261  if (ethRst = '1') then
262  v := REG_INIT_C;
263  end if;
264 
265  -- Register the variable for next clock cycle
266  rin <= v;
267 
268  -- Outputs
269  rxSlave <= v.rxSlave;
271  pauseTx <= r.pauseTx;
272 
273  end process;
274 
275  seq : process (ethClk) is
276  begin
277  if rising_edge(ethClk) then
278  r <= rin after TPD_G;
279  end if;
280  end process seq;
281 
282  end generate;
283 
284  U_BypTxPause : if (PAUSE_EN_G = false) generate
285  mAxisMaster <= rxMaster;
286  rxSlave <= mAxisSlave;
287  pauseTx <= '0';
288  end generate;
289 
290 end rtl;
PAUSE_512BITS_Gnatural range 1 to 1024:= 8
_library_ ieeeieee
in rxPauseValueslv( 15 downto 0)
out mAxisMasterAxiStreamMasterType
TPD_Gtime := 1 ns
array(natural range <> ) of AxiStreamSlaveType AxiStreamSlaveArray
std_logic sl
Definition: StdRtlPkg.vhd:28
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
slv( 15 downto 0) tKeep
TPD_Gtime := 1 ns
in macAddressslv( 47 downto 0)
in sAxisMastersAxiStreamMasterArray( VLAN_SIZE_G- 1 downto 0)
in mAxisSlaveAxiStreamSlaveType
slv( 127 downto 0) tData
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
std_logic_vector slv
Definition: StdRtlPkg.vhd:29