Community
cancel
Showing results for
Did you mean:
Honored Contributor I
2,140 Views

## Help multiplier vhdl

Hi everyone!

I've some problems with a design, I have to Design an algorithmic state machine to implement a parallel series multiplier for eight-bit numbers encoded in SM (Sign-Magnitude). The multiplying is in a register with parallel output and the multiplier in a shift register of length m with serial output, the first bit to be the least significant. Each bit of multiplier, in his turn, multiplies by multiplying all, so that with operations multiplication is performed.

I've the problem with the shift register with serial output, because I don´t know how to do it!!

I'm learning VHDL right now, and I've never work with this hardware description language.

Please if anyone can help me, I'd be very grateful.

Thank you!!
Tags (1)
13 Replies
Honored Contributor I
82 Views

--- Quote Start ---

Hi everyone!

I've some problems with a design, I have to Design an algorithmic state machine to implement a parallel series multiplier for eight-bit numbers encoded in SM (Sign-Magnitude). The multiplying is in a register with parallel output and the multiplier in a shift register of length m with serial output, the first bit to be the least significant. Each bit of multiplier, in his turn, multiplies by multiplying all, so that with operations multiplication is performed.

I've the problem with the shift register with serial output, because I don´t know how to do it!!

I'm learning VHDL right now, and I've never work with this hardware description language.

Please if anyone can help me, I'd be very grateful.

Thank you!!

--- Quote End ---

You need to show what have you done so far and where in design stage you want help.

The 8 bit sign&magnitude can be any value from 0111 1111 to 1111 1111

when you multiply you do that per bit then add up as in primary school multiplication.

You can ignore sign bit as you can conclude that at the end, for demo assume you have:

1) 111 1111

2) 111 1101

thus you multiply 1 by 111 1111 and you get 111 1111 then you multiply by zero which results in zero, shift one bit...

xxxxxxx111 1111

xxxxxx000 0000

xxxxx111 1111

xxxx111 111

xx111 1111

x111 1111

111 1111

------------------------

after 7 multiplications you add all to get result then decide sign bit
Honored Contributor I
82 Views

Thank you kaz, but how can I do that in VHDL??

I know how I have to do the operation, but I don't know how to create the register in VHDL.

Right now, I have this:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.std_logic_unsigned.all;

use IEEE.numeric_std.all;

entity reg_des is

port (

multiplicando: in std_logic_vector (7 downto 0);

registro7: out std_logic_vector (7 downto 0);

registro6: out std_logic_vector (7 downto 0);

Q7: out std_logic;

resultado: out bit_vector (15 downto 0);

clk: in std_logic;

reset: in std_logic);

end reg_des;

architecture behavioral of reg_des is

begin

reg_des : process (multiplicador, clk, reset)

variable Q : std_logic_vector (8 downto 0);

begin

if reset = '1' then Q:= "000000000";

else

if clk'event and clk = '1' then

for i in 0 to 7 loop

Q(i) := Q(i+1);

if i = 0 then

registro7(7) <= Q(i) and multiplicando(7);

end if;

if i = 1 then

registro7(6) <= Q(i) and multiplicando(7);

registro6 (7) <= Q(i-1) and multiplicando(6);

end if;

if i = 2 then

registro7(5) <= Q(i) and multiplicando(7);

registro6 (6) <= Q(i-1) and multiplicando(6);

end if;

if i = 3 then

registro7(4) <= Q(i) and multiplicando(7);

registro6 (5) <= Q(i-1) and multiplicando(6);

end if;

if i = 4 then

registro7(3) <= Q(i) and multiplicando(7);

registro6 (4) <= Q(i-1) and multiplicando(6);

end if;

if i = 5 then

registro7(2) <= Q(i) and multiplicando(7);

registro6 (3) <= Q(i-1) and multiplicando(6);

end if;

if i = 6 then

registro7(1) <= Q(i) and multiplicando(7);

registro6 (2) <= Q(i-1) and multiplicando(6);

end if;

if i = 7 then

registro7(0) <= Q(i) and multiplicando(7);

registro6 (1) <= Q(i-1) and multiplicando(6);

end if;

if i = 8 then

