From 8518775cc2f94cfb9ce945ebeff2046a3ecc4a0f Mon Sep 17 00:00:00 2001 From: Junyeon Lee Date: Mon, 14 Dec 2020 22:22:58 +0900 Subject: [PATCH 01/22] Bug fix It is weird that int_disable function correctly writes the mstatus register and then writes back to 0. Signed-off-by: Junyeon Lee --- sw/libs/sys_lib/inc/int.h | 1 - 1 file changed, 1 deletion(-) diff --git a/sw/libs/sys_lib/inc/int.h b/sw/libs/sys_lib/inc/int.h index 03f60346..da2fc132 100644 --- a/sw/libs/sys_lib/inc/int.h +++ b/sw/libs/sys_lib/inc/int.h @@ -47,7 +47,6 @@ static inline void int_disable(void) { asm volatile ("csrr %0, mstatus": "=r" (mstatus)); mstatus &= 0xFFFFFFF7; asm volatile ("csrw mstatus, %0" : /* no output */ : "r" (mstatus)); - asm("csrw 0x300, %0" : : "r" (0x0) ); #else mtspr(SPR_SR, mfspr(SPR_SR) & (~SPR_SR_IEE)); #endif From fb2d0f7d8d729a276f4a41f47a0baa6cd9d258d0 Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 15:40:30 +0900 Subject: [PATCH 02/22] Update README.md --- README.md | 239 ++++++++++-------------------------------------------- 1 file changed, 43 insertions(+), 196 deletions(-) diff --git a/README.md b/README.md index 736d0612..ccc11c50 100644 --- a/README.md +++ b/README.md @@ -1,207 +1,54 @@ # Introduction - -PULPino is an open-source single-core microcontroller system, based on 32-bit -RISC-V cores developed at ETH Zurich. PULPino is configurable to use either -the RISCY or the zero-riscy core. - -RISCY is an in-order, single-issue core with 4 pipeline stages and it has -an IPC close to 1, full support for the base integer instruction set (RV32I), -compressed instructions (RV32C) and multiplication instruction set -extension (RV32M). It can be configured to have single-precision floating-point -instruction set extension (RV32F). It implements several ISA extensions such as: -hardware loops, post-incrementing load and store instructions, bit-manipulation -instructions, MAC operations, support fixed-point operations, packed-SIMD instructions -and the dot product. It has been designed to increase the energy efficiency of -in ultra-low-power signal processing applications. -RISCY implementes a subset of the 1.9 privileged specification. -Further informations can be found in http://ieeexplore.ieee.org/abstract/document/7864441/. - -zero-riscy is an in-order, single-issue core with 2 pipeline stages and it has -full support for the base integer instruction set (RV32I) and -compressed instructions (RV32C). It can be configured to have multiplication instruction set -extension (RV32M) and the reduced number of registers extension (RV32E). -It has been designed to target ultra-low-power and ultra-low-area constraints. -zero-riscy implementes a subset of the 1.9 privileged specification. - -When the core is idle, the platform can be put into a low power mode, -where only a simple event unit is active and everything else is clock-gated and consumes minimal power (leakage). -A specialized event unit wakes up the core in case an event/interrupt arrives. - -For communication with the outside world, PULPino contains a broad set of -peripherals, including I2S, I2C, SPI and UART. The platform internal devices -can be accessed from outside via JTAG and SPI which allows pre-loading -RAMs with executable code. In standalone mode, the platform boots from an -internal boot ROM and loads its program from an external SPI flash. - -The PULPino platform is available for RTL simulation as well FPGA. -PULPino has been taped-out as an ASIC in UMC 65nm in January 2016. It has full -debug support on all targets. In addition we support extended profiling with -source code annotated execution times through KCacheGrind in RTL simulations. - - +PULPino는 오픈소스로 개발되었으며 ETH Zurich에서 개발한 32-bit RISC-V Single core +기반 마이크로 컨트롤러 시스템이다. PULPino는 내부에 RISCY 또는 zero-riscy 코어를 +선택하여 사용할 수 있다. ("USE_ZERO_RISCY = 0" or "USE_ZERO_RISCY = 1") + +## RISCY Core +RISCY 코어는 in-order, single issue, 4 states 파이프라인을 지원하며, IPC = 1에 +가까운 성능을 제공한다. 또한 RISCY 코어는 RV32I, C, M (Integer, Compressed, +Multiplication) ISA를 지원하며, single-precision floating point ISA 사용 여부는 +configure 할 수 있다. + +RISCY 코어는 RV32ICM(F) 이외 별도의 Custom ISA를 추가로 지원하고 있다. + 1. Hardware Loops + 2. Post-incrementing load and store instructions + 3. Bit-manipulation instruction + 4. MAC operations + 5. Fixed point operations + 6. Packed-SIMD instruction and dot product + +이러한 별도의 명령어는 Low-power signal processing이 필요한 어플리케이션을 위해 +디자인하였다. RISCY의 privileged 명령어는 RISC-V의 1.9 버전 스펙을 기준으로 한다. +RISCV 1.9 privileged : http://ieeexplore.ieee.org/abstract/document/7864441/. + +## zero-riscy Core +zero-riscy는 RISCY보다 작은 코어로 In-order, Single issue, 2 stage 파이프라인을 +지원하며, RV32I, C를 기본으로 지원한다. 또한 configuration을 통해 M(Multiplication), +E(reduced number of registers extension)을 사용할 수 있다. zero-riscy 코어는 +low-area, low-power 환경을 위해 디자인 되었으며 RISCY와 마찬가지로 privileged명령어는 +1.9버전을 기준으로 한다. + +이외 자세한 PULPino 스펙은 pulpino github을 참고하길 바란다. +https://github.com/pulp-platform/pulpino + +# Installation (Simulation 설명은 제외함) ## Requirements - -PULPino has the following requirements - -- ModelSim in reasonably recent version (we tested it with versions >= 10.2c) -- CMake >= 2.8.0, versions greater than 3.1.0 recommended due to support for ninja -- riscv-toolchain, specifically you need riscv32-unknown-elf-gcc compiler and - friends. There are two choices for this toolchain: Either using the official - RISC-V toolchain supported by Berkeley or the custom RISC-V toolchain from - ETH. The ETH versions supports all the ISA extensions that were incorporated - into the RI5CY core as well as the reduced base instruction set for zero-riscy. - Please make sure you are using the newlib version of the toolchain. +- ModelSim >= 10.2c +- CMake >= 3.1.0 - python2 >= 2.6 -- verilator 3.884 only necessary if you want to use Verilator to evaluate PULPino. - -## ISA Support - -PULPino can run either with RISCY or zero-riscy. -The software included in this repository is compatible with both the cores -and automatically targets the correct ISA based on the flags used. -The simulator (modelsim) must be explicitely told which edition you want to build. -Use the environment variable `USE_ZERO_RISCY` and set it to either `1` for zero-riscy or -`0` for RISCY. +- pulp-riscv-gnu-toolchain (https://github.com/pulp-platform/pulp-riscv-gnu-toolchain) +- verilator 3.884 (Verilator 환경을 사용하는 경우에만) +- Vivado 2015.1 -## Version Control +## Download source code +PULPino는 다양한 sub repository들을 사용하고 있기 때문에 아래 명령어로 +git clone하는 것을 추천한다. -PULPino uses multiple git subrepositories + $ git clone --recursive https://github.com/JunyeonL/pulpino -To clone those subrepositores and update them, use +그다음 Hardware ip들을 받기 위해 다음 명령어를 실행한다. ./update-ips.py -This script will read the `ips_lists.txt` file and update to the versions -specified in there. You can choose specific commits, tags or branches. - - -## Documentation - -There is a preliminary datasheet available that includes a block diagram and a memory map of PULPino. -See docs/datasheet/ in this repository. - -It is written in LaTeX and there is no pdf included in the repository. Simply type - - make all - -inside the folder to generate the pdf. Note that you need a working version of latex for this step. - - -## Running simulations - -The software is built using CMake. -Create a build folder somewhere, e.g. in the sw folder - - mkdir build - -Copy the cmake-configure.{*}.gcc.sh bash script to the build folder. -This script can be found in the sw subfolder of the git repository. - -Modify the cmake-configure script to your needs and execute it inside the build folder. -This will setup everything to perform simulations using ModelSim. - -Four cmake-configure bash scripts have been already configured: - -1) cmake_configure.riscv.gcc.sh - -It automatically selects the RISCY cores and compiles SW with all the PULP-extensions -and the RV32IM support. -The GCC ETH compiler is needed and the GCC march flag set to "IMXpulpv2". - -2) cmake_configure.riscvfloat.gcc.sh - -It automatically selects the RISCY cores and compiles SW with all the PULP-extensions -and the RV32IMF support. -The GCC ETH compiler is needed and he GCC march flag set to "IMFXpulpv2". - -3) cmake_configure.zeroriscy.gcc.sh - -It automatically selects the zero-riscy cores and compiles SW with the RV32IM support -(march flag set to RV32IM). - -4) cmake_configure.microriscy.gcc.sh - -It automatically selects the zero-riscy cores and compiles SW with the RV32E support. -The slim GCC ETH compiler is needed and he GCC march flag set to "RV32I" and the "-m16r" -is passed to the compiler to use only the RV32E ISA support. - - -Activate the RVC flag in the cmake file if compressed instructions are desired. - - -Inside the build folder, execute - - make vcompile - -to compile the RTL libraries using ModelSim. - -To run a simulation in the modelsim GUI use - - make helloworld.vsim - - -To run simulations in the modelsim console use - - make helloworld.vsimc - -This will output a summary at the end of the simulation. -This is intended for batch processing of a large number of tests. - -Replace helloworld with the test/application you want to run. - - -### Using ninja instead of make - -You can use ninja instead make to build software for PULPino, just replace all -occurrences of make with ninja. -The same targets are supported on both make and ninja. - - - -## Interactive debug - -To interactively debug software via gdb, you need the jtag bridge as well as a -working version of gdb for the ISA you want to debug. The debug bridge depends -on the `jtag_dpi` package that emulates a JTAG port and provides a TCP socket -to which the jtag bridge can connect to. - - -## Utilities - -We additionally provide some utilitiy targets that are supposed to make -development for PULPino easier. - -For disassembling a program call - - make helloworld.read - -To regenerate the bootcode and copy it to the `rtl` folder use - - make boot_code.install - -## FPGA - -PULPino can be synthesized and run on a ZedBoard. -Take a look at the `fpga` subfolder for more information. - -## Creating a tarball of the PULPino sources - -If for some reason you don't want to use the git sub-repository approach, you -can create a tarball of the whole design by executing `./create-tarball.py`. -This will download the latest PULPino sources, including all IPS, remove the -git internal folders and create a tar gz. - - -## Arduino compatible libraries - -Most of official Arduino libraries are supported by PULPino software, they can -be compiled, simulated and uploded the same way as traditional software programs -using the available PULPino utilities. You only need to include main.cpp at the -beginning of the program: - - #include "main.cpp" - -Take a look at the `sw/libs/Arduino_libs` subfolder for more information about -the status of the currently supported libraries. From b1488f27b2346a10f61d740cfd65273f8119f86c Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 15:50:11 +0900 Subject: [PATCH 03/22] Add files via upload --- vivado_license.JPG | Bin 0 -> 110154 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 vivado_license.JPG diff --git a/vivado_license.JPG b/vivado_license.JPG new file mode 100644 index 0000000000000000000000000000000000000000..7fa44257d3aef36618f129614609f20c97214eba GIT binary patch literal 110154 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 b@0Udx8_P^nKYLPbyGC`>5N+o0|Gx Date: Thu, 17 Dec 2020 15:55:39 +0900 Subject: [PATCH 04/22] Update README.md --- README.md | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ccc11c50..182d2340 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ low-area, low-power 환경을 위해 디자인 되었으며 RISCY와 마찬가 이외 자세한 PULPino 스펙은 pulpino github을 참고하길 바란다. https://github.com/pulp-platform/pulpino -# Installation (Simulation 설명은 제외함) +# Installation (Zedboard) ## Requirements - ModelSim >= 10.2c - CMake >= 3.1.0 @@ -51,4 +51,150 @@ git clone하는 것을 추천한다. 그다음 Hardware ip들을 받기 위해 다음 명령어를 실행한다. ./update-ips.py + +## HW (FPGA) Synthesis 및 petalinux 빌드 +아래는 zedboard를 위한 petalinux (BOOT.BIN, uImage, devicetree.dtb), +PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들기 위한 과정이다. + +1. Vivado 2015.1이 정상적으로 설치되어 있고, Vivado License Manager에서 xc7z020를 지원하는지 확인한다. + + +2. 빌드하려는 코어 종류에 맞게 아래와 같이 설정한다. (설정 안할경우 RISCY 코어로 기본 선택) +zero-riscy : `setenv USE_ZERO_RISCY 1` and `setenv ZERO_RV32M 1` +RISCY : `setenv USE_ZERO_RISCY 0` + +3. fpga 폴더로 이동한다. + +4. 빌드 명령어를 실행한다 (bitstream, petalinux 모두 빌드하기 때문에 많은 시간이 소요된다) + $ make all + +5. 빌드가 성공적으로 끝나면 `fpga/sw/sd_image` 폴더에 생성된 이미지를 확인한다. 정상적으로 빌드 완료 되었다면 BOOT.BIN, devicetree.dtb, rootfs.tar, uImage 등이 생성된다. + +6. Zedboard Boot image를 굽기 위한 SD카드를 준비한다. + +5. Copy the BOOT.BIN, uImage and devicetree.dtb files to the first partition of the SD card. + Those files can be found inside the `fpga/sw/sd_image` folder. + +6. Extract the content of the rootfs.tar archive and put it on the second + partition of the SD card. + You are ready now + +7. Put the SD card into the ZedBoard and boot the system. + You can use minicom or any other terminal emulator tool to communicate with + the UART of the ZedBoard. + +8. You should now be able to login to the ZYNQ and have a fully working Linux + running on it. + +9. To be able to login to Linux via ssh, you have to make sure that Linux is + able to access the local network. By default it will try to get an IP + address via dhcp. You can check with `ifconfig` and friends if your device + has gotten an IP address and use it to connect to it via a host. + +10. In order to login use the following credentials: + + username: root + + password: pulp + + + +The boot.bin and rootfs.tar files can be found under the folder sw/sd_image. + + +## Running applications on PULPino + +1. Make sure you have a fully working Linux running on the ZYNQ. + Otherwise see section "get started" above. + +2. Currently the only method to load a program into the PULPino system is via + SPI. Linux uses its SPI master to communicate with PULPino's SPI slave and + writes directly into the instruction and data memory of PULPino. + The spiload program which can be found under sw/apps/spiload takes care of + this. + +3. Compile the spiload application for the ZYNQ. + Just type `make` inside the sw/apps/spiload folder. + eg: `vivado-2015.1 make` + +4. Transfer this program to the ZYNQ. We suggest using scp, but any other + method works as well of course. + +5. Now you need to compile the program you want to run on PULPino. + Please take a look at the README in pulpino/sw directory which explains how + applications can be compiled using cmake. + Use this flow to compile your application. We need the spi_stim.txt file + from the applications slm_files subfolder. + +6. Transfer the spi_stim.txt file to the ZYNQ. + +7. Run the spiload application on the ZYNQ like this + + ./spiload ./spi_stim.txt + + This resets PULPino, transfers the application to the memories of PULPino + and starts it. + + +As an alternative, there is a cmake target for running applications on fpga +directly. Just call + + make applicationName.fpga + +You need to be able to ssh into the Linux running on the ZYNQ fpga (e.g. using +public keys) and you need to setup the environment variable `$FPGA_HOSTNAME`. +Take a look at the script `./sw/utils/run-on-fpga.sh` to understand how it +works. + + +## stdout via printf on PULPino + +When PULPino is run on the FPGA, it transfers all output via printf via UART to +the ARM host processor in the ZYNQ. To display it, either use a console program +like minicom to read directly from the serial port, or specify a timeout when +using `spiload`. `spiload` will connect to the serial port and display +everything that PULPino sends via UART until the timeout expires. + +## Connected peripherals & communication with PULPino + +PULPino includes a set of built-in peripherals like SPI, UART and GPIOs. +The SPI slave peripheral is connected to the SPI master of the ZYNQ, thus it is +possible to directly write to any memory address of PULPino from outside. + +UART is connected to UART0 of the ZYNQ and is available under /dev/ttyPS0 in +linux. + + +Some of GPIO pins are connected to LEDs, switches and buttons on the ZedBoard. + +Specifically the following is connected: + + PULPino GPIO pin 0: SW 0 + PULPino GPIO pin 1: SW 1 + PULPino GPIO pin 2: SW 2 + PULPino GPIO pin 3: SW 3 + PULPino GPIO pin 4: SW 4 + PULPino GPIO pin 5: SW 5 + PULPino GPIO pin 6: SW 6 + PULPino GPIO pin 7: SW 7 + + PULPino GPIO pin 8: LD 0 + PULPino GPIO pin 9: LD 1 + PULPino GPIO pin 10: LD 2 + PULPino GPIO pin 11: LD 3 + PULPino GPIO pin 12: LD 4 + PULPino GPIO pin 13: LD 5 + PULPino GPIO pin 14: LD 6 + PULPino GPIO pin 15: LD 7 + + PULPino GPIO pin 16: BTNC + PULPino GPIO pin 17: BTND + PULPino GPIO pin 18: BTNL + PULPino GPIO pin 19: BTNR + PULPino GPIO pin 20: BTNU + + + + +[1] http://www.wiki.xilinx.com/Prepare+Boot+Medium From 76af6f37919eeb7bf9044068850f22cec5886d39 Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 16:12:54 +0900 Subject: [PATCH 05/22] Update README.md --- README.md | 74 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 182d2340..7fb2f4e8 100644 --- a/README.md +++ b/README.md @@ -57,11 +57,11 @@ git clone하는 것을 추천한다. PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들기 위한 과정이다. 1. Vivado 2015.1이 정상적으로 설치되어 있고, Vivado License Manager에서 xc7z020를 지원하는지 확인한다. - + 2. 빌드하려는 코어 종류에 맞게 아래와 같이 설정한다. (설정 안할경우 RISCY 코어로 기본 선택) -zero-riscy : `setenv USE_ZERO_RISCY 1` and `setenv ZERO_RV32M 1` -RISCY : `setenv USE_ZERO_RISCY 0` + - zero-riscy : `setenv USE_ZERO_RISCY 1` and `setenv ZERO_RV32M 1` + - RISCY : `setenv USE_ZERO_RISCY 0` 3. fpga 폴더로 이동한다. @@ -70,54 +70,56 @@ RISCY : `setenv USE_ZERO_RISCY 0` 5. 빌드가 성공적으로 끝나면 `fpga/sw/sd_image` 폴더에 생성된 이미지를 확인한다. 정상적으로 빌드 완료 되었다면 BOOT.BIN, devicetree.dtb, rootfs.tar, uImage 등이 생성된다. -6. Zedboard Boot image를 굽기 위한 SD카드를 준비한다. +6. spiloader (petalinux 위에서 동작하는 앱) 빌드를 위해 `sw/apps/spiload`로 이동한다. -5. Copy the BOOT.BIN, uImage and devicetree.dtb files to the first partition of the SD card. - Those files can be found inside the `fpga/sw/sd_image` folder. +7. `make` 명령어를 실행한다. (여기서 arm-xilinx-linux-gnueabi-gcc가 없다는 에러가 발생한다면 Vivado 및 Vivado SDK의 settings64.sh를 실행했는지 다시 확인해본다. 반드시 필요) -6. Extract the content of the rootfs.tar archive and put it on the second - partition of the SD card. - You are ready now +8. 컴파일이 정상적으로 된다면 spiload 실행 파일이 생성된다. -7. Put the SD card into the ZedBoard and boot the system. - You can use minicom or any other terminal emulator tool to communicate with - the UART of the ZedBoard. - -8. You should now be able to login to the ZYNQ and have a fully working Linux - running on it. - -9. To be able to login to Linux via ssh, you have to make sure that Linux is - able to access the local network. By default it will try to get an IP - address via dhcp. You can check with `ifconfig` and friends if your device - has gotten an IP address and use it to connect to it via a host. +9. Zedboard Boot image를 굽기 위한 SD카드를 준비한다. + 참고 : https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841655/Prepare+Boot+Medium + +10. SD카드의 boot 파티션에는 BOOT.BIN, devicetree.dtb, uImage를 넣고, root 파티션에는 rootfs.tar를 압축 해제한다. + $ cp BOOT.BIN /path-to-boot-partition/ + $ cp devicetree.dtb /path-to-boot-partition/ + $ cp uImage /path-to-boot-partition/ -10. In order to login use the following credentials: + $ tar -xvf rootfs.tar /path-to-root-partition/. - username: root +11. 5번 단계에서 생성한 spiload 프로그램을 SD카드 root partition의 home 폴더에 복사한다. + $ cp ./sw/apps/spiload/spiload /path-to-root-partition/home/ - password: pulp +12. SD카드를 Zedboard에 넣고, petalinux가 정상적으로 부팅되는지 확인한다. 만약 정상적으로 로그가 뜬다면, + buildroot 메시지를 볼 수 있고, `username : root` 를 입력하면 된다. +## RISCV 어플리케이션 컴파일 -The boot.bin and rootfs.tar files can be found under the folder sw/sd_image. +1. 반드시 위의 HW 과정을 마무리하여야 하고, petalinux 부팅이 정상적으로 이루어진 뒤 다음 과정을 진행하길 바란다. +2. RISCV용 샘플 코드는 pulpino/sw 폴더에 위치해 있고, helloworld, gpio, freertos 등 다양한 샘플 코드를 지원한다. -## Running applications on PULPino +3. RISCV 소스 코드 컴파일 과정에 Vivado(xilinx) 컴파일러와 충돌 문제가 있으므로, 새로운 터미널을 열어서 RISCV 소스코드 컴파일 하는 것을 추천한다. (새로운 터미널은 Vivado 및 Vivado SDK에서 지원하는 settings64.sh 스크립트가 실행되지 않은 환경 이어야 한다.) -1. Make sure you have a fully working Linux running on the ZYNQ. - Otherwise see section "get started" above. +4. pulpino/sw/ 폴더 안에 build 폴더를 만든다. + $ cd sw + $ mkdir build + +5. sw폴더에 있는 cmake_configure.riscv.gcc.sh 스크립트를 build 폴더로 복사한다. + $ cp ../cmake_configure.riscv.gcc.sh . + +6. cmake_configure.riscv.gcc.sh를 열어서 아래 부분을 수정한다. + -TARGET_C_FLAGS="-O3 -m32 -g" + +TARGET_C_FLAGS="-O3 -march=rv32g -g" -2. Currently the only method to load a program into the PULPino system is via - SPI. Linux uses its SPI master to communicate with PULPino's SPI slave and - writes directly into the instruction and data memory of PULPino. - The spiload program which can be found under sw/apps/spiload takes care of - this. + -GCC_MARCH="IMXpulpv2" + +#GCC_MARCH="IMXpulpv2" + #compile arduino lib + -ARDUINO_LIB=1 + +ARDUINO_LIB=0 -3. Compile the spiload application for the ZYNQ. - Just type `make` inside the sw/apps/spiload folder. - eg: `vivado-2015.1 make` -4. Transfer this program to the ZYNQ. We suggest using scp, but any other +3. Transfer this program to the ZYNQ. We suggest using scp, but any other method works as well of course. 5. Now you need to compile the program you want to run on PULPino. From 99506319dd85c2bbd407a47ae71034efd7b1d2c6 Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 16:18:01 +0900 Subject: [PATCH 06/22] Update README.md --- README.md | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 7fb2f4e8..ef72ae07 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ git clone하는 것을 추천한다. $ git clone --recursive https://github.com/JunyeonL/pulpino -그다음 Hardware ip들을 받기 위해 다음 명령어를 실행한다. +그다음 Hardware ip들을 받기 위해 다음 스크립트를 실행한다. ./update-ips.py @@ -60,14 +60,17 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 2. 빌드하려는 코어 종류에 맞게 아래와 같이 설정한다. (설정 안할경우 RISCY 코어로 기본 선택) - - zero-riscy : `setenv USE_ZERO_RISCY 1` and `setenv ZERO_RV32M 1` - - RISCY : `setenv USE_ZERO_RISCY 0` + + zero-riscy : `setenv USE_ZERO_RISCY 1` and `setenv ZERO_RV32M 1` + + RISCY : `setenv USE_ZERO_RISCY 0` 3. fpga 폴더로 이동한다. 4. 빌드 명령어를 실행한다 (bitstream, petalinux 모두 빌드하기 때문에 많은 시간이 소요된다) + + ``` $ make all - + ``` + 5. 빌드가 성공적으로 끝나면 `fpga/sw/sd_image` 폴더에 생성된 이미지를 확인한다. 정상적으로 빌드 완료 되었다면 BOOT.BIN, devicetree.dtb, rootfs.tar, uImage 등이 생성된다. 6. spiloader (petalinux 위에서 동작하는 앱) 빌드를 위해 `sw/apps/spiload`로 이동한다. @@ -77,17 +80,23 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 8. 컴파일이 정상적으로 된다면 spiload 실행 파일이 생성된다. 9. Zedboard Boot image를 굽기 위한 SD카드를 준비한다. - 참고 : https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841655/Prepare+Boot+Medium + + + 참고 : https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841655/Prepare+Boot+Medium 10. SD카드의 boot 파티션에는 BOOT.BIN, devicetree.dtb, uImage를 넣고, root 파티션에는 rootfs.tar를 압축 해제한다. + +``` $ cp BOOT.BIN /path-to-boot-partition/ $ cp devicetree.dtb /path-to-boot-partition/ $ cp uImage /path-to-boot-partition/ $ tar -xvf rootfs.tar /path-to-root-partition/. +``` 11. 5번 단계에서 생성한 spiload 프로그램을 SD카드 root partition의 home 폴더에 복사한다. +``` $ cp ./sw/apps/spiload/spiload /path-to-root-partition/home/ +``` 12. SD카드를 Zedboard에 넣고, petalinux가 정상적으로 부팅되는지 확인한다. 만약 정상적으로 로그가 뜬다면, buildroot 메시지를 볼 수 있고, `username : root` 를 입력하면 된다. @@ -102,22 +111,25 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 3. RISCV 소스 코드 컴파일 과정에 Vivado(xilinx) 컴파일러와 충돌 문제가 있으므로, 새로운 터미널을 열어서 RISCV 소스코드 컴파일 하는 것을 추천한다. (새로운 터미널은 Vivado 및 Vivado SDK에서 지원하는 settings64.sh 스크립트가 실행되지 않은 환경 이어야 한다.) 4. pulpino/sw/ 폴더 안에 build 폴더를 만든다. + ``` $ cd sw $ mkdir build + ``` 5. sw폴더에 있는 cmake_configure.riscv.gcc.sh 스크립트를 build 폴더로 복사한다. + ``` $ cp ../cmake_configure.riscv.gcc.sh . - + ``` 6. cmake_configure.riscv.gcc.sh를 열어서 아래 부분을 수정한다. + ``` -TARGET_C_FLAGS="-O3 -m32 -g" +TARGET_C_FLAGS="-O3 -march=rv32g -g" -GCC_MARCH="IMXpulpv2" - +#GCC_MARCH="IMXpulpv2" - #compile arduino lib + -ARDUINO_LIB=1 +ARDUINO_LIB=0 - + ``` 3. Transfer this program to the ZYNQ. We suggest using scp, but any other method works as well of course. From a5678cf7c45cb1355b644c2efb837b8a176f1eea Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 16:25:28 +0900 Subject: [PATCH 07/22] Update README.md --- README.md | 113 ++++++++++++++++-------------------------------------- 1 file changed, 34 insertions(+), 79 deletions(-) diff --git a/README.md b/README.md index ef72ae07..40891309 100644 --- a/README.md +++ b/README.md @@ -67,37 +67,44 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 4. 빌드 명령어를 실행한다 (bitstream, petalinux 모두 빌드하기 때문에 많은 시간이 소요된다) - ``` - $ make all - ``` +``` +$ make all +``` 5. 빌드가 성공적으로 끝나면 `fpga/sw/sd_image` 폴더에 생성된 이미지를 확인한다. 정상적으로 빌드 완료 되었다면 BOOT.BIN, devicetree.dtb, rootfs.tar, uImage 등이 생성된다. + 6. spiloader (petalinux 위에서 동작하는 앱) 빌드를 위해 `sw/apps/spiload`로 이동한다. + 7. `make` 명령어를 실행한다. (여기서 arm-xilinx-linux-gnueabi-gcc가 없다는 에러가 발생한다면 Vivado 및 Vivado SDK의 settings64.sh를 실행했는지 다시 확인해본다. 반드시 필요) + 8. 컴파일이 정상적으로 된다면 spiload 실행 파일이 생성된다. + 9. Zedboard Boot image를 굽기 위한 SD카드를 준비한다. + 참고 : https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841655/Prepare+Boot+Medium + 10. SD카드의 boot 파티션에는 BOOT.BIN, devicetree.dtb, uImage를 넣고, root 파티션에는 rootfs.tar를 압축 해제한다. ``` - $ cp BOOT.BIN /path-to-boot-partition/ - $ cp devicetree.dtb /path-to-boot-partition/ - $ cp uImage /path-to-boot-partition/ +$ cp BOOT.BIN /path-to-boot-partition/ +$ cp devicetree.dtb /path-to-boot-partition/ +$ cp uImage /path-to-boot-partition/ - $ tar -xvf rootfs.tar /path-to-root-partition/. +$ tar -xvf rootfs.tar /path-to-root-partition/. ``` + 11. 5번 단계에서 생성한 spiload 프로그램을 SD카드 root partition의 home 폴더에 복사한다. ``` - $ cp ./sw/apps/spiload/spiload /path-to-root-partition/home/ +$ cp ./sw/apps/spiload/spiload /path-to-root-partition/home/ ``` + 12. SD카드를 Zedboard에 넣고, petalinux가 정상적으로 부팅되는지 확인한다. 만약 정상적으로 로그가 뜬다면, buildroot 메시지를 볼 수 있고, `username : root` 를 입력하면 된다. @@ -106,20 +113,26 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 1. 반드시 위의 HW 과정을 마무리하여야 하고, petalinux 부팅이 정상적으로 이루어진 뒤 다음 과정을 진행하길 바란다. + 2. RISCV용 샘플 코드는 pulpino/sw 폴더에 위치해 있고, helloworld, gpio, freertos 등 다양한 샘플 코드를 지원한다. + 3. RISCV 소스 코드 컴파일 과정에 Vivado(xilinx) 컴파일러와 충돌 문제가 있으므로, 새로운 터미널을 열어서 RISCV 소스코드 컴파일 하는 것을 추천한다. (새로운 터미널은 Vivado 및 Vivado SDK에서 지원하는 settings64.sh 스크립트가 실행되지 않은 환경 이어야 한다.) + 4. pulpino/sw/ 폴더 안에 build 폴더를 만든다. ``` $ cd sw $ mkdir build ``` + 5. sw폴더에 있는 cmake_configure.riscv.gcc.sh 스크립트를 build 폴더로 복사한다. ``` $ cp ../cmake_configure.riscv.gcc.sh . ``` + + 6. cmake_configure.riscv.gcc.sh를 열어서 아래 부분을 수정한다. ``` -TARGET_C_FLAGS="-O3 -m32 -g" @@ -131,84 +144,26 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 +ARDUINO_LIB=0 ``` -3. Transfer this program to the ZYNQ. We suggest using scp, but any other - method works as well of course. - -5. Now you need to compile the program you want to run on PULPino. - Please take a look at the README in pulpino/sw directory which explains how - applications can be compiled using cmake. - Use this flow to compile your application. We need the spi_stim.txt file - from the applications slm_files subfolder. -6. Transfer the spi_stim.txt file to the ZYNQ. - -7. Run the spiload application on the ZYNQ like this - - ./spiload ./spi_stim.txt - - This resets PULPino, transfers the application to the memories of PULPino - and starts it. - - -As an alternative, there is a cmake target for running applications on fpga -directly. Just call - - make applicationName.fpga - -You need to be able to ssh into the Linux running on the ZYNQ fpga (e.g. using -public keys) and you need to setup the environment variable `$FPGA_HOSTNAME`. -Take a look at the script `./sw/utils/run-on-fpga.sh` to understand how it -works. - - -## stdout via printf on PULPino - -When PULPino is run on the FPGA, it transfers all output via printf via UART to -the ARM host processor in the ZYNQ. To display it, either use a console program -like minicom to read directly from the serial port, or specify a timeout when -using `spiload`. `spiload` will connect to the serial port and display -everything that PULPino sends via UART until the timeout expires. - -## Connected peripherals & communication with PULPino - -PULPino includes a set of built-in peripherals like SPI, UART and GPIOs. -The SPI slave peripheral is connected to the SPI master of the ZYNQ, thus it is -possible to directly write to any memory address of PULPino from outside. - -UART is connected to UART0 of the ZYNQ and is available under /dev/ttyPS0 in -linux. - - -Some of GPIO pins are connected to LEDs, switches and buttons on the ZedBoard. +7. sw/build 에서 cmake_config.riscv.gcc.sh을 실행한다. + ``` + $ ./cmake_configure.riscv.gcc.sh . + ``` -Specifically the following is connected: - PULPino GPIO pin 0: SW 0 - PULPino GPIO pin 1: SW 1 - PULPino GPIO pin 2: SW 2 - PULPino GPIO pin 3: SW 3 - PULPino GPIO pin 4: SW 4 - PULPino GPIO pin 5: SW 5 - PULPino GPIO pin 6: SW 6 - PULPino GPIO pin 7: SW 7 +8. 여기서 두 가지 문제가 발생할 수 있는데 + + riscv32-unknown 툴체인을 찾을 수 없다는 경우 + + https://github.com/pulp-platform/pulp-riscv-gnu-toolchain 툴체인을 다운받아 빌드한다. + + 만약 이미 설치한 상태라면 riscv32-unknown-elf-gcc가 위치한 경로를 시스템 PATH에 추가한다. + + riscv.ld 링커 스크립트를 찾을 수 없다는 경우 (아래 링크 참고) + + https://github.com/pulp-platform/pulpino/issues/281 - PULPino GPIO pin 8: LD 0 - PULPino GPIO pin 9: LD 1 - PULPino GPIO pin 10: LD 2 - PULPino GPIO pin 11: LD 3 - PULPino GPIO pin 12: LD 4 - PULPino GPIO pin 13: LD 5 - PULPino GPIO pin 14: LD 6 - PULPino GPIO pin 15: LD 7 - PULPino GPIO pin 16: BTNC - PULPino GPIO pin 17: BTND - PULPino GPIO pin 18: BTNL - PULPino GPIO pin 19: BTNR - PULPino GPIO pin 20: BTNU +9. 정상적으로 cmake configure 스크립트가 실행되었다면, sw/build 폴더 안에서 `make helloworld` 명령어를 실행한다. +10. `sw/build/apps/helloworld/slm_files/` 폴더에 `spi_stim.txt` 파일이 만들어졌다면 성공. -[1] http://www.wiki.xilinx.com/Prepare+Boot+Medium +11. From 50bf17d823115adb744d9d4d6a752b4534c7a788 Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 16:27:27 +0900 Subject: [PATCH 08/22] Update README.md --- README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 40891309..4b5b484f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ # Introduction PULPino는 오픈소스로 개발되었으며 ETH Zurich에서 개발한 32-bit RISC-V Single core 기반 마이크로 컨트롤러 시스템이다. PULPino는 내부에 RISCY 또는 zero-riscy 코어를 -선택하여 사용할 수 있다. ("USE_ZERO_RISCY = 0" or "USE_ZERO_RISCY = 1") +선택하여 사용할 수 있다. ("USE_ZERO_RISCY = 0" or "USE_ZERO_RISCY = 1")
## RISCY Core RISCY 코어는 in-order, single issue, 4 states 파이프라인을 지원하며, IPC = 1에 @@ -21,7 +21,7 @@ RISCY 코어는 RV32ICM(F) 이외 별도의 Custom ISA를 추가로 지원하고 이러한 별도의 명령어는 Low-power signal processing이 필요한 어플리케이션을 위해 디자인하였다. RISCY의 privileged 명령어는 RISC-V의 1.9 버전 스펙을 기준으로 한다. -RISCV 1.9 privileged : http://ieeexplore.ieee.org/abstract/document/7864441/. +RISCV 1.9 privileged : http://ieeexplore.ieee.org/abstract/document/7864441/.
## zero-riscy Core zero-riscy는 RISCY보다 작은 코어로 In-order, Single issue, 2 stage 파이프라인을 @@ -31,7 +31,7 @@ low-area, low-power 환경을 위해 디자인 되었으며 RISCY와 마찬가 1.9버전을 기준으로 한다. 이외 자세한 PULPino 스펙은 pulpino github을 참고하길 바란다. -https://github.com/pulp-platform/pulpino +https://github.com/pulp-platform/pulpino
# Installation (Zedboard) ## Requirements @@ -57,35 +57,35 @@ git clone하는 것을 추천한다. PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들기 위한 과정이다. 1. Vivado 2015.1이 정상적으로 설치되어 있고, Vivado License Manager에서 xc7z020를 지원하는지 확인한다. - +
2. 빌드하려는 코어 종류에 맞게 아래와 같이 설정한다. (설정 안할경우 RISCY 코어로 기본 선택) + zero-riscy : `setenv USE_ZERO_RISCY 1` and `setenv ZERO_RV32M 1` - + RISCY : `setenv USE_ZERO_RISCY 0` + + RISCY : `setenv USE_ZERO_RISCY 0`
-3. fpga 폴더로 이동한다. +3. fpga 폴더로 이동한다.
4. 빌드 명령어를 실행한다 (bitstream, petalinux 모두 빌드하기 때문에 많은 시간이 소요된다) ``` $ make all ``` +
+5. 빌드가 성공적으로 끝나면 `fpga/sw/sd_image` 폴더에 생성된 이미지를 확인한다. 정상적으로 빌드 완료 되었다면 BOOT.BIN, devicetree.dtb, rootfs.tar, uImage 등이 생성된다.
-5. 빌드가 성공적으로 끝나면 `fpga/sw/sd_image` 폴더에 생성된 이미지를 확인한다. 정상적으로 빌드 완료 되었다면 BOOT.BIN, devicetree.dtb, rootfs.tar, uImage 등이 생성된다. +6. spiloader (petalinux 위에서 동작하는 앱) 빌드를 위해 `sw/apps/spiload`로 이동한다.
-6. spiloader (petalinux 위에서 동작하는 앱) 빌드를 위해 `sw/apps/spiload`로 이동한다. +7. `make` 명령어를 실행한다. (여기서 arm-xilinx-linux-gnueabi-gcc가 없다는 에러가 발생한다면 Vivado 및 Vivado SDK의 settings64.sh를 실행했는지 다시 확인해본다. 반드시 필요)
-7. `make` 명령어를 실행한다. (여기서 arm-xilinx-linux-gnueabi-gcc가 없다는 에러가 발생한다면 Vivado 및 Vivado SDK의 settings64.sh를 실행했는지 다시 확인해본다. 반드시 필요) - -8. 컴파일이 정상적으로 된다면 spiload 실행 파일이 생성된다. +8. 컴파일이 정상적으로 된다면 spiload 실행 파일이 생성된다.
9. Zedboard Boot image를 굽기 위한 SD카드를 준비한다. - + 참고 : https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841655/Prepare+Boot+Medium + + 참고 : https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841655/Prepare+Boot+Medium
10. SD카드의 boot 파티션에는 BOOT.BIN, devicetree.dtb, uImage를 넣고, root 파티션에는 rootfs.tar를 압축 해제한다. @@ -97,17 +97,17 @@ $ cp uImage /path-to-boot-partition/ $ tar -xvf rootfs.tar /path-to-root-partition/. ``` - +
11. 5번 단계에서 생성한 spiload 프로그램을 SD카드 root partition의 home 폴더에 복사한다. ``` $ cp ./sw/apps/spiload/spiload /path-to-root-partition/home/ ``` - +
12. SD카드를 Zedboard에 넣고, petalinux가 정상적으로 부팅되는지 확인한다. 만약 정상적으로 로그가 뜬다면, buildroot 메시지를 볼 수 있고, `username : root` 를 입력하면 된다. - +
## RISCV 어플리케이션 컴파일 From face254fca4a28dca7454dbc55f548621d1d7e75 Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 16:39:20 +0900 Subject: [PATCH 09/22] Update README.md --- README.md | 89 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 4b5b484f..a38a684e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,9 @@ # Introduction PULPino는 오픈소스로 개발되었으며 ETH Zurich에서 개발한 32-bit RISC-V Single core 기반 마이크로 컨트롤러 시스템이다. PULPino는 내부에 RISCY 또는 zero-riscy 코어를 -선택하여 사용할 수 있다. ("USE_ZERO_RISCY = 0" or "USE_ZERO_RISCY = 1")
+선택하여 사용할 수 있다. + +`USE_ZERO_RISCY = 0` or `USE_ZERO_RISCY = 1`
## RISCY Core RISCY 코어는 in-order, single issue, 4 states 파이프라인을 지원하며, IPC = 1에 @@ -21,7 +23,8 @@ RISCY 코어는 RV32ICM(F) 이외 별도의 Custom ISA를 추가로 지원하고 이러한 별도의 명령어는 Low-power signal processing이 필요한 어플리케이션을 위해 디자인하였다. RISCY의 privileged 명령어는 RISC-V의 1.9 버전 스펙을 기준으로 한다. -RISCV 1.9 privileged : http://ieeexplore.ieee.org/abstract/document/7864441/.
+RISCV 1.9 privileged + - `http://ieeexplore.ieee.org/abstract/document/7864441/`
## zero-riscy Core zero-riscy는 RISCY보다 작은 코어로 In-order, Single issue, 2 stage 파이프라인을 @@ -31,7 +34,7 @@ low-area, low-power 환경을 위해 디자인 되었으며 RISCY와 마찬가 1.9버전을 기준으로 한다. 이외 자세한 PULPino 스펙은 pulpino github을 참고하길 바란다. -https://github.com/pulp-platform/pulpino
+- `https://github.com/pulp-platform/pulpino`
# Installation (Zedboard) ## Requirements @@ -54,23 +57,23 @@ git clone하는 것을 추천한다. ## HW (FPGA) Synthesis 및 petalinux 빌드 아래는 zedboard를 위한 petalinux (BOOT.BIN, uImage, devicetree.dtb), -PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들기 위한 과정이다. +PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들기 위한 과정이다.

-1. Vivado 2015.1이 정상적으로 설치되어 있고, Vivado License Manager에서 xc7z020를 지원하는지 확인한다. -
+1. 리눅스 환경에 Vivado 2015.1이 정상적으로 설치되어 있고, Vivado License Manager에서 xc7z020를 지원하는지 확인한다. +

2. 빌드하려는 코어 종류에 맞게 아래와 같이 설정한다. (설정 안할경우 RISCY 코어로 기본 선택) - + zero-riscy : `setenv USE_ZERO_RISCY 1` and `setenv ZERO_RV32M 1` - + RISCY : `setenv USE_ZERO_RISCY 0`
+ >>> zero-riscy : `setenv USE_ZERO_RISCY 1` and `setenv ZERO_RV32M 1` + >>> RISCY : `setenv USE_ZERO_RISCY 0`
-3. fpga 폴더로 이동한다.
+3. fpga 폴더로 이동한다.


4. 빌드 명령어를 실행한다 (bitstream, petalinux 모두 빌드하기 때문에 많은 시간이 소요된다) -``` -$ make all -``` -
+ ``` + $ make all + ``` + 5. 빌드가 성공적으로 끝나면 `fpga/sw/sd_image` 폴더에 생성된 이미지를 확인한다. 정상적으로 빌드 완료 되었다면 BOOT.BIN, devicetree.dtb, rootfs.tar, uImage 등이 생성된다.
@@ -85,42 +88,40 @@ $ make all 9. Zedboard Boot image를 굽기 위한 SD카드를 준비한다. - + 참고 : https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841655/Prepare+Boot+Medium
+ >>> 참고 : https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841655/Prepare+Boot+Medium
10. SD카드의 boot 파티션에는 BOOT.BIN, devicetree.dtb, uImage를 넣고, root 파티션에는 rootfs.tar를 압축 해제한다. -``` -$ cp BOOT.BIN /path-to-boot-partition/ -$ cp devicetree.dtb /path-to-boot-partition/ -$ cp uImage /path-to-boot-partition/ + ``` + $ cp BOOT.BIN /path-to-boot-partition/ + $ cp devicetree.dtb /path-to-boot-partition/ + $ cp uImage /path-to-boot-partition/ + + $ tar -xvf rootfs.tar /path-to-root-partition/. + ``` -$ tar -xvf rootfs.tar /path-to-root-partition/. -``` -
11. 5번 단계에서 생성한 spiload 프로그램을 SD카드 root partition의 home 폴더에 복사한다. -``` -$ cp ./sw/apps/spiload/spiload /path-to-root-partition/home/ -``` -
+ ``` + $ cp ./sw/apps/spiload/spiload /path-to-root-partition/home/ + ``` 12. SD카드를 Zedboard에 넣고, petalinux가 정상적으로 부팅되는지 확인한다. 만약 정상적으로 로그가 뜬다면, - buildroot 메시지를 볼 수 있고, `username : root` 를 입력하면 된다. -
+ buildroot 메시지를 볼 수 있고, `username : root` 를 입력하면 된다.


## RISCV 어플리케이션 컴파일 -1. 반드시 위의 HW 과정을 마무리하여야 하고, petalinux 부팅이 정상적으로 이루어진 뒤 다음 과정을 진행하길 바란다. +1. 반드시 위의 HW 과정을 마무리하여야 하고, petalinux 부팅이 정상적으로 이루어진 뒤 다음 과정을 진행하길 바란다.

-2. RISCV용 샘플 코드는 pulpino/sw 폴더에 위치해 있고, helloworld, gpio, freertos 등 다양한 샘플 코드를 지원한다. +2. RISCV용 샘플 코드는 pulpino/sw 폴더에 위치해 있고, helloworld, gpio, freertos 등 다양한 샘플 코드를 지원한다.

-3. RISCV 소스 코드 컴파일 과정에 Vivado(xilinx) 컴파일러와 충돌 문제가 있으므로, 새로운 터미널을 열어서 RISCV 소스코드 컴파일 하는 것을 추천한다. (새로운 터미널은 Vivado 및 Vivado SDK에서 지원하는 settings64.sh 스크립트가 실행되지 않은 환경 이어야 한다.) +3. RISCV 소스 코드 컴파일 과정에 Vivado(xilinx) 컴파일러와 충돌 문제가 있으므로, 새로운 터미널을 열어서 RISCV 소스코드 컴파일 하는 것을 추천한다. (새로운 터미널은 Vivado 및 Vivado SDK에서 지원하는 settings64.sh 스크립트가 실행되지 않은 환경 이어야 한다.)

-4. pulpino/sw/ 폴더 안에 build 폴더를 만든다. +4. pulpino/sw/ 폴더 안에 build 폴더를 만든다. ``` $ cd sw $ mkdir build @@ -152,18 +153,30 @@ $ cp ./sw/apps/spiload/spiload /path-to-root-partition/home/ 8. 여기서 두 가지 문제가 발생할 수 있는데 - + riscv32-unknown 툴체인을 찾을 수 없다는 경우 - + https://github.com/pulp-platform/pulp-riscv-gnu-toolchain 툴체인을 다운받아 빌드한다. - + 만약 이미 설치한 상태라면 riscv32-unknown-elf-gcc가 위치한 경로를 시스템 PATH에 추가한다. - + riscv.ld 링커 스크립트를 찾을 수 없다는 경우 (아래 링크 참고) - + https://github.com/pulp-platform/pulpino/issues/281 + >> riscv32-unknown 툴체인을 찾을 수 없다는 경우 + >>> https://github.com/pulp-platform/pulp-riscv-gnu-toolchain 툴체인을 다운받아 빌드한다. + >>> 만약 이미 설치한 상태라면 riscv32-unknown-elf-gcc가 위치한 경로를 시스템 PATH에 추가한다. + >> riscv.ld 링커 스크립트를 찾을 수 없다는 경우 (아래 링크 참고) + >>> https://github.com/pulp-platform/pulpino/issues/281 9. 정상적으로 cmake configure 스크립트가 실행되었다면, sw/build 폴더 안에서 `make helloworld` 명령어를 실행한다. -10. `sw/build/apps/helloworld/slm_files/` 폴더에 `spi_stim.txt` 파일이 만들어졌다면 성공. +10. `sw/build/apps/helloworld/slm_files/` 폴더에 `spi_stim.txt` 파일이 만들어졌다면 컴파일 성공. 여기서 `spi_stim.txt`는 `helloworld` C 코드를 riscv toolchain을 이용하여 컴파일한 바이너리를 PULPino에서 실행하기 위해 PULPino Memory map을 반영한 파일이다. 또한 Zedboard의 `PS(petalinux)`에서 `PL(PULPino)`로 spiload 프로그램을 이용하여 spi_stim.txt를 전송하기 위한 파일 규격을 맞추어 놓았다. (`pulpino/fpga/sw/apps/spiload/main.c` 프로그램 코드와 같이 분석하는 것을 추천한다) + + +11. `spi_stim.txt` 파일을 SD카드 root 파티션의 home 폴더로 복사한다. +>>> 만약 Zedboard와 ethernet 통신이 가능하다면 scp를 이용해서 복사할 수 있다. +>>> Zedboard에서 아래와 같이 실행하면 파일을 당겨올 수 있다. + + ``` + $ scp @:<파일경로> + ``` + >>> 예시 + ``` + $ scp jun@192.168.0.11:/home/pulpino/sw/build/apps/helloworld/slm_files/spi_stim.txt + ``` -11. From 6e441341d0d8a41d9cf5aec0287e4cde5af33688 Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 16:40:30 +0900 Subject: [PATCH 10/22] Update README.md --- README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a38a684e..7b7cd3a6 100644 --- a/README.md +++ b/README.md @@ -63,8 +63,9 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들

2. 빌드하려는 코어 종류에 맞게 아래와 같이 설정한다. (설정 안할경우 RISCY 코어로 기본 선택) - >>> zero-riscy : `setenv USE_ZERO_RISCY 1` and `setenv ZERO_RV32M 1` - >>> RISCY : `setenv USE_ZERO_RISCY 0`
+ > zero-riscy : `setenv USE_ZERO_RISCY 1` and `setenv ZERO_RV32M 1` + + > RISCY : `setenv USE_ZERO_RISCY 0`
3. fpga 폴더로 이동한다.


@@ -88,7 +89,7 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 9. Zedboard Boot image를 굽기 위한 SD카드를 준비한다. - >>> 참고 : https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841655/Prepare+Boot+Medium
+ > 참고 : https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841655/Prepare+Boot+Medium
10. SD카드의 boot 파티션에는 BOOT.BIN, devicetree.dtb, uImage를 넣고, root 파티션에는 rootfs.tar를 압축 해제한다. @@ -153,11 +154,12 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 8. 여기서 두 가지 문제가 발생할 수 있는데 - >> riscv32-unknown 툴체인을 찾을 수 없다는 경우 - >>> https://github.com/pulp-platform/pulp-riscv-gnu-toolchain 툴체인을 다운받아 빌드한다. - >>> 만약 이미 설치한 상태라면 riscv32-unknown-elf-gcc가 위치한 경로를 시스템 PATH에 추가한다. - >> riscv.ld 링커 스크립트를 찾을 수 없다는 경우 (아래 링크 참고) - >>> https://github.com/pulp-platform/pulpino/issues/281 + > riscv32-unknown 툴체인을 찾을 수 없다는 경우 + >> https://github.com/pulp-platform/pulp-riscv-gnu-toolchain 툴체인을 다운받아 빌드한다. + >> 만약 이미 설치한 상태라면 riscv32-unknown-elf-gcc가 위치한 경로를 시스템 PATH에 추가한다. + + > riscv.ld 링커 스크립트를 찾을 수 없다는 경우 (아래 링크 참고) + >> https://github.com/pulp-platform/pulpino/issues/281 9. 정상적으로 cmake configure 스크립트가 실행되었다면, sw/build 폴더 안에서 `make helloworld` 명령어를 실행한다. @@ -173,7 +175,7 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 ``` $ scp @:<파일경로> ``` - >>> 예시 + > 예시 ``` $ scp jun@192.168.0.11:/home/pulpino/sw/build/apps/helloworld/slm_files/spi_stim.txt ``` From a948e0c99eea02d8625fe5d2d29a714b9cf6dd48 Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 16:43:58 +0900 Subject: [PATCH 11/22] Update README.md --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 7b7cd3a6..a794e31a 100644 --- a/README.md +++ b/README.md @@ -59,13 +59,13 @@ git clone하는 것을 추천한다. 아래는 zedboard를 위한 petalinux (BOOT.BIN, uImage, devicetree.dtb), PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들기 위한 과정이다.

-1. 리눅스 환경에 Vivado 2015.1이 정상적으로 설치되어 있고, Vivado License Manager에서 xc7z020를 지원하는지 확인한다. +### 1.리눅스 환경에 Vivado 2015.1이 정상적으로 설치되어 있고, Vivado License Manager에서 xc7z020를 지원하는지 확인한다.

2. 빌드하려는 코어 종류에 맞게 아래와 같이 설정한다. (설정 안할경우 RISCY 코어로 기본 선택) > zero-riscy : `setenv USE_ZERO_RISCY 1` and `setenv ZERO_RV32M 1` - > RISCY : `setenv USE_ZERO_RISCY 0`
+ > RISCY : `setenv USE_ZERO_RISCY 0`

3. fpga 폴더로 이동한다.


@@ -75,21 +75,23 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 $ make all ``` -5. 빌드가 성공적으로 끝나면 `fpga/sw/sd_image` 폴더에 생성된 이미지를 확인한다. 정상적으로 빌드 완료 되었다면 BOOT.BIN, devicetree.dtb, rootfs.tar, uImage 등이 생성된다.
+

+5. 빌드가 성공적으로 끝나면 `fpga/sw/sd_image` 폴더에 생성된 이미지를 확인한다. 정상적으로 빌드 완료 되었다면 BOOT.BIN, devicetree.dtb, rootfs.tar, uImage 등이 생성된다.

-6. spiloader (petalinux 위에서 동작하는 앱) 빌드를 위해 `sw/apps/spiload`로 이동한다.
+6. spiloader (petalinux 위에서 동작하는 앱) 빌드를 위해 `sw/apps/spiload`로 이동한다.

-7. `make` 명령어를 실행한다. (여기서 arm-xilinx-linux-gnueabi-gcc가 없다는 에러가 발생한다면 Vivado 및 Vivado SDK의 settings64.sh를 실행했는지 다시 확인해본다. 반드시 필요)
+7. `make` 명령어를 실행한다. (여기서 arm-xilinx-linux-gnueabi-gcc가 없다는 에러가 발생한다면 Vivado 및 Vivado SDK의 settings64.sh를 실행했는지 다시 확인해본다. 반드시 필요)

-8. 컴파일이 정상적으로 된다면 spiload 실행 파일이 생성된다.
+ +8. 컴파일이 정상적으로 된다면 spiload 실행 파일이 생성된다.

9. Zedboard Boot image를 굽기 위한 SD카드를 준비한다. - > 참고 : https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841655/Prepare+Boot+Medium
+ > 참고 : https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841655/Prepare+Boot+Medium

10. SD카드의 boot 파티션에는 BOOT.BIN, devicetree.dtb, uImage를 넣고, root 파티션에는 rootfs.tar를 압축 해제한다. From 17768f227a1f98fddb3728a18468a70270a2c443 Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 16:45:22 +0900 Subject: [PATCH 12/22] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a794e31a..db1697e2 100644 --- a/README.md +++ b/README.md @@ -59,13 +59,14 @@ git clone하는 것을 추천한다. 아래는 zedboard를 위한 petalinux (BOOT.BIN, uImage, devicetree.dtb), PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들기 위한 과정이다.

-### 1.리눅스 환경에 Vivado 2015.1이 정상적으로 설치되어 있고, Vivado License Manager에서 xc7z020를 지원하는지 확인한다. -

+1.리눅스 환경에 Vivado 2015.1이 정상적으로 설치되어 있고, Vivado License Manager에서 xc7z020를 지원하는지 확인한다. + +

2. 빌드하려는 코어 종류에 맞게 아래와 같이 설정한다. (설정 안할경우 RISCY 코어로 기본 선택) - > zero-riscy : `setenv USE_ZERO_RISCY 1` and `setenv ZERO_RV32M 1` + - zero-riscy : `setenv USE_ZERO_RISCY 1` and `setenv ZERO_RV32M 1` - > RISCY : `setenv USE_ZERO_RISCY 0`

+ - RISCY : `setenv USE_ZERO_RISCY 0`

3. fpga 폴더로 이동한다.


From c4e69f62870b661f9be828762ae8a9ce302536a8 Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 16:50:11 +0900 Subject: [PATCH 13/22] Update README.md --- README.md | 66 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index db1697e2..51eb425e 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ git clone하는 것을 추천한다. 아래는 zedboard를 위한 petalinux (BOOT.BIN, uImage, devicetree.dtb), PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들기 위한 과정이다.

-1.리눅스 환경에 Vivado 2015.1이 정상적으로 설치되어 있고, Vivado License Manager에서 xc7z020를 지원하는지 확인한다. +1.리눅스 환경에 Vivado 2015.1이 설치되어 있고, Vivado License Manager에서 xc7z020를 지원하는지 확인한다.

@@ -68,31 +68,27 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 - RISCY : `setenv USE_ZERO_RISCY 0`

-3. fpga 폴더로 이동한다.


- -4. 빌드 명령어를 실행한다 (bitstream, petalinux 모두 빌드하기 때문에 많은 시간이 소요된다) - +3. fpga 폴더로 이동한 후 빌드 명령어를 실행한다. (bitstream, petalinux 모두 빌드하기 때문에 많은 시간이 소요된다) ``` $ make all ``` +
-

- -5. 빌드가 성공적으로 끝나면 `fpga/sw/sd_image` 폴더에 생성된 이미지를 확인한다. 정상적으로 빌드 완료 되었다면 BOOT.BIN, devicetree.dtb, rootfs.tar, uImage 등이 생성된다.

+5. 빌드가 성공적으로 끝나면 `fpga/sw/sd_image` 폴더에 생성된 이미지를 확인한다. +- 정상적으로 빌드 완료 되었다면 BOOT.BIN, devicetree.dtb, rootfs.tar, uImage 등이 생성된다.

6. spiloader (petalinux 위에서 동작하는 앱) 빌드를 위해 `sw/apps/spiload`로 이동한다.

-7. `make` 명령어를 실행한다. (여기서 arm-xilinx-linux-gnueabi-gcc가 없다는 에러가 발생한다면 Vivado 및 Vivado SDK의 settings64.sh를 실행했는지 다시 확인해본다. 반드시 필요)

- +7. `make` 명령어를 실행한다. (여기서 arm-xilinx-linux-gnueabi-gcc가 없다는 에러가 발생한다면 Vivado 및 Vivado SDK의 settings64.sh를 실행했는지 다시 확인해본다.)

-8. 컴파일이 정상적으로 된다면 spiload 실행 파일이 생성된다.

+8. 컴파일이 정상적으로 된다면 `spiload` 실행 파일이 생성된다.

-9. Zedboard Boot image를 굽기 위한 SD카드를 준비한다. - > 참고 : https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841655/Prepare+Boot+Medium

+9. Zedboard Boot image를 굽기위한 SD카드를 준비한다. (파티션) + - 참고 : https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841655/Prepare+Boot+Medium

10. SD카드의 boot 파티션에는 BOOT.BIN, devicetree.dtb, uImage를 넣고, root 파티션에는 rootfs.tar를 압축 해제한다. @@ -104,25 +100,28 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 $ tar -xvf rootfs.tar /path-to-root-partition/. ``` - +<\br> 11. 5번 단계에서 생성한 spiload 프로그램을 SD카드 root partition의 home 폴더에 복사한다. ``` $ cp ./sw/apps/spiload/spiload /path-to-root-partition/home/ ``` +<\br> 12. SD카드를 Zedboard에 넣고, petalinux가 정상적으로 부팅되는지 확인한다. 만약 정상적으로 로그가 뜬다면, buildroot 메시지를 볼 수 있고, `username : root` 를 입력하면 된다.


+ ## RISCV 어플리케이션 컴파일 -1. 반드시 위의 HW 과정을 마무리하여야 하고, petalinux 부팅이 정상적으로 이루어진 뒤 다음 과정을 진행하길 바란다.

+1. 반드시 위 HW 과정을 마무리하여야 하고, petalinux 부팅이 정상적으로 된 뒤 다음 과정을 진행해야한다.

-2. RISCV용 샘플 코드는 pulpino/sw 폴더에 위치해 있고, helloworld, gpio, freertos 등 다양한 샘플 코드를 지원한다.

+2. RISCV용 샘플 코드는 `pulpino/sw` 폴더에 위치해 있고, `helloworld` `gpio` `freertos` 등 다양한 샘플 코드를 지원한다.

-3. RISCV 소스 코드 컴파일 과정에 Vivado(xilinx) 컴파일러와 충돌 문제가 있으므로, 새로운 터미널을 열어서 RISCV 소스코드 컴파일 하는 것을 추천한다. (새로운 터미널은 Vivado 및 Vivado SDK에서 지원하는 settings64.sh 스크립트가 실행되지 않은 환경 이어야 한다.)

+3. RISCV 소스 코드 컴파일은 Vivado(xilinx) 컴파일러와 충돌 문제가 있으므로, 새로운 터미널을 열어서 RISCV 소스코드 컴파일 하는 것을 추천한다. + - 새로운 터미널은 Vivado 및 Vivado SDK에서 지원하는 settings64.sh 스크립트가 실행되지 않은 환경 이어야 한다.

4. pulpino/sw/ 폴더 안에 build 폴더를 만든다. @@ -130,13 +129,13 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 $ cd sw $ mkdir build ``` - + <\br> 5. sw폴더에 있는 cmake_configure.riscv.gcc.sh 스크립트를 build 폴더로 복사한다. ``` $ cp ../cmake_configure.riscv.gcc.sh . ``` - + <\br> 6. cmake_configure.riscv.gcc.sh를 열어서 아래 부분을 수정한다. ``` @@ -148,37 +147,40 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 -ARDUINO_LIB=1 +ARDUINO_LIB=0 ``` - + <\br> 7. sw/build 에서 cmake_config.riscv.gcc.sh을 실행한다. ``` $ ./cmake_configure.riscv.gcc.sh . ``` - + <\br> 8. 여기서 두 가지 문제가 발생할 수 있는데 - > riscv32-unknown 툴체인을 찾을 수 없다는 경우 - >> https://github.com/pulp-platform/pulp-riscv-gnu-toolchain 툴체인을 다운받아 빌드한다. - >> 만약 이미 설치한 상태라면 riscv32-unknown-elf-gcc가 위치한 경로를 시스템 PATH에 추가한다. + - riscv32-unknown 툴체인을 찾을 수 없다는 경우 + - https://github.com/pulp-platform/pulp-riscv-gnu-toolchain 툴체인을 다운받아 빌드한다. + - 만약 이미 설치한 상태라면 riscv32-unknown-elf-gcc가 위치한 경로를 시스템 PATH에 추가한다. - > riscv.ld 링커 스크립트를 찾을 수 없다는 경우 (아래 링크 참고) - >> https://github.com/pulp-platform/pulpino/issues/281 - + - riscv.ld 링커 스크립트를 찾을 수 없다는 경우 (아래 링크 참고) + - https://github.com/pulp-platform/pulpino/issues/281 +<\br> -9. 정상적으로 cmake configure 스크립트가 실행되었다면, sw/build 폴더 안에서 `make helloworld` 명령어를 실행한다. +9. 정상적으로 cmake configure 스크립트가 실행되었다면, sw/build 폴더 안에서 `make helloworld` 명령어를 실행한다. <\br><\br> -10. `sw/build/apps/helloworld/slm_files/` 폴더에 `spi_stim.txt` 파일이 만들어졌다면 컴파일 성공. 여기서 `spi_stim.txt`는 `helloworld` C 코드를 riscv toolchain을 이용하여 컴파일한 바이너리를 PULPino에서 실행하기 위해 PULPino Memory map을 반영한 파일이다. 또한 Zedboard의 `PS(petalinux)`에서 `PL(PULPino)`로 spiload 프로그램을 이용하여 spi_stim.txt를 전송하기 위한 파일 규격을 맞추어 놓았다. (`pulpino/fpga/sw/apps/spiload/main.c` 프로그램 코드와 같이 분석하는 것을 추천한다) +10. `sw/build/apps/helloworld/slm_files/` 폴더에 `spi_stim.txt` 파일이 만들어졌다면 컴파일 성공. + - 여기서 `spi_stim.txt`는 `helloworld` C 코드를 riscv toolchain을 이용하여 컴파일한 바이너리를 PULPino에서 실행하기 위해 PULPino Memory map을 반영한 파일이다. + - 또한 Zedboard의 `PS(petalinux)`에서 `PL(PULPino)`로 spiload 프로그램을 이용하여 spi_stim.txt를 전송하기 위한 파일 규격을 맞추어 놓았다. + - `pulpino/fpga/sw/apps/spiload/main.c` 프로그램 코드와 같이 분석하는 것을 추천 <\br><\br> 11. `spi_stim.txt` 파일을 SD카드 root 파티션의 home 폴더로 복사한다. ->>> 만약 Zedboard와 ethernet 통신이 가능하다면 scp를 이용해서 복사할 수 있다. ->>> Zedboard에서 아래와 같이 실행하면 파일을 당겨올 수 있다. + - 만약 Zedboard와 ethernet 통신이 가능하다면 scp를 이용해서 복사할 수 있다. + - Zedboard에서 아래와 같이 실행하면 파일을 당겨올 수 있다. ``` $ scp @:<파일경로> ``` - > 예시 + - 예시 ``` $ scp jun@192.168.0.11:/home/pulpino/sw/build/apps/helloworld/slm_files/spi_stim.txt ``` From 4cd5fcc8c3cd99c3cc60b9eff7c08a8409f1b1f4 Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 16:52:16 +0900 Subject: [PATCH 14/22] Update README.md --- README.md | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 51eb425e..bd11e1f4 100644 --- a/README.md +++ b/README.md @@ -100,13 +100,13 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 $ tar -xvf rootfs.tar /path-to-root-partition/. ``` -<\br> +
11. 5번 단계에서 생성한 spiload 프로그램을 SD카드 root partition의 home 폴더에 복사한다. ``` $ cp ./sw/apps/spiload/spiload /path-to-root-partition/home/ ``` -<\br> +
12. SD카드를 Zedboard에 넣고, petalinux가 정상적으로 부팅되는지 확인한다. 만약 정상적으로 로그가 뜬다면, buildroot 메시지를 볼 수 있고, `username : root` 를 입력하면 된다.


@@ -129,13 +129,13 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 $ cd sw $ mkdir build ``` - <\br> +
5. sw폴더에 있는 cmake_configure.riscv.gcc.sh 스크립트를 build 폴더로 복사한다. ``` $ cp ../cmake_configure.riscv.gcc.sh . ``` - <\br> +
6. cmake_configure.riscv.gcc.sh를 열어서 아래 부분을 수정한다. ``` @@ -147,35 +147,35 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 -ARDUINO_LIB=1 +ARDUINO_LIB=0 ``` - <\br> +
7. sw/build 에서 cmake_config.riscv.gcc.sh을 실행한다. ``` $ ./cmake_configure.riscv.gcc.sh . ``` - <\br> +
8. 여기서 두 가지 문제가 발생할 수 있는데 - - riscv32-unknown 툴체인을 찾을 수 없다는 경우 - - https://github.com/pulp-platform/pulp-riscv-gnu-toolchain 툴체인을 다운받아 빌드한다. - - 만약 이미 설치한 상태라면 riscv32-unknown-elf-gcc가 위치한 경로를 시스템 PATH에 추가한다. + - riscv32-unknown 툴체인을 찾을 수 없다는 경우 + - https://github.com/pulp-platform/pulp-riscv-gnu-toolchain 툴체인을 다운받아 빌드한다. + - 만약 이미 설치한 상태라면 riscv32-unknown-elf-gcc가 위치한 경로를 시스템 PATH에 추가한다. - - riscv.ld 링커 스크립트를 찾을 수 없다는 경우 (아래 링크 참고) - - https://github.com/pulp-platform/pulpino/issues/281 -<\br> + - riscv.ld 링커 스크립트를 찾을 수 없다는 경우 (아래 링크 참고) + - https://github.com/pulp-platform/pulpino/issues/281 +
-9. 정상적으로 cmake configure 스크립트가 실행되었다면, sw/build 폴더 안에서 `make helloworld` 명령어를 실행한다. <\br><\br> +9. 정상적으로 cmake configure 스크립트가 실행되었다면, sw/build 폴더 안에서 `make helloworld` 명령어를 실행한다.

10. `sw/build/apps/helloworld/slm_files/` 폴더에 `spi_stim.txt` 파일이 만들어졌다면 컴파일 성공. - - 여기서 `spi_stim.txt`는 `helloworld` C 코드를 riscv toolchain을 이용하여 컴파일한 바이너리를 PULPino에서 실행하기 위해 PULPino Memory map을 반영한 파일이다. - - 또한 Zedboard의 `PS(petalinux)`에서 `PL(PULPino)`로 spiload 프로그램을 이용하여 spi_stim.txt를 전송하기 위한 파일 규격을 맞추어 놓았다. - - `pulpino/fpga/sw/apps/spiload/main.c` 프로그램 코드와 같이 분석하는 것을 추천 <\br><\br> + - 여기서 `spi_stim.txt`는 `helloworld` C 코드를 riscv toolchain을 이용하여 컴파일한 바이너리를 PULPino에서 실행하기 위해 PULPino Memory map을 반영한 파일이다. + - 또한 Zedboard의 `PS(petalinux)`에서 `PL(PULPino)`로 spiload 프로그램을 이용하여 spi_stim.txt를 전송하기 위한 파일 규격을 맞추어 놓았다. + - `pulpino/fpga/sw/apps/spiload/main.c` 프로그램 코드와 같이 분석하는 것을 추천

11. `spi_stim.txt` 파일을 SD카드 root 파티션의 home 폴더로 복사한다. - - 만약 Zedboard와 ethernet 통신이 가능하다면 scp를 이용해서 복사할 수 있다. - - Zedboard에서 아래와 같이 실행하면 파일을 당겨올 수 있다. + - 만약 Zedboard와 ethernet 통신이 가능하다면 scp를 이용해서 복사할 수 있다. + - Zedboard에서 아래와 같이 실행하면 파일을 당겨올 수 있다. ``` $ scp @:<파일경로> @@ -185,5 +185,12 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 $ scp jun@192.168.0.11:/home/pulpino/sw/build/apps/helloworld/slm_files/spi_stim.txt ``` +
+ +12. petalinux에서 아래 명령어를 실행한다. + ``` + $ ./spiload -t10 spi_stim.txt + ``` + From 4db36414c4aa95642b9c65ba7655f40223254b80 Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 16:55:34 +0900 Subject: [PATCH 15/22] Update README.md --- README.md | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index bd11e1f4..372f3fea 100644 --- a/README.md +++ b/README.md @@ -157,11 +157,11 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 8. 여기서 두 가지 문제가 발생할 수 있는데 - riscv32-unknown 툴체인을 찾을 수 없다는 경우 - - https://github.com/pulp-platform/pulp-riscv-gnu-toolchain 툴체인을 다운받아 빌드한다. - - 만약 이미 설치한 상태라면 riscv32-unknown-elf-gcc가 위치한 경로를 시스템 PATH에 추가한다. + - https://github.com/pulp-platform/pulp-riscv-gnu-toolchain 툴체인을 다운받아 빌드한다. + - 만약 이미 설치한 상태라면 riscv32-unknown-elf-gcc가 위치한 경로를 시스템 PATH에 추가한다. - riscv.ld 링커 스크립트를 찾을 수 없다는 경우 (아래 링크 참고) - - https://github.com/pulp-platform/pulpino/issues/281 + - https://github.com/pulp-platform/pulpino/issues/281
9. 정상적으로 cmake configure 스크립트가 실행되었다면, sw/build 폴더 안에서 `make helloworld` 명령어를 실행한다.

@@ -188,9 +188,29 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들
12. petalinux에서 아래 명령어를 실행한다. - ``` - $ ./spiload -t10 spi_stim.txt - ``` - + ``` + $ ./spiload -t10 spi_stim.txt + ``` + ``` + # ./spiload -t10 ./apps/helloworld_spi_stim.txt + SR is 00000001 + CCR0 is 04004005 + CCR2 is 00040080 + Device has been reset + Sending block addr 00000000 with 256 entries + Sending block addr 000003FC with 256 entries + Sending block addr 000007F8 with 256 entries + Sending block addr 00000BF4 with 256 entries + Sending block addr 00000FF0 with 225 entries + Sending block addr 00100000 with 25 entries + Console Thread start + Starting device + Waiting for EOC... + PULPino: Hello World!!!!! + + Timeout reached! + Stopped after 10.7370672 + # + ``` From fbe5c6e0f2bf5965d54d8b94078b29c846c3f161 Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 16:57:00 +0900 Subject: [PATCH 16/22] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 372f3fea..9ccb97ca 100644 --- a/README.md +++ b/README.md @@ -177,13 +177,13 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 - 만약 Zedboard와 ethernet 통신이 가능하다면 scp를 이용해서 복사할 수 있다. - Zedboard에서 아래와 같이 실행하면 파일을 당겨올 수 있다. - ``` - $ scp @:<파일경로> - ``` - - 예시 - ``` - $ scp jun@192.168.0.11:/home/pulpino/sw/build/apps/helloworld/slm_files/spi_stim.txt - ``` + ``` + $ scp @:<파일경로> + ``` + - 예시 + ``` + $ scp jun@192.168.0.11:/home/pulpino/sw/build/apps/helloworld/slm_files/spi_stim.txt + ```
From da9f382ff0091bd51d7670671ba4834f8d66141d Mon Sep 17 00:00:00 2001 From: j-sungyeong Date: Thu, 17 Dec 2020 17:53:13 +0900 Subject: [PATCH 17/22] Update README.md --- README.md | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 9ccb97ca..81044270 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,12 @@ PULPino는 오픈소스로 개발되었으며 ETH Zurich에서 개발한 32-bit `USE_ZERO_RISCY = 0` or `USE_ZERO_RISCY = 1`
## RISCY Core -RISCY 코어는 in-order, single issue, 4 states 파이프라인을 지원하며, IPC = 1에 +RISCY 코어는 in-order, single issue, 4 stages 파이프라인을 지원하며, IPC = 1에 가까운 성능을 제공한다. 또한 RISCY 코어는 RV32I, C, M (Integer, Compressed, Multiplication) ISA를 지원하며, single-precision floating point ISA 사용 여부는 configure 할 수 있다. -RISCY 코어는 RV32ICM(F) 이외 별도의 Custom ISA를 추가로 지원하고 있다. +RISCY 코어는 RV32ICM(F) 와 별도의 Custom ISA를 추가로 지원하고 있다. 1. Hardware Loops 2. Post-incrementing load and store instructions 3. Bit-manipulation instruction @@ -27,10 +27,10 @@ RISCV 1.9 privileged - `http://ieeexplore.ieee.org/abstract/document/7864441/`
## zero-riscy Core -zero-riscy는 RISCY보다 작은 코어로 In-order, Single issue, 2 stage 파이프라인을 +zero-riscy는 RISCY보다 작은 코어로 In-order, Single issue, 2 stages 파이프라인을 지원하며, RV32I, C를 기본으로 지원한다. 또한 configuration을 통해 M(Multiplication), E(reduced number of registers extension)을 사용할 수 있다. zero-riscy 코어는 -low-area, low-power 환경을 위해 디자인 되었으며 RISCY와 마찬가지로 privileged명령어는 +low-area, low-power 환경을 위해 디자인 되었으며 RISCY와 마찬가지로 privileged 명령어는 1.9버전을 기준으로 한다. 이외 자세한 PULPino 스펙은 pulpino github을 참고하길 바란다. @@ -46,10 +46,16 @@ low-area, low-power 환경을 위해 디자인 되었으며 RISCY와 마찬가 - Vivado 2015.1 ## Download source code -PULPino는 다양한 sub repository들을 사용하고 있기 때문에 아래 명령어로 -git clone하는 것을 추천한다. +먼저 PULPino 프로젝트를 git clone 하여 다운받는다. + $ git clone https://github.com/pulp-platform/pulpino.git - $ git clone --recursive https://github.com/JunyeonL/pulpino +pulp toolchain은 다양한 sub repository들을 사용하고 있기 때문에 아래 명령어를 사용하는 것을 추천한다. + + $ git clone --recursive https://github.com/pulp-platform/pulp-riscv-gnu-toolchain + +나머지는 해당 링크를 참조하되 Installation (PULP) 의 명령어를 일부 수정하여 configure해야 한다. + + $ ./configure --prefix=/TOOLCHAIN_PATH --with-arch=rv32imc --enable-multilib 그다음 Hardware ip들을 받기 위해 다음 스크립트를 실행한다. @@ -155,13 +161,34 @@ PULPino bitstream 및 spiloader (PS->PL로 코드전송 프로그램)를 만들 ```
-8. 여기서 두 가지 문제가 발생할 수 있는데 +8. 여기서 문제가 발생할 수 있는데 - riscv32-unknown 툴체인을 찾을 수 없다는 경우 - https://github.com/pulp-platform/pulp-riscv-gnu-toolchain 툴체인을 다운받아 빌드한다. - 만약 이미 설치한 상태라면 riscv32-unknown-elf-gcc가 위치한 경로를 시스템 PATH에 추가한다. - riscv.ld 링커 스크립트를 찾을 수 없다는 경우 (아래 링크 참고) - https://github.com/pulp-platform/pulpino/issues/281 + - build 폴더에 CMakeFiles 폴더를 생성하여 해결할 수도 있다. + + - unrecognized command line option '-m32' 에러가 발생한 경우 + build 폴더 밖에 아래 스크립트를 생성하고, build 폴더 내에서 생성하여 m32 옵션을 제거해야 한다. + ``` + #!/bin/bash + + # Find and replace all occurrances of '-m32' and fix rest of line. + + for file in $(find); do + if [[ -f $file ]]; then + [[ $(cat $file | grep m32) ]] + if [[ $? == 0 ]]; then + echo writing... + echo $file + sed 's/\-m32//g' $file > tmp && mv tmp $file + fi + fi + done + ``` +
9. 정상적으로 cmake configure 스크립트가 실행되었다면, sw/build 폴더 안에서 `make helloworld` 명령어를 실행한다.

From 13070879ebcc51d00052771ac798ccf4b7fbcb4a Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 18:01:01 +0900 Subject: [PATCH 18/22] Update README.md --- README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 81044270..5b075299 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +#### This README.ld file was written by Sungyeong Jang and Junyeon Lee. If you have any question or need to modify this file, please use pull request. + + # Introduction @@ -47,19 +50,22 @@ low-area, low-power 환경을 위해 디자인 되었으며 RISCY와 마찬가 ## Download source code 먼저 PULPino 프로젝트를 git clone 하여 다운받는다. - $ git clone https://github.com/pulp-platform/pulpino.git + ``` + $ git clone --recursive https://github.com/pulp-platform/pulpino.git + ``` pulp toolchain은 다양한 sub repository들을 사용하고 있기 때문에 아래 명령어를 사용하는 것을 추천한다. $ git clone --recursive https://github.com/pulp-platform/pulp-riscv-gnu-toolchain -나머지는 해당 링크를 참조하되 Installation (PULP) 의 명령어를 일부 수정하여 configure해야 한다. +나머지는 해당 링크를 참조하되 Toolchain은 Installation (PULP) 의 명령어를 일부 수정하여 configure해야 한다. $ ./configure --prefix=/TOOLCHAIN_PATH --with-arch=rv32imc --enable-multilib -그다음 Hardware ip들을 받기 위해 다음 스크립트를 실행한다. +그다음 Pulpino 디렉토리에서 Hardware ip들을 받기 위해 다음 스크립트를 실행한다. ./update-ips.py + ## HW (FPGA) Synthesis 및 petalinux 빌드 아래는 zedboard를 위한 petalinux (BOOT.BIN, uImage, devicetree.dtb), From f0a29b74e4b51b570d870a09f7b2c9e43ca804c3 Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 18:01:32 +0900 Subject: [PATCH 19/22] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b075299..4877130d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -#### This README.ld file was written by Sungyeong Jang and Junyeon Lee. If you have any question or need to modify this file, please use pull request. +#### This README.ld file was written by Sungyeong Jang and Junyeon Lee. If you have any question or need to modify it, please use pull request. + + From bca4b8d419e1de9a824d3c5a08b2da03647acb00 Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 18:01:48 +0900 Subject: [PATCH 20/22] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4877130d..14030617 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ #### This README.ld file was written by Sungyeong Jang and Junyeon Lee. If you have any question or need to modify it, please use pull request. - +

From ab461f5f84d84c8fd0db650f805cb1e69a5fa6c1 Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 18:02:20 +0900 Subject: [PATCH 21/22] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 14030617..d1c557ea 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -#### This README.ld file was written by Sungyeong Jang and Junyeon Lee. If you have any question or need to modify it, please use pull request. +#### It was written by Sungyeong Jang and Junyeon Lee. If you have any question or need to modify it, please use pull request.

From d106108c5acab98e2eeebd16dc4c1eea2da0a24f Mon Sep 17 00:00:00 2001 From: JunyeonL Date: Thu, 17 Dec 2020 18:02:54 +0900 Subject: [PATCH 22/22] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d1c557ea..ab9bbbec 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ pulp toolchain은 다양한 sub repository들을 사용하고 있기 때문에 그다음 Pulpino 디렉토리에서 Hardware ip들을 받기 위해 다음 스크립트를 실행한다. ./update-ips.py - +
## HW (FPGA) Synthesis 및 petalinux 빌드 아래는 zedboard를 위한 petalinux (BOOT.BIN, uImage, devicetree.dtb),