[PYTHON] Easily connect Xillybus to user logic with cReComp

Introduction

In this article, I would like to introduce ** cReComp **, which is a development support tool for FPGA, which I am developing. If you can try out the features of cReComp, you only need a PC running ** Ubuntu ** or ** OSX (MacOS) **.

What is cReComp?

cReComp (creator for Reconfigurable Component) is available on Programmable SoCs such as Zynq and Cyclone V. It provides tools and frameworks for ** software componentizing ** circuits written in Verilog.

Specifically, what is meant to do is that by writing a simple setting, the Verilog circuit (hereinafter referred to as user logic) that you wrote is automatically connected to the processor, and the software and FPGA Allows data to be exchanged between circuits. The setting description in cReComp can be done using ** In-language DSL by Python ** or my DSL for cReComp, ** Scrp (specification for cReComp) **.

Please install from the following URL. You can also do pip install, but ** currently under development **, so I think you can get the latest version by python setup.py install after git clone. Github cReComp

About Xillinux

Xillinux is released by Xillybus and is an Ubuntu OS for Programmable SoCs equipped with CPUs and FPGAs such as Zynq and Cyclone V. In Xillinux, FPGA and CPU provide IP that allows data communication through FIFO buffer. The FIFO buffer bit widths supported by the trial version of Xillinux are 32 bits and 8 bits. Data communication between the FPGA and the CPU can be realized by controlling this FIFO buffer on the FPGA. ** cReComp supports and can use this Xillinux FIFO buffer. ** ** This time it is a prerequisite to use this Xillinux. I wrote an article about the introduction of Xillinux before, so please refer to that. Other communication mechanisms will be implemented in the future.

Try developing with cReComp

As I wrote before, there are two styles of setting description in cReComp. One is to set using the framework (in-language DSL) provided by cReComp. For this method, please refer to the Getting Started (Japanese) in the README of the Github repository.

Therefore, this article will show you how to configure and generate code with Scrp.

User logic handled this time

Make sure you have verilog / sonic_sensor.v in the cloned directory. This file is written in Verilog HDL, a hardware description language. This circuit is a circuit for controlling a certain ultrasonic sensor, and when 1 is input to req, the sensor value is returned from ʻout_data`. In addition, busy stands during processing, and finish stands when processing is completed. The compatibility of cReComp with a circuit that can perform such a handshake is good. This time, when the sensor value is needed, it is assumed that the software sends a signal and the software refers to the data.

//  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;
.
.
.

Scrp file template generation

cReComp can automatically generate a Scrp file template for componentization. You can generate a template with the following command. When generating a template, specify the name of the template file and the path to the user logic to be componentized.

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

If the template file is generated successfully, a file called sensor_ctl.scrp should be created. The contents of the generated file are as shown in the code below. If the user logic is specified when the template is generated, the input / output ports of the user logic are read as shown below, and the necessary descriptions are automatically generated. We use pyverilog and veriloggen to analyze Verilog. # Is a comment.

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

Component configuration and generation

Let's specify the setting description for componentization immediately.

Project name (component name)

You can specify the name of the component as follows:

component_name "sensor_ctl"

Declare a signal to wire to user logic

Declare the signal required for user logic wiring according to the following format (signal type bit width "name").

#Component clock and reset signal
input 1 "clk"
input 1 "rst"

#inout signal"sig"Signal for wiring to
inout 1 "sig_out"

# "finish" and "busy"Signal for wiring to
wire 1 "finish_flag"
wire 1 "busy_flag"

req and ʻout_data` have not been declared yet. Declare it again when setting the communication between the user logic and the software. Therefore, here we declare signals for ports other than those that require software and data communication.

Communication logic settings and signal declaration

Uncomment the comment that was already in the template and set as follows.

# Xillybus rcv_cycle snd_cycle rs_cond fifo_width
# @param rcv_cycle  :The number of times the user logic receives data from the CPU
# @param snd_cycle  :The number of times user logic sends data to the CPU
# @param rs_cond    :Conditions for switching between data reception and transmission
# @param fifo_width :FIFO buffer bit width

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

Next, declare the signals required for communication. You also need to declare the signal and then assign it to the Xillybus FIFO buffer. When assigning, it must be a signal that has already been declared. Also, ** rcv ** is used to receive data in the software-> user logic direction, and ** snd ** is used to send data in the user logic-> software direction. That is, it determines which register receives the data and which wire sends the data.

#Register for receiving data from CPU
#Since it is a 32-bit FIFO, prepare a total of 32 bits.

reg 31 "dummy"
reg 1 "req_reg"

#Internal wire for sending data to the CPU

wire 32 "sensor_data"

# req_Assign in the order of reg and dummy.
#It is assigned from the LSB of the FIFO in the order of assignment.

xillybus32_rcv "req_reg"
xillybus32_rcv "dummy"

#Assign signals for data transmission

xillybus32_snd "sensor_data"

Assign signals to user logic

The description for assigning the signal to the user logic is automatically described when the template file is generated by cReComp. For assignment to user logic, assign the signal declared by yourself when setting the component. This time, let's assign as follows.

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

Completed version of configuration file

I think that the file for which the setting description is completed is as follows.

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

Component generation

Let's create a component with the following command. If the generation is successful, Generate component successfully will be output.

$ crecomp -b sensor_ctl.scrp

Generated component

If the generation is successful, a directory with the name of the specified component will be created. The hardware contains the circuit description that runs on the FPGA, and the software contains the software that runs on the CPU. You can use this software to exchange data with user logic.

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

For example, the generated software has the following code.

#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

I myself am doing research on the theme of FPGA and robots, so In fact, this cReComp also has a package generation function for ** ROS **, which has recently become a hot topic as a robot software platform. If you write generate_ros_package in scrp, it will automatically generate a ROS package. Please try.

Please refer to the related article regarding FPGA x ROS.

-OpenReroc, a project to realize a robot using FPGA as a platform with FPGA x ROS -Learn about ROS

By the way, the product is generated in ros_package insoftware /.

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

in conclusion

This time, I introduced the tool cReComp that I am developing and explained the development procedure when using Scrp. As I say many times, it is ** under development **, so please understand that the implementation is still unsatisfactory. I would be very happy if you could give us your impressions of using it or report a bug. Feel free to contact us with any questions regarding the tool.

Contact information and my website

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

Each Github repository

cReComp pyverilog veriloggen

Recommended Posts

Easily connect Xillybus to user logic with cReComp
Connect to BigQuery with Python
Connect to Wikipedia with Python
Connect to Postgresql with GO
Connect to multiple databases with SQLAlchemy
Connect to Bitcoin Testnet with Pycoin
Easily post to twitter with Python 3
Connect to MySQL with Python within Docker
Connect to GNU / Linux with Remote Desktop
Connect to s3 with AWS Lambda Python
Connect to pepper with PEPPER Mac's python interpreter
How to use SQLAlchemy / Connect with aiomysql
Easily convert Jupyter Notebooks to blogs with fastpages
Easily log in to AWS with multiple accounts
Connect to MySQL with Python on Raspberry Pi
Connect to mysql
How to get a logged-in user with Django's forms.py