OpenCores
no use no use 1/1 no use no use
help in multiplication in vhdl
by nitusona on Aug 14, 2011
nitusona
Posts: 3
Joined: Aug 7, 2011
Last seen: Feb 26, 2015
sir,
i want to multiply 0.46 with 3 but can't get the right result while represnting iti nto ieee 754 format in vhdl .plz help.
RE: help in multiplication in vhdl
by jdoin on Aug 15, 2011
jdoin
Posts: 51
Joined: Sep 1, 2009
Last seen: Sep 27, 2024
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
jdoin
Posts: 51
Joined: Sep 1, 2009
Last seen: Sep 27, 2024
in other words:
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.
no use no use 1/1 no use no use
© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.