Forum: FPGA, VHDL & Co. Anfängerfrage zu Schieberegistern bzw. FFs


von Chris (Gast)


Lesenswert?

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.

1
process(clock)
2
begin
3
  if clock'event and clock='1' then
4
    if shift = '1' then
5
      S <= S(6 downto 0) & I;
6
    end if;
7
  end if;
8
end process;
9
10
serial_out <= S(7);

Ciao
Chris

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


Lesenswert?

> 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.

von schnitzel (Gast)


Lesenswert?

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.

von berndl (Gast)


Lesenswert?

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...

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


Lesenswert?

> 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 
;-)

von Chris (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Chris (Gast)


Lesenswert?

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?

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


Lesenswert?

> 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.

von Chris (Gast)


Lesenswert?

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...

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


Lesenswert?

> 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

von Chris (Gast)


Lesenswert?

Ah, danke für das konkrete Beispiel Lothar :-)

von CPLD-Anfänger (Gast)


Lesenswert?

> 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.

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


Angehängte Dateien:

Lesenswert?

> 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?

von chris (offenbar jemand anderes) (Gast)


Lesenswert?

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!

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


Lesenswert?

> 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 ;-)

von Duke Scarring (Gast)


Lesenswert?

@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

von chris (offenbar jemand anderes) (Gast)


Lesenswert?

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.

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


Lesenswert?

> 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 ;-)

von Markus (Gast)


Lesenswert?

> 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

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


Lesenswert?

> 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' and b='1') then
3
         c <= '0';
4
      else
5
         c <= '1';
6
      end if;
7
   end process;
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...

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.