Skip to content
Snippets Groups Projects
Select Git revision
  • d81f992807bb509fc7754a0daebbca19a2f873ee
  • master default protected
  • L2SDP-1131
  • L2SDP-LIFT
  • L2SDP-1137
  • HPR-158
6 results

tb_common_multiplexer.vhd

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    tb_common_multiplexer.vhd 6.94 KiB
    -------------------------------------------------------------------------------
    --
    -- Copyright (C) 2013
    -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
    -- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
    --
    -- This program is free software: you can redistribute it and/or modify
    -- it under the terms of the GNU General Public License as published by
    -- the Free Software Foundation, either version 3 of the License, or
    -- (at your option) any later version.
    --
    -- This program is distributed in the hope that it will be useful,
    -- but WITHOUT ANY WARRANTY; without even the implied warranty of
    -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -- GNU General Public License for more details.
    --
    -- You should have received a copy of the GNU General Public License
    -- along with this program.  If not, see <http://www.gnu.org/licenses/>.
    --
    -------------------------------------------------------------------------------
    
    LIBRARY IEEE, common_lib;
    USE IEEE.std_logic_1164.ALL;
    USE IEEE.numeric_std.ALL;
    USE work.common_pkg.ALL;
    USE work.common_lfsr_sequences_pkg.ALL;
    USE work.tb_common_pkg.ALL;
    
    -- Purpose: Test bench for common_multiplexer.vhd and common_demultiplexer.vhd
    -- Usage:
    -- > as 6
    -- > run -all
    --   The tb p_verify self-checks the output by using first a 1->g_nof_streams
    --   demultiplexer and then a g_nof_streams->1 multiplexer. Both the use the
    --   same output and input selection so that the expected output data is again
    --   the same as the input stimuli data.
    -- Remark:
    
    ENTITY tb_common_multiplexer IS
      GENERIC (
        g_pipeline_demux_in  : NATURAL := 1;
        g_pipeline_demux_out : NATURAL := 1;
        g_nof_streams        : NATURAL := 3;
        g_pipeline_mux_in    : NATURAL := 1;
        g_pipeline_mux_out   : NATURAL := 1;
        g_dat_w              : NATURAL := 8;
        g_random_in_val      : BOOLEAN := FALSE;
        g_test_nof_cycles    : NATURAL := 500
      );
    END tb_common_multiplexer;
    
    ARCHITECTURE tb OF tb_common_multiplexer IS
    
      CONSTANT clk_period        : TIME := 10 ns;
      
      CONSTANT c_rl              : NATURAL := 1;
      CONSTANT c_init            : NATURAL := 0;
      
      -- DUT constants
      CONSTANT c_pipeline_demux  : NATURAL := g_pipeline_demux_in + g_pipeline_demux_out;
      CONSTANT c_pipeline_mux    : NATURAL := g_pipeline_mux_in   + g_pipeline_mux_out;
      CONSTANT c_pipeline_total  : NATURAL := c_pipeline_demux + c_pipeline_mux;
      
      CONSTANT c_sel_w           : NATURAL := ceil_log2(g_nof_streams);
      
      -- Stimuli
      SIGNAL tb_end             : STD_LOGIC := '0';
      SIGNAL rst                : STD_LOGIC;
      SIGNAL clk                : STD_LOGIC := '1';
      SIGNAL ready              : STD_LOGIC := '1';
      SIGNAL verify_en          : STD_LOGIC := '0';
      SIGNAL random_0           : STD_LOGIC_VECTOR(14 DOWNTO 0) := (OTHERS=>'0');  -- use different lengths to have different random sequences
      SIGNAL cnt_en             : STD_LOGIC := '1';
      
      -- DUT input
      SIGNAL in_dat             : STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0) := (OTHERS => '0');
      SIGNAL in_val             : STD_LOGIC;
      SIGNAL in_sel             : STD_LOGIC_VECTOR(c_sel_w-1 DOWNTO 0) := (OTHERS => '0');
      
      -- Demux-Mux interface
      SIGNAL demux_dat_vec      : STD_LOGIC_VECTOR(g_nof_streams*g_dat_w-1 DOWNTO 0);
      SIGNAL demux_val_vec      : STD_LOGIC_VECTOR(g_nof_streams        -1 DOWNTO 0);
      SIGNAL demux_val          : STD_LOGIC;
      SIGNAL demux_sel          : STD_LOGIC_VECTOR(c_sel_w-1 DOWNTO 0);
      
      -- DUT output
      SIGNAL out_dat            : STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
      SIGNAL out_val            : STD_LOGIC;
      
      -- Verify
      SIGNAL prev_out_dat       : STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);
      SIGNAL pipe_dat_vec       : STD_LOGIC_VECTOR(0 TO (c_pipeline_total+1)*g_dat_w-1);
      SIGNAL pipe_val_vec       : STD_LOGIC_VECTOR(0 TO (c_pipeline_total+1)*1      -1);
      
    BEGIN
    
      ------------------------------------------------------------------------------
      -- Stimuli
      ------------------------------------------------------------------------------
      
      -- . tb
      clk <= NOT clk OR tb_end AFTER clk_period/2;
      rst <= '1', '0' AFTER 3*clk_period;
      tb_end <= '0', '1' AFTER g_test_nof_cycles*clk_period;
      
      -- . data
      random_0 <= func_common_random(random_0) WHEN rising_edge(clk);
      
      cnt_en <= '1' WHEN g_random_in_val=FALSE ELSE random_0(random_0'HIGH);
    
      proc_common_gen_data(c_rl, c_init, rst, clk, cnt_en, ready, in_dat, in_val);
      
      -- . selection
      in_sel <= INCR_UVEC(in_sel, 1) WHEN rising_edge(clk) AND TO_UINT(in_sel)<g_nof_streams-1 ELSE
                TO_UVEC(0, c_sel_w)  WHEN rising_edge(clk);  -- periodic selection over all demultiplexer output and multiplexer input streams
    
      -- . verification
      p_verify_en : PROCESS
      BEGIN
        proc_common_wait_until_high(clk, in_val);
        proc_common_wait_some_cycles(clk, c_pipeline_total);
        
        verify_en <= '1';
        WAIT;
      END PROCESS;
      
      ------------------------------------------------------------------------------
      -- DUT : 1 --> g_nof_streams --> 1
      ------------------------------------------------------------------------------
      
      -- . Demultiplex single input to output[in_sel]
      u_demux : ENTITY work.common_demultiplexer
      GENERIC MAP (
        g_pipeline_in   => g_pipeline_demux_in,
        g_pipeline_out  => g_pipeline_demux_out,
        g_nof_out       => g_nof_streams,
        g_dat_w         => g_dat_w
      )
      PORT MAP(
        rst         => rst,
        clk         => clk,
        
        in_dat      => in_dat,
        in_val      => in_val,
    
        out_sel     => in_sel,
        out_dat     => demux_dat_vec,
        out_val     => demux_val_vec
      );
      
      -- . pipeline in_sel to align demux_sel to demux_*_vec
      u_pipe_sel : ENTITY common_lib.common_pipeline
      GENERIC MAP (
        g_pipeline  => c_pipeline_demux,
        g_in_dat_w  => c_sel_w,
        g_out_dat_w => c_sel_w
      )
      PORT MAP (
        rst     => rst,
        clk     => clk,
        in_dat  => in_sel,
        out_dat => demux_sel
      );
      
      demux_val <= demux_val_vec(TO_UINT(demux_sel));
    
      -- . Multiplex input[demux_sel] back to a single output
      u_mux : ENTITY work.common_multiplexer
      GENERIC MAP (
        g_pipeline_in   => g_pipeline_mux_in,  
        g_pipeline_out  => g_pipeline_mux_out,
        g_nof_in        => g_nof_streams,
        g_dat_w         => g_dat_w
      )
      PORT MAP (
        rst         => rst,
        clk         => clk,
        
        in_sel      => demux_sel,
        in_dat      => demux_dat_vec,
        in_val      => demux_val,
    
        out_dat     => out_dat,
        out_val     => out_val
      );     
                          
      
      ------------------------------------------------------------------------------
      -- Verification
      ------------------------------------------------------------------------------
      
      proc_common_verify_data(c_rl, clk, verify_en, ready, out_val, out_dat, prev_out_dat);                   -- verify out_dat assuming incrementing data
      proc_common_verify_latency("data",  c_pipeline_total, clk, verify_en, in_dat, pipe_dat_vec, out_dat);   -- verify out_dat using delayed input
      proc_common_verify_latency("valid", c_pipeline_total, clk, verify_en, in_val, pipe_val_vec, out_val);   -- verify out_val using delayed input
      
    END tb;