Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] adding std_logic numbers

Status
Not open for further replies.

sed_y

Newbie level 4
Joined
Jan 25, 2009
Messages
6
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,355
hi, consider the following mux code
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_SIGNED.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity examp1_pg165 is
    Port ( a : in  STD_LOGIC;
           b : in  STD_LOGIC;
           c : in  STD_LOGIC;
           sel : in  STD_LOGIC;
           y : out  STD_LOGIC);
end examp1_pg165;

architecture Behavioral of examp1_pg165 is
  
begin
     y<= a + b when sel='1' else 
	      a+c ;
end Behavioral;
this gives an error in xilinX ISE as

Code:
 + can not have such operands in this context.
1)So, even after including numeric library, I cannot use '+' with std_logic?
2) so, do i need to convert to signed/unsigned and then add?
3) what is the safest way to use numeric libraries?

Code:
   use IEEE.STD_LOGIC_ARITH.ALL;
   use IEEE.STD_LOGIC_SIGNED.ALL;
   use IEEE.STD_LOGIC_UNSIGNED.ALL;
or

Code:
   use IEEE.NUMERIC_STD.ALL;
   use IEEE.STD_LOGIC_SIGNED.ALL;
   use IEEE.STD_LOGIC_UNSIGNED.ALL;
some authors say, unsigned library is not needed, others say, signed is not needed.
while some say, do not use std_logic_arith with signed/unsigned.
between numeric_std and std_logic_arith, one can make a choice based upon the operators defined. I believe, if more type conversions are needed, std_logic_arith would be better as it has more operator overloading, but it no Boolean operators?
4) The else clause covers other std_logic values. for synthesis point of view, suppose sel takes 'z', then too, y<-a+c. In real world application, would we do this, or write disconnect the mux by using something like

Code:
 y<= a + b when sel='1' else 
	      a+c  when sel ='0' else
               'z';
Thanks
sid
 

1-3: VHDL doesn't treat a std_logic as a number ever. numeric_std defines two types of _vectors_, unsigned and signed. These have convenience functions for addition with integers. the std_logic_*signed packages have some functions for treating std_logic_vectors as signed/unsigned. to use either though, you'd need to convert the std_logic to unsigned or signed. eg, a vector 0 downto 0.

4.) the synthesis library would need to support that in some way. I suspect none will support that. While it is valid for simulation, it probably will not be synthesizable. In the listed case, the synthesis tool would likely ignore the last case, as sel will be either 0 or 1 from its perspective.
 

You cannot use std_logic_signed and std_logic_unsigned at the same time. It is one or the other. This is the disadvantage of these packages as you can only ever do signed or unsigned arithmatic, but never both in the same entity. std_logic_arith defines signed and unsigned types like numeric_std, but it is not a standard and has less functions that numeric_std.

You mention lots of type conversions if you use numeric_std. This is only the case if you insist on using std_logic_vectors everywhere. There is no need to do this. You can quite happily use signed/unsigned in your port definitions so no type conversion is required. You can even use integers if you like. For some reason, many VHDL designers want to use std_logic_vectors on ports - there is no need. You can even use signed/unsigned at the top level - its still and array of bits. The reason people do it is many years ago synthesisors only supported std_logic_vector. But this change a long long time ago.
 

For some reason, many VHDL designers want to use std_logic_vectors on ports - there is no need. You can even use signed/unsigned at the top level - its still and array of bits. The reason people do it is many years ago synthesisors only supported std_logic_vector. But this change a long long time ago.

Then I must be old, very old:)
This limitation disappeared early '00.
 

hi,
I read the Xilinx documentation(synthesis guide) and it says that try to use std_logic_vector as port signals.
so, in your knowledge, it does not matter for synthesis these days?

sid

---------- Post added at 18:11 ---------- Previous post was at 18:11 ----------

hi permute,
i did the way you suggested. and it works.

thanks
sid

---------- Post added at 20:08 ---------- Previous post was at 18:11 ----------

hi guys,
based on the these inputs, I have written following programs. I would like to have comments on these

1) this one adds two 1 bit std_logic numbers and gives sum, carry using std_logic_arith library
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;



entity add_stdlogic_arithlib is
    Port ( a : in  std_logic;
           b : in  std_logic;
           y : out  std_logic;
           cy : out  std_logic);
end add_stdlogic_arithlib;

architecture Behavioral of add_stdlogic_arithlib is
signal a1,b1,y1:unsigned(1 downto 0) ;
signal y2:std_logic_vector(1 downto 0) ;



