saludos vengo a pedir su ayuda ya que tengo que realizar en vhdl un multiplicador 8 x 8 pero de números con signo en complemento a2 mediante el algoritmo de sumas y desplazamientos, ya tengo realizado el código para multiplicar números sin signo.La cuestión es que se que solo tengo que modificarle algo al código pero no se que es, ya estuve leyendo sobre este asunto de la multiplicación en complemento a2 y estuve viendo los distintos algoritmos que existen pero no entiendo que cambiar en mi código o no e encontrado el algoritmo que me de a entender que cambiar al código. si me pudieran ayudar un poco se los agradecería, al menos si me pudieran dar información del algoritmo que tengo que utilizar, les adjunto el código para que vean que es lo que estoy haciendo, como comentario no puedo utilizar estandard logic, lo que utilizo en el código solo es para hacer el barrido a los displays de la tarjeta solo en eso lo puedo utilizar.
saludos y de antemano muchas gracias.
Código:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
entity Mult4x4 is
port(
clk : in bit;
rst : in bit;
enter : in bit;
sw : in bit_vector(7 downto 0);
rdy : out bit;
prod : out bit_vector(15 downto 0);
seg : out std_logic_vector(6 downto 0);
an : out std_logic_vector (3 downto 0);
dp: out std_logic
);
end Mult4x4;
architecture arq_Mult4x4 of Mult4x4 is
-- Señales para el control
type estados is(IDLE, S1, MULT);
signal ep : estados := IDLE;
-- Señales para el procesamiento (data path)
signal mndo, mdor : bit_vector(7 downto 0) := "00000000"; -- Multiplicando y multiplicador
signal ac : bit_vector(16 downto 0) := (others =>'0'); -- Acumulador
signal cnt : bit_vector(2 downto 0) := "000"; -- Contador
signal suma : bit_vector(8 downto 0);
signal mux : bit_vector(7 downto 0);
---señales utiles para el circuito Y/Decodificador/Multiplexor
signal LED1,LED2,LED3,LED4: std_logic_vector(6 downto 0);
constant t_1ms: integer := 50000;
signal delay_1ms: integer range 0 to t_1ms;
-----------------------------------------------
-- Funciones
function add( X, Y : bit_vector) return bit_vector is
variable q : bit_vector(X'range);
variable c : bit_vector((X'HIGH+1) downto 0);
begin
c(0) := '0';
for i in X'reverse_range loop -- Voy de 0 al top de X con "reverse_range"
q(i) := X(i) xor Y(i) xor c(i);
c(i+1) := (X(i) and Y(i)) or
(Y(i) and c(i)) or
(c(i) and X(i));
end loop;
return q;
end function add;
-- Señales para la salida
signal x, y : bit_vector(8 downto 0);
begin
-- Unidad de control
Uctrl:
process(clk)
begin
if(clk'event and clk = '1') then
if(rst = '1') then
ep <= IDLE;
else
case ep is
when IDLE => if(enter = '1') then
ep <= S1;
else
ep <= IDLE;
end if;
when S1 => if(enter = '0') then
ep <= MULT;
else
ep <= S1;
end if;
when MULT => if(cnt = "111") then
ep <= IDLE;
else
ep <= MULT;
end if;
end case;
end if;
end if;
end process Uctrl;
-- Unidad de procesamiento (data path)
Regmndo: -- Registro multiplicando
process(clk)
begin
if(clk'event and clk = '1') then
if(rst = '1') then
mndo <= "00000000";
elsif(enter = '1' and ep = IDLE) then
mndo <= sw;
end if;
end if;
end process Regmndo;
Regmdor: -- Registro mutliplicador
process(clk)
begin
if(clk'event and clk = '1') then
if(rst = '1') then
mdor <= "00000000";
elsif(enter = '0' and ep = S1) then
mdor <= sw;
elsif(ep = MULT) then
mdor <= '0' & mdor(7 downto 1); -- Corrimiento a la derecha
end if;
end if;
end process Regmdor;
Regcnt: -- Registro del contador
process(clk)
begin
if(clk'event and clk = '1') then
if(rst = '1') then
cnt <= "000";
elsif(enter = '1' and ep = IDLE) then
cnt <= "000";
elsif(ep = MULT) then
cnt(0) <= not(cnt(0)); -- Hacemos un pequeño contador. Primera cifra se niega cada pulso
if (cnt(0) = '1') then -- Segunda cifra se niega cada que la primera es '1'.
cnt(1) <= not(cnt(1));
else
cnt(1) <= cnt(1);
end if;
if(cnt(0)='1' and cnt(1)='1') then
cnt(2)<= not(cnt(2));
else
cnt(2)<= cnt(2);
end if;
-- Termina contador de 0 a 7.
end if;
end if;
end process Regcnt;
Regacum: -- Registro del acumulador
process(clk)
begin
if(clk'event and clk = '1') then
if(rst = '1') then
ac <= (others => '0');
elsif(ep = IDLE and enter = '1') then
ac <= (others => '0');
elsif(ep = MULT) then
ac(7 downto 0) <= ac(8 downto 1); -- Corrimiento del RHS del acumulador
ac(16 downto 8) <= suma; -- Suma de producto parcial
end if;
end if;
end process Regacum;
RegRdy: -- Registro de bandera de ready
process(clk)
begin
if(clk'event and clk = '1') then
if(rst = '1') then
Rdy <= '0';
elsif(ep = IDLE and enter = '1') then
Rdy <= '0';
elsif(ep = MULT and cnt = "111") then
Rdy <= '1';
end if;
end if;
end process RegRdy;
x <= '0' & ac(16 downto 9);
y <= '0' & mux;
suma <= add(x,y);
mux <= mndo when mdor(0) = '1' else "00000000";
prod <= ac(16 downto 1); -- Salida.
-------------------------------
--circuito y (codificador)
--HEX-to-seven-segment decoder
-- segment encoinputg
-- 0
-- ---
-- 5 | | 1
-- --- <- 6
-- 4 | | 2
-- ---
-- 3
with ac(4 downto 1) SELect
LED1<= "1111001" when "0001", --1
"0100100" when "0010", --2
"0110000" when "0011", --3
"0011001" when "0100", --4
"0010010" when "0101", --5
"0000010" when "0110", --6
"1111000" when "0111", --7
"0000000" when "1000", --8
"0010000" when "1001", --9
"0001000" when "1010", --A
"0000011" when "1011", --b
"1000110" when "1100", --C
"0100001" when "1101", --d
"0000110" when "1110", --E
"0001110" when "1111", --F
"1000000" when others; --0
with ac(8 downto 5) SELect
LED2<= "1111001" when "0001", --1
"0100100" when "0010", --2
"0110000" when "0011", --3
"0011001" when "0100", --4
"0010010" when "0101", --5
"0000010" when "0110", --6
"1111000" when "0111", --7
"0000000" when "1000", --8
"0010000" when "1001", --9
"0001000" when "1010", --A
"0000011" when "1011", --b
"1000110" when "1100", --C
"0100001" when "1101", --d
"0000110" when "1110", --E
"0001110" when "1111", --F
"1000000" when others; --0
with ac(12 downto 9) SELect
LED3<= "1111001" when "0001", --1
"0100100" when "0010", --2
"0110000" when "0011", --3
"0011001" when "0100", --4
"0010010" when "0101", --5
"0000010" when "0110", --6
"1111000" when "0111", --7
"0000000" when "1000", --8
"0010000" when "1001", --9
"0001000" when "1010", --A
"0000011" when "1011", --b
"1000110" when "1100", --C
"0100001" when "1101", --d
"0000110" when "1110", --E
"0001110" when "1111", --F
"1000000" when others; --0
with ac(16 downto 13) SELect
LED4<= "1111001" when "0001", --1
"0100100" when "0010", --2
"0110000" when "0011", --3
"0011001" when "0100", --4
"0010010" when "0101", --5
"0000010" when "0110", --6
"1111000" when "0111", --7
"0000000" when "1000", --8
"0010000" when "1001", --9
"0001000" when "1010", --A
"0000011" when "1011", --b
"1000110" when "1100", --C
"0100001" when "1101", --d
"0000110" when "1110", --E
"0001110" when "1111", --F
"1000000" when others; --0
----------------------------------------
--circuito multiplexor/contador
process(clk)
begin
if(clk'event and clk='1') then
delay_1ms<= delay_1ms +1;
if(delay_1ms <t_1ms/4) then
seg <= LED1;
an<= "1110";
elsif(t_1ms/4<=delay_1ms and delay_1ms<t_1ms/2) then
seg <= LED2;
an <= "1101";
elsif(t_1ms/2<=delay_1ms and delay_1ms<t_1ms*3/4) then
seg <= LED3;
an <= "1011";
elsif(t_1ms*3/4<=delay_1ms and delay_1ms<t_1ms) then
seg <= LED4;
an <= "0111";
end if;
end if;
end process;
-------------------
dp <='1';
-----
end arq_Mult4x4;
saludos y de antemano muchas gracias.
Última edición por un moderador: