- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!!Link Copied
13 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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; ...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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");- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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!!!!

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page