begin
     a1<= conv_unsigned(a,2);  
	                             
	  b1<= conv_unsigned(b,2);
	  y1<= a1 + b1 ;                           -- 2 bit unsigned add
	  y2<= conv_std_logic_vector(y1,2); -- back to std_logic
	  cy<=y2(1);
	  y<= y2(0);


end Behavioral;

Question 1: std_logic_arith has conversion between std_ulogic and unsigned, so, "b1<= conv_unsigned(b,2);" works because std_logic is subtype of std_ulogic?

2) this code does the same as above but using numeric_std library . here, the library does not specify std_ulogic to unsigned, so I first make std_logic_vector and then convert and add.

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


entity add_stdlogic_numlib is
    Port ( a : in  std_logic;
           b : in  std_logic;
           y : out  std_logic;
           cy : out  std_logic);
end add_stdlogic_numlib;

architecture Behavioral of add_stdlogic_numlib is
signal a11,b11,y1:unsigned(1 downto 0) ;
signal a1,b1:std_logic_vector(1 downto 0) ;

begin	  
	 
     a1 <= '0'& a;   -- std_logic vector
	  a11<= unsigned(a1);  -- std_logic vector to unsigned implicit, explicit using to_unsigned not defined
	  b1<= '0'& b ;
	  b11<= unsigned(b1);  
	  y1<= a11+b11;       -- unsigned sum,2 bit
	  cy<=y1(1);           
	  y<= y1(0);

end Behavioral;

Question2) This simulates and synthesis right. is there more efficient way to do it?

3) Now, I add two std_logic_vectors using std_logic_arith library.
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;


entity add_stdlogicv_arithlib is
   generic(n:integer:= 4);
    Port ( a : in  std_logic_vector(n-1 downto 0);
           b : in  std_logic_vector(n-1 downto 0);
           y : out  std_logic_vector(n downto 0));
           
end add_stdlogicv_arithlib;

architecture Behavioral of add_stdlogicv_arithlib is

begin
    	 
		  y<= std_logic_vector(signed'(signed(sxt(a,n+1)) + signed(sxt(b,n+1))));  
  end Behavioral;
Question 3) If i do not add type qualifier and do
Code:
y<= std_logic_vector(signed(sxt(a,n+1)) + signed(sxt(b,n+1)));
Xilinx gives error
Code:
 Expression in type conversion to std_logic_vector has 2 possible definitions in this scope, for example, SIGNED and std_logic_vector

Why? after signed conversion, I am adding two signed numbers, so argument for std_logic_vector is signed, why the compiler needs type qualifier signed'?

4) now, i add std_logic vectors using numeric library.There is no sxt function in numeric library, only resize, which works on signed, so I first convert std_logic_vector to signed, then resize, add
and convert back.

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

entity add_stdlogicv_numlib is
    generic(n:integer:= 4);
    Port ( a : in  std_logic_vector(n-1 downto 0);
           b : in  std_logic_vector(n-1 downto 0);
           y : out  std_logic_vector(n downto 0));
 end add_stdlogicv_numlib;

architecture Behavioral of add_stdlogicv_numlib is

signal y2:signed(n downto 0) ;
begin
       	  y2<=resize(signed(a),n+1) + resize(signed(b),n+1);
           y<= std_logic_vector(y2);   

end Behavioral;

question 4) This also simulates and synthesizes well.

However, I wanted to use something like
Code:
std_logic_vector(signed(std_logic_vector'("0")&a) + signed(std_logic_vector'("0")&b));
but, since this is signed, i should be able to use 'left attribute instead of "0". But, I am not able to do so.for example
Code:
 std_logic_vector("a'left")
gives error
Code:
The expression can not be qualified by type std_logic_vector
so, what is the right way of adding the type qualifier here?

I know this is a big query, but would appreciate any help, as it would clear lot of issues.
Thanks
sid
 

I read the Xilinx documentation(synthesis guide) and it says that try to use std_logic_vector as port signals.
so, in your knowledge, it does not matter for synthesis these days?
"Try to use" isn't a strict requirement. I'm not working with Xilinx XST, but I would be rather surprized if it doesn't support numeric bit vector types for ports. Even constraint integer types are supported by many synthesis tools. But there may be reasons to restrict the design to std_logic_vector.

std_ulogic is more an abstract type than anything you have to care for in hardware design. If you are interested in the exact meaning, you can refer e.g. to the VHDL specification IEEE Std 1076.

is there more efficient way to do it?
The question often arises with VHDL. The strong typification actually requires a kind of longwinded coding style, lacking elegancy. To give one hint, if you're not satisfied with the set of conversion functions provided by the library, you're free to define a more efficient function on your own.

