Forum: FPGA, VHDL & Co. Frequenzteiler in VHDL


von Michael (Gast)


Lesenswert?

Hallo Leute,

bin gerade neu eingestiegen in VHDL. Wollte jetzt einen Frequenzteiler
programmieren. Habe das bisher immer als schematic gemacht. Einfach ein
paar Fliplops die sich gegenseitig takten. Wie würde ich das in VHDL
machen? Wie ist es Platzeffizienter? In Schematic oder VHDL?
Bei Xilinx Spartan3's kann doch auch irgendwie eine Art Clockmanager
benutzen, oder?
Grüße und dank im voraus

: Gesperrt durch Moderator
von Neutron (Gast)


Lesenswert?

einfach ein signal inkrementieren, zähler.

von J. S. (engineer) Benutzerseite


Lesenswert?

Was platzsparender ist, hängt generell von der Art der Implementierung
ab. Das was Du humannah und einfach formulierst, kostet meist am
meisten Platz :-)

Einen Frequenzteile nur durch 2 realisiert man mit einem JK-FF.

von FPGA-User (Gast)


Lesenswert?

signal counter : integer range 0 to 2**8-1; -- 8 bit Zähler

process(rst, clk)
begin
   if rst='1' then
      counter <= 0;
   elsif rising_edge(clk) then
      counter <= counter +1; -- Bsp. einfach hochzählen
   end if;
end process;


Bitte keine Flip-Flop-Ausgänge auf den nächsten FF-Takteingang
legen. Asynchrone Designs sind was für ASIC-Freaks.

von Michael (Gast)


Lesenswert?

ok, der vhdl code ist klar. Aber wird der Zähler nicht im endeffekt auch
 in Form von asynchronen JKFF realisiert? Oder wie würde das
hardwaremäßig realisiert wenn es synchron sein soll?
Wie kann ich denn dann einzelne Zählerbits, die dann meinen gewünschten
Takt darstellen, als GlobalClock definieren? Mache ich das hinterher
über die constraints?
Danke erstmal - bin halt noch ein Einsteiger..

von FPGA-User (Gast)


Lesenswert?

@Michael

wie soll der Zähler mit "asynchronen" JK-FF realisiert werden,
wenn es weder welche gibt und die Beschreibung streng synchron
ist (alle FFs schalten mit einem Clock - clk ) ?

OK, für einzelne Zählerbits ist der Typ integer ungünstig,
nimm dafür std_logic_vector(MSB downto 0); für MSB setze
Bitbreite-1.
Dann nimm ein einzelnes Bit raus, z.B. counter(3) und lege
es als Clock auf einen globalen Buffer.

Du solltest aber nur 1 Bit als Clock verwenden, sonst bekommst
Du sog. Clock-Skew zwischen den Clocks und das ganze wird wieder
asynchron.

Für mehrere Takte sollten die DCMs verwendet werden (Digital
Clock Manager) - die sorgen dafür, dass alles synchron bleibt.

von Michael (Gast)


Lesenswert?

ok, habe da mal was zusammengebaut... Da ich ein Spartan2 als Ziel habe,
stehen mir die DCM's nicht zur Verfügung. Ich benötige in meinem Design
3 Takte: 10MHZ, 5MHZ und 125,25KHZ. Als Eingangstakt liegen 20 MHZ an.
Die 10MHZ und 5MHZ werden, je nach Modi, auf einen Output gelegt.
Ansonsten benötige ich die Takte für verschiedene andere HDL Sources.
Da ich Anfänger bin würde ich mich über Kritik oder
Verbesserungsvorschläge freuen. Der Taktgenerator soll auf jeden Fall
synchron sein - im Modelsim siehts gut aus:

entity counter is
    Port ( CLOCK : in std_logic;
           CLK10M : out std_logic;
        CLK5M : out std_logic;
        CLK125_25K : out std_logic);
end counter;

architecture Behavioral of counter is
signal count_int : std_logic_vector(0 to 6) := "0000000";
begin
process (CLOCK)
begin
   if CLOCK='1' and CLOCK'event
    then
         count_int <= count_int + 1;
      end if;
