Quiero hacer un elemento de procesamiento simple para calcular la diferencia absoluta entre dos palabras de 8 bits. Sin embargo, este elemento se puede usar como parte de una matriz para acelerar el cálculo de AD, haciéndolo en paralelo con más datos. Entonces, para lograr eso, excepto por las dos entradas de datos de 8 bits y la salida de datos de 8 bits, debería tener otras dos salidas de datos de 8 bits (llamémoslas SHIFT_A y SHIFT_B) que mantendrán el valor del anterior entradas (como un registro de desplazamiento).
Intenté realizar una implementación en VHDL, pero no funciona porque no puedo averiguar cómo hacer que las dos salidas SHIFT tengan valores diferentes a las dos entradas de datos. He intentado muchas cosas sin éxito, por lo que proporciono mi código fuente:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
--use ieee.std_logic_arith.ALL;
use IEEE.NUMERIC_STD.ALL;
entity pe_element is
port(
--Output signals
AD_o : out std_logic_vector(7 downto 0);
SHIFT_CB_o : out std_logic_vector(7 downto 0);
SHIFT_RB_o : out std_logic_vector(7 downto 0);
--Input signals
cb_en_i : in std_logic;
rb_en_i : in std_logic;
diff_en_i: in std_logic;
clk_i : in std_logic;
rst_i : in std_logic;
CB_i : in std_logic_vector(7 downto 0);
RB_i : in std_logic_vector(7 downto 0)
);
end pe_element;
architecture pe_element of pe_element is
--Define FSM states
type statetype is (S0, S1, S2, S3);
signal state, nextstate: statetype;
--Signal definitions
signal adder_tmp: std_logic_vector(8 downto 0);
-- That particular hack is a pretty annoying one. Idiots.
signal am: integer;
signal bm: integer;
signal CBreg: std_logic_vector(7 downto 0);
signal RBreg: std_logic_vector(7 downto 0);
begin
-- Current State Register
process(clk_i)
begin
if clk_i'event and clk_i = '1' then
if rst_i = '1' then
state <= S0;
else
state <= nextstate;
end if;
end if;
end process;
-- Next State Logic
process(state, diff_en_i, cb_en_i, rb_en_i) begin
case state is
when S0 => if diff_en_i = '0' and cb_en_i = '1' then nextstate <= S1;
else nextstate <= S0;
end if;
when S1 => if diff_en_i = '0' and rb_en_i = '1' then nextstate <= S2;
else nextstate <= S1;
end if;
when S2 => if diff_en_i = '1' and rb_en_i = '0' and cb_en_i = '0' then nextstate <= S3;
else nextstate <= S2;
end if;
when S3 => if diff_en_i = '1' then nextstate <= S3;
else nextstate <= S1;
end if;
when others => nextstate <= S0;
end case;
end process;
-- Output Logic
am <= to_integer(signed(CB_i));
bm <= to_integer(signed(RB_i));
CBreg <= CB_i when
((state = S1) and cb_en_i='1');
SHIFT_CB_o <= CBreg when
((state = S1) and cb_en_i = '1');
RBreg <= RB_i when
((state = S2) and rb_en_i='1');
SHIFT_RB_o <= RBreg when
((state = S2) and rb_en_i = '1');
adder_tmp <= std_logic_vector(to_signed(abs((am - bm)),9)) when
((state = S3) and rb_en_i = '0' and cb_en_i = '0' and diff_en_i = '1')
else "000000000";
AD_o <= adder_tmp(7 downto 0) when
((state = S3) and rb_en_i = '0' and cb_en_i = '0' and diff_en_i = '1')
else "00000000";
end pe_element;
Como se puede ver en la siguiente imagen de simulación, la salida de SHIFT mantiene solo el nuevo valor cada vez, y no el anterior.
Estoy bastante seguro de que he codificado algo mal, pero no puedo encontrarlo. ¿Tienes alguna idea?