1
votes

I am writing a code in VHDL for arithmetic operations with the signals. I declared signals as follows:

    signal x : std_logic_vector (7 downto 0); 
    signal y: std_logic_vector (7 downto 0); 
    signal z: std_logic_vector (  7 downto 0);
    z<= x-y ;

In Detail:

  library ieee;
  use ieee.std_logic_1164.all;
  use ieee.numeric_std.all;
  USE ieee.std_logic_arith.conv_std_logic_vector;   
  library ieee_proposed;
  use ieee_proposed.fixed_pkg.all;
  signal heat0,heat1,heat2 : std_logic_vector(31 downto 0); 
  signal Data_In, M_AXIS_TDATA Fixed_input_tdata: std_logic_vector (31 downto 0);
  shared variable float,  h0,h1,h2,fixed1,fixed2,fixed3,fixed_shift :ufixed (23 downto -8);
  shared variable  fixed_64: ufixed (31 downto -32); 
 float := to_ufixed(unsigned (Fixed_input_tdata), 23,-8); 
 h2 :=  to_ufixed(unsigned(Data_In),23,-8); 
 heat1 <= Data_in; 
 h1 :=  to_ufixed(unsigned(heat1),23,-8);  
 heat0<= heat1;
 h0 :=  to_ufixed(unsigned(heat0),23,-8);
 heat1_mult  := std_logic_vector(unsigned(heat1) sll 1);

 fixed_shift := to_ufixed(unsigned (heat1_mult), 23,-8); 
 fixed1 := fixed_shift+h2;   
 fixed2 := h0-fixed1;   
 fixed_64 := fixed2 *float; 
 fixed3 := h1+fixed_64;--(23 downto -8);
M_AXIS_TDATA <= std_logic_vector (fixed3); 

So is it a right method to do arithmetic operations of std_logiC-vector with fixed-Point?

so lets take an example, z= 0x01-0x11. this will give negative output (0xF0): But I don't want negative output. I want to see this value as positive one. I even tried to change these signal types as unsigned, but still couldn't succeed. Actually I have some complex mathematical operations in vhdl, so I am just giving an example here to make my point understandable. I don't want to use signed values. How to send the positive unsigned output ?

Further another example: if my output is bf978000, It will be shown as negative number -1.18. I want it to be positive , not negative.

Let me take another example:

z= 2+ [0.2 * (4-10) ] = 0.8 . 0.8 in fixed point format ( 0x000000cd) (24 integer, 8 fractional format ): 0.2 is 0x00000033 in fixed point format . (24 integer, 8 fractional format ) but I am getting [0x00000002 + (0x00000033 * (0x00000004-0x0000000A) ] = FFFFFED0. (which is negative number). How to represent that output as 0.8 again.

2
Strongly advise using numeric_std instead of std_logic_vector for arithmetic. Also, if you're using Xilinx ISIM, turn its range checks on (in "Process Properties, Advanced view). Simulation is virtually useless without these checks on.user_1818839
Yes, I used that numeric-Std. It Is not a case for waveform, I check the output on terminal too. but that is the same problem for me .user4866219
If you subtract a big number (say, 7) from a smaller one (say, 2), what result do you expect?user_1818839
In your example above you are forgetting to scale the integer. 2 in your 8-fractional format would be 0x0200 not 0x0010 (which is 4, not 2). Get it right in basic arithmetic before trying it in VHDL.user_1818839
Not necessarily, but wherever integer and fixed point meet, you MUST pay attention to scaling, i.e. keep your eye on the decimal point. You cannot add or subtract unless the DP is in the same place in each number. And NONE of your numbers are simple std_logic_vector. They are either signed, unsigned, or fixed point. Mistaking them for slv is part of what is confusing you.user_1818839

2 Answers

1
votes

If you can use z <= x - y directly, it sounds like you are use one of the Synopsys packages like ieee.std_logic_unsigned, but instead you may consider using the VHDL standard package ieee.numeric_std, which is used in the example below.

The std_logic_vector does not by default have any numeric representation; it is just an array of std_logic. The unsigned type in ieee.numeric_std package can indicate a numeric representation of a std_logic_vector doing unsigned(x). So the above expression using unsigned subtraction will be:

z <= std_logic_vector(unsigned(x) - unsigned(z));

Any underrun/overrun, as with "z = 0x01-0x11", will result in wrapping without any indication.

1
votes

I think your question needs some refinement. I don't know why it's tagged verilog, the hexadecimal numbers you've shown are not signed, and std_logic_vector is not arithmetic in the first place (adding such interpretation is done with std_logic_arith or similar, but it's preferable to use unsigned and signed from numeric_std). As such, there must be more to your code for the subtraction to even work, and the negative numbers shown must be from something else; a simulator, perhaps? Simulators and waveform viewers tend to have their own settings for how to interpret signals.

So, expand your sample to show the environment you're using, and explain what operation you're actually seeking. Did you mean to take the absolute value of the difference, or use saturated arithmetic?