Forum: FPGA, VHDL & Co. synchronen 4MHz Takt aus 100MHz generieren


von Vicky M. (vicky_m)


Lesenswert?

Hallo alle zusammen,

ich habe ein FPGA-Board auf dem nur ein 100MHz ClK ist. Diesen Takt kann 
ich mittels eines Zählers ja zu meinem Wunschtakt umfunktionieren. Fast 
zu jedem.

Ich stehe vor dem Problem einen 4MHz Takt zu generieren. Ein 4MHz Takt 
benötigt einen Zähler mit 12.5 Zählschritten. Da nur Integer möglich 
sind, kann ich auf diese einfache Art und Weise keinen 4MHz Takt 
aufbauen.

Gibt es evtl. die Möglichkeit mittels 2MHz CLK und einer 
Taktverschiebung durch ein FF die 4MHz aufzubauen?

Jedoch frage ich mich ob, ich mit so einem 4MHz Takt das Tor zur 
Asynchronen Takt Hölle aufstoßen würde.

Darf man das so machen?

Wie macht man es richtig?

Beste Grüße
Vicky

von Martin O. (ossi-2)


Lesenswert?

Erzeuge doch einfach einen Takt bei dem die High-Zeit etwas von der 
Low-zeit verschieden ist (12:13). Wenn Dein Design immer an der einen 
Taktflanke getriggert wird, macht das nichts aus.

von Frank K. (fchk)


Lesenswert?

Viele FPGAs haben PLLs o.ä., mit denen man (fast) beliebige Frequenzen 
erzeugen kann.

Der Typ Deines FPGA-Boards und das verbaute FPGA sind ja geheim, oder? 
Daher musst Du selber die zugehörige Dokumentation lesen und verstehen.

fchk

von Vicky M. (vicky_m)


Lesenswert?

Frank K. schrieb:
> Viele FPGAs haben PLLs o.ä., mit denen man (fast) beliebige Frequenzen
> erzeugen kann.
>
> Der Typ Deines FPGA-Boards und das verbaute FPGA sind ja geheim, oder?
> Daher musst Du selber die zugehörige Dokumentation lesen und verstehen.
>
> fchk

Nein nein, überhaupt nicht. Es ist ein Nexys Board. Jedoch wollte ich 
die Taktgenerierung der 4MHz so simpel wie möglich halten.

Martin O. schrieb:
> Erzeuge doch einfach einen Takt bei dem die High-Zeit etwas von der
> Low-zeit verschieden ist (12:13). Wenn Dein Design immer an der einen
> Taktflanke getriggert wird, macht das nichts aus.

Das hört sich interessant an. Wie macht man den einen 12:13 Takt? 
Bekomme ich Probleme wenn ich diesen an ein Schieberegister anwende. 
Also das Schieberegister damit Takte?

(Bin noch neu in der VHDL Welt)

von Donni D. (Gast)


Lesenswert?

Eine PLL in sein System einzubauen dauert ungefähr 5 Minuten, ist also 
das einfachste was du machen kannst. Alles andere ist Fuckelei.

von Bedenkenträger (Gast)


Lesenswert?

Die 100 MHz durch 25 zu teilen ist wohl zu einfach.

von Vicky M. (vicky_m)


Lesenswert?

Bedenkenträger schrieb:
> Die 100 MHz durch 25 zu teilen ist wohl zu einfach.

Ich bin ja ein Anfänger aber ich muss ganz klar sagen, da stimmt was 
nicht in deinem Gedankenzug. Wenn ich 4MHz Takt generieren möchte, dann 
bedarf es 12.5 Zählschritte. Bei 25 Zählschritten bekomme ich einen 2MHz 
Takt.


Donni D. schrieb:
> Eine PLL in sein System einzubauen dauert ungefähr 5 Minuten, ist also
> das einfachste was du machen kannst. Alles andere ist Fuckelei.

Ok, gut. Dann werde ich wohl den Ansatz versuchen. Wonach suche ich im 
Netz dann. PLL Zähler? Oder hat mir jemand einen Gedankenanstoß, 
Beispiel usw. ?

von Wolfgang (Gast)


Lesenswert?

Vicky M. schrieb:
> Das hört sich interessant an. Wie macht man den einen 12:13 Takt?
> Bekomme ich Probleme wenn ich diesen an ein Schieberegister anwende.
> Also das Schieberegister damit Takte?

Das Schieberegister wird doch wohl immer mit der gleichen Flanke 
getaktet. Das Tastverhältnis ist da eher unkritisch.

von C. A. Rotwang (Gast)


