how to convert 32bit vector to a number

Status
Not open for further replies.
1. You should be setting it to signed 16 fixed all the time, as thats what the number is.
2. you can output reals to a text file, but they get written in the scientific format:1.234e7
You'll have to write a custom function to make it more readible:

or just borrow mine:


Code VHDL - [expand]
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
------------------------------------------------------------------------------------
  --Returns the size of the given integer as if it were a string in the given Radix
  ------------------------------------------------------------------------------------
  function get_int_length(x : integer; radix : positive range 2 to 36 := 10) return integer is
    variable temp : integer := abs x;
    variable len  : integer := 0;
  begin
    
    if x = 0 then
      len := 1;
    end if;
    
    while temp > 0 loop
      temp := temp / radix;
      
      len  := len + 1;
    end loop;
    
    if x < 0 then
      len := len + 1;   --add extra character for -ve sign
    end if;
      
    return len;
  end function get_int_length;
 
  --------------------------------------------------------------------------------------------------
  --casts a real to an integer, with or without rounding
  --------------------------------------------------------------------------------------------------
  function real_to_int( x : real; round : boolean := false) return integer is
    variable ret : integer;
    variable temp : integer;
  begin
    if round then
      ret := integer(x);
    else
      temp := integer(x);
        
      --always round towards 0
      if temp >= 0 then
        --rounds positive numbers down
        if real(temp) > x then
          ret := temp - 1;
        else
          ret := temp;
        end if;
      else
          --rounds -ve numbers up 
        if real(temp) < x then
          ret := temp + 1;
        else
          ret := temp;
        end if;
      end if;
    end if;
    
    return ret;
  end function;
 
  ------------------------------------------------------------------------
  --Converts a real to a string
  --gives a string representation of a real if you dont want the enire M.FeE format, 
  --and just want m.f
  ------------------------------------------------------------------------
  function real_to_string(x : real; num_frac : positive; radix : positive range 2 to 36 := 10) return string is
    
    --mantissa and fraction as integers
    constant ABS_X            : real              := abs(x);
    constant MANTISSA         : integer           := real_to_int(ABS_X, false);
    constant FRACTION         : integer           := real_to_int( (
                                                                    ( ABS_X-real(MANTISSA) )*real(radix**num_frac) + 0.5
                                                                  ),--takes care of rounding                                                                  
                                                                  false );
    
    constant STRING_LEN_M     : integer           := get_int_length(MANTISSA, radix); --length of mantissa                                                 
    constant STRING_LEN_F     : integer           := get_int_length(FRACTION, radix); --length of fractional part
    constant PAD_LEN          : integer           := num_frac - STRING_LEN_F;         --number of pad 0's
    
    function x_is_neg return integer is
    begin
      if x < 0.0 then return 1;
      else            return 0;
      end if;
    end function x_is_neg;
    
    variable pad_loop         : integer           := 0;                                 
    variable i                : integer;
    variable ret_string       : string(1 to (STRING_LEN_M + STRING_LEN_F + PAD_LEN) + 1 + x_is_neg );
    variable neg_offset       : integer := 0;
  begin
    
    if x < 0.0 then
      ret_string(1)                 := '-';
      neg_offset                    := 1;
    end if;
    
    ret_string( (1+neg_offset) to (STRING_LEN_M + neg_offset) ) := int_to_string(MANTISSA, radix);
    ret_string(STRING_LEN_M+1+neg_offset)                       := '.';
   
    --pad out the string
    while pad_loop < PAD_LEN loop
      i                       := STRING_LEN_M + 2 + pad_loop + neg_offset;
      ret_string(i)           := '0';        
      pad_loop                := pad_loop + 1;
    end loop;
    
    ret_string( (STRING_LEN_M+2+PAD_LEN+neg_offset) to ret_string'high) := int_to_string(FRACTION, radix);
      
    return ret_string;
  end function;

 



thank very much ill try to work with that in my code later...but before i get to this step i have a strange problem in the simulation:

this is my code:

Code:
library IEEE;
use ieee.std_logic_1164.all;
use ieee.fixed_pkg.all;
--use ieee.std_logic_arith.all;
use ieee.numeric_std.all ;

entity  fixed_test is
port(
dudx   : in sfixed(2 downto -16);
dvdx   : in sfixed(2 downto -16);
u0     : in sfixed(11 downto -16);
dudy   : in sfixed(2 downto -16);
dvdy   : in sfixed(2 downto -16);
v0     : in sfixed(11 downto -16);
data_in : in std_logic_vector (19 downto 0); 
data_out : out  std_logic_vector (57 downto 0);
clk   : in std_logic
);
end  fixed_test;


architecture behave of fixed_test is
signal out_x     : sfixed(12 downto -16);
signal out_y     : sfixed(12 downto -16); 
signal in_x     : integer range 0 to 640;
signal in_y     :  integer range 0 to 640;



begin

process (clk)
begin
  
in_x    <= to_integer(unsigned(data_in(9 downto 0)));
in_y    <= to_integer(unsigned(data_in(19 downto 10)));

out_x<= (dudx*in_x)+(dudy*in_y)+u0;
out_y<= (dvdx*in_x)+(dvdy*in_y)+v0;

end process;



data_out <= to_slv(out_x) & to_slv(out_y);

end behave;

and this is my testbench:

Code:
library IEEE;
use ieee.std_logic_1164.all;
use ieee.fixed_pkg.all;
use ieee.numeric_std.all ;


entity  fixed_test_tb is end;



architecture behave of fixed_test_tb is


component fixed_test 
port(
dudx   : in sfixed(2 downto -16);
dvdx   : in sfixed(2 downto -16);
u0     : in sfixed(11 downto -16);
dudy   : in sfixed(2 downto -16);
dvdy   : in sfixed(2 downto -16);
v0     : in sfixed(11 downto -16);
data_in : in std_logic_vector (19 downto 0); 
data_out : out  std_logic_vector (57 downto 0);
clk   : in std_logic
);

end component;

signal s_in_x,s_in_y   : integer range 0 to 640;
signal s_dudx,s_dvdx,s_dudy,s_dvdy  : sfixed(2 downto -16) ;
signal s_u0,s_v0 : sfixed(11 downto -16);
signal s_data_in : std_logic_vector (19 downto 0);
signal s_data_out : std_logic_vector (57 downto 0);
signal s_clk : std_logic;
constant clk_period : time := 10 ns;


begin
  
DUT:fixed_test
port map (
		dudx    =>s_dudx,
		dvdx    =>s_dvdx,
		u0      =>s_u0,
		dudy    =>s_dudy,
		dvdy    =>s_dvdy,
		v0      =>s_v0,
		data_in =>s_data_in,
		data_out =>s_data_out,
		clk    => s_clk);



s_dudx  <=to_sfixed(0.7071,2,-16);
s_dvdx  <=to_sfixed(0.7071,2,-16);		
s_u0	<=to_sfixed(296.5685,11,-16);	
s_dudy	<=to_sfixed(-0.7071,2,-16);
s_dvdy  <=to_sfixed(0.7071,2,-16);
s_v0	<=to_sfixed(-75.9798,11,-16);
s_data_in	<= std_logic_vector( to_unsigned( s_in_y, 10 )) & std_logic_vector( to_unsigned( s_in_x, 10 ));
--s_data_in	<= std_logic_vector( to_unsigned( 0 , 10 )) & std_logic_vector( to_unsigned( 5 , 10 ));



process   
begin
    s_clk <= '0';
    wait for clk_period/2;
    s_clk <= '1';
    wait for clk_period/2;
end process;


process(s_clk) 
begin  
if s_clk'EVENT and s_clk='1' then
    if s_in_x<480 then 
      s_in_x<=s_in_x+1;
    elsif s_in_y<640 then
      s_in_x<=0;
      s_in_y<=s_in_y+1;
    else
      s_in_x<=0;
     s_in_y<=0;
    end if;  
end if;

end process;


end behave;


i wrote a testbench that each clock enter to my code a different coordinate (in_x,in_y) as integer (example: (0,0),(1,0),(2,0),(3,0)...(640,480))
to in_x and in_y..and my code need to do a calculation and put the resulte out to out_x and out_y...

the code work ok in the first 4 coordinats (0,0),(1,0),(2,0),(3,0) but from (4,0) i get the same result as (3,0) coordinate ...and nothing change in the result
only when the testbench get to (0,1)...the code give me a good result again in the output..but again when he get to (4,0)coordinate and up he give me the same resulte as (3,1) coordinate..
and so on...

i dont know what i'm doing wrong :sad:???

can you please help me with that
 



hi

i was wondering what type i need to send to your function and what im getting as a result?

basically i have 2 Sfixed signal (14 downto -16) that i want to write to a file as a real numbers( for example 563.1212 or -896.2548)

can you please tell me what type my signals need to be to use your function?

thanks


BTW i did some debugging for my code ans i succeed to use the sfixed types (im geting a "trancuted" warning but is ok because im getting a correct result) ...so thanks for the help i'm learning alot from your help
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…