Forum: FPGA, VHDL & Co. wie Chipselect bei SPI steuern?


von Anfänger (Gast)


Lesenswert?

Hallo,

ich habe mehrere Teilnehmer am SPI-Bus und wollte mir deshalb einen 
Multiplexer schnitzen, über den auch gleich abgefragt werden kann, ob 
der SPI-Bus aktiv ist oder nicht.

Soweit so gut, aber wie verbinde ich die Adressleitungen mit den 
Modulen, sodass jedes beteiligte Modul die Adressleitungen schalten 
kann?

Soweit ich gelesen habe, gibt es intern kein Tristate. Wie würde ich die 
Verdrahtung dann vornehmen? Der CS-Blocker liefert busy wenn die 
Adressleitungen nicht alle 0 sind.

Nach meinem Verständnis ist der Adressbus unidirektional, aber ich weiß 
trotzdem nicht, wie ich die Leitungen in den Modulen ansteuere. Wenn ich 
den Bus freigebe, setze ich den dann auf 'L', oder 'H', oder '-', 
oder???

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


Lesenswert?

> über den auch gleich abgefragt werden kann, ob
> der SPI-Bus aktiv ist oder nicht.
Wozu willst du das wissen?
Wenn du selber der Master bist, dann weißt du es.
Wenn du ein Slave bist, interessiert dich nur dein eigener Slave-Select.

> ob der SPI-Bus aktiv ist oder nicht.
Du meinst also, ob dein eigenes SPI-Modul aktiv ist?
Ganz einfach: gib ein Busy-Signal aus, solange die Übertragung läuft.

> Wenn ich den Bus freigebe, setze ich den dann auf 'L', oder 'H',
> oder '-', oder???
Da läuft mit der Logik gerade etwas ganz arg schief...

Mal angenommen, du hast drei Module (Input, Output und ADC), die mal was 
mit dem SPI-Modul haben möchten. Dein SPI-Modul sieht z.B. so aus:
1
entity SPI_Modul is
2
    Port ( clk : in  STD_LOGIC;
3
           dataTX : in STD_LOGIC_VECTOR( 7 downto 0);
4
           startTX : in STD_LOGIC;
5
           dataRX : out STD_LOGIC_VECTOR( 7 downto 0)
6
           busy : out STD_LOGIC);
7
end SPI_Modul;
Erst werden dataTX angelegt, dann das startTX aktiviert. Wenn die 
Übertragung läuft, wird busy aktiv. Wenn busy wieder inaktiv ist, können 
die Daten an dataRX abgeholt werden.

Du brauchst jetzt also einen Schiedsrichter (Arbiter), der bestimmt, wer 
von den drei Teilnehmern auf das SPI-Modul darf. Dazu eine 
State-Machine, die die Sendedaten entsprechend durchreicht, dann das 
Übertragungsende abwartet, und zum Schluss die Empfangsdaten an das 
anfordernde Modul abliefert. Und während der ganzen Übertragung einen 
Zugriff von den anderen Modulen blockiert.

Da ist also einiges mehr dran, als nur einen Bus hochohmig zu 
schalten...

von Anfänger (Gast)


Lesenswert?

Guten Morgen Lothar,

>> Wenn ich den Bus freigebe, setze ich den dann auf 'L', oder 'H',
>> oder '-', oder???
> Da läuft mit der Logik gerade etwas ganz arg schief...

Dann bitte ich um Unterweisung, denn genau hier habe ich mein 
(Verständnis-)Problem. Egal ob jetzt mit SPI oder anderswo, es wird 
immer die Situation geben, dass mehrere Module ein anderes verwenden 
können/sollen. Bleibt also die Frage, wie steuere ich gemeinsame 
Leitungen an.
Das aktive Modul kann die Leitungen mit '0' und '1' treiben, aber was 
machen die wartenden Module?

Ich denke mal, das ist weniger eine logische Frage, als vielmehr eine 
technische (FPGA-interne) Frage ;)

>> über den auch gleich abgefragt werden kann, ob
>> der SPI-Bus aktiv ist oder nicht.
> Wozu willst du das wissen?
> Wenn du selber der Master bist, dann weißt du es.
> Wenn du ein Slave bist, interessiert dich nur dein eigener Slave-Select.

Da die Module sowohl unterschiedliche SPI-Modi benötigen, alsauch andere 
Taktfrequenzen, wollte ich das ganze als Multi-Master/Multi-Slave 
aufziehen und eventgesteuert die Übertragung starten.

