Hallo,
gemäß der im Anhang dargestellten Abbildung möchte ich gern den CPLD an
den Bus ankoppeln. Wie ersichtlich ist, existiert ein NE1
(Enable-Signal,low aktiv). Mittels diesen Signals möchte ich erst die
Abarbeitung innerhalb des CPLD beginnen. Um Signalkollisionen zu
vermeiden, möchte ich den Adress-, Daten- und Steuerbus hochohmig
schalten.
Da ich erst begonnen habe mich mit VHDL zu beschäftigen, würde ich euch
bitten über den Code zu schauen und mir zu sagen, ob das die richtige
herangehensweise ist.
Ist es überhaupt nötig alle Bussignale hochohmig zu schalten? Wie kann
man die umgeschalteten Kanäle( 'Z') wieder als Eingang (STE und ADDR)
bzw. als Ein- oder Ausgang (DATA) umschalten? Wäre eine Flankenabfrage
mittels falling_edge() die bessere Variante?
Danke
Stephan
Üblicherweise werden die Adresssen und Steuerleitungen am Bus von einem
Master getrieben, und diese werden nie hochohmig geschalten.
In deinem Fall nehme ich einmal an, dass nicht das CPLD der Master ist,
sondern irgend ein Prozessor außen.
In diesem Fall sind die Adress- und Steuersignale am CPLD keine inouts,
sondern reine Eingänge.
Bei den Daten ist es etwas anderes.
Diese werden wechselseitig jeweils vom Master oder von den einzelnen
Slaves getrieben, wobei immer nur einer die Daten treibt, alle anderen
sind hochohmig.
Die VHDL Beschreibung für das hochohmig-schalten ist ganz einfach:
1
DATA<=DATA_BUFwhenNE1='0'else(others=>'Z';
DATA_BUF sind die errechneten Daten, die an den Bus gehen.
Ja,
ein uC bildet den Master am Bus. Somit stelle ich die Adress- und
Steuerleitungen auf reine Eingänge um.
Mit der von Ihnen beschrieben Befehlszeile findet also eine
Signalumschaltung statt.
Danke
Stephan M. schrieb:> Mit der von Ihnen beschrieben Befehlszeile findet also eine> Signalumschaltung statt.
Nein, als Umschaltung kann man es nicht bezeichnen, da hochohmig kein
Signalwert ist.
Es ist einfach nur die VHDL Beschreibung, mit der man erreicht, dass das
inout-Port DATA entweder hochohmig ist (NE = 1) oder das Signal DATA_BUF
ausgegeben wird.
Du kannst DATA übrigends jederzeit lesend verwenden, dabei liest du die
Daten, die gerade außen am Bus liegen.
Zum Hintergrund:
Wir kommen vom Beitrag "CPLD - I/O Erweiterung"> STE: in std_logic_vector(1 downto 0); --Steuerbus 0-NWE 1-NOE
Teil das besser in 2 Einzelsignale auf, dann liest es sich leichter...
Hier mal mein Ansatz:
(Das Tristate-Zeugs kommt bei den Ports natürlich auch zum Zuge)
1
libraryieee;
2
useieee.std_logic_1164.ALL;
3
4
entityIO_EXis
5
port(NE1:instd_logic;-- ! nimm nur STD_LOGIC ! --Enable (low active) NINT3: out std_logic; --Interrupt (low active)
Stephan M. schrieb:> Da alle Signale low - active sind, muss man dann auf eine fallende> Flanke triggern.
Sieh dir an, wo bei deinem WE-Signal die Daten und Adressen stabil sind.
Ich habe da einen kleinen Bock geschossen...
Das sollte besser heißen:
1
:
2
if(NE1='1')thenNULL;-- nichts tun, wenn disabled
3
elsif(A="000000")thenPortA<=DATA;
4
elsif(A="000001")thenPortB<=DATA;
5
:
6
elsif(A="000100")thenDirA<=DATA;
7
elsif(A="000101")thenDirB<=DATA;
8
:
9
elsif(A="001000")thenADDR_MUX<=D(2downto0);
10
endif;
11
:
Stephan M. schrieb:> ich möchte eine "Don´t care" Auswertung mit einbringen.
Also sowas:
1
:
2
if(NE1='1')thenNULL;-- nichts tun, wenn disabled
3
elsif(ADDR(5downto3)="000")then
4
if(ADDR(2downto0)="000")thenPortA<=DATA;
5
elsif(ADDR(2downto0)="001")thenPortB<=DATA;
6
:
7
elsif(ADDR(2downto0)="101")thenDirA<=DATA;
8
elsif(ADDR(2downto0)="101")thenDirB<=DATA;
9
endif;
10
elsif(A="001000")thenADDR_MUX<=D(2downto0);
11
endif;
12
:
Das ist unnötig, der Synthesizer macht das schon richtig, und ausserdem
ist das miserabel lesbar...
Oh, stimmt mit dem Vergleich!
Bis jetzt schreibe und simuliere ich den Prozess in ModelSim.
Bei der Umsetzung auf einen CPLD von z.B Xlinx und deren
Entwicklungsumgebung, besteht da in der Software die Möglich den
definierten Ports z.B. PA, die Pins zuzuordnen?
Konnte die WebPack noch nicht runterladen...
Stephan M. schrieb:> besteht da in der Software die Möglich den> definierten Ports z.B. PA, die Pins zuzuordnen?
Ja. Diese Einschränkungen nennen sich Constraints (Einschränkungen
deshalb, weil die Toolchain nicht x-beliebig die Pins zuordnen darf) und
werden in einer UCF-Datei (user constraints file) vorgenommen.
Hallo,
nun habe ich es erreichen können, dass die Ports A bis D sowie die
Multiplexer 1 und 2 die über den Datenbus gesendeten Daten korrekt
ausgeben, aber sobald ich denn "letzen" Prozess in den Code einbinde,
kommt in der Simulation, dass die Signale undefiniert sind.
Dieser Prozess soll dazu dienen, die anliegenden Level an den Ports über
die Datenleitung zu senden...
Kann mir vielleicht jemand verraten, was ich übersehen habe?
Die Ports bleiben dann hochohmig, also 'Z' laut Simulator.
Danke Stephan
Du denkst immer noch zu kompliziert und Dein Design funktioniert sicher
auch nicht korrekt so wie Du glaubst.
Vielleicht beschreibst Du noch einmal, was Du erreichen willst:
Sind PA usw. Ports, die der Microprozessor als Eingang oder Ausgang
konfigurieren soll?
Erstmal vorab:
Das Lesen bei dir ist ein rein kombinatorischer Vorgang, bei dem nichts
irgendwo gespeichert werden muß. Es ist also unnötig, da irgendwas mit
einer Flanke abzufragen...
Stephan M. schrieb:> dass die Signale undefiniert sind.
Welche Signale?
Wie auch immmer: dein Problem liegt darin, dass zwei Prozesse die
Richtungssignel treiben: der Lese- (mit '0') und der Schreibprozess (mit
'1'). Das gibt im DIRA..D ein 'X' und damit kommt beim Porttreiber etwas
/='1' und folglich ein 'Z' heraus.
So geht das nicht, du kannst nicht einfach zum Lesen die Richtung eines
Ports umschalten wollen...
Hast du mein Beispiel nachvollzogen? Hast du mal gegengeprüft, wie uCs
das machen mit der Richtungsumschaltung?
Ich habe mir eine Adresstabelle erstellt, wo das oberste Bit ADDR3
entweder eine 0 für CPLD Port einlesen oder eine 1 für CPLD Port
schreiben beinhaltet. Abhängig von diesem Bit, soll der jeweilige Port
des CPLD die Daten vom Datenbus ausgeben bzw. auf den Datenbus
"schreiben".
Bei einer fallenden Flanke an NE1 und NWE sendet der uC Daten an den
CPLD und bei fallender Flanke an NE1 und NOE soll der uC die Daten des
Ports abrufen.
Die Simulation des Schreibens mit den Flankenwechseln funktioniert auch
soweit.
Die Umschaltung der I/Os innerhalb eines uC habe ich immer über die
zugehörigen Librarys bzw. Register gemacht.
Stephan M. schrieb:> Abhängig von diesem Bit, soll der jeweilige Port> des CPLD die Daten vom Datenbus ausgeben bzw. auf den Datenbus> "schreiben".
Das kann aber so nicht funktionieren.
Angenommen, du schreibst zuerst auf PA, dann wird das Port auf Ausgang
geschalten, die Daten liegen danach aber weiterhin an.
Wenn Du jetzt etwas einlesen willst und Du dort von außen ein Signal
anlegt, dann gibt es eine Kollision, weil die Pins schon einen Wert
treiben.
Du musst also eine Methode finden, die Pins von PA zuerst auf Hochohmig
zurückzuschalten.
Da waren deine vorherigen Lösungen sinnvoller.