You have placed the same question in another thread. Don't do that.
VHDL is a logic description language, not a computer programming language.
To have arithmetic operations on signals and registers you must describe the hardware that will perform the indended operations.
Floating point operations require a floating-point unit to be construed, not only representing a 32bit float number, but you'll have to build or instantiate a floating-point multiplier to carry the operation.
If you want to use integer multiplication, to save area, you can use fixed point representation.
For example, you can represent your 0.46 number as a fixed point fraction with 32 bits of fractional size (to do that, compute the fraction by multiplying 0.46 by 2^32), and represent the integer 3 as a 16bit integer, then you can use a simple 32bits x 16bits multiplier to obtain a 48bit result, with 16bit integer part and 32 bits fractional part.
For that you can use the ieee multiplication operator, that will synthesize a multiplier, but you have to align the fractional bits correctly 'by hand' according to the context of your chosen representation.
RE: help in multiplication in vhdl
by jdoin on Aug 15, 2011
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity mult_fixed_top is
Port (
gclk_i : in std_logic := 'X'; -- board clock input 100MHz
--- operands inputs ---
oper_A_16Q0 : in std_logic_vector (15 downto 0); -- operand A: 16 bit integer
oper_B_0Q32 : in std_logic_vector (31 downto 0); -- operand B: 32 bit fractional
--- result output ---
result_16Q32 : out std_logic_vector (47 downto 0) -- result: 48bit (16 bit integer, 32bit fractional)
);
end mult_fixed_top;
architecture rtl of mult_fixed_top is
-- dclare 4 pipeline registers levels for the DSP48A1 block
signal reg_A3 : std_logic_vector (15 downto 0) := (others => '0');
signal reg_B3 : std_logic_vector (31 downto 0) := (others => '0');
signal reg_R3 : std_logic_vector (47 downto 0);
signal reg_A2 : std_logic_vector (15 downto 0) := (others => '0');
signal reg_B2 : std_logic_vector (31 downto 0) := (others => '0');
signal reg_R2 : std_logic_vector (47 downto 0);
signal reg_A1 : std_logic_vector (15 downto 0) := (others => '0');
signal reg_B1 : std_logic_vector (31 downto 0) := (others => '0');
signal reg_R1 : std_logic_vector (47 downto 0);
signal reg_A : std_logic_vector (15 downto 0) := (others => '0');
signal reg_B : std_logic_vector (31 downto 0) := (others => '0');
signal reg_R : std_logic_vector (47 downto 0);
signal R : std_logic_vector (47 downto 0);
begin
-- this is the multiplier block, described as a combinatorial multiplier
mult_16x32_proc: process (reg_A, reg_B) is
variable A : unsigned (15 downto 0) := (others => '0');
variable B : unsigned (31 downto 0) := (others => '0');
variable RES : unsigned (47 downto 0);
begin
-- convert bit array inputs to unsigned integer type by type casting
A := unsigned(reg_A);
B := unsigned(reg_B);
-- infer a 48bit integer multiplier
RES := A * B;
-- convert multiplier output to bit array by type casting
R
The code above implements a multiplier with 4 levels of pipeline registers at inputs and outputs. It is targeted to be inferred by Xilinx tools as a DSP48A1 32x16 pipelined multiplier block. When XST finds a 4-layer pipeline, it synthesizes the DSP48 block with the maximum pipeline level, and the clock rate goes to 372MHz minimum.
The testbench does:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity testbench is
end testbench;
architecture behavior of testbench is
constant CLK_PERIOD : time := 10 ns;
component mult_fixed_top
port(
gclk_i : in std_logic;
oper_A_16Q0 : in std_logic_vector(15 downto 0);
oper_B_0Q32 : in std_logic_vector(31 downto 0);
result_16Q32 : out std_logic_vector(47 downto 0)
);
end component;
signal sysclk : std_logic := '0'; -- 100MHz clock
signal A : std_logic_vector (15 downto 0) := (others => '0');
signal B : std_logic_vector (31 downto 0) := (others => '0');
signal RES : std_logic_vector (47 downto 0) := (others => '0');
begin
Inst_mult_fixed_top: mult_fixed_top port map(
gclk_i => sysclk,
oper_A_16Q0 => A,
oper_B_0Q32 => B,
result_16Q32 => RES
);
gclk_proc: process is
begin
loop
sysclk
The value X"75c28f5c" is the fixed-point 0.46 represented in 32bits with 32 fractional bits (0.46 * 2**32).
The result: X"00016147ae14", or 1.3799999998882413, which is 3 * 0.46 with an epsilon of 2**-33.
To interpret the result, you imagine a binary point at the 16 higher bits: X"0001.6147ae14", and to convert the fractional part to human-readable format, you take the fractional part and divide by 2.0**32.