> Du brauchst jetzt also einen Schiedsrichter (Arbiter), der bestimmt, wer
> von den drei Teilnehmern auf das SPI-Modul darf. Dazu eine
> State-Machine, die die Sendedaten entsprechend durchreicht, dann das
> Übertragungsende abwartet, und zum Schluss die Empfangsdaten an das
> anfordernde Modul abliefert. Und während der ganzen Übertragung einen
> Zugriff von den anderen Modulen blockiert.

Ob ich den Schiedsrichter jetzt Arbiter oder CS-Blocker nenne, 
dürfte doch Jacke wie Hose sein. Aus den unterschiedlichen Anforderungen 
wollte ich kein zentrales SPI-Modul machen, sondern den logischen 
Gegenstücken zu Speicher, ADC und Co die Übertragung gemäß ihren 
Anforderungen durchführen lassen.

> Da ist also einiges mehr dran, als nur einen Bus hochohmig zu
> schalten...

Das ist mir bewusst, aber ich frage da, wo ich gerade nicht weiter komme 
(ungeachtet der Probleme, die noch auf mich zukommen mögen). Ich habe 
mir jetzt ein Konzept für das Entwicklungboard gemacht und das will ich 
Stück für Stück umsetzen. Gelegentlich weiß ich nimmer weiter - soll 
doch vorkommen :)

Ich habe in einigen Tuts gelesen, dass man aufpassen muss, wenn mehrere 
Module an einem internen Bus hängen, aber ich fand noch keine Hinweise 
darauf, wie man es richtig machen kann/soll. Deshalb also meine Frage.

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


Lesenswert?

> Das aktive Modul kann die Leitungen mit '0' und '1' treiben, aber was
> machen die wartenden Module?
Jedes Modul treibt immer genau das, was es ausgeben will. Kein Modul 
kümmert sich um ein anderes. Ein Multiplexer wählt dann aus allen 
anliegenden Modulen eine Quelle für z.B. das SPI-Modul aus.

> Ich denke mal, das ist weniger eine logische Frage, als vielmehr eine
> technische (FPGA-interne) Frage ;)
Wie gesagt: das wird mit Multiplexern gemacht. Im einfachsten Fall (2 
Eingänge, 1 Ausgang) gibt es 1 Auswahlleitung, 1 Inverter, 1 ODER- und 1 
AND-Gatter:
1
                        _______
2
    Quelle 1 ----------|       |
3
                       |   &   |---
4
                    ---|_______|   |
5
                   O               |    _______
6
                  / \               ---|       |
7
                 /___\                 |  >=1  |-----
8
                   |                ---|_______|
9
                   |    _______    |
10
    Select   ------o---|       |   |
11
                       |   &   |---
12
    Quelle 2 ----------|_______|

> *Bleibt also die Frage, wie steuere ich gemeinsame Leitungen an?*
Antwort: Es gibt keine gemeinsame Leitungen.
Jede einzelne Leitung im FPGA hat genau 1 Treiber und mindestens 1 oder 
mehrere Empfänger. Es können nicht mehrere Ausgänge auf 1 Leitung 
geschaltet werden (auch nicht abwechselnd). Wenn sowas gewünscht ist, 
muß ein Multiplexer vorgesehen werden.

> wenn mehrere Module an einem internen Bus hängen,
Es gibt im FPGA keine richtigen (bidirektionalen) interne 
(Tristate-)Busse. Darum sollte jeder Port eines Moduls innerhalb des 
FPGAs mit in oder out definiert sein, nicht mit inout. Ein 
Tristate-Bus wird vom Synthesizer in einen Multiplexer aufgelöst.
Lediglich auf dem Top-Level, also an den FPGA-Pins, können die IO-Zellen 
einen Tristate-Bus ansteuern.

> Da die Module sowohl unterschiedliche SPI-Modi benötigen, alsauch andere
> Taktfrequenzen, wollte ich das ganze als Multi-Master/Multi-Slave
> aufziehen und eventgesteuert die Übertragung starten.
Dann mußt du nicht nur die Daten multiplexen, sondern auch die 
Konfiguration. Wenn du das Eine kannst, ist das Andere nicht schwer.

> das ganze als Multi-Master/Multi-Slave aufziehen
Was ist jetzt bei dir ein Master, und was ein Slave?
Hat das was mit deinem SPI-Modul zu tun? Oder hast du gleich mehrere 
SPI-Module, die auf die selben IO-Pins zugreifen sollen?

von Anfänger (Gast)


Lesenswert?

>> Bleibt also die Frage, wie steuere ich gemeinsame Leitungen an?
> Antwort: Es gibt keine gemeinsame Leitungen.

Ja, wenn das so ist, dann stimmt natürlich die Logik auch nimmer.
Danke auch für's hinterfragen!

Muss nomml nachdenken gehen ;)

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.