Beruflich Dokumente
Kultur Dokumente
on
Contents
1 Introduction
1.1 Prerequisites . . . . . . . . . . .
1.1.1 AHIR V2 Tool-Chain . .
1.1.2 RIFFA 2.0 . . . . . . . .
1.1.3 Additional tools . . . . .
1.1.4 Xilinx ISE Design suite .
1.1.5 Connection of the FPGA
1.2 Conclusion . . . . . . . . . . . .
2 An
2.1
2.2
2.3
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
Card to the
. . . . . . .
. . .
. . .
. . .
. . .
. . .
Host
. . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
Computer
. . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
4
5
7
8
8
8
10
.
.
.
.
.
.
.
11
11
11
12
12
13
15
16
17
. 17
. 17
. 20
. 21
4.4
4.5
26
26
26
30
30
6 References
31
Abstract
We describe a complete pathway using which an algorithm described in C can
be implemented in FPGA hardware. The initial specification and verification
of the algorithm is done in C (using standard C-compilers and debuggers).
Once verified, the C description of the algorithm is converted to VHDL using
the AHIR-V2 tool-chain (developed at IIT Bombay). The generated VHDL
is then verified using the same test infrastructure which was used for algorithm verification at the C level. After successful verification, the AHIR-V2
generated VHDL is mapped to an FPGA target using standard FPGA synthesis tools. In this particular case, we use the ML605 card from Xilinx as
the target platform. The ML605 card uses a Virtex 6 FPGA from Xilinx,
and has a PCI-express interface through which it can be connected to a host
computer. In order to communicate between the card and the host computer,
we use the RIFFA 2.0 infrastructure (developed at UCSD). The final hardware implementation of the algorithm can then be accessed from the host
in real-time. We illustrate the entire pathway by taking an application from
the algorithm level to the final hardware level.
Chapter 1
Introduction
We start this pathway by describing algorithms in C. Using a C test infrastructure, those C algorithms are verified(a standard C compiler like gcc is
used). Initial debugging(if required) is also performed at this stage. The next
step is converting those C specifications into VHDL descriptions by AHIR
V2 tool-chain[1]. The same C test infrastructure which was used to verify the
algorithm is again used to validate the AHIR generated VHDL descriptions.
Once validated, those VHDL files are used to make bit-files using standard
FPGA synthesis tools(in this particular case, we used Xilinx XST). Those
bit-files are mapped to a target FPGA (in this case we used ML605 board
which uses a Virtex 6 FPGA) - by using Xilinx iMPACT. Thus, a hardware
is generated on the FPGA from the intial algorithm specified in C. That
hardware is validated using a RIFFA 2.0 test infrastructure. RIFFA 2.0 [2]
connects the core of an FPGA with a software running on host computer,
through PCI-e interface and yields a very high speed communication between
the host computer and the FPGA hardware. Thus the hardware mapped on
FPGA is verified directly from the terminal of the host computer. This entire
pathway was first integrated by Kartik Lakhotia and Sarath M. in 2013.
In this chapter we describe the tools we need before starting with this
path from C to hardware. We also discuss on how to connect the ML605
FPGA card to PCI-e slot of a computer.
1.1
Prerequisites
We need AHIR V2 tool-chain and RIFFA 2.0 installed in our system. Additionaly, Xilinx ISE 13.2 (which includes iMPACT and XST) must be installed
in the system. Some additional tools are also needed, and downloaded as a
package named addonsAHIR from the VLSI consortium website of IIT Bom4
bay (Will be discussed in details later). The ML605 card also needs to be
connected to the host computer thriugh PCI-e interface.
1.1.1
AHIR V2 Tool-Chain
PATH=$PATH:/full-path-of-the-bin-directory-as-stated-above
export PATH
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path of bin directory
Thus Clang-2.8 and llvm-2.8 installation is completed. Boost is also required
before installing AHIR V2. To download and install Boost, the following
command is executed.
sudo apt-get install libboost-all-dev
It is also possible to install Boost through Synaptic Package Manager.
Installation Procedure
AHIR V2 is an open source tool available for download from github. The
following command is run to download it from git repository.
git clone https://github.com/madhavPdesai/ahir.git
By this, a directory titled ahir will be created in the workspace which will
contain all necessary files,libraries and scripts. The following commands are
then executed in the given order
cd ahir/v2
source build_bashrc
scons
To make a Release of AHIR V2 in the system, following commands are
to be executed.
cd ahir/v2
make -f ReleaseMakefile
After a release for AHIR V2 is made, the bashrc file needs to be modified.
This file is opened by following command.
vi ~/.bashrc
The following lines are added to this file. The AHIR RELEASE path will
change according to the user-name
1.1.2
RIFFA 2.0
These commands build and install the drivers and the libraries. The system
gets configured to load the driver at boot time. It is recommended to reboot
the system once after RIFFA 2.0 driver installation.
1.1.3
Additional tools
Some additional tools are also required to make our AHIR generated designs
compatible with RIFFA interfaces. These tools can be found in the following
link and can be downloaded for free(in tar format). In this package, one script
is also provided to generate bit-files from our HDLs using Xilinx XST. This
entire package is titled as addonsAHIR and can be found in the following
link.
https://www.ee.iitb.ac.in/vlsi/wb/pages/research/completed-projects.php
It is uploaded as a tar file. The tar file is downloaded and extracted. Upon
successful extraction, we will have the all the necessary files ready in our
system.
1.1.4
Xilinx tools are to be installed in the system. In this case, we used Xilinx
ISE 13.2. Two software tools, XST and iMPACT (which are part of this ISE
Design Suite 13.2) will be needed for our work. The detailed procedure to
install these packages can be found in the official webpage of Xilinx in the
following link.
http://www.xilinx.com/support/documentation/sw_manuals/xilinx13_2/iil.pdf
1.1.5
We used ML605 FPGA card from Xilinx - which has a Virtex-6 FPGA on it.
The detailed documentation on this card can be found in the following link.
http://www.xilinx.com/support/documentation/boards_and_kits/ug534.pdf
It is necessary to go through this detailed documentation before starting to
handle the card. If, the card is being used for the first time, then a series of
tests are to be run. These tests will verify the UART links, the LEDs , the
ethernet interface, the switches, the displays, memories and the timers. A
BIST program is provided by Xilinx, which is used to automatically test all
these things. The details of this test can be found in the document available
in the following link.
8
http://www.xilinx.com/support/documentation/boards_and_kits/ug533.pdf
ML-605 can be connected to host computer through a pcie interface or an
ethernet interface. In this case, we only used the PCI-e interface to connect
this card to the host computer. In figure 1.1, we show the ML605 FPGA
card connected to our system through PCI-e interface.
Figure 1.2: Conncetion between FPGA board and computer through USB
JTAG connector
For ML605 board, Xilinx provides a microUSB JTAG connector- which
we used to program the FPGA. This connector connects the board with the
host computer through an USB 2.0 port as shown in figure 1.2. The long
white connector on the left is the USB JTAG connector.
1.2
Conclusion
In this chapter we have described the overall picture of the current work and
also discussed the software and hardware requirments before starting work.
In the next chapters we will take up an example algorithm and illustrate how
it is taken from C algorithm to FPGA hardware on ML605 board.
10
Chapter 2
An Example Algorithm and Its
Verifiction in Software
2.1
Introduction
In the previous chapter, we have described the tools required to take a Calgorithm to FPGA-based physical hardware(using our scheme). Once, we
have all those tools successfully installed in the system and the FPGA card
is properly connected to the system through PCI-e interface, we are ready to
take an algorithm to FPGA hardware and verify it.
In this chapter, we take up a small example algorithm. Then we explain
how to describe that algorithm in C. We also describe how to write a testinfrastructure in C for our example design. Then we will discuss how to
validate our design with that C test-infrastructure.
2.2
We take an addition-example which reads data from two pipes simultaneusly. Then, the system adds the received data and send the result back to a
pipe. We also need to write a test-infrastructure (in C language) to test this
algorithm. Keeping in mind the fact, that the C-algorithm will be converted
to VHDL by AHIR V2, we need to write this C code in a certain way as
described in the next sections. Moreover, we will need to have provisions in
the test infrastructure for purely software level verifiations of the design. For
that, we used conditional group. Conditional group is the part of code introduced within the #ifdef SW and #endif SW part(In the codes mentioned
in the next sections). That part will be executed as a part of the program if
and only if SW is defined.
11
2.3
2.3.1
int idx,i;
for( idx=0 ; idx < ORDER ; idx++)
{
x1[idx] = read_float64("input_port_0");
x2[idx] = read_float64("input_port_1");
}
for( i = 0 ; i < ORDER ; i ++ )
{
x3[i]=x1[i] + x2[i];
}
for( idx=0 ; idx<ORDER ; idx++)
{
write_float64("output_port_0",x3[idx]);
}
}
}
2.3.2
The initial verifiaction of the algorithm was carried out in software level. We
designed the following test-infrastructure in C and tested our algorithm with
it.
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
#include <pthreadUtils.h>
#include <Pipes.h>
#include <pipeHandler.h>
#include "prog.h"
#ifndef SW
#include "vhdlCStubs.h"
#endif
13
#define ORDER 20
#ifdef SW
DEFINE_THREAD(recvd)
#endif
int main(int argc, char* argv[])
{
#ifdef SW
init_pipe_handler();
//The input and output pipes we registered here,
//are of depth 20, and they deal with 64 bit numbers.
register_pipe("input_port_0",20,64,0);
register_pipe("input_port_1",20,64,0);
register_pipe("output_port_0",20,64,0);
PTHREAD_DECL(recvd);
PTHREAD_CREATE(recvd);
#endif
double result[ORDER] ;
uint32_t idx;
uint8_t jdx;
for(idx = 0; idx <ORDER ; idx++)
{
double val = 10*idx ; //we will send multiples of 10
double val2 = 2*idx ; //we will send multiples of 2
write_float64("input_port_0",val); // sent to input_port_0
write_float64("input_port_1",val2); //sent to input_port_1
fprintf(stderr," sent %f %f \n",val,val2);
14
2.4
Inside the example directory (as mentioned before) we need to write a Makefile. This Makefile is shown below. To execute the validation process of the
algorithm using the C testbench, we used this Makefile.
PTHREADUTILS_INCLUDE=$(AHIR_RELEASE)/pthreadUtils/include
SRC=./src
PROGDEFS=
#Stage 2 - this part actually carries out the software level verification
#using gcc compiler.
# -g option enables debugging.
# -c option enables compilation.
# -DSW option enables the use of #ifdef SW segments. These macros will be
#executed only during software level verification, i.e. when SW is defined.
SW: $(SRC)/prog.c $(SRC)/prog.h $(SRC)/testbench.c
gcc -g -c -DSW $(PROGDEFS) -I$(PIPEHANDLER_INCLUDE) -I$(FUNCTIONLIB)/include
-I$(SRC) $(SRC)/prog.c
gcc -g -c -DSW $(PROGDEFS) -I$(PIPEHANDLER_INCLUDE) -I$(PTHREADUTILS_INCLUDE)
-I$(SRC) $(SRC)/testbench.c
gcc -g -o testbench_sw prog.o testbench.o -L$(PIPEHANDLER_LIB) lPipeHandler -lpthread -lriffa
To execute software level verification using that makefile following command
was run from the example directory.
make SW
Upon successful execution, an executable named testbench sw will be created
(in the same working directory from where the make command was run). This
new testbench sw has to be run(using the following command) in order to
carry out the software level verification, and print the results.
./testbench_sw
This executable will run the C algorithm along with its testbench. We can
check the results and verify whether they are accurate.
2.5
Conclusion
Chapter 3
Converting the Example to
VHDL and Its Verification
3.1
Introduction
3.2
17
18
prog.aa
3.3
Upon successful execution of the previous commands, we will have a testbench hw executable inside the working directory. To start the verification,
this executable is run by following command.
./testbench_hw
Now, a new terminal is to be opened and from that terminal the ahir system testbench
executable is run by running the following command.
./ahir_system_testbench
In this experiment, actually the AHIR generated VHDL is simulated in
GHDL and the C testbench gets compiled in the standard gcc compiler.
These two processes interact with each other through sockets. This step is
shown in the screenshot below.
20
Figure 3.1: Hardware Simulation of the Design, Two Processes in Two Different Windows Interact with Each-other
3.4
Conclusion
21
Chapter 4
From VHDL to Physical
Hardware on FPGA
4.1
Introduction
4.2
22
named addonsAHIR)
cd addonsAHIR/ahirWrapper_gen
xilperl wrapgen.pl
This will ask for number of pipes and their names before generating the
wrapper. It will also ask for whether it is to be used for communication
through PCI-e interface or ethrnet interface. All these informations are to
be given correctly. The pipe names are as those specified in the C algorithm.
This will generate a verilog code titled chnl tester.v , which is the wrapper.
This file will be used along with the AHIR VHDL files for bit-file generation.
4.3
Firstly, we need to gather all the necessary HDLs together before synthesizing.(In this case, we will gather all the HDLs inside a directory named
user design. This user designdirectory is kept in the same place with the
synthesis tools of the addonsAHIR package) We need three files to make
the proper bit-file using synthesis tools. The first two files are, the ahir
system.vhdl and ahir system global package.vhdl respectively- which were
created inside the /release/example directory(in this particular case) during
the hardware verification as described in chapter 3. These two files are copied
to a new directory(in this particular case /home/ahir/ahir/fpgaInterface/ml605/user design
directory).
To make this system RIFFA compatible, we will also need the wrapper
for AHIR VHDL descriptions (its generation is discussed in the previous
section). This wrapper is also copied to the user design directory. With
all these files present in the user design directory, one can proceed towards
synthesis and bit-file generation.
We used standard FPGA synthesis tools (in this case, we used Xilinx
XST) to convert our VHDL designs to bit-files. In the existing system,
there is already a perl script by running which we executed this part of the
work(This perl script is also a part of the addonsAHIR package). To run this
perl script in the existing system, following commands were run from the
directory, where we extracted the addonsAHIR(download from VLSI consortium IIT Bombay) package. The detailed directory structure is provided in
the README files inside the addonsAHIR package. The following command
is run to execute this step.
xilperl compile.pl
23
Upon successful execution, a new file named routed.bit will be created inside
synthesis tools/scripts/results directory(inside the addonsAHIR package).
4.4
Since we have our bit-file ready, we need to switch on the ML605 card now
and start working on the card itself. iMPACT is the tool provided by Xilinx,
by which one can upload the configuration file (bit-file) on the FPGA to
generate physical hardware. It is invoked by running the command impact
from the terminal. In the GUI of iMPACT, a new project is to be created.
There is an initialize chain button on the top of the new-project window.
Upon pressing this button, the software is expected to detect the ML605 card
and the FPGA sitting on it if the card is switched on. A screenshot of it is
shown below.
Figure 4.1: The iMPACT software detects the card, Virtex 6 FPGA is denoted by the xc6vlx240t symbol
In the GUI, the software will ask the user to assign configuration files
to the RAM and the FPGA. We shall bypass this step for the RAM. Then,
we need to browse through the file system and chose the newly generated
routed.bit file as the cofiguration file. Then we need to right-click on the
FPGA symbol and program it. Once, the programming is done, the hardware
is generated on the FPGA. However, before starting to use it, we must reboot
our system once (keeping the switch in the ML605 board turned on). Upon
restart, the hardware on FPGA is ready for use and testing.
4.5
Conclusion
In this chapter, we have generated physical hardware from our AHIR VHDL
files generated from some initial C-specifications. This hardware on FPGA
24
25
Chapter 5
Verifying the Hardware on
FPGA With RIFFA Testbench
5.1
Introduction
In the end of the last chapter, we had our hardware ready on the FPGA.
This hardware is generated from the initial algorithmic specification in C.
But this hardware is yet not validated. In this chapter, we will describe the
process of writing the RIFFA test-infrastructure and verifying the hardware
using it.
5.2
RIFFA infrastructure provides us with dedicated functions for communication with the FPGA hardware through PCI-e interface. The general structure
of RIFFA testbench is as follows.
#include <stdio.h>
#include <stdlib.h>
#include <riffa.h>
#define BUF_SIZE (1*1024*1024)
unsigned int buf[BUF_SIZE];
int main(int argc, char* argv[]) {
fpga_t * fpga;
26
<iostream>
<stdio.h>
<stdlib.h>
<pthread.h>
"timer.h"
<riffa.h>
int end = 0;
int numWords = 80000;
int fid=0;
void * sender_fxn(void *)
{
unsigned int * sendbuf;
unsigned int * sendbuf2;
sendbuf = (unsigned int *)malloc(numWords<<2);
for (int i = 0; i<numWords; i++){
sendbuf[i] = 10*i;
}
sendbuf2 = (unsigned int *)malloc(numWords<<2);
for (int i = 0; i<numWords; i++){
sendbuf2[i] = i;
}
int sent;
int sent2;
while(beginRecv){}
sent = fpga_send(fpga, 0,sendbuf, numWords, 0, 1, 2000);
sent2 = fpga_send(fpga, 1,sendbuf2, numWords, 0, 1, 2000);
beginSend = 1;
for (int i=0; i<10; i++){
cout << "sent word " << i << " is "<< sendbuf[i] << endl;
}
while(!end);
if (sendbuf != NULL)
sendbuf = NULL;
for (int i=0; i<10; i++){
cout << "sent word " << i << " is "<< sendbuf2[i] << endl;
}
while(!end);
if (sendbuf2 != NULL)
sendbuf2 = NULL;
}
void * receiver_fxn(void *){
fpga=fpga_open(fid);
unsigned int * recvbuf;
recvbuf = (unsigned int *)malloc((numWords)<<2);
28
5.3
After, programming the FPGA with the bit-file, the system has to be restarted
once (keeping the ML 605 board turned on). Upon restart, the hardware will
be ready to get tested. Then, we need to write the RIFFA testbench as described in the previous section. Once, we have our RIFFA testbench ready, it
is compiled and run to produce an executable. For that, following commands
are to be run.( in this particular clase new edit.cpp is the name of the RIFFA
testbench, and tb will be the name of the generated executable)
g++ -c new_edit.cpp
g++ -o tb new_edit.o -lriffa -lpthread
However, a Makefile can also be written, that contains these two lines. So,
only the make command will be sufficient to build the executable. The
executable(named tb in this case) is run with the command below.
./tb <fpga id>
In our case fpga id is 0. Once, this command is executed, data(as scripted
in the RIFFA testbench) will be sent to the hardware sitting on the FPGA
through PCI-e interface, and the host will receive the computed results from
that hardware. Since, our RIFFA testbench was written with the same data
sets as our initial C test-infrastructure, we expect he results to match with
the results in software simulation and hardware simulation.
5.4
Conclusion
30
Chapter 6
References
[1] Sahasrabuddhe, S.D. Raja, H. ; Arya, K. ; Desai, M.P. AHIR:A Hardware Intermediate Representation , 20th International Conference on VLSI
Design, pages 245 - 250.6-10 January, 2007.
[2] Jacobsen, M., Freund, Y. and Kastner, R. RIFFA: A reusable integration framework for FPGA accelerators. Field-Programmable Custom Computing Machines (FCCM), 2012 20th IEEE Annual International Symposium
on, 29 April - 1 May 2012.
31