diff --git a/LICENSE.txt b/LICENSE.txt index 44e3f12dca..9aa129c6fb 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,5 +1,5 @@ -Copyright (c) 2023, The Board of Trustees of the Leland Stanford Junior +Copyright (c) 2024, The Board of Trustees of the Leland Stanford Junior University, through SLAC National Accelerator Laboratory (subject to receipt of any required approvals from the U.S. Dept. of Energy). All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249Deserializer.vhd b/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249Deserializer.vhd index 1fb907a71d..d8b08f5f12 100644 --- a/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249Deserializer.vhd +++ b/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249Deserializer.vhd @@ -32,14 +32,14 @@ use surf.Ad9249Pkg.all; entity Ad9249Deserializer is generic ( - TPD_G : time := 1 ns; - SIM_DEVICE_G : string := "ULTRASCALE"; - IODELAY_GROUP_G : string := "DEFAULT_GROUP"; - IDELAY_CASCADE_G : boolean := false; - IDELAYCTRL_FREQ_G : real := 300.0; - DEFAULT_DELAY_G : slv(8 downto 0) := (others => '0'); - ADC_INVERT_CH_G : sl := '0'; - BIT_REV_G : sl := '0'); + TPD_G : time := 1 ns; + SIM_DEVICE_G : string := "ULTRASCALE"; + IODELAY_GROUP_G : string := "DEFAULT_GROUP"; + IDELAY_CASCADE_G : boolean := false; + IDELAYCTRL_FREQ_G : real := 300.0; + DEFAULT_DELAY_G : slv(8 downto 0) := (others => '0'); + ADC_INVERT_CH_G : sl := '0'; + BIT_REV_G : sl := '0'); port ( -- Serial Data from ADC dClk : in sl; -- Data clock @@ -207,13 +207,12 @@ begin RST => dRstDiv4 -- 1-bit input: Asynchronous Reset ); - - U_Gearbox : entity surf.Gearbox generic map ( - TPD_G => TPD_G, - SLAVE_WIDTH_G => 8, - MASTER_WIDTH_G => 14 + TPD_G => TPD_G, + SLAVE_WIDTH_G => 8, + MASTER_WIDTH_G => 14, + MASTER_BIT_REVERSE_G => toBoolean(BIT_REV_G) ) port map ( clk => dClkDiv4, @@ -224,11 +223,8 @@ begin slaveData => masterData, -- Master Interface masterValid => adcValid, - masterData => iAdcData, - masterReady => '1' - ); - - adcData <= iAdcData when BIT_REV_G = '0' else bitReverse(iAdcData(6 downto 0)) & bitReverse(iAdcData(13 downto 7)); + masterData => adcData, + masterReady => '1'); end rtl; diff --git a/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup.vhd b/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup.vhd index 0b4c58c91c..e610af0cab 100644 --- a/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup.vhd +++ b/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup.vhd @@ -45,36 +45,36 @@ entity Ad9249ReadoutGroup is SIM_SPEEDUP_G : boolean := false); port ( -- Master system clock, 125Mhz - axilClk : in sl; - axilRst : in sl; + axilClk : in sl; + axilRst : in sl; -- Axi Interface - axilWriteMaster : in AxiLiteWriteMasterType; - axilWriteSlave : out AxiLiteWriteSlaveType; - axilReadMaster : in AxiLiteReadMasterType; - axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType; + axilWriteSlave : out AxiLiteWriteSlaveType; + axilReadMaster : in AxiLiteReadMasterType; + axilReadSlave : out AxiLiteReadSlaveType; -- Reset for adc deserializer (axilClk domain) - adcClkRst : in sl; + adcClkRst : in sl; -- clocks must be provided with USE_MMCME_G = false -- this option is necessary if there is many ADCs -- one external MMCM should be instantiated to be used with all Ad9249ReadoutGroups - adcBitClkIn : in sl; -- 350.0 MHz - adcBitClkDiv4In : in sl; -- 87.5 MHz - adcBitRstIn : in sl; - adcBitRstDiv4In : in sl; + adcBitClkIn : in sl; -- 350.0 MHz + adcBitClkDiv4In : in sl; -- 87.5 MHz + adcBitRstIn : in sl; + adcBitRstDiv4In : in sl; -- Serial Data from ADC - adcSerial : in Ad9249SerialGroupType; + adcSerial : in Ad9249SerialGroupType; -- Deserialized ADC Data - adcStreamClk : in sl; - adcStreams : out AxiStreamMasterArray(NUM_CHANNELS_G-1 downto 0) := - (others => axiStreamMasterInit((false, 2, 8, 0, TKEEP_NORMAL_C, 0, TUSER_NORMAL_C))); + adcStreamClk : in sl; + adcStreams : out AxiStreamMasterArray(NUM_CHANNELS_G-1 downto 0) := + (others => axiStreamMasterInit((false, 2, 8, 0, TKEEP_NORMAL_C, 0, TUSER_NORMAL_C))); -- optional ready to allow evenout samples readout in adcStreamClk - adcReady : in slv(NUM_CHANNELS_G-1 downto 0) := (others => '1') - ); + adcReady : in slv(NUM_CHANNELS_G-1 downto 0) := (others => '1') + ); end Ad9249ReadoutGroup; -- Define architecture @@ -111,7 +111,7 @@ architecture rtl of Ad9249ReadoutGroup is readoutDebug1 => (others => (others => '0')), lockedCountRst => '0', invert => '0' - ); + ); signal lockedSync : sl; signal lockedFallCount : slv(15 downto 0); @@ -123,24 +123,24 @@ architecture rtl of Ad9249ReadoutGroup is -- ADC Readout Clocked Registers ------------------------------------------------------------------------------------------------- type AdcRegType is record - slip : sl; - count : slv(5 downto 0); + slip : sl; + count : slv(5 downto 0); --loadDelay : sl; --delayValue : slv(8 downto 0); - locked : sl; - fifoWrData : Slv16Array(NUM_CHANNELS_G-1 downto 0); - fifoWrDataEn : slv(NUM_CHANNELS_G-1 downto 0); + locked : sl; + fifoWrData : Slv16Array(NUM_CHANNELS_G-1 downto 0); + fifoWrDataEn : slv(NUM_CHANNELS_G-1 downto 0); end record; constant ADC_REG_INIT_C : AdcRegType := ( - slip => '0', - count => (others => '0'), + slip => '0', + count => (others => '0'), --loadDelay => '0', --delayValue => (others => '0'), - locked => '0', - fifoWrData => (others => (others => '0')), - fifoWrDataEn => (others => '0') - ); + locked => '0', + fifoWrData => (others => (others => '0')), + fifoWrDataEn => (others => '0') + ); signal adcR : AdcRegType := ADC_REG_INIT_C; signal adcRin : AdcRegType; @@ -157,9 +157,9 @@ architecture rtl of Ad9249ReadoutGroup is signal adcBitRst : sl; signal adcClkRstSync : sl; - signal adcFrame : slv(13 downto 0); - signal adcFrameSync : slv(13 downto 0); - signal adcData : Slv14Array(NUM_CHANNELS_G-1 downto 0); + signal adcFrame : slv(13 downto 0); + signal adcFrameSync : slv(13 downto 0); + signal adcData : Slv14Array(NUM_CHANNELS_G-1 downto 0); signal curDelayFrame : slv(8 downto 0); signal curDelayData : slv9Array(NUM_CHANNELS_G-1 downto 0); @@ -173,7 +173,7 @@ architecture rtl of Ad9249ReadoutGroup is signal frameDelay : slv(8 downto 0); signal frameDelaySet : sl; - signal invertSync : sl; + signal invertSync : sl; begin ------------------------------------------------------------------------------------------------- @@ -198,7 +198,7 @@ begin rdClk => axilClk, rdRst => axilRst, cntRst => axilR.lockedCountRst - ); + ); Synchronizer_1 : entity surf.Synchronizer generic map ( @@ -240,9 +240,9 @@ begin begin v := axilR; - v.dataDelaySet := (others => '0'); - v.frameDelaySet := '0'; - v.lockedCountRst := '0'; + v.dataDelaySet := (others => '0'); + v.frameDelaySet := '0'; + v.lockedCountRst := '0'; -- Store last two samples read from ADC for i in 0 to NUM_CHANNELS_G-1 loop @@ -318,14 +318,14 @@ begin G_MMCM : if USE_MMCME_G = true generate AdcClk_I_Ibufds : IBUFDS - generic map ( - DQS_BIAS => "FALSE" - ) - port map ( - I => adcSerial.dClkP, - IB => adcSerial.dClkN, - O => adcDclk - ); + generic map ( + DQS_BIAS => "FALSE" + ) + port map ( + I => adcSerial.dClkP, + IB => adcSerial.dClkN, + O => adcDclk + ); ------------------------------------------ -- Generate clocks from ADC incoming clock @@ -335,22 +335,22 @@ begin -- clkOut(1) : 87.50 MHz adcBitClkDiv4 clock U_iserdesClockGen : entity surf.ClockManagerUltraScale generic map( - TPD_G => 1 ns, - TYPE_G => "MMCM", -- or "PLL" - INPUT_BUFG_G => true, - FB_BUFG_G => true, - RST_IN_POLARITY_G => '1', -- '0' for active low - NUM_CLOCKS_G => 2, + TPD_G => 1 ns, + TYPE_G => "MMCM", -- or "PLL" + INPUT_BUFG_G => true, + FB_BUFG_G => true, + RST_IN_POLARITY_G => '1', -- '0' for active low + NUM_CLOCKS_G => 2, -- MMCM attributes - BANDWIDTH_G => "OPTIMIZED", - CLKIN_PERIOD_G => 2.85, -- Input period in ns ); - DIVCLK_DIVIDE_G => 10, - CLKFBOUT_MULT_F_G => 20.0, - CLKFBOUT_MULT_G => 5, - CLKOUT0_DIVIDE_F_G => 1.0, - CLKOUT0_DIVIDE_G => 2, - CLKOUT1_DIVIDE_G => 8 - ) + BANDWIDTH_G => "OPTIMIZED", + CLKIN_PERIOD_G => 2.85, -- Input period in ns ); + DIVCLK_DIVIDE_G => 10, + CLKFBOUT_MULT_F_G => 20.0, + CLKFBOUT_MULT_G => 5, + CLKOUT0_DIVIDE_F_G => 1.0, + CLKOUT0_DIVIDE_G => 2, + CLKOUT1_DIVIDE_G => 8 + ) port map( clkIn => adcDclk, rstIn => '0', @@ -359,16 +359,16 @@ begin rstOut(0) => adcBitRst, rstOut(1) => adcBitRstDiv4, locked => open - ); + ); end generate G_MMCM; G_NO_MMCM : if USE_MMCME_G = false generate - adcBitClk <= adcBitClkIn; - adcBitClkDiv4 <= adcBitClkDiv4In; - adcBitRst <= adcBitRstIn; - adcBitRstDiv4 <= adcBitRstDiv4In; + adcBitClk <= adcBitClkIn; + adcBitClkDiv4 <= adcBitClkDiv4In; + adcBitRst <= adcBitRstIn; + adcBitRstDiv4 <= adcBitRstDiv4In; end generate G_NO_MMCM; @@ -386,7 +386,7 @@ begin ADC_INVERT_CH_G => '1', BIT_REV_G => '0') port map ( - dClk => adcBitClk, -- Data clock + dClk => adcBitClk, -- Data clock dRst => adcBitRst, dClkDiv4 => adcBitClkDiv4, dRstDiv4 => adcBitRstDiv4, @@ -398,7 +398,7 @@ begin bitSlip => adcR.slip, adcData => adcFrame, adcValid => adcFrameValid - ); + ); U_FrmDlyFifo : entity surf.SynchronizerFifo generic map ( @@ -436,7 +436,7 @@ begin ADC_INVERT_CH_G => ADC_INVERT_CH_G(i), BIT_REV_G => '1') port map ( - dClk => adcBitClk, -- Data clock + dClk => adcBitClk, -- Data clock dRst => adcBitRst, dClkDiv4 => adcBitClkDiv4, dRstDiv4 => adcBitRstDiv4, @@ -481,7 +481,7 @@ begin ---------------------------------------------------------------------------------------------- -- Slip bits until correct alignment seen ---------------------------------------------------------------------------------------------- - v.slip := '0'; + v.slip := '0'; if (adcR.count = 0) then if adcFrameValid = '1' then if (adcFrame = FRAME_PATTERN_C) then @@ -537,14 +537,14 @@ begin end process adcSeq; RstSync_1 : entity surf.RstSync - generic map ( - TPD_G => TPD_G - ) - port map ( - clk => adcBitClkDiv4, - asyncRst => adcClkRst, - syncRst => adcClkRstSync - ); + generic map ( + TPD_G => TPD_G + ) + port map ( + clk => adcBitClkDiv4, + asyncRst => adcClkRst, + syncRst => adcClkRstSync + ); -- synchronize data cross-clocks G_FIFO_SYNC : for i in NUM_CHANNELS_G-1 downto 0 generate @@ -552,9 +552,9 @@ begin U_DataFifo : entity surf.SynchronizerFifo generic map ( - TPD_G => TPD_G, - DATA_WIDTH_G => 16, - ADDR_WIDTH_G => 4) + TPD_G => TPD_G, + DATA_WIDTH_G => 16, + ADDR_WIDTH_G => 4) port map ( rst => adcBitRstDiv4, wr_clk => adcBitClkDiv4, @@ -564,7 +564,7 @@ begin rd_en => fifoDataRdEn(i), valid => fifoDataValid(i), dout => adcStreams(i).tdata(15 downto 0) - ); + ); fifoDataRdEn(i) <= adcReady(i) and fifoDataValid(i); adcStreams(i).tDest <= toSlv(i, 8); @@ -572,9 +572,9 @@ begin U_DataFifoDebug : entity surf.SynchronizerFifo generic map ( - TPD_G => TPD_G, - DATA_WIDTH_G => 16, - ADDR_WIDTH_G => 4) + TPD_G => TPD_G, + DATA_WIDTH_G => 16, + ADDR_WIDTH_G => 4) port map ( rst => adcBitRstDiv4, wr_clk => adcBitClkDiv4, @@ -584,7 +584,7 @@ begin rd_en => debugDataValid(i), valid => debugDataValid(i), dout => debugData(i) - ); + ); end generate; diff --git a/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup2.vhd b/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup2.vhd index 7b0557a7b3..4a86948b48 100644 --- a/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup2.vhd +++ b/devices/AnalogDevices/ad9249/UltraScale/rtl/Ad9249ReadoutGroup2.vhd @@ -74,8 +74,8 @@ architecture rtl of Ad9249ReadoutGroup2 is delay : slv(8 downto 0); delaySet : sl; freezeDebug : sl; - readoutDebug0 : slv16Array(NUM_CHANNELS_G-1 downto 0); - readoutDebug1 : slv16Array(NUM_CHANNELS_G-1 downto 0); + readoutDebug0 : slv16Array(7 downto 0); + readoutDebug1 : slv16Array(7 downto 0); lockedCountRst : sl; invert : sl; realign : sl; @@ -92,7 +92,7 @@ architecture rtl of Ad9249ReadoutGroup2 is readoutDebug1 => (others => (others => '0')), lockedCountRst => '0', invert => '0', - realign => '0', + realign => '1', minEyeWidth => X"50"); signal lockedSync : sl; @@ -109,7 +109,7 @@ architecture rtl of Ad9249ReadoutGroup2 is end record; constant ADC_REG_INIT_C : AdcRegType := ( - errorDet => '0'); + errorDet => '1'); signal adcR : AdcRegType := ADC_REG_INIT_C; @@ -122,11 +122,12 @@ architecture rtl of Ad9249ReadoutGroup2 is signal adcBitClkDiv4 : sl; signal adcBitRstDiv4 : sl; - signal adcFrame : slv(13 downto 0); - signal adcFrameValid : sl; - signal adcFrameSync : slv(13 downto 0); - signal adcData : slv14Array(NUM_CHANNELS_G-1 downto 0); - signal adcDataValid : slv(NUM_CHANNELS_G-1 downto 0); + signal adcFrame : slv(13 downto 0); + signal adcFrameValid : sl; + signal adcFrameSync : slv(13 downto 0); + signal adcFrameSyncValid : sl; + signal adcData : slv14Array(NUM_CHANNELS_G-1 downto 0); + signal adcDataValid : slv(NUM_CHANNELS_G-1 downto 0); signal fifoWrData : slv16Array(NUM_CHANNELS_G-1 downto 0); signal fifoDataValid : sl; @@ -136,7 +137,7 @@ architecture rtl of Ad9249ReadoutGroup2 is signal debugDataValid : sl; signal debugDataOut : slv(NUM_CHANNELS_G*16-1 downto 0); - signal debugDataTmp : slv16Array(NUM_CHANNELS_G-1 downto 0); + signal debugDataTmp : slv16Array(7 downto 0); signal invertSync : sl; signal bitSlip : sl; @@ -204,16 +205,21 @@ begin rdRst => axilRst); - SynchronizerVector_FRAME : entity surf.SynchronizerVector + SynchronizerVector_FRAME : entity surf.SynchronizerFifo generic map ( - TPD_G => TPD_G, - STAGES_G => 2, - WIDTH_G => 14) + TPD_G => TPD_G, + MEMORY_TYPE_G => "distributed", + DATA_WIDTH_G => 14, + ADDR_WIDTH_G => 4) port map ( - clk => axilClk, - rst => axilRst, - dataIn => adcFrame, - dataOut => adcFrameSync); + rst => axilRst, + wr_clk => adcBitClkDiv4, + wr_en => adcFrameValid, + din => adcFrame, + rd_clk => axilClk, + rd_en => adcFrameSyncValid, + valid => adcFrameSyncValid, + dout => adcFrameSync); U_SynchronizerVector_CUR_DELAY : entity surf.SynchronizerVector generic map ( @@ -237,15 +243,14 @@ begin dataIn => axilR.invert, dataOut => invertSync); - Synchronizer_REALIGN : entity surf.SynchronizerEdge + Synchronizer_REALIGN : entity surf.RstSync generic map ( - TPD_G => TPD_G, - STAGES_G => 3) + TPD_G => TPD_G, + RELEASE_DELAY_G => 3) port map ( - clk => adcBitClkDiv4, - rst => adcBitRstDiv4, - dataIn => axilR.realign, - risingEdge => realignSync); + clk => adcBitClkDiv4, + asyncRst => axilR.realign, + syncRst => realignSync); Synchronizer_USR_DELAY_SET : entity surf.Synchronizer generic map ( @@ -308,6 +313,7 @@ begin axiWrDetect(axilEp, X"00", v.delaySet); axiSlaveRegisterR(axilEp, X"00", 0, curDelay); + v.realign := '0'; axiSlaveRegister(axilEp, X"20", 0, v.realign); axiSlaveRegisterR(axilEp, X"30", 0, errorDetCount); @@ -322,7 +328,7 @@ begin axiSlaveRegister(axilEp, X"60", 0, v.invert); -- Debug registers. Output the last 2 words received - for ch in 0 to NUM_CHANNELS_G-1 loop + for ch in 0 to 7 loop axiSlaveRegisterR(axilEp, X"80"+toSlv((ch*4), 8), 0, axilR.readoutDebug0(ch)); axiSlaveRegisterR(axilEp, X"80"+toSlv((ch*4), 8), 16, axilR.readoutDebug1(ch)); end loop; @@ -404,13 +410,13 @@ begin SIM_DEVICE_G => SIM_DEVICE_G, DEFAULT_DELAY_G => DEFAULT_DELAY_G, IDELAYCTRL_FREQ_G => 350.0, -- Check this - ADC_INVERT_CH_G => '0', -- Should maybe be '1' - BIT_REV_G => '0') + ADC_INVERT_CH_G => '0', + BIT_REV_G => '1') port map ( dClk => adcBitClk, dRst => adcBitRst, dClkDiv4 => adcBitClkDiv4, - dRstDiv4 => adcBitRstDiv4, + dRstDiv4 => realignSync, sDataP => adcSerial.fClkP, sDataN => adcSerial.fClkN, loadDelay => dlyLoad, @@ -430,16 +436,16 @@ begin TPD_G => TPD_G, SIM_DEVICE_G => SIM_DEVICE_G, DEFAULT_DELAY_G => DEFAULT_DELAY_G, - IDELAYCTRL_FREQ_G => 350.0, -- Check this - ADC_INVERT_CH_G => ADC_INVERT_CH_G(ch), -- Should maybe be '1' - BIT_REV_G => '1') + IDELAYCTRL_FREQ_G => 350.0, -- Check this + ADC_INVERT_CH_G => ADC_INVERT_CH_G(ch), + BIT_REV_G => '1') -- Should maybe be '1' port map ( dClk => adcBitClk, dRst => adcBitRst, dClkDiv4 => adcBitClkDiv4, - dRstDiv4 => adcBitRstDiv4, - sDataP => adcSerial.fClkP, - sDataN => adcSerial.fClkN, + dRstDiv4 => realignSync, + sDataP => adcSerial.chP(ch), + sDataN => adcSerial.chN(ch), loadDelay => dlyLoad, delay => dlyCfg, bitSlip => bitSlip, @@ -457,7 +463,7 @@ begin TPD_G => TPD_G, SIMULATION_G => SIMULATION_G, CODE_TYPE_G => "LINE_CODE", - DLY_STEP_SIZE_G => 1) + DLY_STEP_SIZE_G => ite(SIMULATION_G, 16, 1)) port map ( clk => adcBitClkDiv4, -- [in] rst => adcBitRstDiv4, -- [in] @@ -482,12 +488,14 @@ begin ------------------------------------------------------------------------------------------------- -- ADC Bit Clocked Logic ------------------------------------------------------------------------------------------------- - adcComb : process (adcFrame, adcR) is + adcComb : process (adcFrame, adcFrameValid, adcR) is variable v : AdcRegType; begin v := adcR; - v.errorDet := toSl(adcFrame /= "11110000"); + if (adcFrameValid = '1') then + v.errorDet := toSl(adcFrame /= "11111110000000"); + end if; adcRin <= v; @@ -545,7 +553,7 @@ begin port map ( rst => adcBitRstDiv4, wr_clk => adcBitClkDiv4, - wr_en => '1', --Always write data + wr_en => adcFrameValid, --Always write data din => fifoDataIn, rd_clk => adcStreamClk, rd_en => fifoDataValid, @@ -562,7 +570,7 @@ begin port map ( rst => adcBitRstDiv4, wr_clk => adcBitClkDiv4, - wr_en => '1', --Always write data + wr_en => adcFrameValid, --Always write data din => fifoDataIn, rd_clk => axilClk, rd_en => debugDataValid, diff --git a/devices/AnalogDevices/ad9249/tb/Ad9249Group.vhd b/devices/AnalogDevices/ad9249/tb/Ad9249Group.vhd index 694c68637f..02db1c9676 100644 --- a/devices/AnalogDevices/ad9249/tb/Ad9249Group.vhd +++ b/devices/AnalogDevices/ad9249/tb/Ad9249Group.vhd @@ -32,8 +32,8 @@ entity Ad9249Group is CLK_PERIOD_G : time := 24 ns; DIVCLK_DIVIDE_G : integer := 1; CLKFBOUT_MULT_G : integer := 49; - CLK_DCO_DIVIDE_G : integer := 49; - CLK_FCO_DIVIDE_G : integer := 7); + CLK_DCO_DIVIDE_G : integer := 7; + CLK_FCO_DIVIDE_G : integer := 49); port ( clk : in sl; @@ -230,31 +230,32 @@ begin -- Use a clock manager to create the serial clock -- There's probably a better way but this works. ------------------------------------------------------------------------------------------------- - U_CtrlClockManager7 : entity surf.ClockManager7 - generic map ( - TPD_G => TPD_G, - TYPE_G => "MMCM", - INPUT_BUFG_G => false, - FB_BUFG_G => true, - NUM_CLOCKS_G => 4, - BANDWIDTH_G => "HIGH", - CLKIN_PERIOD_G => CLK_PERIOD_C, - DIVCLK_DIVIDE_G => DIVCLK_DIVIDE_G, - CLKFBOUT_MULT_G => CLKFBOUT_MULT_G, - CLKOUT0_DIVIDE_G => CLK_FCO_DIVIDE_G, - CLKOUT1_DIVIDE_G => CLK_DCO_DIVIDE_G, - CLKOUT2_DIVIDE_G => CLK_DCO_DIVIDE_G, - CLKOUT2_PHASE_G => 90.0, - CLKOUT3_DIVIDE_G => CLK_FCO_DIVIDE_G, - CLKOUT3_PHASE_G => 257.143) - port map ( - clkIn => clk, - rstIn => pllRst, - clkOut(0) => fClk, - clkOut(1) => dClk, - clkOut(2) => dco, - clkOut(3) => fco, - locked => locked); + U_CtrlClockManager7 : entity surf.ClockManager7 + generic map ( + TPD_G => TPD_G, + TYPE_G => "PLL", + INPUT_BUFG_G => false, + FB_BUFG_G => true, + NUM_CLOCKS_G => 4, + BANDWIDTH_G => "HIGH", + CLKIN_PERIOD_G => CLK_PERIOD_C, + DIVCLK_DIVIDE_G => DIVCLK_DIVIDE_G, + CLKFBOUT_MULT_G => CLKFBOUT_MULT_G, + CLKOUT0_DIVIDE_G => CLK_FCO_DIVIDE_G, + CLKOUT1_DIVIDE_G => CLK_DCO_DIVIDE_G, + CLKOUT2_DIVIDE_G => CLK_DCO_DIVIDE_G, + CLKOUT2_PHASE_G => 90.0, + CLKOUT3_DIVIDE_G => CLK_FCO_DIVIDE_G, + CLKOUT3_PHASE_G => 257.143) + port map ( + clkIn => clk, + rstIn => pllRst, + clkOut(0) => fClk, + clkOut(1) => dClk, + clkOut(2) => dco, + clkOut(3) => fco, + locked => locked); + RstSync_1 : entity surf.RstSync diff --git a/devices/AnalogDevices/ruckus.tcl b/devices/AnalogDevices/ruckus.tcl index 0d3997bbe6..0e92b6ce04 100644 --- a/devices/AnalogDevices/ruckus.tcl +++ b/devices/AnalogDevices/ruckus.tcl @@ -10,4 +10,8 @@ if { $::env(VIVADO_VERSION) > 0.0} { loadRuckusTcl "$::DIR_PATH/ad9467" loadRuckusTcl "$::DIR_PATH/ad9249" loadRuckusTcl "$::DIR_PATH/ad9681" -} \ No newline at end of file + + # AD9249 sim model requires ClockManager7 + loadSource -lib surf -path "$::DIR_PATH/../../xilinx/7Series/general/rtl/ClockManager7.vhd" + loadSource -lib surf -path "$::DIR_PATH/../../xilinx/7Series/general/rtl/ClockManager7Pkg.vhd" +} diff --git a/python/surf/devices/analog_devices/_Ad9249.py b/python/surf/devices/analog_devices/_Ad9249.py index f497266b13..a25c07934c 100644 --- a/python/surf/devices/analog_devices/_Ad9249.py +++ b/python/surf/devices/analog_devices/_Ad9249.py @@ -421,6 +421,158 @@ def readBlocks(self, *, recurse=True, variable=None, checkEach=False, index=-1, for key,value in self.devices.items(): value.readBlocks(recurse=True, checkEach=checkEach, **kwargs) + +class Ad9249ReadoutGroup2(pr.Device): + def __init__(self, + name = 'Ad9249Readout', + description = 'Configure readout of 1 bank of an AD9249', + fpga = '7series', + channels = 8, + **kwargs): + + assert (channels > 0 and channels <= 8), f'channels ({channels}) must be between 0 and 8' + super().__init__(name=name, description=description, **kwargs) + + if fpga == '7series': + delayBits = 6 + elif fpga == 'ultrascale': + delayBits = 9 + else: + delayBits = 6 + + + self.add(pr.RemoteVariable( + name = 'Delay', + description = 'IDELAY value', + offset = 0x00, + bitSize = delayBits, + bitOffset = 0, + base = pr.UInt, + mode = 'RW', + verify = False, + groups = 'NoConfig', + )) + + self.add(pr.RemoteCommand( + name='Relock', + hidden=False, + offset=0x20, + bitSize=1, + bitOffset=0, + base=pr.UInt, + function=pr.RemoteCommand.toggle)) + + self.add(pr.RemoteVariable( + name = 'ErrorDetCount', + description = 'Number of times that frame lock has been lost since reset', + offset = 0x30, + disp = '{:d}', + bitSize = 16, + bitOffset = 0, + base = pr.UInt, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'LostLockCount', + description = 'Number of times that frame lock has been lost since reset', + offset = 0x50, + bitSize = 16, + bitOffset = 0, + base = pr.UInt, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'Locked', + description = 'Readout has locked on to the frame boundary', + offset = 0x50, + bitSize = 1, + bitOffset = 16, + base = pr.Bool, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'AdcFrameSync', + description = 'Last deserialized FCO value for debug', + offset = 0x58, + bitSize = 14, + base = pr.UInt, + mode = 'RO', + )) + + self.add(pr.RemoteVariable( + name = 'Invert', + description = 'Optional ADC data inversion (offset binary only)', + offset = 0x60, + bitSize = 1, + bitOffset = 0, + base = pr.Bool, + mode = 'RW', + )) + + for i in range(channels): + self.add(pr.RemoteVariable( + name = f'AdcChannel[{i:d}]', + description = f'Last deserialized channel {i:d} ADC value for debug', + offset = 0x80 + (i*4), + bitSize = 32, + bitOffset = 0, + base = pr.UInt, + disp = '{:09_x}', + mode = 'RO', + )) + + for i in range(channels): + self.add(pr.LinkVariable( + name = f'AdcVoltage[{i}]', + mode = 'RO', + disp = '{:1.9f}', + variable = self.AdcChannel[i], + linkedGet = lambda read, check, r=self.AdcChannel[i]: 2*pr.twosComplement(r.get(read=read, check=check)>>18, 14)/2**14, + units = 'V')) + + self.add(pr.RemoteCommand( + name = 'LostLockCountReset', + description = 'Reset LostLockCount', + function = pr.BaseCommand.toggle, + offset = 0x5C, + bitSize = 1, + bitOffset = 0, + )) + + self.add(pr.RemoteCommand( + name='FreezeDebug', + description='Freeze all of the AdcChannel registers', + hidden=True, + offset=0xA0, + bitSize=1, + bitOffset=0, + base=pr.UInt, + function=pr.RemoteCommand.touch)) + + def readBlocks(self, *, recurse=True, variable=None, checkEach=False, index=-1, **kwargs): + """ + Perform background reads + """ + checkEach = checkEach or self.forceCheckEach + + if variable is not None: + pr.startTransaction(variable._block, type=rim.Read, checkEach=checkEach, variable=variable, index=index, **kwargs) + + else: + self.FreezeDebug(1) + for block in self._blocks: + if block.bulkOpEn: + pr.startTransaction(block, type=rim.Read, checkEach=checkEach, **kwargs) + self.FreezeDebug(0) + + if recurse: + for key,value in self.devices.items(): + value.readBlocks(recurse=True, checkEach=checkEach, **kwargs) + + class AdcTester(pr.Device): def __init__(self, **kwargs): """Create AdcTester""" diff --git a/python/surf/xilinx/_AxiSysMonUltraScale.py b/python/surf/xilinx/_AxiSysMonUltraScale.py index c2de0bf748..f2371904fc 100644 --- a/python/surf/xilinx/_AxiSysMonUltraScale.py +++ b/python/surf/xilinx/_AxiSysMonUltraScale.py @@ -20,7 +20,9 @@ def __init__( **kwargs): super().__init__(description=description, **kwargs) - self.simpleViewList = simpleViewList + if simpleViewList is not None: + self.simpleViewList = simpleViewList[:] + self.simpleViewList.append('enable') def addPair(name, offset, bitSize, units, bitOffset, description, function, pollInterval=0): self.add(pr.RemoteVariable( @@ -528,8 +530,8 @@ def addPair(name, offset, bitSize, units, bitOffset, description, function, poll ) # Default to simple view - self.simpleView() - + if simpleViewList is not None: + self.simpleView() @staticmethod def convTempSYSMONE1(dev, var): @@ -568,9 +570,8 @@ def convAuxVoltage(var): return round(var.dependencies[0].value() * 244e-6,3) def simpleView(self): - if self.simpleViewList is not None: - # Hide all the variable - self.hideVariables(hidden=True) - # Then unhide the most interesting ones - vars = self.simpleViewList - self.hideVariables(hidden=False, variables=vars) + # Hide all the variable + self.hideVariables(hidden=True) + # Then unhide the most interesting ones + vars = self.simpleViewList + self.hideVariables(hidden=False, variables=vars) diff --git a/python/surf/xilinx/_Xadc.py b/python/surf/xilinx/_Xadc.py index a53c99cefd..71bdd85dab 100644 --- a/python/surf/xilinx/_Xadc.py +++ b/python/surf/xilinx/_Xadc.py @@ -30,8 +30,9 @@ def __init__(self, if isinstance(auxChannels, int): auxChannels = list(range(auxChannels)) - self.simpleViewList = simpleViewList - self.simpleViewList.append('enable') + if simpleViewList is not None: + self.simpleViewList = simpleViewList[:] + self.simpleViewList.append('enable') def addPair(name, offset, bitSize, units, bitOffset, description, function, pollInterval=0): self.add(pr.RemoteVariable( @@ -572,8 +573,8 @@ def addPair(name, offset, bitSize, units, bitOffset, description, function, poll ) # Default to simple view - self.simpleView() - + if simpleViewList is not None: + self.simpleView() @staticmethod def convTemp(dev, var):