Electrical – VHDL multiplication for std_logic_vector

fpgavhdlvivado

When simulating I get a run time error, so I'm trying to run a RTL analysis in Vivado to see if the schematic of the component can be created at least. The code is the following

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity multiplicator_test is
    generic(
            WORD_SIZE: natural := 8;
            EXP_SIZE: natural := 3
        );
        port(
            input_1: in std_logic_vector(WORD_SIZE-1 downto 0);
            input_2: in std_logic_vector(WORD_SIZE-1 downto 0);
            result: out std_logic_vector(WORD_SIZE-1 downto 0)
        );
end entity multiplicator_test;

architecture multiplicator_test_arch of multiplicator_test is
    constant SIGNIFICAND_SIZE: natural := WORD_SIZE - EXP_SIZE - 1;

    signal significand: std_logic_vector(SIGNIFICAND_SIZE-1 downto 0) := (others => '0');
    signal exponent: std_logic_vector(EXP_SIZE-1 downto 0) := (others => '0');
    signal sign: std_logic := '0';
    signal aux: std_logic_vector((2*SIGNIFICAND_SIZE)-1 downto 0) := (others => '0');
begin
        aux <= std_logic_vector(signed(input_1(SIGNIFICAND_SIZE-1 downto 0))*signed(input_2(SIGNIFICAND_SIZE - 1 downto 0)));
        significand <= aux(SIGNIFICAND_SIZE - 1 downto 0);
        exponent <= std_logic_vector(unsigned(input_1(WORD_SIZE-2 downto WORD_SIZE-EXP_SIZE-2))+unsigned(input_2(WORD_SIZE-2 downto WORD_SIZE-EXP_SIZE-2)));
        sign <= input_1(WORD_SIZE-1) or input_2(WORD_SIZE-1);
        result <= sign & exponent & significand;
end architecture multiplicator_test_arch;

When running the analysis, I get

ERROR: [Synth 8-690] width mismatch in assignment; target has 3 bits, source has 4 bits [(...)/multiplicador.vhd:27]

The line with the error is 27,

aux <= std_logic_vector(signed(input_1(SIGNIFICAND_SIZE-1 downto 0))*signed(input_2(SIGNIFICAND_SIZE - 1 downto 0)));

Apparently the target (aux) is 3 bits, but really it should be 8.

Best Answer

To get straight to the error:

You try to multiply two 4-bit-signed without putting the result into a 8-bit-signed.

Example (leads to your error):

architecture multiplicator_test_arch of multiplicator_test is
    signal input_1: signed(WORD_SIZE - 1 downto 0);
    signal input_2: signed(WORD_SIZE - 1 downto 0);
    signal result_sig : signed(WORD_SIZE - 1 downto 0);
begin  
    result_sig <= input_1 * input_2;
end architecture multiplicator_test_arch;

Example (doesn't lead to your error):

architecture multiplicator_test_arch of multiplicator_test is
    signal input_1: signed(WORD_SIZE - 1 downto 0);
    signal input_2: signed(WORD_SIZE - 1 downto 0);
    signal result_sig : signed((WORD_SIZE * 2) - 1 downto 0);
begin  
    result_sig <= input_1 * input_2;
end architecture multiplicator_test_arch;

The result-signed-type has to be double width from the two input-signed-types.

So what you have to do is:

  • Declare another signed-signal with the double width from your multiplication
  • put the result from the multiplication in there
  • formate the new signal into a std_logic_vector

Moreover your code is not realy readable. You do a lot of formatting in one row. What do you have to ask yourself: Is it necessary to work with std_logic_vector as input, or can you maybe use signed-types. If not so - ok. But then I would try to keep the signals as signed and do the calculation with this signals. After this you formate your result from signed into std_logic_vector. But this is a question of coding style.

Related Topic