Lab five (Digital Systems)

Copyright © 2024 J. M. Spivey
Jump to navigation Jump to search

This lab concerns thumbsim, a simulation of an implementation of the Thumb instruction set. The simulation follows the structure of the register-level design developed in the lectures for a single-cycle implementation. You can add extra instructions, including the ones suggested in exercises on Problem Sheet 6, or you can write and assemble test programs (using the same assembler as for the micro:bit) and run them on the simulator. The following files are provided:

Makefile Build script
thumbsim.w Source code for the simulator
test*.s Various test programs
thumb.ld Linker script

In addition, there is a formatted listing of the simulator prepared from the annotated source code.

Building instructions

The simulator is written in C but, using Don Knuth's idea of 'literate programming', in a form that can either be formatted as documentation or compiled into a program. As usual, there's a Makefile that automates the building process, and all being well you can just invoke make and have everything happen by itself. Here, though is an explanation of the steps.

  • The first step is to take the literate source thumbsim.w and 'tangle' it to get a compilable C program. As you will see if you 'weave' the program or look at the online copy (see below), the program is divided into manageable chunks that must be assembled in the right order before the program can be compiled, and that is the job of ctangle.
$ ctangle thumbsim.w
  • The second step is to compile the resulting file thumbsim.c using the host C compiler. There's no need to use our old friend arm-none-eabi-gcc here, because we are building a program to run on the host computer, not to be downloaded to the micro:bit.
$ gcc -o thumbsim thumbsim.c

The whole program is in one C file, with no header files or other gubbins.

As well as compiling the program to run it, you can also format it as documentation, either by saying make thumbsim.pdf, or by following these steps.

  • Format the program and generate a file thumbsim.tex ready for processing with TeX.
$ cweave thumbsim.w
  • Run TeX (or more precisely, pdfTeX) on the file to produce PDF output.
$ pdftex thumbsim.tex

Note that it's TeX itself that is used here, and not LaTeX. The resulting PDF file (for the original program) can also be viewed online. Note that the document as produced by pdfTeX has the contents page at the end, and it can be moved to the beginning using the command

$ pdftk thumbsim.pdf cat end 1-r2 output new.pdf

if the program pdftk is installed.

Running the simulation

The simulator is designed so that when it starts, it expects to load a binary file containing a memory image of the Thumb processor. The machine registers are initialised with 0 in the PC, the address of the top of the 16kB memory in the SP, and a special value in the LR that will halt the simulation when the program returns as from a subroutine. We can prepare such a binary file using the same tools we used to assemble micro:bit programs last term, but with a different linker script. The simulator provides no input/output – the intention is that we follow the execution of the program by studying an execution trace, and for testing capture the return value when the program finishes.

Follow through these steps to run the first test, which simply sets register r0 to 42 before halting.

  • First, assemble the test file.
$ arm-none-eabi-as -march=armv6 -mthumb test1.s -o test1.o
  • Next, use the linker with the linker script thumb.ld to put the code at address 0.
$ arm-none-eabi-ld -T thumb.ld test1.o -o test1.elf
  • Finally, copy the code into a raw binary image.
$ arm-none-eabi-objcopy -O binary test1.elf test1.bin
  • You can now invoke the simulator to run the program.
$ ./thumbsim test1.bin 23 34

As you'll see, values specified (in decimal or in hexadecimal with an 0x prefix) on the command line after the binary file are used to initialise the first few registers of the machine. The simulation runs cycle by cycle with a display of the contents of the first few registers, until the main program returns and puts the magic return address 0xfffffffe in the PC. The simulator prints the value from r0 as the result of the program.

Various other test programs are provided, including a recursive factorial program test8.s and another, test11.s, that uses an array to compute Catalan numbers. The absence of the push and pop instructions makes assembly-language programming for the machine a bit inconvenient but not impossible. You can say make test3.s (for example) to automate the steps required to assemble and run one of the tests, comparing the actual output of the simulation with expected output embedded as a comment in the file.