end process;

CLK10M <= count_int(6);
CLK5M <= count_int(5);
CLK125_25K <= count_int(0);
end Behavioral;

Wie ist das mit den Ressourcen? Ein asynchroner Zähler würde doch
weniger Ressourcen in Anspruch nehmen, oder?

von FPGA-User (Gast)


Lesenswert?

@Michael

1) Du kannst davon ausgehen, dass die Synthesetools das VHDL
optimal umsetzen, kein Grund asynchrone Designs zu machen

2) Im Modelsim sieht immer alles gut aus, wenn Du nur funktional
simulierst, d.h. ohne Hardware-Delays

2) bei synchronen Designs verwendet man z.B. Clock-Enable Signale,
um mit unterschiedlichen Takten zu arbeiten.
Beispiel 10 MHz / 5 MHz

Alles wird mit 10 MHz getaktet, Du generierst ein clk_ena mit 5MHz:

process(clk_10M)
begin
   if rising_edge(clk_10M) then
      clk_ena <= not clk_ena; -- f = 5 MHz
   end if;
end process;

Die Funktion, die mit 5 MHz laufen soll, sieht dann so aus :

process(clk_10M)
begin
   if rising_edge(clk_10M) then
      if clk_ena then -- 5 MHz Enable-Signal für alle FFs
         sig_y <= sig_x;
         ...
      end if;
   end if;
end process;

Ich würde mir gut überlegen, ob ich mir die Probleme mit 3 Clock-
Sinalen einhandeln möchte. Es wäre besser, alles mit einem Clock
zu machen, in den meisten Fällen geht das auch.

von FPGA-User (Gast)


Lesenswert?

Bei Spartan II hast Du übrigens alles, was Du für eine
ordentliche Taktaufbereitung brauchst:

DLLs !

Schau mal ins Datenblatt .

von Peter (Gast)


Lesenswert?

Hallo zusammen,

kann mir einer folgende Zeilen aus dem obigen Beispiel erklären:

...
signal count_int : std_logic_vector(0 to 6) := "0000000";
...
CLK10M <= count_int(6);
CLK5M <= count_int(5);
CLK125_25K <= count_int(0);
end Behavioral;
....

Ich verstehe die Zuweisungen nicht.

Warum benutzt man einen Bitvektor und nicht einfach einen Integer-Wert,
wie beim hochzählen ? Bitte aber auch um Erklärunfg der Bit-Lösung.

Gruß
Peter

PS: bin VHDL-Neuling...

von FPGA-User (Gast)


Lesenswert?

signal count_int : std_logic_vector(0 to 6) := "0000000";
-- das ist ein 7-bit breites Signal, also am Ende 7 Flip-Flops
...
CLK10M <= count_int(6);
-- das bit 6 von count_int wird als Signal CLK10M als einzelnes Bit
-- herausgenommen und kann damit als Taktsignal verwendet werden
CLK5M <= count_int(5);
-- s.o. nur für bit 5
CLK125_25K <= count_int(0);
-- s.o. für bit 0
end Behavioral;

warum kein Integer? Da tut man sich etwas schwerer, einzelne Bits
rauszulegen

von Henrik K. (henrik)


Lesenswert?

Anschaulich: Du hast einen 7 Bit Zähler vor dir liegen. Du nimmst nun
eine Leitung mit dem Namen "CLK10M" und verbindest sie mit Bit 6
deines Zählers. Gleiches machst du mit "CLK5M" und "CLK125_25M".

Du kannst auch einem Integer-Wert nehmen; damit du einzelne Bits
abnehmen kannst, musst du den Integer aber in einen std_logic_vector
umwandeln.
Die Umwandlung hat man sich hier einfach gespart, indem man gleich
einen std_logic_vector zum zählen genommen hat.
Beide Variante (müssen) bringen beim Umsetzen auf die Hardware das
gleiche Ergebniss; mit den Integer ist nur der Code etwas länger.

Folgender Code müsste identisch sein:

