Re Report HPS UpdatedJan2021

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 36

TABLE OF CONTENT

PART 1 ABSTRACT
PART 2 GENERATE QUARTUS PROJECT
2.1. Generate using DE-10 System Builder
2.2. Building QSYS
2.2.1. Generate HPS
2.2.2. New Component
2.2.3. A complete QSYS Schematic
2.3. FPGA Synthesis and Compile
PART 3 PREPARE LINUX SD CARD
3.1. Linux SD Card Check List
3.2. Write Linux Boot Image
3.2.1. Write Linux Boot Image
3.2.2. Boot HPS System
3.3. Convert FPGA Programming File
3.4. Prepare Software Headers
3.4.1. Generate qsys_hps header
3.4.1 Locate HWLIB system header

PART 4 HPS PROGRAM


4.1. Mount files from SD Card to Linux Kernel
4.2. Make File
4.3. Vim and main.c
PART 1 ABSTRACT
Up till now, we have configed and embedded Linux on Altera DE10 Kit.

PART 2 GENERATE QUARTUS PROJECT


2.1. Generate using DE-10 System Builder
Similar to every DE10 project, firstly, it is convenient to use System Builder to generate a
Verilog template. Select the suitable components. In this project, it requires:
Top File Type: Verilog
- CLOCK, LED x 10, SD RAM 32MB, HPS, 7-Seqment x 6, Switch x 10
- IO Voltage: 3.3 V
Finally, press Generate.

System Builder’s configuration


2.2. Building QSYS
Qsys is a useful, familiar tool for Verilog Designs. Begin the project by opening Qsys on
Quartus II interface.
2.2.1. Generate HPS
HPS IP:
Search and add Hard Processor System from Qsys IP Catalog.
HPS parameters:
In this project, the following configuration for HPS are used:
- FPGA-to-HPS interface width: Unused
- HPS-to-FPGA interface width: 32-bit
- Lightweight HPS-to-FPGA interface width: 32-bit
- f2h_sdram0:
+ Type: Avalon-MM Bidirection
+ Width: 256
- In tab SDRAM, we choose Memory Clock Frequency at 400 MHz
Configuration of HPS
2.2.2. New component:
Please refer to custom IP component for more information about creating new custom IP for the
schematic.
In order to add a new component that we designed, we go to ‘New Component’ in IP Catalog,
choose our component in ‘Component Editor’. In the New Component Tab, choose ‘File >
Add File > <the desired Verilog file(s)>’
New Component – Files

Click Analyze Synthesis Files to compile the added IP.


Analyzing Synthesis Files: Successful Message
Then go to ‘Signal and Interface’ tab, verify the signals by choosing their corresponding signal
type.
Try to follow the instructions in the ‘Message Terminal’ until there is no bug left. Then click
‘Finish’. Now, you would be able to see your IPs in the Qsys IP Catalog.
2.2.3. A complete Schematic

Builded Qsys
When we complete our Qsys configuration, choose Generate HDL and then Finish.
In this project we connect h2f_axi_master to a 7 segment display and the lightweight bridge
controls 4 leds.
2.3. FPGA Synthesis and Compile
Add Synthesize Files:
In order to compile the previously built qsys in fpga project, add synthesized system file ‘.qip’
and qsys instantiation file ‘.v’ that is available at <qsys folder> /synthesis.

Step 1
Write instantiations:

Instantiations of the synthesized Qsys.


These lines are provided in <DE-10 Standard>/ /Demonstration/SoC
or Qsys tool bar > Tool > Instantiation

Synthesis and TCL:


In order to assign backend level pin to HPS, parameterization of the HPS is required.
Firstly, Analysis & Synthesize the project
Synthesize the project

Run Synthesis
After the netlist is synthesized, the project now can identify the HPS. For backend script, run
TCL script by going to ‘Tools > TCL Scripts’ menu. Only run the two .tcl files in the red box.

Finally, click COMPILE to complete the Verilog Program.


