Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)

Help multiplier vhdl

Altera_Forum
Honored Contributor II
2,734 Views

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!!
0 Kudos
13 Replies
Altera_Forum
Honored Contributor II
676 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
0 Kudos
Altera_Forum
Honored Contributor II
676 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 ( 

multiplicador: in std_logic; 

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; 

Q(8):=multiplicador; 

 

Q7 <= Q(7); 

end if; 

end if; 

 

 

end process; 

 

end behavioral; 

 

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

Is this the correct way to do it?? 

Thank you!
0 Kudos
Altera_Forum
Honored Contributor II
676 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 ( 

multiplicador: in std_logic; 

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; 

Q(8):=multiplicador; 

 

Q7 <= Q(7); 

end if; 

end if; 

 

 

end process; 

 

end behavioral; 

 

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

Is this the correct way to do it?? 

Thank you!
0 Kudos
Altera_Forum
Honored Contributor II
676 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.
0 Kudos
Altera_Forum
Honored Contributor II
676 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?
0 Kudos
Altera_Forum
Honored Contributor II
676 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; 

 

...
0 Kudos
Altera_Forum
Honored Contributor II
676 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; 

 

resultado <= y; 

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?
0 Kudos
Altera_Forum
Honored Contributor II
676 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");
0 Kudos
Altera_Forum
Honored Contributor II
676 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;
0 Kudos
Altera_Forum
Honored Contributor II
676 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

0 Kudos
Altera_Forum
Honored Contributor II
676 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;
0 Kudos
Altera_Forum
Honored Contributor II
675 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
0 Kudos
Altera_Forum
Honored Contributor II
675 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!!!!
0 Kudos
Reply