[PYTHON] Connectez facilement Xillybus et la logique utilisateur avec cReComp

introduction

Dans cet article, je voudrais vous présenter ** cReComp **, qui est un outil d'aide au développement pour les FPGA que je développe. Si vous pouvez essayer la fonction cReComp, vous pouvez le faire tant que vous avez un PC exécutant ** Ubuntu ** ou ** OSX (MacOS) **.

Qu'est-ce que cReComp?

cReComp (créateur de Reconfigurable Component) est disponible sur les SoC programmables tels que Zynq et Cyclone V. Il fournit des outils et des frameworks pour la ** composante logicielle ** des circuits écrits en Verilog.

En écrivant un paramètre simple, le circuit Verilog (ci-après dénommé logique utilisateur) que vous avez écrit est automatiquement connecté au processeur, au logiciel et au FPGA Permet aux données d'être échangées entre les circuits. La description du paramètre dans cReComp peut être effectuée en utilisant ** DSL en langage par Python ** ou mon DSL pour cReComp, ** Scrp (spécification pour cReComp) **.

Veuillez installer à partir de l'URL suivante. Vous pouvez également faire pip install, mais ** actuellement en cours de développement **, donc je pense que vous pouvez obtenir la dernière version par git clone puis python setup.py install. Github cReComp

À propos de Xillinux

Xillinux est publié par Xillybus et est un système d'exploitation Ubuntu pour les SoC programmables équipés de processeurs et de FPGA tels que Zynq et Cyclone V. Dans Xillinux, FPGA et CPU fournissent une adresse IP qui permet la communication de données via le tampon FIFO. Les largeurs de bits du tampon FIFO prises en charge par la version d'essai de Xillinux sont de 32 bits et 8 bits. La communication de données entre le FPGA et le CPU peut être réalisée en contrôlant ce tampon FIFO sur le FPGA. ** cReComp prend en charge et peut utiliser ce tampon FIFO Xillinux. ** ** Cette fois, c'est un prérequis pour utiliser ce Xillinux. J'ai déjà écrit un article sur l'introduction de Xillinux, alors veuillez vous y référer. D'autres mécanismes de communication seront mis en place à l'avenir.

Essayez de développer avec cReComp

Comme je l'ai déjà écrit, il existe deux styles d'écriture des paramètres dans cReComp. La première consiste à définir en utilisant le framework (DSL en langage) fourni par cReComp. Pour cette méthode, veuillez vous reporter à Getting Started (japonais) dans le README du référentiel Github.

Par conséquent, dans cet article, je vais vous présenter comment configurer avec Scrp et comment générer du code.

Logique utilisateur gérée cette fois

Assurez-vous que vous avez verilog / sonic_sensor.v dans le répertoire cloné. Ce fichier est écrit en Verilog HDL, le langage de description du matériel. Ce circuit est un circuit pour commander un certain capteur à ultrasons, et lorsque 1 est entré dans "req", la valeur du capteur est renvoyée depuis "out_data". En outre, des stands occupés pendant le traitement et des stands de finition lorsque le traitement est terminé. La compatibilité de cReComp avec un circuit capable de faire une telle poignée de main est bonne. Cette fois, lorsque la valeur du capteur est nécessaire, on suppose que le logiciel envoie un signal et que le logiciel se réfère aux données.

//  verilog/sonic_sensor.v
`timescale 1ns / 1ps
module sonic_sensor(
	input clk,
	input rst,
	input req,
	output [0:0] busy,
	inout sig,
	output finish,
	output [31:0] out_data
);
	parameter STATE_INIT            = 0,
				 STATE_IDLE         = 1,
				 STATE_OUT_SIG      = 2,
				 STATE_OUT_END      = 3,
				 STATE_WAIT750      = 4,
				 STATE_IN_SIG_WAIT  = 5,
				 STATE_IN_SIG       = 6,
				 STATE_IN_SIG_END   = 7,
				 STATE_WAIT200      = 8,
				 STATE_PROCESS_END  = 9;
	reg [3:0] state;
	reg [31:0] echo;
.
.
.

Génération de modèle de fichier Scrp

cReComp peut générer automatiquement un modèle de fichier Scrp pour la composante. Vous pouvez générer un modèle avec la commande suivante. De plus, lors de la génération d'un modèle, spécifiez le nom du fichier modèle et le chemin d'accès à la logique utilisateur à intégrer.

$ crecomp -u sonic_sensor.v -s sensor_ctl.scrp

Si le fichier modèle est généré avec succès, un fichier appelé sensor_ctl.scrp doit être créé. Le contenu du fichier généré est comme indiqué dans le code ci-dessous. Si la logique utilisateur est spécifiée lors de la génération d'un modèle, les ports d'entrée / sortie de la logique utilisateur sont lus comme indiqué ci-dessous et les descriptions nécessaires sont automatiquement générées. Pyverilog et veriloggen sont utilisés pour analyser Verilog. # C'est un commentaire.

component_name ""

# communication xillybus 1 1 "1" 32
# xillybus32_rcv ""
# xillybus32_snd ""

userlogic_path "sonic_sensor.v" instance_name "uut"
userlogic_assign
	input,1,clk =
	input,1,rst =
	input,1,req =
	output,1,busy =
	inout,1,sig =
	output,1,finish =
	output,32,out_data =
assign_end

end

Configuration et génération de composants

Spécifions immédiatement la description du paramètre pour la mise en composants.

Nom du projet (nom du composant)

Vous pouvez spécifier le nom du composant comme suit:

component_name "sensor_ctl"

Déclarer un signal à câbler à la logique utilisateur

Déclarez le signal requis pour le câblage de la logique utilisateur selon le format suivant (type de signal largeur de bits "nom").

#Horloge des composants et signal de réinitialisation
input 1 "clk"
input 1 "rst"

#signal d'entrée"sig"Signal pour le câblage vers
inout 1 "sig_out"

# "finish" and "busy"Signal pour le câblage vers
wire 1 "finish_flag"
wire 1 "busy_flag"

req et ʻout_data` n'ont pas encore été déclarés. Déclarez-le à nouveau lors du paramétrage de la communication entre la logique utilisateur et le logiciel. Par conséquent, nous déclarons ici des signaux pour des ports autres que ceux qui nécessitent une communication logicielle et de données.

