Menu:

Project: FPGA68k  -  Tipps & Tricks

Tipp 1: Verwendung eines DCM (Digital Clock Manager)

Nicht selten ist der standardmäßig verbaute Quarzoszillator ungeeignet, um das eigene Design mit einem passenden Taktsignal zu versorgen. Vielleicht möchte man zum Beispiel ein VGA-Signal für 1024 Pixel horizontal und 768 Pixel vertikal erzeugen. Bei einer Wiederholfrequenz von 70 Hz benötigt man hierfür einen Pixeltakt von 75,00 MHz. Mit den im FPGA eingebauten DCMs (Digital Clock Manager) kannst Du ohne Probleme den 25,00 MHz-Oszillator verwenden und die Taktfrequenz um den Faktor 3 erhöhen.

Das folgende Beispiel bezieht sich allerdings nicht auf eine VGA-Signalerzeugung, sondern auf das VHDL-Testdesign #1, wobei hier die LED beispielsweise mit der achtfachen Geschwindigkeit blinken soll. Das Verfahren ist jedoch leicht auf andere Anwendungen mit anderen Multiplikatoren und Divisoren übertragbar. Allerdings ist anzumerken, dass nicht jeder beliebiger Faktor und Divisor verwendet werden kann. Näheres hierzu findest Du in den Datenblättern zum Spartan-6.

 

Vorgehensweise

Um die LED aus dem VHDL-Testdesign #1 mit der achtfachen Geschwindigkeit blinken zu lassen, wird bei diesem Tipp der Oszillatortakt von 25,00 MHz mittels eines DCM um den Faktor 8 auf 200,00 MHz vervielfacht. Dazu wird ein DCM zwischen dem Oszillatorausgang und dem Takteingang des Designs geschaltet, der Multiplikator auf "8" und der Divisor auf "1" gesetzt. Die 200,00 MHz am DCM-Ausgang takten dann das unveränderte VHDL-Testdesign #1. Da die Eingangsfrequenz um den Faktor 8 erhöht wurde, blinkt die LED jetzt ebenfalls mit der achtfachen Frequenz.

DCM

 

Quelltext

Im folgenden Quelltext sind die Stellen, welche gegenüber der Originalversion geändert werden müssen, mittels roter Schrift markiert. Da es nun auch zwei Taktfrequenzen gibt, wurde "Clock" umbenannt zu "Clock25" und "Clock200".


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

library unisim;
use unisim.vcomponents.all;

entity DCM01 is
        Port(   Clock25 :  in   STD_LOGIC;
                LED     :  out  STD_LOGIC
            );
end DCM01;


architecture Behavioral of DCM01 is

constant maximum        :  integer    := 5000000-1;

signal  counter         :  integer range 0 to maximum := maximum;
signal  led_status      :  std_logic  := '0';

-- Zusätzliche Signale für den DCM
signal  clkin1          :  std_logic;
signal  clk0            :  std_logic;
signal  clkfb           :  std_logic;
signal  clkfx           :  std_logic;
signal  Clock200        :  std_logic;                        -- neuer Takt

begin

-- Beschreibung des DCM
My_Clock_Gen1: DCM_SP

generic map(   CLKDV_DIVIDE        => 2.000,
               CLKFX_DIVIDE        => 1,                     -- Divisor
               CLKFX_MULTIPLY      => 8,                     -- Multiplikator
               CLKIN_DIVIDE_BY_2   => FALSE,
               CLKIN_PERIOD        => 40.000,
               CLKOUT_PHASE_SHIFT  => "NONE",
               CLK_FEEDBACK        => "1X",
               DESKEW_ADJUST       => "SYSTEM_SYNCHRONOUS",
               PHASE_SHIFT         => 0,
               STARTUP_WAIT        => FALSE)

port map(      CLKIN               => clkin1,
               CLKFB               => clkfb,
               CLK0                => clk0,
               CLK90               => OPEN,
               CLK180              => OPEN,
               CLK270              => OPEN,
               CLK2X               => OPEN,
               CLK2X180            => OPEN,
               CLKFX               => clkfx,
               CLKFX180            => OPEN,
               CLKDV               => OPEN,
               PSCLK               => '0',
               PSEN                => '0',
               PSINCDEC            => '0',
               PSDONE              => OPEN,
               LOCKED              => OPEN,
               STATUS              => OPEN,
               RST                 => '0',
               DSSEN               => '0');


Buffer_Clock_In:         IBUFG
port map( O => clkin1,   I => Clock25);

Buffer_Clock_Feedback:   BUFG
port map( O => clkfb,    I => clk0);

Buffer_Clock_Output:     BUFG
port map( O => Clock200, I => clkfx);


  process begin
      wait until rising_edge(Clock200);      -- warten bis zur nächsten positiven Flanke
      if (counter>0) then                    -- wenn der Zähler größer 0 ist, dann
          counter <= counter-1;              -- den Zähler dekrementieren
      else                                   -- ansonsten (Zähler ist 0):
          counter <= maximum;                -- Zähler wieder auf Ausgangswert setzen
          led_status <= not led_status;      -- und internen Status der LED invertieren
      end if;
  end process;

  LED <= led_status;                         -- den internen LED-Status an die LED übergeben

end Behavioral;

Der eigentliche Prozeß wird unverändert übernommen, nur wird jetzt auf die Taktflanke des neuen 200,00 MHz-Taktes gewartet. Über dem Prozeß wird eine Standard-Beschreibung von Xilinx für einen DCM eingefügt.

 

Zuweisungen der FPGA-Pins (User Constraint File)


# User Constraints für DCM01

NET "Clock25"          LOC = P55    | IOSTANDARD = LVCMOS33;
NET "LED"              LOC = P41    | IOSTANDARD = LVCMOS33;

Da dieselben Pins für den Oszillator und die LED verwendet werden, sind die "User Constraints" unverändert.