RISCV Single Cycle RISC-V Processor

Overview

In lecture we built up the RV32I single-cycle datapath stage by stage — Fetch, Decode, Execute, Memory, and Write-Back — and traced how each instruction types flows through it. In this lab you will use the Ripes visual processor simulator to watch that datapath in motion. By stepping through real programs one clock cycle at a time, you will observe exactly which wires carry data, which control signals are asserted, and where each instruction type spends its time.

By the end of this lab you should be able to:


Part 1 — Ripes Orientation

1.1 Launch and Set the Processor Model

  1. Open Ripes: ripes from the terminal.
  2. Click the Select Processor button (CPU chip icon) in the toolbar.
  3. Choose RISC-V Single Cycle Processor.
  4. Under Layout, select Extended (this shows the control unit and all signal wires).
  5. Click OK.

1.2 Tour the Interface

Spend a few minutes locating the following panels — you will use all of them in this lab.

Panel Where to find it What it shows
Editor Left tab Assembly source; assembled hex on the right
Processor view Center of Processor tab Datapath diagram with live signal values
Registers Right side of Processor tab All 32 registers and their current values
Instruction memory Below the processor view PC, stage indicator, and disassembled instruction
Memory tab Separate tab Full address space (.text, .data, stack)

1.3 Toolbar Controls

Button Action
Reset Set PC to entry point, clear register and memory changes
Clock (single step) Advance one clock cycle
Reverse Undo one clock cycle
Auto-clock Step continuously at a chosen rate
Run Execute to completion (no GUI update — use for speed)

Tip: Zoom in and out on the processor diagram with Ctrl + scroll wheel. Click any wire to highlight its full route through the datapath. Hover over any wire to see its signal name and value when running a simulation.

1.4 Explore the Datapath

With the processor loaded but before entering any program, take a few minutes to examine the Extended layout.

Question 1.1 Identify and locate each of the five datapath stages — Fetch, Decode, Execute, Memory, and Write-Back — in the processor diagram. For each stage, name one hardware component (e.g., a memory, an adder, a register file) that belongs to it.


Part 2 — Tracing R-Type Instructions

2.1 Enter the Program

In the Editor tab, clear any existing code and type the following program exactly as shown:

.text
main:
    addi t0, x0, 10       # t0 = 10
    addi t1, x0, 7        # t1 = 7
    add  t2, t0, t1       # t2 = t0 + t1  (R-type)
    sub  t3, t0, t1       # t3 = t0 - t1  (R-type)
    and  t4, t0, t1       # t4 = t0 & t1  (R-type)
    or   t5, t0, t1       # t5 = t0 | t1  (R-type)

    li a7, 10             # Halt the simulator
    ecall

Click Reset to load the program, then switch to the Processor tab.

2.2 Step Through the R-Type Add

Click Clock once to execute addi t0, x0, 10, then again to execute addi t1, x0, 7. Now you are about to execute add t2, t0, t1.

Before clocking, look at the processor diagram and answer the pre-execution questions, then click Clock once and answer the post-execution questions.

Question 2.1 An R-type instruction reads two registers and writes one. In the Extended layout, locate the Register File block. Which two registers are being accessed by the read ports (labeled R1 idx and R2 idx)? What is the name of the ripes signals going to these two read ports? What is the register number going to the write port (labeled Wr idx)? What is the value to the write port (labeled Data in)?

Question 2.2 After clocking add t2, t0, t1, check the Registers panel. What is the value in t2 (x7)? Verify this matches 10 + 7 = 17.

Question 2.3 For an R-type instruction, the Memory stage is a pass-through. In the Extended layout, look at the wire from the ALU result to the data memory block. Is the mem_do_write_ctl control signal high (green) or low (red)) during this instruction? What does that tell you about whether memory is being accessed?

2.3 Observe the Control Unit

The Extended layout shows the Control Unit block receiving a decoded instruction signal from the Decode stage.