but, since this is signed, i should be able to use 'left attribute instead of "0". But, I am not able to do so.for example
You misunderstood the meaning of the 'left attribute. It's giving bit positions (integer values) rather than bit values. Thus std_logic_vector("a'left") isn't a legal VHDL expression.

It seems to me that you're making progress. It's not necessary, to achieve optimal coding style at once. Making the code compile correctly isn't bad.
 
  • Like
Reactions: sed_y

    sed_y

    Points: 2
    Helpful Answer Positive Rating
hi FVM,
the response is a bit late, but i thought everybody would be busy in long weekend.
anyhow, thanks for pointing out
You misunderstood the meaning of the 'left attribute. It's giving bit positions (integer values) rather than bit values. Thus std_logic_vector("a'left") isn't a legal VHDL expression.
.
based in this, i tried three options all of which work.

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

entity add_stdlogicv_numlib is
    generic(n:integer:= 4);
    Port ( a : in  std_logic_vector(n-1 downto 0);
           b : in  std_logic_vector(n-1 downto 0);
           y : out  std_logic_vector(n downto 0);
	   mthd: in std_logic_vector(1 downto 0));
 end add_stdlogicv_numlib;

architecture Behavioral of add_stdlogicv_numlib is

signal y2:signed(n downto 0) ;
signal y3,y4:std_logic_vector(n downto 0) ;

begin
  process(a,b,y3,y4,y2,mthd)
    begin
          if (mthd="00") then
			     y3<= std_logic'(a(a'left))&a;
			     y4<= std_logic'(b(b'left))&b;
			     y<= std_logic_vector(signed(y3)+ signed(y4));
				
			 elsif (mthd= "01") then
			    y<= std_logic_vector(signed(std_logic'(a(a'left))&a) + signed(std_logic'(b(b'left))&b));
			
			 else
			  y2<=resize(signed(a),n+1) + resize(signed(b),n+1);
           y<= std_logic_vector(y2);   
			   
           end if;
	end process;	  
			  
end Behavioral;

now, I have 2 problems
1) this worked when i made three separate programs with each of these options. but, within this mux structure , i get error:
Code:
Xst:737 - Found 5-bit latch for signal <y2>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
Xst:737 - Found 5-bit latch for signal <y3>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
Xst:737 - Found 5-bit latch for signal <y4>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.

any ideas why?
also,
Code:
y<= std_logic_vector(signed(std_logic'(a(a'left))&a) + signed(std_logic'(b(b'left))&b));
works but as i had pointed earlier using std-logic_arith , following gives type qualification error. why?
Code:
 y<= std_logic_vector(signed(sxt(a,n+1)) + signed(sxt(b,n+1)));

Thank you
 

Latch generation is a side effect of your way to use signals for intermediate results. You can avoid it by either using a continuous assignment outside a process or variables instead of signals for y2, y3, y4.
 

1) this worked when i made three separate programs with each of these options. but, within this mux structure , i get error:
Code:
Xst:737 - Found 5-bit latch for signal <y2>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
Xst:737 - Found 5-bit latch for signal <y3>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
Xst:737 - Found 5-bit latch for signal <y4>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.

any ideas why?

Yes. Because it is an asynchronous process, you need to assign all outputs (Y,Y2,Y3,Y4) in all paths. Only Y is assign for all conditions, the others are not assigned sometimes and so have to remember their state, hence the latch.

also,
Code:
y<= std_logic_vector(signed(std_logic'(a(a'left))&a) + signed(std_logic'(b(b'left))&b));
works but as i had pointed earlier using std-logic_arith , following gives type qualification error. why?
Code:
 y<= std_logic_vector(signed(sxt(a,n+1)) + signed(sxt(b,n+1)));

IIRC, sxt only works on signed types, and a and b are std_logic_vectors.
Also, this might happen if you have numeric_std and std_logic_arith included in the same file. Because they both declare type signed, you need to specify which signed type you mean:

y<= std_logic_vector(std_logic_arith.signed(sxt(a,n+1)) + std_logic_arith.signed(sxt(b,n+1)));

But all this is rather long winded.

Main rules to stick with now and continue before you develop bad habbits:
1. use numeric_std, forget about std_logic_arith. You wont regret it, especially when you start using the new 2008 libraries (because they can convert everything to numeric_std types, not std_logic_arith).

2. use signed/unsigned on your ports. Then you dont have to do all these long winded type conversions.
 
  • Like
Reactions: sed_y

    sed_y

    Points: 2
    Helpful Answer Positive Rating
