aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/top/x400/rf/sim/tb_duc_400m_saturate.vhd
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/top/x400/rf/sim/tb_duc_400m_saturate.vhd')
-rw-r--r--fpga/usrp3/top/x400/rf/sim/tb_duc_400m_saturate.vhd133
1 files changed, 133 insertions, 0 deletions
diff --git a/fpga/usrp3/top/x400/rf/sim/tb_duc_400m_saturate.vhd b/fpga/usrp3/top/x400/rf/sim/tb_duc_400m_saturate.vhd
new file mode 100644
index 000000000..e3117bdd6
--- /dev/null
+++ b/fpga/usrp3/top/x400/rf/sim/tb_duc_400m_saturate.vhd
@@ -0,0 +1,133 @@
+--
+-- Copyright 2021 Ettus Research, a National Instruments Brand
+--
+-- SPDX-License-Identifier: LGPL-3.0-or-later
+--
+-- Module: tb_duc_400m_saturate
+--
+-- Description:
+--
+-- Self-checking testbench used to check the saturation logic needed in DDC.
+--
+
+library IEEE;
+ use IEEE.std_logic_1164.all;
+ use IEEE.numeric_std.all;
+
+library WORK;
+ use WORK.PkgRf.all;
+
+entity tb_duc_400m_saturate is
+end tb_duc_400m_saturate;
+
+
+architecture RTL of tb_duc_400m_saturate is
+
+ component duc_400m_saturate
+ port (
+ Clk : in std_logic;
+ cDataIn : in std_logic_vector(287 downto 0);
+ cDataValidIn : in std_logic;
+ cReadyForInput : out std_logic;
+ cDataOut : out std_logic_vector(191 downto 0);
+ cDataValidOut : out std_logic := '0');
+ end component;
+
+ signal TestStart : boolean := false;
+
+ signal cDataIn : std_logic_vector(287 downto 0);
+ signal cDataOut : std_logic_vector(191 downto 0);
+ signal cDataValidIn : std_logic;
+ signal cDataValidOut : std_logic;
+
+ signal StopSim : boolean;
+ constant kPer : time := 10 ns;
+ constant kSamplesPerClock : integer := 12;
+
+ signal Clk: std_logic := '1';
+
+ procedure ClkWait(X : positive := 1) is
+ begin
+ for i in 1 to X loop
+ wait until rising_edge(Clk);
+ end loop;
+ end procedure ClkWait;
+
+begin
+
+ Clk <= not Clk after kPer/2 when not StopSim else '0';
+
+
+ -- cReadyForInput is a constant in the design and is not being tested.
+ dut: duc_400m_saturate
+ port map (
+ Clk => Clk,
+ cDataIn => cDataIn,
+ cDataValidIn => cDataValidIn,
+ cReadyForInput => open,
+ cDataOut => cDataOut,
+ cDataValidOut => cDataValidOut);
+
+ main: process
+ begin
+
+ ClkWait;
+ TestStart <= false;
+ ClkWait;
+ TestStart <= true;
+
+ -- This wait is needed to sweep through the entire range of 18 bits signed
+ -- value. Since we operate the saturation logic with 12 samples per cycle,
+ -- we need to wait for 2^kDucDataOutWidth/12. We are adding an extra 10
+ -- clock cycles wait just as a buffer for the DUT latency.
+ ClkWait(2**kDucDataOutWidth/kSamplesPerClock + 10);
+ StopSim <= true;
+ wait;
+ end process;
+
+ -- Process to generate 18-bit signed data.
+ DataGen: process(Clk)
+ variable Sample : Sample18_t := kSmallest18;
+ begin
+ if falling_edge(Clk) then
+ if TestStart then
+ cDataValidIn <= '1';
+ cDataIn <= "000000" & std_logic_vector(Sample+kSamplesPerClock-1) &
+ "000000" & std_logic_vector(Sample+kSamplesPerClock-2) &
+ "000000" & std_logic_vector(Sample+kSamplesPerClock-3) &
+ "000000" & std_logic_vector(Sample+kSamplesPerClock-4) &
+ "000000" & std_logic_vector(Sample+kSamplesPerClock-5) &
+ "000000" & std_logic_vector(Sample+kSamplesPerClock-6) &
+ "000000" & std_logic_vector(Sample+kSamplesPerClock-7) &
+ "000000" & std_logic_vector(Sample+kSamplesPerClock-8) &
+ "000000" & std_logic_vector(Sample+kSamplesPerClock-9) &
+ "000000" & std_logic_vector(Sample+kSamplesPerClock-10) &
+ "000000" & std_logic_vector(Sample+kSamplesPerClock-11) &
+ "000000" & std_logic_vector(Sample+kSamplesPerClock-12);
+ Sample := Sample +12;
+ end if;
+ end if;
+ end process;
+
+ -- Check if saturation and data packing is done correctly.
+ DataCheck: process(Clk)
+ variable Sample : Sample18_t := kSmallest18;
+ variable ExpectedData : std_logic_vector(15 downto 0);
+
+ begin
+ if falling_edge(Clk) then
+ if cDataValidOut then
+ for i in 1 to 12 loop
+ ExpectedData := tb_saturate(std_logic_vector(Sample));
+ assert cDataOut(kSatDataWidth*i-1 downto kSatDataWidth*(i-1)) = ExpectedData
+ report "Saturation data out mismatch in index : " & to_string(i) & LF &
+ "Expected data is : " & to_hstring(ExpectedData) & LF &
+ "Received data is : " & to_hstring(cDataOut(kSatDataWidth*i-1 downto kSatDataWidth*(i-1)))
+ severity error;
+ Sample := Sample+1;
+ end loop;
+ end if;
+ end if;
+ end process;
+
+end RTL;