VHDL: Wie kann der Open-Collector-Ausgang für FPGA richtig modelliert werden?

7

I2C verwendet Open-Collector-Ausgänge. FPGAs haben solche Ausgänge nicht. Sie haben jedoch Tri-State-Puffer.

  1. Wie sollte der Open-Collector-Ausgang in einer VHDL für ein FPGA definiert werden?
  2. Wie soll der Open-Collector-Ausgang in der Testbench hochgezogen werden? dh wie modelliert man den Pull-up-Widerstand zB auf einer SDA-Leitung, die Master mit Slave verbindet, in einer Testbench?
quantum231
quelle
Die Hauptschwierigkeit ist die Simulationsseite davon
quantum231

Antworten:

12

FPGAs haben Drei-Zustands-Ausgänge:

sda <= 'Z' when dout='1' else '0';

Manchmal gibt es auch optionale interne Pull-Ups, die jedoch keine externen Schaltkreise ansteuern sollen. Daher benötigt ein I2C-Bus einen tatsächlichen Pull-Up-Widerstand.

Der VHDL-Standardlogiktyp hat die Werte 'H' und 'L', um Pull-up und Pulldowns zu simulieren. Du kannst schreiben

sda <='H';

im Prüfstand, um einen Klimmzug zu simulieren.

std_logic ist ein "aufgelöster" Typ, ein Signal kann mehrere Treiber haben und eine Auflösungsfunktion wird verwendet, um den Endzustand zu bestimmen: 'Z' + 'H' = 'H', '0' + 'H' = '0'

TEMLIB
quelle
Aber ist 'Z' + 'H' = '1'? Dies ist der verwirrende Teil. Mit anderen Worten, wenn sowohl der Empfänger als auch der Sender 'Z' auf SDA fahren und dann einer von ihnen den Wert auf SDA liest, sollte er '1' erhalten, da er extern hochgezogen wird, oder?
Quantum231
5
Z + H = H. Aber to_01 (H) = 1, so dass H von nahezu jedem nachfolgenden Gate oder Prozess als 1 angesehen wird.
Brian Drummond
6

1) Laut Xilinx können Sie durch Erstellen eines Tristate-Geräts in VHDL einen Open-Collector / Drain-Ausgang anhand des folgenden Logikdiagramms modellieren:

Geben Sie hier die Bildbeschreibung ein

Der VHDL-Code:

dout <= 'Z' when din='1' else '0';

Der Verilog-Code (obwohl Sie speziell nach VHDL gefragt haben):

always @(ENABLE)
if (ENABLE)
DOUT = 1'bZ;
else
DOUT = 1'b0;

Code, Bild und Informationen finden Sie hier

2) Um Klimmzüge validieren zu können, würden Sie stattdessen logische HIGH- und LOW-Werte verwenden, d dout <= '1'. H. Sie sollten auch die Spezifikationen Ihrer Master- und Slave-Geräte überprüfen, welche Pull-Ups empfohlen werden.

KingDuken
quelle
2
Warum 5 Zeilen Verilog, wenn Sie nur können assign DOUT = ENABLE ? 1'b0 : 1'bz;? (Außerdem fungiert Ihr ENABLEals DISABLE, was den Code etwas verwirrend macht).
Das Photon
@ThePhoton Der Code stammt von der Xilinx-Website (wie in meiner Antwort erwähnt).
KingDuken
Danke König. Hier ist die Frage ausschließlich aus Simulationssicht. Wenn sowohl Sender als auch Empfänger 'Z' auf den SDA fahren und einer von ihnen den SDA einliest, wenn er nicht hochgezogen wird, muss er 'Z' einlesen. Wenn es hoch herausgezogen wird, sollte '1' lauten. Das Problem ist, wenn wir extern mit '1' hoch ziehen, dann kollidiert es mit dem SDA, der auf '0' getrieben wird, wie es bei offenen Kollektoren der Fall ist. Können wir 'H' verwenden? Weiß nicht, da ich es nie benutzt habe. Wenn das Lesen extern zu 'H' und intern zu 'Z' geführt wird, ergibt das interne Lesen dann '1' oder 'H'?
Quantum231
5

Beachten Sie, dass FPGA-Designtools manchmal ein bestimmtes Open-Drain-Grundelement in ihrer Bibliothek bereitstellen. ZB in Quartus II können Sie schreiben

LIBRARY altera;
USE altera.altera_primitives_components.all; 
sda: opndrn PORT MAP (
a_in => sda_wire,
a_out => sda_pin
);

Dies sollte für einen Bidir-E / A-Pin keinen Unterschied machen, kann jedoch einen Unterschied machen, wenn Sie einen Nur-Ausgabe-Pin verwenden oder Ihr Design auf ASIC migrieren müssen. Es macht Ihren Code jedoch herstellerspezifisch.

Dmitry Grigoryev
quelle