Lesenswert?

Vicky M. schrieb:

>> Die 100 MHz durch 25 zu teilen ist wohl zu einfach.
>
> Ich bin ja ein Anfänger aber ich muss ganz klar sagen, da stimmt was
> nicht in deinem Gedankenzug. Wenn ich 4MHz Takt generieren möchte, dann
> bedarf es 12.5 Zählschritte. Bei 25 Zählschritten bekomme ich einen 2MHz
> Takt.

Wenn dir das Tastverhältnis egal ist, zahlst due von 0 bis 24, dann 
setzt du den Zähler zurück, den Takt erzeugst dann in etwa so

clk_neu <= '1' when cnt_q = 24 else '0';

 -> 4 MHz

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Vicky M. schrieb:
>
> ich habe ein FPGA-Board auf dem nur ein 100MHz ClK ist. Diesen Takt kann
> ich mittels eines Zählers ja zu meinem Wunschtakt umfunktionieren. Fast
> zu jedem.

Es hängt halt auch stark davon ab, was du für Erwartungen an deinen Takt 
hast. Soll dieser wirklich ein Clock Netz Treiben (egal ob global oder 
lokal), dann kann es unter Umständen unmöglich werden, mittels Zähler. 
In diesem Fall bist du mit einer PLL oder DCM am besten bedient, jeder 
noch so kleine FPGA hat da mittlerweile brauchbare Elemente integriert.

Willst du gar keinen richtigen Takt, sondern einfach nur ein 4 MHz 
Enable Signal, dann sollte es dich auch nicht stören, wenn der Duty 
Cycle nicht bei 50:50 liegt. Das kann dann z.B. auch ein Zähler sein, 
der auf 100 zählt und bei 0, 25, 50 und 75 für einen Taktzyklus dein 
Enable Signal auf High setzt. Duty Cycle wäre dann 1:25. In der Regel 
verwendet man diese Techniken um Lowspeed Schnittstellen wie I2C, SPI, 
UART, etc. zu realisieren.

von Vicky M. (vicky_m)


Angehängte Dateien:

Lesenswert?

Also damit ich villt mein Anliegen noch ein wenig besser verdeutlichen 
kann. Ich habe folgendes Schieberegister:
1
process(clk, test, enable, data_sync(2))                                                
2
          begin
3
              if rising_edge(clk) then
4
                  if test = '1' AND enable = '0' AND data_sync(2) = '0' then                                                                
5
                     sr <= load0;
6
                     count2 <= "00000";
7
                 elsif test = '1' AND enable = '0' AND data_sync(2) = '1' then                                                                     
8
                     sr <= load1;
9
                     count2 <= "00000";
10
                 elsif test = '1' AND enable = '1' AND data_sync(2) = '1'  then                                                                                        
11
                     sr <= load_s;
12
                     count2 <= "00000";
13
                 elsif test = '0' AND enable = '0' then  
14
                       if count = "01011" then                                               
15
                          count <= "00000";
16
                          sr <= '0' & sr(15 downto 1);
17
                       else
18
                          count <= count + 1;
19
                       end if;  
20
                 end if;
21
             end if;
22
    end process;

Das Seriell Out (sr) möchte ich mit 4MHz ausgeben. Nun brauche ich eben 
ein 4MHz Taktsignal, oder?

Kann ich auf so eine Anwendung ein unsymmetrisches Taktsignal verwenden?



Nachtrag: Bild wurde leider falsch formatiert. Das unterste Signal ist 
mein serieller Ausgang.

: Bearbeitet durch User
von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Ok, damit kann man arbeiten. ;)

Als erstes: Schmeiß mal bitte test, enable, data_sync(2) aus deiner 
Sensitivity List raus. Ich hoffe dir ist kalr warum. Falls nicht: 
Nochmal ein paar Grundlagen nachlesen.

Jetzt hängt es ein bisschen davon ab, was du genau realisieren willst. 
Im einfachsten Fall erstellst du dir einen weiteren Prozess, der nichts 
anderes macht als über einen Zähler dir ein 4 MHz Clock-Enable Signal zu 
generieren.

Im Prinzip sieht das doch shcon ganz gut aus. Ich persönlich würde vll. 
das 4 MHz enable Signal in einen extra Prozess machen (zumindest in der 
Lernphase).

Wenn dein Takt 100 MHz ist, dann würde sich z.B. folgendes anbieten:
1
ce_4MHz : process (clk)
2
    constant TICKS := 25;
3
    variable i : integer range 0 to TICKS-1 := 0;
4
begin
5
6
    if (rising_edge(clk)) then
