Forum: FPGA, VHDL & Co. wie Flankenerkennung bei gemultiplextem Takt?


von Anfänger (Gast)


Lesenswert?

Hallo,

ich führe mehrere (externe) Taktquellen zu einem Multiplexer, welcher 
sich dann auf den jeweils aktiven Takt synchronisieren soll.

Die Taktumschaltung erfolgt jeweils aus dem Reset heraus, sodass 
Glitches und ähnliche Dreckeffekte eher untergeordnete Bedeutung haben.

Bei Altera wird erkannt, dass ein Takt gemultiplexed wird und es werden 
entsprechende Schutzkonstrukte generiert. Ich bekomme zwar eine Warnung, 
dass das Design evtl. nicht funktioniert, aber das RTL sieht (soweit ich 
das beurteilen kann) gut aus.

Bei Xilinx erhalte ich den Fehler, dass der Indexwert bei 
rising_edge(...) nicht konstant ist (was ja beabsichtigt ist).

Wie muss ich eine Flankenerkennung für einen gemultiplexten Takt bei 
Xilinx (in VHDL) formulieren, damit der Code übersetzt bzw. 
synthetisiert werden kann?

von Jan M. (mueschel)


Lesenswert?

Klingt so, als solltest du den Multiplexer explizit beschreiben und 
nicht direkt in rising_edge angeben.

Irgendwo gab es doch von irgendeinem Hersteller eine AppNote wie man 
Taktmultiplexer am sinnvollsten beschreibt, wenn sie nicht in 
dedizierter Hardware laufen sollen.

Ganz nebenbei, Takte zu multiplexen ist immer nur 3. Wahl - kannst du 
nicht mit Oversampling oder einem festen Takt arbeiten?

von Christian R. (supachris)


Lesenswert?

Bei Xilinx gibts BUFGMUX Elemente, die man instanziieren kann, 
vielleicht hilft dir das weiter. Dein Takt-Mux muss ja aber auch einen 
Ausgang haben, den kannst du doch als Bedingung für rising_edge() 
nehmen? Oder wie sieht das bei dir aus? Abgesehen davon, dass man 
Takt-Signale nur im äußersten Notfall muxt....

von Michael O. (mischu)


Lesenswert?

So ganz habe ich nicht verstanden, was Du mit synchronisieren meinst.
Ein Multiplexer multiplexed - der hat kein Synch sondern nur select 
Eingänge.
Was heisst "Der Indexwert ist nicht konstant"?  Poste mal die 
entsprechende Codestelle.

Der Ausgang deines Mux sollte tunlichts per BUFG auf ein globales 
Taktnetz gelegt werden (sonst versucht XST die Leitung normal zu 
routen).
Für Multiplexaufgaben des Taktes  gibt es den oben genannten BUFGMUX der 
meine ich 4:1 auswählen kann.

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


Lesenswert?

> dass der Indexwert bei rising_edge(...)
Du probierst sowas:
1
signal clk : sdt_logic_vector(3 downto 0);
2
:
3
   if rising_edge(clk(idx)) then...
Richtig?

Dann machs besser über die Instantiierung eines BUFGMUX, der als Eingang 
das gemultiplexte Signal erhält, und am Ausgang auf ein Taktnetz geht.


> Bei Altera ... eine Warnung, dass das Design evtl. nicht funktioniert,
> aber das RTL sieht (soweit ich das beurteilen kann) gut aus.
Der RTL-Schaltplan sagt noch gar nichts darüber aus, ob dein Design in 
ein FPGA passt. Der bedeutet nur, dass die Synthese Bauteile gefunden 
hat, die in etwa deiner Beschreibung entsprechen. Der RTL-Schaltplan 
wird auch für ein CPLD genau gleich aussehen. Ob Translate diesen Plan 
dann in "reale" FPGA-Bauteile übersetzen kann, das kommt erst später.

BTW:
Ich bin mir (immer noch) nicht sicher, ob du auf dem richtigen Weg bist 
;-)

von Anfänger (Gast)


Lesenswert?

Guten Morgen und herzlichen Dank für Eure Antworten!

> Ganz nebenbei, Takte zu multiplexen ist immer nur 3. Wahl - kannst du
> nicht mit Oversampling oder einem festen Takt arbeiten?

Ok, das Thema hatten wir in einem anderen Thread.
Deshalb schrieb ich externe Taktquellen. Die Taktquellen sind unabhängig 
vom Systemtakt.

