aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/top/x400/rf/400m/dac_gearbox_6x8.vhd
diff options
context:
space:
mode:
authorWade Fife <wade.fife@ettus.com>2021-06-08 19:40:46 -0500
committerAaron Rossetto <aaron.rossetto@ni.com>2021-06-10 11:56:58 -0500
commit6d3765605262016a80f71e36357f749ea35cbe5a (patch)
tree7d62d6622befd4132ac1ee085effa1426f7f53e5 /fpga/usrp3/top/x400/rf/400m/dac_gearbox_6x8.vhd
parentf706b89e6974e28ce76aadeeb06169becc86acba (diff)
downloaduhd-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/400m/dac_gearbox_6x8.vhd')
-rw-r--r--fpga/usrp3/top/x400/rf/400m/dac_gearbox_6x8.vhd99
1 files changed, 99 insertions, 0 deletions
diff --git a/fpga/usrp3/top/x400/rf/400m/dac_gearbox_6x8.vhd b/fpga/usrp3/top/x400/rf/400m/dac_gearbox_6x8.vhd
new file mode 100644
index 000000000..c673cd732
--- /dev/null
+++ b/fpga/usrp3/top/x400/rf/400m/dac_gearbox_6x8.vhd
@@ -0,0 +1,99 @@
+--
+-- Copyright 2021 Ettus Research, a National Instruments Brand
+--
+-- SPDX-License-Identifier: LGPL-3.0-or-later
+--
+-- Module: dac_gearbox_6x8
+--
+-- Description:
+--
+-- Gearbox to expand the data width from 6 SPC to 8 SPC.
+-- Input Clocks, all aligned to one another and coming from same MMCM
+-- PLL reference clock = 61.44 or 62.5 MHz.
+-- RfClk: 184.32 or 187.5 MHz (3x PLL reference clock)
+-- Clk1x: 122.88 or 125 MHz (2x PLL reference clock)
+-- Clk2x: 245.76 or 250 MHz (4x PLL reference clock)
+--
+
+library IEEE;
+ use IEEE.std_logic_1164.all;
+ use IEEE.numeric_std.all;
+
+entity dac_gearbox_6x8 is
+ port(
+ Clk1x : in std_logic;
+ Clk2x : in std_logic;
+ RfClk : in std_logic;
+ ac1Reset_n : in std_logic;
+ ac2Reset_n : in std_logic;
+ arReset_n : in std_logic;
+ -- 16 bit data packing: [Q5,I5,Q4,I4,Q3,I3,Q2,I2,Q1,I1,Q0,I0] (I in LSBs)
+ c2DataIn : in std_logic_vector(191 downto 0);
+ c2DataValidIn : in std_logic;
+ -- 16 bit data packing: [Q7,I7,Q6,I6,..,Q2,I2,Q1,I1,Q0,I0] (I in LSBs)
+ rDataOut : out std_logic_vector(255 downto 0) := (others => '0');
+ rReadyForOutput : in std_logic;
+ rDataValidOut : out std_logic := '0'
+ );
+end dac_gearbox_6x8;
+
+architecture struct of dac_gearbox_6x8 is
+
+ signal c1DataOut : std_logic_vector(383 downto 0);
+ signal c1DataValidOut : std_logic;
+
+begin
+
+ -- Clk1x, Clk2x, and RfClk are source from the same PLL and have a known
+ -- phase relationship between power cycles. Since, they have known phase
+ -- relationship, clock crossing as be done without a dual clock FIFO or any
+ -- other handshaking mechanism. We cannot move data from Clk2x to RfClk
+ -- because of the clock relation between these two clocks will make it almost
+ -- impossible to close timing. So, we move data from Clk2x to Clk1x and then
+ -- to RfClk domain. Since, we need deterministic delay in the data path, we
+ -- cannot use a FIFO to do data crossing.
+ --
+ -- Clk1x = Sample clock/24
+ -- Clk2x = Sample clock/12
+ -- RfClk = Sample clock/16
+ --
+ -- Clk1x __/-----\_____/-----\_____/-----\_____/-----\_____/-----\___
+ -- | |
+ -- Clk2x __/--\__/--\__/--\__/--\__/--\ | |
+ -- | | | |
+ -- | | <- Setup relationship | | <- Setup relationship
+ -- | | | |
+ -- RfClk __/---\___/---\___/---\___/---\___/---\___/---\___/---\___/-
+ --
+ -- As you can see the setup relationship for passing data synchronously from
+ -- Clk2x to RfClk is very small (Sample clock period * 4). It is not possible
+ -- to close timing with this requirement. For passing data from Clk1x to
+ -- RfClk the setup relationship is (Sample clock period * 8) which is
+ -- relatively easy to close timing.
+
+ dac_gearbox_6x12_i: entity work.dac_gearbox_6x12 (RTL)
+ port map (
+ Clk1x => Clk1x,
+ Clk2x => Clk2x,
+ ac1Reset_n => ac1Reset_n,
+ ac2Reset_n => ac2Reset_n,
+ c2DataIn => c2DataIn,
+ c2DataValidIn => c2DataValidIn,
+ c1DataOut => c1DataOut,
+ c1DataValidOut => c1DataValidOut
+ );
+
+ dac_gearbox_12x8_i: entity work.dac_gearbox_12x8 (RTL)
+ port map (
+ Clk1x => Clk1x,
+ RfClk => RfClk,
+ ac1Reset_n => ac1Reset_n,
+ arReset_n => arReset_n,
+ c1DataIn => c1DataOut,
+ c1DataValidIn => c1DataValidOut,
+ rDataOut => rDataOut,
+ rReadyForOutput => rReadyForOutput,
+ rDataValidOut => rDataValidOut
+ );
+
+end struct;