Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VHDL How to add a std_logic_vector with a std_logic signal together?

Tags:

vhdl

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
like image 739
Jonathan Avatar asked Jan 23 '23 02:01

Jonathan


2 Answers

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.

like image 51
Martin Thompson Avatar answered Apr 30 '23 17:04

Martin Thompson


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!!!

like image 20
jdehaan Avatar answered Apr 30 '23 17:04

jdehaan