Wie oft braucht man nur einfach irgend einen Takt?
Der muss nicht genau oder stabil sein, sondern einfach nur vor sich hintakten.
Dann ist die gute alte Methode über Gatterlaufzeiten und einen Inverter einen Ringoszillator zu bauen eigentlich naheliegend. Allerdings neigen die Tools beim FPGA-Design zur Optimierung. Hintereinandergeschaltete Gatter werden zusammengefasst, vereinfacht und gehen so im Build-Prozess verloren
Dagegen hilft bei Xilinx das Attribut "KEEP". Auf ein Signal angewandt teilt man der Toolchain mit, dass dieses Signal erhalten bleiben soll. Und das ist der Weg, der für den Ringoszillator beschritten wird.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity RingOszillator is
Port (reset : in std_logic;
oscout : out std_logic);
end RingOszillator;
architecture Behavioral of RingOszillator is
signal oscff : std_logic := '0';
signal ring : std_logic_vector(7 downto 0);
attribute KEEP : string;
attribute KEEP of ring : signal is "true";
begin
-- die Gatterkette
ring <= ring(6 downto 0) & not ring(7) when reset='0' else (others=>'0');
-- das Symmetrier-Flipflop
process (ring) begin
if rising_edge(ring(7)) then
oscff <= not oscff;
end if;
end process;
-- die Ausgangszuweisung
oscout <= oscff;
end Behavioral;
Der reset ist wichtig, ohne dieses Signal wird die Gatterkette nicht richtig zurückgesetzt, und der Oszillator beginnt nicht zu schwingen.
Mit einem Spartan3 XC3S400 im FG456 Gehäuse erhält man damit eine ziemlich temperaturstabile Frequenz von 50MHz am oscout. Damit lässt sich doch schon arbeiten, oder? ![]()