signal counter : integer range 0 to 2**8-1; -- 8 bit Zähler
signal Temp    : std_logic_vector (7 downto 0); -- Nur für die
Umwandlung, benötigt keine Hardwareressourcen

process(rst, clk)
begin
   if rst='1' then
      counter <= 0;
   elsif rising_edge(clk) then
      counter <= counter +1; -- Bsp. einfach hochzählen
   end if;
end process;

Temp<=conv_std_logic_vector(counter, 8);

CLK10M <= Temp(6);
CLK5M <= Temp(5);
CLK125_25K <= Temp(0);

Gruss Henrik

von Peter (Gast)


Lesenswert?

OK, das mit dem Zähler und den Bits herausnehmen habe ich schon
verstanden. Allerdings kapiere ich noch nicht, warum ich ausgerechnet
Bit 5 herausnehmen muss, um 5 MHz zu bekommen oder warum ich Bit 0
nehmen muss, um 125.25 kHz zu bekommen. Daran hapert es bei mir.
Vielleicht könnt ihr mir das noch erklären ? Vielleicht könnt ihr mir
das kurz vorrechnen


Und warum brauche ich im dem Fall einen 7-Bit Zähler ? 2 hoch 7 sind
128.....

Ich hoffe ich nerve nicht mit meinen einfachen Fragen, aber ich kapiere
es halt nicht. Hoffe ihr bleibt cool und könnt mir helfen...

Gruß Peter

von Henrik K. (henrik)


Lesenswert?

Also mein Zähler ist 8 bit breit, der von Michael ist 7 breit.
Michael hat den Vektor auch andersrum definiert (0 to 6), d.h. Bit 6
ist bei ihm das niederwertigste.
Er speisst 20 MHz ein und am niederwertigsten kommen dann 10 raus; das
ist bei ihm Bit 6!
20MHz/2^2 (entspricht Bit 5)=5MHz
Das mit den 125.25 KHz stimmt nicht! 20Mhz durch 2^7 (Bit 0) ist 156.25
KHz.

von Henrik K. (henrik)


Lesenswert?

Wobei mir da auffällt, das mein Code die Signale anden falschen Stellen
abgreife. Sorry! Ein kleiner Copy-and-Paste Fehler.

von Michael (Gast)


Lesenswert?

Für so viel Verwirrung wollte ich eigentlich nicht sorgen, sorry.
Aber jetzt ist ja alles gesagt.

von Peter (Gast)


Lesenswert?

OK, das mit dem Zähler und den Bits herausnehmen habe ich schon
verstanden. Allerdings kapiere ich noch nicht, warum ich ausgerechnet
Bit 5 herausnehmen muss, um 5 MHz zu bekommen oder warum ich Bit 0
nehmen muss, um 125.25 kHz zu bekommen. Daran hapert es bei mir.
Vielleicht könnt ihr mir das noch erklären ? Vielleicht könnt ihr mir
das kurz vorrechnen


Und warum brauche ich im dem Fall einen 7-Bit Zähler ? 2 hoch 7 sind
128.....

Ich hoffe ich nerve nicht mit meinen einfachen Fragen, aber ich
kapiere
es halt nicht. Hoffe ihr bleibt cool und könnt mir helfen...

Gruß Peter

von commander (Gast)


Lesenswert?

ich halte es für ein ausgesprochenes gerücht, dass sämtliche flip-flops 
taktflankengesteuert sind. es gibt auch pegelgesteuerte flip-flops, auch 
wenn diese in modernen fpgas nicht eingesetzt werden.

von date (Gast)


Lesenswert?

commander schrieb:
> ich halte es für ein ausgesprochenes gerücht, dass sämtliche flip-flops
> taktflankengesteuert sind. es gibt auch pegelgesteuerte flip-flops, auch
> wenn diese in modernen fpgas nicht eingesetzt werden.

und um das herauszufinden, hast du 7 Jahre gebraucht?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Und zudem ist die Behauptung auch noch falsch.

Ein pegelgesteuertes Flipflop heisst nämlich Latch

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.