0
votes

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.

2
ok, where is the question?Staszek
And provide numbers, that you used for simulation.Staszek
You probably want to use post-shifting to align the result. And you've using signed fixed-point input.JHBonarius

2 Answers

0
votes

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;
0
votes

I totally agree with everything that Paebbels write. But I will explain to you this things about number of bits in the result. So I will explain it by examples in base 10.

9 * 9 = 81 (two 1 digit numbers gives maximum of 2 digits)
99 * 99 = 9801 (two 2 digit numbers gives maximum of 4 digits)
999 * 999 = 998001 (two 3 digit numbers gives maximum of 6 digits)
9999 * 9999 = 99980001 (4 digits -> 8 digits)

And so on... It is totally the same for binary. That's why output is (2*N)-bits of size of input.

But if your numbers are smaller, then result will fit in same number of digits, as factors:

3 * 3 = 9
10 * 9 = 90
100 * 99 = 990

And so on. So if your numbers are small enough, then result will be 32 bit. Of course, as Paebbels already written, result will be in least significant part of signal.

And as J.H.Bonarius already pointed out, if your input consist not of integer, but fixed point numbers, then you would have to do post shifting. If this is your case, write it in the comment, and I will explain what to do.