Otro code-kata a traer vengo de nuevo continuando con el post anterior sobre registros. Los registros se usan para varias tareas como almacenamiento de valores, direccionar a la memoria, el contador de programa, códigos de operación, lo que haga falta.. así que añadiendo funcionalidades al registro simple del post anterior, llegamos al registro multifunción.
Es decir, los registros multifunción son como los simples, pero añaden más señales de entrada, para hacer operaciones simples con el dato que les llega, valga la redundancia. Por ejemplo las señales y operaciones pueden ser:
- Precarga o carga en paralelo.
- Desplazamiento a la izquierda o derecha con bit extra de desplazamiento.
- Rotación a la izquierda o derecha.
Sin demasiadas explicaciones, la carga en paralelo activa en la salida la entrada sólo si la señal de carga está activada. El reset pone a ceros la salida. Un desplazamiento convierte por ejemplo una entrada de la forma «00001111» con entrada a 0 en «00011110». Y en la rotación no tenemos entrada extra, si no que por ejemplo, una rotación a la derecha de «00001111» quedaría en «10000111».
Al grano, el código del registro multifunción
library IEEE;
use IEEE.std_logic_1164.all;
entity eightBitsRegister is
port (
valueOut : out std_logic_vector (7 downto 0);
valueIn : in std_logic_vector (7 downto 0);
reset, clock, load : in std_logic;
shiftLeft, shiftLeftValueIn, shiftRight, shiftRightValueIn : in std_logic;
rotateLeft, rotateRight : in std_logic
);
end entity;
architecture arch_eightBitsRegister of eightBitsRegister is
signal auxValueOut : std_logic_vector (7 downto 0);
begin
valueOut <= auxValueOut;
identifier : process (clock)
begin
if rising_edge(clock) then
if reset = '1' then
auxValueOut <= "00000000";
elsif load = '1' then
auxValueOut <= valueIn;
elsif shiftLeft = '1' then
auxValueOut(0) <= shiftLeftValueIn;
for i in 1 to 7 loop
auxValueOut(i) <= valueIn(i-1);
end loop;
elsif shiftRight = '1' then
for i in 0 to 6 loop
auxValueOut(i) <= valueIn(i+1);
end loop;
auxValueOut(7) <= shiftRightValueIn;
elsif rotateLeft = '1' then
auxValueOut(0) <= valueIn(7);
for i in 1 to 7 loop
auxValueOut(i) <= valueIn(i-1);
end loop;
elsif rotateRight = '1' then
for i in 0 to 6 loop
auxValueOut(i) <= valueIn(i+1);
end loop;
auxValueOut(7) <= valueIn(0);
end if;
end if;
end process;
end architecture;
El banco de pruebas
library IEEE;
use IEEE.std_logic_1164.all;
entity eightBitsRegister_tb is
end entity;
architecture arch_eightBitsRegister_tb of eightBitsRegister_tb is
component eightBitsRegister is
port (
valueOut : out std_logic_vector (7 downto 0);
valueIn : in std_logic_vector (7 downto 0);
reset, clock, load : in std_logic;
shiftLeft, shiftLeftValueIn, shiftRight, shiftRightValueIn : in std_logic;
rotateLeft, rotateRight : in std_logic
);
end component;
signal testReset, testClock : std_logic := '0';
signal testValueOut, testValueIn : std_logic_vector (7 downto 0);
signal tics : integer := 0;
signal testLoad, testShiftLeft, testShiftLeftValueIn, testShiftRight, testShiftRightValueIn, testRotateLeft, testRotateRight : std_logic;
begin
testing_unit: eightBitsRegister port map (
valueOut => testValueOut,
valueIn => testValueIn,
reset => testReset,
clock => testClock,
load => testLoad,
shiftLeft => testShiftLeft,
shiftLeftValueIn => testShiftLeftValueIn,
shiftRight => testShiftRight,
shiftRightValueIn => testShiftRightValueIn,
rotateLeft => testRotateLeft,
rotateRight => testRotateRight
);
generate_100Mhzs_clock : process
begin
report "Tic tac..";
testClock <= not testClock;
wait for 5 ns; -- Tiempo de espera en un flanco de reloj.
if testClock = '1' then tics <= tics + 1; end if;
if tics >= 25 then wait; end if;
end process;
generate_signals : process
begin
wait for 5 ns;
testReset <= '1'; wait for 10 ns;
testReset <= '0'; wait for 10 ns;
testLoad <= '1'; wait for 10 ns;
testValueIn <= "00001101"; wait for 10 ns;
testValueIn <= "00001110"; wait for 10 ns;
testValueIn <= "00001111"; wait for 10 ns;
testLoad <= '0'; wait for 10 ns;
testReset <= '1'; wait for 10 ns;
testReset <= '0'; wait for 10 ns;
testShiftLeftValueIn <= '1'; wait for 10 ns;
testShiftLeft <= '1'; wait for 10 ns;
testShiftLeftValueIn <= '0'; testShiftLeft <= '0'; wait for 10 ns;
testShiftRightValueIn <= '1'; wait for 10 ns;
testShiftRight <= '1'; wait for 10 ns;
testShiftRightValueIn <= '0'; testShiftRight <= '0'; wait for 10 ns;
testRotateLeft <= '1'; wait for 10 ns;
testRotateLeft <= '0'; wait for 10 ns;
testRotateRight <= '1'; wait for 10 ns;
testRotateRight <= '0'; wait for 10 ns;
wait;
end process;
end architecture;
Si todo va bien, en la simulación se tiene que ver algo como lo de la imagen del principio.