PART 3 PREPARE LINUX SD CARD
3.1. Linux SD Card Check List
 Linux Image Required
 soc_system.rbf Required
 Hardware Library (hwlib) Optional but recommended

 HPS headers Required


 socpcinfo Optional
 Prebuilt execution file Optional
 Makefile Optional
 C/C++ scripts Optional
3.2. Write Linux Boot Image:
3.2.1. Write Linux Boot Image
This section indicates writing Linux Image onto a SD Card.
 Linux Image Required
 soc_system.rbf Required
 Hardware Library (hwlib) Optional but recommended

 HPS headers Required


 socpcinfo Optional
 Prebuilt execution file Optional
 Makefile Optional
 C/C++ scripts Optional
Differ from LTXD Ubuntu Linux, Angstrom Linux Console does not configure FPGA fabric.
And the FPGA fabric can be customized by user. Thus, Angstrom Linux Console is chosen to
for this SoC-FPGA Design.
Angstrom Linux Console is available at:
https://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&No=1081&PartNo=4

First of all, we have to have a clean SD Card by using ‘SD Card Formatter’ and choose quick
format.
SD Card Formatter interface
Then we load the boot image by the suitable version of Linux to the kit by Win32 Disk Imager.
Choose the Disk of the SD, which is D in my laptop. We also have to choose the .img file
which is the DE10_Standard_Angstrom_console.img and write to the SD card.
Angstrom Console for DE10

Choose “ Write” to load the boot image


This action will executions the following steps in Linux Boot Flow:
3.2.2. Boot HPS System
After loading the boot image, we check the USB Serial Port for ‘PuTTy’ terminal by going to
Device Manager.

Our terminal is COM3


We config the PuTTy with these following parameters:
- Serial line: COM3
- Speed: 11520
- Connection type: Serial
The click “ Open”.
Our PuTTy Configuration
After that, we will access to the Linux interface of Angstrom. At socfpga login, type “ root” and
Enter and the system will fully boot for us.
Interface of Angstrom
3.3. Convert FPGA Programming File
 Linux Image Required
 soc_system.rbf Required
 Hardware Library (hwlib) Optional but recommended

 HPS headers Required


 socpcinfo Optional
 Prebuilt execution file Optional
 Makefile Optional
 C/C++ scripts Optional

Since HPS will execute our program, we have to convert the .sof file to .rbf ( Raw Binary File)
in order to embedded the code to the HPS. We go to File > Convert Programming File, fill in
the template below and click Convert. After the .rbf file is generated, copy it to SD Card.
Converter interface
! Please rename your .rbf file to soc_system.rbf , which the Linux Kernel will
automatically load during booting.
3.4. Prepare Software Headers
Starting from this point, users are recommended to use Embedded Development Suite for SoC-
FPGA.

Embedded Development Suite console


3.4.1. Generate qsys_hps header
 Linux Image Required
 soc_system.rbf Required
 Hardware Library (hwlib) Optional but recommended

 HPS headers Required


 socpcinfo Optional
 Prebuilt execution file Optional
 Makefile Optional
 C/C++ scripts Optional

After Qsys is generated, we generate a library for headers called hps_0.h from .sopcinfo file.
The generater_hps_header.sh can be created using text file, or provided at
“<DE10_Standard>/DE10_Standard/Demonstration/SoC_fpga/”
This header file is derived directly from the previously built qsys. It contains addresses of
created blocks and crucial information about the system that will be used later on in this project.
In order the this demonstation to work correctly, please change user-define Quartus II directory
and the name of the ‘created project’.socpcinfo

\
generate_hps_qysy_header.sh file for generating Qsys header
The written generate_hps_qsys_header.sh should be placed in the same directory as the ‘.qsys’
and ‘.socpcinfo’ files
The start EDS and go to qsys directory
@EDS$ cd /cygdrive/d/cuong/Quartus/Project/fp_adder_test_1/qsys
@EDS$ ./generate_hps_qsys_header.sh
EDS would return the following line if the header is generated successfully

