Lab Demo Resources
Starting from the Lab 02 (including Lab 02), you will be required to use one assembly program for the hardware implementation demo. Based on our experience, we think UART is the best practice for the demo. As up until Lab 03, all we need to do is to input numbers, and the CPU processes the numbers and show the output on the SevenSeg. To achieve that easier, we provide our UART example program for inputing 32-bit numbers into our processor using RealTerm and process them. (Different from Prof. Rajesh's one, but more practical for Lab Demo usage)
# CG3207 Lab 3 UART Based Arithmetic emulator
# ----------------------------------------------------------------
# Supported commands:
# 'a' -> ADD (t4 = t2 + t3)
# 's' -> SUB (t4 = t2 - t3)
# 'm' -> MUL (t4 = t2 * t3)
# 'd' -> DIVU (t4 = t2 / t3)
# Sent as 4 raw bytes via RealTerm (MSB first)
#
# Registers:
# s0?s5 : UART MMIO base & offsets
# s7 : bitmask 0x1
# t0 : flag/temp
# t1 : command (ASCII)
# t2 : operand1 (32-bit)
# t3 : operand2 (32-bit)
# t4 : result (32-bit)
# t5 : byte counter
# t6 : current received byte
# ----------------------------------------------------------------
.eqv MMIO_BASE 0xFFFF0000
.eqv UART_RX_VALID_OFF 0x00 # RX valid flag (bit0=1 means data ready)
.eqv UART_RX_OFF 0x04 # RX data register
.eqv UART_TX_READY_OFF 0x08 # TX ready flag (bit0=1 means ready)
.eqv UART_TX_OFF 0x0C # TX data register
.eqv SEVENSEG_OFF 0x80 # 7-segment/LED output
.eqv LSB_MASK 0x01 # mask for bit0
.text
main:
# Initialization of MMIO addresses
li s0, MMIO_BASE
addi s1, s0, UART_RX_VALID_OFF
addi s2, s0, UART_RX_OFF
addi s3, s0, UART_TX_READY_OFF
addi s4, s0, UART_TX_OFF
addi s5, s0, SEVENSEG_OFF
li s7, LSB_MASK
# Main processing loop
loop:
# Read command byte
READ_CMD:
lw t0, 0(s1) # t0 = UART_RX_VALID
and t0, t0, s7 # check bit0
beqz t0, READ_CMD # loop until data ready
lw t1, 0(s2) # t1 = received command (ASCII)
andi t1, t1, 0xFF # keep only low 8 bits
# Echo command back to RealTerm for confirmation
ECHO_CMD:
lw t0, 0(s3) # check TX_READY
and t0, t0, s7
beqz t0, ECHO_CMD # wait until ready
sw t1, 0(s4) # transmit command back
# Read Operand 1 (4 bytes or 32 bits, MSB first)
li t5, 4 # t5 = byte counter (4)
li t2, 0 # t2 = operand1
READ_OP1_LOOP:
lw t0, 0(s1) # check RX_VALID
and t0, t0, s7
beqz t0, READ_OP1_LOOP # wait for next byte
lw t6, 0(s2) # t6 = received byte
andi t6, t6, 0xFF
# echo the received byte back to realterm
ECHO_OP1_BYTE:
lw t0, 0(s3)
and t0, t0, s7
beqz t0, ECHO_OP1_BYTE
sw t6, 0(s4)
# Build the 32-bit number
slli t2, t2, 8 # shift previous bytes left
or t2, t2, t6 # append new byte
addi t5, t5, -1
bnez t5, READ_OP1_LOOP # repeat 4 times
# After loop:
# t2 = operand1 (32-bit)
# Read Operand 2 (4 bytes or 32 bits, MSB first)
li t5, 4 # t5 = byte counter (4)
li t3, 0 # t3 = operand2
READ_OP2_LOOP:
lw t0, 0(s1)
and t0, t0, s7
beqz t0, READ_OP2_LOOP
lw t6, 0(s2)
andi t6, t6, 0xFF
# Echo the received byte back
ECHO_OP2_BYTE:
lw t0, 0(s3)
and t0, t0, s7
beqz t0, ECHO_OP2_BYTE
sw t6, 0(s4)
# Build the 32-bit number
slli t3, t3, 8
or t3, t3, t6
addi t5, t5, -1
bnez t5, READ_OP2_LOOP
# After loop:
# t3 = operand2 (32-bit)
# Decode and execute command
CMD_CHECK:
li t0, 'a'
beq t1, t0, DO_ADD
li t0, 's'
beq t1, t0, DO_SUB
li t0, 'm'
beq t1, t0, DO_MUL
li t0, 'd'
beq t1, t0, DO_DIVU
j loop # invalid command, restart
# ADD: t4 = t2 + t3
DO_ADD:
add t4, t2, t3
sw t4, 0(s5) # show result on 7-seg
j loop
# SUB: t4 = t2 - t3
DO_SUB:
sub t4, t2, t3
sw t4, 0(s5)
j loop
# MUL: t4 = t2 * t3 (32-bit)
DO_MUL:
mul t4, t2, t3
sw t4, 0(s5)
j loop
# DIVU: t4 = t2 / t3 (unsigned)
DO_DIVU:
beqz t3, DIV_ZERO # protect div-by-zero
divu t4, t2, t3
sw t4, 0(s5)
j loop
# Handle divide-by-zero
DIV_ZERO:
li t4, 0xFFFFFFFF
sw t4, 0(s5)
j loopThe lab manual has provided a detailed guide to setup the RealTerm.
Last updated