Hice una pregunta similar aquí . Pensé que esa respuesta sería aplicable a este código pero tengo el mismo problema. Tengo una ROM que funciona al doble de la velocidad de mi CPU (dejé fuera todos los comandos, excepto 'OUT' para que sea más fácil de entender). La razón por la que se ejecuta al doble de la velocidad es porque la ROM tiene una tubería.
El primer valor en mi ROM es '0xF100' que ejecutaría la instrucción 'OUT'. Para propósitos de depuración, dejo que mi instrucción 'OUT' ponga 'salida' a "11111111". Cuando simulo el diseño con ModelSim, encuentro que 'output' no se configura en "11111111" inmediatamente, sino que necesita otro borde ascendente de 'ClockDivided' para establecer su valor. Quiero 'output' para obtener su valor inmediatamente, ¿cómo hago esto?
código:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity first is
port(
input : in STD_LOGIC_VECTOR(7 downto 0) := "00000000";
output : out STD_LOGIC_VECTOR(7 downto 0) := "00000000";
PCout : out STD_LOGIC_VECTOR(15 downto 0) := "0000000000000000";
clock : in STD_LOGIC
);
end first;
architecture behavioral of first is
signal PC : STD_LOGIC_VECTOR(7 downto 0) := "00000000";
signal data : STD_LOGIC_VECTOR(15 downto 0) := "0000000000000000";
signal regC : STD_LOGIC_VECTOR(3 downto 0) := "0000";
signal regA : STD_LOGIC_VECTOR(3 downto 0) := "0000";
signal regB : STD_LOGIC_VECTOR(3 downto 0) := "0000";
signal opcode : STD_LOGIC_VECTOR(3 downto 0) := "0000";
type registerFile is array(15 downto 0) of std_logic_vector(7 downto 0);
signal registers : registerFile := (others => "00000000");
signal clockDivided : STD_LOGIC := '1';
component rom is
port(
address : in STD_LOGIC_VECTOR(7 downto 0);
q : out STD_LOGIC_VECTOR(15 downto 0);
clock : in STD_LOGIC := '1'
);
end component;
begin
rom_inst : rom PORT MAP (
address => PC,
clock => clock,
q => data
);
PCout <= data;
process(clock)
begin
if rising_edge(clock) then
clockDivided <= not(clockDivided); --dividing the clock because the ROM runs twice as fast
end if;
end process;
process(clockDivided)
begin
opcode <= data(15 downto 12);
regC <= data(11 downto 8);
regA <= data(7 downto 4);
regB <= data(3 downto 0);
if rising_edge(clockDivided) then
registers(0) <= "00000000";
case opcode is
when "1111" => output <= "11111111"; --output doesn't get set to "11111111" immediately
PC <= PC + 1;
--OUT
when others =>
PC <= PC + 1;
end case;
end if;
end process;
end behavioral;
banco de pruebas:
library ieee;
use ieee.std_logic_1164.all;
entity testbench is
end testbench;
architecture behavioral of testbench is
signal inputX : STD_LOGIC_VECTOR(7 downto 0) := "00000000";
signal outputX : STD_LOGIC_VECTOR(7 downto 0) := "00000000";
signal PCX : STD_LOGIC_VECTOR(15 downto 0);
signal clockX : STD_LOGIC := '0';
component first
port(
input : in STD_LOGIC_VECTOR(7 downto 0);
output : out STD_LOGIC_VECTOR(7 downto 0);
PCout : out STD_LOGIC_VECTOR(15 downto 0);
clock : in STD_LOGIC
);
end component;
begin
uut: first port map(
input => inputX,
output => outputX,
PCout => PCX,
clock => clockX
);
stim_proc: process
begin
clockX <= '0';
wait for 1 ns;
clockX <= '1';
wait for 1 ns;
end process;
end behavioral;