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.

Using The Multiplier Operator In VHDL

Status
Not open for further replies.

jerryt

Junior Member level 3
Joined
Jan 26, 2009
Messages
31
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,608
Hi, I am fairly new to VHDL. I have a project for school where I need to multiply constants and send the result to an output. Before I write the in depth code I wanted to verify the VHDL multiply operator with a simple example. I assign two constants integer values and then multiply these two constants and store the result in output C.

I tried to compile my code but I see the following error:

# ** Error: D:/Profiles/w30239/My Documents/Miscallaneous/ECE 584/Project/Example Code/MultExample.vhd(20): Type error resolving infix expression "*" as type ieee.std_logic_1164.STD_LOGIC.
# ** Error: D:/Profiles/w30239/My Documents/Miscallaneous/ECE 584/Project/Example Code/MultExample.vhd(22): VHDL Compiler exiting

I can't figure out how to resolve the error. My code is below. How do I fix this compiler error?
Thanks for everyone's help!
----------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity MultExample is
Port (C : OUT std_logic);
end MultExample;

architecture Behavioral of MultExample is

constant A: integer:= 4;
constant B: integer:= 2;

begin

C <= A*B;

end Behavioral;
----------------------------------------------------------
 

C is a std_logic, so it is a single bit. You cannot create a single bit from two 32 bit numbers. You need to make C an integer.

In future, you may want to use the signed/unsigned types. THis way you can select how long the integers are - because the integer type is always 32 bits signed.

finally - delete the non-standard std_logic_arith and std_logic_unsigned library. The standard library is numeric_std.
 
  • Like
Reactions: jerryt

    jerryt

    Points: 2
    Helpful Answer Positive Rating
VHDL is strongly typed ,

A ,B integer

C std_logic

so it's an Error

If you want to synthesize ,use signed /unsigned

Code:
  library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

entity MultExample is
Port (C : OUT unsigned (31 downto 0));
end MultExample;

architecture Behavioral of MultExample is

constant A: integer:= 4;
constant B: integer:= 2;

begin

C <=TO_UNSIGNED(A*B,32);

end Behavioral;


---------- Post added at 14:17 ---------- Previous post was at 14:14 ----------

h**p://www.synthworks.com/papers/vhdl_math_tricks_mapld_2003.pdf

A mini-tutorial on VHDL types (esp. unsigned and signed), packages, strong typing rules, conversions, ambiguous expressions, and math tricks.
 
  • Like
Reactions: jerryt

    jerryt

    Points: 2
    Helpful Answer Positive Rating
Thanks Tricky and Blooz.

I have one more question. If I will be multiplying signed integer numbers. I have a function which is Y = A*x1 + B*x2. Some of the coefficients in the function will be port inputs and some will be predetermined constants already known.

In the code below,
x1 and x2 are port signed integer inputs that are to be 8 bits in length.
Y is the signed integer output of the overall function which is to be 10 bits in length.
a and b are predetermined signed integer constants that will be used in the function calculation.

In the code below am I declaring the inputs, outputs, and constants correctly to represent a function that results in a 10 bit signed number?

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

entity FunctionExample is
Port (
x1 : IN signed (7 downto 0);
x2 : IN signed (7 downto 0);
Y : OUT signed (9 downto 0));
end FunctionExample;

architecture Behavioral of FunctionExample is

constant A: integer:= 4;
constant B: integer:= 2;

begin

C <=TO_SIGNED(A*x1 + B*x2,10);

end Behavioral;
 

Thanks Tricky and Blooz.

I have one more question. If I will be multiplying signed integer numbers. I have a function which is Y = A*x1 + B*x2. Some of the coefficients in the function will be port inputs and some will be predetermined constants already known.

In the code below,
x1 and x2 are port signed integer inputs that are to be 8 bits in length.
Y is the signed integer output of the overall function which is to be 10 bits in length.
a and b are predetermined signed integer constants that will be used in the function calculation.

In the code below am I declaring the inputs, outputs, and constants correctly to represent a function that results in a 10 bit signed number?

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

