library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity speicher_klein is Port ( CLK: in std_logic; input: in std_logic_vector(8 downto 1); -- Daten in den Ringspeicher input_flag: in std_logic; -- Wenn hier eine Flanke auftritt, wird der input Wert im Speicher abgelegt output: out std_logic_vector(8 downto 1); -- Daten vom Ringspeicher empty_flag: out std_logic := '1'; -- Wenn der Speicher leer ist steht dieses Flag auf 1 next_flag: in std_logic -- Wenn hier eine Flanke auftritt, wird ein neuer Wert auf output gelegt ); end speicher_klein; architecture Behavioral of speicher_klein is type ram_type is array(0 to 15) of std_logic_vector(8 downto 1); -- Typen Deklaration für Daten zum PC subtype ram_addr is std_logic_vector(4 downto 1); -- 4 Bits => 16 Elemente (0...15) signal ram: ram_type; -- 16 Byte Speicher signal input_puffer: std_logic_vector(8 downto 1); -- Daten-Puffer in den Ringspeicher signal write_addr: ram_addr := "0000"; -- dort sollen Daten hingeschrieben werden, die bisher erst in ram_input vorliegen signal read_addr: ram_addr := "0000"; -- Lese-Adresse für Daten vom Ringpuffer begin --###################################### -- Speicher (Aurel Richtung RS232) --###################################### process (CLK) variable next_flag_puffer : std_logic := '0'; variable input_flag_puffer : std_logic := '0'; begin if (CLK'event and CLK = '1') then -- wenn Schreib- und Lese-Zeiger auf dem selben Feld stehen, dann ist der Speicher völlig leer if (write_addr = read_addr) then empty_flag <= '1'; else -- wenn der Speicher nicht leer ist empty_flag <= '0'; if (next_flag_puffer /= next_flag) then -- und ein neues Zeichen gelesen werden soll read_addr <= read_addr + 1; -- dann wird der Lesezeiger eine Zelle weiter gesetzt end if; end if; next_flag_puffer := next_flag; -- es sollen Daten in den Ringpuffer geschrieben werden if (input_flag /= input_flag_puffer) AND ( (write_addr + 1) /= read_addr ) then -- mit Schreibbefehl darf aktuelle Lesezelle nicht überschrieben werden write_addr <= write_addr + 1; input_puffer <= input; end if; input_flag_puffer := input_flag; end if; end process; --###################################### -- Prototyp für den Speicher --###################################### process (CLK) variable write_addr_puffer: ram_addr := "0000"; -- dort liegen auch tatsächlich die Daten schon vor! begin if (CLK'event and CLK = '1') then if (write_addr /= write_addr_puffer) then ram(CONV_INTEGER(write_addr)) <= input_puffer; write_addr_puffer := write_addr; end if; output <= ram(CONV_INTEGER(read_addr)); end if; end process; end Behavioral;