mikrocontroller.net

Forum: FPGA, VHDL & Co. Frequenzteiler


Autor: Marktschreier (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich möchte eine Frequenz durch 125 teilen.
Wie kann ich das in VHDL programmieren?
Könnte mir jemand die verschiedenen Möglichkeiten aufzeigen?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marktschreier schrieb:
> Wie kann ich das in VHDL programmieren?
So etwa:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity Clockdivider is
    Generic ( divider  : integer := 125);
    Port ( ci : in  STD_LOGIC;
           co : out  STD_LOGIC);
end Clockdivider;

architecture Behavioral of Clockdivider is
signal clkdiv : integer range 0 to divider-1 := 0;
begin
   process begin
      wait until rising_edge(ci);
      -- erst mal ein Zähler mit 125 Schritten
      if (clkdiv < divider-1) then   clkdiv < clkdiv + 1;
      else                           clkdiv <= 0;
      end if;
      -- und dann so
      if (clkdiv < divider/2) then   co <= '1';
      else                           co <= '0';
      end if;
   end process;
   -- oder so
   co <= '1' when clkdiv < divider/2 else '0';
end Behavioral;

Aber so ein Takt sollte nicht innerhalb eines FPGAs weiterverwendet 
werden. Dort arbetiet man idR. besser mit Clock-Enables. Etwa so:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity Clockdivider is
    Generic ( divider  : integer := 125);
    Port ( ci : in  STD_LOGIC;
           :
           :
           );
end Clockdivider;

architecture Behavioral of Clockdivider is
signal clkdiv : integer range 0 to divider-1 := 0;
signal ce: std_logic := '0';
begin
   process begin
      wait until rising_edge(ci);
      -- erst mal ein Zähler mit 125 Schritten
      if (clkdiv < divider-1) then   
         clkdiv < clkdiv + 1;
         ce <= '0';
      else
         clkdiv <= 0;
         ce <= '1';
      end if;
   end process;

   process begin
      wait until rising_edge(ci);
      if (ce='1') then
        :
        : -- mach was alle 125 Takte   
        :
      end if;
   end process;

end Behavioral;

Sieh dir da mal das Lauflicht an:
http://www.lothar-miller.de/s9y/archives/61-Lauflicht.html

Autor: Marktschreier (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lieber Lothar,

hab ganz vielen herzlichen Dank für deinen tollen VHDL-Code!

Der Hintergrund, warum ich so einen Code haben wollte war übrigens 
folgendes:

1. Um davon zu lernen... Besten Dank :-)
2. Ich möchte einen alten Frequenzzähler mit einem Vorteiler/Prescaler 
versehen. Einem schnellen Teiler durch 8 würde ich dann einen Teiler 
durch 125 nachschalten um insgesamt auf einen Teilerfaktor von 1000 zu 
kommen.

Darf ich den Thread hier durch eine Zusatzfrage erweitern?:
Wenn mein Prescaler durch 512 teilt, und ich insgesamt einen 
Teilerfaktor von 1000 haben möchte, wie kann man das realisieren?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marktschreier schrieb:
> Wenn mein Prescaler durch 512 teilt, und ich insgesamt einen
> Teilerfaktor von 1000 haben möchte, wie kann man das realisieren?
Nur sehr schlecht, denn ohne den Eingangstakt zu haben, ist dann im 
heruntergeteilten Takt zuviel Information verloren...

Autor: Mathias Jt (mjpdx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weitere Möglichkeit:
Sequentielle Anweisung:


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity Divider_module is

port(

clk: IN std_logic ;
divclk: OUT std_logic;
);

end Divider_module;


architecture Bev of Divider_module is

signal  sig_clk    : std_logic_vector (6 downto 0);

begin
process (clk)
begin

if (clk 'event and clk = '1') then
   sig_clk <= sig_clk + 1 ;

   if(sig_clk = "1111101") ; -- =125
     divclk <= '1'  ;
     sig_clk <=  "0000000" ;

     else
      divclk <= '0' ;

   end if
end if
end process ;
end Bev;


Vielleicht etwas leichter verständlich.
Über die Qualität kann ich keine Aussage machen, da Anfänger;-
Getestet habe ich die Anweisung noch nicht, sollte aber laufen!

> Wenn mein Prescaler durch 512 teilt, und ich insgesamt einen
> Teilerfaktor von 1000 haben möchte, wie kann man das realisieren?

Auf 1024 zu kommen wäre leicht: /2
Aber auf 1000:  /1.953... Mir fällt auf die schnelle nichts ein!

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mathias Jt schrieb:
> signal  sig_clk    : std_logic_vector (6 downto 0);
> :
>    sig_clk <= sig_clk + 1 ;
Was mir dazu einfällt: mit Vektoren rechnet man nicht.
Stattdessen gibt es die Datentypen signed, unsigned und integer.
Und dazu dann die numeric_std.all verwenden

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mathias Jt schrieb:
> Aber auf 1000:  /1.953... Mir fällt auf die schnelle nichts ein!

Da hilft ein fractional counter. Problematisch könnte der Jitter in 
diesem Fall werden. Wofür brauchst Du denn den Takt?

Duke

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.