Vivado: mode Picasso

Annotation


Folie tous âges soumis


Lors de la conception de modules sur FPGA, l'idée d'une utilisation pas tout à fait standard de l'environnement de conception lui-même et des outils qu'il fournit pour la conception vient parfois à l'esprit. Dans ce court article, nous verrons comment, à l'aide de l'outil de gestion environnementale implémenté sur Tcl, nous pouvons littéralement dessiner des photographies, des peintures, des portraits et des memesics sur le FPGA.


Un tel «itinéraire de conception» inhabituel a été mis en place il y a un an et demi, mais ce n'est que maintenant que l'idée est venue de l'organiser sous la forme d'une note, dans laquelle il est peu pratique d'utiliser des scripts Tcl pour gérer l'environnement de conception, en l'occurrence Vivado. Cependant, avec des modifications mineures, tout peut facilement être adapté à d'autres environnements de développement, par exemple Quartus II.



Présentation


Bien sûr, l'idée n'est pas venue de nulle part. Son apparition a été favorisée par mon emploi à l'époque dans des projets de traitement d'images et de gestion de flux vidéo sur FPGA. Il arrive à tout le monde qu'en s'asseyant sur une solution à un problème, chaque hérésie vient à l'esprit pourquoi cela ne fonctionne pas ou fonctionne exactement comme il se doit, mais pas comme nous nous y attendons.


Pour résoudre le problème, j'ai dû recourir à l'un des outils de l'environnement Vivado, à savoir colorier les composants et modules correspondants dans le projet après le placement et le traçage et regarder les chronogrammes sans fin.


En conséquence, j'ai peint plusieurs blocs logiques configurables de CLB dans différentes couleurs, et cela m'est apparu - ce sont les pixels de l'image, donc je peux essayer de dessiner quel fil l'image est, en faisant correspondre chaque pixel avec son propre CLB coloré? ... eh bien, ça a commencé


Comment Tcl va-t-il nous aider?


Supposons que nous ayons une petite image de taille 100x100 pixels. Supposons maintenant que pour colorer le CLB, nous devons faire deux choses: sélectionner le CLB et sélectionner la couleur. Dans l'image 100x100, nous avons 10 000 pixels et faire une telle coloration manuellement est assez fastidieux, d'autant plus que les actions sont les mêmes et répétitives. Ainsi, peindre manuellement chaque CLB n'est pas une option et vous devez utiliser Tcl et des scripts. Mais par où commencer?


La première chose qui m'est venue à l'esprit a été de trouver la bonne équipe responsable de l'attribution de la couleur à l'élément sélectionné. Heureusement, lors de l'exécution manuelle des actions, Vivado affiche les commandes Tcl appropriées sur la console, et il semble que le problème de recherche devrait être résolu le plus rapidement possible. Mais ce n'était pas là. Vivado ignore simplement la sortie de la commande pour mettre en évidence les éléments sélectionnés, et la seule option pour trouver la commande, et j'étais absolument sûr qu'elle devrait l'être, est de plonger tête baissée dans le guide Tcl disponible dans Vivado, et cela fait presque 2000 pages [1].


Ne désespérez pas, le mot clé "highlight" a rapidement trouvé la commande correspondante, qui s'appelle highlight_objects. Cette commande met en évidence les objets spécifiés ou sélectionnés dans une couleur spécifique, spécifiée à l'aide d'options. Les options de la commande highlight_objects sont les suivantes:


- color_index - (facultatif) la valeur valide de l'argument option doit être un nombre compris entre 1 et 20. La couleur dans laquelle l'objet sélectionné sera peint est déterminée par son numéro de série dans la palette de couleurs prédéfinie, qui se trouve dans Couleurs → Surbrillance dans la section de menu Outils → Paramètres .
- rgb - (facultatif) définit la couleur de l'objet sélectionné au format RVB
- couleur - (facultatif) met en surbrillance l'objet sélectionné dans l'une des couleurs suivantes: rouge, vert, bleu, magenta, jaune, cyan et orange


Les options restantes de la commande se rapportent aux paramètres système de la commande elle-même et ne nous seront pas utiles. Cependant, lorsque vous utilisez la commande highlight_objects, gardez à l'esprit que deux ou plusieurs options de coloration ne peuvent pas être appliquées en même temps.
De toute évidence, une option qui définit une couleur arbitraire au format RVB convient à notre tâche - l'option RVB


