tags:

views:

2262

answers:

4

I've got

douta   : in std_logic_vector (3 downto 0);
doutb   : in std_logic_vector (3 downto 0);
c0  : in std_logic;
f1  : in std_logic;
f0  : in std_logic;
res : out std_logic_vector (3 downto 0);

Im' trying to build a simple ALU, and one of the function this ALU provide is when

f1 and f0 both = 1 res = douta plus b plus c0

so I wrote

f1 = '1' and f0 = '1' then res <= douta + doutb + c0;

but obviously its not gonna work because the datatype of douta and doutb is std_logic_vector where as co is just std_logic

and I got this error when compile

' Error 603 line 34 : Incompatible types for arithmetic operator: LHS=std_logic_vector!18, RHS=std_logic

any idea how I can fix this problem ?

edit: also have tried

f1 = '1' and f0 = '1' then res <= douta + doutb + ("000" & c0);

but still no luck, this time the compiler says

LHS=std_logic_vector!7, RHS=array_1_of_std_logic_3_d_0
+1  A: 

You could transform c0 into a std_logic_vector. It has been a long time since I made VHDL...

if f1 = '1' and f0 = '1' then
 if c0 = '1' then
   res <= douta + doutb + "0001";
 else
   res <= douta + doutb;
 end if;
end if;

This is probably not so performant, maybe the silicium compiler synthesizes it so something good, maybe it's a better idea to write it so that c0 is modified into a vector and then add all three douta, doutb and the converter c0. Another option would be to do the calculations bit for bit but then what do you have the compiler for?

It may sound ridiculous but sometimes the compiler produces a better result if you give it some hints like this (just try it out and verify the output, by such a small example not a big deal):

if f1 = '1' and f0 = '1' then
 if c0 = '1' then
   res <= douta + doutb + "0001";
 else
   res <= douta + doutb + "0000";
 end if;
end if;

Another advice, if you write if's and the results are somewhat strange, introduce an else to fix the undecided states (some compilers behave badly if they have too much freedom!). But that's from my experience that is already getting back to year 2004!!!

jdehaan
thanks for the suggestion, yes I tried this f1 = '1' and f0 = '1' then res <= douta + doutb + ("000" but again I thought just make up the missing bits with all 1 but it doesn't work the compiler says Incompatible types for arithmetic operator: LHS=std_logic_vector!7, RHS=array_1_of_std_logic_3_d_0I guess I will give your idea a try !
Jonathan
+1  A: 

Oh I think I found a fix, need to add the following library

use ieee.std_logic_arith.all;

and what we tried will work :) Thanks to @jdehaan

Jonathan
A: 

You don't need to convert the std_logic to a std_logic_vector to do the addition. Just do the addition as is, and make sure that "res" has enough bits to hold the max answer. In this case res needs to be 5 bits wide in order for it to now overflow.

And as a style nit, don't name your input ports "dout". That's bad form. Call them din here, because that's what they are. And in the architecture than instantiates this you connect another component's output port named "dout" to the "din" of this component.

SDGator
+1  A: 

Please don't use std_logic_vector if you're going to do arithmetic on them. Use ieee.numeric_std, and use the signed or unsigned types. Then you can just add your '0' or '1' to it.

The workaround of using std_logic_arith.all is a fudge using a non-standard library, which can get you into portability troubles when you change toolchains.

There was some discussion on this on comp.lang.vhdl here: http://groups.google.com/group/comp.lang.vhdl/browse_thread/thread/549e1bbffd35914d/83cc0f19350fc392?hl=en&amp;q=group:comp.lang.vhdl+numeric_std#83cc0f19350fc392 and also in the comp.lang.vhdl FAQ.

Martin Thompson