7
8
        if (i = TICKS-1) then
9
            i := 0;
10
            ce <= '1';
11
        else
12
            i := i + 1;
13
            ce <= '0';
14
        end if;
15
16
    end if;
17
18
end process;

Damit kannst du dan in deinem letzten elsif Zweig dein Schieberegister 
raustakten:
1
                 elsif test = '0' AND enable = '0' then  
2
                       if ce = '1' then                                               
3
                          sr <= '0' & sr(15 downto 1);
4
                       end if;  
5
                 end if;

Es hängt natürlich noch davon ab was du genau machen möchtest. 
Wahrscheinlich bietet es sich an eine FSM zu schreiben, die in einem 
ersten Schritt die Daten lädt, dann die Daten raustaktet und dann in 
einen Ruhezustand geht bis zum nächsten Zyklus.

Die Möglichkeiten sind unendlich und welcher Weg der goldene ist, hängt 
stark von den Details ab. Aber prinzipiell kann man es erstmal so 
machen, wie du es beschrieben hast. Dein clk Signal ist ja dein 
symmetrisches 100 MHz Signal, damit kannst du jegliche Logik daraus 
bauen, die dich an dein Ziel bringt (unter der Bedingung, dass deine 
Toolchain mit deinem Code was anfangen kann).

Auch ein Nachtrag: Das Bild sieht doch ganz ordentlich aus. Gibt es 
etwas was dich an deinem seriellen Ausgang stört? Jedoch sind es nicht 
exakt 4 MHz, da dein Counter nur bis 24 zählen sollte.

: Bearbeitet durch User
von Bedenkenträger (Gast)


Lesenswert?

> constant TICKS := 25;

Aha. Also doch so einfach.

Nur weibliche Logik muss bis 12 einhalb zählen.

von C. A. Rotwang (Gast)


Lesenswert?

Vicky M. schrieb:

> Das Seriell Out (sr) möchte ich mit 4MHz ausgeben. Nun brauche ich eben
> ein 4MHz Taktsignal, oder?

Beschäftige Dich mal mit dem Begriffen "clock" und "clock enable":
Taktung FPGA/CPLD: Clock Enable
https://alteraforum.com/forum/showthread.php?t=754
Beitrag "Clock Enable, wie macht man's richtig?"
http://www.csit-sun.pub.ro/courses/Masterat/Xilinx%20Synthesis%20Technology/toolbox.xilinx.com/docsan/xilinx4/data/docs/xst/hdlcode8.html

Du brauchst nicht zwingenden einen zweiten (abgeleiteten 
Takt/derivated_clock) Takt wenn man ein clock enable, das den Takt 
"deaktiviert", hat.

Ohnehin sollte man eher wenig Taktsignale in einem Design verwenden und 
FPGA's bieten auch nur eine bgrenzte Anzahl von Taktverbindungskanälen 
an.

von Frank K. (fchk)


Lesenswert?

Vicky M. schrieb:
> Frank K. schrieb:
>> Viele FPGAs haben PLLs o.ä., mit denen man (fast) beliebige Frequenzen
>> erzeugen kann.
>>
>> Der Typ Deines FPGA-Boards und das verbaute FPGA sind ja geheim, oder?
>> Daher musst Du selber die zugehörige Dokumentation lesen und verstehen.
>>
>> fchk
>
> Nein nein, überhaupt nicht. Es ist ein Nexys Board. Jedoch wollte ich
> die Taktgenerierung der 4MHz so simpel wie möglich halten.

Lies das hier:

https://www.xilinx.com/support/documentation/user_guides/ug382.pdf

Du suchsts die DCMs (Digital Clock Managers).

fchk

von npn (Gast)


Lesenswert?

Bedenkenträger schrieb:
>> constant TICKS := 25;
>
> Aha. Also doch so einfach.
>
> Nur weibliche Logik muss bis 12 einhalb zählen.

Dass unter der einen Zeile, die du zitiert hast, noch weitere Zeilen 
stehen, hast du schon gesehen, oder etwa nicht? ;-)

von Vicky M. (vicky_m)


Lesenswert?

Bedenkenträger schrieb:
>> constant TICKS := 25;
>
> Aha. Also doch so einfach.
>
> Nur weibliche Logik muss bis 12 einhalb zählen.


:D



Tobias B. schrieb:
> Wenn dein Takt 100 MHz ist, dann würde sich z.B. folgendes anbieten:
> ce_4MHz : process (clk)
>     constant TICKS := 25;
>     variable i : integer range 0 to TICKS-1 := 0;
> begin
>
>     if (rising_edge(clk)) then
>
>         if (i = TICKS-1) then
>             i := 0;
>             ce <= '1';
>         else
>             i := i + 1;
>             ce <= '0';
>         end if;
>
>     end if;
>
> end process;