Maintenant, il ne serait pas mauvais d'obtenir les valeurs en pixels de l'image, mais je n'ai pas pu trouver l'image qui serait présentée au format bitmap. En ouvrant chaque fichier avec un éditeur de texte, il n'était pas possible de trouver des lignes avec une valeur en pixels. Bien sûr, je n'ai pas écrit de programme de conversion d'images au format bitmap, mais j'ai simplement grimpé sur Internet pour chercher une solution toute faite. La recherche n'a pas été trop longue. Il s'est avéré que la tâche de convertir une image au format bitmap (c'est-à-dire lorsque nous voyons les valeurs en pixels d'une image non compressée) est tout à fait pertinente (probablement, une telle tâche est confiée aux étudiants-programmeurs comme devoir pour les travaux de laboratoire). Une courte recherche a résulté sur github, d'où le programme Image2Bitmap a été téléchargé [2].


Le programme nécessite une entrée d'image et génère des valeurs de pixels sous la forme d'un tableau s avec des valeurs de pixels hexadécimales au format RGB565. Ce format indique que le codage couleur du composant rouge utilise 5 bits, 6 bits verts et 5 bits bleus. Cela s'est avéré suffisant pour le travail. Maintenant, tout ce qui est nécessaire est de mapper les valeurs obtenues directement sur les sections peintes (tranche).


SĂ©lection FPGA


Plus le FPGA est grand, plus ses ressources sont logiques, et donc le «champ de créativité» lui-même est plus grand et l'image sera plus claire. Il convient de noter tout de suite que la «décoration» est un processus assez long et peut prendre un temps décent, selon la taille de l'image. Pour les tests, il vaut la peine de choisir un FPGA avec une petite quantité de ressources. Par exemple, la famille Spartan-7. Après le test, vous pouvez changer le FPGA en plus "gras", par exemple, de la famille Ultrascale +.


  1. On démarre Vivado et on crée le projet


  2. Nous sélectionnons le cristal xc7s6cpga196-2, sur lequel nous allons dessiner l'image de test


  3. Pour afficher le dessin, nous devons ouvrir l'image du cristal lui-même, cependant, cela peut être fait après la phase de synthèse ou élaboré. Dans Vivado, pour cela, nous devons créer un module factice dans n'importe quelle langue.


  4. Ajoutez un script au projet Tcl.
    a. Pour ce faire, créez un fichier avec l'extension «.tcl» dans le dossier avec le projet, par exemple, «fpga_painter.tcl»


    b. Accédez à Vivado et ajoutez ce fichier au projet.


    c. Après avoir mis à jour la hiérarchie du projet, désactivez le fichier.


  5. Après avoir créé le module, il apparaîtra dans la fenêtre de hiérarchie du projet et le bouton Ouvrir la conception élaborée sera disponible pour nous. Poussez-le.


  6. Après avoir ouvert Elaborate Design, accédez à Fenêtre → Appareil. Un affichage du champ de notre FPGA apparaîtra.


  7. La préparation est terminée, nous commençons à écrire un script.



Définition des paramètres et des procédures


Image de test


Commençons par déboguer l'algorithme / le code en tant que tel sur une petite image, disons 5x3, puis exécutons-le «au maximum».


  1. Ouvrez Paint, limitez le champ d'image à 5x3 pixels (vous pouvez prendre toutes les couleurs). Enregistrez le fichier sous «5x3.png»


  2. Ouvrez le programme Image2Bitmap et convertissez notre image en un tableau RGB565.


  3. Après la conversion, le programme nous donnera un tableau de 15 pixels



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

Préparation des données


Avant de procéder au traitement des pixels, nous transformons les données générées par Image2Bitmap en une simple liste dans laquelle les valeurs hexadécimales des pixels sont écrites. Nous allons copier les données du programme et les enregistrer dans le fichier pic_array.dat, qui devrait se trouver dans le dossier du projet.



Lors du démarrage du script créé, nous devons traiter le fichier "pic_array.dat". Il convient de noter que le nombre d'éléments dans la ligne retournée par Image2Bitmap ne correspond pas au nombre de pixels dans la ligne de l'image convertie, pour cette raison, nous allons créer une liste séparée de "pixels".



Lors de la lecture d'un fichier, vous devez ignorer la première ligne "uint16_t image = {" et la dernière "};". Pour ignorer la première ligne lors de la lecture d'un fichier, placez simplement la lecture de la ligne avant le cycle de lecture du fichier entier.



Après avoir lu l'intégralité du fichier, nous verrons que la dernière ligne du fichier «};» est devenue un élément de la liste, qui est simplement supprimé.



Ceci termine la formation de la liste avec des valeurs de pixels hexadécimaux. Commençons maintenant à les traiter.


Dimensionnement de l'image


Encore une fois, jetez un œil au champ FPGA et à l'image. Le champ FPGA est divisé en sections (SLICE), qui ont les coordonnées horizontales "X" et "Y" verticales correspondantes. Par exemple, SLICE_X6Y36.



