Für ein Projekt an der Uni habe ich mit zwei Kommilitonen ein Malprogram („FPGArt“) auf einem FPGA implementiert. Dabei wird eine Maus per PS/2-Schnittstelle angebunden und das Bild schließlich per VGA ausgegeben. Zu dem Projekt selber später vielleicht mehr, hier jetzt nur ein kleines VHDL-Snippet das man vielleicht man gebrauchen kann.
In dem Projekt wird regelmäßig die relative Bewegung der Maus abgefragt und zu dem alten Wert addiert. Natürlich hat das Bild eine begrenze Größe und der Mauszeiger muss in diesen Grenzen von 800×600 gehalten werden. Es wird also eine sog. Sättigungsarithmetik benötigt: Sollte das Ergebnis der Addition größer als 800 (bzw. 600) sein, oder kleiner als 0 wird es auf den Grenzwert gesetzt. Das ganze ist gar nicht so einfach in Hardware zu implementieren (zumindest ist uns nichts intelligentes eingefallen…).
In jedem Fall muss es ein Zwischenergebnis geben das ausreichend groß ist, um Überläufe überhaupt zu erkennen. Die Maus kann pro Intervall Maximal um 256 bewegt werden, entsprechend muss als ein Wert von 800+256 = 1056 gespeichert werden können. Mit 11 bit kommt man auf 2048, das reicht. Hiermit kann man auch Unterläufe erkennen: 0-256 = -256 was dann 1792 entspricht. Dieser Bereich überlappt auch nicht mit den 1056 nach oben. Es ist also immer einwandfrei erkennbar, dass ein Über/Unterlauf stattgefunden hat.
Unsere erste Idee war nun, einfach in jedem Takt zu prüfen, ob das Ergebnis größer als 800 ist (Überlauf) oder größer als 1792 (Unterlauf), und den Wert dann auf 800 bzw. 0 zu setzen. Leider lag dann noch einen Takt das falsche Ergebnis im Register, was nicht so gut war. Der folgende Code realisiert die Überprüfung direkt in der Addition. In Hardware wird ein ziemlicher Wust aus Multiplexern daraus, entsprechend ist das ganze vermutlich nicht besonders schnell. Es werden VHDL-Variablen benutzt um die Lesbarkeit zu erhöhen:
https://gist.github.com/nrother/2441334546a0f3b09ef63d6eb7aa7bf9
Man kann das bestimmt noch intelligenter lösen, vielleicht mit einem speziellen Addierer, der Sättigungsarithmetik unterstützt, aber so funktioniert es auf jeden Fall 😉