We can see a header file hps_0.h is generated successfully


3.4.1. Locate HWLIB System Header
 Linux Image Required
 soc_system.rbf Required
 Hardware Library (hwlib) Optional but recommended

 HPS headers Required


 socpcinfo Optional
 Prebuilt execution file Optional
 Makefile Optional
 C/C++ scripts Optional

In order to support for HPS programming, we need to have hwlib which provides us the
addresses of bridges and system functions that required in our project such as Lightweight.
This library is optional, but it is recommended because it includes address of Avalon, AXI
bridges and sends warnings and stoppages if user tries to access an illegal memory block.
We can find this hwlib folder:
<SoC EDS installation path>\embedded\ip\altera\hps\altera_hps>.
Verify the content of our hwlib:
Because our device is Altera Cyclone V, we only focus on our header folder ‘soc_cv_av’ which
has headers for our current project.
header files in folder soc_cv_av

The folder soc_cv_av refers to ‘System on Chip Cyclone V Avalon”, this library indicates the
OS the device being configured.
Please refer to tar.gz compression to emerge this library from PC to SoC-HPS.
@EDS$ cd /cygdrive/d/cuong/Quartus/embedded\ip\altera\hps\altera_hps
@EDS$ tar –czvf hwlib.tar.gz hwlib

The new hwlib.tar.gz has been created successfully.


Tar.gz is a compression type specified for Linux. Thus, less error would occur if we do it this
way.
We need to copy this library to Linux Kernel to access bridges. Firstly, we must compress this
library to tar.gz ( Linux Compression Format). Secondly, we can copy in 2 steps:
1. Compress file the library
2. Copy to SD Card using Mount or Ethernet
It is recommended the library be extracted and located in ‘/home/root’ in Linux Kernel.
3. HPS PROGRAM
3.1. SoC-FPGA Checklist
Before putting SD Card into DE10-Standard, copy the required files instructed in the
previous part into the SD Card.
Remember to set MSEL [4:0] to “101011” (SoC Mode)

 Linux Image Installed


Linux Image includes Boot Image and Boot Scripts, which initiates boot flow configure
Linux Kernel.
 soc_system.rbf Installed
The programming file will automatically configure FPGA Fabric during boot.
 Hardware Library (hwlib) Installed
Mandatory for SoC-FPGA C/C++ program
 HPS headers Installed
Mandatory for SoC-FPGA C/C++ program
 socpcinfo Not required

 Execution file Not done


This file can be compiled using EDS Compiler. But in this report, we use SoC Compiler,
which will be instructed later.
 Makefile Not done
This file can be compiled using EDS. But in this report, we use SoC Compiler, which will
be instructed later.
 C/C++ scripts Not done
This file can be compiled using EDS. But in this report, we use SoC Compiler, which will
be instructed later.
3.2. Mount SD CARD to Linux Kernel:
If we want to copy files from SD Card, we use the mount command like the photo.
We can use the following command line to mount files in SD Card to Linux Kernel
root@socfpga mkdir new_folder_name
root@socfpga mount /dev/mmcblk0p1/ /home/root/new_folder_name
How to mount files from SD Card

Build C code by VI on Angstrom:


After successfully boot Angstrom for the kit, we create a folder for our new program by mkdir [
our folder for program]. Next, type “ cd [ out folder for program]” in order to go into that new
folder we created. In that blank folder, we type “ touch [our program’s name].[c or cpp]” to
create a new C or C++ file where .c is for C and .cpp is for C++. In this example, we will make
a program to test our kit by printing something on the screen.
In order to build a C or C++ code on Angstrom, we type “ vi [our program’s name].[c or cpp]”
like in our case, we have a “ my_second_linux.c”. After that, it will show us an editor like
below but in order to edit it, press “ i ”, which stands for Insert, and put our lines of code in.
When we finsh, type “ :wq” standing for Write and Quit to save and back to the Angstrom
terminal. In our demo program, we try to print “ Hello MF!” on the screen to say “ Hello My
Friend!” to user.
Interface of vim editor on Angstrom
In order to create an output file from the created program, we type “ gcc [ our program] -o
[ our output file’s name]” like “ gcc my_second_linux.c -o helloMF. Then executing that
output generated by the compiler, we type “ ./[our output file’s name]” such as “ ./helloMF”
then it will print the message on screen like below.