Paramètres de la logique de communication et déclaration du signal

Décommentez le commentaire qui figurait déjà dans le modèle et définissez-le comme suit.

# Xillybus rcv_cycle snd_cycle rs_cond fifo_width
# @param rcv_cycle  :Le nombre de fois que la logique utilisateur reçoit des données de la CPU
# @param snd_cycle  :Nombre de fois que la logique utilisateur envoie des données à la CPU
# @param rs_cond    :Conditions de basculement entre la réception et l'envoi de données
# @param fifo_width :Largeur de bits du tampon FIFO

communication xillybus 1 1 "finish_flag && busy_flag != 0" 32

Ensuite, déclarez le signal requis pour la communication. Vous devez également déclarer le signal, puis l'affecter au tampon FIFO Xillybus. Lors de l'attribution, il doit s'agir d'un signal qui a déjà été déclaré. De plus, ** rcv ** est utilisé pour recevoir des données dans le sens logiciel -> logique utilisateur, et ** snd ** est utilisé pour envoyer des données dans le sens logique utilisateur -> logiciel. C'est-à-dire qu'il détermine dans quel registre les données sont reçues et dans quel fil les données circulant sont envoyées.

#Inscrivez-vous pour recevoir des données de la CPU
#Puisqu'il s'agit d'un FIFO 32 bits, préparez un total de 32 bits.

reg 31 "dummy"
reg 1 "req_reg"

#Câble interne pour l'envoi de données à la CPU

wire 32 "sensor_data"

# req_Assignez dans l'ordre reg et dummy.
#Il est attribué à partir du LSB de la FIFO dans l'ordre d'affectation.

xillybus32_rcv "req_reg"
xillybus32_rcv "dummy"

#Attribuer des signaux pour la transmission de données

xillybus32_snd "sensor_data"

Attribuer des signaux à la logique utilisateur

La description d'attribution du signal à la logique utilisateur est automatiquement décrite lorsque le fichier modèle est généré par cReComp. Pour l'affectation à la logique utilisateur, affectez le signal que vous avez déclaré lors de la configuration du composant. Cette fois, attribuons comme suit.

userlogic_path "sonic_sensor.v" instance_name "uut"
userlogic_assign
	input,1,clk = clk
	input,1,rst = rst
	input,1,req = req_reg
	output,1,busy = busy_flag
	inout,1,sig = sig_out
	output,1,finish = finish_flag
	output,32,out_data = sensor_data
assign_end

Version terminée du fichier de configuration

Je pense que le fichier pour lequel la description du réglage est complétée est le suivant.

component_name "sensor_ctl"

input 1 "clk"
input 1 "rst"
inout 1 "sig_out"
wire 1 "finish_flag"
wire 1 "busy_flag"

reg 31 "dummy"
reg 1 "req_reg"

wire 32 "sensor_data"

xillybus32_rcv "req_reg"
xillybus32_rcv "dummy"

xillybus32_snd "sensor_data"

userlogic_path "sonic_sensor.v" instance_name "uut"
userlogic_assign
	input,1,clk = clk
	input,1,rst = rst
	input,1,req = req_reg
	output,1,busy = busy_flag
	inout,1,sig = sig_out
	output,1,finish = finish_flag
	output,32,out_data = sensor_data
assign_end

end

Génération de composants

Créons un composant avec la commande suivante. Si la génération réussit, "Générer le composant avec succès" sera affiché.

$ crecomp -b sensor_ctl.scrp

Composant généré

