Skip to content
Snippets Groups Projects
Commit c683e251 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Added/updated functions for fixed point SLV/INTEGER to and from REAL.

parent 8a0bf9f5
Branches
No related tags found
1 merge request!162L2SDP-214
......@@ -192,6 +192,7 @@ test_bench_files =
tb/vhdl/tb_requantize.vhd
tb/vhdl/tb_resize.vhd
tb/vhdl/tb_round.vhd
tb/vhdl/tb_common_to_sreal.vhd
tb/vhdl/tb_delta_cycle_demo.vhd
tb/vhdl/tb_mms_common_variable_delay.vhd
......@@ -220,6 +221,7 @@ regression_test_vhdl =
tb/vhdl/tb_resize.vhd
#tb/vhdl/tb_round.vhd -- has no self verification yet
tb/vhdl/tb_requantize.vhd
tb/vhdl/tb_common_to_sreal.vhd
tb/vhdl/tb_common_pulse_delay.vhd
tb/vhdl/tb_tb_common_adder_tree.vhd
......
......@@ -373,8 +373,13 @@ PACKAGE common_pkg IS
FUNCTION TO_SVEC_32(dec : INTEGER) RETURN STD_LOGIC_VECTOR; -- = TO_SVEC() with w=32 for t_slv_32_arr slv elements
FUNCTION TO_UREAL(uvec : STD_LOGIC_VECTOR) RETURN REAL; -- convert unsigned slv of any length to REAL
FUNCTION TO_SREAL(svec : STD_LOGIC_VECTOR) RETURN REAL; -- convert signed slv of any length to REAL
FUNCTION TO_UINT(udec : REAL; w, resolution_w : INTEGER) RETURN NATURAL; -- REAL >= 0 to NATURAL fixed point number
FUNCTION TO_SINT(sdec : REAL; w, resolution_w : INTEGER) RETURN INTEGER; -- REAL to INTEGER fixed point number
FUNCTION TO_UVEC(udec : REAL; w, resolution_w : INTEGER) RETURN STD_LOGIC_VECTOR; -- REAL >= 0 to unsigned SLV fixed point number
FUNCTION TO_SVEC(sdec : REAL; w, resolution_w : INTEGER) RETURN STD_LOGIC_VECTOR; -- REAL to signed SLV fixed point number
FUNCTION TO_UREAL(uvec : STD_LOGIC_VECTOR) RETURN REAL; -- convert unsigned slv of any length to REAL, fixed point number with resolution = 1
FUNCTION TO_SREAL(svec : STD_LOGIC_VECTOR) RETURN REAL; -- convert signed slv of any length to REAL, fixed point number with resolution = 1
FUNCTION TO_UREAL(uvec : STD_LOGIC_VECTOR; resolution_w : INTEGER) RETURN REAL; -- convert unsigned fixed point slv of any length, and with resolution of 2**resolution_w, to REAL
FUNCTION TO_SREAL(svec : STD_LOGIC_VECTOR; resolution_w : INTEGER) RETURN REAL; -- convert signed fixed point slv of any length, and with resolution of 2**resolution_w, to REAL
......@@ -1813,61 +1818,158 @@ PACKAGE BODY common_pkg IS
RETURN TO_SVEC(dec, 32);
END;
FUNCTION TO_UINT(udec : REAL; w, resolution_w : INTEGER) RETURN NATURAL IS
CONSTANT c_resolution : REAL := 1.0 / 2.0**REAL(resolution_w);
CONSTANT c_ureal : REAL := ROUND(udec / c_resolution); -- rounds away from zero
BEGIN
IF udec >= 0.0 THEN
RETURN TO_SINT(udec, w + 1, resolution_w); -- w + 1, because unsigned has no sign bit
ELSE
REPORT "Negative REAL clipped to INTEGER 0 : " & REAL'IMAGE(c_ureal) & " --> 0" SEVERITY WARNING;
RETURN 0;
END IF;
END;
FUNCTION TO_SINT(sdec : REAL; w, resolution_w : INTEGER) RETURN INTEGER IS
CONSTANT c_max : REAL := 2.0**REAL(w - 1) - 1.0;
CONSTANT c_min : REAL := -2.0**REAL(w - 1);
CONSTANT c_resolution : REAL := 1.0 / 2.0**REAL(resolution_w);
CONSTANT c_sreal : REAL := ROUND(sdec / c_resolution); -- rounds away from zero
CONSTANT c_sint : INTEGER := INTEGER(c_sreal);
BEGIN
IF c_sreal >= c_min THEN
IF c_sreal <= c_max THEN
RETURN c_sint;
ELSE
REPORT "REAL clipped to INTEGER max : " & REAL'IMAGE(c_sreal) & " --> " & INTEGER'IMAGE(INTEGER(c_max)) SEVERITY WARNING;
RETURN INTEGER(c_max); -- clip to max
END IF;
ELSE
REPORT "REAL clipped to INTEGER min : " & REAL'IMAGE(c_sreal) & " --> " & INTEGER'IMAGE(INTEGER(c_min)) SEVERITY WARNING;
RETURN INTEGER(c_min); -- clip to min
END IF;
END;
FUNCTION TO_UVEC(udec : REAL; w, resolution_w : INTEGER) RETURN STD_LOGIC_VECTOR IS
-- Determine range that fits w bits
CONSTANT c_uvec_max : STD_LOGIC_VECTOR(w-1 DOWNTO 0) := (OTHERS => '1');
CONSTANT c_max : REAL := 2.0**REAL(w) - 1.0;
CONSTANT c_resolution : REAL := 1.0 / 2.0**REAL(resolution_w);
VARIABLE v_ureal : REAL := ROUND(udec / c_resolution); -- rounds away from zero
-- Convert to uvec
VARIABLE v_floor : REAL := 0.0;
VARIABLE v_uvec : STD_LOGIC_VECTOR(w-1 DOWNTO 0) := (OTHERS => '0');
BEGIN
IF udec >= 0.0 THEN
IF v_ureal <= c_max THEN
-- Avoid using INTEGER, which is limited to 32 bit, by determining per
-- bit whether the REAL value contributes to it.
-- If the REAL, after fixed point scaling by c_resolution, fits in w
-- bits, then the remainer v_floor after w times dividing by 2.0 will
-- be 0.0, because 2**w * 0.5 = 2**(w-1). For example u(4,0) = 7.0
-- yields:
-- 7.0 / 2 = 3.5 --> [0] = '1'
-- floor(3.5) = 3.0 / 2 = 1.5 --> [1] = '1'
-- floor(1.5) = 1.0 / 2 = 0.5 --> [2] = '1'
-- floor(0.5) = 0.0 / 2 = 0.0 --> [3] = '0'
-- so u(4,0) = 7.0 yields remainder 0.0 and SLV[3:0] = "0111"
-- similar u(4,0) = 8.0 yields remainder 0.5 and SLV[3:0] = "1000"
-- and u(4,0) > 8.0 yields remainder >= 0.5
FOR I IN 0 TO w-1 LOOP
v_ureal := v_ureal / 2.0;
v_floor := floor(v_ureal);
IF v_ureal > v_floor THEN
v_uvec(I) := '1';
END IF;
v_ureal := v_floor;
END LOOP;
ASSERT v_floor = 0.0 REPORT "Unexpected TO_UVEC REAL remainder : " & REAL'IMAGE(v_floor) & " /= 0.0" SEVERITY FAILURE;
RETURN v_uvec;
ELSE
REPORT "Positive REAL clipped to UVEC max : " & REAL'IMAGE(v_ureal) & " --> " & REAL'IMAGE(c_max) SEVERITY WARNING;
RETURN c_uvec_max;
END IF;
ELSE
REPORT "Negative REAL clipped to UVEC 0 : " & REAL'IMAGE(v_ureal) & " --> 0" SEVERITY WARNING;
RETURN TO_UVEC(0, w);
END IF;
END;
FUNCTION TO_SVEC(sdec : REAL; w, resolution_w : INTEGER) RETURN STD_LOGIC_VECTOR IS
-- Determine range that fits w bits
CONSTANT c_svec_max : STD_LOGIC_VECTOR(w-1 DOWNTO 0) := '0' & (w-2 DOWNTO 0 => '1');
CONSTANT c_svec_min : STD_LOGIC_VECTOR(w-1 DOWNTO 0) := '1' & (w-2 DOWNTO 0 => '0');
CONSTANT c_max : REAL := 2.0**REAL(w - 1) - 1.0;
CONSTANT c_min : REAL := -2.0**REAL(w - 1);
CONSTANT c_resolution : REAL := 1.0 / 2.0**REAL(resolution_w);
CONSTANT c_sreal : REAL := ROUND(sdec / c_resolution); -- rounds away from zero
-- Convert to positive using TO_UVEC, so if sdec is negative, then
-- negate sdec to have positive c_udec.
CONSTANT c_pos : BOOLEAN := sdec >= 0.0;
CONSTANT c_udec : REAL := sel_a_b(c_pos, sdec, -sdec);
-- Determine SLV value for positive REAL, use w+1 to fit negate of most negative value
CONSTANT c_uvec : STD_LOGIC_VECTOR(w DOWNTO 0) := TO_UVEC(c_udec, w + 1, resolution_w);
-- Back to signed, so if sdec is negative, then negate c_uvec to have positive c_svec
CONSTANT c_svec : STD_LOGIC_VECTOR(w DOWNTO 0) := sel_a_b(c_pos, c_uvec, NEGATE_SVEC(c_uvec));
BEGIN
IF c_sreal >= c_min THEN
IF c_sreal <= c_max THEN
RETURN c_svec(w-1 DOWNTO 0);
ELSE
REPORT "REAL clipped to SVEC max : " & REAL'IMAGE(c_sreal) & " --> " & REAL'IMAGE(c_max) SEVERITY WARNING;
RETURN c_svec_max; -- clip to max
END IF;
ELSE
REPORT "REAL clipped to SVEC min : " & REAL'IMAGE(c_sreal) & " --> " & REAL'IMAGE(c_min) SEVERITY WARNING;
RETURN c_svec_min; -- clip to min
END IF;
END;
FUNCTION TO_UREAL(uvec : STD_LOGIC_VECTOR) RETURN REAL IS
CONSTANT c_len : NATURAL := uvec'LENGTH;
VARIABLE v_uvec : STD_LOGIC_VECTOR(c_len-1 DOWNTO 0) := uvec;
CONSTANT c_uvec : STD_LOGIC_VECTOR(c_len-1 DOWNTO 0) := uvec;
VARIABLE v_real : REAL := 0.0;
BEGIN
-- Avoid using INTEGER, which is limited to 32 bit, by determining per bit whether it contributes to the REAL value
FOR I IN 0 TO c_len-1 LOOP
IF v_uvec(I)='1' THEN
v_real := v_real + 2**REAL(I);
IF c_uvec(I)='1' THEN
v_real := v_real + 2.0**REAL(I);
END IF;
END LOOP;
RETURN v_real;
END;
FUNCTION TO_SREAL(svec : STD_LOGIC_VECTOR) RETURN REAL IS
CONSTANT c_len : NATURAL := svec'LENGTH + 1; -- use +1 so the v_uvec can also fit abs() of most negative is -1 * -2**(c_len-1)
VARIABLE v_pos : BOOLEAN := TRUE;
VARIABLE v_uvec : STD_LOGIC_VECTOR(c_len-1 DOWNTO 0) := RESIZE_SVEC(svec, c_len);
VARIABLE v_real : REAL := 0.0;
BEGIN
-- Negate svec to have positive v_uvec.
IF SIGNED(svec) < 0 THEN
v_pos := FALSE;
v_uvec := INCR_UVEC(NOT svec, 1); -- negate the svec to make it positive
END IF;
-- Increase vector length by +1 so the c_uvec can also fit abs() of most negative is -1 * -2**(c_len-1)
CONSTANT c_len : NATURAL := svec'LENGTH + 1;
CONSTANT c_svec : STD_LOGIC_VECTOR(c_len-1 DOWNTO 0) := RESIZE_SVEC(svec, c_len);
-- If c_svec is negative, then negate c_svec to have positive c_uvec.
CONSTANT c_pos : BOOLEAN := SIGNED(svec) >= 0;
CONSTANT c_uvec : STD_LOGIC_VECTOR(c_len-1 DOWNTO 0) := sel_a_b(c_pos, c_svec, NEGATE_SVEC(c_svec));
-- Determine REAL value for positive
v_real := TO_UREAL(v_uvec);
CONSTANT c_real : REAL := TO_UREAL(c_uvec);
BEGIN
-- Update the sign
IF v_pos THEN
RETURN v_real;
ELSE
RETURN -v_real;
END IF;
RETURN sel_a_b(c_pos, c_real, -c_real);
END;
FUNCTION TO_UREAL(uvec : STD_LOGIC_VECTOR; resolution_w : INTEGER) RETURN REAL IS
-- First convert as unsigned integer:
VARIABLE v_real : REAL := TO_UREAL(uvec);
BEGIN
-- Then scale to real (see TO_SREAL)
RETURN v_real * 2.0**REAL(resolution_w);
-- First convert as unsigned integer, then scale to real. See TO_SREAL()
-- for interpretation of resolution_w
RETURN TO_UREAL(uvec) / 2.0**REAL(resolution_w);
END;
FUNCTION TO_SREAL(svec : STD_LOGIC_VECTOR; resolution_w : INTEGER) RETURN REAL IS
-- First convert as signed integer:
VARIABLE v_real : REAL := TO_SREAL(svec);
BEGIN
-- Then scale to real:
-- First convert as unsigned integer, then scale to real
-- . The resolution_w is the number of bits that LSbit 0 in svec(HIGH-1 DOWNTO 0) is after
-- (when resolution_w > 0), or before (when resolution_w < 0) the fixed point.
-- . The real value is then scaled by scaling the integer value by 2**(-1 * resolution_w):
-- . The real value is then scaled by scaling the integer value by 1.0 / 2**(resolution_w):
-- . resolution_w = 0 : scale by 2**0 = 1, so no scaling and the value is treated as an integer
-- . resolution_w < 0 : scale up
-- . resolution_w > 0 : scale down
RETURN v_real * 2.0**REAL(-1 * resolution_w);
RETURN TO_SREAL(svec) / 2.0**REAL(resolution_w);
END;
......@@ -1931,7 +2033,10 @@ PACKAGE BODY common_pkg IS
FUNCTION NEGATE_SVEC(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
BEGIN
-- use NUMERIC_STD to avoid range limitation of 32b INTEGER
-- default approach
RETURN STD_LOGIC_VECTOR(-SIGNED(vec)); -- negate by multiplying by -1
-- alternative equivalent approach
-- RETURN INCR_UVEC(NOT vec, 1); -- negate by using two complement negate
END;
-- Negate vec, but avoid overflow by forcing -min to +max. Use w <= vec'LENGTH.
......
-- --------------------------------------------------------------------------
-- 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;
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;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment