Forum: FPGA, VHDL & Co. Hold Time violation - was tun?


von Rolf E. (Firma: Appsys ProAudio) (roffez)


Lesenswert?

Ich habe hier ein FPGA-Design, wo mehrere Entities auf eine gemeinsame 
Tabelle zugreifen (alles intern im FPGA) - einige nur lesend, einige nur 
schreibend. Der Zugriff auf die Tabelle wird von einem 
Round-Robin-Scheduler gesteuert, der nacheinander die Adressdaten 
abfragt und den entsprechenden Tabelleninhalt (24 bit breit) 
zurückliefert.

Egal wie ich den Datenbus designe (shared oder dedizierte Leitungen zu 
den Lese-Entities, registered oder nicht), ich kämpfe immer mit 
Hold-Time-Violations - Setup slack ist reichlich da. Die Daten auf dem 
Bus müssen über den Chip verteilt an vielen Stellen verfügbar sein - 
irgendwie scheint das Problem damit zu tun zu haben...

Das gesamte System läuft synchron über eine 50MHz Clock in einem Altera 
EP4CE40.

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


Lesenswert?

Rolf E. schrieb:
> Egal wie ich den Datenbus designe
Es gibt keine Tristate-Busse in einen aktuellen FPGA. Wenn du also 
mehrere Teilnehmer hast, die auf eine Ressource zugreifen wollen, dann 
bekommst du zwingend Multiplexer an den Adressen und den Daten. Und wenn 
du viele "Teilnehmer" hast, dann bekommst du riesige und langsame 
Multiplexer.

> wo mehrere Entities auf eine gemeinsame Tabelle zugreifen (alles intern
> im FPGA)
Wie ist diese "Tabelle" realisiert? Als RAM-Block oder ist sie mit 
Logikzellen aufgebaut?

> Die Daten auf dem Bus müssen über den Chip verteilt an vielen Stellen
> verfügbar sein
Hast du dir schon mal den RTL-Schaltplan und den Technologie-Schaltplan 
angeschaut? Passt das, was du dort siehst, zu dem, was du mit VHDL 
beschrieben hast?

von Markus F. (mfro)


Lesenswert?

Rolf E. schrieb:
> ich kämpfe immer mit
> Hold-Time-Violations - Setup slack ist reichlich da. Die Daten auf dem
> Bus müssen über den Chip verteilt an vielen Stellen verfügbar sein -
> irgendwie scheint das Problem damit zu tun zu haben...

Ohne dein Design zu kennen, kann man nur sehr allgemeine Ausagen 
treffen.

Hold Time Timing Violations sind ja ein "Hase und Igel-Problem". "Hase" 
ist die Clock und "Igel" sind die Daten. Der Igel ist schon da, während 
der Hase (die Clock) noch hastet.

In einem sauberen, synchronen Design hat man an der Grenze zur maximalen 
Taktfrequenz meist eher mit Setup- als mit Hold-Violations zu tun, weil 
die Daten es im Vergleich zur Clock (die den Luxus der "Clock 
Netz-Autobahn" geniessen und keine kombinatorischen Delays kompensieren 
müssen) schwer haben, rechtzeitig anzukommen.

Wenn Du also Hold-Time Violations hast, hast Du (nochmal: bei einem 
sauber synchronen Design) eher ein Luxusproblem (deine Daten sind zu 
schnell im Verhältnis zum Takt), das sich mit ein bißchen "eigentlich 
unnötiger, zusätzlicher Kombinatorik" im Datenpfad lösen lässt.

Ich tippe aber eher darauf, dass das Design eben nicht sauber synchron 
ist und würde erst mal danach suchen (asynchrone Clocks, Clock Gating, 
ein Prozess auf der "falschen" Taktflanke, ...).

von Vancouver (Gast)


Lesenswert?

Ein großer Setup-Slack, aber dafür eine Holdtime-Violation, das 
bedeutet, dass das Zeitfenster, in dem die Daten stabil anliegen zu früh 
kommt (bezogen auf die aktive Clock-Edge).

Die Daten sind also nicht zu langsam, sondern der Takt kommt zu spät. 
Das klingt eher nach einem Problem mit dem Taktnetz. Hast irgendwo Logik 
auf den Taktleitungen (Clock-Gates, Clock-Muxer) oder verwendest gar ein 
normales Netz für den Takt? Eine PLL/DCM mit falschem Phase-Shift?