L'image, à son tour, a des pixels, également avec des coordonnées horizontales et verticales. Lors de la superposition de l'image sur le FPGA, nous devons combiner le pixel supérieur gauche avec la section supérieure gauche du FPGA. Dans ce cas, le cristal sélectionné a une section supérieure avec la coordonnée X0Y49.



La taille de l'image sera déterminée par le nombre de sections du FPGA horizontalement et verticalement. Pour le cristal sélectionné, la coordonnée horizontale des sections varie de X0 à X131 et la coordonnée verticale de Y49 à Y0. Il s'ensuit que théoriquement, nous pouvons dessiner une image de taille 132x50 sur le cristal sélectionné.


Paramètres initiaux


Pour résumer: les paramètres initiaux de notre script seront:


  1. X position de départ de la section: nom de variable start_x


  2. Position de début de section sur l'axe y: nom de variable start_y


  3. Largeur de l'image (pour l'image de test est 5): variable w


  4. Hauteur de l'image (pour l'image de test est 3): variable h



RĂ©glage de la couleur des pixels


Image2Bitmap fournit un tableau de pixels au format RGB565 sous la forme d'un nombre de 16 bits écrit au format hexadécimal. Nous devons:


  1. Convertissez la valeur en pixels au format binaire. Cela peut être fait en utilisant la procédure hex2bin, qui peut être trouvée dans [3]


  2. Faites correspondre les bits aux composants de couleur correspondants:
    • La composante rouge de R [15:11]


    • Composant vert G [10: 5]


    • Composant bleu B [4: 0]



Explication: l'ordre est modifié car la procédure hex2bin renvoie une chaîne dans laquelle la numérotation des éléments commence à 0, c'est-à-dire que le 15e bit correspond au 0e élément de la ligne et le 0e bit correspond au 15e élément de la ligne


  1. Convertissez la valeur du composant couleur de binaire en décimal. Cela peut être fait en utilisant la procédure bin2dec, qui peut être trouvée [3]:




  2. Convertissez les valeurs de pixels du format RGB565 au format RGB888, pour un affichage d'image plus fluide. Cela se fait en utilisant deux listes, qui peuvent être trouvées dans [4]. Comment ça marche:
    • La résolution des composantes de couleur R et B est de 5 bits. En prenant la valeur décimale du composant, nous la comparons avec la position du nombre écrit dans la liste t5, et la valeur du composant devient la valeur du tableau






    • De même pour le composant G et le tableau t6





Disponibilité des sections


À l'intérieur de certains FPGA, il existe des ressources spéciales ou des vides qui peuvent perturber la numérotation séquentielle des coordonnées de section. Par exemple, dans la figure ci-dessous, vous pouvez voir que la numérotation des sections est interrompue (cristal xc7s50)


Pour cette raison, avant de colorer, nous vérifions d'abord l'existence de la section. S'il existe, peignez, s'il n'existe pas, passez au pixel suivant


Coloration de la section


Couleur de section définie, section vérifiée. Maintenant, la couleur doit être attribuée aux sections à l'aide de la commande highlight_objects:


Vecteur → Réseau bidimensionnel


Au début, nous avons converti les données d'image en une liste de pixels, qui stocke un balayage progressif de l'image. Pour organiser l'image, nous introduisons deux variables, x et y, qui correspondront à la position des pixels dans l'image. En lisant séquentiellement les éléments de la liste de pixels, nous formerons une image à l'aide de deux boucles for: une par le nombre de lignes, la seconde par la position du pixel dans la ligne




Liste complète des scripts


Liste de Fpga_painter.tcl
 #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" 

Test


  1. Pour commencer les tests, assurez-vous que le champ FPGA est disponible, c'est-à-dire l'une des étapes de conception est ouverte: élaborée, synthétisée ou mise en œuvre. Pour afficher le champ FPGA, sélectionnez Fenêtre → Périphérique


  2. Ouvrez le fichier pic_array.dat et copiez les données d'Image2Bitmap dans le fichier. Enregistrer le fichier


  3. Ouvrons le script. Définissez les coordonnées du pixel supérieur gauche 0 et 49, la taille de l'image de test est de 5 par 3 et exécutez le script. Pour ce faire, cliquez avec le bouton droit dans le champ de script et sélectionnez Exécuter.


  4. Accédez à la console Tcl et assurez-vous que le script a été exécuté.


  5. Accédez à l'onglet Périphérique et assurez-vous que les cellules sont colorées dans la couleur appropriée.


  6. Maintenant, nous pouvons prendre n'importe quelle image, la convertir à la taille souhaitée et remplir le champ FPGA. Voici quelques exemples.



PS: l'attribution de couleur personnalisée remplace le paramètre de couleur par défaut de Vivado


Les références


  1. UG835. Guide de référence de Vivado Design Suite TclCommand
  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-and-protection-mushrooms-from-fading

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


All Articles