registro6 (0) <= Q(i-1) and multiplicando(6);

end if;

end loop;

Q7 <= Q(7);

end if;

end if;

end process;

end behavioral;

------------------------------------------------------

Is this the correct way to do it??

Thank you!
Honored Contributor I
82 Views

--- Quote Start ---

You need to show what have you done so far and where in design stage you want help.

The 8 bit sign&magnitude can be any value from 0111 1111 to 1111 1111

when you multiply you do that per bit then add up as in primary school multiplication.

You can ignore sign bit as you can conclude that at the end, for demo assume you have:

1) 111 1111

2) 111 1101

thus you multiply 1 by 111 1111 and you get 111 1111 then you multiply by zero which results in zero, shift one bit...

xxxxxxx111 1111

xxxxxx000 0000

xxxxx111 1111

xxxx111 111

xx111 1111

x111 1111

111 1111

------------------------

after 7 multiplications you add all to get result then decide sign bit

--- Quote End ---

Thank you kaz, but how can I do that in VHDL??

I know how I have to do the operation, but I don't know how to create the register in VHDL.

Right now, I have this:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.std_logic_unsigned.all;

use IEEE.numeric_std.all;

entity reg_des is

port (

multiplicando: in std_logic_vector (7 downto 0);

registro7: out std_logic_vector (7 downto 0);

registro6: out std_logic_vector (7 downto 0);

Q7: out std_logic;

resultado: out bit_vector (15 downto 0);

clk: in std_logic;

reset: in std_logic);

end reg_des;

architecture behavioral of reg_des is

begin

reg_des : process (multiplicador, clk, reset)

variable Q : std_logic_vector (8 downto 0);

begin

if reset = '1' then Q:= "000000000";

else

if clk'event and clk = '1' then

for i in 0 to 7 loop

Q(i) := Q(i+1);

if i = 0 then

registro7(7) <= Q(i) and multiplicando(7);

end if;

if i = 1 then

registro7(6) <= Q(i) and multiplicando(7);

registro6 (7) <= Q(i-1) and multiplicando(6);

end if;

if i = 2 then

registro7(5) <= Q(i) and multiplicando(7);

registro6 (6) <= Q(i-1) and multiplicando(6);

end if;

if i = 3 then

registro7(4) <= Q(i) and multiplicando(7);

registro6 (5) <= Q(i-1) and multiplicando(6);

end if;

if i = 4 then

registro7(3) <= Q(i) and multiplicando(7);

registro6 (4) <= Q(i-1) and multiplicando(6);

end if;

if i = 5 then

registro7(2) <= Q(i) and multiplicando(7);

registro6 (3) <= Q(i-1) and multiplicando(6);

end if;

if i = 6 then

registro7(1) <= Q(i) and multiplicando(7);

registro6 (2) <= Q(i-1) and multiplicando(6);

end if;

if i = 7 then

registro7(0) <= Q(i) and multiplicando(7);

registro6 (1) <= Q(i-1) and multiplicando(6);

end if;

if i = 8 then

registro6 (0) <= Q(i-1) and multiplicando(6);

end if;

end loop;

Q7 <= Q(7);

end if;

end if;

end process;

end behavioral;

------------------------------------------------------

Is this the correct way to do it??

Thank you!
Honored Contributor I
82 Views

At least you got something...

if it was me I will run a 7 states machine (or just a counter 0 to 6).

Assuming y = A*B then I might go as below

``` case count is when 0 => if A(0) = '1' then temp <= B; else temp <= "0000000"; end if; y <= y + temp; -- first of 7 additions, initialise y to zero when 1 => if A(1) = '1' then temp <= B; else temp <= "0000000"; end if; y <= y + temp&'0'; --increase weight by one digit ...etc ```

you will need to declare proper types and manage bitwidth for addition.
Honored Contributor I
82 Views

--- Quote Start ---

At least you got something...

if it was me I will run a 7 states machine (or just a counter 0 to 6).

Assuming y = A*B then I might go as below

``` case count is when 0 => if A(0) = '1' then temp <= B; else temp <= "0000000"; end if; y <= y + temp; -- first of 7 additions, initialise y to zero when 1 => if A(1) = '1' then temp <= B; else temp <= "0000000"; end if; y <= y + temp&'0'; --increase weight by one digit ...etc ```

