Hallo,
ich habe zur Übung gerade versucht eigenständig ein Schieberegister in
VHDL zu realisieren. Mein erster Versuch hat in der Simulation auch
schon funktioniert.
1
entityshiftis
2
port(
3
CLK:instd_logic;
4
DATA:instd_logic;
5
CS:instd_logic;
6
Q:outstd_logic_vector(3downto0));
7
endshift;
8
9
architecturebhvofshiftis
10
signalstream:std_logic_vector(3downto0);
11
begin
12
processbegin
13
waituntilrising_edge(CLK);
14
if(CS='0')then
15
stream<=stream(2downto0)&DATA;
16
endif;
17
endprocess;
18
Q<=stream;
19
endbhv;
Aber wenn die Daten mit dem selben Takt generiert werden wie "CLK", dann
werden die Daten genau bei der Zustandsänderung gelesen. In der
Simulation funktioniert es anscheinend trotzdem, aber in der Hardware
kann das doch niemals funktionieren, oder?
Um das Problem jetzt einfach zu lösen habe ich einfach das Taktsignal
invertiert.
1
entityshiftis
2
port(
3
CLK:instd_logic;
4
DATA:instd_logic;
5
CS:instd_logic;
6
Q:outstd_logic_vector(3downto0));
7
endshift;
8
9
architecturebhvofshiftis
10
signalnclk:std_logic;
11
signalstream:std_logic_vector(3downto0);
12
begin
13
nclk<=notCLK;
14
processbegin
15
waituntilrising_edge(nclk);
16
if(CS='0')then
17
stream<=stream(2downto0)&DATA;
18
endif;
19
endprocess;
20
Q<=stream;
21
endbhv;
Irgendwo habe ich gelesen, dass man in einem Design immer nur eine
Flanke auswerten sollte. Wenn ich den Takt negiere kommt die die
Bedingung rising_edge(nckl) aber ja der Abfrage falling_edge(CKL)
gleich. Ich würde in meinem Design also beide Flanken auswerten. Die
steigende z.B. in dem Teil der die Daten generiert und die fallende im
Schieberegister. Deshalb mal die einfache Frage: Wie sollte man ein
Schieberegister in VHDL denn tatsächlich beschreiben?
PS: Wenn ich im Internet suche finde ich immer wieder Beispiele
folgender Art:
http://users.etech.haw-hamburg.de/users/schwarz/En/Lecture/DI/Notes/DI_18.pdf
Darin kommen aber Statements der Form "after 10 ns" vor. So etwas wäre
doch niemals synthetisierbar oder?
> Aber wenn die Daten mit dem selben Takt generiert werden wie "CLK", dann> werden die Daten genau bei der Zustandsänderung gelesen. In der> Simulation funktioniert es anscheinend trotzdem, aber in der Hardware> kann das doch niemals funktionieren, oder?
Warum nicht? Genau so funktioniert ein synchrones Design.
much schrieb:> entity shift is
Eine VHDL Beschreibung beginnt schont vor dem Keyword "entity"...
much schrieb:> im Internet finde ich immer wieder Beispiele folgender Art: ...> Darin kommen aber Statements der Form "after 10 ns" vor. So etwas wäre> doch niemals synthetisierbar oder?
Ncith nur das, symbolische Verzögerungen sind gefährlicher Murks!
Sie haben in synthetisierbarem Code nichts verloren. Sie sollen Schülern
helfen, zeitliche Abläufe besser zu "verstehen" ("da sieht man dann
schön, was wovon abhängt"). In der Praxis legen genau diese Schüler sich
dann selbst ein Ei. Ich verweise mal auf den
Beitrag "Re: Simulation - Bei Abtastung anliegendes Signal übernehmen" und die Links in
diesem Post...
Dazu auch noch der Post, der sich auf das Synthese-Buch von
Reichardt&Schwarz bezieht, wo (leider) genau solche Konstrukte zum
Aufzeigen von inneren Abläufen verwendet werden:
Beitrag "Re: Verständnisproblem Xilinx XC9572 CPLD"much schrieb:> Ich würde in meinem Design also beide Flanken auswerten.
Das tust du tatsächlich. Und verdoppelst damit deine Taktfrequenz (oder
andersrum: dein Design wird nur noch halb so schnell sein können...)
Das kommt darauf an, wo der Empfänger, also der lesende Teilnehmer
sitzt.
Wird der lesende Teilnehmer von der selben Taktquelle gespeist und gibt
es dann noch ein Taktnetzwerk wie im FPGA, das garantiert, dass jedes FF
relativ zu den Datenleitungen die Takte zur selben Zeit wahrnimmt und
entsprechende Setup/Hold-Zeiten eingehalten werden, machst du im
einfachsten Fall Sender und Empfänger synchron zur steigenden Flanke. Im
Moment der steigenden Flanke schalten Sender und Empfänger um, der
Empfänger sieht (=speichert) in dem Fall das, was zur bzw. kurz vor der
steigenden Flanke auf der Leitung ist, wenn du es dir für die
funktionale Simulation so vorstellen willst.
Diese Art der Taktung findet man oft unter "System synchronous". Mit
solchen after statements kannst du noch eine Verzögerung simulieren, die
auf der Hardware möglicherweise vorkommt, aber synthetisierbar ist die
nicht. In Hardware gilt für die Daten, dass diese Setup/Hold-Zeiten
erfüllen müssen, d.h. es wird eine Zeit spezifiziert, wie lange vor bzw.
nach der Taktflanke die Daten gültig sein müssen, um sicher gelesen
werden zu können. Innerhalb eines FPGA ist das bereits durch den
Hersteller sicher gestellt (bzw. wird u.a. dadurch der Maximaltakt für
dein Design begrenzt).
Ist der lesende Teilnehmer z.B. ein externes Bauteil und du als Sender
schickst den Takt mit, wird oft einer der Teilnehmer genau auf der
anderen Flanke seine Operationen durchführen (um z.B. sicher die
Setup/Hold-Zeiten einzuhalten). Für das Mitsenden des Taktes wird der
Ausdruck "Source synchronous" gebraucht, was oft gleichbedeutend mit den
gegenläufigen Taktflanken ist.
much schrieb:> aber in der Hardware kann das doch niemals funktionieren, oder?
"Kann" es das nicht oder "tut" es das nicht?
Dazu hätte ich noch ein paar Fragen:
Woher kommt der "Takt"? Woher kommen die Daten? Welche Frequenzen hast
du da?
Lothar M. schrieb:> Ncith nur das, symbolische Verzögerungen sind gefährlicher Murks!>> Sie haben in synthetisierbarem Code nichts verloren.
Gibt es dafür einen technischen Grund?
Ich habe jetzt kein Beispiel, aber es kann doch sein, dass man sich aus
irgendeinem Grund mal ein ungefähres Laufzeitverhalten simulieren will.
Ob ich die Verzögerungen vor der Synthese von Hand lösche oder ob der
Synthesizer das macht, sollte doch eigentlich egal sein, oder?
VHDL hotline schrieb im Beitrag #4500700:
> Innerhalb eines FPGA ist das bereits durch den> Hersteller sicher gestellt (bzw. wird u.a. dadurch der Maximaltakt für> dein Design begrenzt).
Dann brauche ich mich beim Design nicht um solche Timing-Probleme zu
kümmern, da das im FPGA so realisiert ist, dass zu Zeitpunkten gelesen
wird, zu denen die Signale definierte Zustände haben. Sehe ich das
Richtig?
VHDL hotline schrieb im Beitrag #4500700:
> Im> Moment der steigenden Flanke schalten Sender und Empfänger um, der> Empfänger sieht (=speichert) in dem Fall das, was zur bzw. kurz vor der> steigenden Flanke auf der Leitung ist, wenn du es dir für die> funktionale Simulation so vorstellen willst.
Wenn bei der steigenden Flanke der Wert der kurz zuvor auf der Leitung
war empfangen wird dann habe ich im Design eine Verzögerung von einer
Taktperiode. Habe ich das richtig verstanden?
VHDL hotline schrieb im Beitrag #4500700:
> Wird der lesende Teilnehmer von der selben Taktquelle gespeist und gibt> es dann noch ein Taktnetzwerk wie im FPGA, das garantiert, dass jedes FF> relativ zu den Datenleitungen die Takte zur selben Zeit wahrnimmt und> entsprechende Setup/Hold-Zeiten eingehalten werden, machst du im> einfachsten Fall Sender und Empfänger synchron zur steigenden Flanke.
Das heißt CLK muss aus dem Systemtakt kommen und ich darf keine
Datenleitung als CLK missbrauchen (z.B. einen IO-Pin). Richtig?
Lothar M. schrieb:> "Kann" es das nicht oder "tut" es das nicht?>> Dazu hätte ich noch ein paar Fragen:> Woher kommt der "Takt"? Woher kommen die Daten? Welche Frequenzen hast> du da?
Ich arbeite zur Zeit noch mit ghdl. Ich habe also keinen konkrete
Frequenz ect. Ich dachte mir nur es macht Sinn sich beim Arbeiten am
Simulator schon ein wendig Gedanken darüber zu machen, welche
Hindernisse an der Hardware auftreten können/werden.
Dussel schrieb:> Lothar M. schrieb:>> Ncith nur das, symbolische Verzögerungen sind gefährlicher Murks!>> Sie haben in synthetisierbarem Code nichts verloren.> Gibt es dafür einen technischen Grund?
Sieh dir bitte mal die verlinkten Beiträge an. Dort stehen genug Gründe.
Und dazu kommt noch, dass ein "after 10 ns" hinter jeder Zuweisung der
Lesbarkeit des Codes nicht gut tun...
much schrieb:> Das heißt CLK muss aus dem Systemtakt kommen und ich darf keine> Datenleitung als CLK missbrauchen (z.B. einen IO-Pin). Richtig?
Richtig. Simple EA-Signale sind (in erster Näherung) keine Takte.
Sie werden vor Verwendung auf den (einzigen) FPGA-Takt
einsynchronisiert. Siehe dazu
http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren
Es taucht immer wieder jemand auf, der das nicht tut, und dessen Design
"zu 99% funktioniert", aber eben einmal pro Minute/Stunde/Tag irgendwie
seltasme Fehler bringt. Die Ursache ist dann recht oft schnell
gefunden...
Lothar M. schrieb:>> Das heißt CLK muss aus dem Systemtakt kommen und ich darf keine>> Datenleitung als CLK missbrauchen (z.B. einen IO-Pin). Richtig?> Richtig. Simple EA-Signale sind (in erster Näherung) keine Takte.>> Sie werden vor Verwendung auf den (einzigen) FPGA-Takt> einsynchronisiert.
Das heist aber auch das CLK nicht an einen herunter geteilten Takt
angeschlossen werden darf. Wenn ich z.B. den Systemtakt (CLK_system) mit
einem Counter um einen Faktor herunter teile (CLK_pre), dann darf ich
CLK_pre nicht als Takt CLK des oben beschriebenen Schieberegisters
verwenden, da ja auf CLK_system und nicht auf CLK_pre synchronisiert
wird. CLK_pre ist dann eine ganz normale Datenleitung. Habe ich das
richtig verstanden?
much schrieb:> Habe ich das richtig verstanden?
Im Prinzip ja. Nur ist dieses heruntergeteilte Signal eben kein Takt mit
50% Tastverhältnis, sondern ein Clock-Enable, das immer wieder mal für 1
Taktperiode aktiv ist. Zum Erzeugen eines 1kHz Clock-Enables aus einem
50MHz Systemtakt ist dieser Clock-Enable demnach 49999 Takte low und 1
Takt High.
Siehe z.B. das Lauflicht auf meiner Homepage:
http://www.lothar-miller.de/s9y/archives/61-Lauflicht.html
much schrieb:> Lothar M. schrieb:>>> Das heißt CLK muss aus dem Systemtakt kommen und ich darf keine>>> Datenleitung als CLK missbrauchen (z.B. einen IO-Pin). Richtig?>> Richtig. Simple EA-Signale sind (in erster Näherung) keine Takte.>>>> Sie werden vor Verwendung auf den (einzigen) FPGA-Takt>> einsynchronisiert.>> Das heist aber auch das CLK nicht an einen herunter geteilten Takt> angeschlossen werden darf. Wenn ich z.B. den Systemtakt (CLK_system) mit> einem Counter um einen Faktor herunter teile (CLK_pre), dann darf ich> CLK_pre nicht als Takt CLK des oben beschriebenen Schieberegisters> verwenden, da ja auf CLK_system und nicht auf CLK_pre synchronisiert> wird. CLK_pre ist dann eine ganz normale Datenleitung. Habe ich das> richtig verstanden?
das sind die richtigen Fragen. Ich glaube für besseres Verständnis
solltest du nachschauen unter dem Begriff "Delta Delays". Mit diesen
arbeitet der Simulator und kann damit entscheiden, was vor oder nach der
rising edge deines Clock-Signals liegt.
In gerouteten Designs mit Bauelemente-Informationen wirst du sehen, dass
die Daten eine definierte Zeit vor der Taktflanke anliegen (Setup zeit).
In der Verhaltenssimulation ist die Verzögerung jedoch noch nicht
abgebildet.
Klakx schrieb:> In der Verhaltenssimulation ist die Verzögerung jedoch noch nicht> abgebildet.
Diese Verzögerung ist auch nicht interessant, denn sie wird
gewährleistet, indem passende Constraints vorgegeben werden. Im
einfachsten Fall wird der Toolchain gesagt: pass auf, das Design muss
mit 50MHz laufen. Dann wird die Toolcahin meckern, wenn sie es aus
irgendwelchen Gründen nicht schafft...
der mechatroniker schrieb:>> Aber wenn die Daten mit dem selben Takt generiert werden wie "CLK", dann>> werden die Daten genau bei der Zustandsänderung gelesen. In der>> Simulation funktioniert es anscheinend trotzdem, aber in der Hardware>> kann das doch niemals funktionieren, oder?> Warum nicht? Genau so funktioniert ein synchrones Design.
Sagen wir genauer, ein synchrones Logikdesign innerhalb einer Simulation
funktioniert so. Man darf nie vergessen, dass das, was da im Simulator
gezeigt ist, reine funktionelle Logik auf der Ebene von abstrahierten
Bauelementen oder Mathematik darstellt.
Das darf mit realen Simulationen, in denen Timing analysiert wird, nicht
verwechselt werden. Dort ist es dann in der Tat nötig, dass der
Taktwechsel eben niemals auftritt, wenn sich Daten ändern, bzw. es ist
zu untersuchen, wie sich das auswirkt. Da in "normalen" Schaltungen alle
Reaktionen auf einen Takt verzögert laufen, gibt es bei aus reichend
kurzen Verzögerungen keine solchen Fälle. Transparente FFs, gegatete
Leitungen und anti-Hazzard-Redundanzen sowie andere rückgekoppelte und
selbstschwingende Systeme schließt man nicht ohne Grund aus dem
Logikdesign aus! Will man sowas, muss man extra und technologieabhängig
simulieren.
Ich empfehle daher, grundsätzlich Logiksimulation und physikalische
Simulation stickt voneinander zu trennen. In der Logiksimulation haben
z.B. die für die Taktbehandlung wichtigen IO-Zellen, Buffer, Multiplexer
z.B. die Verzögerung Null, was zu kritischen Effekten bei der Simulation
führt, wenn man solche Elemente kombiniert und die Eigenheiten der
Logiksimulation diesbezüglich nicht berücksichtigt. Daher mein Tipp, die
so weit, als möglich rauszunehmen.
Physik sollte daher generell von der Logik im FPGA getrennt werden und
auch getrennt simuliert werden. Damit kann man die umständlichere
Timing-Simulation auf einige Schaltungsteile begrenzen und bei einfachen
Designs sogar oft komplett wegfallen lassen.
Für die Synthese gilt, was Lothar schon geschrieben hat: Vollsynchrones
Logikdesigen OHNE konkretisierte Verzögerungen bauen und das tool das
timing rechnen lassen. Das ist heute umso wichtiger, weil die tools
nicht nur das timing einer platzierten Schaltung analysieren und
indirekt Tipps zum Verbessern geben, sondern das Platzieren und sogar
die Auswahl der Implementierung timing-orientiert durchführen (können).
Große und fordernde Designs bekommt man nur so geroutet. Lediglich
kleine Parzellen in FPGAs mit Sonderfunktionen werden manuell erzeugt,
um dort spezielle Funktionen zu realisieren.
Das Ziel muss sein, die Physik (Pegel, Reflektion, Jitter, Synchronität,
Koheränz) an den IO-Zellen zu erledigen und ab dann nur noch Logik zu
bauen.