diff --git a/protocols/pgp/pgp4/core/rtl/Pgp4RxLiteLowSpeed.vhd b/protocols/pgp/pgp4/core/rtl/Pgp4RxLiteLowSpeed.vhd new file mode 100644 index 0000000000..ad9eb2fb81 --- /dev/null +++ b/protocols/pgp/pgp4/core/rtl/Pgp4RxLiteLowSpeed.vhd @@ -0,0 +1,182 @@ +------------------------------------------------------------------------------- +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: Pgp4RxLite Low Speed Wrapper +------------------------------------------------------------------------------- +-- This file is part of 'SLAC Firmware Standard Library'. +-- It is subject to the license terms in the LICENSE.txt file found in the +-- top-level directory of this distribution and at: +-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +-- No part of 'SLAC Firmware Standard Library', including this file, +-- may be copied, modified, propagated, or distributed except according to +-- the terms contained in the LICENSE.txt file. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +library surf; +use surf.StdRtlPkg.all; +use surf.AxiStreamPkg.all; +use surf.AxiLitePkg.all; +use surf.Pgp4Pkg.all; + +entity Pgp4LiteRxLowSpeed is + generic ( + TPD_G : time := 1 ns; + SIMULATION_G : boolean := false; + DLY_STEP_SIZE_G : positive range 1 to 255 := 1; + NUM_LANE_G : positive := 1; + STATUS_CNT_WIDTH_G : natural range 1 to 32 := 16; + ERROR_CNT_WIDTH_G : natural range 1 to 32 := 8; + AXIL_CLK_FREQ_G : real; -- In units of HZ + AXIL_BASE_ADDR_G : slv(31 downto 0)); + port ( + -- Deserialization Interface (deserClk domain) + deserClk : in sl; + deserRst : in sl; + deserData : in Slv8Array(NUM_LANE_G-1 downto 0); + dlyLoad : out slv(NUM_LANE_G-1 downto 0); + dlyCfg : out Slv9Array(NUM_LANE_G-1 downto 0); + -- PGP Streaming Outputs (deserClk domain) + pgpRxMasters : out AxiStreamMasterArray(NUM_LANE_G-1 downto 0); + -- AXI-Lite Interface (axilClk domain) + axilClk : in sl; + axilRst : in sl; + axilReadMaster : in AxiLiteReadMasterType; + axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType; + axilWriteSlave : out AxiLiteWriteSlaveType); +end Pgp4LiteRxLowSpeed; + +architecture mapping of Pgp4LiteRxLowSpeed is + + constant NUM_AXIL_MASTERS_C : positive := NUM_LANE_G+1; + + constant XBAR_CONFIG_C : AxiLiteCrossbarMasterConfigArray(NUM_AXIL_MASTERS_C-1 downto 0) := genAxiLiteConfig(NUM_AXIL_MASTERS_C, AXIL_BASE_ADDR_G, 20, 12); + + signal axilWriteMasters : AxiLiteWriteMasterArray(NUM_AXIL_MASTERS_C-1 downto 0); + signal axilWriteSlaves : AxiLiteWriteSlaveArray(NUM_AXIL_MASTERS_C-1 downto 0) := (others => AXI_LITE_WRITE_SLAVE_EMPTY_SLVERR_C); + signal axilReadMasters : AxiLiteReadMasterArray(NUM_AXIL_MASTERS_C-1 downto 0); + signal axilReadSlaves : AxiLiteReadSlaveArray(NUM_AXIL_MASTERS_C-1 downto 0) := (others => AXI_LITE_READ_SLAVE_EMPTY_SLVERR_C); + + signal deserReset : sl; + signal dlyConfig : Slv9Array(NUM_LANE_G-1 downto 0); + + signal enUsrDlyCfg : sl; + signal usrDlyCfg : Slv9Array(NUM_LANE_G-1 downto 0); + signal minEyeWidth : slv(7 downto 0); + signal lockingCntCfg : slv(23 downto 0); + signal bypFirstBerDet : sl; + signal polarity : slv(NUM_LANE_G-1 downto 0); + signal bitOrder : slv(1 downto 0); + signal errorDet : slv(NUM_LANE_G-1 downto 0); + signal bitSlip : slv(NUM_LANE_G-1 downto 0); + signal eyeWidth : Slv9Array(NUM_LANE_G-1 downto 0); + signal locked : slv(NUM_LANE_G-1 downto 0); + +begin + + dlyCfg <= dlyConfig; + + U_deserReset : entity surf.RstPipeline + generic map ( + TPD_G => TPD_G) + port map ( + clk => deserClk, + rstIn => deserRst, + rstOut => deserReset); + + U_XBAR : entity surf.AxiLiteCrossbar + generic map ( + TPD_G => TPD_G, + NUM_SLAVE_SLOTS_G => 1, + NUM_MASTER_SLOTS_G => NUM_AXIL_MASTERS_C, + MASTERS_CONFIG_G => XBAR_CONFIG_C) + port map ( + axiClk => axilClk, + axiClkRst => axilRst, + sAxiWriteMasters(0) => axilWriteMaster, + sAxiWriteSlaves(0) => axilWriteSlave, + sAxiReadMasters(0) => axilReadMaster, + sAxiReadSlaves(0) => axilReadSlave, + mAxiWriteMasters => axilWriteMasters, + mAxiWriteSlaves => axilWriteSlaves, + mAxiReadMasters => axilReadMasters, + mAxiReadSlaves => axilReadSlaves); + + U_Reg : entity surf.Pgp4RxLiteLowSpeedReg + generic map ( + TPD_G => TPD_G, + SIMULATION_G => SIMULATION_G, + STATUS_CNT_WIDTH_G => STATUS_CNT_WIDTH_G, + NUM_LANE_G => NUM_LANE_G) + port map ( + -- Deserialization Interface (deserClk domain) + deserClk => deserClk, + deserRst => deserRst, + dlyConfig => dlyConfig, + errorDet => errorDet, + bitSlip => bitSlip, + eyeWidth => eyeWidth, + locked => locked, + enUsrDlyCfg => enUsrDlyCfg, + usrDlyCfg => usrDlyCfg, + minEyeWidth => minEyeWidth, + lockingCntCfg => lockingCntCfg, + bypFirstBerDet => bypFirstBerDet, + polarity => polarity, + bitOrder => bitOrder, + -- AXI-Lite Interface (axilClk domain) + axilClk => axilClk, + axilRst => axilRst, + axilReadMaster => axilReadMasters(0), + axilReadSlave => axilReadSlaves(0), + axilWriteMaster => axilWriteMasters(0), + axilWriteSlave => axilWriteSlaves(0)); + + GEN_LANE : + for i in NUM_LANE_G-1 downto 0 generate + + U_PgpLane : entity surf.Pgp4RxLiteLowSpeedLane + generic map ( + TPD_G => TPD_G, + SIMULATION_G => SIMULATION_G, + DLY_STEP_SIZE_G => DLY_STEP_SIZE_G, + STATUS_CNT_WIDTH_G => STATUS_CNT_WIDTH_G, + ERROR_CNT_WIDTH_G => ERROR_CNT_WIDTH_G, + AXIL_CLK_FREQ_G => AXIL_CLK_FREQ_G) + port map ( + -- Deserialization Interface (deserClk domain) + deserClk => deserClk, + deserRst => deserReset, + deserData => deserData(i), + dlyLoad => dlyLoad(i), + dlyCfg => dlyConfig(i), + -- Config/Status Interface (deserClk domain) + enUsrDlyCfg => enUsrDlyCfg, + usrDlyCfg => usrDlyCfg(i), + minEyeWidth => minEyeWidth, + lockingCntCfg => lockingCntCfg, + bypFirstBerDet => bypFirstBerDet, + polarity => polarity(i), + bitOrder => bitOrder, + errorDet => errorDet(i), + bitSlip => bitSlip(i), + eyeWidth => eyeWidth(i), + locked => locked(i), + -- PGP Streaming Outputs (deserClk domain) + pgpRxMaster => pgpRxMasters(i), + -- AXI-Lite Register Interface (axilClk domain) + axilClk => axilClk, + axilRst => axilRst, + axilReadMaster => axilReadMasters(i+1), + axilReadSlave => axilReadSlaves(i+1), + axilWriteMaster => axilWriteMasters(i+1), + axilWriteSlave => axilWriteSlaves(i+1)); + + end generate GEN_LANE; + +end mapping; diff --git a/protocols/pgp/pgp4/core/rtl/Pgp4RxLiteLowSpeedLane.vhd b/protocols/pgp/pgp4/core/rtl/Pgp4RxLiteLowSpeedLane.vhd new file mode 100644 index 0000000000..1cd31fec56 --- /dev/null +++ b/protocols/pgp/pgp4/core/rtl/Pgp4RxLiteLowSpeedLane.vhd @@ -0,0 +1,200 @@ +------------------------------------------------------------------------------- +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: Wrapper on the Pgp4RxLite Low Speed Lane +------------------------------------------------------------------------------- +-- This file is part of 'SLAC Firmware Standard Library'. +-- It is subject to the license terms in the LICENSE.txt file found in the +-- top-level directory of this distribution and at: +-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +-- No part of 'SLAC Firmware Standard Library', including this file, +-- may be copied, modified, propagated, or distributed except according to +-- the terms contained in the LICENSE.txt file. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +library surf; +use surf.StdRtlPkg.all; +use surf.AxiStreamPkg.all; +use surf.AxiLitePkg.all; +use surf.Pgp4Pkg.all; + +entity Pgp4RxLiteLowSpeedLane is + generic ( + TPD_G : time := 1 ns; + SIMULATION_G : boolean := false; + DLY_STEP_SIZE_G : positive range 1 to 255 := 1; + STATUS_CNT_WIDTH_G : natural range 1 to 32 := 16; + ERROR_CNT_WIDTH_G : natural range 1 to 32 := 8; + AXIL_CLK_FREQ_G : real); -- In units of HZ + port ( + -- Deserialization Interface (deserClk domain) + deserClk : in sl; + deserRst : in sl; + deserData : in slv(7 downto 0); + dlyLoad : out sl; + dlyCfg : out slv(8 downto 0); + -- Config/Status Interface (deserClk domain) + enUsrDlyCfg : in sl; + usrDlyCfg : in slv(8 downto 0); + minEyeWidth : in slv(7 downto 0); + lockingCntCfg : in slv(23 downto 0); + bypFirstBerDet : in sl; + polarity : in sl; + bitOrder : in slv(1 downto 0); + errorDet : out sl; + bitSlip : out sl; + eyeWidth : out slv(8 downto 0); + locked : out sl; + -- PGP Streaming Outputs (deserClk domain) + pgpRxMaster : out AxiStreamMasterType; + -- AXI-Lite Interface (axilClk domain) + axilClk : in sl; + axilRst : in sl; + axilReadMaster : in AxiLiteReadMasterType; + axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType; + axilWriteSlave : out AxiLiteWriteSlaveType); +end Pgp4RxLiteLowSpeedLane; + +architecture mapping of Pgp4RxLiteLowSpeedLane is + + signal deserDataMask : slv(7 downto 0) := (others => '0'); + + signal deserReset : sl := '1'; + signal gearboxAligned : sl := '0'; + signal slip : sl := '0'; + + signal phyRxValid : sl := '0'; + signal phyRxData : slv(65 downto 0); + +begin + + process(deserClk) + begin + if rising_edge(deserClk) then + bitSlip <= slip after TPD_G; + locked <= gearboxAligned after TPD_G; + end if; + end process; + + U_reset : entity surf.RstPipeline + generic map ( + TPD_G => TPD_G) + port map ( + clk => deserClk, + rstIn => deserRst, + rstOut => deserReset); + + deserDataMask <= deserData when(polarity = '0') else not(deserData); + + --------------- + -- 8:66 Gearbox + --------------- + U_Gearbox : entity surf.Gearbox + generic map ( + TPD_G => TPD_G, + SLAVE_WIDTH_G => 8, + MASTER_WIDTH_G => 66) + port map ( + clk => deserClk, + rst => deserReset, + slip => slip, + -- Slave Interface + slaveValid => '1', + slaveData => deserDataMask, + slaveBitOrder => bitOrder(0), + -- Master Interface + masterValid => phyRxValid, + masterData => phyRxData, + masterReady => '1', + masterBitOrder => bitOrder(1)); + + ------------------ + -- Gearbox Aligner + ------------------ + U_GearboxAligner : entity surf.SelectIoRxGearboxAligner + generic map ( + TPD_G => TPD_G, + SIMULATION_G => SIMULATION_G, + DLY_STEP_SIZE_G => DLY_STEP_SIZE_G, + CODE_TYPE_G => "SCRAMBLER") + port map ( + -- Clock and Reset + clk => deserClk, + rst => deserReset, + -- Line-Code Interface (CODE_TYPE_G = "LINE_CODE") + lineCodeValid => '0', + lineCodeErr => '0', + lineCodeDispErr => '0', + linkOutOfSync => '0', + -- 64b/66b Interface (CODE_TYPE_G = "SCRAMBLER") + rxHeaderValid => phyRxValid, + rxHeader => phyRxData(65 downto 64), + -- Link Status and Gearbox Slip + bitSlip => slip, + -- IDELAY (DELAY_TYPE="VAR_LOAD") Interface + dlyLoad => dlyLoad, + dlyCfg => dlyCfg, + -- Configuration Interface + enUsrDlyCfg => enUsrDlyCfg, + usrDlyCfg => usrDlyCfg, + bypFirstBerDet => bypFirstBerDet, + minEyeWidth => minEyeWidth, + lockingCntCfg => lockingCntCfg, + -- Status Interface + errorDet => errorDet, + eyeWidth => eyeWidth, + locked => gearboxAligned); + + ------------------ + -- PGPv4 Core Lite + ------------------ + U_Pgp4CoreLite : entity surf.Pgp4CoreLite + generic map ( + TPD_G => TPD_G, + NUM_VC_G => 1, -- Only 1 VC per PGPv4 Lite link + PGP_RX_ENABLE_G => true, -- Enable the RX path + PGP_TX_ENABLE_G => false, -- Disable the unused TX path + SKIP_EN_G => false, -- No skips (assumes clock source synchronous system) + FLOW_CTRL_EN_G => false, -- No flow control + EN_PGP_MON_G => true, -- Enable the AXI-Lite interface + WRITE_EN_G => true, + STATUS_CNT_WIDTH_G => STATUS_CNT_WIDTH_G, + ERROR_CNT_WIDTH_G => ERROR_CNT_WIDTH_G, + AXIL_CLK_FREQ_G => AXIL_CLK_FREQ_G) + port map ( + -- Tx User interface + pgpTxClk => deserClk, + pgpTxRst => deserReset, + pgpTxActive => '0', + pgpTxMasters => (others => AXI_STREAM_MASTER_INIT_C), + -- Tx PHY interface + phyTxActive => '0', + phyTxReady => '0', + -- Rx User interface + pgpRxClk => deserClk, + pgpRxRst => deserReset, + pgpRxMasters(0) => pgpRxMaster, + pgpRxCtrl(0) => AXI_STREAM_CTRL_UNUSED_C, + -- Rx PHY interface + phyRxClk => deserClk, + phyRxRst => deserReset, + phyRxActive => gearboxAligned, + phyRxStartSeq => '0', + phyRxValid => phyRxValid, + phyRxData => phyRxData(63 downto 0), + phyRxHeader => phyRxData(65 downto 64), + -- AXI-Lite Register Interface (axilClk domain) + axilClk => axilClk, + axilRst => axilRst, + axilReadMaster => axilReadMaster, + axilReadSlave => axilReadSlave, + axilWriteMaster => axilWriteMaster, + axilWriteSlave => axilWriteSlave); + +end mapping; diff --git a/protocols/pgp/pgp4/core/rtl/Pgp4RxLiteLowSpeedReg.vhd b/protocols/pgp/pgp4/core/rtl/Pgp4RxLiteLowSpeedReg.vhd new file mode 100644 index 0000000000..fc21864c7c --- /dev/null +++ b/protocols/pgp/pgp4/core/rtl/Pgp4RxLiteLowSpeedReg.vhd @@ -0,0 +1,223 @@ +------------------------------------------------------------------------------- +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: Pgp4RxLite Low Speed Lane Registers +------------------------------------------------------------------------------- +-- This file is part of 'SLAC Firmware Standard Library'. +-- It is subject to the license terms in the LICENSE.txt file found in the +-- top-level directory of this distribution and at: +-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +-- No part of 'SLAC Firmware Standard Library', including this file, +-- may be copied, modified, propagated, or distributed except according to +-- the terms contained in the LICENSE.txt file. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +library surf; +use surf.StdRtlPkg.all; +use surf.AxiLitePkg.all; + +entity Pgp4RxLiteLowSpeedReg is + generic ( + TPD_G : time := 1 ns; + SIMULATION_G : boolean := false; + STATUS_CNT_WIDTH_G : natural range 1 to 32 := 16; + NUM_LANE_G : positive := 1); + port ( + -- Deserialization Interface (deserClk domain) + deserClk : in sl; + deserRst : in sl; + dlyConfig : in Slv9Array(NUM_LANE_G-1 downto 0); + errorDet : in slv(NUM_LANE_G-1 downto 0); + bitSlip : in slv(NUM_LANE_G-1 downto 0); + eyeWidth : in Slv9Array(NUM_LANE_G-1 downto 0); + locked : in slv(NUM_LANE_G-1 downto 0); + enUsrDlyCfg : out sl; + usrDlyCfg : out Slv9Array(NUM_LANE_G-1 downto 0); + minEyeWidth : out slv(7 downto 0); + lockingCntCfg : out slv(23 downto 0); + bypFirstBerDet : out sl; + polarity : out slv(NUM_LANE_G-1 downto 0); + bitOrder : out slv(1 downto 0); + -- AXI-Lite Interface (axilClk domain) + axilClk : in sl; + axilRst : in sl; + axilReadMaster : in AxiLiteReadMasterType; + axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType; + axilWriteSlave : out AxiLiteWriteSlaveType); +end Pgp4RxLiteLowSpeedReg; + +architecture mapping of Pgp4RxLiteLowSpeedReg is + + constant STATUS_SIZE_C : positive := 3*NUM_LANE_G; + + type RegType is record + enUsrDlyCfg : sl; + usrDlyCfg : Slv9Array(NUM_LANE_G-1 downto 0); + minEyeWidth : slv(7 downto 0); + lockingCntCfg : slv(23 downto 0); + bypFirstBerDet : sl; + polarity : slv(NUM_LANE_G-1 downto 0); + bitOrder : slv(1 downto 0); + cntRst : sl; + rollOverEn : slv(STATUS_SIZE_C-1 downto 0); + readSlave : AxiLiteReadSlaveType; + writeSlave : AxiLiteWriteSlaveType; + end record; + + constant REG_INIT_C : RegType := ( + enUsrDlyCfg => ite(SIMULATION_G, '1', '0'), + usrDlyCfg => (others => toSlv(219, 9)), + minEyeWidth => toSlv(80, 8), + lockingCntCfg => ite(SIMULATION_G, x"00_0004", x"00_FFFF"), + bypFirstBerDet => '1', + polarity => (others => '0'), + bitOrder => (others => '0'), + cntRst => '1', + rollOverEn => (others => '0'), + readSlave => AXI_LITE_READ_SLAVE_INIT_C, + writeSlave => AXI_LITE_WRITE_SLAVE_INIT_C); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + + signal statusIn : slv(STATUS_SIZE_C-1 downto 0); + signal statusOut : slv(STATUS_SIZE_C-1 downto 0); + signal statusCnt : SlVectorArray(STATUS_SIZE_C-1 downto 0, STATUS_CNT_WIDTH_G-1 downto 0); + + signal readMaster : AxiLiteReadMasterType; + signal readSlave : AxiLiteReadSlaveType; + signal writeMaster : AxiLiteWriteMasterType; + signal writeSlave : AxiLiteWriteSlaveType; + +begin + + U_AxiLiteAsync : entity surf.AxiLiteAsync + generic map ( + TPD_G => TPD_G, + NUM_ADDR_BITS_G => 12) + port map ( + -- Slave Interface + sAxiClk => axilClk, + sAxiClkRst => axilRst, + sAxiReadMaster => axilReadMaster, + sAxiReadSlave => axilReadSlave, + sAxiWriteMaster => axilWriteMaster, + sAxiWriteSlave => axilWriteSlave, + -- Master Interface + mAxiClk => deserClk, + mAxiClkRst => deserRst, + mAxiReadMaster => readMaster, + mAxiReadSlave => readSlave, + mAxiWriteMaster => writeMaster, + mAxiWriteSlave => writeSlave); + + comb : process (deserRst, dlyConfig, eyeWidth, r, readMaster, statusCnt, + statusOut, writeMaster) is + variable v : RegType; + variable axilEp : AxiLiteEndPointType; + begin + -- Latch the current value + v := r; + + -- Reset the strobes + v.cntRst := '0'; + + -- Determine the transaction type + axiSlaveWaitTxn(axilEp, writeMaster, readMaster, v.writeSlave, v.readSlave); + + -- Map the read registers + for i in STATUS_SIZE_C-1 downto 0 loop + axiSlaveRegisterR(axilEp, toSlv((4*i), 12), 0, muxSlVectorArray(statusCnt, i)); + end loop; + axiSlaveRegisterR(axilEp, x"400", 0, statusOut); + + for i in NUM_LANE_G-1 downto 0 loop + + -- Address starts at 0x200 + axiSlaveRegisterR(axilEp, toSlv(512+4*i, 12), 0, eyeWidth(i)); + + -- Address starts at 0x500 + axiSlaveRegister (axilEp, toSlv(1280+4*i, 12), 0, v.usrDlyCfg(i)); + + -- Address starts at 0x600 + axiSlaveRegisterR(axilEp, toSlv(1536+4*i, 12), 0, dlyConfig(i)); + + end loop; + + axiSlaveRegisterR(axilEp, x"7FC", 8, toSlv(NUM_LANE_G, 8)); + + axiSlaveRegister (axilEp, x"800", 0, v.enUsrDlyCfg); + -- axiSlaveRegister (axilEp, x"804", 0, v.usrDlyCfg); -- Changed from "common" to 1 per lane + axiSlaveRegister (axilEp, x"808", 0, v.minEyeWidth); + axiSlaveRegister (axilEp, x"80C", 0, v.lockingCntCfg); + + axiSlaveRegister (axilEp, x"810", 0, v.bypFirstBerDet); + axiSlaveRegister (axilEp, x"814", 0, v.polarity); + axiSlaveRegister (axilEp, x"818", 0, v.bitOrder); + + axiSlaveRegister (axilEp, x"FF8", 0, v.rollOverEn); + axiSlaveRegister (axilEp, x"FFC", 0, v.cntRst); + + -- Closeout the transaction + axiSlaveDefault(axilEp, v.writeSlave, v.readSlave, AXI_RESP_DECERR_C); + + -- Outputs + writeSlave <= r.writeSlave; + readSlave <= r.readSlave; + enUsrDlyCfg <= r.enUsrDlyCfg; + usrDlyCfg <= r.usrDlyCfg; + minEyeWidth <= r.minEyeWidth; + lockingCntCfg <= r.lockingCntCfg; + bypFirstBerDet <= r.bypFirstBerDet; + polarity <= r.polarity; + bitOrder <= r.bitOrder; + + -- Synchronous Reset + if (deserRst = '1') then + v := REG_INIT_C; + end if; + + -- Register the variable for next clock cycle + rin <= v; + + end process comb; + + seq : process (deserClk) is + begin + if (rising_edge(deserClk)) then + r <= rin after TPD_G; + end if; + end process seq; + + U_SyncStatusVector : entity surf.SyncStatusVector + generic map ( + TPD_G => TPD_G, + COMMON_CLK_G => true, + OUT_POLARITY_G => '1', + CNT_RST_EDGE_G => false, + CNT_WIDTH_G => STATUS_CNT_WIDTH_G, + WIDTH_G => STATUS_SIZE_C) + port map ( + -- Input Status bit Signals (wrClk domain) + statusIn => statusIn, + -- Output Status bit Signals (rdClk domain) + statusOut => statusOut, + -- Status Bit Counters Signals (rdClk domain) + cntRstIn => r.cntRst, + rollOverEnIn => r.rollOverEn, + cntOut => statusCnt, + -- Clocks and Reset Ports + wrClk => deserClk, + rdClk => deserClk); + + statusIn((2*NUM_LANE_G)+NUM_LANE_G-1 downto 2*NUM_LANE_G) <= errorDet; + statusIn((1*NUM_LANE_G)+NUM_LANE_G-1 downto 1*NUM_LANE_G) <= bitSlip; + statusIn((0*NUM_LANE_G)+NUM_LANE_G-1 downto 0*NUM_LANE_G) <= locked; + +end mapping; diff --git a/python/surf/protocols/pgp/_Pgp4RxLiteLowSpeedReg.py b/python/surf/protocols/pgp/_Pgp4RxLiteLowSpeedReg.py new file mode 100644 index 0000000000..5cef5d059f --- /dev/null +++ b/python/surf/protocols/pgp/_Pgp4RxLiteLowSpeedReg.py @@ -0,0 +1,197 @@ +#----------------------------------------------------------------------------- +# This file is part of the 'SLAC Firmware Standard Library'. It is subject to +# the license terms in the LICENSE.txt file found in the top-level directory +# of this distribution and at: +# https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +# No part of the 'SLAC Firmware Standard Library', including this file, may be +# copied, modified, propagated, or distributed except according to the terms +# contained in the LICENSE.txt file. +#----------------------------------------------------------------------------- + +import pyrogue as pr + +class Pgp4RxLiteLowSpeedReg(pr.Device): + def __init__(self, + numberLanes = 1, + statusCountBits = 16, + **kwargs): + super().__init__(**kwargs) + + self.addRemoteVariables( + name = 'LockedCnt', + description = 'status count that increases per locked detection event', + offset = 0*(numberLanes<<2), + bitSize = statusCountBits, + mode = 'RO', + number = numberLanes, + stride = 4, + pollInterval = 1, + ) + + self.addRemoteVariables( + name = 'BitSlipCnt', + description = 'status count that increases per bitslip detection event', + offset = 1*(numberLanes<<2), + bitSize = statusCountBits, + mode = 'RO', + number = numberLanes, + stride = 4, + pollInterval = 1, + ) + + self.addRemoteVariables( + name = 'ErrorDetCnt', + description = 'status count that increases per error detection event', + offset = 2*(numberLanes<<2), + bitSize = statusCountBits, + mode = 'RO', + number = numberLanes, + stride = 4, + pollInterval = 1, + ) + + self.addRemoteVariables( + name = 'EyeWidth', + description = 'Measured eye width after locking completed', + offset = 0x200, + bitSize = 9, + mode = 'RO', + number = numberLanes, + stride = 4, + pollInterval = 1, + ) + + self.add(pr.RemoteVariable( + name = 'Locked', + description = 'auto aligner locked status', + offset = 0x400, + bitSize = numberLanes, + mode = 'RO', + pollInterval = 1, + )) + + self.addRemoteVariables( + name = 'UsrDlyCfg', + description = 'manual user delay value when EnUsrDlyCfg = 0x1', + offset = 0x500, + bitSize = 9, + mode = 'RW', + number = numberLanes, + stride = 4, + ) + + self.addRemoteVariables( + name = 'DlyConfig', + description = 'Current IDELAY value', + offset = 0x600, + bitSize = 9, + mode = 'RO', + number = numberLanes, + stride = 4, + pollInterval = 1, + ) + + self.add(pr.RemoteVariable( + name = 'NUM_LANE_G', + description = 'NUM_LANE_G VHDL genenic value', + offset = 0x7FC, + bitSize = 8, + bitOffset = 8, + mode = 'RO', + disp = '{:d}', + )) + + self.add(pr.RemoteVariable( + name = 'EnUsrDlyCfg', + description = 'Enables User delay config (UsrDlyCfg)', + offset = 0x800, + bitSize = 1, + mode = 'RW', + )) + +##################################### +# Changed from "common" to 1 per lane +##################################### +# self.add(pr.RemoteVariable( +# name = 'UsrDlyCfg', +# description = 'User delay config', +# offset = 0x804, +# bitSize = 9, +# mode = 'RW', +# )) + + self.add(pr.RemoteVariable( + name = 'MinEyeWidth', + description = 'Sets the minimum eye width required for locking (units of IDELAY step)', + offset = 0x808, + bitSize = 8, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'LockingCntCfg', + description = 'Number of error-free event before state=LOCKED_S', + offset = 0x80C, + bitSize = 24, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'BypFirstBerDet', + description = 'Set to 0x1 if IDELAY full scale range > 2 Unit Intervals (UI) of serial rate (example: IDELAY range 2.5ns > 1 ns (1Gb/s) )', + offset = 0x810, + bitSize = 1, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'Polarity', + description = '1: Invert diff pair, 0: Non-inverted diff pair', + offset = 0x814, + bitSize = numberLanes, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'GearboxSlaveBitOrder', + description = '1: reverse gearbox input bit ordering, 0: normal bit ordering', + offset = 0x818, + bitSize = 1, + bitOffset = 0, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'GearboxMasterBitOrder', + description = '1: reverse gearbox output bit ordering, 0: normal', + offset = 0x818, + bitSize = 1, + bitOffset = 1, + mode = 'RW', + )) + + self.add(pr.RemoteVariable( + name = 'RollOverEn', + description = 'Rollover enable for status counters', + offset = 0xFF8, + bitSize = 7, + mode = 'RW', + )) + + self.add(pr.RemoteCommand( + name = 'CntRst', + description = 'Status counter reset', + offset = 0xFFC, + bitSize = 1, + function = lambda cmd: cmd.post(1), + hidden = False, + )) + + def hardReset(self): + self.CntRst() + + def softReset(self): + self.CntRst() + + def countReset(self): + self.CntRst() diff --git a/python/surf/protocols/pgp/__init__.py b/python/surf/protocols/pgp/__init__.py index 4dc84b367a..c15cdbbeae 100644 --- a/python/surf/protocols/pgp/__init__.py +++ b/python/surf/protocols/pgp/__init__.py @@ -11,3 +11,4 @@ from surf.protocols.pgp._Pgp2fcAxi import * from surf.protocols.pgp._Pgp3AxiL import * from surf.protocols.pgp._Pgp4AxiL import * +from surf.protocols.pgp._Pgp4RxLiteLowSpeedReg import *