1 ------------------------------------------------------------------------------- 2 -- File : EthMacTxExportXgmii.vhd 3 -- Author : Ryan Herbst <rherbst@slac.stanford.edu> 4 -- Company : SLAC National Accelerator Laboratory 5 -- Created : 2008-02-11 6 -- Last update: 2016-10-06 7 ------------------------------------------------------------------------------- 8 -- Description: 10GbE Export MAC core with GMII interface 9 ------------------------------------------------------------------------------- 10 -- This file is part of 'SLAC Firmware Standard Library'. 11 -- It is subject to the license terms in the LICENSE.txt file found in the 12 -- top-level directory of this distribution and at: 13 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. 14 -- No part of 'SLAC Firmware Standard Library', including this file, 15 -- may be copied, modified, propagated, or distributed except according to 16 -- the terms contained in the LICENSE.txt file. 17 ------------------------------------------------------------------------------- 20 use ieee.std_logic_1164.
all;
21 use ieee.std_logic_arith.
all;
22 use ieee.std_logic_unsigned.
all;
29 --! @ingroup ethernet_EthMacCore 50 end EthMacTxExportXgmii;
54 constant INTERGAP_C : slv(3 downto 0) := x"3";
68 signal intAdvance : sl;
72 signal intLastLine : sl;
73 signal intLastValidByte : slv(2 downto 0);
74 signal frameShift0 : sl;
75 signal frameShift1 : sl;
76 signal txEnable0 : sl;
77 signal txEnable1 : sl;
78 signal txEnable2 : sl;
79 signal txEnable3 : sl;
80 signal nxtMaskIn : slv(7 downto 0);
82 signal intData : slv(63 downto 0);
83 signal stateCount : slv(3 downto 0);
84 signal stateCountRst : sl;
85 signal exportWordCnt : slv(3 downto 0);
86 signal crcFifoIn : slv(71 downto 0);
87 signal crcFifoOut : slv(71 downto 0);
88 signal crcTx : slv(31 downto 0);
89 signal crcIn : slv(63 downto 0);
91 signal crcMaskIn : slv(7 downto 0);
92 signal crcInAdj : slv(63 downto 0);
93 signal crcDataWidth : slv(2 downto 0);
94 signal crcDataValid : sl;
96 signal crcOut : slv(31 downto 0);
101 signal curState : slv(2 downto 0);
102 signal nxtState : slv(2 downto 0);
103 constant ST_IDLE_C : slv(2 downto 0) := "000";
104 constant ST_DUMP_C : slv(2 downto 0) := "001";
105 constant ST_READ_C : slv(2 downto 0) := "010";
106 constant ST_WAIT_C : slv(2 downto 0) := "011";
107 constant ST_PAD_C : slv(2 downto 0) := "100";
110 attribute dont_touch : ;
112 attribute dont_touch of intAdvance : signal is "true";
113 attribute dont_touch of intDump : signal is "true";
114 attribute dont_touch of intRunt : signal is "true";
115 attribute dont_touch of intPad : signal is "true";
116 attribute dont_touch of intLastLine : signal is "true";
117 attribute dont_touch of intLastValidByte : signal is "true";
118 attribute dont_touch of frameShift0 : signal is "true";
119 attribute dont_touch of frameShift1 : signal is "true";
120 attribute dont_touch of txEnable0 : signal is "true";
121 attribute dont_touch of txEnable1 : signal is "true";
122 attribute dont_touch of txEnable2 : signal is "true";
123 attribute dont_touch of txEnable3 : signal is "true";
124 attribute dont_touch of nxtMaskIn : signal is "true";
125 attribute dont_touch of nxtEOF : signal is "true";
126 attribute dont_touch of intData : signal is "true";
127 attribute dont_touch of stateCount : signal is "true";
128 attribute dont_touch of stateCountRst : signal is "true";
129 attribute dont_touch of exportWordCnt : signal is "true";
130 attribute dont_touch of crcFifoIn : signal is "true";
131 attribute dont_touch of crcFifoOut : signal is "true";
132 attribute dont_touch of crcTx : signal is "true";
133 attribute dont_touch of crcIn : signal is "true";
134 attribute dont_touch of crcInit : signal is "true";
135 attribute dont_touch of crcMaskIn : signal is "true";
136 attribute dont_touch of crcInAdj : signal is "true";
137 attribute dont_touch of crcDataWidth : signal is "true";
138 attribute dont_touch of crcDataValid : signal is "true";
139 attribute dont_touch of crcReset : signal is "true";
140 attribute dont_touch of crcOut : signal is "true";
141 attribute dont_touch of intError : signal is "true";
142 attribute dont_touch of nxtError : signal is "true";
148 -- General Configurations 154 -- FIFO configurations 160 -- AXI Stream Port Configurations 172 mAxisMaster => macMaster,
-- 64-bit AXI stream interface 176 macSlave.tReady <= (intAdvance and (not intPad)) or intDump;
179 process (intPad, macMaster)
182 if intPad = '1' or macMaster.tKeep(i) = '0' then 183 intData(i*8+7 downto i*8) <= (others => '0');
185 intData(i*8+7 downto i*8) <= macMaster.tData(i*8+7 downto i*8);
190 -- State machine logic 193 if rising_edge(ethClk) then 195 curState <= ST_IDLE_C after TPD_G;
196 intError <= '0' after TPD_G;
197 stateCount <= (others => '0') after TPD_G;
198 exportWordCnt <= (others => '0') after TPD_G;
202 curState <= nxtState after TPD_G;
203 intError <= nxtError after TPD_G;
206 if stateCountRst = '1' then 207 stateCount <= (others => '0');
209 stateCount <= stateCount + 1;
212 if stateCountRst = '1' then 213 exportWordCnt <= (others => '0');
214 elsif intAdvance = '1' and intRunt = '1' then 215 exportWordCnt <= exportWordCnt + 1;
223 intRunt <= not exportWordCnt(3);
224 intLastValidByte <= "111" when curState = ST_PAD_C else onesCount(macMaster.tKeep(7 downto 1));
227 process (curState,
ethRst, intError, intRunt, macMaster,
phyReady, stateCount)
234 nxtError <= intError;
239 -- IDLE, wait for data to be available 241 stateCountRst <= '1';
249 -- Wait for start flag 254 nxtState <= ST_READ_C;
256 -- Phy is not ready dump data 258 nxtState <= ST_DUMP_C;
262 nxtState <= curState;
268 stateCountRst <= '0';
272 nxtState <= curState;
274 -- Read until we get last 275 if macMaster.tLast = '1' and intRunt = '1' then 276 nxtState <= ST_PAD_C;
280 elsif macMaster.tLast = '1' and intRunt = '0' then 282 nxtState <= ST_WAIT_C;
284 stateCountRst <= '1';
288 elsif macMaster.tValid = '0' then 298 -- Reading from PIC, Dumping data 301 stateCountRst <= '0';
304 -- Read until we get last 305 if macMaster.tLast = '1' then 308 nxtState <= ST_WAIT_C;
309 stateCountRst <= '1';
313 intDump <= macMaster.tValid;
315 nxtState <= curState;
318 -- Wait for inter-frame gap 322 stateCountRst <= '0';
326 -- Wait for gap, min 3 clocks 327 if stateCount >= INTERGAP_C and stateCount >= 3 then 328 nxtState <= ST_IDLE_C;
330 nxtState <= curState;
336 stateCountRst <= '0';
340 if intRunt = '1' then 342 nxtState <= curState;
345 nxtState <= ST_WAIT_C;
346 stateCountRst <= '1';
350 nxtState <= ST_IDLE_C;
353 stateCountRst <= '0';
360 -- Format data for input into CRC delay FIFO. 363 if rising_edge(ethClk) then 365 frameShift0 <= '0' after TPD_G;
366 frameShift1 <= '0' after TPD_G;
367 txEnable0 <= '0' after TPD_G;
368 txEnable1 <= '0' after TPD_G;
369 txEnable2 <= '0' after TPD_G;
370 txEnable3 <= '0' after TPD_G;
371 crcDataWidth <= (others => '0') after TPD_G;
372 crcMaskIn <= (others => '0') after TPD_G;
373 nxtMaskIn <= (others => '0') after TPD_G;
374 crcIn <= (others => '0') after TPD_G;
375 crcDataValid <= '0' after TPD_G;
378 -- Shift register to track frame state 379 frameShift0 <= intAdvance after TPD_G;
380 frameShift1 <= frameShift0 after TPD_G;
382 -- Input to transmit enable shift register. 383 -- Asserted with frameShift0 384 if intAdvance = '1'and frameShift0 = '0' then 385 txEnable0 <= '1' after TPD_G;
387 -- De-assert following frame shift0, 388 -- keep one extra clock if nxtMask contains a non-zero value. 389 elsif frameShift0 = '0' and nxtMaskIn = x"00" then 390 txEnable0 <= '0' after TPD_G;
393 -- Transmit enable shift register 394 txEnable1 <= txEnable0 after TPD_G;
395 txEnable2 <= txEnable1 after TPD_G;
396 txEnable3 <= txEnable2 after TPD_G;
399 crcDataValid <= intAdvance after TPD_G;
401 -- Word 0, set source mac address 402 if exportWordCnt = 0 then 404 crcIn(47 downto 0) <= intData(47 downto 0) after TPD_G;
406 -- Word 1, set source mac address 407 elsif exportWordCnt = 1 then 408 crcIn(63 downto 32) <= intData(63 downto 32) after TPD_G;
413 crcIn <= intData after TPD_G;
417 if intLastLine = '1' then 418 crcDataWidth <= intLastValidByte after TPD_G;
420 crcDataWidth <= "111" after TPD_G;
423 -- Generate CRC Mask Value for CRC append after delay buffer. 424 -- depends on number of bytes in last transfer 425 if intLastLine = '1' and frameShift0 = '1' then 426 if intError = '1' then -- Corrupt CRC 427 crcMaskIn <= x"FF" after TPD_G;
428 nxtMaskIn <= x"00" after TPD_G;
430 case intLastValidByte is 431 when "000" => crcMaskIn <= x"1E" after TPD_G;
nxtMaskIn <= x"00" after TPD_G;
432 when "001" => crcMaskIn <= x"3C" after TPD_G;
nxtMaskIn <= x"00" after TPD_G;
433 when "010" => crcMaskIn <= x"78" after TPD_G;
nxtMaskIn <= x"00" after TPD_G;
434 when "011" => crcMaskIn <= x"F0" after TPD_G;
nxtMaskIn <= x"00" after TPD_G;
435 when "100" => crcMaskIn <= x"E0" after TPD_G;
nxtMaskIn <= x"01" after TPD_G;
436 when "101" => crcMaskIn <= x"C0" after TPD_G;
nxtMaskIn <= x"03" after TPD_G;
437 when "110" => crcMaskIn <= x"80" after TPD_G;
nxtMaskIn <= x"07" after TPD_G;
438 when "111" => crcMaskIn <= x"00" after TPD_G;
nxtMaskIn <= x"0F" after TPD_G;
439 when others => crcMaskIn <= x"00" after TPD_G;
nxtMaskIn <= x"00" after TPD_G;
443 crcMaskIn <= nxtMaskIn after TPD_G;
444 nxtMaskIn <= (others => '0') after TPD_G;
450 -- Select CRC FIFO Data 451 crcFifoIn(71 downto 64) <= crcMaskIn;
452 crcFifoIn(63 downto 0) <= crcIn;
455 U_CrcFifo :
entity work.
Fifo 495 -- Output Stage to PHY 498 if rising_edge(ethClk) then 502 nxtEOF <= '0' after TPD_G;
505 -- EOF Charactor Required If CRC was in last word and there was 506 -- not enough space for EOF 510 nxtEOF <= '0' after TPD_G;
513 elsif (txEnable2 = '0') and (txEnable3 = '0' or crcFifoOut(71 downto 64) = 0) then 518 elsif txEnable2 = '1' and txEnable3 = '0' then 522 -- Normal data or CRC data. Select CRC / data combination 524 case crcFifoOut(71 downto 64) is -- CRC MASK 529 phyTxd(63 downto 56) <= crcTx(7 downto 0) after TPD_G;
530 phyTxd(55 downto 0) <= crcFifoOut(55 downto 0) after TPD_G;
534 phyTxd(23 downto 0) <= crcTx(31 downto 8) after TPD_G;
543 phyTxd(7 downto 0) <= crcFifoOut(7 downto 0) after TPD_G;
548 phyTxd(15 downto 0) <= crcFifoOut(15 downto 0) after TPD_G;
553 phyTxd(23 downto 0) <= crcFifoOut(23 downto 0) after TPD_G;
557 phyTxd(31 downto 0) <= crcFifoOut(31 downto 0) after TPD_G;
559 nxtEOF <= '1' after TPD_G;
561 phyTxd(63 downto 40) <= crcTx(23 downto 0) after TPD_G;
562 phyTxd(39 downto 0) <= crcFifoOut(39 downto 0) after TPD_G;
565 phyTxd(63 downto 8) <= x"070707070707FD" after TPD_G;
566 phyTxd(7 downto 0) <= crcTx(31 downto 24) after TPD_G;
569 phyTxd(63 downto 48) <= crcTx(15 downto 0) after TPD_G;
570 phyTxd(47 downto 0) <= crcFifoOut(47 downto 0) after TPD_G;
573 phyTxd(63 downto 16) <= x"0707070707FD" after TPD_G;
574 phyTxd(15 downto 0) <= crcTx(31 downto 16) after TPD_G;
590 ------------------------------------------ 592 ------------------------------------------ 596 crcInAdj(63 downto 56) <= crcIn(7 downto 0);
597 crcInAdj(55 downto 48) <= crcIn(15 downto 8);
598 crcInAdj(47 downto 40) <= crcIn(23 downto 16);
599 crcInAdj(39 downto 32) <= crcIn(31 downto 24);
600 crcInAdj(31 downto 24) <= crcIn(39 downto 32);
601 crcInAdj(23 downto 16) <= crcIn(47 downto 40);
602 crcInAdj(15 downto 8) <= crcIn(55 downto 48);
603 crcInAdj(7 downto 0) <= crcIn(63 downto 56);
618 -- CRC for transmission 619 crcTx(31 downto 24) <= crcOut(7 downto 0);
620 crcTx(23 downto 16) <= crcOut(15 downto 8);
621 crcTx(15 downto 8) <= crcOut(23 downto 16);
622 crcTx(7 downto 0) <= crcOut(31 downto 24);
SYNC_STAGES_Ginteger range 3 to ( 2** 24):= 3
in dinslv( DATA_WIDTH_G- 1 downto 0)
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 9
out wr_data_countslv( ADDR_WIDTH_G- 1 downto 0)
natural range 0 to 8 TDEST_BITS_C
XIL_DEVICE_Gstring := "7SERIES"
EMPTY_THRES_Ginteger range 1 to ( 2** 24):= 1
PIPE_STAGES_Gnatural range 0 to 16:= 1
out crcOutslv( 31 downto 0)
FWFT_EN_Gboolean := false
SLAVE_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
in crcDataWidthslv( 2 downto 0)
FULL_THRES_Ginteger range 1 to ( 2** 24):= 1
out macObSlaveAxiStreamSlaveType
SLAVE_READY_EN_Gboolean := true
RST_ASYNC_Gboolean := false
natural range 1 to 16 TDATA_BYTES_C
USE_DSP48_Gstring := "no"
GEN_SYNC_FIFO_Gboolean := false
TkeepModeType TKEEP_MODE_C
natural range 0 to 8 TID_BITS_C
in macAddressslv( 47 downto 0)
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
INT_PIPE_STAGES_Gnatural range 0 to 16:= 0
integer := 0 EMAC_EOFE_BIT_C
in macObMasterAxiStreamMasterType
TUserModeType TUSER_MODE_C
natural range 0 to 8 TUSER_BITS_C
GEN_SYNC_FIFO_Gboolean := false
out sAxisSlaveAxiStreamSlaveType
out doutslv( DATA_WIDTH_G- 1 downto 0)
in rstsl :=not RST_POLARITY_G
in sAxisMasterAxiStreamMasterType
out mAxisMasterAxiStreamMasterType
in crcInslv(( BYTE_WIDTH_G* 8- 1) downto 0)
USE_BUILT_IN_Gboolean := false
in mAxisSlaveAxiStreamSlaveType
CASCADE_SIZE_Ginteger range 1 to ( 2** 24):= 1
USE_BUILT_IN_Gboolean := false
VALID_THOLD_Ginteger range 0 to ( 2** 24):= 1
out rd_data_countslv( ADDR_WIDTH_G- 1 downto 0)
out phyTxcslv( 7 downto 0)
MASTER_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
AxiStreamConfigType :=(TSTRB_EN_C => false,TDATA_BYTES_C => 16,TDEST_BITS_C => 8,TID_BITS_C => 0,TKEEP_MODE_C => TKEEP_COMP_C,TUSER_BITS_C => 4,TUSER_MODE_C => TUSER_FIRST_LAST_C) EMAC_AXIS_CONFIG_C
out phyTxdslv( 63 downto 0)