Vivado: Picasso-Modus

Anmerkung


Madness All Ages Devot


Beim Entwerfen von Modulen auf FPGAs fällt manchmal die Idee ein, dass die Entwurfsumgebung selbst und die darin enthaltenen Tools nicht ganz normal verwendet werden. In diesem kurzen Artikel werden wir uns ansehen, wie wir mit Hilfe des in Tcl implementierten Umweltmanagement-Tools buchstäblich Fotos, Gemälde, Porträts und Memesics auf dem FPGA zeichnen können.


Eine solche ungewöhnliche „Designroute“ wurde vor eineinhalb Jahren implementiert, aber erst jetzt kam die Idee, sie in Form einer Notiz anzuordnen, in der es wenig Übung gibt, Tcl-Skripte zum Verwalten der Designumgebung zu verwenden, in diesem Fall Vivado. Mit geringfügigen Änderungen kann jedoch alles problemlos an andere Entwicklungsumgebungen angepasst werden, z. B. Quartus II.



Einleitung


Die Idee kam natürlich nicht von ungefähr. Sein Auftreten wurde durch meine damalige Beschäftigung in Projekten zur Bildverarbeitung und zum Videostream-Management auf FPGA gefördert. Es passiert jedem, dass beim Überdenken einer Problemlösung jede Häresie in den Sinn kommt, warum es nicht funktioniert oder genau so funktioniert, wie es sollte, aber nicht so, wie wir es erwarten.


Bei der Lösung des Problems musste ich auf eines der Tools der Vivado-Umgebung zurückgreifen, nämlich die entsprechenden Komponenten und Module im Projekt nach der Platzierung einzufärben, aufzuspüren und in endlose Zeitdiagramme zu blicken.


Als Ergebnis habe ich mehrere konfigurierbare logische Blöcke von CLB in verschiedenen Farben gezeichnet, und es dämmerte mir - dies sind die Pixel des Bildes, damit ich versuchen kann, den Faden des Bildes zu zeichnen, wobei jedes Pixel mit seinem eigenen farbigen CLB übereinstimmt


Wie hilft uns Tcl?


Angenommen, wir haben ein kleines Bild mit einer Größe von 100 x 100 Pixel. Angenommen, um die CLB einzufärben, müssen wir zwei Dinge tun: Wählen Sie die CLB aus und wählen Sie die Farbe aus. Im 100x100-Bild haben wir 10.000 Pixel und es ist ziemlich mühsam, eine solche Färbung manuell vorzunehmen, zumal die Aktionen die gleichen und sich wiederholenden sind. Manuelles Zeichnen jeder CLB ist daher keine Option und Sie müssen Tcl und Skripte verwenden. Aber wo soll ich anfangen?


Das erste, was mir in den Sinn kam, war, das richtige Team zu finden, das dem ausgewählten Element Farbe verleiht. Glücklicherweise zeigt Vivado beim manuellen Ausführen von Aktionen die entsprechenden Tcl-Befehle an der Konsole an, und es scheint, dass das Suchproblem so schnell wie möglich behoben werden sollte. Es war jedoch nicht da. Vivado ignoriert einfach die Ausgabe des Befehls, um die ausgewählten Elemente hervorzuheben, und die einzige Option, um den Befehl zu finden, und ich war mir absolut sicher, dass es so sein sollte, ist, kopfüber in die in Vivado verfügbare Tcl-Anleitung einzutauchen, und das sind fast 2000 Seiten [1].


Verzweifle nicht, das Schlüsselwort "highlight" fand schnell den entsprechenden Befehl, der highlight_objects heißt. Dieser Befehl hebt die angegebenen oder ausgewählten Objekte in einer bestimmten Farbe hervor, die mithilfe von Optionen festgelegt wurde. Die Optionen für den Befehl highlight_objects lauten wie folgt:


