The project at DTU is a small 32-bit processor, called Leros. Leros is a tiny processor core for embedded systems. See more documentation on the website for Leros.
Leros is able to execute a fixed program from a read-only memory or a program can be loaded to a programmable instruction memory. The instruction memory is programmed via an APB interface which is connected to the Ibex core in the staff area as well as to an UART-to-APB bridge. The UART-to-APB bride uses a serial protocol for performing APB read and write transactions from a host machine.
Leros is controlled through a register mapped into the APB memory space which controls the boot source and Leros' reset pin. It has access to a UART interface and 4 GPIO pins.
Cross Core Registers facilite communication between Leros and Ibex. They consist of two sets of registers, the first set is readable from APB and writeable from Leros, the second set is writeable from APB and readable from Leros. For now system features 4 cross core registers in each direction. Cross core registers are 32-bit wide.
Initialize git submodules:
git submodule update --init --recursiveGenerate SystemVerilog:
make generateRun tests:
make testSynthesize the design with the specified program in ROM.
make -C basys3 gen synth PROG=leros-asm/??.sUpload the bitstream to the FPGA:
make -C basys3 progUpload a program to the instruction memory:
make -C basys3 upload PROG=leros-asm/??.smake -C openlane gen hardenmake -C openlane gen librelaneThe DTU subsystem is configured using DtuSubsystemConfig. An example configuarion is shown below:
new DtuSubsystem(
DtuSubsystemConfig(
romProgramPath = "leros-asm/didactic_rt.s",
instructionMemorySize = 1 << 11, // 2kB
dataMemorySize = 1 << 8, // 256 bytes
lerosSize = 32, // 32-bit accumulator
lerosMemAddrWidth = 16, // 16-bit address space
crossCoreRegisters = 4,
frequency = 8000000, // 8MHz
lerosBaudRate = 9600,
ponteBaudRate = 9600,
apbAddrWidth = 12,
apbDataWidth = 32
)
)| Name | Direction | Function |
|---|---|---|
clock |
input | clock |
reset |
input | reset signal (active high) |
io_apb_p<signal> |
input/output | APB interface |
io_irq |
output | unused |
io_irqEn |
input | unused |
io_ssCtrl |
input | unused |
io_gpio[0] |
output | Tx for Uart to Apb bridge |
io_gpio[1] |
input | Rx for Uart to Apb bridge |
io_gpio[2] |
output | Tx for Leros Uart |
io_gpio[3] |
input | Rx for Leros Uart |
io_gpio[4-15] |
input/output | Leros GPIO |
The DTU subsystem development can be done with either Docker or Nix/Lix.
-
Lix (Recommended): https://lix.systems/install/
- A modern implementation of the Nix language with improved usability
- Commited to maintaining purpose for open source community than commercial interests.
- Built for better error messages and developer experience
- Fully compatible with Nix packages and flakes
- Designed to evolve while maintaining backward compatibility
-
Nix: https://nixos.org/download
- The original package manager that Lix is based on
-
Docker: https://docs.docker.com/engine/install/
- Container-based alternative if you prefer not to install Nix/Lix
- Enter the development environment (assuming from project root):
nix develop open-source-hardware-development-environment/- You'll now have access to all development tools including:
- Openlane 2 with all dependencies
- Verilator for Verilog simulation
- SBT for Scala/Chisel development
- Leros LLVM toolchain (x86 platforms only)
- ZSH with developer-friendly configuration
# Build the Docker image
docker build -t hw-dev-env open-source-hardware-development-environment/
# Run the Docker container with the development environment
# in the current directory
docker run -it -rm \
-v .:/home/developer/workdir/ \
hw-dev-env \
nix developRemember to change the local path to your codebase in the Docker command if it is needed elsewhere.
For more detailed instructions, see the development environment README from the project or from the repository page of the submodule