Posted on

MaSoCist opensource 0.2 release

I’ve finally got to release the opensource tree of our SoC builder environment on github:

https://github.com/hackfin/MaSoCist

Changes in this release:

  • Active support for Papilio and Breakout MachXO2 board had been dropped
  • Very basic support for the neo430 (msp430 compatible) added, see Docker notes below
  • Includes a non-configureable basic ‘eval edition’ (in VHDL only) of our pipelined ZPUng core
  • Basic Virtual board support (using ghdlex co-simulation extensions)
  • Docker files and recipes included

Docker environment

Docker containers are in my opinion the optimum for automated deployment and for testing different configurations. To stay close to actual GHDL simulator development, the container is based on the ghdl/ghdl:buster-gcc-7.2.0 edition.

Here’s a short howto to set up an environment ready to play with. You can try this online at

https://labs.play-with-docker.com, for example.

Just register yourself a Docker account, login and start playing in your online sandbox.

If you want to skip the build, you can use the precompiled docker image by running

docker run -it -v/root:/usr/local/src hackfin/masocist

and skip (3.) below.

You’ll need to build and copy some files from contrib/docker to the remote Docker machine instance.

  1. Run ‘make dist’ inside contrib/docker, this will create a file masocist_sfx.sh
  2. Copy Dockerfile and init-pty.sh to Docker playground by dragging the file onto the shell window
  3. Build the container and run it:
    docker build -t masocist .
    
    docker run -it -v/root:/usr/local/src masocist
  4. Copy masocist_sfx.sh to the Docker machine and run, inside the running container’s home dir (/home/masocist):
    sudo sh /usr/local/src/masocist_sfx.sh
  5. Now pull and build all necessary packages:
    make all run
  6. If nothing went wrong, the simulation for the neo430 CPU will be built and started with a virtual UART and SPI simulation. A minicom terminal will connect to that UART and you’ll be able to speak to the neo430 ‘bare metal’ shell, for example, you can dump the content of the virtual SPI flash by:
    s 0 1
    

    Note: This can be very slow. On a docker playground virtual machine, it can take up to a minute until the prompt appears, depending on the server load.

Development details

The simulation is a cycle accurate model of your user program, which you can of course modify. During the build process, i.e. when you run ‘make sim’ in the masocist(-opensource) directory, the msp430-gcc compiler builds the software C code from the sw/ directory and places the code into memory according to the linker script in sw/ldscripts/neo430. This results in a ELF binary, which is again converted into a VHDL initialization file for the target. Then the simulation is built.

The linker script is, however very basic. Since a somewhat different, automatically generated memory map is used at this experimental stage, all peripherals are configured in the XML device description at hdl/plat/minimal.xml, however the data memory configuration (‘dmem’ entity) does not automatically adapt the linker script.

Turning this into a fully configurable solution is left to be done.

 

 

 

Posted on

Setting up virtual CPU environment on Windows

This is a short howto to get a Linux specific Virtual Chip running on a Windows OS:

  1. Download and install the Docker Toolbox
  2. Download and install the Xming X-Server
  3. Run ‘Docker Quickstart terminal’, normally installed on your desktop. Be patient, the environment takes some time to start up
  4. Download MaSoCist docker container:
    docker pull hackfin/masocist
  5. Optional: (GTKwave support): Prepare the Xming server by running XLaunch and configuring as follows using the Wizard:
    • Multiple Windows
    • Start no client
    • No access control selected (Warning, this could cause security issues, depending on your system config)
  6. Start the container using the script below
    docker run -ti --rm -u masocist -w /home/masocist -e DISPLAY=192.168.99.1:0 \
    -v /tmp/.X11-unix:/tmp/.X11-unix hackfin/masocist bash

You might save this script to a file like run.sh and start it next time from the Docker Quickstart terminal:

. run.sh

Depending on the MaSoCist release you’ve got, there are different install methods:

Opensource github

See README.md for most up to date build notes. GTKwave is not installed by default.

Custom ‘vendor’ license

You should have received a vendor-<YOUR_ORGANIZATION>.pdf for detailed setup notes, see ‘Quick start’ section.

