CSCE 611 Fall 2026 Lecture 2: RISC-V ISA 1
Watch on YouTube →
Overview
Jason D. Bakos reviews RISC-V assembly concepts needed to design a CPU, then demonstrates instruction execution and debugging in RARS. He also introduces fixed-point arithmetic, showing how scaling and 64-bit product re-normalization support Lab 1’s FPGA square-root calculator using 18 switches and hex displays.
Key takeaways
- RISC-V’s load-store architecture requires explicit movement between memory and registers, so correct register allocation depends on tracking each value’s lifetime through its last use.
- For an integer array, element i is at base + 4i; shifting the index left by two calculates the byte offset, while loop control generally needs a separate index register.
- RARS exposes the difference between assembly mnemonics and machine instructions, including pseudo-instruction expansion, and its single-step debugger advances whole instructions rather than pipeline cycles.
- The class FPGA I/O convention maps F00 to hex-display output and F02 to switch input through a modified `csrrw` implementation; standard RARS system calls instead use A7 for the service number and A0 for arguments or results.
- In fixed-point multiplication, fractional-bit counts add: two 14-fractional-bit operands produce 28 fractional bits, so returning to the original scale requires shifting the combined 64-bit product right by 14.
- Lab 1 applies fixed-point arithmetic to a binary-search square-root calculator, using the FPGA’s 18 switches for the input and its hex displays for the result.
Chapters
0:00
Course Plan, RARS Setup, and Lab 1 Logistics
- The lecture moves from a RISC-V assembly review to simulator demonstrations, fixed-point representation, and an introduction to Lab 1.
- RARS is a Java-based RISC-V simulator; running it locally requires a Java Virtual Machine, and course downloads include a modified version for FPGA I/O.
- Lab 1 uses RARS and does not require an FPGA board; its stated deadline is Sunday, September 6, before midnight.
2:29
Why CPU Design Requires RISC-V Assembly and Load-Store Thinking
- The course focuses on microarchitecture, but students need to understand the instruction set architecture that the processor implements.
- RISC-V uses a load-store model: move data into registers, operate on it there, then store or output the results.
- This model makes tracking which variables occupy registers—and when those values remain live—an important source of assembly bugs.
5:05
RISC-V Register Numbers, ABI Names, and the Zero Register
- RISC-V has 32 integer registers, X0–X31, which can also be referenced by ABI names such as T0–T6, S0–S11, and A0–A7.
- X0 always reads as zero, so adding X0 to another register provides a copy operation; the `move` mnemonic is a pseudo-instruction for this behavior.
- RA is X1, while argument registers A0–A7 and temporary and saved registers follow calling-convention roles that matter especially in subroutines.
- System calls use symbolic names such as A7, so code may mix ABI names and X-register numbers for the same physical registers.
9:27
Immediate Instructions and Register-Lifetime Bugs
- An immediate is a constant embedded in an instruction; `addi` can increment a register, while RISC-V has no `subi`, so subtraction uses a negative `addi` constant.
- R-type arithmetic uses three registers, whereas I-type arithmetic uses a register and an immediate; these instruction formats are encoded differently.
- A register becomes live when initialized and remains live through its final use; reusing it too early can overwrite a needed value.
- In the expression example, reinitializing T0 for a multiply destroys B before the final addition, illustrating why lifetime tracking prevents bugs.
15:39
Branch Logic, If-Else Translation, and Array Loop Counters
- Conditional branches test register values for relations such as equal, less than, or greater than; RISC-V also provides unsigned comparison branches.
- To keep the `if` body first in the instruction sequence, the example branches on the negated condition to `else`, then jumps past the else body.
- Array loops commonly need separate registers for the loop index and byte address: an integer-array address advances by four bytes per element.
- A loop’s continuation test can directly branch when the condition is true, unlike the demonstrated if-else layout that branches on the negation.
22:42
The RISC-V Instruction Subset for the Course CPU
- Bakos identifies the subset the class will implement rather than all roughly 40 base instructions plus multiplication extensions.
- The selected arithmetic group includes add, shifts, signed and unsigned set-less-than, and multiply operations; the complete list also includes logical operations and right shifts.
- A class-specific subset is sufficient for hand-written programs, but omitting instructions from a general-purpose processor could leave compiler-generated code unsupported.
25:23
RARS Assembly, Machine Code, and Single-Step R-Type Demos
- RARS combines a code editor, assembler, simulator, and debugger; its register panel shows both ABI and numeric names and displays register values.
- Assembly reveals the generated machine instructions, making pseudo-instruction expansion—such as `move` becoming an add with X0—visible.
- The demonstration initializes X2 and X3 to 2 and 3, then checks results including add = 5, left shift of 2 by 3 = 16, and set-less-than = 1.
- A 32-bit multiply writes the low product bits; `mulh` or `mulhu` retrieves the high bits for signed or unsigned multiplication.
34:01
Immediate Arithmetic and Shifts in the RARS Simulator
- `addi` adds a constant directly to a register, while an immediate left shift multiplies the value by a power of two.
- The demo shifts 2 left by 10 bits, yielding 2,048, which illustrates the equivalence to multiplication by 2^10.
- RARS can assemble multiple open files together, so the demonstration adjusts its assemble-all setting to avoid accidentally concatenating test programs.
36:44
Conditional Branches, Jump-and-Link, and Link Addresses
- With X1 = 1 and X2 = 2, `blt` takes the branch to `skip` because 1 is less than 2.
- `jal` jumps to a target and writes the next-instruction address into its destination register; the demo stores that link address in X3.
- `jr` through X3 returns execution to the saved address, while jumps can discard the link by targeting X0.
- A branch instruction already uses its immediate to encode a target, so comparing against a constant such as 10 requires first placing 10 in a register.
42:14
Base-Offset Loads and Computing Array Element Addresses
- A load or store combines a base-register address with a fixed immediate offset; variable array indices require explicit address calculation.
- For an integer array, the element address is the array base plus index × 4; shifting the index left by two computes that byte offset.
- In the RARS example, `foo` contains four words, index 2 selects the third element, and the calculated load returns 6.
- The `la` address-loading pseudo-instruction expands into real instructions, including `auipc`; the course CPU project will not implement loads and stores.
48:22
CSR-Based FPGA I/O with RISC-V CSRRW
- The course uses `csrrw` as a class-specific path to FPGA input and output because the project CPU does not implement ordinary loads and stores.
- The instruction ordinarily swaps a general-purpose register value with a control-and-status register; the modified RARS adds I/O registers at addresses F00–F03.
- The class uses F00 for output to the FPGA hex displays and F02 for input from the switches, with the selected address determining the direction.
- The modified simulator exposes IO0–IO3 in its control-and-status register view; the lab sheet will specify the required hardware behavior.
54:28
RARS Console System Calls and Lab 1 Input/Output
- RISC-V uses `ecall` for simulator system calls; RARS help documents the call numbers and their register conventions.
- For example, printing an integer uses call 1 in A7 and the value in A0; printing a string uses call 4 and its address in A0.
- A0 carries either an output argument or an input result, while A7 selects the service; X-register aliases work because they refer to the same registers.
- Console calls support Lab 1 testing in RARS, but hardware execution replaces them with FPGA switch input and display output.
58:26
Binary Place Values, Unsigned Ranges, and Two’s-Complement Ranges
- Convert a binary value by summing each bit multiplied by 2 raised to its position, counting from bit 0 at the right.
- An unsigned 7-bit value ranges from 0 to 2^7 − 1 = 127, with a resolution of one.
- A signed 7-bit two’s-complement value ranges from −64 to 63, still representing 128 distinct bit patterns.
1:01:41
Fixed-Point Scaling, Fractional Bits, and Numeric Resolution
- Fixed-point representation assigns binary place values to fractional bits without requiring special arithmetic hardware.
- With two fractional bits, the stored integer is scaled by 2^-2; a bit pattern representing 83 as an integer therefore represents 20.75.
- An M.N format can mean M total bits and N fractional bits, though some conventions use M for whole-number bits, so the notation must be checked.
- For an unsigned format with N fractional bits, the step size is 2^-N and the maximum value is 2^(M−N) − 2^-N when M counts total bits.
1:07:31
64-Bit Fixed-Point Products and Lab 1’s FPGA Square-Root Search
- Multiplying two fixed-point values with 14 fractional bits produces 28 fractional bits; converting the result back to the original format requires a 14-bit right shift.
- For 32-bit operands, `mul` returns the low 32 product bits and `mulh` returns the high 32 bits, together forming the 64-bit product.
- A 32.14-style value can be re-normalized across the register boundary by shifting the low word right 14, shifting the high word left 18, and combining the pieces with bitwise OR.
- Lab 1 uses binary search and repeated squaring to estimate a square root; the FPGA’s 18 switches provide the integer input and the hex displays show the fractional result.
Summary, takeaways, and chapters were generated by AI from the video's transcript and may contain errors. The video belongs to its creator, Jason D. Bakos.