Vielen Dank für deinen Tipp. Ich bin diesen gerade am umsetzen.Jedoch 
verstehe ich die Zeile nicht:

variable i : integer range 0 to TICKS-1 := 0;

Ist das synthetisierbar?

Kann ich das irgendwie auch so schreiben:

signal i : integer ( 0 downto TICKS-1) := 0;

Beste Grüße

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


Lesenswert?

Vicky M. schrieb:
> Kann ich das irgendwie auch so schreiben:
> signal i : integer ( 0 downto TICKS-1) := 0;
Kannst du schon. Gibt halt einen Fehler...

Warum würdest du das denn eigentlich gerade SO schreiben wollen?

von Weltbester FPGA-Pongo (Gast)


Lesenswert?

Vicky M. schrieb:
> Nein nein, überhaupt nicht. Es ist ein Nexys Board. Jedoch wollte ich
> die Taktgenerierung der 4MHz so simpel wie möglich halten.

Die Nutzung der PLL, die ohnehin schwingt, WÄRE die einfachste Lösung.
Man teilt einfach durch 25 und nicht nur durch 12.5, um 8MHz zu haben, 
der dann toggelt (und das wirst du vorhaben).

Umgekehrt wäre ein enable zu emfehlen welches auch wieder mit 25 
geteilt werden könnte, da es mit 24:1 getaktet sein muss.

Du brauchst also weder für einen Takt noch einen Pseudotakt einen Teiler 
von 1:12.5

Was Du brauchst ist ein gutes Buch über synchrones design.

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Vicky M. schrieb:
>
> Ist das synthetisierbar?
>
> Kann ich das irgendwie auch so schreiben:
>
> signal i : integer ( 0 downto TICKS-1) := 0;
>
> Beste Grüße

Integer sind vom Typ Skalare. Wenn du mit downto kommst, beschreibst du 
Felder / Vektoren.

Ich empfehle mal ein Blick ins das Buck "The Designer's Guide to VHDL" 
von Peter Ashenden. Das erklärt super die VHDL Grundlagen und eignet 
sich auch später wunderbar als Nachschlagewerk.

Noch ein Nachtrag: Lass dich nicht von der Variablen stören, zu denen 
existieren viele Mythen in der FPGA Welt. Was ich dir ans Herz legen 
kann ist - Wenn du dir nicht sicher bis ob etwas synthetisierbar ist 
oder nicht, schau am besten in das entsprechende Handbuch. Solte das 
nicht weiterhelfen, dann probier es am besten aus und seh dir einfach 
die Synthese Resultate an. In deinem Fall geht es im Xilinx FPGAs, da 
kann ich dir aus Erfahrung sagen, dass sich Integer Variablen 
hervorrangend synthetisieren lassen (sowohl mit dem Synthesizer von ISE, 
als auch von Vivado). Wenn du dich jedoch noch unwohl und unsicher mit 
dem Umgang von Variablen fühlst, dann kannst du auch einfach einen 
Zähler mithilfe von Signalen machen. Wird genauso funktionieren. 
Allerdings wie Lothar bereits schreib: Nicht mit dem Syntax den du 
vorgeschlagen hast. ;)

Weltbester FPGA-Pongo schrieb im Beitrag #5416283:
> Die Nutzung der PLL, die ohnehin schwingt, WÄRE die einfachste Lösung.
> Man teilt einfach durch 25 und nicht nur durch 12.5, um 8MHz zu haben,
> der dann toggelt (und das wirst du vorhaben).

Das ist leider so nicht korrekt. Sofern der Takt nicht auf ein Clock 
Netz muss, wäre das eine sehr ungünstige Lösung. Wenn ich das Problem 
richtig verstanden habe, dann müssen einfach nur Daten serialisiert 
ausgegeben werden. Das in Logik zu realisieren ist deutlich unkomplexer.

Sollte man auch ein paar andere Randbedingungen haben wie 
Powereffizienz, kann eine zusätzliche PLL / DCM sogar das Killerargument 
schlechthin sein.

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


Lesenswert?

Tobias B. schrieb:
> In deinem Fall geht es im Xilinx FPGAs, da kann ich dir aus Erfahrung
> sagen, dass sich Integer Variablen hervorrangend synthetisieren lassen
Natürlich. Warum auch nicht?
Das Problem an den Variablen sind nicht die Variablen an sich, sondern 
das falsche Verständnis von Anfängern über sie...

