Skip to content

Latest commit

 

History

History
112 lines (82 loc) · 3.41 KB

README.md

File metadata and controls

112 lines (82 loc) · 3.41 KB

Programming the Pulpino on CW305

This README contains all the information needed to program the PULPINO core on the CW305 given the source files in this repository. This README assumes that you have a ready synthesized project according to the setup guide in this repository. First, this README gives a small overview of the memory system and the solutions to program each of them. Then, all the specifics a given to program each of them.

Overview

The PULPINO contains 3 main memories:

  1. Bootcode ROM
  2. Instruction RAM
  3. Data RAM

The Bootcode ROM needs to be defined on Vivado synthesis in the ./rtl/bootcode.sv files. The details are explained in Programming the Bootcode. The Instruction and Data RAM are programmed each time the core is reset. The details on how to program the RAM are given in Programming the RAM.

There exist two prepared implementation on how to program the PULPINO, with Rust and with C. Both provide an example blinky led program for the RAM called blinky_ram. You can adapt your program from there.

The C and Rust implementations use small libraries called ext_io that allow for IO with the python interface. The communication protocol is documented here. The ext/connection.py file provides the python side of that interface and can be used to start program and start the board.

Programming the Bootcode

In the current setup the bootcode is used to program the RAM and jump to the proper entry address. The source code for this bootcode can be found in the /program/target/rust/bootcode. A precompiled version can be found /program/target/out/bootcode_program. This contains the Verilog array that can be pasted into the ./rtl/bootcode.sv source file in your PULPINO project.

To compile it yourself.

cd target
./compile.sh rust/bootcode --out=verilog

# Copy `out/bootcode` array into `rtl/bootcode.sv`

Programming the RAM

The RAM is programmed using the USB interface. The python communication layer for this is defined in the ext/connection.py. This expects an array of bytes in Little-Endian per word. The target/compile.sh script can generate this array for you. Below, is an example for the blinky_led example.

cd target
./compile.sh rust/blinky_led
# ./compile.sh c/blinky_led

# Copy `out/blinky_led` array into your python file

Within Python you can then run the following to program it.

from connection import PulpinoConnection

RAM = [
	# ...
]

# TODO: add your bitstream
bitpath = "path/to/bitstream.bit"
pulpino = PulpinoConnection(bitpath, force = True)

if not pulpino.get_raw().fpga.isFPGAProgrammed():
    print("ERR: FPGA failed to program")
    exit(1)

# Reset the PULPINO
pulpino.reset()

# Program the RAM address at an offset of 0x0
pulpino.program(0x0, RAM)

# Stop Programming
pulpino.stop_programming()

# Entry Address
pulpino.send_word(0x0)

# Now the PULPINO is running

Creating a new application

To create a new application using C or Rust. Just copy the respective blinky_led to the respective c or rust folder and make your changes. For Rust, remember to update the Cargo.toml to match the folder name.

Now, you can compile your new folder with the compile.sh script by running.

cd program/target
./compile.sh c/your_new_folder
# OR
./compile.sh rust/your_new_folder