Printing “ Hello MF!” on the screen


Our true target for HPS:
After we checked our hardware works properly,we can now build a complex C code for our
HPS. Based on the headers, we now can build our main C code. In this example, we will input
one of these instructions:
w+ or w- to add or subtract a to b
rl to update the outermost result
sa or sb or sr or so to see the value of a, b, result or operator
cl to clear all registers
Makefile:

Makefile’s content

The name of our generated file will be the TARGET’s name. Our CROSS_COMPILE, which
allows us to access external devices and system registers as a developer instead of MinGW that
limits our access, is changed to arm-angstrom-linux-gnueabi-.

Main.c
3.2. Open bridges by mmap:
4. How mmap helps us access the bridges

Main c:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdint.h>
#include "hwlib.h"
#include "socal/socal.h"
#include "socal/hps.h"
#include "socal/alt_gpio.h"
#include "hps_0.h"

#define REGS_BASE (ALT_LWFPGASLVS_OFST)


#define REGS_SPAN (0x00200000)
#define H2F_MAS_BASE 0xC0000000
#define H2F_MAS_SPAN 0x00100000

int main()
{
int fd;
void *virtual_base, *master_base;
int loop_count;
void *leds_addr;
volatile uint32_t* hex7_addr;
int counter = 0;

printf("\n");
printf("1.PROGRAM START\n");
printf("2\n" );

printf( "ALT_STM_OFST Value: 0x%08x\n" , ALT_STM_OFST );


printf( "ALT_LWFPGASLVS_OFST Value: 0x%08x\n" ,
ALT_LWFPGASLVS_OFST);

// map the address space for the LED registers into user space so we can interact with
them.
// we'll actually map in the entire CSR span of the HPS since we want to access various
registers within that span
if ((fd = open( "/dev/mem" , (O_RDWR | O_SYNC))) == -1)
{
printf( "ERROR: could not open \"/dev/mem\"...\n");
return -1;
}

printf("3. File Desciptor Successful\n");

virtual_base = mmap(NULL, REGS_SPAN, PROT_READ | PROT_WRITE,


MAP_SHARED, fd, REGS_BASE);
master_base = mmap(NULL, H2F_MAS_SPAN, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, H2F_MAS_BASE);

if (virtual_base == MAP_FAILED)
{
printf("ERROR: mmap() failed...\n");
close(fd);
return -1;
}

if (master_base == MAP_FAILED){
printf("ERROR: mmap() failed @ H2F_master..\n");
close(fd);
return -1;
}

printf("4\n");

leds_addr = virtual_base + LEDS_BASE;


hex7_addr = master_base + CUSTOM_DISPLAY7_BASE;

*(hex7_addr) = 0x05;
// Toggle the LEDs in a counting pattern
while (loop_count < 60)
{
printf("5\n");

// Set LEDs to counter value


*(uint32_t *)leds_addr = counter;

printf("6\n");

// Wait 1s
usleep(1000 * 1000);

// Update LEDs counter


if (counter++ >= 16)
counter = 0;

printf("Counter: %i\n", counter);

// Increment loop counter


++loop_count;
}

// Clean up our memory mapping and exit


if (munmap(virtual_base, REGS_SPAN) != 0)
{
printf("ERROR: munmap() failed...\n");
close(fd);
return -1;
}

if (munmap(master_base, H2F_MAS_SPAN) != 0){


printf("ERROR: mmap() failed @ H2F_master..\n");
close(fd);
return -1;
}

close(fd);
return 0;
}

You might also like