diff --git a/axi/axi-stream/rtl/AxiStreamDeMux.vhd b/axi/axi-stream/rtl/AxiStreamDeMux.vhd index 5dd0cd8767..f1e798b3db 100644 --- a/axi/axi-stream/rtl/AxiStreamDeMux.vhd +++ b/axi/axi-stream/rtl/AxiStreamDeMux.vhd @@ -26,6 +26,7 @@ use surf.AxiStreamPkg.all; entity AxiStreamDeMux is generic ( TPD_G : time := 1 ns; + RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset RST_ASYNC_G : boolean := false; NUM_MASTERS_G : integer range 1 to 256 := 12; MODE_G : string := "INDEXED"; -- Or "ROUTED" Or "DYNAMIC" @@ -39,7 +40,7 @@ entity AxiStreamDeMux is axisRst : in sl; -- Dynamic Route Table (only used when MODE_G = "DYNAMIC") dynamicRouteMasks : in slv8Array(NUM_MASTERS_G-1 downto 0) := (others => "00000000"); - dynamicRouteDests : in slv8Array(NUM_MASTERS_G-1 downto 0) := (others => "00000000"); + dynamicRouteDests : in slv8Array(NUM_MASTERS_G-1 downto 0) := (others => "00000000"); -- Slave sAxisMaster : in AxiStreamMasterType; sAxisSlave : out AxiStreamSlaveType; @@ -139,7 +140,7 @@ begin sAxisSlave <= v.slave; -- Reset - if (RST_ASYNC_G = false and axisRst = '1') then + if (RST_ASYNC_G = false and axisRst = RST_POLARITY_G) then v := REG_INIT_C; end if; @@ -151,14 +152,14 @@ begin end process comb; - GEN_VEC : - for i in (NUM_MASTERS_G-1) downto 0 generate + GEN_VEC : for i in (NUM_MASTERS_G-1) downto 0 generate U_Pipeline : entity surf.AxiStreamPipeline generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - PIPE_STAGES_G => PIPE_STAGES_G) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G, + PIPE_STAGES_G => PIPE_STAGES_G) port map ( axisClk => axisClk, axisRst => axisRst, @@ -171,7 +172,7 @@ begin seq : process (axisClk, axisRst) is begin - if (RST_ASYNC_G and axisRst = '1') then + if (RST_ASYNC_G and axisRst = RST_POLARITY_G) then r <= REG_INIT_C after TPD_G; elsif rising_edge(axisClk) then r <= rin after TPD_G; diff --git a/axi/axi-stream/rtl/AxiStreamMux.vhd b/axi/axi-stream/rtl/AxiStreamMux.vhd index 7a12f90d5a..0b49679101 100644 --- a/axi/axi-stream/rtl/AxiStreamMux.vhd +++ b/axi/axi-stream/rtl/AxiStreamMux.vhd @@ -27,6 +27,7 @@ use surf.AxiStreamPkg.all; entity AxiStreamMux is generic ( TPD_G : time := 1 ns; + RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset RST_ASYNC_G : boolean := false; PIPE_STAGES_G : integer range 0 to 16 := 0; NUM_SLAVES_G : integer range 1 to 256 := 4; @@ -308,7 +309,7 @@ begin sAxisSlaves <= v.slaves; -- Reset - if (RST_ASYNC_G = false and axisRst = '1') then + if (RST_ASYNC_G = false and axisRst = RST_POLARITY_G) then v := REG_INIT_C; end if; @@ -322,7 +323,7 @@ begin seq : process (axisClk, axisRst) is begin - if (RST_ASYNC_G) and (axisRst = '1') then + if (RST_ASYNC_G) and (axisRst = RST_POLARITY_G) then r <= REG_INIT_C after TPD_G; elsif rising_edge(axisClk) then r <= rin after TPD_G; @@ -332,9 +333,10 @@ begin -- Optional output pipeline registers to ease timing AxiStreamPipeline_1 : entity surf.AxiStreamPipeline generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - PIPE_STAGES_G => PIPE_STAGES_G) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G, + PIPE_STAGES_G => PIPE_STAGES_G) port map ( axisClk => axisClk, axisRst => axisRst, diff --git a/axi/axi-stream/rtl/AxiStreamPipeline.vhd b/axi/axi-stream/rtl/AxiStreamPipeline.vhd index 8d706f866b..1a0cd2dcae 100644 --- a/axi/axi-stream/rtl/AxiStreamPipeline.vhd +++ b/axi/axi-stream/rtl/AxiStreamPipeline.vhd @@ -23,6 +23,7 @@ use surf.AxiStreamPkg.all; entity AxiStreamPipeline is generic ( TPD_G : time := 1 ns; + RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset RST_ASYNC_G : boolean := false; SIDE_BAND_WIDTH_G : positive := 1; -- General purpose sideband PIPE_STAGES_G : natural := 0); @@ -148,7 +149,7 @@ begin mSideBand <= r.mSideBand(PIPE_STAGES_C); -- Synchronous Reset - if (RST_ASYNC_G = false and axisRst = '1') then + if (RST_ASYNC_G = false and axisRst = RST_POLARITY_G) then v := REG_INIT_C; end if; @@ -159,7 +160,7 @@ begin seq : process (axisClk, axisRst) is begin - if (RST_ASYNC_G and axisRst = '1') then + if (RST_ASYNC_G and axisRst = RST_POLARITY_G) then r <= REG_INIT_C after TPD_G; elsif rising_edge(axisClk) then r <= rin after TPD_G; diff --git a/base/crc/rtl/Crc32.vhd b/base/crc/rtl/Crc32.vhd index 5293cd6ba3..1b3582de6a 100644 --- a/base/crc/rtl/Crc32.vhd +++ b/base/crc/rtl/Crc32.vhd @@ -34,15 +34,16 @@ use surf.CrcPkg.all; entity Crc32 is generic ( TPD_G : time := 1 ns; + RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset RST_ASYNC_G : boolean := false; BYTE_WIDTH_G : positive := 4; INPUT_REGISTER_G : boolean := true; CRC_INIT_G : slv(31 downto 0) := x"FFFFFFFF"; CRC_POLY_G : slv(31 downto 0) := x"04C11DB7"); port ( - crcPwrOnRst : in sl := '0'; - crcOut : out slv(31 downto 0); -- CRC output - crcRem : out slv(31 downto 0); -- CRC interim remainder + crcPwrOnRst : in sl := not RST_POLARITY_G; + crcOut : out slv(31 downto 0); -- CRC output + crcRem : out slv(31 downto 0); -- CRC interim remainder crcClk : in sl; -- system clock crcDataValid : in sl; -- indicate that new data arrived and CRC can be computed crcDataWidth : in slv(2 downto 0); -- indicate width in bytes minus 1, 0 - 1 byte, 1 - 2 bytes ... , 7 - 8 bytes @@ -146,10 +147,10 @@ begin seq : process (crcClk, crcPwrOnRst) is begin - if (RST_ASYNC_G and crcPwrOnRst = '1') then + if (RST_ASYNC_G and crcPwrOnRst = RST_POLARITY_G) then r <= REG_INIT_C after TPD_G; - elsif (rising_edge(crcClk)) then - if (RST_ASYNC_G = false and crcPwrOnRst = '1') then + elsif (rising_edge(crcClk)) then + if (RST_ASYNC_G = false and crcPwrOnRst = RST_POLARITY_G) then r <= REG_INIT_C after TPD_G; else r <= rin after TPD_G; diff --git a/base/crc/rtl/Crc32Parallel.vhd b/base/crc/rtl/Crc32Parallel.vhd old mode 100755 new mode 100644 index 7222680894..aee2bededa --- a/base/crc/rtl/Crc32Parallel.vhd +++ b/base/crc/rtl/Crc32Parallel.vhd @@ -40,20 +40,21 @@ use surf.CrcPkg.all; entity Crc32Parallel is generic ( TPD_G : time := 1 ns; + RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset RST_ASYNC_G : boolean := false; BYTE_WIDTH_G : positive := 4; INPUT_REGISTER_G : boolean := true; CRC_INIT_G : slv(31 downto 0) := x"FFFFFFFF"); port ( - crcPwrOnRst : in sl := '0'; - crcOut : out slv(31 downto 0); -- CRC output - crcRem : out slv(31 downto 0); -- CRC interim remainder + crcPwrOnRst : in sl := not RST_POLARITY_G; + crcOut : out slv(31 downto 0); -- CRC output + crcRem : out slv(31 downto 0); -- CRC interim remainder crcClk : in sl; -- system clock crcDataValid : in sl; -- indicate that new data arrived and CRC can be computed crcDataWidth : in slv(2 downto 0); -- indicate width in bytes minus 1, 0 - 1 byte, 1 - 2 bytes ... , 7 - 8 bytes crcIn : in slv((BYTE_WIDTH_G*8-1) downto 0); -- input data for CRC calculation crcInit : in slv(31 downto 0) := CRC_INIT_G; -- optional override of CRC_INIT_G - crcReset : in sl); -- initializes CRC logic to crcInit + crcReset : in sl); -- initializes CRC logic to crcInit end Crc32Parallel; architecture rtl of Crc32Parallel is @@ -188,10 +189,10 @@ begin seq : process (crcClk, crcPwrOnRst) is begin - if (RST_ASYNC_G and crcPwrOnRst = '1') then + if (RST_ASYNC_G and crcPwrOnRst = RST_POLARITY_G) then r <= REG_INIT_C after TPD_G; - elsif (rising_edge(crcClk)) then - if (RST_ASYNC_G = false and crcPwrOnRst = '1') then + elsif (rising_edge(crcClk)) then + if (RST_ASYNC_G = false and crcPwrOnRst = RST_POLARITY_G) then r <= REG_INIT_C after TPD_G; else r <= rin after TPD_G; diff --git a/base/general/rtl/Scrambler.vhd b/base/general/rtl/Scrambler.vhd index 614239cb64..c6a9948f69 100644 --- a/base/general/rtl/Scrambler.vhd +++ b/base/general/rtl/Scrambler.vhd @@ -25,6 +25,7 @@ use surf.StdRtlPkg.all; entity Scrambler is generic ( TPD_G : time := 1 ns; + RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset RST_ASYNC_G : boolean := false; DIRECTION_G : string := "SCRAMBLER"; -- or DESCRAMBLER DATA_WIDTH_G : integer := 64; @@ -129,7 +130,7 @@ begin inputReady <= v.inputReady; -- Reset - if (RST_ASYNC_G = false and rst = '1') then + if (RST_ASYNC_G = false and rst = RST_POLARITY_G) then v := REG_INIT_C; end if; @@ -150,7 +151,7 @@ begin seq : process (clk, rst) is begin - if (RST_ASYNC_G and rst = '1') then + if (RST_ASYNC_G and rst = RST_POLARITY_G) then r <= REG_INIT_C after TPD_G; elsif rising_edge(clk) then r <= rin after TPD_G; diff --git a/base/sync/rtl/RstSync.vhd b/base/sync/rtl/RstSync.vhd index 0da4f2a68d..cca8ab948b 100644 --- a/base/sync/rtl/RstSync.vhd +++ b/base/sync/rtl/RstSync.vhd @@ -4,6 +4,9 @@ -- Description: Synchronizes the trailing edge of an asynchronous reset to a -- given clock. ------------------------------------------------------------------------------- +-- Note: Using "std_logic" instead of "sl" for generics due to issues with +-- SystemVerilog handling VHDL subtype on generics properly +------------------------------------------------------------------------------- -- 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: @@ -21,9 +24,9 @@ use surf.StdRtlPkg.all; entity RstSync is generic ( - TPD_G : time := 1 ns; -- Simulation FF output delay - IN_POLARITY_G : sl := '1'; -- 0 for active low rst, 1 for high - OUT_POLARITY_G : sl := '1'; + TPD_G : time := 1 ns; -- Simulation FF output delay + IN_POLARITY_G : std_logic := '1'; -- 0 for active low rst, 1 for high + OUT_POLARITY_G : std_logic := '1'; BYPASS_SYNC_G : boolean := false; -- Bypass Synchronizer module for synchronous data configuration RELEASE_DELAY_G : integer range 3 to positive'high := 3; -- Delay between deassertion of async and sync resets OUT_REG_RST_G : boolean := true); -- Apply async reset to final reg stage @@ -57,7 +60,7 @@ begin dataOut => syncInt); -- Final stage does not have async constraints applied, can be duplicated to ease timing - OUT_REG : process (clk, asyncRst) is + OUT_REG : process (asyncRst, clk) is begin if (asyncRst = IN_POLARITY_G and OUT_REG_RST_G) then syncRst <= OUT_POLARITY_G after TPD_G; diff --git a/base/sync/rtl/SynchronizerFifo.vhd b/base/sync/rtl/SynchronizerFifo.vhd index 7b50cff926..4233d12fd6 100644 --- a/base/sync/rtl/SynchronizerFifo.vhd +++ b/base/sync/rtl/SynchronizerFifo.vhd @@ -22,18 +22,19 @@ use surf.StdRtlPkg.all; entity SynchronizerFifo is generic ( - TPD_G : time := 1 ns; - RST_ASYNC_G : boolean := false; - COMMON_CLK_G : boolean := false; -- Bypass FifoAsync module for synchronous data configuration - MEMORY_TYPE_G : string := "distributed"; - SYNC_STAGES_G : integer range 3 to (2**24) := 3; - PIPE_STAGES_G : natural range 0 to 16 := 0; - DATA_WIDTH_G : integer range 1 to (2**24) := 16; - ADDR_WIDTH_G : integer range 2 to 48 := 4; - INIT_G : slv := "0"); + TPD_G : time := 1 ns; + RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset + RST_ASYNC_G : boolean := false; + COMMON_CLK_G : boolean := false; -- Bypass FifoAsync module for synchronous data configuration + MEMORY_TYPE_G : string := "distributed"; + SYNC_STAGES_G : integer range 3 to (2**24) := 3; + PIPE_STAGES_G : natural range 0 to 16 := 0; + DATA_WIDTH_G : integer range 1 to (2**24) := 16; + ADDR_WIDTH_G : integer range 2 to 48 := 4; + INIT_G : slv := "0"); port ( -- Asynchronous Reset - rst : in sl := '0'; + rst : in sl := not RST_POLARITY_G; -- Write Ports (wr_clk domain) wr_clk : in sl; wr_en : in sl := '1'; @@ -58,15 +59,16 @@ begin FifoAsync_1 : entity surf.FifoAsync generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - MEMORY_TYPE_G => MEMORY_TYPE_G, - FWFT_EN_G => true, - SYNC_STAGES_G => SYNC_STAGES_G, - PIPE_STAGES_G => PIPE_STAGES_G, - DATA_WIDTH_G => DATA_WIDTH_G, - ADDR_WIDTH_G => ADDR_WIDTH_G, - INIT_G => INIT_C) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G, + MEMORY_TYPE_G => MEMORY_TYPE_G, + FWFT_EN_G => true, + SYNC_STAGES_G => SYNC_STAGES_G, + PIPE_STAGES_G => PIPE_STAGES_G, + DATA_WIDTH_G => DATA_WIDTH_G, + ADDR_WIDTH_G => ADDR_WIDTH_G, + INIT_G => INIT_C) port map ( rst => rst, wr_clk => wr_clk, diff --git a/protocols/packetizer/rtl/AxiStreamDepacketizer2.vhd b/protocols/packetizer/rtl/AxiStreamDepacketizer2.vhd index 8f7912faa6..4571eb9c35 100644 --- a/protocols/packetizer/rtl/AxiStreamDepacketizer2.vhd +++ b/protocols/packetizer/rtl/AxiStreamDepacketizer2.vhd @@ -30,6 +30,7 @@ use surf.AxiStreamPacketizer2Pkg.all; entity AxiStreamDepacketizer2 is generic ( TPD_G : time := 1 ns; + RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset RST_ASYNC_G : boolean := false; MEMORY_TYPE_G : string := "distributed"; REG_EN_G : boolean := false; @@ -159,9 +160,10 @@ begin ----------------- U_Input : entity surf.AxiStreamPipeline generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - PIPE_STAGES_G => INPUT_PIPE_STAGES_G) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G, + PIPE_STAGES_G => INPUT_PIPE_STAGES_G) port map ( axisClk => axisClk, axisRst => axisRst, @@ -186,15 +188,16 @@ begin GEN_SEQ : if (SEQ_CNT_SIZE_G > 0) generate U_DualPortRam_1 : entity surf.DualPortRam generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - MEMORY_TYPE_G => MEMORY_TYPE_G, - REG_EN_G => REG_EN_G, - DOA_REG_G => REG_EN_G, - DOB_REG_G => REG_EN_G, - BYTE_WR_EN_G => false, - DATA_WIDTH_G => RAM_DATA_WIDTH_C, - ADDR_WIDTH_G => ADDR_WIDTH_C) + TPD_G => TPD_G, + RST_ASYNC_G => RST_ASYNC_G, + RST_POLARITY_G => RST_POLARITY_G, + MEMORY_TYPE_G => MEMORY_TYPE_G, + REG_EN_G => REG_EN_G, + DOA_REG_G => REG_EN_G, + DOB_REG_G => REG_EN_G, + BYTE_WR_EN_G => false, + DATA_WIDTH_G => RAM_DATA_WIDTH_C, + ADDR_WIDTH_G => ADDR_WIDTH_C) port map ( clka => axisClk, rsta => axisRst, @@ -207,10 +210,10 @@ begin NO_SEQ : if (SEQ_CNT_SIZE_G = 0) generate process (axisClk, axisRst) is begin - if (RST_ASYNC_G and axisRst = '1') then + if (RST_ASYNC_G and axisRst = RST_POLARITY_G) then ramDout <= (others => '0') after TPD_G; elsif (rising_edge(axisClk)) then - if (RST_ASYNC_G = false and axisRst = '1') then + if (RST_ASYNC_G = false and axisRst = RST_POLARITY_G) then ramDout <= (others => '0') after TPD_G; else ramDout <= ramDin after TPD_G; @@ -228,6 +231,7 @@ begin U_Crc32 : entity surf.Crc32Parallel generic map ( TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, RST_ASYNC_G => RST_ASYNC_G, INPUT_REGISTER_G => false, BYTE_WIDTH_G => 8, @@ -248,6 +252,7 @@ begin U_Crc32 : entity surf.Crc32 generic map ( TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, RST_ASYNC_G => RST_ASYNC_G, INPUT_REGISTER_G => false, BYTE_WIDTH_G => 8, @@ -649,10 +654,10 @@ begin seq : process (axisClk, axisRst) is begin - if (RST_ASYNC_G and axisRst = '1') then + if (RST_ASYNC_G and axisRst = RST_POLARITY_G) then r <= REG_INIT_C after TPD_G; elsif (rising_edge(axisClk)) then - if (RST_ASYNC_G = false and axisRst = '1') then + if (RST_ASYNC_G = false and axisRst = RST_POLARITY_G) then r <= REG_INIT_C after TPD_G; else r <= rin after TPD_G; @@ -665,9 +670,10 @@ begin ------------------ U_Output : entity surf.AxiStreamPipeline generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - PIPE_STAGES_G => OUTPUT_PIPE_STAGES_G) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G, + PIPE_STAGES_G => OUTPUT_PIPE_STAGES_G) port map ( axisClk => axisClk, axisRst => axisRst, diff --git a/protocols/pgp/pgp3/core/rtl/Pgp3RxGearboxAligner.vhd b/protocols/pgp/pgp3/core/rtl/Pgp3RxGearboxAligner.vhd index 73afb8b48d..0b175365e0 100644 --- a/protocols/pgp/pgp3/core/rtl/Pgp3RxGearboxAligner.vhd +++ b/protocols/pgp/pgp3/core/rtl/Pgp3RxGearboxAligner.vhd @@ -27,9 +27,10 @@ use surf.StdRtlPkg.all; entity Pgp3RxGearboxAligner is generic ( - TPD_G : time := 1 ns; - RST_ASYNC_G : boolean := false; - SLIP_WAIT_G : integer := 32); + TPD_G : time := 1 ns; + RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset + RST_ASYNC_G : boolean := false; + SLIP_WAIT_G : integer := 32); port ( clk : in sl; rst : in sl; @@ -119,7 +120,7 @@ begin when others => null; end case; - if (RST_ASYNC_G = false and rst = '1') then + if (RST_ASYNC_G = false and rst = RST_POLARITY_G) then v := REG_INIT_C; end if; @@ -132,7 +133,7 @@ begin seq : process (clk, rst) is begin - if (RST_ASYNC_G) and (rst = '1') then + if (RST_ASYNC_G) and (rst = RST_POLARITY_G) then r <= REG_INIT_C after TPD_G; elsif rising_edge(clk) then r <= rin after TPD_G; diff --git a/protocols/pgp/pgp4/core/rtl/Pgp4Rx.vhd b/protocols/pgp/pgp4/core/rtl/Pgp4Rx.vhd index 8a61df5ebd..4460018892 100644 --- a/protocols/pgp/pgp4/core/rtl/Pgp4Rx.vhd +++ b/protocols/pgp/pgp4/core/rtl/Pgp4Rx.vhd @@ -29,6 +29,7 @@ use surf.AxiStreamPacketizer2Pkg.all; entity Pgp4Rx is generic ( TPD_G : time := 1 ns; + RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset RST_ASYNC_G : boolean := false; NUM_VC_G : integer range 1 to 16 := 4; SKIP_EN_G : boolean := true; -- TRUE for Elastic Buffer @@ -99,9 +100,10 @@ begin -- Gearbox aligner U_Pgp3RxGearboxAligner_1 : entity surf.Pgp3RxGearboxAligner -- Same RX gearbox aligner as PGPv3 generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - SLIP_WAIT_G => ALIGN_SLIP_WAIT_G) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G, + SLIP_WAIT_G => ALIGN_SLIP_WAIT_G) port map ( clk => phyRxClk, -- [in] rst => phyRxRst, -- [in] @@ -115,6 +117,7 @@ begin U_Scrambler_1 : entity surf.Scrambler generic map ( TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, RST_ASYNC_G => RST_ASYNC_G, DIRECTION_G => "DESCRAMBLER", DATA_WIDTH_G => 64, @@ -134,8 +137,9 @@ begin -- Elastic Buffer U_Pgp4RxEb_1 : entity surf.Pgp4RxEb generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G) port map ( phyRxClk => phyRxClk, -- [in] phyRxRst => phyRxRst, -- [in] @@ -161,9 +165,10 @@ begin -- Main RX protocol logic U_Pgp4RxProtocol_1 : entity surf.Pgp4RxProtocol generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - NUM_VC_G => NUM_VC_G) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G, + NUM_VC_G => NUM_VC_G) port map ( pgpRxClk => pgpRxClk, -- [in] pgpRxRst => pgpRxRst, -- [in] @@ -185,6 +190,7 @@ begin U_AxiStreamDepacketizer2_1 : entity surf.AxiStreamDepacketizer2 generic map ( TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, RST_ASYNC_G => RST_ASYNC_G, MEMORY_TYPE_G => "distributed", CRC_MODE_G => "DATA", @@ -206,13 +212,14 @@ begin -- Demultiplex the depacketized streams U_AxiStreamDeMux_1 : entity surf.AxiStreamDeMux generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - NUM_MASTERS_G => NUM_VC_G, - MODE_G => "INDEXED", - PIPE_STAGES_G => 0, - TDEST_HIGH_G => 7, - TDEST_LOW_G => 0) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G, + NUM_MASTERS_G => NUM_VC_G, + MODE_G => "INDEXED", + PIPE_STAGES_G => 0, + TDEST_HIGH_G => 7, + TDEST_LOW_G => 0) port map ( axisClk => pgpRxClk, -- [in] axisRst => pgpRxRst, -- [in] diff --git a/protocols/pgp/pgp4/core/rtl/Pgp4RxEb.vhd b/protocols/pgp/pgp4/core/rtl/Pgp4RxEb.vhd index 71164c686b..78a66cab2c 100644 --- a/protocols/pgp/pgp4/core/rtl/Pgp4RxEb.vhd +++ b/protocols/pgp/pgp4/core/rtl/Pgp4RxEb.vhd @@ -25,8 +25,9 @@ use surf.Pgp4Pkg.all; entity Pgp4RxEb is generic ( - TPD_G : time := 1 ns; - RST_ASYNC_G : boolean := false); + TPD_G : time := 1 ns; + RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset + RST_ASYNC_G : boolean := false); port ( phyRxClk : in sl; phyRxRst : in sl; @@ -112,7 +113,7 @@ begin end if; -- Reset - if (RST_ASYNC_G = false and phyRxRst = '1') then + if (RST_ASYNC_G = false and phyRxRst = RST_POLARITY_G) then -- Maintain save behavior before the remLinkData update (not reseting fifoIn or fifoWrEn) v.remLinkData := (others => '0'); end if; @@ -124,7 +125,7 @@ begin seq : process (phyRxClk, phyRxRst) is begin - if (RST_ASYNC_G) and (phyRxRst = '1') then + if (RST_ASYNC_G) and (phyRxRst = RST_POLARITY_G) then r <= REG_INIT_C after TPD_G; elsif rising_edge(phyRxClk) then r <= rin after TPD_G; @@ -133,9 +134,10 @@ begin U_remLinkData : entity surf.SynchronizerFifo generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - DATA_WIDTH_G => 48) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G, + DATA_WIDTH_G => 48) port map ( rst => phyRxRst, wr_clk => phyRxClk, @@ -146,13 +148,14 @@ begin U_FifoAsync_1 : entity surf.FifoAsync generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - MEMORY_TYPE_G => "block", - FWFT_EN_G => true, - PIPE_STAGES_G => 0, - DATA_WIDTH_G => 66, - ADDR_WIDTH_G => 9) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G, + MEMORY_TYPE_G => "block", + FWFT_EN_G => true, + PIPE_STAGES_G => 0, + DATA_WIDTH_G => 66, + ADDR_WIDTH_G => 9) port map ( rst => phyRxRst, -- Write Interface 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..c533f3a121 --- /dev/null +++ b/protocols/pgp/pgp4/core/rtl/Pgp4RxLiteLowSpeedLane.vhd @@ -0,0 +1,205 @@ +------------------------------------------------------------------------------- +-- 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); + + signal phyRxValidMask : sl := '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); + + -- Mask off the Valid until the gearbox is locked + phyRxValidMask <= phyRxValid and 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 => phyRxValidMask, + 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/protocols/pgp/pgp4/core/rtl/Pgp4RxProtocol.vhd b/protocols/pgp/pgp4/core/rtl/Pgp4RxProtocol.vhd index c0f7164bba..6aacdcaf92 100644 --- a/protocols/pgp/pgp4/core/rtl/Pgp4RxProtocol.vhd +++ b/protocols/pgp/pgp4/core/rtl/Pgp4RxProtocol.vhd @@ -31,9 +31,10 @@ use surf.Pgp4Pkg.all; entity Pgp4RxProtocol is generic ( - TPD_G : time := 1 ns; - RST_ASYNC_G : boolean := false; - NUM_VC_G : integer range 1 to 16 := 4); + TPD_G : time := 1 ns; + RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset + RST_ASYNC_G : boolean := false; + NUM_VC_G : integer range 1 to 16 := 4); port ( -- User Transmit interface pgpRxClk : in sl; @@ -90,8 +91,9 @@ begin U_phyRxActiveSync : entity surf.SynchronizerEdge generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G) port map ( clk => pgpRxClk, rst => pgpRxRst, @@ -278,7 +280,7 @@ begin locRxLinkReady <= r.pgpRxOut.linkReady; -- Reset - if (RST_ASYNC_G = false and pgpRxRst = '1') then + if (RST_ASYNC_G = false and pgpRxRst = RST_POLARITY_G) then v := REG_INIT_C; end if; @@ -289,7 +291,7 @@ begin seq : process (pgpRxClk, pgpRxRst) is begin - if (RST_ASYNC_G) and (pgpRxRst = '1') then + if (RST_ASYNC_G) and (pgpRxRst = RST_POLARITY_G) then r <= REG_INIT_C after TPD_G; elsif rising_edge(pgpRxClk) then r <= rin after TPD_G; diff --git a/protocols/pgp/pgp4/core/rtl/Pgp4TxLite.vhd b/protocols/pgp/pgp4/core/rtl/Pgp4TxLite.vhd index 0a3a179ffe..8cafbe26c1 100644 --- a/protocols/pgp/pgp4/core/rtl/Pgp4TxLite.vhd +++ b/protocols/pgp/pgp4/core/rtl/Pgp4TxLite.vhd @@ -28,6 +28,7 @@ use surf.Pgp4Pkg.all; entity Pgp4TxLite is generic ( TPD_G : time := 1 ns; + RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset RST_ASYNC_G : boolean := false; NUM_VC_G : integer range 1 to 16 := 1; SKIP_EN_G : boolean := false; @@ -82,8 +83,9 @@ begin -- Synchronize remote link and FIFO status to tx clock U_Synchronizer_REM : entity surf.Synchronizer generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G) port map ( clk => pgpTxClk, -- [in] rst => pgpTxRst, -- [in] @@ -92,9 +94,10 @@ begin REM_STATUS_SYNC : for i in NUM_VC_G-1 downto 0 generate U_SynchronizerVector_1 : entity surf.SynchronizerVector generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - WIDTH_G => 2) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G, + WIDTH_G => 2) port map ( clk => pgpTxClk, -- [in] rst => pgpTxRst, -- [in] @@ -107,8 +110,9 @@ begin -- Synchronize local rx status U_Synchronizer_LOC : entity surf.Synchronizer generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G) port map ( clk => pgpTxClk, -- [in] rst => pgpTxRst, -- [in] @@ -117,8 +121,9 @@ begin LOC_STATUS_SYNC : for i in NUM_VC_G-1 downto 0 generate U_Synchronizer_pause : entity surf.Synchronizer generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G) port map ( clk => pgpTxClk, -- [in] rst => pgpTxRst, -- [in] @@ -126,8 +131,9 @@ begin dataOut => syncLocRxFifoCtrl(i).pause); -- [out] U_Synchronizer_overflow : entity surf.SynchronizerOneShot generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G) + TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, + RST_ASYNC_G => RST_ASYNC_G) port map ( clk => pgpTxClk, -- [in] rst => pgpTxRst, -- [in] @@ -158,6 +164,7 @@ begin U_AxiStreamMux_1 : entity surf.AxiStreamMux generic map ( TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, RST_ASYNC_G => RST_ASYNC_G, NUM_SLAVES_G => NUM_VC_G, MODE_G => "INDEXED", @@ -189,6 +196,7 @@ begin U_Protocol : entity surf.Pgp4TxLiteProtocol generic map ( TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, RST_ASYNC_G => RST_ASYNC_G, NUM_VC_G => NUM_VC_G, SKIP_EN_G => SKIP_EN_G, @@ -216,6 +224,7 @@ begin U_Scrambler_1 : entity surf.Scrambler generic map ( TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, RST_ASYNC_G => RST_ASYNC_G, DIRECTION_G => "SCRAMBLER", DATA_WIDTH_G => 64, @@ -237,6 +246,7 @@ begin outputSideband(1 downto 0) => phyTxHeader, -- [out] outputSideband(2) => phyTxStart); -- [out] - phyTxActiveL <= not(phyTxActive); + -- not using ite to prevent errors in ASIC synth flow + phyTxActiveL <= not(phyTxActive) when RST_POLARITY_G = '1' else phyTxActive; end architecture rtl; diff --git a/protocols/pgp/pgp4/core/rtl/Pgp4TxLiteProtocol.vhd b/protocols/pgp/pgp4/core/rtl/Pgp4TxLiteProtocol.vhd index 0f28e10d17..7b9aac70d2 100644 --- a/protocols/pgp/pgp4/core/rtl/Pgp4TxLiteProtocol.vhd +++ b/protocols/pgp/pgp4/core/rtl/Pgp4TxLiteProtocol.vhd @@ -32,6 +32,7 @@ use surf.Pgp4Pkg.all; entity Pgp4TxLiteProtocol is generic ( TPD_G : time := 1 ns; + RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset RST_ASYNC_G : boolean := false; NUM_VC_G : integer range 1 to 16 := 1; SKIP_EN_G : boolean := false; @@ -127,6 +128,7 @@ begin U_Crc32 : entity surf.Crc32Parallel generic map ( TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, RST_ASYNC_G => RST_ASYNC_G, INPUT_REGISTER_G => false, BYTE_WIDTH_G => 8, @@ -453,7 +455,7 @@ begin end loop; -- Reset - if (RST_ASYNC_G = false and pgpTxRst = '1') then + if (RST_ASYNC_G = false and pgpTxRst = RST_POLARITY_G) then v := REG_INIT_C; end if; @@ -464,7 +466,7 @@ begin seq : process (pgpTxClk, pgpTxRst) is begin - if (RST_ASYNC_G) and (pgpTxRst = '1') then + if (RST_ASYNC_G) and (pgpTxRst = RST_POLARITY_G) then r <= REG_INIT_C after TPD_G; elsif rising_edge(pgpTxClk) then r <= rin after TPD_G; diff --git a/protocols/pgp/pgp4/core/rtl/Pgp4TxLiteWrapper.vhd b/protocols/pgp/pgp4/core/rtl/Pgp4TxLiteWrapper.vhd index 2eb515de10..c51528b645 100644 --- a/protocols/pgp/pgp4/core/rtl/Pgp4TxLiteWrapper.vhd +++ b/protocols/pgp/pgp4/core/rtl/Pgp4TxLiteWrapper.vhd @@ -24,12 +24,13 @@ use surf.Pgp4Pkg.all; entity Pgp4TxLiteWrapper is generic ( - TPD_G : time := 1 ns; - RST_ASYNC_G : boolean := false); + TPD_G : time := 1 ns; + RST_POLARITY_G : sl := '1'; -- '1' for active HIGH reset, '0' for active LOW reset + RST_ASYNC_G : boolean := false); port ( -- Clock and Reset clk : in sl; - rst : in sl; -- Active HIGH reset + rst : in sl; -- 64-bit Input Framing Interface txValid : in sl; -- tValid txReady : out sl; -- tReady @@ -71,8 +72,9 @@ begin U_Pgp4TxLite : entity surf.Pgp4TxLite generic map ( TPD_G => TPD_G, + RST_POLARITY_G => RST_POLARITY_G, RST_ASYNC_G => RST_ASYNC_G, - NUM_VC_G => 1, -- Only 1 VC per PGPv4 link + NUM_VC_G => 1, -- Only 1 VC per PGPv4 link SKIP_EN_G => false, -- No skips (assumes clock source synchronous system) FLOW_CTRL_EN_G => false) -- no pause flow control from PGPv4.RX side port map ( @@ -97,6 +99,7 @@ begin phyTxData => phyTxData(63 downto 0), phyTxHeader => phyTxData(65 downto 64)); - rstL <= not(rst); + -- not using ite to prevent errors in ASIC synth flow + rstL <= not(rst) when RST_POLARITY_G = '1' else rst; end architecture mapping; diff --git a/protocols/saci/rtl/AxiLiteSaciMaster.vhd b/protocols/saci/rtl/AxiLiteSaciMaster.vhd index 139add9c56..50025de5e1 100644 --- a/protocols/saci/rtl/AxiLiteSaciMaster.vhd +++ b/protocols/saci/rtl/AxiLiteSaciMaster.vhd @@ -27,13 +27,13 @@ use surf.SaciMasterPkg.all; entity AxiLiteSaciMaster is generic ( - TPD_G : time := 1 ns; - AXIL_CLK_PERIOD_G : real := 8.0e-9; -- In units of seconds - AXIL_TIMEOUT_G : real := 1.0E-3; -- In units of seconds - SACI_CLK_PERIOD_G : real := 1.0e-6; -- In units of seconds - SACI_CLK_FREERUN_G : boolean := false; - SACI_NUM_CHIPS_G : positive range 1 to 4 := 1; - SACI_RSP_BUSSED_G : boolean := false); + TPD_G : time := 1 ns; + AXIL_CLK_PERIOD_G : real := 8.0e-9; -- In units of seconds + AXIL_TIMEOUT_G : real := 1.0E-3; -- In units of seconds + SACI_CLK_PERIOD_G : real := 1.0e-6; -- In units of seconds + SACI_CLK_FREERUN_G : boolean := false; + SACI_NUM_CHIPS_G : positive := 1; + SACI_RSP_BUSSED_G : boolean := false); port ( -- SACI interface saciClk : out sl; @@ -43,6 +43,8 @@ entity AxiLiteSaciMaster is -- Optional SACI bus arbitration saciBusReq : out sl; saciBusGr : in sl := '1'; + -- Optional ASIC Global Reset + asicRstL : in sl := '1'; -- AXI-Lite Register Interface axilClk : in sl; axilRst : in sl; @@ -128,6 +130,7 @@ begin port map ( sysClk => axilClk, -- [in] sysRst => r.saciRst, -- [in] + asicRstL => asicRstL, -- [in] req => r.req, -- [in] ack => ack, -- [out] fail => fail, -- [out] @@ -142,7 +145,7 @@ begin saciCmd => saciCmd, -- [out] saciRsp => saciRsp); -- [in] - comb : process (ack, axilReadMaster, axilRst, axilWriteMaster, fail, r, rdData, saciBusGr) is + comb : process (ack, asicRstL, axilReadMaster, axilRst, axilWriteMaster, fail, r, rdData, saciBusGr) is variable v : RegType; variable axilStatus : AxiLiteStatusType; variable resp : slv(1 downto 0); @@ -170,7 +173,7 @@ begin v.saciRst := '0'; v.timer := 0; v.saciBusReq := '0'; - if (saciBusGr = '1') then + if (saciBusGr = '1') and (asicRstL = '1') then -- Check for a write request if (axilStatus.writeEnable = '1') then v.saciBusReq := '1'; diff --git a/protocols/saci/rtl/SaciMaster2.vhd b/protocols/saci/rtl/SaciMaster2.vhd index 854c091ecb..e2d1307edb 100644 --- a/protocols/saci/rtl/SaciMaster2.vhd +++ b/protocols/saci/rtl/SaciMaster2.vhd @@ -19,7 +19,6 @@ use IEEE.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; - library surf; use surf.StdRtlPkg.all; @@ -33,9 +32,13 @@ entity SaciMaster2 is SACI_NUM_CHIPS_G : positive := 1; SACI_RSP_BUSSED_G : boolean := false); port ( - sysClk : in sl; -- Main clock + -- Clock and Reset + sysClk : in sl; sysRst : in sl; + -- Optional ASIC Global Reset + asicRstL : in sl := '1'; + -- Request interface req : in sl; ack : out sl; @@ -67,6 +70,7 @@ architecture rtl of SaciMaster2 is state : StateType; shiftReg : slv(52 downto 0); shiftCount : slv(5 downto 0); + asicRstL : slv(31 downto 0); --Saci clk gen clkCount : slv(SACI_CLK_COUNTER_SIZE_C downto 0); @@ -88,6 +92,7 @@ architecture rtl of SaciMaster2 is state => IDLE_S, shiftReg => (others => '0'), shiftCount => (others => '0'), + asicRstL => (others => '1'), clkCount => (others => '0'), saciClkRising => '0', saciClkFalling => '0', @@ -124,7 +129,7 @@ begin ------------------------------------------------------------------------------------------------- -- Main logic ------------------------------------------------------------------------------------------------- - comb : process (addr, chip, cmd, op, r, req, saciRspSync, sysRst, wrData) is + comb : process (addr, asicRstL, chip, cmd, op, r, req, saciRspSync, sysRst, wrData) is variable v : RegType; variable rspIndex : integer; begin @@ -139,6 +144,7 @@ begin if (r.clkCount = SACI_CLK_HALF_PERIOD_C) then v.saciClk := not r.saciClk; v.clkCount := (others => '0'); + v.asicRstL := r.asicRstL(30 downto 0) & '1'; end if; -- Create saciClk edge strobes @@ -153,15 +159,20 @@ begin end if; end if; + -- Check for ASIC reset condition + if (asicRstL = '0') then + -- Reset the bus + v.asicRstL := (others => '0'); + end if; + case (r.state) is when IDLE_S => v.fail := '0'; v.shiftReg := (others => '0'); v.shiftCount := (others => '0'); v.saciSelL := (others => '1'); - -- Hold clock inactive while idle - -- Make this configurable? - if (not SACI_CLK_FREERUN_G) then + -- Hold clock inactive while idle else there is a ASIC reset + if (not SACI_CLK_FREERUN_G) and (r.asicRstL(31)='1') then v.saciClk := '0'; v.clkCount := (others => '0'); end if; diff --git a/python/surf/devices/transceivers/_Qsfp.py b/python/surf/devices/transceivers/_Qsfp.py index 6ac1caf298..50f5cf6e39 100644 --- a/python/surf/devices/transceivers/_Qsfp.py +++ b/python/surf/devices/transceivers/_Qsfp.py @@ -124,6 +124,37 @@ def __init__(self,**kwargs): dependencies = [self.TxPwrRaw[2*i+0],self.TxPwrRaw[2*i+1]], )) + for i in range(4): + self.add(pr.RemoteVariable( + name = f'TxDisable[{i}]', + description = 'Tx_Disable bit that allows software disable of transmitters, Writing 1 disables the laser of the channel', + offset = (86 << 2), + bitSize = 1, + bitOffset = i, + mode = 'RW', + base = pr.Bool, + )) + + self.add(pr.RemoteVariable( + name = 'PowerOverride', + description = '0: allows setting power mode with hardware, 1: allows setting power mode with software', + offset = (93 << 2), + bitSize = 1, + bitOffset = 0, + mode = 'RW', + base = pr.Bool, + )) + + self.add(pr.RemoteVariable( + name = 'PowerMode', + description = 'Power set to low power mode: 1 sets to LP mode if PowerOverride is 1', + offset = (93 << 2), + bitSize = 1, + bitOffset = 1, + mode = 'RW', + base = pr.Bool, + )) + ################ # Upper Page 00h ################ 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 * diff --git a/xilinx/UltraScale/general/rtl/SelectioDeserUltraScale.vhd b/xilinx/UltraScale/general/rtl/SelectioDeserUltraScale.vhd index 325aebb03e..cd3799d3ae 100644 --- a/xilinx/UltraScale/general/rtl/SelectioDeserUltraScale.vhd +++ b/xilinx/UltraScale/general/rtl/SelectioDeserUltraScale.vhd @@ -34,20 +34,23 @@ entity SelectioDeserUltraScale is CLKIN_PERIOD_G : real := 10.0; -- 100 MHz DIVCLK_DIVIDE_G : positive := 1; CLKFBOUT_MULT_G : positive := 10; -- 1 GHz = 100 MHz x 10 / 1 - CLKOUT0_DIVIDE_G : positive := 2); -- 500 MHz = 1 GHz/2 + CLKOUT0_DIVIDE_G : positive := 2; -- 500 MHz = 1 GHz/2 + CLKOUT1_DIVIDE_G : positive := 32); -- 31.25 MHz = 1 GHz/32 port ( -- SELECTIO Ports rxP : in slv(NUM_LANE_G-1 downto 0); rxN : in slv(NUM_LANE_G-1 downto 0); - pllClk : out sl; - -- External PLL Interface + -- Optional Clock Outputs + pllClk : out sl; -- clkout0 + userClk : out sl; -- clkout1 + -- External PLL Interface (EXT_PLL_G = TRUE) extPllClkIn : in sl := '0'; extPllRstIn : in sl := '1'; - -- Reference Clock and Reset + -- Reference Clock and Reset (EXT_PLL_G = FALSE) refClk : in sl; refRst : in sl; -- Deserialization Interface (deserClk domain) - deserClk : out sl; + deserClk : out sl; -- clkout0/4 deserRst : out sl; deserData : out Slv8Array(NUM_LANE_G-1 downto 0); dlyLoad : in slv(NUM_LANE_G-1 downto 0); @@ -73,6 +76,7 @@ architecture mapping of SelectioDeserUltraScale is signal locked : sl := '0'; signal clkFb : sl := '0'; signal clkout0 : sl := '0'; + signal clkout1 : sl := '0'; signal clkx4 : sl := '0'; signal clkx1 : sl := '0'; @@ -122,7 +126,8 @@ begin CLKIN_PERIOD => CLKIN_PERIOD_G, DIVCLK_DIVIDE => DIVCLK_DIVIDE_G, CLKFBOUT_MULT => CLKFBOUT_MULT_G, - CLKOUT0_DIVIDE => CLKOUT0_DIVIDE_G) + CLKOUT0_DIVIDE => CLKOUT0_DIVIDE_G, + CLKOUT1_DIVIDE => CLKOUT1_DIVIDE_G) port map ( DCLK => axilClk, DRDY => drpRdy, @@ -139,7 +144,7 @@ begin CLKFBIN => clkFb, LOCKED => locked, CLKOUT0 => clkout0, - CLKOUT1 => open); + CLKOUT1 => clkout1); end generate GEN_REAL; @@ -148,7 +153,7 @@ begin axilReadSlave <= AXI_LITE_READ_SLAVE_EMPTY_DECERR_C; axilWriteSlave <= AXI_LITE_WRITE_SLAVE_EMPTY_DECERR_C; - U_ClkRst : entity surf.ClkRst + U_clkout0 : entity surf.ClkRst generic map ( CLK_PERIOD_G => (CLKIN_PERIOD_G*DIVCLK_DIVIDE_G*CLKOUT0_DIVIDE_G/CLKFBOUT_MULT_G)*(1.0 ns), RST_START_DELAY_G => 0 ns, @@ -157,6 +162,14 @@ begin clkP => clkout0, rstL => locked); + U_clkout1 : entity surf.ClkRst + generic map ( + CLK_PERIOD_G => (CLKIN_PERIOD_G*DIVCLK_DIVIDE_G*CLKOUT1_DIVIDE_G/CLKFBOUT_MULT_G)*(1.0 ns), + RST_START_DELAY_G => 0 ns, + RST_HOLD_TIME_G => 1000 ns) + port map ( + clkP => clkout1); + end generate GEN_SIM; U_Bufg640 : BUFG @@ -169,9 +182,15 @@ begin GEN_EXT_PLL : if (EXT_PLL_G = true) generate clkx4 <= extPllClkIn; clkout0 <= extPllClkIn; + clkout1 <= extPllClkIn; locked <= not(extPllRstIn); end generate GEN_EXT_PLL; + U_UserClk : BUFG + port map ( + I => clkout1, + O => userClk); + ------------------------------------------------------------------------------------------------------ -- clkx1 is the ISERDESE3/OSERDESE3's CLKDIV port -- Refer to "Figure 3-49: Sub-Optimal to Optimal Clocking Topologies for OSERDESE3" in UG949 (v2018.2)