you will need to declare proper types and manage bitwidth for addition.

--- Quote End ---

Sorry but I can´t understand what you want to do.

Can you explain me?
Honored Contributor I
82 Views

--- Quote Start ---

Sorry but I can´t understand what you want to do.

Can you explain me?

--- Quote End ---

take this example:

A = 1111101

B = 1111111

y = 0

count = 0 , A(0) = '1' hence result of A(0) *B = B (1111111), I called it temp

update sum: y = y+temp;

count <= count + 1;

count = 1 , A(1) = '0' hence result of A(1) *B = 0, I called it temp

update sum: y = y+temp&'0'; --shift temp by one bit

count <= count + 1;

count = 2 , A(2) = '1' hence result of A(2) *B = B, I called it temp

update sum: y = y+temp&'00'; --shift temp by two bits

count <= count + 1;

...
Honored Contributor I
82 Views

--- Quote Start ---

take this example:

A = 1111101

B = 1111111

y = 0

count = 0 , A(0) = '1' hence result of A(0) *B = B (1111111), I called it temp

update sum: y = y+temp;

count <= count + 1;

count = 1 , A(1) = '0' hence result of A(1) *B = 0, I called it temp

update sum: y = y+temp&'0'; --shift temp by one bit

count <= count + 1;

count = 2 , A(2) = '1' hence result of A(2) *B = B, I called it temp

update sum: y = y+temp&'00'; --shift temp by two bits

count <= count + 1;

...

--- Quote End ---

I've been working in this project and I've get this:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.std_logic_unsigned.all;

use IEEE.numeric_std.all;

entity prueba2 is

port (

A : in std_logic_vector (7 downto 0);

B : in std_logic_vector (7 downto 0);

inicio : in std_logic;

clk : in std_logic;

reset: in std_logic;

q : out std_logic_vector (2 downto 0);

resultado : out std_logic_vector (15 downto 0)

);

end prueba2;

architecture behavioral of prueba2 is

begin

multi : process (A, clk, reset)

variable y : std_logic_vector (15 downto 0);

variable cuenta : std_logic_vector (2 downto 0);

variable temp : std_logic_vector (7 downto 0);

begin

if reset = '1' then y:= "0000000000000000";

else

if clk'event and clk = '1' and inicio = '1' then

cuenta := cuenta + 1;

end if;

q <= cuenta;

end if;

case cuenta is

when "000" =>

if A(0) = '1' then

temp := B;

else

temp := "00000000";

end if;

y := y + temp;

when "001" =>

if A(1) = '1' then

temp := B;

else

temp := "00000000";

end if;

y := y + temp&"0";

when "010" =>

if A(2) = '1' then

temp := B;

else

temp := "00000000";

end if;

y := y + temp&"00";

when "011" =>

if A(3) = '1' then

temp := B;

else

temp := "00000000";

end if;

y := y + temp&"000";

when "100" =>

if A(4) = '1' then

temp := B;

else

temp := "00000000";

end if;

y := y + temp&"0000";

when "101" =>

if A(5) = '1' then

temp := B;

else

temp := "00000000";

end if;

y := y + temp&"00000";

when "110" =>

if A(6) = '1' then

temp := B;

else

temp := "00000000";

end if;

y := y + temp&"000000";

when "111" =>

if A(7) = '1' then

temp := B;

else

temp := "00000000";

end if;

y := y + temp&"0000000";

end case;

end process;

end behavioral;

-------------------------------------------

But there is an error when I do y := y + temp&"0"; because expression has 17 elements, but must have 16 elements.

How can I correct this?
Honored Contributor I
82 Views

That is because + and & operators have equal precedence, so it is doing the add followed by concatenate, giving you a 17 bit result (ie. you code is actaully y := (Y+temp)& "0"; )

You need to put () in to fix the precedence:

y := y + (temp&"0");
Honored Contributor I
82 Views

here is my go without sim and without sign bit output.

