Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

Weird VHDL Multiplier Problem

Hello all,

I was recently given reign over a DE0-Nano board by my research adviser to turn into a interference fringe counter of sorts but I am having some problems programming multiplication in VHDL and cannot seem to find anyone with similar errors online (my adviser also seems to be befuddled as to what, exactly, is wrong). I am trying to multiply two 32 bit unsigned numbers, one of which is a constant and the other a signal from a button press(for testing purposes), and then later convert it to bcd and put it on a 7-seg display. I have successfully implemented a binary to bcd and bcd to 7seg display code and use a set of seven segmented displays to check the outputs for my multiplier. For certain constant values, such as "100...0" or "111...1" or "100...01", the multiplier seems to work properly. However, if the multiplier tries to multiply a 'sandwiched' zero (like the number 13 which has the binary representation 1101), it will fail to produce the correct output. For example if the constant is 13, the display reads the following solutions for each multiplication: 0x13=0; 1x13=13; 2x13=54; 3x13=39; 4x13=76; 5x13=65; etc... As you can see, some of the values are correct, however others are plain wrong. (NOTE: the pattern for 13 seems typical... the even multiples are off, although I do not know for sure if this is always the case).

Here's my code for the multiplier:


library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity mult_32 is
port (
  a: in  unsigned(31 downto 0);
  c   : out unsigned(63 downto 0);
  clear : in std_logic
);
constant b: unsigned(31 downto 0):=to_unsigned(13,32); 
end entity mult_32;
architecture rtl of mult_32 is
signal a_reg : unsigned(31 downto 0);
signal b_reg: unsigned(31 downto 0);
signal c_reg : unsigned(63 downto 0);
begin
    process (clear)
    begin
        if (clear ='1') then
            -- Reset all register data to 0
            a_reg <= (others => '0');
            b_reg <= (others => '0');
            c_reg <= (others => '0');
        else
            -- Store input and output values in registers
            a_reg <= a;
            b_reg <= b;
            c_reg <= a_reg * b_reg;    
        end if;
    end process;
    
c<=c_reg;
end rtl;

I am new to coding in VHDL and believe that I have likely made some sort of syntax error, type cast conversion error (although I have been careful to use unsigned for everything) or other newbie mistake. If it is relevant, I am writing and compiling my code in Quratus II version 13 (64 bit version).

Thanks for your help.

12 Replies