Hallo zusammen,
ich fange gerade mit Verilog an und wollte einen "einfachen" Counter
simulieren. Anscheinend ist das aber nicht so einfach wie gedacht. (Das
ist es doch meistens) Anbei mal mein HDL:
1
module verilog_test(
2
input clk,
3
output [0:3]count);
4
5
reg [0:3] c;
6
7
always @(posedge clk)
8
begin
9
c<=c+1;
10
end
11
12
assign count=c;
13
14
endmodule
Quartus 7.2 macht daraus, wie erwartet, einen Addierer mit nachfolgendem
Register. Jetzt gibt es aber das Problem, daß in der Simulation Glitches
auftauchen. Beim Wechsel von einem Zählerwert zum nächsten treten
kurzzeitig andere Zählerwerte auf. Das kann ich auch nicht dadurch
verhindern, daß ich am Zählerausgang noch ein weiteres Register einfüge,
daß ich mit einer fallenden Flanke takte. Meine Frage lautet jetzt:
Wie kommen die Glitches zustande? (Wahrscheinlich Laufzeitunterschiede
im FPGA?!?) Und viel wichtiger: wie kann ich sie vermeiden? Mich wundert
es, daß die Laufzeitunterschiede hinter dem Register auftreten. Sollte
Quartus die Register nicht nahe beieinander legen, daß die Unterschiede
minimal bleiben?
Schonmal Danke für euere Antworten.
Gruß,
SIGINT
Sigint 112 schrieb:> Mich wundert es, daß die Laufzeitunterschiede hinter dem Register> auftreten.
Du machst eine Timingsimulation und du siehst hier Glitches im Sub-ns
Bereich. Das sind offenbar Routing-Delays. Immerhin hat schon der Takt
eine Verzögerung von einigen ns.
Meine Empfehlung: mach eine Verhaltenssimulation und gibt sinnvolle
Constraints vor. Dann wirst du die Timingsimulation nie brauchen oder
vermissen...
> Mich wundert es, daß die Laufzeitunterschiede hinter dem Register> auftreten.
Die Glitches sind normal. Und die Signale müssen erst rechtzeitig vor
dem nächsten Takt stabil anliegen...
Sigint 112 schrieb:> Wie kommen die Glitches zustande?
Dadurch, dass nicht alle 8 Register des Zählers exakt gleichzeitig
schalten
Sigint 112 schrieb:> wie kann ich sie vermeiden?
Gar nicht!
Und es gibt auch keinen Grund, diese vermeiden zu wollen.
Darum baut man synchrone Designs, in denen die Signale immer nur zur
Taktflanke gültig sein müssen (und dazwischen glitchen können).
Vielen Dank für die Antworten. Ich hatte noch vergessen zu sagen, daß es
mir erstmal nur um das Verstehen der Problematik geht. :-) Ich versuche
schon seit einiger Zeit, ohne großen Erfolg, mich in FPGAs
einzuarbeiten.
Nochmal zur Problematik: Intern kann ich ja alles schön synchron
aufbauen. Wenn ich aber mehrere Signale nach aussen weiterreichen möchte
und dort nicht synchron weiterarbeiten kann, wie kann ich sicherstellen,
daß die Signale keine Glitches enthalten? Nur so hyptothetisch
betrachtet.
Oder ist das einfach nicht machbar?
Gruß,
SIGINT
Sigint 112 schrieb:> Wenn ich aber mehrere Signale nach aussen weiterreichen möchte> und dort nicht synchron weiterarbeiten kann, wie kann ich sicherstellen,> daß die Signale keine Glitches enthalten? Nur so hyptothetisch> betrachtet.
Wenn du intern einen Takt hast und dann die Signale, die "nach draussen
gehen" sauber ueber FlipFlops in deinem FPGA fuehrst, dann bist du
erstmal sauber (und glitchfrei). Das Problem hat dann eventuell 'der
andere', der diese Signale empfangen muss...
@berndl:
Aber da liegt mein Problem ja: Der Bus "count" ist ja am Ausgang des
Registers, das von dem internen Takt getriggert wird. Trotzdem hab ich
hinter dem Register Glitches, wahrscheinlich durch die Positionierung
der FFs. Na ist auch egal... ich ignorier das erstmal und schau, ob
meine Designs trotzdem laufen.
Gruß,
SIGINT
Wenn du dir die einzelnen Signale deines Counters ansehen würdest, dann
glitcht davon keins. Aber weil die Signale zu leicht unterschiedlichen
Zeiten umschalten "glitcht der Zählerstand als Ganzes".
Solche minimalen Laufzeitunterschiede sind unvermeidbar, die
nachgeschaltete Logik darf auf den kurzzeitig falschen Zählerstand halt
nicht kritisch reagieren.
Die Signale schalten ja auch nicht beliebig schnell um sondern brauchen
eine Zeit, um vom einen Logikpegel zum anderen zu kommen. Deine
nachgeschaltete Logik muss ja auch damit klarkommen, dass während des
Umschaltens für kurze Zeit keine definierten Pegel anliegen.
Dieses Problem hast du immer und es ist unvermeidbar.
Da der Zähler als "Ganzes" zu betrachten ist, und die Register (selbst
wenn sie alle am Ausgang sitzen) nie exakt gleichzeitig schalten, wirst
du immer kurzzeitig Zählerstände erhalten, die ungültig sind.
Das ist auch nichts anderes, wenn du z.B. einen Controller hast und an
dessen Adress/Daten-Bus ein RAM anschließt. Auch hier sind die Adressen
oder die zu schreibenden Daten niemals zu jedem Moment gültig.
Bei einem Controller wird das dann z.B. für das angeschlossene RAM so
gelöst, dass die Datenübernahme zB mit dem WR-Signal erfolgt. Dieses
wird erst dann erzeugt, wenn die Daten am Ausgang definitiv stabil sind.
Und der RAM übernimmt die Daten dann nur mit dem WR-Signal.
Für die nachgeschaltete Logik hast du eigentlich zwei Möglichkeiten.
Entweder du führst den Takt, mit dem du die internen Register schaltest,
nach Außen und machst deine nachgeschaltete Logik synchron zu der Logik
im FPGA oder du erzeugst im FPGA ein Steuersignal (1 Bit), das immer
dann aktiv ist, wenn die Daten (in deinem Fall der Counter) stabil ist.
Die nachgeschaltete Logik darf dann die Daten nur übernehmen, wenn
dieses Steuersignal aktiv ist.