- color_index - (optional) Der gültige Wert des Optionsarguments muss eine Zahl von 1 bis 20 sein. Die Farbe, in der das ausgewählte Objekt gezeichnet wird, wird durch die Seriennummer aus der vordefinierten Farbpalette bestimmt, die Sie unter Farben → Hervorheben im Menübereich Extras → Einstellungen finden .
- rgb - (optional) legt die Farbe des ausgewählten Objekts im RGB-Format fest
- Farbe - (optional) hebt das ausgewählte Objekt in einer der folgenden Farben hervor: Rot, Grün, Blau, Magenta, Gelb, Cyan und Orange


Die übrigen Optionen des Befehls beziehen sich auf die Systemeinstellungen des Befehls selbst und sind für uns nicht nützlich. Beachten Sie jedoch, dass bei Verwendung des Befehls highlight_objects nicht zwei oder mehr Farboptionen gleichzeitig angewendet werden können.
Natürlich ist eine Option, die eine beliebige Farbe im RGB-Format festlegt, für unsere Aufgabe geeignet - die Option rgb


Jetzt wäre es nicht schlecht, die Pixelwerte des Bildes zu erhalten, aber ich konnte das Bild nicht finden, das im Bitmap-Format dargestellt werden würde. Beim Öffnen jeder Datei mit einem Texteditor konnten keine Zeilen mit einem Pixelwert gefunden werden. Natürlich habe ich kein Programm zum Konvertieren von Bildern in das Bitmap-Format geschrieben, sondern einfach im Internet nach einer schlüsselfertigen Lösung gesucht. Die Suche dauerte nicht lange. Wie sich herausstellte, ist die Aufgabe, ein Bild in ein Bitmap-Format zu konvertieren (d. H. Wenn wir die Pixelwerte eines unkomprimierten Bildes sehen), ziemlich relevant (wahrscheinlich wird eine solche Aufgabe Studenten-Programmierern als Hausaufgabe für die Laborarbeit übertragen). Es ergab sich eine kurze Suche nach github, von wo das Programm Image2Bitmap heruntergeladen wurde [2].


Das Programm benötigt eine Bildeingabe und gibt Pixelwerte in Form eines s-Arrays mit hexadezimalen Pixelwerten im RGB565-Format aus. Dieses Format besagt, dass die Farbcodierung für die rote Komponente 5 Bit, grüne 6 Bit und blaue 5 Bit verwendet. Dies erwies sich als ausreichend für die Arbeit. Jetzt müssen nur noch die erhaltenen Werte direkt auf die lackierten Schnitte (Slice) abgebildet werden.


FPGA-Auswahl


Je größer das FPGA ist, desto logischer sind die Ressourcen, und daher ist das „Feld für Kreativität“ selbst größer und das Bild wird klarer. Es sollte sofort angemerkt werden, dass das „Dekorieren“ ein ziemlich langer Prozess ist und abhängig von der Größe des Bildes eine angemessene Zeitdauer in Anspruch nehmen kann. Zum Testen lohnt es sich, ein FPGA mit geringem Ressourceneinsatz zu wählen. Zum Beispiel die Spartan-7-Familie. Nach dem Testen können Sie das FPGA beispielsweise aus der Ultrascale + -Familie auf "fett" umstellen.


  1. Wir starten Vivado und erstellen das Projekt


  2. Wir wählen den Kristall xc7s6cpga196-2 aus, auf den wir das Testbild zeichnen werden


  3. Um die Zeichnung anzuzeigen, müssen wir das Bild des Kristalls selbst öffnen, dies kann jedoch nach der Synthesestufe erfolgen oder aufwändig sein. In Vivado müssen wir dazu ein Dummy-Modul in einer beliebigen Sprache erstellen.


  4. Fügen Sie dem Tcl-Projekt ein Skript hinzu.
    a. Erstellen Sie dazu eine Datei mit der Erweiterung „.tcl“ in dem Ordner mit dem Projekt, z. B. „fpga_painter.tcl“.


    b. Gehen Sie zu Vivado und fügen Sie diese Datei dem Projekt hinzu.


    c. Deaktivieren Sie die Datei nach dem Aktualisieren der Projekthierarchie.


  5. Nach dem Erstellen des Moduls wird es im Projekthierarchie-Fenster angezeigt und die Schaltfläche Open Elaborate Design steht uns zur Verfügung. Schieben Sie es.


  6. Gehen Sie nach dem Öffnen von Elaborate Design zu Fenster → Gerät. Es erscheint eine Anzeige des Feldes unseres FPGA.


  7. Die Vorbereitung ist beendet, wir schreiben ein Skript.