Si la génération réussit, un répertoire avec le nom du composant spécifié sera créé. Le matériel contient la description du circuit qui s'exécute sur le FPGA et le logiciel contient le logiciel qui s'exécute sur le CPU. Vous pouvez utiliser ce logiciel pour échanger des données avec la logique utilisateur.

sensor_ctl/
|--hardware/
	|--sensor_ctl.v
	|--sonic_sensor.v
|--software/
	|--sensor_ctl.cpp
	|--lib_cpp.h
	|--Makefile

Par exemple, le logiciel généré a le code suivant.

#include "lib_cpp.h"
#include <iostream>
using namespace std;

class sensor_ctl_32 :public If_module{
	unsigned int sensor_ctl_dout_32;
	unsigned int sensor_ctl_din_32;
public:
	sensor_ctl_32(){}
	~sensor_ctl_32(){}
	unsigned int get_sensor_ctl_32();
	void set_sensor_ctl_32(unsigned int argv);
};
unsigned int sensor_ctl_32::get_sensor_ctl_32(){
	int rc = 0;
	while(1){
		rc = read(fr, &sensor_ctl_dout_32, sizeof(sensor_ctl_dout_32));
		if(rc < 0){
			cout << "fail read from fifo" << endl;
			continue;
			}
		else if(rc == sizeof(sensor_ctl_dout_32)) break;
		}
	return sensor_ctl_dout_32;
}

void sensor_ctl_32::set_sensor_ctl_32(unsigned int argv){
	int rc = 0;
	sensor_ctl_din_32 = argv;
	while(1){
		rc = write(fw, &sensor_ctl_dout_32, sizeof(sensor_ctl_din_32));
		if(rc < 0){
			cout << "fail write to fifo" << endl;
			continue;
		}
		else if (rc == sizeof(sensor_ctl_din_32)) break;
	}
	return;
}


int main(int argc, char const *argv[]){

	sensor_ctl_32 cp_32;
	cp_32.set_devfile_read("/dev/xillybus_read_32");
	cp_32.open_devfile_read();
	cp_32.set_devfile_write("/dev/xillybus_write__32");
	cp_32.open_devfile_write();


	///Please deicribe your code///

	cp_32.close_devfile_read();
	cp_32.close_devfile_write();

	return 0;
}

Bonus FPGA x ROS

Je fais moi-même des recherches sur le thème du FPGA et des robots. En fait, ce cReComp dispose également d'une fonction de génération de package pour ** ROS **, qui est récemment devenu un sujet brûlant en tant que plate-forme logicielle de robot. Si vous écrivez generate_ros_package dans scrp, le package ROS sera généré automatiquement. S'il vous plaît essayez.

Veuillez vous référer à l'article correspondant concernant FPGA x ROS.

En passant, le produit est généré dans ros_package dans software /.

sensor_ctl/
|--hardware/
|	|--sensor_ctl.v
|	|--sonic_sensor.v
|--software/
|	|--ros_package/
|		|--sensor_ctl/
|			|--include/
|			|--msg/
|			|--src/
|			|--CMakeLists.txt
|			|--package.xml
|--sensor_ctl.cpp
|--lib_cpp.h
|--Makefile

en conclusion

Cette fois, j'ai présenté l'outil cReComp que je suis en train de développer et expliqué la procédure de développement lors de l'utilisation de Scrp. Comme je l'ai dit à plusieurs reprises, il est ** en cours de développement **, alors comprenez bien que la mise en œuvre n'est toujours pas satisfaisante. Je serais très heureux si vous pouviez nous donner vos impressions sur son utilisation ou signaler un bug. N'hésitez pas à nous contacter pour toute question concernant l'outil.

Coordonnées et mon site Web

Email : kazushi_at_virgo.is.utsunomiya-u.ac.jp Twitter : KazushihuzaK Github : kazuyamshi HP : Kazushi Yamashina

Chaque référentiel Github

cReComp pyverilog veriloggen

Recommended Posts

Connectez facilement Xillybus et la logique utilisateur avec cReComp
Connectez-vous à BigQuery avec Python
Connectez-vous à Wikipedia avec Python
Connectez-vous à Postgresql avec GO
Connectez-vous à plusieurs bases de données avec SQL Alchemy
Connectez-vous à Bitcoin Testnet avec Pycoin
Publiez facilement sur Twitter avec Python 3
Connectez-vous à MySQL avec Python dans Docker
Connectez-vous à GNU / Linux avec un bureau distant
Connectez-vous à s3 avec AWS Lambda Python
Connectez-vous à Pepper avec l'interpréteur Python de PEPPER Mac
Comment utiliser SQLAlchemy / Connect avec aiomysql
Convertissez facilement les notebooks Jupyter en blogs avec Fastpages
Connectez-vous facilement à AWS avec plusieurs comptes
Connectez-vous à MySQL avec Python sur Raspberry Pi
Connectez-vous à mysql
Comment obtenir un utilisateur connecté avec les forms.py de Django