VHDL How to add a std_logic_vector with a std_logic signal together?
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);
I'm trying to build a simple ALU, and one of the functions this ALU provides 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
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.
I wrote a more detailed page on this: http://parallelpoints.com/node/3
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&q=group:comp.lang.vhdl+numeric_std#83cc0f19350fc392 and also in the comp.lang.vhdl FAQ.
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!!!
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
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.
精彩评论