Skip to content
Snippets Groups Projects
Select Git revision
  • c9aa70ccdfe26b8df28c1fb5ca1349d42f39adc3
  • master default protected
  • L2SDP-LIFT
  • L2SDP-1113
  • HPR-158
5 results

run_altera_simlib_comp

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    tb_common_to_sreal.vhd 8.42 KiB
    -- --------------------------------------------------------------------------
    -- Copyright 2021
    -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
    -- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
    --
    -- Licensed under the Apache License, Version 2.0 (the "License");
    -- you may not use this file except in compliance with the License.
    -- You may obtain a copy of the License at
    --
    -- http://www.apache.org/licenses/LICENSE-2.0
    --
    -- Unless required by applicable law or agreed to in writing, software
    -- distributed under the License is distributed on an "AS IS" BASIS,
    -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    -- See the License for the specific language governing permissions and
    -- limitations under the License.
    -- --------------------------------------------------------------------------
    --
    -- Author: E. Kooistra, 13 okt 2021
    -- Purpose: Verify to_sreal() and to_svec() from common_pkg.vhd
    -- Description:
    --   The tb shows how a REAL value is represented by a fixed point SLV. The
    --   signed REAL value is denoted as s(w, p) as defined and explained in []:
    --
    --     s = sign bit, value +1 or -1
    --     w = width in number of bits of the SLV
    --     p = position of the fixed point in the SLV, p = 0 for integers, p > 0
    --         for p bit fraction, p < 0 for scale factor 2**p
    --
    --   The resolution of the REAL value is r = 1/2**p.
    --
    --   . to_svec() converts a fixed point INTEGER or SLV into a REAL value
    --   . to_sreal() converts a REAL value into a fixed point SLV or INTEGER
    --
    --   The tb verifies that a_slv(w-1:0) = to_svec(to_sreal(a_slv(w-1:0))).
    --
    -- References:
    -- [1] https://support.astron.nl/confluence/display/L2M/L3+SDP+Decision%3A+Definition+of+fixed+point+numbers
    --
    -- Usage:
    -- > as 5, observe signals with radix decimal
    -- > run -all
    LIBRARY IEEE;
    USE IEEE.STD_LOGIC_1164.ALL;
    USE IEEE.MATH_REAL.ALL;
    USE work.common_pkg.ALL;
    
    
    ENTITY tb_common_to_sreal IS
    END tb_common_to_sreal;
    
    ARCHITECTURE tb OF tb_common_to_sreal IS
    
      CONSTANT clk_period   : TIME    := 10 ns;
    
      CONSTANT c_resolution_w : NATURAL := 5;
      CONSTANT c_width        : NATURAL := 4;
      CONSTANT c_min          : INTEGER := -2**(c_width-1);
      CONSTANT c_max          : INTEGER :=  2**(c_width-1)-1;
    
      SIGNAL tb_end           : STD_LOGIC := '0';
      SIGNAL clk              : STD_LOGIC := '1';
      SIGNAL rst              : STD_LOGIC := '1';
    
      SIGNAL a_real           : REAL := 0.0;
      SIGNAL a_sint           : INTEGER := 0;
      SIGNAL a_slv            : STD_LOGIC_VECTOR(c_width-1 DOWNTO 0) := (OTHERS => '0');
      SIGNAL dbg_resolution_w : INTEGER := 0;
      SIGNAL dbg_resolution   : REAL := 0.0;
    
      PROCEDURE proc_wait_some_cycles(SIGNAL clk          : IN  STD_LOGIC;
                                             c_nof_cycles : IN  NATURAL) IS
      BEGIN
        FOR I IN 0 TO c_nof_cycles-1 LOOP WAIT UNTIL rising_edge(clk); END LOOP;
      END proc_wait_some_cycles;
    
    BEGIN
    
      -- Stimuli
      clk <= NOT clk OR tb_end AFTER clk_period/2;
      rst <= '1', '0' AFTER 3*clk_period;
      
      -- Testbench end
      p_tb : PROCESS
        VARIABLE v_slv : STD_LOGIC_VECTOR(c_width-1 DOWNTO 0) := (OTHERS => '0');
        VARIABLE v_real : REAL;
      BEGIN
        -- Simulator evaluates process until first WAIT at startup 0 ps, but
        -- simulator does not recognise WAIT in proc_wait_some_cycles() then.
        -- Therefore add WAIT here to avoid ASSERT messages that occur later.
        WAIT UNTIL rising_edge(clk);
        proc_wait_some_cycles(clk, 10);
    
        -- Try all v_slv for c_width and resolutions beyond c_width
        FOR R IN -c_resolution_w TO c_resolution_w LOOP
          dbg_resolution_w <= R;
          dbg_resolution <= 1.0 / 2.0**REAL(R);
          FOR I IN c_min TO c_max LOOP
            v_slv := TO_SVEC(I, c_width);
            -- Convert fixed point v_slv with binary point at resolution width R, to real and back to slv
            v_real := TO_SREAL(v_slv, R);
            -- Show as signals in Wave window
            a_real <= v_real;
            a_sint <= TO_SINT(v_real, c_width, R);
            a_slv <= TO_SVEC(v_real, c_width, R);
            WAIT UNTIL rising_edge(clk);
            -- Verify
            ASSERT a_sint = I REPORT "Wrong REAL to INTEGER conversion for I = " & INTEGER'IMAGE(I) SEVERITY ERROR;
            ASSERT a_slv = v_slv REPORT "Wrong REAL to SLV conversion for I = " & INTEGER'IMAGE(I) SEVERITY ERROR;
          END LOOP;
          proc_wait_some_cycles(clk, 10);
        END LOOP;
    
        proc_wait_some_cycles(clk, 10);
    
        -- Try overflow
        -- . No overflow with 4 bit integers for -16.49 : +15.49
        v_real := -9.51; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real := -9.49; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real := -8.51; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real := -8.49; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real := -7.51; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real := -7.49; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real := -6.51; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real := -6.49; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real :=  6.49; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real :=  6.51; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real :=  7.49; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real :=  7.51; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        proc_wait_some_cycles(clk, 5);
    
        -- . Just overflow with 4 bit integers for -16.5 : +15.5
        v_real := -15.5; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real :=  15.5; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        proc_wait_some_cycles(clk, 5);
    
        -- . Large overflow with 4 bit integers for << -16.5 : >> +15.5
        v_real := -18.0; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real :=  18.0; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real := -28.0; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real :=  28.0; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real := -38.0; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real :=  38.0; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real := -48.0; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real :=  48.0; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real := -58.0; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real :=  58.0; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real := -68.0; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
        v_real :=  68.0; a_real <= v_real; a_sint <= TO_SINT(v_real, 4, 0); a_slv <= TO_SVEC(v_real, 4, 0); WAIT UNTIL rising_edge(clk);
    
        proc_wait_some_cycles(clk, 10);
        tb_end <= '1';
        WAIT;
      END PROCESS;
    
      -- TO_SINT() and TO_SVEC() must always yield same result
      ASSERT a_sint = TO_SINT(a_slv) REPORT "Unexpected difference between TO_SINT() and TO_SVEC() :" & INTEGER'IMAGE(a_sint) & " /= " & INTEGER'IMAGE(TO_SINT(a_slv));
    
    END tb;