BlackSoC

This SoC that this book will concentrate on is BlackSoC which is derived from icoSoC, which itself was derived from Clifford Wolf’s picorv32 SoC.

BlackSoC is introduced early in this ebook as it is used to access a lot of hardware. That is because devices that use complex I2C or SPI protocols are much easier to access in C than in Verilog.

BlackSoC and icoSoc on which it is based, consist of a picorv32 Risc-V implementation plus a set of Verilog modules with a standardised interface that can be used by Risc-V program written in C (or another language).

The modules are accessed via a memory-mapped API. Corresponding to each Verilog module is some simple standardised python code that generates the C API code for accessing the module.

BlackSoC modules

BlackSoC currently has the following modules:

BlackSoC examples

For each program to be run and specifically for each BlackSoC example program, there is a configuration file, icosoc.cfg, that defines what modules the program uses, what pins they are connected to and other parameters.

There is a python program, icosoc.py, that generates all the run time files including the top-level Verilog file, the pcf file, C header files, a hex image file for the C program, and the Makefile.

It processes all configuration files and uses the python API files for each module used by the program.

There is also main.c program that defines the top-level C program to be run. The C program uses the APIs defined by the .py files.

If modules exist for all the hardware you wish to use, then all you need to do to write is an icosoc.cfg file and a main.c file.

If you need to access new hardware, you need to write a new Verilog module file and a corresponding python API file.

Here are the current BlackSoC examples:

Running BlackSoC programs

More information on BlackSoC is available in the README file. Before you can run BlackSoC programs, you need to install the picorv32 toolchain which is needed to build the C programs. BlackSoC examples only use the basic picorv32i version of the toolchain, not all 4 variants. But they will use the variants if the configuration file requires them.

To run one of the examples, first do:

git clone https://github.com/lawrie/icotools

You will need both USB1 and USB2 connected.

In one terminal do:

stty -F /dev/ttyACM0 raw
cat /dev/ttyACM0

You will see the iceboot messages in this terminal.

In a second terminal do:

stty -F /dev/ttyUSB0 raw -echo 115200
cat /dev/ttyUSB0

In a third terminal, do:

cd icotools/icosoc/examples/<example-directory>
make run

You will see the BlackSoC bootloader messages in the second terminal. Followed by any messages from the example program. If the example program requires console input, you can connect a serial terminal program to /dev/ttyUSB0.

If you edit main.c without touching any of the other files (like icosoc.cfg) and do “make run” again, the bitstream will not change so the program should rebuild quickly. Your will see bootloader messages on /dev/ttyUSB0 again as a new appimage.hex file is sent to the BlackSoC bootloader.

To write your own application, follow the conventions of the example programs. You can write new modules and they will be used automatically providing they follow all the rules sand are in the correct directory. Each module used must have an entry in icosoc.cfg, specifying the pins it uses, and other parameters.

Last updated