Back to EECS 31L Index

6. EECS 31L / 06 Processor Design (Single-Cycle)

EECS 31L • Study Notes • Processor Design
Mahmoud Elfar • Spring 2026 • v0.1

v0.1: Initial version


Table of Contents


6.1. General-Purpose Processors

Loosely speaking, a processor is a piece of hardware that executes instructions. An instruction is a command that tells the hardware to perform a specific operation (ex: add two numbers). But we want our hardware to do more than just addition. As such, the idea of a general-purpose processor emerges: Give me a piece of hardware that can:

Let’s rewrite these requirements in more precise terms:

  1. The program must be stored somewhere. A processor does not know in advance what it will compute. The sequence of operations it should perform must be loaded into memory before execution begins, and the processor must be able to read those operations one at a time.

  2. Execution must be step-by-step and repeatable. The processor reads one instruction, executes it, then moves to the next. State from one step must persist to the next. This requires memory elements — not just combinational logic.

Everything in this note is a direct consequence of these requirements. Some of the historical details were covered in lecture, but they are not part of your exam material, so we won’t cover them here.

↑ Back to top


6.2. ISA vs. Microarchitecture

Before building a processor, it is important to separate two distinct concepts that are often conflated.

Instruction Set Architecture (ISA) is the contract between software and hardware. It defines:

The ISA says what the processor must do. It says nothing about how.

Microarchitecture is the hardware implementation of an ISA. Two processors can implement the exact same ISA in completely different ways — different numbers of pipeline stages, different cache organizations, different ALU designs — and both will correctly execute the same programs because they both honor the ISA contract.

In this course, the ISA we use in our examples is RISC-V: a modern, open ISA designed for simplicity. The microarchitecture we will implement is the single-cycle processor: every instruction completes in exactly one clock cycle. Later in your career, you will encounter more complex and sophisticated ISAs and microarchitectures, but the basic principles will be the same.

At some point, we will also give an example for how to trace the execution of a program on a processor that uses different ISA and microarchitecture than what you implement in the lab. For this, we will use the Emotion Engine – the processor used in the original PlayStation and PlayStation 2 consoles.

In class, we jumped back and forth between ISA and microarchitecture details. In this note, we will follow a more disciplined approach and start with the microarchitecture first.

↑ Back to top


6.3. Microarchitecture: Datapath Building Blocks

A microarchitecture describes the hardware components that implement an ISA. We can divide the components into two categories:

The components within each:

Our focus here is on the datapath building blocks. We will cover how those blocks are interconntected to form the datapath and the controller in later notes.

6.3.1. The ALU

The Arithmetic Logic Unit (ALU) is the combinational component that performs computations: addition, subtraction, AND, OR, comparison, and so on.

ALU Model:

flags are 1-bit signals that describe properties of the result. The flags used in this course are:

Flag Name Set to 1 when…
zero Zero The result is exactly zero (all bits are 0)
sign Sign The result is negative (the most significant bit is 1)
overflow Overflow The result overflows (whether signed or unsigned)
carry_out Carry out The addition or subtraction produced a carry out of the most significant bit (relevant for unsigned arithmetic)

Note: Remember that not all carry outs are overflows. In exams, I won’t ask you to compute or model either flags. You have suffered enough through EECS 31.

There can be more flags. In this class, we will focus only on zero and sign – you must know what they mean.
zero is particularly important for branch instructions. For example, beq subtracts two registers and branches if zero is asserted. What is beq, you ask? “Branch if equal”, but that’s a topic for another day.

Here is an example of the logic diagram (simplified for clarity) of a 32-bit ALU.

32-bit ALU Logic Diagram

Simplified Logic Diagram of a 32-bit ALU

From how the multiplexer is wired, we can deduce the ALU control encoding for each operation:

Operation ALU control value
ADD 000 (0x0)
SUB 001 (0x1)
XOR 100 (0x4)
OR 101 (0x5)
AND 110 (0x6)

Some notes:

This is a favorite exam question as it tests your understanding of how the ALU works, as well as your ability to read and interpret logic diagrams and multiplexer control signals.

↑ Back to top

6.3.2. The Register File

Purpose:

Construction: You can build a homebrew register file by doing the following:

This is getting out of hand. Just check the logic diagram below. You should be able to build something like this – you studied each component before in EECS 31. It is important to understand how the register file works internally. For 31L exams, you only need to know the input and output ports, the behavior, and how to interpret and select the correct values for W and N.

Register File Diagram

Simplified Logic Diagram of a 32-bit Register File

N×W notation. A register file is described as N×W, or an N W-bit register file, where:

A 32×32 register file, or a 32 32-bit register file, has 32 registers, each is 32 bits wide, with a 5-bit address bus and 32-bit data buses. I guess it is a bad example of naming, but RISC-V’s register file is 32×32.

A better example:
A 64×16 register file has 64 registers, each is 16 bits (2 bytes) wide. Expect the address bus to be 6 bits (log₂64 = 6) and the data buses to be 16 bits wide.

Why two read ports, one write port. Most instructions read two source registers and write one destination register. Having two independent read ports means both operands are available simultaneously in the same cycle — no need to sequence them. One write port is sufficient because an instruction produces at most one result. Adding a second write port would roughly double the decoder and wiring complexity with no benefit for the instruction set we support.

One example of port naming convention is given in the following table. There are many variations, you should get used to encountering a new one, even within the same course.

Register File Block

Register File Block Diagram (ports only)

                +-------------+
rg_rd_addr1 ──→ |             | ──→ rg_rd_data1
rg_rd_addr2 ──→ |    Reg      | ──→ rg_rd_data2
rg_wrt_addr ──→ |    File     |
rg_wrt_data ──→ |    32×32    |
rg_wrt_en   ──→ |             |
clk         ──→ |             |
                +-------------+
Port Direction Width Name in lab
Read address 1 Input 5 rg_rd_addr1
Read address 2 Input 5 rg_rd_addr2
Read data 1 Output 32 rg_rd_data1
Read data 2 Output 32 rg_rd_data2
Write address Input 5 rg_wrt_addr
Write data Input 32 rg_wrt_data
Write enable Input 1 rg_wrt_en

Register File Model:

Memory Elements as Register File Variants:
All other memory elements in the processor are variations of the same concept. What varies is the number of registers, the number of read/output buses (1 or 2), and the number of write buses (1 or none).

6.3.3. Program Counter (PC)

Purpose:

Construction:


next_pc ──→ [ PC ] ──→ pc_out
clk     ──→ [    ]

6.3.4. Instruction Memory (IMEM)

Purpose:

Construction:

            +---------+
pc_out ───→ |  IMEM   | ──→ instruction (32 bits)
            |   N×32  |
            |  ROM    |
            +---------+

6.3.5. Data Memory (DMEM)

Purpose:

Construction:

               +-------+
addr       ──→ | DMEM  | ──→ read_data
write_data ──→ |  N×32 |
MemWrite   ──→ |  RAM  |
MemRead    ──→ |       |
clk        ──→ |       |
               +-------+

6.4. It is all Memory (an insight, not another component)

Every storage element in the processor can be seen as an instance of the same abstraction: a bank of registers, with combinational read and synchronous write. The differences are in scale and access restrictions, not in kind.

Element Size Read ports Write ports Type
PC 1×W 1 1 Register
IMEM N×32 1 0 ROM
Register File 32×32 2 1 RAM
DMEM N×32 1 1 RAM

↑ Back to top


In the next two study notes, we will see how do instructions look like, and trace their execution through the datapath.