Question 2.4 Hover over the wire connecting the Decode block to the Control unit while the add instruction is ready to execute. You might expect to see 0x33 — the raw 7-bit opcode field that the RISC-V ISA assigns to all R-type instructions — but you will see a different value. In Ripes, the Decode unit does not pass the raw opcode to the Control unit. Instead, it uses the 7-bit opcode field together with the funct3 and funct7 fields to produce a single fully-decoded instruction identifier (a 6-bit value that uniquely identifies which instruction this is out of all instructions in the ISA). What value do you see on the wire? Explain why it makes sense for the Decode unit to do this extra work before handing off to the Control unit, rather than sending the raw opcode and letting the Control unit figure out the rest.

Now step through sub, and, and or. Watch the ALU result wire after each clock. Verify that the expected and actual results match.


Part 3 — Tracing I-Type Instructions and Loads

3.1 Immediate Arithmetic

Clear the editor and enter the following:

.data
value: .word 42

.text
main:
    addi t0, x0, 100      # t0 = 100  (I-type arithmetic)
    addi t1, t0, -25      # t1 = 100 + (-25) = 75  (I-type, negative imm)
    andi t2, t0, 0xF      # t2 = 100 & 15 = 4
    lw   t3, value        # t3 = 42  (load word — I-type format)
    lw   t4, value        # t4 = 42  (repeat for observation)

    li a7, 10             # Halt the simulator
    ecall

Click Reset, then switch to the Processor tab.

3.2 Sign Extension of the Immediate

Step to the addi t1, t0, -25 instruction (after executing addi t0, x0, 100).

Question 3.1 The I-type immediate is a 12-bit two’s complement value that is sign-extended to 32 bits before it reaches the ALU. Before clocking this instruction, locate the Immediate Generator (labeled “Imm.”) block in the diagram and hover over its output wire. What 32-bit hex value do you see? Convert -25 to 32-bit two’s complement by hand. Do they match?

Question 3.2 The ALU’s second input comes through a MUX that selects between the register value (rs2) and the sign-extended immediate. For addi, which input should be selected? Look at the green dot on the MUX in the diagram — confirm which input is active.

3.3 The Load Instruction — The Critical Path

The lw instruction is special: it uses all five stages meaningfully and defines the critical path of the single-cycle design.

Step to the first lw t3, value instruction.

Question 3.3 Now clock through the lw. In the Memory tab (open it during or after the clock), navigate to the .data section. What address does the label value occupy? Verify by looking at the ALU result wire in the processor view — it should show the same address being sent to data memory.

Question 3.4 Go back one instruction, back to the lw. Look at the Write-Back MUX (the final MUX before the register file write port). Is the MUX in Ripes selecting the memory data path?

3.4 Visualizing Data Flow

Question 3.5 Click on the wire carrying the ALU result in the processor diagram. Trace where it goes — does it go to both the Data Memory and the Write-Back MUX simultaneously? This is a key property of the single-cycle design: every wire combinationally reaches its destination within the same clock cycle. Describe the path you observe and describe the meanings of those values for each part it connects to. For example, for which instructions does the output of the ALU go to Data Memory? What does that value represent?


Part 4 — Store and Branch Instructions

4.1 Store Instructions

Clear the editor and enter:

.data
buf: .word 0, 0, 0        # three words initialized to 0

.text
main:
    addi t0, x0, 99       # t0 = 99
    addi t1, x0, 4        # t1 = 4 (byte offset for second word)
    la   t2, buf          # t2 = base address of buf

    sw   t0, 0(t2)        # store 99 at buf[0]
    sw   t0, 4(t2)        # store 99 at buf[1]  (S-type)

    li a7, 10             # Halt the simulator
    ecall

Step through to the sw t0, 0(t2) instruction.

Question 4.1 A store instruction has an S-type format: the immediate is split across bits [31:25] and [11:7] of the instruction word to keep rs1 and rs2 in fixed positions. In the Extended layout, look at the Immediate Generator — it must reconstruct the full immediate from both halves. After the ALU computes the store address (base + offset), what address is sent to Data Memory? Look at the memory tab before and after — confirm the value 99 appears at the correct address.

Question 4.2 For a store, the Write-Back stage does nothing — there is no register to update. Look at the register file write-enable signal (mem_do_write_ctrl) in the Extended layout. Is it high or low during a store instruction? What does this confirm about the design?