A few more notes

  • All changes you will make to this docker container are void on exit. If this is not desired, remove the ‘–rm’ option and use the ‘docker ps -a’ and ‘docker start -i <container_id>’ commands to reenter your container. Consult the Docker documentation for details.
  • Closing the GTKwave window will not stop the simulation!
  • Ctrl-C on the console stops the simulation, but does not close the wave window
  • The UART output of the virtual SoC is printed on the console (“Hello!”). Virtual UART input is not supported on this system, but can be implemented using tools supporting virtual COM ports and Windows pipes.
  • Once you have the Docker container imported, you can alternatively use the Kitematic GUI and apply the above options, in particular:
    • -v: Volume mounts to /tmp/.X11-unix
    • -e: DISPLAY environment setting

 

Posted on

ECP5 and SPI data overlay

As described in a previous blog post on playing with the ECP5 under Linux, I’ve ported a IoT and networking proven concept to the Versa ECP5G developer kit from Lattice. As we don’t want to use up the entire RAM for program code or data that is rarely used, another attempt was made on this platform to recreate the SPI cache trick implemented on Xilinx Spartan[3,6] hardware (Virtual ROM on small FPGAs).

The first blind run without reading the docs threw me an error: the SPI MCLK dedicated pin can not be used in “user mode”, i.e. after the FPGA has booted. Well, not as user pin, that is. However, the ECP5 has a specific primitive called USRMCLK which obviously allows to mux in a user defined clock to the MCLK pin. However, this requires you to turn off the MASTER_SPI_PORT option in the SYSCONFIG line of your preference *.lpf:

SYSCONFIG SLAVE_SPI_PORT=DISABLE CONFIG_MODE=JTAG CONFIG_SECURE=OFF TRANSFR=OFF MASTER_SPI_PORT=DISABLE SLAVE_PARALLEL_PORT=DISABLE MCCLK_FREQ=38.8 BACKGROUND_RECONFIG=OFF ;

The other SPI pins (MISO/MOSI/CS) again are accessed as normal user pins specified in the LPF. The SPI clock from the custom SPI IP core (there’s no hard IP as in the MachXO* platforms) is silently routed through the USRMCLK primitive to the MCLK pin after the boot process has finished. The USRMCLK also requires a tristate input signal (‘1’ = SPI clock not active). If you are tempted to use this as a clock enable: Don’t. Just feed the gated SPI clock to the usrmclki pin of the USRMCLK primitive and use the /CS signal of the SPI core for the usrmclkts pin.

The disadvantage of this solution: When MASTER_SPI_PORT is disabled, background programming of the SPI flash through the Diamond Programmer will no longer work. Every time you update, you will have to load another bit file with enabled MSPI before you can update the flash. Or alternatively, mess with the boot mode so that you have a default configuration allowing background programming.

On the other hand, we can now update the flash “in system” using a simple UART boot loader so we don’t have to wait for the somewhat painfully slow Programmer to finish.

Program layout

Using the linker script has already been described in (Virtual ROM on small FPGAs). Using this technique again, we relocate all seldom used programm code such as initialization code into the external program memory. We then end up with the boot ROM code in a pure HDL file (RAM initialization bit vectors) and a binary image containing the program/data overlay code. This image is created by a simple objcopy call from the Firmware Makefile:

zpu-elf-objcopy \
        -j .ext.text \
        -j .ext.rodata \
        -O binary main.elf flashdata.bin

This is assembled using the Deployment Tool of the Diamond Programmer, found in the Utilities menu. This tool creates an intel hex file (*.mcs) from the BIT file and an attached flashdata.bin that you can select under the “User Data Files” tap in the Advanced SPI flash creation wizard. Finally, this MCS file can be burned into the SPI flash using the boot loader command:

# bl                                                                            
> Waiting for data..

Then simply upload the mcs file to the target inside your terminal program. Then you can hit the PROG button (not the global reset) to load the new image. Note that there are no safety checks at this moment, an illegal image will not boot and you will have to use the Programmer again.

SPI flash filesystems

A nice way to store files (such as default settings) on the target is by using the OpenSource spiffs tools. It may not fit into the standard configuration though, the library itself is roughly 36k in size. You could try to put parts of it into “overlay”, but it is probably safer to keep it in L1 memory and increase that by another power of two.

This is the repo we use:

https://github.com/pellepl/spiffs.git