CMPUT 229 - Computer Organization and Architecture I

Lab 4: Multi-Timer Implementation

229 Lab 4: Multi-Timer Implementation

Multi-Timer Implementation

Information

This lab focuses on the coordination of asynchronous operations, such as interruptions, with the processor. Instead of using syscalls, in this assigment you will handle all input and output using interruption handlers and memory-mapped device access. Display functions will be handled by an interruption handler that you will create and will use memory-mapped device access.

Interrupts

Cause and Status Register

This lab uses external interrupts from hardware. The role of three CSRs (Control and Status Registers) are important for the use of interrupts: ustatus, uie and utvec.

These CSRs can be set by using the CSR instructions. For example, to enable user-level interrupts in ustatus use "CSR Read/Write Immediate" instruction: csrrwi zero, 0, 0x1. Or use pseudo-instructions to read and write to the CSR registers. For example:

        csrr    t0, 4       # read from CSR#4 to t0
        csrw    t0, 6       # write whats in t0 to CSR#6
        csrwi   0, 0x4      # write 0x4 to CSR#0
    

Once an interrupt is raised it must be handled in an interrupt handler that you will create. An interrupt handler is analogous to a normal function but there are some key differences. An interrupt can occur at any time, therefore the handler must guarantee that all registers are restored to their original values after the handler finishes. Thus, the handler must save any register that it uses (not just the s registers) and the handler must restore the original values to these registers prior to returning. Also, the instruction uret must be used to leave the interrupt handler instead of the jr ra instruction that is used to return from a normal function.

Keyboard & Display

Use the Keyboard and Display MMIO Simulator, available under the "Tools" tap in RARS, to interact with the timer. You will display the timers in the display section, and will start or modify timers in the keyboard section. Don't forget to click "Connect To Program" after you assemble your program and before running it.

Generally devices have two registers associated with them, a control and a data register. The control register relays information about the device's state, and the data register relays data to or from a device.

Bit 0 in the display control register is the ready bit. Its value must be 1 before a character is sent to the display. If the ready bit is 0, you have to wait till it becomes 1 before sending a value to the data register.

A bell character (ASCII #7) in the lower 8 bits of the data register indicates a cursor positioning command. The new position of the cursor is specified as follows: the row number is in the bits 8-19, and the column number in bits 20-31 in the data register.

To print a character, save the ASCII code for that character to the lower 8 bits of the data register, the upper 24 bits are irrelevant if the character is not the bell character.

The keyboard input, also has a control and a data register. The control register is used to enable keyboard interrupts. Setting bit 1 in the control register to 1 enables keyboard interrupts. Bit 0 is automatically reset to 0 after a keyboard interrupt occurs. Thus, after handling such an interrupt, the handler must set this bit to 1 to re-enable keyboard interrupts.

The keyboard data register contains the code of the key pressing that caused the interrupt.

A separate keyboard interrupt occurs for every key pressed when the keyboard interrupts are enabler. Therefore, the user program receives one character at a time. The solution for this lab has to build a string using these characters until it receives a newline character (ASCII code 0x0a), corresponding to the user pressing enter. At that point, the solution has to parse the string, start/modify the timer accordingly, and reset the string for the next input. For more information about the tool, click the help button in the tool window.

Timer

In RISC-V timing functionality is managed by the timing harware thread (hart), maintaining the time asynchronous and allowing the program to raise an interrupt at a specific time. To do this the core keeps track of the time in the 64-bit register time which holds the current time (in milliseconds) since the program started. To generate a timer interrupt at a specified time, the value in the register timecmp must be set. When the value in timecmp is less than or equal to the value in time a timer interrupt occurs. To simulate RISC-V timing functionality you must use the Timer Tool under the "Tools" tap in RARS. Don't forget to click "Connect To Program" and "Play" after you assemble your program and before running it.

Memory-Mapped IO

Memory-mapped IO allows interaction with external devices through an interface pretending to be system memory. This mapping allows the processor to communicate with these devices using the load-word and store-word instructions.

The keyboard control reigister is mapped to the address 0xFFFF0000. For interrupts to be enabled, bit 0 must be set to 1; after the keyboard interrupt occurs, this bit is automatically reset to 0.

The keyboard data register is mapped to the address 0xFFFF0004. The ASCII value of the last key pressed is stored here.

The display control register is mapped to the address 0xFFFF0008. Bit 0 of this register indicates whether the processor can write tothe display. While this bit is 0 the processor cannot writte to the display. Thus, the program must wait until this bit is 1.

The display data register is mapped to the address 0xFFFF000C. When a character is placed into this register, given that the display control ready bit (bit 0) is 1, that character is drawn onto the display. If the character is the bell character (ASCII code 0x07) the display will move the cursor and the bits 8-19 and 20-31 correspond to the row and column respectively.

The time register is mapped to the address 0xFFFF0018. time is a read only register holding the time since the the program has started in milliseconds.

The timecmp register is mapped to the address 0xFFFF0020. timecmp holds the time that the timer will go off. Writing to this register is required in order to setup the timer.

Assignment

The task in this lab is to write a program in RISC-V assembly that manages six separate countdown timers concurrently. This program will read in the time in seconds for a given timer, accurately count down the timers to zero, and then reset the timer. The program must do the following:

Constraints:

\begin{itemize} \item Reading or printing syscalls cannot be used in this program. Instead, the program must use the interrupt/poll system to interact with the keyboard and the display. \end{itemize}

You're provided with a Keyboard and Display MMIO Simulator display demo and a solution template with pre-programmed functionality that you can use.

As you will be writing your own handler, runtime errors won't be shown with RARS as usual. Thus, you are provided with a section of the handler that prints the line where an error occurred and the error code. Use the table to the right to identify the error.

Resources

Slides used for in-class introduction of the lab (.ppt) (.pdf)

Slides used for in-lab introduction of the lab (.pdf)

Marking Guide

Assignments too short to be adequately judged for code quality will be given a zero.

Submission

There is a single file to be submitted for this lab. The file name should be multiTimer.s and it should contain the code for both the interrupt handler and the main (i.e. your file must contain all the code for a successful stopwatch execution).