Probeweise könntest Du mal versuchen, im Ziel die Daten mit der 
umgekehrten Taktflanke zu samplen (also der fallenden vermutlich). Ist 
zwar nicht die bevorzugte Lösung, aber hilft vielleicht, das Problem zu 
analysieren.

von Rolf E. (Firma: Appsys ProAudio) (roffez)


Lesenswert?

Tatsächlich, jetzt dämmerts mir (und ich habe gestern nur die halbe 
Wahrheit erzählt, war schon spät): Es gibt zwei Clockdomains, und zwei 
Datenbusse. Jeder Busteilnehmer arbeitet umschaltbar auf zwei 
verschiedenen Clockdomains, dazu sind die Daten- und Clockleitungen 
gemultiplext.

Das wird so synthetisiert, dass die Clocknetze nur bis zum Mux auf der 
"Autobahn" laufen und danach über ein normales Netz. Vielleicht hilft 
es, wenn ich den Clockmux so nahe am Ziel wie möglich platziere?

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


Lesenswert?

Rolf E. schrieb:
> dazu sind die Daten- und Clockleitungen gemultiplext.
Wie?

von Rolf E. (Firma: Appsys ProAudio) (roffez)


Lesenswert?

Lothar M. schrieb:
> Rolf E. schrieb:
>> dazu sind die Daten- und Clockleitungen gemultiplext.
> Wie?


-- Kombinatorisches Muxing von Daten und Clock entsprechend der 
gewählten
-- Clockdomain
-- mclk_0, mclk_1 sind globale clocks (laufen auf Clocknetzen)

clk  <= mclk_0 when domain = 0 else mclk_1;
data <= data_0 when domain = 0 else data_1;

von Vancouver (Gast)


Lesenswert?

Rolf E. schrieb:
> Kombinatorisches Muxing von Daten und Clock entsprechend der
> gewählten

Dazu verwendest Du besser die Clockmuxer-Primitive. Die sind glitchfree, 
und der Ausgang wird auch wieder auf ein Taktnetz geroutet.

von Markus F. (mfro)


Lesenswert?

Clock Multiplexing mit

ALTCLKCTRL

Dem Timing Analyzer muss man allerdings zusätzlich (mit exclusive clock 
groups, z.B.) auch sagen, dass immer nur eine Clock zur Zeit "scharf" 
ist.

von Rolf E. (Firma: Appsys ProAudio) (roffez)


Lesenswert?

> Dazu verwendest Du besser die Clockmuxer-Primitive. Die sind glitchfree,
> und der Ausgang wird auch wieder auf ein Taktnetz geroutet.

>Clock Multiplexing mit
> ALTCLKCTRL

Hab ich probiert: Der Ausgang von ALTCLKCTRL muss auf ein Taktnetz 
gerouted werden, sagt der Fitter. Leider gibts davon nicht genügend 
(bräuchte ca. 30 extra Taktnetze).

>das sich mit ein bißchen "eigentlich unnötiger, zusätzlicher Kombinatorik" >im 
Datenpfad lösen lässt

Das wäre meine Lieblingsvariante. Weiss jemand, wie ich das hinbekomme? 
Versuche a la

data_1 <= data_in;
data_2 <= data_1;
data_out <= data_2;

werden konsequent wegoptimiert, obwohl ich das eigentlich via "attribute 
keep", "attribute noprune" etc. verboten habe und "duplicate logic 
removal" ausgeschaltet ist.

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


Lesenswert?

Rolf E. schrieb:
> (bräuchte ca. 30 extra Taktnetze)
Ist so ein Design tatsächlich beherrschbar?
Immer, wenn ich etwas "brauche", für das es keinen Hersteller gibt, 
frage ich mich, warum ich der Einzige mit diesem "Problem" bin... ;-)

von Markus F. (mfro)


Lesenswert?

Rolf E. schrieb:
> Hab ich probiert: Der Ausgang von ALTCLKCTRL muss auf ein Taktnetz
> gerouted werden, sagt der Fitter. Leider gibts davon nicht genügend
> (bräuchte ca. 30 extra Taktnetze).

Das will mir jetzt nicht so richtig einleuchten. Du hast >30 Clocks in 
deinem Design?

Vielleicht beschreibst Du uns noch mal ausführlich, was Du da eigentlich 
treibst.

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


Lesenswert?

Rolf E. schrieb:
> Versuche a la
> data_1 <= data_in;
> data_2 <= data_1;
> data_out <= data_2;
> werden konsequent wegoptimiert
Das ist ja auch keine "Kombinatorik", sondern nur eine Umbenennung eines 
Signals. Denn letztlich kann der Router den Pfad von data_in über data1 
und data2 nach data_out ja so "hintereinander" platzieren, dass 
dazwischen kein Elektron mehr Platz hat. Dann hat er seine Arbeit super 
gemacht!