Ein Signal oder eine Variable ist erst mal nichts, was irgendwie 
irgendeine Hardware darstellt. Erst aus der Beschreibung ergibt es sich, 
ob daraus ein Register oder Logik wird, oder ob alles wegoptimiert wird.

> Lass dich nicht von der Variablen stören, zu denen existieren viele
> Mythen in der FPGA Welt.
Dabei könnte es so einfach sein...
Siehe dazu den uralten und immer noch aktuellen 
Beitrag "Variable vs Signal"

: Bearbeitet durch Moderator
von Bedenkenträger (Gast)


Lesenswert?

Eine PLL/DCM/... braucht auch Zeit bis zum Lock. Bis dahin
muss die Zaehlmimik sich gedulden was zusaetzlichen Aufwand
in der Beschreibung erfordert.

Der Inputclock sollte nach der FPGA-Konfiguration aus dem
Configflash aber schon stabil und benutzbar sein.

Einem SR-Takt ist es egal ob der ein 50 % Dutycycle sieht.

Die einfachste Variante ist da wohl doch die beste.

Ganz wissenschaftlich koennte man auch eine FSM mit 25
Zustaenden verwenden und bei genau einem State, welcher
ist uebrigens egal, das Austakten durchfuehren.

Da werden die Ergebnisse dann alle 250 ns rauspurzeln...

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Lothar M. schrieb:
> Tobias B. schrieb:
>> In deinem Fall geht es im Xilinx FPGAs, da kann ich dir aus Erfahrung
>> sagen, dass sich Integer Variablen hervorrangend synthetisieren lassen
> Natürlich. Warum auch nicht?
> Das Problem an den Variablen sind nicht die Variablen an sich, sondern
> das falsche Verständnis von Anfängern über sie...
>
> Ein Signal oder eine Variable ist erst mal nichts, was irgendwie
> irgendeine Hardware darstellt. Erst aus der Beschreibung ergibt es sich,
> ob daraus ein Register oder Logik wird, oder ob alles wegoptimiert wird.

Da bin ich absolut bei dir. Ich kenne jedoch nur die Synthese Werkzeuge 
von Xilinx und Lattice. Daher möchte ich jetzt nicht pauschal behaupten, 
dass alle anderen bei der Synthese korrekt mit Variablen umgehen.

Lothar M. schrieb:
>
>> Lass dich nicht von der Variablen stören, zu denen existieren viele
>> Mythen in der FPGA Welt.
> Dabei könnte es so einfach sein...
> Siehe dazu den uralten und immer noch aktuellen
> Beitrag "Variable vs Signal"

Diese Mythen sind wirklich wie ein Krebsgeschwür. Mein Favorit: 
"Variablen müssen grundsätzlich vermieden werden, weil man nicht weiß 
was das Synthesewerkzeug macht.". Hab ich sinngemäß so schon in 
Publikationen gelesen die sich Fachbücher schimpfen (vielleicht war so 
eine Aussage vor 20 Jahren ja auch mal korrekt, keine Ahnung).

