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:
- Navigate the Ripes interface (editor, processor view, register panel, memory tab)
- Step through execution one clock cycle at a time and observe the five stages
- Identify which datapath signals change for different types of instructions
- Verify stage computations against live simulator values
- Measure and reason about the single-cycle critical path
Part 1 — Ripes Orientation
1.1 Launch and Set the Processor Model
- Open Ripes:
ripesfrom the terminal. - Click the Select Processor button (CPU chip icon) in the toolbar.
- Choose RISC-V Single Cycle Processor.
- Under Layout, select Extended (this shows the control unit and all signal wires).
- 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
ripessignals 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 int2(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_ctlcontrol 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
addinstruction 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 thefunct3andfunct7fields 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.datasection. What address does the labelvalueoccupy? 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
rs1andrs2in 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: thebeqencodes a PC-relative offset. Does the new PC matchPC_of_beq + offset? (The offset is the number of bytes to theequallabel.)
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
t1is initialized to 6 instead of 5, making the branch not taken. Reset and step through thebeq. Does execution now fall through toaddi t2, x0, 0? Confirm by checking the value int2after 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 ininst[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 |