Hallo zusammen,
ich habe eine Frage zu Schieberegistern. Wahrscheinlich liegt das
Problem darin, dass ich noch nicht 100% verstehe wie Flipflops
funktionieren.
Nehmen wir an das SR in dem Beispiel unten ist mit einem zweiten SR
verbunden.
Wenn jetzt clock schaltet wird gleichzeitig Bit 7 in das Ziel-SR
geschrieben und das ursprüngliche Bit 7 in S überschrieben. Meine Frage:
Wenn es tatsächlich gleichzeitig wäre, würde ja an serial_out schon das
nächste Bit anliegen, noch bevor das Ziel-SR eine Chance hat das
ursprüngliche Bit zu schreiben.
Wo liegt das Verständnisproblem? Ich nehme an es gibt irgendeine
Verzögerung, bevor ein FF ein frisch geschriebenes Bit am Ausgang
anliegen hat.
> Wo liegt das Verständnisproblem?
Lass dir doch einfach mal den RTL Schaltplan anzeigen. Du hast hier 8
FFs hintereinander, und das letzte FF ist der Ausgang. Genauso wie du es
beschrieben hast.
> ... wird gleichzeitig Bit 7 in das Ziel-SR geschrieben und das> ursprüngliche Bit 7 in S überschrieben.
Wie gesagt: das letzte FF im SR (Bit 7) ist gleichzeitig der Ausgang.
Das ist einfach nur parallel verdrahtet, denn du gibst das concurrent
aus.
> noch bevor das Ziel-SR eine Chance hat das> ursprüngliche Bit zu schreiben.
das habe ich jetzt aber nicht verstanden... :-/
> bevor ein FF ein frisch geschriebenes Bit am Ausgang anliegen hat.
Ja, die Zeit heißt "Clock to Output" abgekürzt mit tco. Das hat mit
deinem Verständnisproblem aber eigentlich nichts zu tun.
Bin kein FPGA Experte, aber Dein Verständnisproblem lieg wohl im
Verstehen von getaktenen Schaltwerken.
Üblicherweise werden hier getaktete Master-Slave-FlipFlops verwendet,
d.h. die Momentan am FF Eingang anliegenden Werte werden bei der
steigenden Takt-Flanke eigelesen und erst bei der fallenden Takt-Flanke
am Ausgang entsprechend geändert.
Gleichzeitig gibt es nur in der Simulation, und da ist klar, was vorher
war und was nachher zu sein hat.
Deine Frage hat absolute Berechtigung, wenn man auch so Sachen wie
Clock-Jitter in Betracht zieht. Da koennte man durch ein FF sozusagen
'durchschiessen'. Deshalb bauen die Synthesetools bei ASICs oder
Standart-Zell Designs dann zusaetzliche Buffer in das Logiksignal ein
(early-mode Problem), damit kann man das zuverlaessig verhindern.
Beim FPGA hast du von Logic-cell zu Logic-cell sowieso ein Delay, das
groesser ist als der Clock-Jitter. Damit ist das Problem vom Tisch...
> Wahrscheinlich liegt das Problem darin, dass ich noch> nicht 100% verstehe wie Flipflops funktionieren.
Ein Flipflop (so, wie du es zum Verständnis hier brauchst)
hat zwei Eingänge: den Takt Clk und den Dateneingang D
sowie einen Ausgang Q. Mit der steigenden Flanke des Taktes wird
(quasi sofort) der Eingang an den Ausgang gespeichert und gehalten.
So ein einfaches Schieberegister sieht also etwa so aus:
1
S0 S1 S2 ... S7
2
____ ____ ____ ____
3
I ---|D Q|-----|D Q|-----|D Q|-...----|D Q|----- serial_out
4
.-|C | .-|C | .-|C | .-|C |
5
| |____| | |____| | |____| | |____|
6
Clk -o----------o----------o--------...--'
In deinem Fall ist es ein wenig aufwendiger. Deine FFs brauchen einen
Clock-Enable-Eingang (CE) wegen "if shift = '1'". Mit dem Clock-Enable
kann der Takteingang abgeschaltet werden. Irgendwelche Flanken werden
dann ignoriert.
Dein Schieberegister sieht also so aus:
1
S0 S1 ... S7
2
____ ____ ____
3
I -----|D Q|-------|D Q|-----...-----|D Q|----- serial_out
4
.---|C | .---|C | .---|C |
5
| .-|CE__| | .-CE___| | .-CE___|
6
Clk -o-+----------o-+------------...-' |
7
Shift -o------------o------------...---'
> Da koennte man durch ein FF sozusagen 'durchschiessen'.
Ich glaube, von diesen Ausnahmeproblemen (die zum Glück bei FPGAs von
Ingenieuren zur allseitigen Zufriedenheit gelöst sind) sollten wir hier
noch nicht anfangen. Chris geht es um allergrundlegendste Grundlagen
;-)
Hi Lothar,
erstmal danke für die Antwort. Ich versuch's nochmal. Womöglich hast du
meine Frage aber mit dem Hinweis auf tco schon teilweise beantwortet.
Ich das ist jetzt für das FPGA-Forum nicht zu Offtopic :-)
Im Idealfall sollte es ja so aussehen wie im Anhang: FF 1 und 2 gehören
zum ersten SR, und FF 3 gehört zu einem anderen SR, das die Daten
empfangen soll.
Wenn jetzt Clock mit steigender Flanke eintrifft passiert aus meiner
Sichtweise folgendes:
FF 3 speichert das Bit von FF 2 und gibt es aus.
FF 2 speichert das Bit von FF 1 und gibt es aus.
Wenn doch aber FF 2 den Wert von FF 1 ausgibt wie kann dann FF 3 den
Wert von FF 2 speichern?
Die Lösung ist wohl das von dir erwähnte tco. Dann wäre allerdings noch
die Frage ob es sein kann dass das FF 3 wesentlich langsamer ist als die
anderen FFs (weil es ein anderes Fabrikat ist), und eventuell wirklich
den Wert von FF 1 statt von FF 2 speichert.
Hallo zusammen, danke für die viel zu schnellen Antworten :-)
Das es innerhalb des FPGA nicht zu solchen Problemen kommen kann habe
ich jetzt begriffen. Aber nochmal meine letzte Frage wiederholt:
Wenn ich das SR vom FPGA an irgendeinem externen SR anschließe (Z.B. für
SPI) kann es dann sein, dass dieses externe SR so langsam schreibt dass
der Wert von FF 1 (der ja kurz danach an FF 2 anliegt) statt von FF 2
(siehe oben) empfangen wird?
> Wenn doch aber FF 2 den Wert von FF 1 ausgibt wie kann dann FF 3 den> Wert von FF 2 speichern?> Die Lösung ist wohl das von dir erwähnte tco.
Richtig, der Ausgang vom FF 2 ist noch solange stabil, dass FF 3 den
Wert von FF 2 übernimmt.
> Wenn ich das SR vom FPGA an irgendeinem externen SR anschließe (Z.B. für> SPI) kann es dann sein, dass dieses externe SR so langsam schreibt dass> der Wert von FF 1 (der ja kurz danach an FF 2 anliegt) statt von FF 2> (siehe oben) empfangen wird?
Mit ungünstigem Takt-Routing (das ja innerhalb des FPGAs sauber gelöst
ist) kann dir das auf der Platine passieren. Hier mußt du die Setup- und
die Hold-Zeit des externen FFs mit deinen realen Gegebenheiten (Layout,
FF-Typ...) gegenprüfen.
Danke Lothar,
Hat jemand schon konkrete Erfahrungen gemacht wie wahrscheinlich dieses
Problem bei der Realisierung von SPI auftreten kann? Mein konkretes
anliegen:
Ich hatte in der Vergangenheit schon erfolgreich SD-Karten per SPI mit
einem Atmega ausgelesen. Nun ist die Frage ob es per FPGA mit einem 0815
standard Schieberegister als Herzstück realisierbar ist, oder ob man an
der Stelle mehr Aufwand betreiben muss...
> Nun ist die Frage ob es per FPGA mit einem 0815> standard Schieberegister als Herzstück realisierbar ist,
Ja.
Hier findest du z.B. einen SPI-Slave:
http://www.lothar-miller.de/s9y/categories/26-SPI-Slave
Der Master sieht nicht sehr viel aufwendiger aus.
> oder ob man an der Stelle mehr Aufwand betreiben muss...
Man muß wissen, was man tut.
Wichtig ist, dass der entsprechende SPI-Modus richtig implementiert ist.
Dann werden die Setup- und Hold-Zeiten problemlos eingehalten.
So ein SPI-Master ist nicht einfach "nur" ein Schieberegister, sondern
ein wenig mehr. Du hast (je nach SPI-Mode) z.B. eine fallende Flanke, an
der sich die Daten ändern, und eine steigende Flanke, an der die Daten
eingelesen werden. Es wird also bei SPI nicht mit dem Takt
gleichzeitig gelesen und geändert!!
Siehe unten in http://www.lothar-miller.de/s9y/categories/17-SPI
> Hier findest du z.B. einen SPI-Slave:> http://www.lothar-miller.de/s9y/categories/26-SPI-Slave
Dieser SPI-Slave ist fehlerhaft. Genauer: Der Process um die
Parallel-Eingänge nach MISO zu shiften, und zwar in beiden Varianten.
> Dieser SPI-Slave ist fehlerhaft.
Die Simulation (Screenshot) und die Realität sagt was anderes.. :-o
> Genauer: Der Process um die Parallel-Eingänge nach MISO zu shiften,> und zwar in beiden Varianten.
Die Eingänge werden übernommen, solange der Slave deselektiert
(SS-Eingang inaktiv) ist. Was denkst du, was da falsch sein sollte?
danke für den code, Lothar, ich glaube das studium hat mich bei meinem
Verständnis wieder etwas weiter gebracht. Ich glaube jedenfalls diesem
folgen zu können und zu verstehen, warum du das so gemacht hast.
Meine Frage hört sich vielleicht daher auch dämlich an: wie verwende ich
den spi eigentlich in einem anderen code? Sprich wenn eine ensprechend
veranbarte anzahl bits reingekommen ist, ein neues Wort angekommen ist -
wie stellt das ein anderes Modul am besten fest um da etwas mit zu
machen?
Also wie verschalte ich den spi mit einem Teil der was auch immer mit
einem empfangenen Wort macht.
Wird (und wie?) erkannt, daß Dout aktualisiert wurde, oder wird auch
noch dem SS Signal geguckt und dieses in die Sensitivitätsliste
irgendeines anderen Prozesses gepackt?
Was empfiehlt sich?
Wie gesagt: hört sich wohl blöde an, aber bin ja noch frisch. Sonst
würde ich mich ja nicht so über deinen Code gefreut haben.
Ganz Klasse Sache von dir weiter so das hilft!
> oder wird auch noch dem SS Signal geguckt
Es wird nur nach dem SS geschaut, denn das signalisiert ja das Ende
der Übertragung.
> und dieses in die Sensitivitätsliste eines anderen Prozesses gepackt?
Wenn du "nur" auf CPLDs arbeitest, dann kann man solche Tricks
durchgehen lassen. Bei FPGAs empfiehlt es sich allerdings, das Signal
artgerecht auf den FPGA-Takt einzusynchronisieren ;-)
@chris:
Ich weiß nicht, ob ich Dich richtig verstanden habe: Für die internen
Signale im FPGA (zwischen den FPGA-Modulen) verwende ich immer ein
enable. Damit weiß man immer wann gültige Daten vorhanden sind. Im
worst case halt jeden Takt.
Duke
danke euch beiden. Beide bringen mich schon weiter.
Ja es ging mir ursprünglich darum, wie 2 Module sich austauschen, wenn
sie gemeinsame 'Resourcen' benutzen. Und auch wie solche enables für
interne Signale dann hin käme? Equivalente zu globalen Variablen gibts
ja nicht.
Käme das besagte enable dann in die Port Liste der spi entitiy bei dir?
Falls das so wäre dürfte ein anderes Modul dieses direkt verwenden? Ist
ja ein internes signal und sollte durch das spi Modul ja schn synchron
gesetzt werden oder?
Ich komme irgendwie mit dem strukturellen Aufbau eines vhdl Projekten
generell noch extrem mangelhaft klar; wahrscheinlich versaut durch
jahrelange Assembler und C Entwicklung.
Solche code snippets wie auf Lothars homepage versteh ich inzwischen ja
ganz gut und ich meine mir auch einige Herangehensweisen und Tips
verinnerlichen zu können, beim umfasenderen Aufbau und der
Herangehensweise eines komplexeren projektes siehts auber noch düster
aus...
Das ist wirklich eine harte Sache nachträglich Krusten im Hirn
aufzubrechen.
Das lesen als Gast ist aber schon hilfreich und man kennt schon da durch
seine Pappenheimer und weiß worauf man nix geben muss - ich glaub ich
sollte mich langsam im Forum mal anmelden.
> Ja es ging mir ursprünglich darum, wie 2 Module sich austauschen, wenn> sie gemeinsame 'Resourcen' benutzen.
Wenn zwei das selbe wollen, dann brauchst du einen dritten
(Schiedsrichter, Arbiter), der das Ganze verwaltet. Das ist nur allzu
menschlich ;-)
Wenn also z.B. 2 Prozessoren im FPGA sind, und nur 1 SPI Interface, dann
muß einer der beiden solange warten, bis das Interface wieder frei ist.
Das ist allerdings ein aufwendigerer Prozess, als du dir das gerade
vorstellst.
> Käme das besagte enable dann in die Port Liste der spi entitiy bei dir?
Mit "Einfach nur in die Sensitiv-Liste einfügen" ist da nichts getan.
Denn (Achtung: Lernen fürs Leben) die Sensitiv-Liste wird
ausschliesslich und nur für die Simulation verwendet!!
Und in der Sensitiv-Liste sollte für FPGA-Designs im Idealfall nur der
Takt, oder am besten gar nichts stehen (das geht wirklich) ;-)
Diese Buch ist für solche Datenübergabegeschichten ganz gut, da werden
ganze Systeme aufgebaut: ISBN 0470185317
Allerdings gefällt mir die durchgängig eingehaltene
2-Prozess-Schreibweise nicht. Naja, Ansichtssache ;-)
> Denn (Achtung: Lernen fürs Leben) die Sensitiv-Liste wird> ausschliesslich und nur für die Simulation verwendet!!
Kannst du das bitte mal genauer erklähren?
Wovon hängt denn die Sensitivität der synthetisierten Hardware ab?
Warum ist das in der Simulation anders?
Heißt das etwa, die Simulation ist falsch (also schlecht)?
> Und in der Sensitiv-Liste sollte für FPGA-Designs im Idealfall nur> der Takt, oder am besten gar nichts stehen (das geht wirklich) ;-)
Auf deiner Homepage finden sich aber sehr viele Gegenbeispiele...
Ist denn das bei CPLD-Designs nicht so? Und wenn: warum nicht?
MfG, Markus
> Wovon hängt denn die Sensitivität der synthetisierten Hardware ab?
Von den möglichen Warnungen :-)
Sowas wird zum Beispiel bei der Synthese in eine Kombinatorik
(NAND-Gatter abgebildet):
1
process(clk)begin
2
if(a='1'andb='1')then
3
c<='0';
4
else
5
c<='1';
6
endif;
7
endprocess;
Dazu gibt es zwei Warnungen, dass a und b in der Sensitivliste fehlen.
> Warum ist das in der Simulation anders?
Die Simulation verlässt sich blind auf die Sensitivliste. Nur dann, wenn
sich eines der Signale in der Liste ändert, wird der Prozess neu
berechnet.
> Heißt das etwa, die Simulation ist falsch (also schlecht)?
Wenn du das obige (absichtlich einfach gehaltene) Beispiel simulierst,
sieht das aus, wie wenn das Ganze irgendwas mit dem clk zu tun hätte: c
wird nur berechnet, wenn sich der clk ändert.
Fazit: Sensitivliste falsch ==> Simulation falsch :-(
Was passiert z.B. wenn sowas in der Liste stehen würde (ein klassischer
Typo):
1
process(c,b)begin...
> Ist denn das bei CPLD-Designs nicht so? Und wenn: warum nicht?
Doch, dort ist es genauso.
Allerdings kann ich die FFs beim CPLD ja fast noch an einer Hand
abzählen (144 sind schon viel). Deshalb erlaube ich mir bei CPLDs
Sachen, die nicht unbedingt die pure Lehre eines synchronen Designs
verfolgen.
>> Und in der Sensitiv-Liste sollte für FPGA-Designs im Idealfall nur>> der Takt, oder am besten gar nichts stehen (das geht wirklich) ;-)> Auf deiner Homepage finden sich aber sehr viele Gegenbeispiele...
Ja, wenn man weiß, was man tut, kann man durchaus z.B. lokale
Registergruppen mit einem anderen Takt als /dem einen globalen
FPGA-Takt/ anfahren (SPI-Takt, PS/2-Takt...). Nur sollte man dazu genau
wissen, was man tut, und wie man das wieder synchron auf den FPGA-Takt
bekommt...