"Unnötige" Logik ist z.B. ein weiterer Multiplexer, der allerdings auch 
nicht statisch auf einen bestimmten Wert "geschaltet" sein darf. Sonst 
fliegt zu Recht auch der raus.

> werden konsequent wegoptimiert, obwohl ich das eigentlich via "attribute
> keep", "attribute noprune" etc. verboten habe und "duplicate logic
> removal" ausgeschaltet ist.
Du drehst da an Schrauben, wo man normalerweise nie zu drehen hat. 
Bestenfalls für wilde Hacks oder partielle Probleme sind diese Schalter 
nötig.

Mir scheint, du hast da irgendein grundlegendes Designproblem...

von Rolf E. (Firma: Appsys ProAudio) (roffez)


Lesenswert?

Markus F. schrieb:
> Das will mir jetzt nicht so richtig einleuchten. Du hast >30 Clocks in
> deinem Design?

Nein, nur 2 Clocks. Aber 30 Entities die entweder mit der einen oder mit 
der anderen Clock betrieben werden, und einzeln umschaltbar sein müssen.


> Vielleicht beschreibst Du uns noch mal ausführlich, was Du da eigentlich
> treibst.


Das ist Teil eines Audio-Matrix-Switches, der 448x448 digitale 
Audiokanäle routen kann. Diese kommen über verschiedene Interfaces (z.B. 
MADI) mit je 64x64 Kanälen ins System bzw. wieder raus.

Die zwei verschiedenen Clocks braucht es, weil für die Audiodaten zwei 
Clockdomains zur Verfügung stehen. Jedes Interface kann dynamisch 
entweder der einen oder der anderen Domain zugeordnet werden.

Interfaces auf der selben Clockdomain kommunizieren direkt über besagten 
Bus; der Datenaustausch zwischen beiden Clockdomains erfolgt über einen 
Samplerate-Konverter (der allerdings nicht im FPGA implementiert ist, 
sondern in externer Hardware).

von Michael W. (Gast)


Lesenswert?

Lothar M. schrieb:
> Ist so ein Design tatsächlich beherrschbar?
> Immer, wenn ich etwas "brauche", für das es keinen Hersteller gibt,
> frage ich mich, warum ich der Einzige mit diesem "Problem" bin... ;-)

Ich glaube auch, er sollte nochmal überdenken, was er da baut! Ein 50MHz 
FPGA ist einfach nicht schnell genug, um soviele Eingangs-Domänen zu 
muxen. Man sollte es lieber einsynchronisieren und intern synchron 
muxen.

von Rolf E. (Firma: Appsys ProAudio) (roffez)


Lesenswert?

Markus W. schrieb:
> Lothar M. schrieb:
>> Ist so ein Design tatsächlich beherrschbar?
>> Immer, wenn ich etwas "brauche", für das es keinen Hersteller gibt,
>> frage ich mich, warum ich der Einzige mit diesem "Problem" bin... ;-)
>
> Ich glaube auch, er sollte nochmal überdenken, was er da baut! Ein 50MHz
> FPGA ist einfach nicht schnell genug, um soviele Eingangs-Domänen zu
> muxen. Man sollte es lieber einsynchronisieren und intern synchron
> muxen.

Nochmal: Es sind nur 2 Domänen. Die Challenge ist eher, dass es halt 
wahlweise die eine oder andere ist. Es ist definitiv auch 
beherrschbar, weil schon gebaut, geprüft, käuflich erwerbbar und für gut 
befunden:
https://appsys.ch/mvr-64

von Markus F. (mfro)


Lesenswert?

o.k., danke.

Hast Du jetzt einen dicken Clockmultiplexer gebaut, der jedem der 
Entities seine eigene Clock zuführt oder 30 kleine, die vor jedem dieser 
Entities die Umschaltung erlauben?

Stehen die Clocks in irgendeinem konstanten (Takt-) Verhältnis 
zueinander?

von Rolf E. (Firma: Appsys ProAudio) (roffez)


Lesenswert?

> Hast Du jetzt einen dicken Clockmultiplexer gebaut, der jedem der
> Entities seine eigene Clock zuführt oder 30 kleine, die vor jedem dieser
> Entities die Umschaltung erlauben?

