aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/top/n3xx/WrapBufg.vhd
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/top/n3xx/WrapBufg.vhd')
-rw-r--r--fpga/usrp3/top/n3xx/WrapBufg.vhd172
1 files changed, 172 insertions, 0 deletions
diff --git a/fpga/usrp3/top/n3xx/WrapBufg.vhd b/fpga/usrp3/top/n3xx/WrapBufg.vhd
new file mode 100644
index 000000000..1f3417658
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/WrapBufg.vhd
@@ -0,0 +1,172 @@
+--------------------------------------------------------------------------------
+--
+-- File: WrapBufg.vhd
+-- Author: Robert Atkinson
+-- Original Project: RF-RIO
+-- Date: 13 January 2012
+--
+--------------------------------------------------------------------------------
+-- Copyright 2012 Ettus Research, A National Instruments Company
+-- SPDX-License-Identifier: GPL-3.0
+--------------------------------------------------------------------------------
+--
+-- Purpose: This is a simple wrapper around a BUFG to make instantiating BUFGCTRLs
+-- easier without a headache to relearn the port usage each time. This
+-- wrapper only supports a single input clock. When disabled, the BUFG
+-- output is zero.
+--
+--------------------------------------------------------------------------------
+
+library ieee;
+ use ieee.std_logic_1164.all;
+
+library UNISIM;
+ use UNISIM.vcomponents.all;
+
+
+entity WrapBufg is
+ generic(
+ -- ClkIn is selected by default if set to true, otherwise zero.
+ kEnableByDefault : boolean := false;
+ -- If kIgnore is set to true, then the BUFG will switch inputs whenever
+ -- the aCe signal changes as opposed to waiting for ClkIn to transition low.
+ kIgnore : boolean := false;
+ -- If aCe is asynchronous to ClkIn, set this generic to true and the select
+ -- lines of the BUFGCTRL will be used. If aCe is synchronous to ClkIn, then the CE pins
+ -- will be used - note that this requires that setup and hold times be met! If aCe is
+ -- synchronous to ClkIn but no timing relationship is really needed then set this to true.
+ kEnableIsAsync : boolean := false
+ );
+ port(
+ -- Input clock
+ ClkIn : in std_logic;
+ -- Enable to the BUFG - this signal is treated either asynchronously
+ -- or synchronously based on the value of the kEnableIsAsync generic.
+ aCe : in std_logic;
+ -- Clock output
+ ClkOut : out std_logic
+ );
+end WrapBufg;
+
+
+architecture rtl of WrapBufg is
+
+ signal iCe0,
+ iCe1,
+ aSel0,
+ aSel1,
+ kIgnore0 : std_logic;
+
+begin
+
+ -- From Data Sheet:
+ -- The BUFGCTRL is designed to switch between two clock inputs without the possibility of a
+ -- glitch. When the presently selected clock transitions from High to Low after S0 and S1
+ -- changes, the output is kept Low until the other (to-be-selected) clock has transitioned from
+ -- High to Low. Then the new clock starts driving the output. The default configuration for
+ -- BUFGCTRL is falling edge sensitive and held at Low prior to the input switching.
+ -- BUFGCTRL can also be rising edge sensitive and held at High prior to the input switching
+ -- by using the INIT_OUT attribute.
+ -- In some applications the conditions previously described are not desirable. Asserting the
+ -- IGNORE pins will bypass the BUFGCTRL from detecting the conditions for switching
+ -- between two clock inputs. In other words, asserting IGNORE causes the MUX to switch
+ -- the inputs at the instant the select pin changes. IGNORE0 causes the output to switch away
+ -- from the I0 input immediately when the select pin changes, while IGNORE1 causes the
+ -- output to switch away from the I1 input immediately when the select pin changes.
+ -- Selection of an input clock requires a "select" pair (S0 and CE0, or S1 and CE1) to be
+ -- asserted High. If either S or CE is not asserted High, the desired input will not be selected.
+ -- In normal operation, both S and CE pairs (all four select lines) are not expected to be
+ -- asserted High simultaneously. Typically only one pin of a "select" pair is used as a select
+ -- line, while the other pin is tied High.
+
+ -- If the aCe input is async to the I clock, then use the select pins
+ -- of the BUFGCTRL since setup and hold times at the S* pins do not have
+ -- to be met. Enable both Select pins if the aCe signal is synchronous to the I clock.
+ aSel0 <= aCe when kEnableIsAsync else
+ '1';
+ aSel1 <= not aCe when kEnableIsAsync else
+ '1';
+
+ -- Only use the CE pins when the input aCe signal is synchronous to the I clock.
+ iCe0 <= '1' when kEnableIsAsync else
+ aCe;
+ iCe1 <= '1' when kEnableIsAsync else
+ not aCe;
+
+ -- No PkgNiUtilities for me.
+ kIgnore0 <= '1' when kIgnore else
+ '0';
+
+ --vhook_i BUFGCTRL GlobalBuffer
+ --vhook_a {^IS_(.*)} '0'
+ --vhook_a INIT_OUT 0
+ --vhook_a PRESELECT_I0 kEnableByDefault
+ --vhook_a PRESELECT_I1 not kEnableByDefault
+ --vhook_a O ClkOut
+ --vhook_a CE0 iCe0
+ --vhook_a CE1 iCe1
+ --vhook_a I0 ClkIn
+ --vhook_a I1 '0'
+ --vhook_a IGNORE0 kIgnore0
+ --vhook_a IGNORE1 '1'
+ --vhook_a S0 aSel0
+ --vhook_a S1 aSel1
+ GlobalBuffer: BUFGCTRL
+ generic map (
+ INIT_OUT => 0, --integer:=0
+ IS_CE0_INVERTED => '0', --bit:='0'
+ IS_CE1_INVERTED => '0', --bit:='0'
+ IS_I0_INVERTED => '0', --bit:='0'
+ IS_I1_INVERTED => '0', --bit:='0'
+ IS_IGNORE0_INVERTED => '0', --bit:='0'
+ IS_IGNORE1_INVERTED => '0', --bit:='0'
+ IS_S0_INVERTED => '0', --bit:='0'
+ IS_S1_INVERTED => '0', --bit:='0'
+ PRESELECT_I0 => kEnableByDefault, --boolean:=false
+ PRESELECT_I1 => not kEnableByDefault) --boolean:=false
+ port map (
+ O => ClkOut, --out std_ulogic
+ CE0 => iCe0, --in std_ulogic
+ CE1 => iCe1, --in std_ulogic
+ I0 => ClkIn, --in std_ulogic
+ I1 => '0', --in std_ulogic
+ IGNORE0 => kIgnore0, --in std_ulogic
+ IGNORE1 => '1', --in std_ulogic
+ S0 => aSel0, --in std_ulogic
+ S1 => aSel1); --in std_ulogic
+
+
+ --vscan Begin Add Explain Clock
+ --vscan # These are the outputs of the BUFGCTRLs in the WrapBufg module. VScan
+ --vscan # sees the output as glitchy but the clocks are guaranteed to switch
+ --vscan # in a glitchless fashion provided that either setup and hold times
+ --vscan # are met at the CE pins of the BUFGCTRL (these paths are analyzed by the
+ --vscan # tools for timing) or the CE pins are hardwired and the S pins are used
+ --vscan # which require no timing relationship to the input clocks.
+ --vscan *[WrapBufg]GlobalBuffer/[BUFGCTRL]O
+ --vscan End Add Explain Clock
+
+
+ -- Check that enable lines match up with the generics of the BUFGCTRL
+ --vscan vscan_off
+ --synthesis translate_off
+ SimProcess: process
+ begin
+ wait for 1 ns;
+ if kEnableIsAsync then
+ assert kEnableByDefault = (aSel0 = '1')
+ report "Initial condition on enable lines do not match between" & LF
+ & "the BUFGCTRL generic and the SEL line"
+ severity error;
+ else
+ assert kEnableByDefault = (iCe0 = '1')
+ report "Initial condition on enable lines do not match between" & LF
+ & "the BUFGCTRL generic and the CE line"
+ severity error;
+ end if;
+ wait;
+ end process SimProcess;
+ --synthesis translate_on
+ --vscan vscan_on
+
+end rtl;