diff options
author | Wade Fife <wade.fife@ettus.com> | 2021-06-08 19:40:46 -0500 |
---|---|---|
committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2021-06-10 11:56:58 -0500 |
commit | 6d3765605262016a80f71e36357f749ea35cbe5a (patch) | |
tree | 7d62d6622befd4132ac1ee085effa1426f7f53e5 /fpga/usrp3/top/x400/rf/common/rf_reset_controller.vhd | |
parent | f706b89e6974e28ce76aadeeb06169becc86acba (diff) | |
download | uhd-6d3765605262016a80f71e36357f749ea35cbe5a.tar.gz uhd-6d3765605262016a80f71e36357f749ea35cbe5a.tar.bz2 uhd-6d3765605262016a80f71e36357f749ea35cbe5a.zip |
fpga: x400: Add support for X410 motherboard FPGA
Co-authored-by: Andrew Moch <Andrew.Moch@ni.com>
Co-authored-by: Daniel Jepson <daniel.jepson@ni.com>
Co-authored-by: Javier Valenzuela <javier.valenzuela@ni.com>
Co-authored-by: Joerg Hofrichter <joerg.hofrichter@ni.com>
Co-authored-by: Kumaran Subramoniam <kumaran.subramoniam@ni.com>
Co-authored-by: Max Köhler <max.koehler@ni.com>
Co-authored-by: Michael Auchter <michael.auchter@ni.com>
Co-authored-by: Paul Butler <paul.butler@ni.com>
Co-authored-by: Wade Fife <wade.fife@ettus.com>
Co-authored-by: Hector Rubio <hrubio@ni.com>
Diffstat (limited to 'fpga/usrp3/top/x400/rf/common/rf_reset_controller.vhd')
-rw-r--r-- | fpga/usrp3/top/x400/rf/common/rf_reset_controller.vhd | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/fpga/usrp3/top/x400/rf/common/rf_reset_controller.vhd b/fpga/usrp3/top/x400/rf/common/rf_reset_controller.vhd new file mode 100644 index 000000000..d69228a80 --- /dev/null +++ b/fpga/usrp3/top/x400/rf/common/rf_reset_controller.vhd @@ -0,0 +1,208 @@ +-- +-- Copyright 2021 Ettus Research, a National Instruments Brand +-- +-- SPDX-License-Identifier: LGPL-3.0-or-later +-- +-- Module: rf_reset_controller +-- +-- Description: +-- +-- Control RFDC, ADC, and DAC resets. +-- + +library IEEE; + use IEEE.std_logic_1164.all; + use IEEE.numeric_std.all; + +library WORK; + use WORK.PkgRFDC_REGS_REGMAP.all; + +entity rf_reset_controller is + port( + -- Clocks + -- Config clock is async to all the others. + ConfigClk : in std_logic; + DataClk : in std_logic; + PllRefClk : in std_logic; + RfClk : in std_logic; + RfClk2x : in std_logic; + DataClk2x : in std_logic; + + -- Master resets from the Radio + dAdcResetPulse : in std_logic; + dDacResetPulse : in std_logic; + + -- ADC Resets + dAdcDataOutReset_n : out std_logic; + r2AdcFirReset_n : out std_logic; + rAdcRfdcAxiReset_n : out std_logic; + rAdcEnableData : out std_logic; + rAdcGearboxReset_n : out std_logic; + + -- DAC Resets + dDacDataInReset_n : out std_logic; + r2DacFirReset_n : out std_logic; + d2DacFirReset_n : out std_logic; + rDacRfdcAxiReset_n : out std_logic; + rDacGearboxReset_n : out std_logic; + + -- SW Control and Status + -- Control to initiate resets to RFDC and decimation block including the + -- gearboxes. The reset status is a sticky status of both ADC and DAC. + cSoftwareControl : in std_logic_vector(31 downto 0); + cSoftwareStatus : out std_logic_vector(31 downto 0) + ); +end rf_reset_controller; + + +architecture RTL of rf_reset_controller is + + -- POR value for all resets are high. + signal cTriggerAdcReset : std_logic := '1'; + signal cTriggerAdcResetDlyd : std_logic := '1'; + signal cTriggerDacReset : std_logic := '1'; + signal cTriggerDacResetDlyd : std_logic := '1'; + + signal dTriggerAdcReset_ms : std_logic := '1'; + signal dTriggerAdcReset : std_logic := '1'; + signal dTriggerDacReset_ms : std_logic := '1'; + signal dTriggerDacReset : std_logic := '1'; + + -- POR value of all reset done signals are set to low. + signal cTriggerAdcResetDone_ms : std_logic := '0'; + signal cTriggerAdcResetDone : std_logic := '0'; + signal cAdcResetDoneSticky : std_logic := '0'; + signal cTriggerDacResetDone_ms : std_logic := '0'; + signal cTriggerDacResetDone : std_logic := '0'; + signal cDacResetDoneSticky : std_logic := '0'; + + attribute ASYNC_REG : string; + attribute ASYNC_REG of dTriggerAdcReset : signal is "TRUE"; + attribute ASYNC_REG of dTriggerDacReset : signal is "TRUE"; + attribute ASYNC_REG of cTriggerAdcResetDone : signal is "TRUE"; + attribute ASYNC_REG of cTriggerDacResetDone : signal is "TRUE"; + attribute ASYNC_REG of dTriggerAdcReset_ms : signal is "TRUE"; + attribute ASYNC_REG of dTriggerDacReset_ms : signal is "TRUE"; + attribute ASYNC_REG of cTriggerAdcResetDone_ms : signal is "TRUE"; + attribute ASYNC_REG of cTriggerDacResetDone_ms : signal is "TRUE"; + +begin + + -- rAdcEnableData is set to '1' as we don't control the flow of RX data. + rAdcEnableData <= '1'; + + cTriggerAdcReset <= cSoftwareControl(kADC_RESET); + cTriggerDacReset <= cSoftwareControl(kDAC_RESET); + + cSoftwareStatus <= ( + kADC_SEQ_DONE => cAdcResetDoneSticky, + kDAC_SEQ_DONE => cDacResetDoneSticky, + others => '0' + ); + + ----------------------------------------------------------------------------- + -- High-Level Resets Using ConfigClk + ----------------------------------------------------------------------------- + -- Pass the master FSM reset around to the other clock domains and then + -- return them back to the ConfigClk domain. This is also a handy way to + -- prove all your clocks are toggling to some extent. + ----------------------------------------------------------------------------- + + SeqResetDataClk : process(DataClk) + begin + if rising_edge(DataClk) then + -- double-syncs have no sync reset! + dTriggerAdcReset_ms <= cTriggerAdcReset; + dTriggerAdcReset <= dTriggerAdcReset_ms; + dTriggerDacReset_ms <= cTriggerDacReset; + dTriggerDacReset <= dTriggerDacReset_ms; + end if; + end process; + + ----------------------------------------------------------------------------- + -- Reset Sequence Done Status + ----------------------------------------------------------------------------- + -- Now back to ConfigClk! We provide the status for all software controlled + -- resets. We move the signal from ConfigClk to DataClk domain and move it + -- back to ConfigClk domain. This just proves that DataClk is toggling and + -- the reset requested by software is sampled in the DataClk. + ----------------------------------------------------------------------------- + + SeqResetDone : process(ConfigClk) + begin + if rising_edge(ConfigClk) then + -- double-syncs have no sync reset! + cTriggerAdcResetDone_ms <= dTriggerAdcReset; + cTriggerAdcResetDone <= cTriggerAdcResetDone_ms; + cTriggerDacResetDone_ms <= dTriggerDacReset; + cTriggerDacResetDone <= cTriggerDacResetDone_ms; + end if; + end process; + + -- ADC reset done + SwAdcResetDone: process(ConfigClk) + begin + if rising_edge(ConfigClk) then + cTriggerAdcResetDlyd <= cTriggerAdcReset; + -- De-assert reset status on the rising edge of SW ADC reset. + if cTriggerAdcReset = '1' and cTriggerAdcResetDlyd = '0' then + cAdcResetDoneSticky <= '0'; + -- Assert and hold the ADC reset status on ADC reset strobe. + elsif cTriggerAdcResetDone = '1' then + cAdcResetDoneSticky <= '1'; + end if; + end if; + end process SwAdcResetDone; + + -- DAC reset done + SwDacResetDone: process(ConfigClk) + begin + if rising_edge(ConfigClk) then + cTriggerDacResetDlyd <= cTriggerDacReset; + -- De-assert reset status on the rising edge of SW DAC reset. + if cTriggerDacReset = '1' and cTriggerDacResetDlyd = '0' then + cDacResetDoneSticky <= '0'; + -- Assert and hold the DAC reset status on DAC reset strobe. + elsif cTriggerDacResetDone = '1' then + cDacResetDoneSticky <= '1'; + end if; + end if; + end process SwDacResetDone; + + ----------------------------------------------------------------------------- + -- rf_reset Instances + ----------------------------------------------------------------------------- + + AdcResets: entity work.rf_reset (RTL) + port map ( + DataClk => DataClk, + PllRefClk => PllRefClk, + RfClk => RfClk, + RfClk2x => RfClk2x, + DataClk2x => DataClk2x, + dTimedReset => dAdcResetPulse, + dSwReset => dTriggerAdcReset, + dReset_n => dAdcDataOutReset_n, + d2Reset_n => open, + r2Reset_n => r2AdcFirReset_n, + rAxiReset_n => rAdcRfdcAxiReset_n, + rReset_n => rAdcGearboxReset_n + ); + + DacResets: entity work.rf_reset (RTL) + port map ( + DataClk => DataClk, + PllRefClk => PllRefClk, + RfClk => RfClk, + RfClk2x => RfClk2x, + DataClk2x => DataClk2x, + dTimedReset => dDacResetPulse, + dSwReset => dTriggerDacReset, + dReset_n => dDacDataInReset_n, + d2Reset_n => d2DacFirReset_n, + r2Reset_n => r2DacFirReset_n, + rAxiReset_n => rDacRfdcAxiReset_n, + rReset_n => rDacGearboxReset_n + ); + +end RTL; |