Definition von Parametern und Prozeduren


Testbild


Debuggen wir zunächst den Algorithmus / Code als solchen auf einem kleinen Bild, beispielsweise 5x3, und führen Sie ihn dann "vollständig" aus.


  1. Öffnen Sie Paint, beschränken Sie das Bildfeld auf 5 x 3 Pixel (Sie können beliebige Farben verwenden). Speichern Sie die Datei als "5x3.png"


  2. Öffnen Sie das Programm Image2Bitmap und konvertieren Sie unser Bild in ein RGB565-Array.


  3. Nach der Konvertierung gibt uns das Programm ein Array von 15 Pixeln



*uint16_t image = { 0xf800, 0x07e0, 0x001f, 0x8410, 0x8010, 0xfbe4, 0xff80, 0x2589, 0x051d, 0x3a59, 0xa254, 0xbbca, 0xfd79, 0xef36, 0x9edd, };* 

Datenaufbereitung


Bevor wir mit der Verarbeitung von Pixeln fortfahren, transformieren wir die von Image2Bitmap generierten Daten in eine einfache Liste, in die hexadezimale Pixelwerte geschrieben werden. Wir kopieren die Programmdaten und speichern sie in der Datei pic_array.dat, die sich im Projektordner befinden sollte.



Beim Start des erstellten Skripts müssen wir die Datei "pic_array.dat" verarbeiten. Es ist zu beachten, dass die Anzahl der Elemente in der von Image2Bitmap zurückgegebenen Zeile nicht mit der Anzahl der Pixel in der Zeile des konvertierten Bildes übereinstimmt. Aus diesem Grund erstellen wir eine separate Liste von "Pixeln".



Beim Lesen einer Datei müssen Sie die erste Zeile "uint16_t image = {" und die letzte "};" ignorieren. Um die erste Zeile beim Lesen einer Datei zu überspringen, platzieren wir einfach die Zeile vor dem Zyklus des Lesens der gesamten Datei.



Nach dem Lesen der gesamten Datei sehen wir, dass die letzte Zeile der Datei „};“ zu einem Element der Liste geworden ist, das einfach gelöscht wird.



Dies vervollständigt die Bildung der Liste mit hexadezimalen Pixelwerten. Jetzt fangen wir an, sie zu verarbeiten.


Bildgröße


Schauen Sie sich noch einmal das FPGA-Feld und das Bild an. Das FPGA-Feld ist in Abschnitte (SLICE) unterteilt, die die entsprechenden horizontalen Koordinaten "X" und vertikalen "Y" haben. Zum Beispiel SLICE_X6Y36.



Das Bild hat wiederum Pixel, auch mit horizontalen und vertikalen Koordinaten. Wenn Sie das Bild auf dem FPGA überlagern, sollten Sie das obere linke Pixel mit dem oberen linken Abschnitt des FPGA kombinieren. In diesem Fall hat der ausgewählte Kristall einen oberen Bereich mit der Koordinate X0Y49.



Die Bildgröße wird durch die Anzahl der Abschnitte im FPGA horizontal und vertikal bestimmt. Für den ausgewählten Kristall variiert die horizontale Koordinate der Schnitte von X0 bis X131 und die vertikale Koordinate von Y49 bis Y0. Daraus folgt, dass wir theoretisch ein Bild der Größe 132x50 auf dem ausgewählten Kristall zeichnen können.


Anfangsparameter


Zusammenfassend: Die Anfangsparameter unseres Skripts sind:


  1. X Startposition des Abschnitts: Variablenname start_x


  2. Startposition des Abschnitts auf der y-Achse: Variablenname start_y


  3. Bildbreite (für Testbild ist 5): Variable w


  4. Bildhöhe (für Testbild ist 3): Variable h



