开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