library ieee;
use ieee.std_logic_1164.all;
entity ALU is
port(
input1: in std_logic_vector(31 downto 0);
input2: in std_logic_vector(31 downto 0);
reset: in std_logic; --Asynchronous Reset
operation: in std_logic_vector(3 downto 0);
zero_flag: out std_logic;
ov_flag: out std_logic;
output: out std_logic_vector(31 downto 0)
);
end ALU;
architecture hybrid of ALU is
-------------------------Component Declaration------------------------
component kogge_stone_adder is
port(
input1: in std_logic_vector(31 downto 0);
input2: in std_logic_vector(31 downto 0);
ov_flag: out std_logic;
zero_flag: out std_logic;
output: out std_logic_vector(31 downto 0)
);
end component;
component two_complement is
port(
input: in std_logic_vector(31 downto 0);
output: out std_logic_vector(31 downto 0)
);
end component;
----------------------End Component Declaration-----------------------
--------------------------Signal Declaration--------------------------
signal adder_in_1: std_logic_vector(31 downto 0);
signal adder_in_2: std_logic_vector(31 downto 0);
signal adder_ov_flag: std_logic;
signal adder_zero_flag: std_logic;
signal adder_output: std_logic_vector(31 downto 0);
signal input2_comp: std_logic_vector(31 downto 0);
-----------------------End Signal Declaration------------------------
begin
process(all)
begin
---------------------------------Reset-------------------------------
if reset = '1' then
output <= x"00000000";
zero_flag <= '0';
ov_flag <= '0';
----------------------------End Reset----------------------------------
else
------------Case Statement to Perform the required operation-----------
case operation is
when "0000" => --ADD
adder_in_1 <= input1;
adder_in_2 <= input2;
ov_flag <= adder_ov_flag;
zero_flag <= adder_zero_flag;
output <= adder_output;
when "0001" => --SUBTRACT
adder_in_1 <= input1;
adder_in_2 <= input2_comp;
zero_flag <= adder_zero_flag;
ov_flag <= adder_ov_flag;
output <= adder_output;
--when "0010" => --MULTIPLY
when "0011" => -- COMPARE EQUAL
adder_in_1 <= input1;
adder_in_2 <= input2_comp;
ov_flag <= adder_ov_flag;
zero_flag <= adder_zero_flag;
if adder_zero_flag = '1' then
output <= x"00000001";
else
output <= x"00000000";
end if;
when "0100" => --COMPARE LESS THAN
adder_in_1 <= input1;
adder_in_2 <= input2_comp;
ov_flag <= adder_ov_flag;
zero_flag <= adder_zero_flag;
if adder_output(31) = '1' then
output <= x"00000001";
else
output <= x"00000000";
end if;
when "0101" => --COMPARE LESS THAN OR EQUAL
adder_in_1 <= input1;
adder_in_2 <= input2_comp;
ov_flag <= adder_ov_flag;
zero_flag <= adder_zero_flag;
if adder_output(31) = '1' or adder_zero_flag = '1' then
output <= x"00000001";
else
output <= x"00000000";
end if;
when "0110" => --SHIFT RIGHT
output <= '0' & input1(31 downto 1);
when "0111" => --SHIFT LEFT
output <= input1(30 downto 0) & '0';
when "1000" => --ARITHMECTIC SHIFT RIGHT
output <= input1(31) & input1(31 downto 1);
when "1001" => -- BITWISE AND
and_gate: for counter in 0 to 31 loop
output(counter) <= input1(counter) and input2(counter);
end loop;
when "1010" => -- BITWISE OR
or_gate: for counter in 0 to 31 loop
output(counter) <= input1(counter) or input2(counter);
end loop;
when "1011" => -- BITWISE XOR
xor_gate: for counter in 0 to 31 loop
output(counter) <= input1(counter) xor input2(counter);
end loop;
when "1100" => -- BITWISE XNOR
xnor_gate: for counter in 0 to 31 loop
output(counter) <= input1(counter) xnor input2(counter);
end loop;
when "1101" => -- BITWISE NOT
not_gate: for counter in 0 to 31 loop
output(counter) <= not input1(counter);
end loop;
when "1110" => --ROTATE RIGHT
output <= input1(0) & input1(31 downto 1);
when "1111" => --ROTATE LEFT
output <= input1(30 downto 0) & input1(31);
when others =>
output <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
zero_flag <= 'Z';
ov_flag <= 'Z';
end case;
end if;
end process;
------------------------Component Instantiation-------------------------
adder: kogge_stone_adder port map(
input1 => adder_in_1,
input2 => adder_in_2,
ov_flag => adder_ov_flag,
zero_flag => adder_zero_flag,
output => adder_output
);
complementer: two_complement port map(
input => input2,
output => input2_comp
);
----------------------End Component Instantiation-----------------------
end hybrid;
Mientras sintetizaba un circuito combinacional, quartus II informó en el analizador de tiempo que una señal llamada operación (1) es el reloj e informó una holgura negativa, la operación es un bus de 4 bits. Realmente no sé por qué eligió este bit específico, por lo que el la pregunta es ¿Cómo puedo eliminar el reloj del diseño o ¿Cómo puedo decirle a quartus que este es un circuito combinacional?
Esta es la vista RTL completa:
Esta es una vista RTL ampliada (el resto del rtl es hacer lo mismo con los otros bits):
Este mensaje también apareció en la consola durante la síntesis: ¿El mensaje anterior es el motivo por el que quartus asigna un reloj? (Sintetizar pestillos en lugar de lógica combinacional)
El conjunto de herramientas Quartus (y las herramientas FPGA en general) están destinados al diseño síncrono. Tratar de usarlos para desarrollar un diseño puramente asincrónico requiere mucha experiencia y, a menudo, sigue siendo un ejercicio de frustración.
El análisis de tiempo en particular requiere un reloj, y si no asigna uno, las herramientas intentarán elegir un candidato probable, con resultados menos que óptimos, como ha descubierto.
Tendrá que restringir cada combinación de entrada y salida de su circuito de forma independiente si desea que las herramientas de síntesis optimicen la implementación correctamente. Esto rápidamente se vuelve inmanejable para cualquier cosa que no sea el más trivial de los circuitos.
Tenga en cuenta que esta es una respuesta genérica. Si quieres ayuda con tu problema específico, muéstranos tu código.
Hasan Ibrahim
Tapas Sourabh