Anpassung der Pixelfarbe


Image2Bitmap bietet eine Reihe von Pixeln im RGB565-Format als 16-Bit-Zahl im Hexadezimalformat. Wir sollten:


  1. Konvertiert den Pixelwert in das Binärformat. Dies kann mit dem hex2bin-Verfahren durchgeführt werden, das in [3] zu finden ist.


  2. Ordnen Sie die Bits den entsprechenden Farbkomponenten zu:
    • Die rote Komponente von R [15:11]


    • Grünkomponente G [10: 5]


    • Blaue Komponente B [4: 0]



Erläuterung: Die Reihenfolge wird geändert, weil die hex2bin-Prozedur eine Zeichenfolge zurückgibt, in der die Nummerierung der Elemente mit 0 beginnt, dh das 15. Bit entspricht dem 0. Element der Zeichenfolge und das 0. Bit dem 15. Element der Zeichenfolge


  1. Konvertieren Sie den Wert der Farbkomponente von binär in dezimal. Dies kann mit der bin2dec-Prozedur durchgeführt werden, die zu finden ist [3]:




  2. Konvertieren Sie die Pixelwerte von RGB565 in das RGB888-Format, um eine flüssigere Bildanzeige zu erzielen. Dies geschieht mit zwei Listen, die in [4] zu finden sind. Wie es funktioniert:
    • Die Auflösung der Farbkomponenten R und B beträgt 5 Bit. Der Dezimalwert der Komponente wird mit der Position der in die Liste t5 geschriebenen Zahl verglichen, und der Wert der Komponente ändert sich in den Wert in der Tabelle






    • Ähnlich für Komponente G und Tabelle t6





Abschnitt Verfügbarkeit


In einigen FPGAs gibt es spezielle Ressourcen oder Lücken, die die fortlaufende Nummerierung der Schnittkoordinaten stören können. In der folgenden Abbildung sehen Sie beispielsweise, dass die Abschnittsnummerierung unterbrochen ist (xc7s50-Kristall).


Aus diesem Grund prüfen wir vor dem Anfärben zunächst das Vorhandensein des Schnitts. Wenn es existiert, dann male, wenn es nicht existiert, dann gehe zum nächsten Pixel


Schnittfärbung


Abschnittsfarbe definiert, Abschnitt geprüft. Jetzt muss die Farbe mit dem Befehl highlight_objects den Abschnitten zugewiesen werden:


Vektor → Zweidimensionales Array


Zu Beginn haben wir die Bilddaten in eine Liste von Pixeln konvertiert, in denen ein progressiver Scan des Bildes gespeichert ist. Um das Bild zu organisieren, führen wir zwei Variablen ein, x und y, die der Position der Pixel im Bild entsprechen. Durch sequentielles Lesen der Elemente der Pixelliste wird ein Bild mit zwei for-Schleifen erzeugt: eine durch die Anzahl der Zeilen, die zweite durch die Position des Pixels in der Zeile




Vollständige Skriptliste


