EmbDev.net

Forum: FPGA, VHDL & Verilog 16 bit serial multiplier


von Omar (Guest)


Rate this post
useful
not useful
Hello

Im trying to write the behavioral code for a serial 16 bit multiplier. 
However, my output is always 0 for some reason. I used the debugging 
feature in vcs and apparently my R1,R2,R3 values are not being updated 
by the A values. Below are my source code and test bench:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_arith.all;
4
5
entity SerialMultiplier1 is
6
port(A,B: IN std_logic_vector(15 downto 0);
7
     reset: IN std_logic;
8
     X: OUT std_logic_vector(31 downto 0));
9
end SerialMultiplier1;
10
11
architecture behavior of SerialMultiplier1 is
12
signal R1,R2,R3: std_logic_vector(31 downto 0) := (others => '0');
13
14
begin
15
16
process(reset)
17
begin 
18
  if reset='1' then
19
    X <= (others => '0');
20
  end if;
21
end process;
22
23
process(A,B)
24
25
begin
26
  for i in 0 to 31 loop
27
  
28
    if i = 0 then
29
      if B(i) = '1' then
30
        R1(15+i downto i) <= A(15 downto 0);
31
      else
32
        R1(15+i downto i) <= (others => '0');
33
      end if;
34
      X(i) <= R1(i);
35
    
36
    elsif (i>0 and i<16) then
37
      if B(i) = '1' then
38
        R2(15+i downto i) <= A(15 downto 0);
39
      else
40
        R2(15+i downto i) <= (others => '0');
41
      end if;
42
      R3 <= unsigned(R1) + unsigned(R2); X(i) <= R3(i);
43
      R1 <= R3; R2 <= (others => '0');
44
    
45
    else
46
      X(i) <= R3(i);
47
    end if;
48
  
49
  end loop;
50
end process;
51
end behavior;
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_arith.all;
4
5
entity tb_SerialMultiplier1 is
6
end tb_SerialMultiplier1;
7
8
architecture behavior of tb_SerialMultiplier1 is
9
  component SerialMultiplier1
10
     port(A,B: IN std_logic_vector(15 downto 0);
11
          reset: IN std_logic;
12
          X: OUT std_logic_vector(31 downto 0));
13
  end component;
14
15
signal A,B: std_logic_vector(15 downto 0);
16
signal reset: std_logic;
17
signal X: std_logic_vector(31 downto 0);
18
19
begin
20
DUT: SerialMultiplier1 port map(A,B,reset,X);
21
22
process
23
begin
24
wait for 0 ns;
25
A<=x"0002";B<=x"0004";reset<='1';
26
wait for 10 ns;
27
reset<='0';
28
wait for 10 ns;
29
--A<=x"000B";B<=x"000A";
30
--wait for 10 ns;
31
--A<=x"0111";B<=x"0011";
32
--wait for 10 ns;
33
end process;
34
end behavior;

: Locked by Moderator
von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
1. With that loop in VHDL you don't generate serial hardware. Instead 
you get a parallel multiplier.

2. You will not get this VHDL code on real hardware, because the signal 
X is driven from two sources.

A serial multiplier as I see it will need a clock, a shift register and 
an adder. Then with each clock the first operand is shifted one further 
and summed up, if the bit in the second operand is set. After 16 clock 
cycles the multiplication is done...

: Edited by Moderator
von Thomas R. (Company: abaxor engineering) (abaxor)


Rate this post
useful
not useful
Lothar Miller wrote:
> A serial multiplier as I see it will need a clock, a shift register and
> an adder. Then with each clock the first operand is shifted one further
> and summed up, if the bit in the second operand is set. After 16 clock
> cycles the multiplication is done...

Is not. A 16 bits x 16 bits multiplication will lead to a 32 bits 
product which needs 32 clock. Furthermore 16 adders are needed.

See

http://www.abaxor.de/publications/diss/diss_reinemann.pdf

page 29.

It's in German.

Tom

von -gb- (Guest)


Rate this post
useful
not useful
> Furthermore 16 adders are needed.

Or 16 clock cycles if you use 1 only adder.

von -gb- (Guest)


Rate this post
useful
not useful

von Omar Rashad (Guest)


Rate this post
useful
not useful
Hi,

I have managed to write the behavioral code for it successfully. 
However, I am find it difficult to write the structural code for it 
because using for-generate statements to use the FA and HA components 
(that is required) means we cannot use a process. But if we don't use a 
process, how can we clock it?

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Omar Rashad wrote:
> I am find it difficult to write the structural code for it because using
> for-generate statements to use the FA and HA components (that is
> required) means we cannot use a process.
A multiplier usually does not need a clock at all. it can be implemented 
completly as a combinatorial description. So first you have to answer: 
do you need a clock at all?

> But if we don't use a process, how can we clock it?
This is a synthesizeable concurrent description of a clocked D-flipflop:
1
   FF_Dout <= FF_Din when rising_edge(clk);


BTW: doing VHDL with structural description is like drilling holes in 
steel with a wooden stick. Its just an old fashioned way to waste 
time...

And doing VHDL without using a process is like driving a car without a 
gearbox or only in the first gear: nearly senseless...

For any contemporary FPGA you write a multiplication this way:
1
   result <= a*b;

: Edited by Moderator
This topic is locked and can not be replied to.