Leider muss ich immer wieder feststellen, dass dadurch eine große 
Unsicherheit bei Anfängern besteht, da gerade diese erstmal alles 
unreflektiert aufsaugen und wiedergeben. :-(

von M. Н. (Gast)


Lesenswert?

Tobias B. schrieb:
> Mein Favorit:
> "Variablen müssen grundsätzlich vermieden werden, weil man nicht weiß
> was das Synthesewerkzeug macht."

Ich verwende Variablen mittlerweile nur noch ungern, da ich häufiger 
genau diese Erfahrung mit Lattice gemacht habe. Altera und Xilinx 
machten bis jetzt keine Probleme.

Ich hatte eine Ethernet MAC in VHDL geschrieben. Diese hat einen Zähler, 
der als Variable implementiert ist und ein Schieberegister steuert, dass 
die 2 bit Pakete des RMII Interfaces in Bytes zusammenpackt. Lattice hat 
mir diesen Zähler einfach rausoptimiert und auf den Wert 1 
festgeklemmt... Dadurch ist in der weiteren Synthese alles 
zusammengeklappt und sämtliche Statemachines + nachfolgende Module 
wurden wegoptimiert. Das einzige, das vom Design übrig blieb, war der 
Reset-Synchronizer.

Nach einiger Zeit Fehlersuche habe ich das ganze als Signal 
implementiert und gut war's. Auf Altera lief alles von Anfang an.
Mittlerweile läuft der Code mit Variable auch wieder auf Lattice (seit 
Diamond 3.10).

von Vicky M. (vicky_m)


Lesenswert?

Also ich muss mich doch nochmal melden.

beim implementieren deines Codes gab es immer einen Fehler, aufgrund das 
ich sehr wahrscheinlich nicht alles 100% verstanden habe. Somit habe ich 
versucht zu verstehen was du gemacht hast und diesen übersetzt:
1
  process (clk)                                                                               
2
       begin
3
          if rising_edge(clk) then
4
              if start = '1' then
5
                  if count = "11000" then
6
                     count <= "00000";
7
                     clk_shift <= '1';
8
                  else
9
                     count <= count + 1;
10
                     clk_shift <= '0';
11
                end if;
12
            end if;
13
        end if;
14
    end process;
Und in das eingefügt:
1
elsif TAKT_NF  = '0' AND enable_st = '0' then  
2
                        if clk_shift = '1' then
3
                            sr <= '0' & sr(15 downto 1);
4
                         end if;
5
                 end if;

Problem ist das, was ich schon hatte. Ich habe ein high von 250ns und 
ein low von 250ns. Was wiederum ein 2MHz Signal ist.

Ich wollte aber 125ns high und 125ns low. Deshalb muss ich ja auch auf
12.5 Zählen.

Warum möchte ich ein 4Mhz Signal: Ich möchte meine Bits alle 250ns
herausschreiben. Das geht aber nur wenn ich entweder alle 125ns auf die
steigende Flanke oder alle 250ns auf fallende und steigende Flanke
schiebe.

Nun gibt es zwei Möglichkeiten, entweder habe ich deinen Code nicht
richtig verstanden oder ich habe mein Problem falsch erklärt!

Nun ist die Frage wie am Anfang. Wie kann ich dies bewerkstelligen?

Idee: Wie oben schon erwähnt die Bits mit der fallende und steigende
Flanke vom 2Mhz Signal heraus schubsen.

: Bearbeitet durch User
von Patrick B. (p51d)


Lesenswert?

Vicky M. schrieb:
> Problem ist das, was ich schon hatte. Ich habe ein high von 250ns und
> ein low von 250ns. Was wiederum ein 2MHz Signal ist.

Von welchem Signal sprichst du?
Gemäss deinem Code sehe ich keines, dass symmetrisch sein sollte.

von Bedenkenträger (Gast)


Lesenswert?

Wenn man ein alternierendes Signal mit 4 MHz herausschiebt
hat das herausgeschobene natuerlich nur 2 MHz...

Ist doch logisch.
1
_____-----_____----- := Periode 500 ns 2 MHz
2
^    ^    ^    ^
3
0    250  500  1000  := 4 MHz

von M. Н. (Gast)


Lesenswert?

Patrick B. schrieb:
> Vicky M. schrieb:
>> Problem ist das, was ich schon hatte. Ich habe ein high von 250ns und
>> ein low von 250ns. Was wiederum ein 2MHz Signal ist.
>
> Von welchem Signal sprichst du?
> Gemäss deinem Code sehe ich keines, dass symmetrisch sein sollte.

Richtig.
1
if count = "11000" then
2
                     count <= "00000";
3
                     clk_shift <= '1';
4
                  else
5
                     count <= count + 1;
6
                     clk_shift <= '0';
7
                end if;

Das generiert einen Strobe mit einer Pulslänge von einem Takt, nachdem 
der Zähler "11000" erreicht. In jedem anderen Takt wird das Signal auf 
'0' gesetzt.

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Vicky M. schrieb:
>
> Ich wollte aber 125ns high und 125ns low. Deshalb muss ich ja auch auf
> 12.5 Zählen.
>
> Warum möchte ich ein 4Mhz Signal: Ich möchte meine Bits alle 250ns
> herausschreiben. Das geht aber nur wenn ich entweder alle 125ns auf die
> steigende Flanke oder alle 250ns auf fallende und steigende Flanke
> schiebe.

Ok, dann hab ich hier vielleicht ein Missverständnis. Ich hatte dein 4 
MHz Signal als einen beliebigen seriellen Datenstrom mit 4 Mbit/s 
interpretiert. D.h. jedes Bit ist genau für 250 ns High oder Low. Das 
nennt sich übrigens NRZ (Non-Return to Zero) Kodierung.

Das was du beschreibst wäre ein RZ (Return to Zero) kodiertes Signal. 
Das wird meiner Erfahrung nach relativ selten benötigt, wenn du kurz 
beschreiben könntest was dein Ziel ist, würdest du helfen weitere 
Missverständnisse vorzubeugen.

>
> Nun gibt es zwei Möglichkeiten, entweder habe ich deinen Code nicht
> richtig verstanden oder ich habe mein Problem falsch erklärt!
>
> Nun ist die Frage wie am Anfang. Wie kann ich dies bewerkstelligen?
>

Ne, du hast das schon richtig verstanden, aber wir haben vielleicht ein 
Missverständnis. :(

Daher die jetzt alles entscheidende Frage: Was möchtest du genau 
realisieren?

1.) Ein beliebiges Datenwort mit 4 MHz NRZ ausgeben?
2.) Ein beliebiges Datenwort mit 4 MHz RZ ausgeben?
3.) Einen Takt mit 50:50 Duty Cycle mit 4 MHz ausgeben?

