1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 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;
|