4.2 Branch Instructions

Add the following to a new program in the editor:

.text
main:
    addi t0, x0, 5
    addi t1, x0, 5
    beq  t0, t1, equal    # branch should be TAKEN (t0 == t1)
    addi t2, x0, 0        # this should be SKIPPED
equal:
    addi t3, x0, 1        # t3 = 1 (execution continues here)

    li a7, 10             # Halt the simulator
    ecall

Click Reset. Step through until you reach the beq instruction (after the two addis).

Question 4.3 Before clocking the beq, note the current value of the PC by looking at the output of the PC register. After clocking, what is the new PC value? Calculate the expected branch target address manually: the beq encodes a PC-relative offset. Does the new PC match PC_of_beq + offset? (The offset is the number of bytes to the equal label.)

Question 4.4 The branch decision in the single-cycle design is made in the Execute stage by a comparator (called Branch and separate from the main ALU). Locate the branch-taken signal in the diagram. Is it green (1) or grey (0) when t0 == t1? What happens to the PC-select MUX when the branch is taken?

Question 4.5 Now modify the program so that t1 is initialized to 6 instead of 5, making the branch not taken. Reset and step through the beq. Does execution now fall through to addi t2, x0, 0? Confirm by checking the value in t2 after execution.


Part 5 — Tracing Your a Program

Run the following RISC-V assembly program that computes the sum of integers from 1 to N (for a fixed N of your choice, e.g., N = 5), using a loop.

.text
main:
    addi t0, x0, 5       # t0 = N (loop counter)
    addi t1, x0, 0       # t1 = sum accumulator

loop:
    add  t1, t1, t0      # sum += counter
    addi t0, t0, -1      # counter--
    bne  t0, x0, loop    # if counter != 0, repeat

    # t1 should now hold 1+2+3+4+5 = 15

    # Print result
    mv   a0, t1
    li   a7, 1
    ecall

    li a7, 10
    ecall

Question 5.1 How many total clock cycles does your loop execute? Count the instructions in the loop body and multiply by the number of iterations. (Each instruction takes exactly one cycle in the single-cycle processor.) Record your count, then use Run followed by checking the Execution info panel to verify.

Question 5.2 How many of those cycles involve the Memory stage doing real work (i.e., a load or store)? What fraction of all cycles involve active memory access?


Part 6 — Instruction Encoding Exploration

In the Editor tab, the right-hand Program Viewer shows each instruction in its assembled binary and hex form.

6.1 Decode an R-type Instruction

Find the encoded instruction for add t1, t1, t0 in the program viewer.

Question 6.1 Write the 32-bit hex value you see. Now break it into the R-type fields using the bit positions from the lecture:

Field Bits Your Value
opcode [6:0]
rd [11:7]
funct3 [14:12]
rs1 [19:15]
rs2 [24:20]
funct7 [31:25]

Verify: rd should be register 6 (t1), rs1 = 6 (t1), rs2 = 5 (t0), opcode = 0x33.

6.2 Decode an I-type Instruction

Find the encoding for addi t0, t0, -1.

Question 6.2 Write the hex and break it into I-type fields:

Field Bits Your Value
opcode [6:0]
rd [11:7]
funct3 [14:12]
rs1 [19:15]
imm[11:0] [31:20]

Convert imm[11:0] from binary to decimal. Does it equal -1?

6.3 Spot the Difference: S-type Split Immediate

Find the encoding for sw t0, 4(t2) (from Part 4).

Question 6.3 The immediate value is 4 (byte offset). In the S-type format, the immediate is split: bits [11:5] go in inst[31:25] and bits [4:0] go in inst[11:7]. Extract these two halves from the instruction word and reassemble them into the full immediate. Does the result equal 4?


Submission

Put your answers to the questions above in a textfile called lab8_answers.txt and upload to Gradescope to complete the lab.


Appendix A — ecall Quick Reference

a7 Effect
1 Print integer in a0
4 Print null-terminated string whose address is in a0
10 Exit (halt simulator)
11 Print