Forum: FPGA, VHDL & Co. Rundungsprobleme mit Timing in der Simulation


von Matthias G. (mgottke)


Lesenswert?

Hallo zusammen,

in einer Simulation (RTL) muss ich verschiedene Timingeigenschaften 
überprüfen. Es sind in dem Design auch etliche Timer mit Generics 
enthalten, die über eine Library die Taktrate (CLK_SPEED_SYS) laden und 
daraus Zähler generieren um absolute Zeiten in wählbaren Zeiteinheiten 
zu generieren.

Das funktioniert im Design so weit auch gut, aber in der Simulation 
kommt es da zu Rundungsproblemen. Hier dazu ein Auszug aus der 
Testbench:
1
constant CLK_TIME   : time := 1000 ms / CLK_SPEED_SYS;
2
...
3
clk_proc: process
4
begin
5
   clk <= '1';
6
   wait for 0.5 * CLK_TIME;
7
   clk <= '0';
8
   wait for 0.5 * CLK_TIME;
9
end process;
Aus meinen 75 MHz (CLK_SPEED_SYS := 75000000) wird dann nämlich eine 
CLK_TIME von 13333 ps. Bei Absoluten Zeiten im ms-Bereich wird der 
Fehler dann schon relativ groß. Vor allem kann ich die Signalzeiten 
nicht mehr mit absoluten Werten vergleichen, welche ich innerhalb der 
Testbench messe.

Hat jemand eine Idee, wie ich dies lösen kann?

von Tobias (Gast)


Lesenswert?

Hallo Matthias,

ich hatte ein ähnliches Problem und es so gelöst. In der Simulation habe 
ich den Takt etwas erhöht, bis keine Rundungsprobleme mehr auftreten. 
Die Simulation lief dann einwandfrei.

Der Nachteil dabei ist aber, dass die Zeiten dann nicht mehr exakt mit 
den realen übereinstimmen.

Tobias

von Klaus F. (kfalser)


Lesenswert?

Warum mußt Du mit absoluten Zeiten arbeiten?
Ich würde die Testbench umstellen auf Zeitdifferenzen z.B. relativ zum 
Takt.

von Matthias G. (mgottke)


Lesenswert?

Absolute Zeiten benötige ich, da das Design in einer Echtzeitumgebung 
eingebunden ist. Dort gibt es absolute Zeiten die genau einzuhalten 
sind.

Zwischenzeitlich behelfe ich mir in der Simulation damit, dass ich nicht 
mehr die Zeiten messe (aufaddiere), sondern Takte Zähle. In einem streng 
synchronen Design ist das möglich. In dem Moment in dem ich dann die 
resultierende Zeit benötige, multipliziere ich die Takte mit einer 
Sekunde und dividiere anschließend durch die Taktrate. Dadurch fallen 
die Rundungsfehler weg, bzw. Summieren sich nicht mehr. Es entsteht 
maximal an der untersten Zeiteinheit (das sind jetzt bei mir 1fs) ein 
Rundungsfehler. Dieser ist dann zu vernachlässigen.

von Klaus F. (kfalser)


Lesenswert?

> Dort gibt es absolute Zeiten die genau einzuhalten sind.

Dir ist aber schon bewusst, dass ein Oszillator Toleranzen von 
vielleicht 100ppm hat? Das dürfte mehr sein als Dein Rundungsfehler.

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


Lesenswert?

> Dort gibt es absolute Zeiten die genau einzuhalten sind.
Und das funktioniert dann nicht mehr, wenn du statt 40000ps nur 39999ps 
wartest? Das sind harte Kriterien. Kältespray und Föhn her ;-)

von Matthias G. (mgottke)


Lesenswert?

Es geht mir nicht um die Quarzgenauigkeiten. Das stimmt, das kann man 
nicht einhalten. Trotzdem sollte das Design nominell erst mal generisch 
die "richtigen" Zeiten generieren.

Daher: Wenn ein Timer absolute Zeiten generieren soll, z.B. einen Puls 
von 1000 ms, und mit 75 MHz getaktet wird, dann sollte er in der 
Simulation auch genau 1000 ms lang (Sprich 75 Mio Takte) sein. Wenn nun 
im Design durch einen Fehler der Puls aber 75.000.001 Takt lange oder 
74.999.999 Takte lange ist, dann muss ich mein Design korrigieren. 
Schließlich will ich ja mit der Testbench mein Design testen.

