diff options
Diffstat (limited to 'fpga/usrp3/top/n3xx/WrapBufg.vhd')
-rw-r--r-- | fpga/usrp3/top/n3xx/WrapBufg.vhd | 172 |
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; |