entity FunctionExample is
Port (
x1 : IN signed (7 downto 0);
x2 : IN signed (7 downto 0);
Y : OUT signed (9 downto 0));
end FunctionExample;

architecture Behavioral of FunctionExample is

constant A: integer:= 4;
constant B: integer:= 2;

begin

C <=TO_SIGNED(A*x1 + B*x2,10);

end Behavioral;


The above with some changes

Code:
 library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

entity FunctionExample is
Port (
x1 : IN signed (7 downto 0);
x2 : IN signed (7 downto 0);
C : OUT signed (16 downto 0));
end FunctionExample;

architecture Behavioral of FunctionExample is

constant A: integer:= 4;
constant B: integer:= 2;

begin

C <=TO_SIGNED(A,9)*x1 + TO_SIGNED(B,9)*x2;

end Behavioral;
 
  • Like
Reactions: jerryt

    jerryt

    Points: 2
    Helpful Answer Positive Rating
Blooz, thanks for your help. This makes perfect sense. I have two really simple questions:

1. For the C funtion in the code above:

Why did you put 9 for TO_SIGNED(A,9) and TO_SIGNED(B,9)? That would make integer A and B 9 bits. Is there a reason why you chose 9 bits or did you just happen to choose 9 for this example?

2. Is the IEEE.numeric_std package synthesizable? In my project I need to do FPGA synthesis to find resource usage and throughput numbers.

Thanks for you help!
 

C <=TO_SIGNED(A,9)*x1 +TO_SIGNED( B,9)*x2;


here the size of C has to be 16 downto 0 ,

---------- Post added at 08:45 ---------- Previous post was at 08:43 ----------

Blooz, thanks for your help. This makes perfect sense. I have two really simple questions:

1. For the C funtion in the code above:

Why did you put 9 for TO_SIGNED(A,9) and TO_SIGNED(B,9)? That would make integer A and B 9 bits. Is there a reason why you chose 9 bits or did you just happen to choose 9 for this example?

2. Is the IEEE.numeric_std package synthesizable? In my project I need to do FPGA synthesis to find resource usage and throughput numbers.

Thanks for you help!

1.I just choose 9 . But the resultant C must have width of A and X combined that is 8+9 ,17


2.Yes IEEE.numeric_std packages is synthesizable
 
  • Like
Reactions: jerryt

    jerryt

    Points: 2
    Helpful Answer Positive Rating
Thanks Blooz! This was very helpful. I have one more question:

If needed to multiply three inputs all of size 8 bits by three integers and store result in an output of 16 bits, what would be the width size (represented by X in the C equation below) of integer A, B, and C?

Example:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

entity FunctionExample is
Port (
x1 : IN signed (7 downto 0);
x2 : IN signed (7 downto 0);
x3 : IN signed (7 downto 0);
C : OUT signed (16 downto 0));
end FunctionExample;

architecture Behavioral of FunctionExample is

constant A: integer:= 4;
constant B: integer:= 2;
constant C: integer:= 6;

begin

C <=TO_SIGNED(A,X)*x1 + TO_SIGNED(B,X)*x2 + TO_SIGNED(C,X)*x3;

end Behavioral;
 

why are you chosing integers? why not stick with signed?
The problem is integer types will expand to 32 bits, and 8bits x 32 bits gives you a 40 bit output, unless you constrain them on conversion.

But with the integers you supply, they only need to be a max of 4 bits each (so 8 bits will be fine).

The easiest thing to do is set X to 8.
 
  • Like
Reactions: jerryt

    jerryt

    Points: 2
    Helpful Answer Positive Rating
Thanks Tricky. I am going to stick with signed for all my numbers. Is there any good documentation on this topic concerning all VHDL operators?
 

what kind of documentation? you could read the package declaration. Just google numeric_std.

The Doulos VHDL Golden Reference guide is a good source of quick VHDL info (but its not a tutorial).
 
  • Like
Reactions: jerryt

    jerryt

    Points: 2
    Helpful Answer Positive Rating
Thanks for everyones help! Very much appreciated!
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top