Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

1Learning Outcomes

In this section we discuss how to implement the controller, i.e., the control logic block. Here are two figures from previous sections to jog your memory.

As the datapath computes values, the control logic selects the necessary values needed to execute the instruction.

As the datapath computes values, the control logic selects the necessary values needed to execute the instruction (Figure 3 from our chapter introduction).

2Review Control Signals

Before continuing, review the following video, which practices identifying and setting the control signals that set the datapath operation for two different instructions: sw and beq.

Then, confirm the control signals for the subset of instructions shown in Table 1.

Table 1:A partially filled out truth table for RV32I Control Logic, based on the input instruction inst. An asterisk (*) means “don’t care.” Work out the full table in Project 3!

InstructionPCSelImmSelBrUnASelBSelALUSelMemRWRegWEnWBSel
add+4**RegRegAddRead1ALU
sub+4**RegRegSubRead1ALU
addi+4I*RegImmAddRead1ALU
lw+4I*RegImmAddRead1Mem
sw+4S*RegImmAddWrite0*
beq(Table 2)B*PCImmAddRead0*
bne(Table 2)B*PCImmAddRead0*
blt(Table 2)B0PCImmAddRead0*
bltu(Table 2)B1PCImmAddRead0*
jalrALUI*RegImmAddRead1PC+4
jalALUJ*PCImmAddRead1PC+4
auipc+4U*PCImmAddRead1ALU

Remember that branches conditionally update PC based on the output of the branch comparator block. The block’s output signals BrEq and BrLT are fed into the control logic, which then sets PCSel selector that wires into the PCSel mux. See the partial truth table below (Table 2).

Table 2:A partially filled out truth table that determines PCSel for branch instructions.

InstructionBranch?BrEqBrLTPCSel
beqnot taken0*+4
beqtaken1*ALU
bnenot taken1*+4
bnetaken0*ALU
blttaken*1ALU
bltutaken*1ALU

3Control Logic / Controller

The control logic subcircuit (i.e., the controller) takes the instruction bits (and BrEq, BrLT) and outputs all the control signals needed to execute that instruction. The control signals are listed in Table 3.

Table 3:Signals for control logic. Course project signal names, if different, are in parentheses.

NameBit WidthPurpose
PCSel1Selects the ALU input for all B-type instructions where the branch is taken (according to the branch comparator output) and all jumps. Selects the PC+4 input for all other instructions.
ImmSel3Selects the instruction format so the immediate generator can extract the immediate correctly. See Table 3 in the Immediate Generator section
RegWEn11 if the instruction writes to a register, and 0 otherwise.
BrUn11 if the branch instruction is unsigned, and 0 if the branch instruction is signed. Don’t care for all other instructions.
ASel1Selects whether to send the data in rdata1 (RegReadData1) or the PC to the ALU.
BSel1Selects whether to send the data in rdata2 (RegReadData2) or the immediate to the ALU.
ALUSel4Selects the correct operation for the ALU. See Table 2 in the ALU section.
MemRW11 if the instruction writes to memory, and 0 otherwise.
WBSel2Selects whether to write the memory read from DMEM, the ALU output, or PC+4 to rd.

In general, there are two approaches to implementing control logic:

  1. Read-Only Memory (ROM): A ROM reads out words at a given input address. Because the ROM is read-only, it is populated with the needed ones and zeros at design time.

    The regular structure of a ROM means it can easily designed and reprogrammed to fix errors (e.g., during prototyping) or when adding instructions (like extensions for compressed instructions). ROMs are also popular when designing control logic manually, like in this course.

  2. Combinational Logic using AND, OR, and NOT gates. In real chip design, control is typically designed with logic gates because it is more compact and much faster than ROM alternatives. Today, chip designers use logic synthesis tools to convert truth tables to networks of gates. See this approach below.

4ROM Approach

In this course, we implement the controller design in Figure 2, which has two subcircuits:

  1. Read-Only Memory (ROM): The ROM takes in a 9-bit address constructed from the instruction bits, then outputs a 14-bit “word” that can be decoded into the needed control signals.

  2. The Take branch? combinational logic block takes in the Branch Comparator outputs and outputs the PCSel control signal.

Suggested control design has two parts.

Figure 2:Suggested control design has two parts.

5Combinational Logic Approach

Because the ROM effectively performs a lookup on a giant truth table, we can alternatively implement our control logic subcircuit entirely using AND, OR, and NOT gates. We can use our trusty Sum of Products approach to write the canonical form, then reduce the expression using Boolean Algebra Laws.

Example 1: Suppose we wanted to implement a signal that is high if we have an R-Type instruction. The opcode for all R-Type instructions is 0110011 (instruction bits inst[7:0]), so our corresponding boolean expression is:

R-Type=(inst[6]inst[5]inst[4]inst[3]inst[2])\text{R-Type} = (\overline{\texttt{inst}[6]} \cdot \texttt{inst}[5] \cdot \texttt{inst}[4] \cdot \overline{\texttt{inst}[3]} \cdot \overline{\texttt{inst}[2]})

Example 2: Suppose we wanted to implement the BrUn signal. The BrUn signal is high if we have a B-Type instruction AND if that instruction’s funct3 indicates an unsigned compare.

Table 4:B-Type opcode and funct3 fields derived from the RISC-V green card.

InstructionOpcode
(inst[6:0])
Funct3
(inst[14:12])
beq rs1 rs2 label110 0011000
bne rs1 rs2 label110 0011001
blt rs1 rs2 label110 0011100
bltu rs1 rs2 label110 0011110
bge rs1 rs2 label110 0011101
bgeu rs1 rs2 label110 0011111

Considering the fields of the relevant instructions above, we can write an expression for BrUn:

BrUn=(B-Type)(Unsigned Compare)=(inst[6]inst[5]inst[4]inst[3]inst[2])(inst[13])\begin{aligned} \texttt{BrUn} &= (\text{B-Type}) \cdot (\text{Unsigned Compare}) \\ &= (\texttt{inst}[6] \cdot \texttt{inst}[5] \cdot \overline{\texttt{inst}[4]} \cdot \overline{\texttt{inst}[3]} \cdot \overline{\texttt{inst}[2]}) \cdot (\texttt{inst}[13]) \end{aligned}