``` library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.numeric_std.all; entity prueba2 is port ( A : in std_logic_vector (7 downto 0); B : in std_logic_vector (7 downto 0); inicio : in std_logic; clk : in std_logic; reset : in std_logic; q : out std_logic_vector (2 downto 0); resultado : out std_logic_vector (15 downto 0) ); end prueba2; architecture behavioral of prueba2 is signal y : unsigned(15 downto 0); begin multi : process (clk, reset) variable cuenta : unsigned(2 downto 0); variable temp : unsigned(15 downto 0); begin if reset = '1' then --reset all elsif clk'event and clk = '1' then if inicio = '1' then cuenta := cuenta + 1; end if; q <= std_logic_vector(cuenta); temp := (others => '0'); --default y <= y + temp; if cuenta = "000" then --update output resultado <= std_logic_vector(y); end if; case cuenta is when "000" => if A(0) = '1' then temp := "00000000"&unsigned(B); end if; when "001" => if A(1) = '1' then temp := "0000000"&unsigned(B)&'0'; end if; when "010" => if A(2) = '1' then temp := "000000"&unsigned(B)&"00"; end if; when "011" => if A(3) = '1' then temp := "00000"&unsigned(B)&"000"; end if; when "100" => if A(4) = '1' then temp := "0000"&unsigned(B)&"0000"; end if; when "101" => if A(5) = '1' then temp := "000"&unsigned(B)&"00000"; end if; when "110" => if A(6) = '1' then temp := "00"&unsigned(B)&"000000"; end if; when "111" => if A(7) = '1' then temp := "0"&unsigned(B)&"0000000"; end if; end case; end if; end process; end behavioral; ```
Honored Contributor I
82 Views

I suggest you change my code to all signals instead of variables as I fell into that trap since temp may not be set to zeros in the way I have written

Honored Contributor I
82 Views

Im feeling pretty generous today. I hate seeing overly complicated case statements.

I think the following code does what you're trying to do:

``` library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.numeric_std.all; entity prueba2 is port ( A : in std_logic_vector( (7 downto 0); B : in unsigned (7 downto 0); inicio : in std_logic; clk : in std_logic; reset : in std_logic; q : out unsigned (2 downto 0); resultado : out unsigned (15 downto 0) ); end prueba2; architecture behavioral of prueba2 is signal cuenta : unsigned(2 downto 0); signal y : unsigned(15 downto 0); begin multi : process (clk, reset) begin if reset = '1' then y <= (others => '0'); elsif rising_edge(clk) then if inicio = '1' then cuenta <= cuenta + 1; end if; if A /= x"00" then if A( to_integer(cuenta) ) = '1' then Y <= Y + ( resize(B, y'length)*(2**to_integer(cuenta)) ); end if; end if; end if; end process; q <= cuenta; resultado <= y; end architecture; ```
Honored Contributor I
82 Views

--- Quote Start ---

Im feeling pretty generous today. I hate seeing overly complicated case statements.

I think the following code does what you're trying to do:

``` library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.numeric_std.all; entity prueba2 is port ( A : in unsigned (7 downto 0); B : in unsigned (7 downto 0); inicio : in std_logic; clk : in std_logic; reset : in std_logic; q : out unsigned (2 downto 0); resultado : out unsigned (15 downto 0) ); end prueba2; architecture behavioral of prueba2 is signal cuenta : unsigned(2 downto 0); signal y : unsigned(15 downto 0); begin multi : process (A, clk, reset) begin if reset = '1' then y <= (others => '0'); elsif rising_edge(clk) then if inicio = '1' then cuenta <= cuenta + 1; end if; if B /= x"00" then Y <= Y + ( resize(B, 15)*(2**to_integer(cuenta)) ); end if; end if; end process; q <= cuenta; resultado <= y; end architecture; ```

--- Quote End ---

well Tricky that might work but is too tricky for beginner, after all I can just say y = a*b

I assume it is exercise that gets more and more compact under pressure...great
Honored Contributor I
82 Views

--- Quote Start ---

well Tricky that might work but is too tricky for beginner, after all I can just say y = a*b

I assume it is exercise that gets more and more compact under pressure...great

--- Quote End ---

Thank you kaz and Tricky, finally before I read your answers I have solved it in the way that kaz as told me.

So I've understood it very well. Thank you so much for the help!!!!