Fpga_painter.tcl Auflistung
 #https://tcl.tk/ #http://www.tune-it.ru/web/il/home/-/blogs/-rgb888-<->-rgb565----- #https://github.com/FoxExe/Image2Bitmap/releases/tag/0.5 #        set start_x 0; # set start_y 49; # set w 5; #  (   ) set h 3; #  ( ) proc hex2bin hex { set t [list 0 0000 1 0001 2 0010 3 0011 4 0100 \ 5 0101 6 0110 7 0111 8 1000 9 1001 \ a 1010 b 1011 c 1100 d 1101 e 1110 f 1111 \ A 1010 B 1011 C 1100 D 1101 E 1110 F 1111] regsub {^0[xX]} $hex {} hex return [string map -nocase $t $hex] } proc bin2dec bin { #returns integer equivalent of $bin set res 0 if {$bin == 0} { return 0 } elseif {[string match -* $bin]} { set sign - set bin [string range $bin[set bin {}] 1 end] } else { set sign {} } foreach i [split $bin {}] { set res [expr {$res*2+$i}] } return $sign$res } ############### #RGB565 -> RGB888 using tables set t5 [list 0 8 16 25 33 41 49 58 66 74 82 90 99 107 115 123 132\ 140 148 156 165 173 181 189 197 206 214 222 230 239 247 255] set t6 [list 0 4 8 12 16 20 24 28 32 36 40 45 49 53 57 61 65 69\ 73 77 81 85 89 93 97 101 105 109 113 117 121 125 130 134 138\ 142 146 150 154 158 162 166 170 174 178 182 186 190 194 198\ 202 206 210 215 219 223 227 231 235 239 243 247 251 255] ############### #  .         set script_path [get_property DIRECTORY [get_projects *]] cd $script_path #       set fId [open {pic_array.dat} r] # ,       set pixels [list ] #    .    gets $fId line #  .     . while {[gets $fId line] > 0} { set pixels [concat $pixels $line] } #   pixels   "};",    Image2Bitmap set pixels [lrange $pixels 0 end-1] #    pixels set pix_num 0; #      for {set y 0} { $y < $h } {incr y} { #    ( ) set Y [expr {$start_y - $y}] #    for {set x 0} { $x < $w } {incr x } { set pix_val [lindex $pixels $pix_num]; incr pix_num #   binary  set pix_bin [hex2bin $pix_val] ; #     set R_bin [string range $pix_bin 0 4] #    set R_dec [ bin2dec $R_bin ] #       t5 set R [lindex $t5 $R_dec] #       set G_bin [string range $pix_bin 5 10] set G [lindex $t6 [ bin2dec $G_bin ]] set B_bin [string range $pix_bin 11 15] set B [lindex $t5 [ bin2dec $B_bin ] ] #    set X [expr {$start_x + $x}] #,      set cond [get_sites "SLICE_X${X}Y${Y}"] if {$cond ne ""} { #  highlight_objects [get_sites "SLICE_X${X}Y${Y}"] -rgb "$R $G $B" } puts "X = $XY = $Y; $R $G $B" } } close $fId puts "Complete::Check FPGA field::Window->Device" 

Testen


  1. Stellen Sie vor dem Testen sicher, dass das FPGA-Feld für Sie verfügbar ist, d. H. Eine der Entwurfsphasen ist offen: ausgearbeitet, synthetisiert oder implementiert. Um das FPGA-Feld anzuzeigen, wählen Sie Fenster → Gerät


  2. Öffnen Sie die Datei pic_array.dat und kopieren Sie die Daten von Image2Bitmap in die Datei. Datei speichern


  3. Lassen Sie uns das Skript öffnen. Stellen Sie die Koordinaten der oberen linken Pixel 0 und 49 ein, die Größe des Testbilds beträgt 5 x 3, und führen Sie das Skript aus. Klicken Sie dazu mit der rechten Maustaste in das Skriptfeld und wählen Sie Ausführen.


  4. Gehen Sie zur Tcl-Konsole und stellen Sie sicher, dass das Skript ausgeführt wurde.


  5. Gehen Sie zur Registerkarte Gerät und stellen Sie sicher, dass die Zellen in der entsprechenden Farbe gefärbt sind.


  6. Jetzt können wir ein beliebiges Bild aufnehmen, es in die gewünschte Größe konvertieren und das FPGA-Feld ausfüllen. Nachfolgend einige Beispiele.



PS: Die benutzerdefinierte Farbzuweisung ersetzt die Standardfarbeinstellung von Vivado


Referenzliste


  1. UG835. Vivado Design Suite TclCommand Referenzhandbuch
  2. https://github.com/FoxExe/Image2Bitmap/releases/tag/0.5
  3. https://tcl.tk
  4. http://www.tune-it.ru/web/il/home/-/blogs/conversion-rgb888 - <-> -rgb565-und-schutz-pilze-vor-verblassen

Source: https://habr.com/ru/post/de477974/


All Articles