Skip to content
Snippets Groups Projects
Select Git revision
1 result Searching

t_defaultmailaddresses.py

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    tb_common_transpose.vhd 9.18 KiB
    -------------------------------------------------------------------------------
    --
    -- Copyright (C) 2012
    -- 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 common_lib.common_pkg.ALL;
    USE common_lib.tb_common_pkg.ALL;
    
    -- Purpose: Test bench for common_transpose.vhd
    -- Usage:
    -- > as 3
    -- > run -all
    --   p_verify self-checks the data output and the addr output of two times the
    --   transpose.
    
    ENTITY tb_common_transpose IS
      GENERIC (
        g_pipeline_shiftreg  : NATURAL := 0;
        g_pipeline_transpose : NATURAL := 0;
        g_pipeline_hold      : NATURAL := 0;
        g_pipeline_select    : NATURAL := 1;
        g_nof_data           : NATURAL := 3;
        g_data_w             : NATURAL := 12;
        g_addr_w             : NATURAL := 9;
        g_addr_offset        : NATURAL := 10    -- default use fixed offset, in_offset * g_nof_data must fit in g_addr_w address range
      );
    END tb_common_transpose;
    
    ARCHITECTURE tb OF tb_common_transpose IS
    
      CONSTANT clk_period     : TIME := 10 ns;
      
      CONSTANT c_pipeline     : NATURAL := g_pipeline_shiftreg + g_pipeline_transpose + g_pipeline_select;
      CONSTANT c_repeat       : NATURAL := 10;
      CONSTANT c_lo           : NATURAL := 0;
      CONSTANT c_interval_len : NATURAL := 100;
      CONSTANT c_blk_len      : NATURAL := 10;
      CONSTANT c_gap_len      : NATURAL := 50;
      
      CONSTANT c_symbol_w     : NATURAL := g_data_w/g_nof_data;
      
      CONSTANT c_frame_len    : NATURAL :=  7 * g_nof_data;
      CONSTANT c_frame_eop    : NATURAL := (c_frame_len-1) MOD c_frame_len;
      
      PROCEDURE proc_align_eop(SIGNAL clk      : IN  STD_LOGIC;
                               SIGNAL stimuli_phase : IN  STD_LOGIC;
                               SIGNAL in_val   : OUT STD_LOGIC) IS
      BEGIN
        WHILE stimuli_phase='0' LOOP
          in_val <= '1';
          proc_common_wait_some_cycles(clk, 1);
        END LOOP;
        in_val <= '0';
      END proc_align_eop;
      
      -- Stimuli
      SIGNAL tb_end         : STD_LOGIC := '0';
      SIGNAL rst            : STD_LOGIC;
      SIGNAL clk            : STD_LOGIC := '1';
      
      SIGNAL stimuli_end    : STD_LOGIC;
      SIGNAL stimuli_data   : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := (OTHERS=>'0');
      SIGNAL stimuli_phase  : STD_LOGIC;
      
      SIGNAL in_offset      : STD_LOGIC_VECTOR(g_addr_w-1 DOWNTO 0) := TO_UVEC(g_addr_offset, g_addr_w);
      SIGNAL in_addr        : STD_LOGIC_VECTOR(g_addr_w-1 DOWNTO 0) := (OTHERS=>'0');
      SIGNAL in_data        : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0) := (OTHERS=>'0');
      SIGNAL in_val         : STD_LOGIC;
      SIGNAL in_eop         : STD_LOGIC;
      
      -- DUT output
      SIGNAL trans_offset   : STD_LOGIC_VECTOR(g_addr_w-1 DOWNTO 0) := TO_SVEC(-g_addr_offset, g_addr_w);  -- use -g_addr_offset as inverse operation
      SIGNAL trans_addr     : STD_LOGIC_VECTOR(g_addr_w-1 DOWNTO 0);
      SIGNAL trans_data     : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0);
      SIGNAL trans_val      : STD_LOGIC;
      SIGNAL trans_eop      : STD_LOGIC;
      
      SIGNAL out_addr       : STD_LOGIC_VECTOR(g_addr_w-1 DOWNTO 0);
      SIGNAL out_data       : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0);
      SIGNAL out_val        : STD_LOGIC;
      SIGNAL out_eop        : STD_LOGIC;
      
      -- Verify
      SIGNAL verify_en      : STD_LOGIC := '0';
      SIGNAL ready          : STD_LOGIC := '1';
      SIGNAL prev_out_addr  : STD_LOGIC_VECTOR(g_addr_w-1 DOWNTO 0) := (OTHERS=>'1');
      SIGNAL prev_out_data  : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0) := (OTHERS=>'1');
      
    BEGIN
    
      -- Stimuli
      clk <= NOT clk OR tb_end AFTER clk_period/2;
      rst <= '1', '0' AFTER 3*clk_period;
      
      p_stimuli : PROCESS
      BEGIN
        in_val <= '0';
        in_eop <= '0';
        verify_en <= '0';
        proc_common_wait_until_low(clk, rst);
        proc_common_wait_some_cycles(clk, 10);
        verify_en <= '1';
        
        -- Verify pulsed valid
        FOR J IN 0 TO 2*g_nof_data LOOP
          FOR I IN 1 TO c_blk_len+J LOOP
            proc_common_val_duty(1, 1, clk, in_val);
          END LOOP;
          proc_align_eop(clk, stimuli_phase, in_val);
          proc_common_eop(clk, in_val, in_eop);
          proc_common_wait_some_cycles(clk, 2*c_blk_len);
        END LOOP;
        
        FOR J IN 0 TO 2*g_nof_data LOOP
          FOR I IN 1 TO c_blk_len+J LOOP
            proc_common_val_duty(1, 1, clk, in_val);
          END LOOP;
          proc_align_eop(clk, stimuli_phase, in_val);
          proc_common_wait_some_cycles(clk, 1);
          proc_common_eop(clk, in_val, in_eop);
          proc_common_wait_some_cycles(clk, 2*c_blk_len);
        END LOOP;
        
        -- Verify muli pulsed valid
        FOR P IN 0 TO 1 LOOP
          FOR I IN c_lo TO c_repeat LOOP
            FOR J IN c_lo TO c_repeat LOOP
              IF P=0 THEN
                proc_common_val_duty(I, J, clk, in_val);
              ELSE
                proc_common_val_duty(J, I, clk, in_val);
              END IF;
            END LOOP;
          END LOOP;
          proc_common_wait_some_cycles(clk, c_gap_len);
          FOR I IN c_lo TO c_repeat LOOP
            FOR J IN c_repeat DOWNTO c_lo LOOP
              IF P=0 THEN
                proc_common_val_duty(I, J, clk, in_val);
              ELSE
                proc_common_val_duty(J, I, clk, in_val);
              END IF;
            END LOOP;
          END LOOP;
          proc_common_wait_some_cycles(clk, c_gap_len);
          FOR I IN c_repeat DOWNTO c_lo LOOP
            FOR J IN c_lo TO c_repeat LOOP
              IF P=0 THEN
                proc_common_val_duty(I, J, clk, in_val);
              ELSE
                proc_common_val_duty(J, I, clk, in_val);
              END IF;
            END LOOP;
          END LOOP;
          proc_common_wait_some_cycles(clk, c_gap_len);
          FOR I IN c_repeat DOWNTO c_lo LOOP
            FOR J IN c_repeat DOWNTO c_lo LOOP
              IF P=0 THEN
                proc_common_val_duty(I, J, clk, in_val);
              ELSE
                proc_common_val_duty(J, I, clk, in_val);
              END IF;
            END LOOP;
          END LOOP;
          proc_align_eop(clk, stimuli_phase, in_val);
          proc_common_eop(clk, in_val, in_eop);
          proc_common_wait_some_cycles(clk, c_gap_len);
        END LOOP;
        
        -- Verify active valid
        in_val <= '1';
        proc_common_wait_until_lo_hi(clk, stimuli_end);
        proc_common_wait_some_cycles(clk, c_interval_len);
        proc_align_eop(clk, stimuli_phase, in_val);
        proc_common_eop(clk, in_val, in_eop);
        in_val <= '0';
        proc_common_wait_some_cycles(clk, c_gap_len);
        
        tb_end <= '1';
        WAIT;
      END PROCESS;
    
      stimuli_end <= '1' WHEN SIGNED(in_data)=-1 ELSE '0';
      
      in_addr <= stimuli_data(g_addr_w-1 DOWNTO 0);
      in_data <= stimuli_data(g_data_w-1 DOWNTO 0);
      
      stimuli_data  <= INCR_UVEC(stimuli_data, 1) WHEN rising_edge(clk) AND in_val='1';
      stimuli_phase <= in_val WHEN TO_UINT(stimuli_data) MOD g_nof_data = g_nof_data-2 ELSE '0';
      
      -- DUT
      u_transpose_in : ENTITY common_lib.common_transpose
      GENERIC MAP (
        g_pipeline_shiftreg  => g_pipeline_shiftreg,
        g_pipeline_transpose => g_pipeline_transpose,
        g_pipeline_hold      => g_pipeline_hold,
        g_pipeline_select    => g_pipeline_select,
        g_nof_data           => g_nof_data,
        g_data_w             => g_data_w,
        g_addr_w             => g_addr_w,
        g_addr_offset        => g_addr_offset
      )
      PORT MAP (
        rst        => rst,
        clk        => clk,
        
        in_offset  => in_offset,
        in_addr    => in_addr,
        in_data    => in_data,
        in_val     => in_val,
        in_eop     => in_eop,
        
        out_addr   => trans_addr,
        out_data   => trans_data,
        out_val    => trans_val,
        out_eop    => trans_eop
      );  
      
      u_transpose_out : ENTITY common_lib.common_transpose
      GENERIC MAP (
        g_pipeline_shiftreg  => g_pipeline_shiftreg,
        g_pipeline_transpose => g_pipeline_transpose,
        g_pipeline_hold      => g_pipeline_hold,
        g_pipeline_select    => g_pipeline_select,
        g_nof_data           => g_nof_data,
        g_data_w             => g_data_w,
        g_addr_w             => g_addr_w,
        g_addr_offset        => g_addr_offset
      )
      PORT MAP (
        rst        => rst,
        clk        => clk,
        
        in_offset  => trans_offset,
        in_addr    => trans_addr,
        in_data    => trans_data,
        in_val     => trans_val,
        in_eop     => trans_eop,
        
        out_addr   => out_addr,
        out_data   => out_data,
        out_val    => out_val,
        out_eop    => out_eop
      );  
      
      -- Verification p_verify
      proc_common_verify_data(1, clk, verify_en, ready, out_val, out_addr, prev_out_addr);
      proc_common_verify_data(1, clk, verify_en, ready, out_val, out_data, prev_out_data);
      
    END tb;