> Für Multiplexaufgaben des Taktes  gibt es den oben genannten BUFGMUX der
> meine ich 4:1 auswählen kann.

Hm, habe mal das Handbuch des Spartan durchwühlt. Da wird zwar öfters 
von BUFGMUX geschrieben, aber ich fand keinen Hinweis, was ich beim 
Codieren beachten muss, damit ein solcher instantiiert wird.
Ach ja, laut Handbuch (Spartan-3) wählt ein BUFGMUX "nur" einen Ausgang 
aus 2 Eingängen.

> Du probierst sowas:
1
signal clk : sdt_logic_vector(3 downto 0);
2
:
3
   if rising_edge(clk(idx)) then...
> Richtig?

Völlig korrekt.
Da ich die Breite von clk über einen generischen Parameter festlege, 
weiß ich nicht, wie ich das anders formulieren soll.
Wenn der eine feste Breite hat, könnte ich ein Case-Konstrukt verwenden.

Lässt sich die Flankenabfrage über ein generate behandeln?
Mir fehlt noch der Zugang, wie ich diese Abfrage auscodieren kann und 
trotzdem "dynamisch", also in Abhängigkeit von dem generischen 
Parameter, bleiben kann.

> BTW:
> Ich bin mir (immer noch) nicht sicher, ob du auf dem richtigen Weg bist
> ;-)

Na, dann sind wir ja schon zu zweit :)

Ich musste feststellen, dass die Einarbeitung doch sehr schnell extrem 
komplex wird. Jedesmal ne Testbench stricken und die Signale überprüfen 
- puh - ist ein Haufen Schreibarbeit.
Allerdings entsteht so langsam auch ein Gefühl für die Materie und ich 
habe zumindest schon verstanden, wie ich Signallaufzeiten und glitches 
provozieren und testen kann. Also so ganz verkehrt wird der Weg nicht 
sein.

von Christian R. (supachris)


Lesenswert?

Anfänger schrieb:

> Hm, habe mal das Handbuch des Spartan durchwühlt. Da wird zwar öfters
> von BUFGMUX geschrieben, aber ich fand keinen Hinweis, was ich beim
> Codieren beachten muss, damit ein solcher instantiiert wird.

Instanziieren machst du selber. Solche Sachen können nicht inferriert 
werden.

> Ach ja, laut Handbuch (Spartan-3) wählt ein BUFGMUX "nur" einen Ausgang
> aus 2 Eingängen.

Dann musst du schachteln. Aber wenn ich mich recht erinnere, hattest du 
doch so schnarch-langsame Takte als Quelle, oder? Die kannst du 
wahrscheinlich mit einem normalen Mux über das normale Routing schicken.

Und auch noch mit generic und variabler Anzahl Takte? Hmm...also die 
eierlegende Wollmilchsau geht meistens schief....

von Klaus F. (kfalser)


Lesenswert?

Anfänger schrieb:
>> Du probierst sowas:
>
1
> signal clk : sdt_logic_vector(3 downto 0);
2
> :
3
>    if rising_edge(clk(idx)) then...
4
>
>> Richtig?
>
> Völlig korrekt.
> Da ich die Breite von clk über einen generischen Parameter festlege,
> weiß ich nicht, wie ich das anders formulieren soll.
> Wenn der eine feste Breite hat, könnte ich ein Case-Konstrukt verwenden.
>

So etwas wird meiner Meinung nach für die Synthese nicht funktionieren, 
da der Compiler nicht intelligent genug ist, einen Multiplexer vor den 
Takt zu schalten. Außerdem muß davon stark abgeraten werden.
Wenn Du das ganze unbedingt so willst, mußt Du das ganze selbst 
beschreiben:
Zuerst eine Komponente Multiplexer, diese liefert ein Signal ClkOut.

In das rising_edge statement kommt dann nur mehr ClkOut.
Die einzige saubere Variante für den Multiplexer ist die BUFGMUX 
Komponente, diese kann aber nur zwischen 2 Takten umschalten.

Aber nochmals, vom Umschalten zwischen beliebig vielen Takten kann nur 
abgeraten werden.
Als Anfänger und womöglich Softwerker denkt man am Anfang zu 
kompliziert. Einen gewisse Flexibilität der geschriebenen Module mittels 
Generics ist schon gut, aber letztendlich muß es zur verfügbaren 
Hardware passen.

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.