Bis jetzt ist das ein dicker "30fach 2:1" Mux, jede Entity bekommt also 
entweder "clk_0" oder clk_1" und die Daten dazu synchron "data_0" bzw. 
"data_1". Weil nicht soviele Clocknetzwerke da sind, müssen sie über 
normale Signale getaktet werden - das ist auch kein Problem weil im 
Wesentlichen auf dieser Seite nur ein bisschen Bitschieberei getan 
werden muss.


> Stehen die Clocks in irgendeinem konstanten (Takt-) Verhältnis
> zueinander?

clk_0 und clk_1 nicht, die Domains sind völlig unabhängig voneinander - 
beide Takte kommen von verschiedenen externen Geräten.

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


Lesenswert?

Und jedes der 30 Module kann unabhängig von jedem anderen seinen Takt 
umschalten. Bzw. muss es können?
Oder laufen immer alle mit dem selben Takt? Oder wenigstens Gruppen 
davon?

von Rolf E. (Firma: Appsys ProAudio) (roffez)


Lesenswert?

Vancouver schrieb:

> Probeweise könntest Du mal versuchen, im Ziel die Daten mit der
> umgekehrten Taktflanke zu samplen (also der fallenden vermutlich). Ist
> zwar nicht die bevorzugte Lösung, aber hilft vielleicht, das Problem zu
> analysieren.

Top Idee - Getan, synthetisiert, getestet und für gut befunden! Timing 
bestens, Setup- und Holdslack ausgeglichen, was will man mehr. Made my 
day!

von Rolf E. (Firma: Appsys ProAudio) (roffez)


Lesenswert?

Lothar M. schrieb:
> Und jedes der 30 Module kann unabhängig von jedem anderen seinen Takt
> umschalten. Bzw. muss es können?
> Oder laufen immer alle mit dem selben Takt? Oder wenigstens Gruppen
> davon?
Ja, also rund 15 davon müssen unbedingt einzeln umschalten können, d.h. 
wahlweise aus clk_0 oder clk_1 betrieben werden. Die restlichen laufen 
entweder statisch immer auf der gleichen Clock oder werden in Gruppen 
umgeschaltet.

von Audiomann (Gast)


Lesenswert?

Rolf E. schrieb:
> https://appsys.ch/mvr-64

interessant: "Swiss Design Made in Germany". Was sagt uns das?

von Markus F. (mfro)


Lesenswert?

Rolf E. schrieb:
> Top Idee - Getan, synthetisiert, getestet und für gut befunden! Timing
> bestens, Setup- und Holdslack ausgeglichen, was will man mehr. Made my
> day!

Wenn's so funktioniert ist's ja bestens. Gratuliere.

von Vancouver (Gast)


Lesenswert?

Allerdings hast du jetzt immernoch das Problem der Glitches beim 
Umschalten, wenn du rein kombinatorische Muxer verwendest. Vielleicht 
spielt das bei Audio keine Rolle (wenn man es nicht hört), aber sicherer 
wäre es trotzdem, die Glitches zu vermeiden.

Es gab dazu mal ein richtig gutes Paper (von der SNUG, glaube ich), aber 
das finde ich nicht mehr. Vielleicht hilft die das hier weiter:

https://www.eetimes.com/techniques-to-make-clock-switching-glitch-free/#

von Rolf E. (Firma: Appsys ProAudio) (roffez)


Lesenswert?

Ja, das ist klar. Umgeschaltet wird aber niemals im Betrieb, sondern 
geht immer mit einem Reset einher (in der Regel wird das Gerät auch 
vorher umverkabelt - daher kein Problem).

von Christoph Z. (christophz)


Lesenswert?

Audiomann schrieb:
> interessant: "Swiss Design Made in Germany". Was sagt uns das?

Zitat der Firmenwebseite: "Our products are developed in Switzerland and 
manufactured by our long-term partner in Germany who is responsible for 
PCB and mechanical assembly, QA and logistics."

von Sigi (Gast)


Lesenswert?

Wenn du insgesamt nur 2 Takte hast, dann kannst du
ja die Tabelle spiegeln und so für jede Taktdomaine
eine Tabelle betreiben: alle Schreibzugriffe werden
je Domaine einsynchronisiert und per MUX (z.B. mit
Priorisierung) an die jeweilige Tabelle weitergeleitet.
(ein Schreibzugriff schreibt immer in beide Tabellen!)

Bei den Lesezugriffen sieht das MUXing einfacher aus:
hier muss nur entweder aus Tabelle 1 oder Tabelle 2
gelesen werden.

