Search code examples
vhdlfpgaxilinx-ise

VHDL multiplier which output has the same side of it's inputs


I'm using VHDL for describing a 32 bits multiplier, for a system to be implemented on a Xilinx FPGA, I found on web that the rule of thumb is that if you have inputs of N-bits size, the output must've (2*N)-bits of size. I'm using it for a feedback system, is it posible to has a multiplier with an output of the same size of it's inputs?.

I swear once I found a fpga application, which vhdl code has adders and multipliers blocks wired with signals of the same size. The person who wrote the code told me that you just have to put the result of the product on a 64 bits signal and then the output has to get the most significant 32 bits of the result (which was not necesarily on the most significant 32 bits of the 64 bits signal).

At the time I build a system (apparently works) using the next code:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Multiplier32Bits is
    port(
        CLK: in std_logic;
        A,B: in std_logic_vector(31 downto 0);
        R: out std_logic_vector(31 downto 0)
    );
end Multiplier32Bits;

architecture Behavioral of Multiplier32Bits is
signal next_state: std_logic_vector(63 downto 0);
signal state: std_logic_vector(31 downto 0);

begin

    Sequential: process(CLK,state,next_state)
    begin
        if CLK'event and CLK = '1' then
            state <= next_state(61 downto 30);
        else
            state <= state;
        end if;
    end process Sequential;

    --Combinational part
        next_state <= std_logic_vector(signed(A)*signed(B));

    --Output assigment
    R <= state;

end Behavioral;

I though it was working since at the time I had the block simulated with Active-HDL FPGA simulator, but know that I'm simulating the whole 32 bit system using iSim from Xilinx ISE Design Suite. I found that my output has a big difference from the real product of A and B inputs, which I don't know if it's just the accuracy loose from skipping 32 bits or my code is just bad.


Solution

  • Your code has some problems:

    1. next_state and state don't belong into the sensitivity list
    2. The writing CLK'event and CLK = '1' should be replaced by rising_edge(CLK)
    3. state <= state; has no effect and causes some tools like ISE to misread the pattern. Remove it.
    4. Putting spaces around operators doesn't hurt, but improves readability.
    5. Why do you expect the result of a * b in bits 30 to 61 instead of 0 to 31?
    6. state and next_state don't represent states of a state machine. It's just a register.

    Improved code:

    architecture Behavioral of Multiplier32Bits is
      signal next_state: std_logic_vector(63 downto 0);
      signal state: std_logic_vector(31 downto 0);
    begin
      Sequential: process(CLK)
      begin
        if rising_edge(CLK) then
          state <= next_state(31 downto 0);
        end if;
      end process Sequential;
    
      --Combinational part
      next_state <= std_logic_vector(signed(A) * signed(B));
    
      --Output assigment
      R <= state;
    end architecture Behavioral;