Einführung
In einem FPGA hat jeder I/O-Port seinen eigenen kleinen Bereich auf dem Logik-Fabric. Dieser Bereich wird IOB (Input/Output Block) genannt und enthält alles, was die Funktionen des I/O-Ports unterstützt: analoge Schaltungen, die am Pin des I/O-Ports für korrekte Spannungen und Ströme sorgen, sowie einige spezielle Logikelemente.
An dieser Stelle möchte ich darauf hinweisen, dass der Begriff „IOB“ zur Terminologie von AMD (ehemals Xilinx) gehört. Jeder FPGA-Hersteller verwendet dafür einen anderen Begriff.
In einem IOB gibt es fast immer IOB-Register. Diese Register sind Flip-Flops, die direkt mit dem Pin des I/O-Ports verbunden sind.
Einige Flip-Flops sind für den Fall vorgesehen, dass der Pin als Eingang verwendet wird: Ihr D-Eingang ist mit dem Pin des I/O-Ports verbunden. Ein solches Flip-Flop übernimmt also die Abtastung (sampling) des von außen ankommenden Signals.
Andere Flip-Flops sind für den Fall vorgesehen, dass der Pin als Ausgang dient. Deren Q-Ausgang ist mit dem Pin verbunden.
Der Aufbau der IOBs ist von FPGA zu FPGA unterschiedlich. Manche IOBs sind komplex und funktionsreich, andere sind einfacher aufgebaut. Nicht selten ist das IOB-Register Teil eines größeren Logikelements, zum Beispiel eines SERDES. Selbst wenn also in der Zeichnung, die das IOB in der Dokumentation beschreibt, keine Flip-Flops explizit eingezeichnet sind, ist es dennoch möglich, dass die I/O-Pins des FPGAs über IOB-Register verfügen.
Warum IOB-Register verwenden?
Der Hauptgrund für den Einsatz von IOB-Registern ist das Timing: Wegen ihrer unmittelbaren Nähe zum Pin des I/O-Ports ist die so erreichte Clock-to-Output-Zeit unschlagbar. Auch für Eingänge hat ein IOB-Register die besten Aussichten, das geforderte Timing einzuhalten.
Aber selbst wenn es leichtfällt, die Timing-Anforderungen zu erfüllen, gibt es einen guten Grund, auf IOB-Registern zu bestehen: die Wiederholbarkeit. Andernfalls ist die Verzögerung zwischen dem Pin des I/O-Ports und dem Flip-Flop von Implementierung zu Implementierung des FPGA-Projekts unterschiedlich. Das liegt daran, dass die Tools das Flip-Flop jedes Mal an eine andere Stelle setzen können. Sie dürfen auch die Routing-Verzögerung verändern, solange die Timing-Vorgaben (englisch: timing constraints) erfüllt sind. Das ist so lange kein Problem, wie das Leiterplattendesign korrekt ist und die Schnittstelle zu den externen Komponenten sauber geplant wurde. Wenn solche Probleme aber tatsächlich vorliegen, kann der Unterschied in der Verzögerung von einer Implementierung zur nächsten Verwirrung stiften: Etwas funktioniert nicht, man repariert etwas am Design, und das Problem scheint gelöst. Doch was den Unterschied wirklich ausgemacht hat, war eine minimale Änderung des I/O-Timings an irgendeiner Stelle.
Der Einsatz von IOB-Registern stellt sicher, dass sich die elektrische Schnittstelle zu den externen Komponenten während der Entwicklung der FPGA-Logik nicht ungewollt ändert. Wenn Probleme auftreten, lassen sie sich dadurch leichter eingrenzen.
IOB-Register anfordern
Es kann erforderlich sein, den FPGA-Tools ausdrücklich mitzuteilen, dass sie IOB-Register verwenden sollen. Meist ist dafür das Synthesewerkzeug (englisch: synthesizer) zuständig. Ein Synthese-Attribut dieser Art kann mit Vivado verwendet werden:
(* IOB = "TRUE" *) input the_input,
Dasselbe ist auch in der XDC-Datei möglich:
set_property IOB true [get_ports the_input]
Eine weitere Möglichkeit besteht darin, das mit dem Eingang verbundene Register mit einem Synthese-Attribut zu versehen:
(* IOB = "TRUE" *) reg the_input_samp;
Zu beachten ist, dass ein Attribut in der XDC-Datei unter Umständen nicht ausreicht: Oft muss das Synthesewerkzeug Register replizieren, um Flip-Flops in den IOBs unterzubringen. Das ist immer dann relevant, wenn der Ausgang des Flip-Flops auch von der übrigen Logik im FPGA verwendet wird. Der Grund dafür ist, dass der Ausgang des Flip-Flops im IOB nur für den Port verwendet werden kann. Es wird daher ein weiteres Flip-Flop benötigt, das dasselbe Ausgangssignal erzeugt und in der Logikstruktur verwendet werden kann. In dieser Situation ist oft ein Synthese-Attribut (wie oben gezeigt) erforderlich.
Bei Quartus lassen sich Befehle dieser Art in die QSF-Datei eintragen:
set_instance_assignment -name FAST_INPUT_REGISTER ON -to the_input set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to the_output
Jedes Tool hat seine eigene Methode, das zu erreichen.
Timing-Constraints
Gibt es einen Grund, für einen Port, der ein IOB-Register verwendet, Timing-Constraints zu schreiben? Immerhin gibt es für das IOB-Register nur eine mögliche Position. Kann man daraus nicht gefahrlos den Schluss ziehen, dass das Timing mit oder ohne Timing-Constraints immer gleich ist?
Es gibt vor allem zwei gute Gründe, auch bei Verwendung von IOB-Registern Timing-Constraints zu schreiben.
Der erste Grund besteht darin, sicherzustellen, dass tatsächlich ein IOB-Register verwendet wird: Eine Änderung am Logikdesign kann mitunter ungewollt dazu führen, dass für alle oder einzelne Ports keine IOBs mehr zum Einsatz kommen. Die Tools beschweren sich darüber selten. Stattdessen wird stillschweigend ein Flip-Flop verwendet, das nicht im IOB liegt. Eine Timing-Constraint kann das verhindern: Wenn die Timing-Constraint nur erfüllt werden kann, wenn alle betreffenden Flip-Flops in ihren IOBs liegen, bleibt das Entfernen dieser Flip-Flops aus den IOBs nicht unbemerkt – die Timing-Constraint wird dann verletzt.
Der zweite Grund ist, dass die Tools eine absichtliche Verzögerung zwischen dem Pin des I/O-Ports und dem IOB-Register einfügen können (auch wenn nicht alle FPGAs diese Funktion unterstützen). Der Zweck dieser Verzögerung ist es, das Timing im Hinblick auf thold zu verbessern (siehe dieses Beispiel mit Quartus). Dieser unerwünschte Eingriff lässt sich mit einer Timing-Constraint verhindern, die nur ohne diese zusätzliche Verzögerung erfüllt werden kann.
set_max_delay ist normalerweise die geeignete Timing-Constraint, um eine konsistente Verwendung der IOB-Register sicherzustellen. Wenn die FPGA-Tools bei diesem Befehl die Option "datapath_only" unterstützen (oder eine ähnliche Funktion), ist das noch bequemer.
Fazit
IOB-Register sollten wann immer möglich verwendet werden. Die FPGA-Tools erledigen das nicht unbedingt von selbst; es kann also ein wenig Aufwand nötig sein, um dieses Ziel zu erreichen. Der Lohn für diese Mühe ist nicht nur optimales Timing, sondern auch ein reproduzierbares Verhalten der I/O-Ports.