diff --git a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd index 9a46107392..a5ff669184 100644 --- a/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd +++ b/devices/Marvell/Sgmii88E1111/lvdsUltraScale/Sgmii88E1111LvdsUltraScale.vhd @@ -27,6 +27,7 @@ entity Sgmii88E1111LvdsUltraScale is TPD_G : time := 1 ns; STABLE_CLK_FREQ_G : real := 156.25E+6; PAUSE_EN_G : boolean := true; + JUMBO_G : boolean := true; EN_AXIL_REG_G : boolean := false; PHY_G : natural range 0 to 31 := 7; AXIS_CONFIG_G : AxiStreamConfigType := EMAC_AXIS_CONFIG_C); @@ -191,6 +192,7 @@ begin generic map ( TPD_G => TPD_G, PAUSE_EN_G => PAUSE_EN_G, + JUMBO_G => JUMBO_G, EN_AXIL_REG_G => EN_AXIL_REG_G, AXIS_CONFIG_G => AXIS_CONFIG_G) port map ( diff --git a/devices/Ti/dp83867/core/SgmiiDp83867Mdio.vhd b/devices/Ti/dp83867/core/SgmiiDp83867Mdio.vhd index ba8565a345..74c285461a 100644 --- a/devices/Ti/dp83867/core/SgmiiDp83867Mdio.vhd +++ b/devices/Ti/dp83867/core/SgmiiDp83867Mdio.vhd @@ -38,6 +38,7 @@ entity SgmiiDp83867Mdio is linkIsUp : out sl; -- MDIO interface mdc : out sl; + mdTri : out sl; mdo : out sl; mdi : in sl; -- link status change interrupt @@ -47,25 +48,24 @@ end entity SgmiiDp83867Mdio; architecture rtl of SgmiiDp83867Mdio is constant P_INIT_C : MdioProgramArray := ( - mdioWriteInst(PHY_G, 16#0D#, x"001F", false), -- Address 0x000D: Setup for extended address - mdioWriteInst(PHY_G, 16#0E#, x"00D3", false), -- Address 0x000E: Set extended address = 0x00D3 - mdioWriteInst(PHY_G, 16#0D#, x"401F", false), -- Address 0x000D: Setup for extended data write - mdioWriteInst(PHY_G, 16#0E#, x"4000", false), -- Address 0x000E: Enable SGMII clock - - mdioWriteInst(PHY_G, 16#0D#, x"001F", false), -- Address 0x000D: Setup for extended address - mdioWriteInst(PHY_G, 16#0E#, x"0032", false), -- Address 0x000E: Set extended address = 0x0032 - mdioWriteInst(PHY_G, 16#0D#, x"401F", false), -- Address 0x000D: Setup for extended data write - mdioWriteInst(PHY_G, 16#0E#, x"0000", false), -- Address 0x000E: RGMII must be disabled - - mdioWriteInst(PHY_G, 16#1E#, x"0082", false), -- Address 0x001E: INTN/PWDNN Pad is an Interrupt Output. - mdioWriteInst(PHY_G, 16#14#, x"29C7", false), -- Address 0x0014: Configure interrupt polarity, enable auto negotiation, Enable Speed Optimization - mdioWriteInst(PHY_G, 16#12#, X"0c00", false), -- Address 0x0012: Interrupt of link and autoneg changes - mdioWriteInst(PHY_G, 16#10#, x"5868", false), -- Address 0x0010: Enable SGMII - -- mdioWriteInst(PHY_G, 16#09#, X"0200", false), -- Address 0x0009: Advertise 1000 FD only - -- mdioWriteInst(PHY_G, 16#04#, X"0140", false), -- Address 0x0004: Advertise 10/100 FD only - mdioWriteInst(PHY_G, 16#00#, x"1140", false), -- Address 0x0000: Enable autoneg and full duplex - - mdioWriteInst(PHY_G, 16#1F#, x"4000", true)); -- Address 0x001F: Initiate the soft restart. + mdioWriteInst(PHY_G, 16#0D#, x"001F", false), -- Address 0x0D: Setup for extended address + mdioWriteInst(PHY_G, 16#0E#, x"00D3", false), -- Address 0x0E: Set extended address = 0xD3 (more than 5-bit address) + mdioWriteInst(PHY_G, 16#0D#, x"401F", false), -- Address 0x0D: Setup for extended data write + mdioWriteInst(PHY_G, 16#0E#, x"4000", false), -- Address 0x0E: Enable SGMII clock + + mdioWriteInst(PHY_G, 16#0D#, x"001F", false), -- Address 0x0D: Setup for extended address + mdioWriteInst(PHY_G, 16#0E#, x"0032", false), -- Address 0x0E: Set extended address = 0x32 (more than 5-bit address) + mdioWriteInst(PHY_G, 16#0D#, x"401F", false), -- Address 0x0D: Setup for extended data write + mdioWriteInst(PHY_G, 16#0E#, x"0000", false), -- Address 0x0E: RGMII must be disabled + + mdioWriteInst(PHY_G, 16#00#, x"1140", false), -- Address 0x00: enable autoneg on copper side + mdioWriteInst(PHY_G, 16#10#, x"5848", false), -- Address 0x10: Enable SGMII + mdioWriteInst(PHY_G, 16#14#, x"2907", false), -- Address 0x14: disable ANEG on SMII side + + mdioWriteInst(PHY_G, 16#09#, X"0200", false), -- Address 0x09: Advertise 1000 FD only + mdioWriteInst(PHY_G, 16#04#, X"0001", false), -- Address 0x04: Don't advertise 10/100 + + mdioWriteInst(PHY_G, 16#1F#, x"4000", true)); -- Address 0x1F: Initiate the soft restart. constant REG0x13_IDX_C : natural := 0; constant REG0x11_IDX_C : natural := 1; @@ -118,8 +118,10 @@ begin hdlrDone => hdlrDone, args => args, mdc => mdc, + mdTri => mdTri, mdi => mdi, - mdo => mdo, phyIrq => linkIrq); + mdo => mdo, + phyIrq => linkIrq); COMB : process(args, hdlrDone, r) variable v : RegType; diff --git a/devices/Ti/dp83867/lvdsUltraScale/SgmiiDp83867LvdsUltraScale.vhd b/devices/Ti/dp83867/lvdsUltraScale/SgmiiDp83867LvdsUltraScale.vhd index b3b9792a11..c3e397a80e 100644 --- a/devices/Ti/dp83867/lvdsUltraScale/SgmiiDp83867LvdsUltraScale.vhd +++ b/devices/Ti/dp83867/lvdsUltraScale/SgmiiDp83867LvdsUltraScale.vhd @@ -16,91 +16,115 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; - library surf; use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; use surf.AxiLitePkg.all; use surf.EthMacPkg.all; +library UNISIM; +use UNISIM.vcomponents.all; + entity SgmiiDp83867LvdsUltraScale is generic ( TPD_G : time := 1 ns; STABLE_CLK_FREQ_G : real := 156.25E+6; - USE_BUFG_DIV_G : boolean := true; - CLKOUT1_PHASE_G : real := 90.0; + PAUSE_EN_G : boolean := true; + JUMBO_G : boolean := true; + EN_AXIL_REG_G : boolean := false; PHY_G : natural range 0 to 15 := 3; AXIS_CONFIG_G : AxiStreamConfigType := EMAC_AXIS_CONFIG_C); port ( -- clock and reset - extRst : in sl; -- active high - stableClk : in sl; -- Stable clock reference - phyClk : out sl; - phyRst : out sl; + extRst : in sl; -- active high + stableClk : in sl; -- Stable clock reference + phyClk : out sl; + phyRst : out sl; -- Local Configurations/status - localMac : in slv(47 downto 0); -- big-Endian configuration - phyReady : out sl; - linkUp : out sl; - speed10 : out sl; - speed100 : out sl; - speed1000 : out sl; - mmcmLocked : out sl; + localMac : in slv(47 downto 0); -- big-Endian configuration + phyReady : out sl; + linkUp : out sl; + speed10 : out sl; + speed100 : out sl; + speed1000 : out sl; -- Interface to Ethernet Media Access Controller (MAC) - macClk : in sl; - macRst : in sl; - obMacMaster : out AxiStreamMasterType; - obMacSlave : in AxiStreamSlaveType; - ibMacMaster : in AxiStreamMasterType; - ibMacSlave : out AxiStreamSlaveType; + macClk : in sl; + macRst : in sl; + obMacMaster : out AxiStreamMasterType; + obMacSlave : in AxiStreamSlaveType; + ibMacMaster : in AxiStreamMasterType; + ibMacSlave : out AxiStreamSlaveType; + -- Slave AXI-Lite Interface + axilClk : in sl := '0'; + axilRst : in sl := '0'; + axilReadMaster : in AxiLiteReadMasterType := AXI_LITE_READ_MASTER_INIT_C; + axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType := AXI_LITE_WRITE_MASTER_INIT_C; + axilWriteSlave : out AxiLiteWriteSlaveType; -- ETH external PHY Ports - phyClkP : in sl; -- 625.0 MHz - phyClkN : in sl; - phyMdc : out sl; - phyMdio : inout sl; - phyRstN : out sl; -- active low - phyIrqN : in sl; -- active low + phyClkP : in sl; -- 625.0 MHz + phyClkN : in sl; + phyMdc : out sl; + phyMdio : inout sl; + phyRstN : out sl; -- active low + phyIrqN : in sl; -- active low -- LVDS SGMII Ports - sgmiiRxP : in sl; - sgmiiRxN : in sl; - sgmiiTxP : out sl; - sgmiiTxN : out sl); + sgmiiRxP : in sl; + sgmiiRxN : in sl; + sgmiiTxP : out sl; + sgmiiTxN : out sl); end entity SgmiiDp83867LvdsUltraScale; architecture mapping of SgmiiDp83867LvdsUltraScale is - signal phyClock : sl; - signal phyReset : sl; - signal phyInitRst : sl; signal phyIrq : sl; + signal phyTri : sl; signal phyMdi : sl; + signal phyMdiSync : sl; signal phyMdo : sl := '1'; signal extPhyRstN : sl := '0'; signal sp10_100 : sl := '0'; signal sp100 : sl := '0'; - - signal sp10_100_sync : sl := '0'; - signal sp100_sync : sl := '0'; - signal initDone : sl := '0'; begin - phyClk <= phyClock; - phyRst <= phyReset; - speed10 <= sp10_100 and not sp100; speed100 <= sp10_100 and not sp100; speed1000 <= not sp10_100 and not sp100; -- Tri-state driver for phyMdio - phyMdio <= 'Z' when phyMdo = '1' else '0'; + U_phyMdio : IOBUF + port map ( + I => phyMdo, -- 1-bit input: Buffer input + O => phyMdi, -- 1-bit output: Buffer output + IO => phyMdio, -- 1-bit inout: Buffer inout + T => phyTri); -- 1-bit input: 3-state enable input -- Reset line of the external phy phyRstN <= extPhyRstN; + U_SyncIrq : entity surf.Synchronizer + generic map ( + TPD_G => TPD_G, + OUT_POLARITY_G => '0', + INIT_G => "11") + port map ( + clk => stableClk, + dataIn => phyIrqN, + dataOut => phyIrq); + + U_SyncMdi : entity surf.Synchronizer + generic map ( + TPD_G => TPD_G) + port map ( + clk => stableClk, + dataIn => phyMdi, + dataOut => phyMdiSync); + -------------------------------------------------------------------------- -- We must hold reset for >10ms and then wait >5ms until we may talk -- to it (we actually wait also >10ms) which is indicated by 'phyInitRst' @@ -110,7 +134,7 @@ begin TPD_G => TPD_G, IN_POLARITY_G => '1', OUT_POLARITY_G => '0', - DURATION_G => getTimeRatio(STABLE_CLK_FREQ_G, 100.0)) -- 10 ms reset + DURATION_G => getTimeRatio(STABLE_CLK_FREQ_G, 2.0)) -- 500 ms reset port map ( arst => extRst, clk => stableClk, @@ -121,24 +145,17 @@ begin TPD_G => TPD_G, IN_POLARITY_G => '0', OUT_POLARITY_G => '1', - DURATION_G => getTimeRatio(STABLE_CLK_FREQ_G, 100.0)) -- 10 ms reset + DURATION_G => getTimeRatio(STABLE_CLK_FREQ_G, 2.0)) -- 500 ms reset port map ( arst => extPhyRstN, clk => stableClk, rstOut => phyInitRst); - ----------------------------------------------------------------------- - -- The SaltCore does not support auto-negotiation on the SGMII link - -- (mac<->phy) - however, the DP83867ISRGZ PHY (by default) assumes it does. - -- We need to disable auto-negotiation in the PHY on the SGMII side - -- and handle link changes (aneg still enabled on copper) flagged - -- by the PHY... - ----------------------------------------------------------------------- U_PhyCtrl : entity surf.SgmiiDp83867Mdio generic map ( TPD_G => TPD_G, PHY_G => PHY_G, - DIV_G => getTimeRatio(STABLE_CLK_FREQ_G, 2*1.0E+6)) -- phyMdc = 1.0 MHz + DIV_G => getTimeRatio(STABLE_CLK_FREQ_G, 2*2.5E+6)) -- phyMdc = 2.5 MHz (nominal) port map ( clk => stableClk, rst => phyInitRst, @@ -146,74 +163,50 @@ begin speed_is_10_100 => sp10_100, speed_is_100 => sp100, linkIsUp => linkUp, - mdi => phyMdi, + mdi => phyMdiSync, mdc => phyMdc, + mdTri => phyTri, mdo => phyMdo, linkIrq => phyIrq); - ---------------------------------------------------- - -- synchronize MDI and IRQ signals into 'clk' domain - ---------------------------------------------------- - U_SyncMdi : entity surf.Synchronizer - generic map ( - TPD_G => TPD_G) - port map ( - clk => stableClk, - dataIn => phyMdio, - dataOut => phyMdi); - - U_SyncIrq : entity surf.Synchronizer - generic map ( - TPD_G => TPD_G, - OUT_POLARITY_G => '0', - INIT_G => "11") - port map ( - clk => stableClk, - dataIn => phyIrqN, - dataOut => phyIrq); - - U_sync_speed : entity surf.SynchronizerVector + U_1GigE : entity surf.GigEthLvdsUltraScale generic map ( - TPD_G => TPD_G, - WIDTH_G => 2) - port map ( - clk => phyClock, - dataIn(0) => sp10_100, - dataIn(1) => sp100, - dataOut(0) => sp10_100_sync, - dataOut(1) => sp100_sync); - - U_1GigE : entity surf.GigEthLvdsUltraScaleWrapper - generic map ( - TPD_G => TPD_G, - USE_BUFG_DIV_G => USE_BUFG_DIV_G, - CLKOUT1_PHASE_G => CLKOUT1_PHASE_G, - AXIS_CONFIG_G => (others => AXIS_CONFIG_G)) + TPD_G => TPD_G, + PAUSE_EN_G => PAUSE_EN_G, + JUMBO_G => JUMBO_G, + EN_AXIL_REG_G => EN_AXIL_REG_G, + AXIS_CONFIG_G => AXIS_CONFIG_G) port map ( -- Local Configurations - localMac(0) => localMac, + localMac => localMac, -- Streaming DMA Interface - dmaClk(0) => macClk, - dmaRst(0) => macRst, - dmaIbMasters(0) => obMacMaster, - dmaIbSlaves(0) => obMacSlave, - dmaObMasters(0) => ibMacMaster, - dmaObSlaves(0) => ibMacSlave, - -- Misc. Signals - extRst => extRst, - phyClk => phyClock, - phyRst => phyReset, - mmcmLocked => mmcmLocked, - phyReady(0) => phyReady, - speed_is_10_100(0) => sp10_100_sync, - speed_is_100(0) => sp100_sync, - -- MGT Clock Port - sgmiiClkP => phyClkP, - sgmiiClkN => phyClkN, - -- MGT Ports - sgmiiTxP(0) => sgmiiTxP, - sgmiiTxN(0) => sgmiiTxN, - sgmiiRxP(0) => sgmiiRxP, - sgmiiRxN(0) => sgmiiRxN); + dmaClk => macClk, + dmaRst => macRst, + dmaIbMaster => obMacMaster, + dmaIbSlave => obMacSlave, + dmaObMaster => ibMacMaster, + dmaObSlave => ibMacSlave, + -- Slave AXI-Lite Interface + axilClk => axilClk, + axilRst => axilRst, + axilReadMaster => axilReadMaster, + axilReadSlave => axilReadSlave, + axilWriteMaster => axilWriteMaster, + axilWriteSlave => axilWriteSlave, + -- Speed selection + speed_is_10_100 => sp10_100, + speed_is_100 => sp100, + -- PHY + MAC signals + extRst => phyInitRst, + ethClk => phyClk, + ethRst => phyRst, + phyReady => phyReady, + -- SGMII / LVDS Ports + sgmiiClkP => phyClkP, -- 625 MHz + sgmiiClkN => phyClkN, -- 625 MHz + sgmiiTxP => sgmiiTxP, + sgmiiTxN => sgmiiTxN, + sgmiiRxP => sgmiiRxP, + sgmiiRxN => sgmiiRxN); end mapping; diff --git a/ethernet/GigEthCore/lvdsUltraScale/ip/GigEthLvdsUltraScaleCore.dcp b/ethernet/GigEthCore/lvdsUltraScale/ip/GigEthLvdsUltraScaleCore.dcp index 2baa9e17aa..f60c27d33b 100644 --- a/ethernet/GigEthCore/lvdsUltraScale/ip/GigEthLvdsUltraScaleCore.dcp +++ b/ethernet/GigEthCore/lvdsUltraScale/ip/GigEthLvdsUltraScaleCore.dcp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a882be8700d046ef2ec3e4e2a8078e9ca84675708fdd9b25522b694d1bf3bbb5 -size 227537 +oid sha256:24dadac53d89c86b234c45bb902a0ae7f425f10951a71cd465ed860d5d7bdd9e +size 297138 diff --git a/ethernet/GigEthCore/lvdsUltraScale/ip/README.md b/ethernet/GigEthCore/lvdsUltraScale/ip/README.md new file mode 100644 index 0000000000..ebfcf59d2d --- /dev/null +++ b/ethernet/GigEthCore/lvdsUltraScale/ip/README.md @@ -0,0 +1,20 @@ +# Post .DCP generation hack to make it work with both Ultrascale and Ultrascale+ + +1) Open the .DCP with Vivado +```bash +vivado surf/ethernet/GigEthCore/lvdsUltraScale/ip/GigEthLvdsUltraScaleCore.dcp +``` + +2) Change VCO freqnecy from 625MHz to 1250MHz because Ultrascale+ VCO(min. freq) = 800MHz + +```tcl +set_property CLKFBOUT_MULT_F 4.000 [get_cells U0/core_clocking_i/mmcme3_adv_inst] +set_property CLKOUT0_DIVIDE_F 10.000 [get_cells U0/core_clocking_i/mmcme3_adv_inst] +set_property CLKOUT1_DIVIDE 4 [get_cells U0/core_clocking_i/mmcme3_adv_inst] +set_property CLKOUT2_DIVIDE 2 [get_cells U0/core_clocking_i/mmcme3_adv_inst] +``` + +3) Save the changes +```tcl +write_checkpoint surf/ethernet/GigEthCore/lvdsUltraScale/ip/GigEthLvdsUltraScaleCore.dcp -force +``` diff --git a/protocols/mdio/rtl/MdioCore.vhd b/protocols/mdio/rtl/MdioCore.vhd index 5c84d282ce..03707701dd 100644 --- a/protocols/mdio/rtl/MdioCore.vhd +++ b/protocols/mdio/rtl/MdioCore.vhd @@ -43,6 +43,7 @@ entity MdioCore is -- MDIO interface mdc : out sl; mdo : out sl; + mdTri : out sl; mdi : in sl ); end entity MdioCore; @@ -58,6 +59,7 @@ architecture MdioCoreImpl of MdioCore is din : slv(15 downto 0); count : slv( 5 downto 0); div : slv(DIV_BITS_C - 1 downto 0); + tri : sl; mdc : sl; don : sl; state : State; @@ -68,6 +70,7 @@ architecture MdioCoreImpl of MdioCore is din => ( others => '0' ), count => ( others => '1' ), div => ( others => '0' ), + tri => '1', mdc => '0', don => '0', state => IDLE @@ -76,10 +79,14 @@ architecture MdioCoreImpl of MdioCore is signal r : RegType := REG_INIT_C; signal rin : RegType; + -- attribute dont_touch : string; + -- attribute dont_touch of r : signal is "TRUE"; + begin mdo <= r.dataOut(32); mdc <= r.mdc; + mdTri <= r.tri; don <= r.don; din <= r.din; @@ -93,6 +100,7 @@ begin v.div := slv( unsigned(r.div) - 1 ); if ( r.state = IDLE ) then + v.tri := '1'; if ( trg /= '0' ) then v.state := RUN; v.dataOut(31 downto 30) := "01"; -- start @@ -103,6 +111,7 @@ begin v.dataOut(16) := cmd.rdNotWr; v.dataOut(15 downto 0) := cmd.dataOut; v.div := toSlv(DIV_G - 1, DIV_BITS_C); + v.tri := '0'; end if; else if ( unsigned(r.div) = 0 ) then @@ -119,6 +128,9 @@ begin v.dataOut( 32 downto 1 ) := r.dataOut(31 downto 0); v.dataOut( 0 ) := '1'; end if; + if r.count = b"01_0010" then + v.tri := cmd.rdNotWr; + end if; else v.din( 15 downto 1 ) := r.din (14 downto 0); v.din( 0 ) := mdi; diff --git a/protocols/mdio/rtl/MdioLinkIrqHandler.vhd b/protocols/mdio/rtl/MdioLinkIrqHandler.vhd index b00e9fa4bd..d53c2c7bd8 100644 --- a/protocols/mdio/rtl/MdioLinkIrqHandler.vhd +++ b/protocols/mdio/rtl/MdioLinkIrqHandler.vhd @@ -62,6 +62,7 @@ entity MdioLinkIrqHandler is -- MDIO interface mdc : out sl; + mdTri : out sl; mdo : out sl; mdi : in sl; @@ -113,6 +114,12 @@ architecture MdioLinkIrqHandlerImpl of MdioLinkIrqHandler is signal mdioDone : sl; signal mdioData : slv(15 downto 0); + -- attribute dont_touch : string; + -- attribute dont_touch of r : signal is "TRUE"; + -- attribute dont_touch of mdioRead : signal is "TRUE"; + -- attribute dont_touch of mdioDone : signal is "TRUE"; + -- attribute dont_touch of mdioData : signal is "TRUE"; + begin initDone <= r.initDone; @@ -136,6 +143,7 @@ begin don => mdioDone, mdc => mdc, + mdTri => mdTri, mdi => mdi, mdo => mdo ); diff --git a/protocols/mdio/rtl/MdioSeqCore.vhd b/protocols/mdio/rtl/MdioSeqCore.vhd index 84861cd5bd..3203ade66d 100644 --- a/protocols/mdio/rtl/MdioSeqCore.vhd +++ b/protocols/mdio/rtl/MdioSeqCore.vhd @@ -75,6 +75,7 @@ entity MdioSeqCore is -- MDIO interface mdc : out sl; + mdTri : out sl; mdo : out sl; mdi : in sl ); @@ -123,6 +124,7 @@ begin don => oneDone, mdc => mdc, + mdTri => mdTri, mdi => mdi, mdo => mdo );