Variante 1.) ist die Lösung die du gerade hast. Variante 3.) würdest du 
über eine PLL/DCM und einen ODDR Buffer.

Nachtrag: Die Lösung die ich hier hingeklatscht habe war Blödsinn hoch 
10.

> Idee: Wie oben schon erwähnt die Bits mit der fallende und steigende
> Flanke vom 2Mhz Signal heraus schubsen.

Das geht bei Xilinx mit einem ODDR Buffer. Du könntest einen der beiden 
Dateneingänge Eingänge (z.B. D1) fix auf '0' setzen. Ist im nachhinein 
betrachtet vielleicht sogar die einfachste Lösung, sofern dein FPGA ODDR 
Buffer unterstützt. ;)

: Bearbeitet durch User
von Vicky M. (vicky_m)


Lesenswert?

Tobias B. schrieb:
> 2.) Ein beliebiges Datenwort mit 4 MHz RZ ausgeben?

Genau das ist mein Vorhaben. Ich möchte ein Datenwort mit einem Takt von 
4MHz ausgeben. Eben da gibt es nur eine Möglichkeiten da 12.5 
Zählschritte nicht machbar sind.

Idee 1.)
Von einem 2MHz Signal die steigende und fallende Flanke delektieren. 
Daraus zwei Hilfssignale generieren die versetzt sind und mit XOR 
verknüpft ein 4MHz Signal ergeben
1
 process (clk)                                                                               
2
   begin
3
      if rising_edge(clk) then
4
          if start = '1' then
5
             if count = "11000" then
6
                count <= "00000";
7
                    a <= not a;
8
             else
9
                count <= count + 1;
10
                end if;   
11
         end if;
12
       end if;
13
  end process;
14
       
15
  process begin                                                       
16
    wait until rising_edge(clk); 
17
         irq <= irq(1 downto 0) & a;                                          
18
         if irq(1 downto 0) = "01" then 
19
            b <= '0';
20
            c <= '1';
21
         end if;
22
         if irq(1 downto 0) = "10" then                               
23
            b <= '1';
24
            c <= '0';
25
         end if;
26
  end process;

Kann man meine Idee so umsetzen? Bekomme ich auf dem Board damit 
Probleme? Ich handel mir jedoch dadurch eine Verzögerung um einen Takt 
ein aufgrund des Flipflops. Wie kann ich meine ganzen design dann gleich 
verzögern?

So habe ich zwei Variablen a und b, die zusammen eine steigenden Flanke 
mit 4MHz haben.

Ist die Idee gut? Oder eben nur gepfuscht? Wie würdet Ihr das machen. 
Ich bin Dankbar um Beispiele da ich nur anhand der lernen kann wie man 
es richtig tut.

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


Lesenswert?

Vicky M. schrieb:
> So habe ich zwei Variablen a und b
Ich sehe im geposteten Code keine Variablen...

> Kann man meine Idee so umsetzen?
Wenn man es unbedingt umständlich machen will, dann schon.
1. Warum machst du eine Flankenerkennung auf ein Signal, das mit einem 
Zähler erzeugt wird?
2. Warum erzeugst du nicht einfach direkt mit einem Zähler das Signal b 
und schreibst du dann nicht einfach:
c <= not b;

Wenn du 100 MHz Taktfrequenz hast, dann nimm doch einfach einen Zähler 
von 0 bis 24. Und wenn der überläuft, dann gibst du einfach das nächste 
Bit aus. Denk einfach mal über den folgenden Satz nach: du brauchst 
gar keinen Takt mit 4 MHz (auch wenn du ihn unbedingt willst ), 
sondern du brauchst nur ein Clock-Enable mit 4 MHz.

Vicky M. schrieb:
> Ist die Idee gut? Oder eben nur gepfuscht?
Du drehst dich immer und immer im selben Kreis.

