www.mikrocontroller.net

Forum: FPGA, VHDL & Co. inout std_logic H als 1 erkennen


Autor: na (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

meine augenblickliches Problem ist folgendes:

Eine Komponente ist als slave an einem I2C-Bus angeschlossen. Sie hat 
also die zwei inout ports SCL und SDA, welche als std_logic definiert 
sind.

In meiner Testbench lege ich den Bus per Standard auf 'H'. Die Testbench 
beschreibt das Verhalten eines I2C-Masters, welcher SCL und SDA 
hochohmig setzt (so dass das 'H' zur Geltung kommt) bzw. auf '0' zieht.

Mein Problem ist nun, dass der I2C-Slave das 'H' nicht als '1' wahrnimmt 
und daher keine Flanken oder Level erkennt.

Ich habe als workaround in der Testbench
i2c_sda <= 'H'; -- standardzuweisungen pullup
i2c_scl <= 'H';

i2c_slave_sda <= '1' when (i2c_sda = 'H') else '0'; -- workaround
i2c_slave_scl <= '1' when (i2c_scl = 'H') else '0'; -- i2c_slave_sda und i2c_slave_scl sind die inouts des I2C slave

probiert, was aber logischerweise Probleme gibt, wenn der slave selbst 
SDA oder SCL treibt.

Gibt es Erfahrungen, wie man das machen kann?

Danke schon einmal.

na

Autor: Jan M. (mueschel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Definiere dir eine Funktion, die die entsprechenden Signale umwandelt 
und zurueck gibt.

function i2c_logic_conv (s: std_logic) return std_logic is
begin
 case s is
 when '0' => return '0';
 when 'H' | '1' => return '1';
.....
end funtion;

Autor: na (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke fuer den Vorschlag.

Aber das macht ja mein workaround auch schon. Das Problem ist die 
Bidirektionalitaet des Signals.

Wuerde ich nun mit der Funktion schreiben
i2c_slave_sda <= i2c_logic_conv(i2c_sda);

dann klappt das wunderbar, solange der slave SDA liest. Will er dann 
aber sein acknowledge oder Daten senden, also selbst SDA schreiben, dann 
darf der SDA Bus nur 'H' sein (um ueberschrieben zu werden) aber nicht 
aufgeloest auf '1', da es dann zum Konflikt kommt. Es darf also im 
Prinzip nur der SDA input des slaves aufgeloest werden, nicht aber der 
Bus. Das ist aber so nicht moeglich, da SDA am slave ja ein und dasselbe 
Signal fuer input und output ist. Von aussen besteht keine Moeglichkeit 
festzustellen, wann der Treiber an und aus ist.
In realer Hardware klappt es ja, weil es nun mal 'H' ist (pullup) und 
als '1' erkannt wird, nur die Simulation mag das nicht in der Weise.

Autor: Jan M. (mueschel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, vielleicht verstehe ich dich immer noch falsch, aber:

Du nimmst ein Bus-Signal sda_bus. Dann nimmst du ein internes Signal 
sda_slave_internal <= i2c_logic_conv(sda_bus). Deine Ausgabe erfolgt 
immer auf sda_bus, gelesen wird aber nur sda_slave_internal. Dieses 
Signal sollte dann immer die korrekten 1/0-Werte haben.

Im Prinzip ist das nichts anderes, als das interne aufteilen des 
inout-Signals in ein in- und ein out-Signal.

Autor: Mark (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi na,

Du musst direkt im Slave eine Anpassung machen.

Die Stelle wo SDA auf 0 gezogen wird kannst Du so lassen.
Dort wo SDA eingelesen wird kommt die Konvertierung von H auf 1 rein,
also m.E. gibts da auch die fertige Funktion to_X01() oder so...

Autor: na (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jan M.
Ja, das geht nur in meinem Fall nicht. Aus der Komponente kommt das 
bidirektionale Signal I2C_SDA. Dieses setze ich als Bus in der Testbench 
standardmaessig 'H', was dann eben auftritt, wenn niemand den Bus treibt 
bzw. bei I2C auch eine gueltige '1' darstellt. Damit der slave die '1' 
erkennt, wandle ich es um und lege das umgewandelte Signal an (an den 
bidirektionalen slave port). Will der slave nun aber das Signal treiben, 
liegt auf seinem Bus eine aktive '1'. Das ist das Problem.

@Mark
Danke, damit klappt es. Wollte/sollte zwar nichts mehr an dem slave 
aendern, aber solange das nicht die Synthese oder das Verhalten 
beeinflusst geht es wohl.

Autor: noob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
warum so umstaendlich ?!
i2c_sda <= '0' when (i2c_sda_out_int = '0') else 'Z';

schreiben tust du nun mit i2c_sda_out_int = 0/1. wenn du lesen willst 
einfach
i2c_sda_int auf 1 setzen und i2c_sda einlesen .

Autor: na (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@noob
Das hochohmig setzen wird komponentenintern gemacht. Die Testbench soll 
mir den Bus und die Kommunikation nachbilden und da gibt es kein 
zusaetzliches Richtungssignal.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.