Luz
Contents
1 Introduction
This document will help you get started using / hacking on Luz. It doesn't explain Luz in any depth - read the user manual for that.
1.1 What is Luz?
Luz is an open-source CPU suite. The suite includes:
- A fully functional simulator of the Luz 32-bit RISC CPU.
- An assembler and a linker for code written in the Luz assembly (LASM) language.
In the future, Luz will also feature a complete synthesizable VHDL
implementation of the CPU. For the time being, a partial implementation is
available in the experimental
directory of the Luz source code tree.
The following diagram describes Luz:
1.2 License
The code of Luz is in the public domain. For more information, see the COPYING file in the main directory.
1.3 What is Luz useful for?
Note: this answer is from the time I originally worked on Luz, circa 2008-2010.
I don't know yet. It's a self-educational project of mine, and I learned a lot by working on it. I suppose that Luz's main value is as an educational tool. Its implementation focuses on simplicity and modularity, and is done in Python, which is a portable and very readable high-level language.
Luz can serve as a sample of implementing a complete assembler, a complete linker, a complete CPU simulator. Other such tools exist, but usually not in the clean and self-contained form offered by Luz. In any case, if you've found Luz useful, I'd love to receive feedback.
2 Getting started with Luz
2.1 Documentation
Start with this README and then take a look at the user manual for more details.
2.2 Dependencies
Luz is implemented in pure Python. To run it, you need to have a couple of things installed:
- Python version 2.7 or 3.2+
- The PLY Python library. Luz should work with all recent versions of PLY; I last tested it with 3.9
2.3 Structure of the source tree
doc
: Documentationluz_asm_sim
: The Luz assembler/linker and simulator:
luz_asm_sim/lib
: The implementation of Luzluz_asm_sim/tests_full
: Full tests of Luz that also serve as examplesluz_asm_sim/tests_unit
: Unit tests for Luz
experimental
: Experimental code and features (not currently suitable for use)
2.4 Running examples
Luz has a framework of "full tests" in luz_asm_lib/tests_full
. Each full test is a directory with one or more .lasm
files that implement a program in Luz assembly language (LASM). The full tests serve two roles:
- As examples of using Luz
- For testing the Luz suite on complete programs
See tests_full/README.rst for more details on how to run the full tests. Here I want to focus on one simple example.
2.4.1 The simple loop example
Open tests_full/loop_simple
. In there you'll find a LASM file named
loop.asm
. Open it and take a look. This is a program that computes the sum
of an array. The array is defined statically in the .data
segment, and the
program itself starts with the asm_main
symbol (as all LASM programs should
start - see the user's manual for more details). It iterates over the array in a
loop and sums it into the $r8
register.
Take a few minutes to study the code: if you've seen any other assembly code before, it should be simple to understand. Consult the user's manual for the meaning of individual instructions.
Now, to run the example, make sure PYTHONPATH
is set properly and execute:
python run_test_interactive.py -i loop_simple
You should see something like:
LUZ simulator started at 0x00100000 [0x00100000] [lui $sp, 0x13] >>
This is the interactive shell of the Luz simulator that allows you to execute
the code step-by step, viewing the contents of registers, and so on. If this
sounds like a debugger, you're right - it is. Type help
to see the available
commands and what they mean. Note that run_test_interactive.py
can also run
the whole test from start to finish, without the interactive prompt. Run it with
-h
to see the options.
Execute the following commands:
[0x00100000] [lui $sp, 0x13] >> s 100 [0x00100038] [halt] >> set alias 0 [0x00100038] [halt] >> r $r0 = 0x00000000 $r1 = 0x00000000 $r2 = 0x00000000 $r3 = 0x00000000 $r4 = 0x00000000 $r5 = 0x00100050 $r6 = 0x00100050 $r7 = 0x00000000 $r8 = 0x0000021F $r9 = 0x0010003C $r10 = 0x00000000 $r11 = 0x00000000 $r12 = 0x00000000 $r13 = 0x00000000 $r14 = 0x00000000 $r15 = 0x00000000 $r16 = 0x00000000 $r17 = 0x00000000 $r18 = 0x00000000 $r19 = 0x00000000 $r20 = 0x00000000 $r21 = 0x00000000 $r22 = 0x00000000 $r23 = 0x00000000 $r24 = 0x00000000 $r25 = 0x00000000 $r26 = 0x00000000 $r27 = 0x00000000 $r28 = 0x00000000 $r29 = 0x0013FFFC $r30 = 0x00000000 $r31 = 0x0010000C
- The first command asks the simulator to step through 100 instructions
- The second command disables displaying register alias names since the LASM
code of
loop_simple
doesn't use them (see the user's manual about alias names) - The third command asks Luz to display the contents of all registers.
As you can see, the simulator is now at a halt
instruction, which means the
CPU stopped executing ("halted"). $r8
holds the sum of the array. Now you
can enter the q
command to quit the interactive simulator.
The other examples can be run similarly.