Und um Glitches zu vermeiden: Der Taktwechsel wird
per Handshaking betrieben. Daraus lässt sich einfach
ein Ready-Signal für Lese-Zugriffe ableiten, die
das Lesen absolut sicher macht. Schreibzugriffe sind
davon unabhängig.

Das ganze funktioniert ohne Tricks wie positive oder
negative Flanke nutzen etc.

von Rolf E. (Firma: Appsys ProAudio) (roffez)


Lesenswert?

Genau so ist es implementiert - zwei Tabellen, eine pro Clock. Aber der 
Tabellenzugriff ist gar nicht das Problem, wie ich jetzt gelernt habe.
Sondern dass die "Leserclock" nicht direkt eine globale Clock (aus einem 
Clocknetz) ist, sondern aus deren zwei gemultiplext ausgewählt wird. 
Diese gemuxte Clock wird nicht auf ein Clocknetz (weil zuwenig vorhanden 
sind), sondern als normales (zu langsames) Datennetzwerk geroutet.

Der Trick mit der fallenden Flanke sorgt quasi dafür, dass die Clock 
einen halben Zyklus schneller am Ziel ist, das geht genau auf. 
Setup-Violations bekomme ich trotzdem keine, weil null Kombinatorik 
dazwischen ist. Für diesen (und nur für diesen!) Pfad sieht es dann 
Setup-mässig so aus, wie wenn das Design mit 100MHz statt mit 50MHz 
laufen würde.

: Bearbeitet durch User
von Sigi (Gast)


Lesenswert?

Rolf E. schrieb:
> Diese gemuxte Clock wird nicht auf ein Clocknetz (weil zuwenig vorhanden
> sind), sondern als normales (zu langsames) Datennetzwerk geroutet.

Genau das ist der Fehler im Konzept. Für
meine Methode reichen zwei Clocknetze aus.

Jeder "Teilnehmer" kann lesen/schreiben sowie
den Takt auswählen (wenn dies nicht zentral
geschieht), die Signale dazu werden in die
jeweiligen Domainen einsynchronisiert und
steuern dann die Logik und erhalten ggf einen
Lesedatum zurück.

von Sigi (Gast)


Lesenswert?

Und was ich noch vergessen habe: für meinen
Ansatz brauchst du kein Clock-MUX, das MUXen
geschieht hier nur auf der Ausgabeseite.

von Rolf E. (Firma: Appsys ProAudio) (roffez)


Lesenswert?

Geht nicht, weil die Takte und damit die Daten auseinanderlaufen. Bei 
nominell 48kHz Abtastrate werden die Daten in der einen Clcokdomain  die 
Daten vielleicht mit  vielleicht 48.001 kHz erzeugt bzw. erwartet, 
während in Domäne 1 ein anderer Clockmaster den Takt angibt und 
vielleicht mit 47.999 kHz arbeitet.

Dadurch werden in jeder Clockdomain unterschiedliche Mengen an Daten 
(Samples) erzeugt bzw. erwartet, irgendwann gibt es buffer 
over/underruns aufgrund zuvieler oder fehlender Daten. Tontechniker 
kennen das: es äussert sich in periodischem Klicken im Signal.

von dfIas (Gast)


Lesenswert?

Dass die Verschiebung um einen halben Clock ausreicht, halte ich für 
Zufall. Das mag für das erste abgetastete Datenbit helfen. Sowie mehrere 
FF hintereinander mit einem Nicht-Clock-Netz betrieben werden, haben die 
dann untereinander das Hold-Problem.
Zu empfehlen wäre, mit einem einzigen und entsprechend höherem Clock zu 
arbeiten, z. B. 120 MHz. Dann den jeweiligen Eingangs-Clock und die 
Daten abtasten (letztere nach erkanntem 0-1-Wechsel des Clocks mit 
Verzögerung übernehmen oder umgekehrt). Erfordert allerdings einen 
eigenen Oszillator. Gibt es den oder wird auf die Eingangs-Clocks 
verwiesen?

von dfIas (Gast)


Lesenswert?

Hmm, MHz oder kHz? Dezimal- oder Tausenderpunkte? Audio sind doch kHz, 
oder?
In jedem Fall Clock UND Daten abtasten - keine Clock-Spielereien!

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Würde man das bei Audio nicht eher so machen, dass man den Eingang 
erstmal interpoliert auf eine höhere Sample-Rate bringt und dann mit der 
gewünschten Ausgangs-Sample-Rate wieder runtersampelt?

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.