Bei einem Takt weniger komme ich ja nur noch auf 0,99999998... Sekunden. 
Durch die Rundungsfehler in der Simulation bin ich auf ähnliche Werte 
gekommen, obwohl es exakt 75 Mio Takte waren. Eine Bewertung des Designs 
war also nicht möglich. Diesen Fehler wollte ich ausschließen. Deshalb 
Zähle ich nun Takte und löse die Zeitermittlung nun so:
1
in1_to_in2_time <= ((edge2_clks - edge1_clks) * 1 sec) / clk_speed_hz;
"in1_to_in2_time" ist vom Typ time, die anderen von Typ integer.
Zuvor hatte ich es so versucht:
1
in1_to_in2_time <= edge2_time - edge1_time;
Da war alles vom Typ time.

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

1
clk_proc: process is
2
begin
3
   clk <= '1', '0' after CLK_TIME * 0.5;
4
   wait for CLK_TIME;
5
end process clk_proc;

Der duty-cycle leidet dann zwar immer noch unter dem Rundungsfehler, 
aber die Periodendauer ist exakt.

Gruß
Marcus
http://www.doulos.com/

von Matthias G. (mgottke)


Lesenswert?

> Der duty-cycle leidet dann zwar immer noch unter dem Rundungsfehler,
> aber die Periodendauer ist exakt.

Leider klappt das mit der exakten Periodendauer nicht, denn der Fehler 
tritt schon in der Berechnung der CLK_TIME auf. Die ergibt nämlich bei 
der Division eine periodiesche Zahl.
1
constant CLK_TIME   : time := 1000 ms / CLK_SPEED_SYS;
Es könnte aber geringfügig genauer werden, da die Periode nur ein Mal 
gerundet wird.

von Christian R. (supachris)


Lesenswert?

Matthias G. wrote:

> Daher: Wenn ein Timer absolute Zeiten generieren soll, z.B. einen Puls
> von 1000 ms, und mit 75 MHz getaktet wird, dann sollte er in der
> Simulation auch genau 1000 ms lang (Sprich 75 Mio Takte) sein. Wenn nun
> im Design durch einen Fehler der Puls aber 75.000.001 Takt lange oder
> 74.999.999 Takte lange ist, dann muss ich mein Design korrigieren.
> Schließlich will ich ja mit der Testbench mein Design testen.

Das macht in meinen Augen keinen Sinn. Wenn du im Test eine kürzere Zeit 
erzeugen lässt, bei der du die Takt-Zyklen abzählen kannst, meinetwegen 
75, und das läuft sauber, wieso sollte es dann nicht mit 75 Millionen 
Zyklen sauber laufen?

von Matthias G. (mgottke)


Lesenswert?

Das läuft ja auch mit 75 Mio Zyklen sauber. Ich teste ja nicht mit 75 
Takzyklen, sondern mit den Zeiten, die ich in meinem Prozess brauche.
Parallel zu den vielen Timern im Prozess laufen ja auch noch andere 
Berechnungen, die in Bezug zu diesen Zeiten stehen. Da sollte die 
Taktanzahl schon stimmen.
Aus Anwendersicht werden nämlich absolute Zeiten Parametriert. Den 
Anwender interessiert es nicht ob da 75 MHz Taktrate oder 10 MHz 
Taktrate im FPGA laufen. Es müssen aber trotz allem die zeitlichen 
Bezüge zueinander stimmen.
Es kann sich ja auch im Laufe der Entwicklung herausstellen, dass 75 MHz 
zu schnell für den FPGA sind. Dann muss die Rate ev. verkleinert werden. 
Ev. kann aber auch mit höheren Taktraten gearbeitet werden. 75 MHz 
scheint mir aber bei einem Cyclon 3 im langsamsten Speedgrade 
realistisch. Abgesehen davon ist die Frequenz auch für den DDR2-RAM 
günstig.

von Matthias G. (mgottke)


Lesenswert?

Für alle die mal ein ähnlichen Konstrukt verwenden wollen so sollten man 
den von mit oben genannten Konstrukt:
1
in1_to_in2_time <= ((edge2_clks - edge1_clks) * 1 sec) / clk_speed_hz;
nicht verwenden, sondern folgenden:
1
in1_to_in2_time <= (real(edge2_clks - edge1_clks)) / (real(clk_speed_hz)) * 1 sec;
Bei größeren Integerwerten für die (edge2_clks - edge1_clks) geht das 
sonst schief.

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.