Hier ist nicht der Vorteiler gemeint, der etwa ein zu messendes Signal bei 1 GHz auf eine Frequenz z.B. unter 10 MHz herunterteilt, sondern der Vorteiler, der den Referenztakt von 10 MHz auf 10 kHz reduziert. Die Ablaufsteuerung wird den Takt weiter herunterteilen so daß Torzeiten zwischen 0.01 und 10 Sekunden verfügbar sind.
Der Vorteiler ist relativ einfach, weswegen ich ihn am Anfang präsentieren. Er soll also ein 10 MHz-Signal auf 10 kHz herunterteilen. Er wird daher einen Eingang namens clk haben und einen Ausgang, den ich mit clk1000 (1000 steht für 1/1000) bezeichne. Darüber hinaus gibt es einen reset-Eingang (reset) und einen enable-Eingang (en). Im folgenden der VHDL-Code:
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity prescaler is port(clk : in std_logic; en : in std_logic; clk1000 : out std_logic; reset : in std_logic ); end; architecture behavioral of prescaler is signal x : std_logic_vector (8 downto 0); signal c_int : std_logic; begin p1: process(clk, en, reset) begin if reset = '1' then x <= conv_std_logic_vector(499,9); c_int <= '0'; elsif clk = '1' and clk'event then if en = '1' then if x = "000000000" then x <= conv_std_logic_vector(499,9); c_int <= not c_int; else x <= x-1; end if; end if; end if; end process p1; clk1000 <= c_int; end behavioral;
Ohne den code im einzelnen erklären zu wollen sei erwähnt, daß die entity prescaler genau die oben aufgeführten Ein- und Ausgänge besitzt und daß intern ein 9 bit breiter Zähler verwendet wird. Er beginnt bei Zählerstand 499 rückwärts bis auf Null zu zählen und invertiert dann beim Vesuch auf -1 zu zählen c_int. Außerhalb der synchronen Umgebung p1 wird der Zustand von c_int direkt an clk1000 in einem nebenläufigen Prozeß weitergereicht. Nachfolgend noch die Constraints, die die Pinbelegung festlegen.
NET "clk" LOC = "P1" | BUFG = CLK ; NET "clk1000" LOC = "P28" ; NET "en" LOC = "P7" ; NET "reset" LOC = "P33" | BUFG = SR ;
Der Vorteiler wurde auch simuliert. Das folgende File zeigt den Simulationsaufbau.
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.std_logic_unsigned.all; USE ieee.numeric_std.ALL; ENTITY presscaler_test IS END presscaler_test; ARCHITECTURE behavior OF presscaler_test IS -- Component under Test COMPONENT prescaler PORT( clk : IN std_logic; en : IN std_logic; clk1000 : OUT std_logic; reset : IN std_logic); END COMPONENT; --Inputs signal clk : std_logic := '0'; signal en : std_logic := '0'; signal reset : std_logic := '0'; --Outputs signal clk1000 : std_logic; -- Clock period definition for 10 MHz constant clk_period : time := 100 ns; BEGIN -- Instantiate the Unit Under Test (UUT) uut: prescaler PORT MAP ( clk => clk, en => en, clk1000 => clk1000, reset => reset); -- Clock process definitions clk_process :process begin clk <= '0'; wait for clk_period/2; clk <= '1'; wait for clk_period/2; end process; -- Enable signal generation en_process :process begin en <= '0'; wait for 10 us; en <= '1'; wait; end process; -- Reset signal generation reset_process :process begin reset <= '0'; wait for 3 us; reset <= '1'; wait for 3 us; reset <= '0'; wait; end process; END;
Initial sind alle Eingänge auf Low. Der Augang ist anfangs undefiniert. Simuliert wird mit einer Taktfrequenz von 10 MHz. Das Reset-Signal (active high) geht nach 3 us für 3 us auf High um danach für den Rest der Simulation auf Low zu verbleiben. Das enable-Signal (evenfalls active high) geht nach 10 us bis zum Ender der Simulation auf High. Ab diesem Zeitpunkt wird das Eingangssignal mit 10 MHz Taktfrequenz durch 1000 geteilt. Das folgende Bild illustriert das Simulationsergebnis:
Die oberste Spur zeigt das 10 MHz-Signal, das bei dem gewählten Zeitfenster nicht mehr aufgelöst dargestellt wird. Daher der breite grüne Balken. Darunter ist das enable Signal dargestellt, gefolgt vom Reset-Signal. Gemessen wurde nun der Abstand zweier aufeinanderfolgender steigender Flanken des Ausgangssignals clk1000. Schon die automatische Abstandsmessung der beiden Cursorlinien zeigt 100,000,000 ps an, was, nach auszählern der Nullern genau 100 us entspricht und das ist nichts anderes als 10 kHz. Dieses CPLD müßte schon mal funktionieren und tut es auch, nachdem es auf dem Experimentierboard programmiert worden ist.