> Wie würdet Ihr das machen. Ich bin Dankbar um Beispiele
Sieh dir an, wie ich das Weiterschalten dort beim Lauflicht mache:
http://www.lothar-miller.de/s9y/archives/61-Lauflicht.html
Es gibt in diesem Design nur 1 Takt. Und es gibt das Clock Enable für 
den nächsten Schritt. Überlege mal  wie dir das weiter helfen könnte.

: Bearbeitet durch Moderator
von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Das Problem sind einfach, dass hier ein Signal RZ kodiert ausgegeben 
werden soll (auch wenn ich bisher immer noch bezweifle, dass die 
Anwendung dies erfordert, aber ok). Bei 4 Mbit/s muss man wenn man RZ 
will, irgendwie die Bits mit 8 MHz toggeln können.

Da immer noch nicht der FPGA Typ genannt wurde, 2 Vorschläge:

1.) Zähler von 0 bis 24 und dann mit einem Duty Cycle von 12:13 oder 
13:12 arbeiten.

2.) Mit zwei Prozesses arbeiten, einer der auf steigender und einer der 
auf fallender Flanke arbeitet und die Resultate kombinatorisch 
Verknüpft. Damit kommst du auch auf den 12.5 Teiler, handelst dir aber 
jede Menge andere Probleme ein.

3.) ODDR Buffer in Kombination mit einer DCM/PLL (hängt hier halt ab, 
was für Möglichkeiten der FPGA bietet).

Ich schlag vor, dass du einfach mal alle Möglichkeiten durchprobierst 
und dann das zufriedenstellenste Ergbniss nimmst. Simulieren und 
Synthetisieren kannst du ja schon.

Aber wie Lothar schon schrieb: Das ganze dreht sich hier im Kreis und so 
langsam wird es auch anstrengend (zumindest für mich).

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


Lesenswert?

Tobias B. schrieb:
> Bei 4 Mbit/s muss man wenn man RZ will, irgendwie die Bits mit 8 MHz
> toggeln können.
Dann nehme ich einen Taktmanager (DCM, PLL, DLL oder wasauchimmer) und 
erzeuge aus den 100MHz z.B. 80MHz oder 40MHz oder 160MHz und dann wirds 
wieder einfach mit dem Teiler. Das Gebastel mit der Kombinatorik und den 
steigenden und fallenden Flanken ist viel zu wackelig...

von Vicky M. (vicky_m)


Lesenswert?

@Lothar Miller:

Ich werde versuchen dein Vorschlag zu verstehen und umzusetzen in meinem 
Design. Sobald ich das getan habe werde ich den Code hier präsentieren 
und hoffe das ich es korrekt umgesetzt habe.

Vielen Dank dir.

@Tobias:

Auch dir vielen Dank für deine Hilfestellungen und Tipps. Ich habe oben 
geschrieben das es sich um ein Nexys Board handelt, somit dachte ich es 
wäre klar das darauf ein Xilinx Artix-7 FPGA XC7A100T-1CSG324C verbaut 
wäre. Wollte nichts verheimlichen.

Ich melde mich sobald ich wie oben erwähnt eure Tipps und Ratschläge 
umgesetzt habe.

Viele Grüße

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Lothar M. schrieb:
> Tobias B. schrieb:
>> Bei 4 Mbit/s muss man wenn man RZ will, irgendwie die Bits mit 8 MHz
>> toggeln können.
> Dann nehme ich einen Taktmanager (DCM, PLL, DLL oder wasauchimmer) und
> erzeuge aus den 100MHz z.B. 80MHz oder 40MHz oder 160MHz und dann wirds
> wieder einfach mit dem Teiler. Das Gebastel mit der Kombinatorik und den
> steigenden und fallenden Flanken ist viel zu wackelig...

Full ACK. Hatte ich auch so geschrieben, dass das nicht unbedingt zu 
empfehlen ist. Aber man darf ja mal alle Möglichkeiten offerieren. ;)

Vicky M. schrieb:
> Auch dir vielen Dank für deine Hilfestellungen und Tipps. Ich habe oben
> geschrieben das es sich um ein Nexys Board handelt, somit dachte ich es
> wäre klar das darauf ein Xilinx Artix-7 FPGA XC7A100T-1CSG324C verbaut
> wäre. Wollte nichts verheimlichen.

Ich kenne die Nexys Boards nicht. Bei FPGA Fragen am besten immer den 
Typ mit angeben, das hilft am meisten. Aber alle 3 Vorschläge sind mit 
einem Artix 7 realisierbar. Daher passt das soweit.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.