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)