Ach mist. das hab ich Total verpennt...
Heute ist der Silberdraht gekommen, da ists mir wieder eingefallen -.-
Video gibts zwar nicht, aber dafür hab ich mal ein paar Fotos gemacht...
Hier der Würfel in Aktion, mit Testbild.
Sonst hätte ich im Augenblick noch die Standart-Animationen wie Ebenen, Fading, Regen usw anzubieten. Aber nichts besonderes
Die LEDs sind leider bemerkenswert scheisse, so dass man die eigentlich nur bei Nacht sieht (restekiste halt). Entsprechend schlecht ist das foto, sry deswegen -.-
hier mal der ganze Aufbau aus FPGA-Board und Cube...
Der Würfel im detail
Die Transistoren sind BC557C, mit 220ohm Vorwiederstand. Diese ziehen je eine Ebene auf masse.
Die Vorwiderstände der LEDs sind unter dem klebeband.
Das Board hat einen Altera Cyclone 2 EP2C5 drauf, und einen SDRAM mit 32MB. Gabs auf ebay für ~20€. Der USB-Blaster kostet nochmal 4€.
Das FPGA steuert je 16 LEDs (also eine Ebene, 4x4) auf einmal an.
Für den 10er Würfel werde ich auf 32 Ausgänge + D-Latches umsteigen müssen, mangels IO-Pins.
Das Design besteht aktuell aus einem NIOS 2 System, und einem Display Controller.
Die einzige Aufgabe des NIOS ist es, das Bild zu generieren, und in den Grafikspeicher abzulegen.
Zum Design: * Natürlich Der NIOS-Prozessor, in der /e version. Die größeren hätten zwar noch reingepasst, aber die muss man lizensieren.
* ein SDRAM-controller, für den Onboard-RAM. 32MB Programm und Daten
* ein Timer, aktuell noch nicht programmierbar (habs am anfang nicht hinbekommen ). Erzeugt alle 50ms ein interrupt. (also 20 mal/sec).
* ram_c, das ist ein Dual-Port SRAM, dazu später mehr
* rng, ein hardware-zufallsgenerator (aus opencores.org, leicht modifiziert)
* addshift, eine Custom-instruction für den NIOS, soll die berechnung der Addressen für den Garfikspeicher vereinfachen.
* und der eigentliche Display Controller... interessanterweise der am Wenigsten (Zeit)aufwändigste Teil....
Das Teil macht eine 14 bit-PWM, davon 10 bit gamma-Korrektur.
Diese wird direkt von der Hardware erledigt, Funktioniert, ist aber noch Optimierungsfähig
Der Display-controller besteht aus 2 teilen:
matrixcomp und Cube_top. Cube-Top enthält nebenbei auch noch das NIOS-System.
zur Funktion:in Cube_top gibt es 2 relevante Register:
[13:0]pwmcnt und [1:0]level_cnt.
Die oberen 4 bit [13:10] von pwmcnt sind für die Helligkeit der LED, die ersten 10 sind für die gamma-korrektur.
level_cnt zählt die Ebenen durch. Da es nur 4 Ebenen gibt (noch
) reichen 2 bit aus.
level_cnt dient auch gleichzeitig als Addresse für den Grafikspeicher (ram_c).
Pro Takt wird pwmcnt um 1 erhöht. Wenn die ersten 10 bit überlaufen, wird ein neuer Startwert gesetzt, zwecks gamma-korrektur.
Bei einem kompletten durchlauf von pwmcnt wird level_cnt um 1 erhöht.
assign level_out = ~(4'b0001 << level_cnt);
dient zum ansteuern der Ebenen-Transen. Die 1 wird um level_cnt stellen nach links geshiftet und Negiert (weil die BC557C PNP Transen sind...)
Der Ausgang des Grafikspeichers ist 64 Bit breit (4 bit/LED, 16 LEDs), und wird an das Modul matrixcomp angeschlossen (über wire [63:0]matrixdata). Das Erledigt der generate-Block.
Je eine Instanz von matrixcomp steuert eine LED an. (entsprechend gibt es 16 Instanzen...)
Es macht eigentlich nichts anderes, als den Aktuellen wert der letzten 4 bit von pwmcnt mit der erwünschten Helligkeit zu vergleichen. Je nach dem wird das Ausgangsbit gesetzt oder eben nicht...
Zu ram_c:Um das ganze einfach zu halten, hab ich einfach ein paar der Internen Speicherzellen für den grafikspeicher genommen.
Da der NIOS ein 32-Bit prozzi ist, und man, um 4 Bit werte in den RAM schreiben zu können, tierisch viel (unnötige) bitschubserei machen muss, hab ich kurzerhand diese kleine Modul gebastelt, was aus einem 8-bit schreibzugriff einen 4bit-schreibzugriff macht.
Die oberen 4 Bit werden einfach Ignoriert. Bei einem Lesezuriff werden die als 0 gelesen.
So Wird aus einem 8bit ein 4 bit zugriff, 16 zu 8 und 32 zu 16 bit.
Damit lassen sich die einzelnen LEDs bequem mit dem Datentyp char addressieren, ganz ohne bitschubserei.
mit einem Short kann man 2 LEDs gleichzeitig steuern, ein Int 4.
zu addshift:das problem beim Addressieren war jetzt nurnoch, dass ich 2 Shifts und 4 Additionen durchführen musste (Addresse = offset + x + y << 2 + ebene << 4)
Was für den Nios mehrere Anweisungen sind, ist für das FPGA eine Sache von 1 taktzyklus. So habe ich dann eine Custom-instruction gebaut die das ganze in 2 Anweisungen erledigt.
==== Download ====Es ist mir nicht gelungen, den Projektordner aufzuräumen, ohne irgendwas wichtiges zu löschen...
nach dem ersten bauen wären die dateien eh wieder da, also was solls
Geschrieben in Verilog, die *.v dateien sind also die interessanten.
DOWNLOAD
Zuletzt bearbeitet: 26.05.13 02:53 von felixh