#2 is more of an opinion. I nearly always violate it because of things like:
Line 195: Type error near tmp ; current type std_logic_vector; expected type unsigned
Line 207: Type error near poly ; current type unsigned; expected type std_logic_vector
which was introduced simply by declaring an unsigned instead of a std_logic_vector in a random VHDL project.

In the vast majority of cases I will use arithmetic on a given signal on less than 3 lines, all of which are within a very small section. At the same time, the signal will be used alongside std_logic_vectors, typically on several lines spread throughout the file.

So I can either micromanage signals, or just do the type conversions every time. As a result, I pretty much will never type something as unsigned or signed unless there is a _real_ reason to do so -- either a compare greater/less or a multiplication. As defined by VHDL's rules I clearly didn't want an unsigned/signed -- the signal is used as a std_logic_vector on several lines while it is used as an unsigned on very few lines.

Some of this port debate will probably go away when VHDL2008 becomes prevalent and modules are ported to VHDL2008. VHDL2008 allows types to be generics. eg, a generic can be used to declare the type of a port instead of just its size.

I also will point out that I routinely use record and array types as ports. I don't follow the SLV-only requirement. But I don't create many signed/unsigned signals which results in very few ports of those types.
 

yes, thanks. i need to assigning dummy o/p for y2,y3,y4 or use variables. both of them worked as below
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity add_stdlogicv_numlib1 is
    generic(n:integer:= 4);
    Port ( a : in  std_logic_vector(n-1 downto 0);
           b : in  std_logic_vector(n-1 downto 0);
           y : out  std_logic_vector(n downto 0);
			  mthd: in std_logic_vector(1 downto 0));
 end add_stdlogicv_numlib1;

architecture Behavioral of add_stdlogicv_numlib1 is

begin
  process(a,b,mthd)
    variable y2:signed(n downto 0) ;
    variable y3,y4:std_logic_vector(n downto 0) ;
    begin
          if (mthd="00") then
			     y3:= std_logic'(a(a'left))&a;
			     y4:= std_logic'(b(b'left))&b;
			     y<= std_logic_vector(signed(y3)+ signed(y4));
				
			 elsif (mthd= "01") then
			    
			    y<= std_logic_vector(signed(std_logic'(a(a'left))&a) + signed(std_logic'(b(b'left))&b));
			
			 else
			    y2:=resize(signed(a),n+1) + resize(signed(b),n+1);
			    y<= std_logic_vector(y2);  
			  			   
           end if;
			  
	end process;	  
			  
end Behavioral;

or
Code:
entity add_stdlogicv_numlib is
    generic(n:integer:= 4);
    Port ( a : in  std_logic_vector(n-1 downto 0);
           b : in  std_logic_vector(n-1 downto 0);
           y : out  std_logic_vector(n downto 0);
			  mthd: in std_logic_vector(1 downto 0));
 end add_stdlogicv_numlib;

architecture Behavioral of add_stdlogicv_numlib is

signal y2:signed(n downto 0) ;
signal y3,y4:std_logic_vector(n downto 0) ;

begin
  process(a,b,y3,y4,y2,mthd)
    begin
          if (mthd="00") then
			     y2<=(others=>'0');  -- to provide o/p for y2 to avoid latch inference
			     y3<= std_logic'(a(a'left))&a;
			     y4<= std_logic'(b(b'left))&b;
			     y<= std_logic_vector(signed(y3)+ signed(y4));
				
			 elsif (mthd= "01") then
			    y2<=(others=>'0'); 
			    y3<=(others=>'0');  
				 y4<=(others=>'0');
			    y<= std_logic_vector(signed(std_logic'(a(a'left))&a) + signed(std_logic'(b(b'left))&b));
			
			 else
			  y3<=(others=>'0');  -- to provide o/p for y3 to avoid latch inference
			  y4<=(others=>'0');
			  y2<=resize(signed(a),n+1) + resize(signed(b),n+1);
			  y<= std_logic_vector(y2);  
			  
			   
           end if;
	end process;	  
			  
end Behavioral;

Thank you

---------- Post added at 23:52 ---------- Previous post was at 23:49 ----------

from all the replies , i have gathered the following
1) use signed/unsigned on ports and latest vhdl package like Vhdl 2000 rather than vhdl 93.
2) if portability is required, std_logic_vector should be good, and better to use numeric

:smile::smile:

---------- Post added at 23:53 ---------- Previous post was at 23:52 ----------

from all the replies , i have gathered the following
1) use signed/unsigned on ports and latest vhdl package like Vhdl 2000 rather than vhdl 93.
2) if portability is required, std_logic_vector should be good, and better to use numeric_std

:smile::smile:
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top