Shixuan Li



RISC-V Based CPU Design with Logisim [Part 5]

ALU Design and Input Selection

5. ALU System

An Arithmetic Logic Unit (ALU) is a combinational digital electronic circuit that performs arithmetic and bitwise operations on integer binary numbers.

We will talk about the designing of the ALU system and the input control of ALU in the CPU system. Note that in this part we might use some result achieved from Part 3 (ALUSel). Reviewing Part 3 is recommended.

5.1 ALU Design

As we've talked about in Part 3, our ALU will take in two inputs (remember Bob's story in Part 4?) and do certain operations following instructions given by ALUSel. We perform an Multiplexer to select the proper arithmetic unit in ALU to be performed. Since in Part 3 we've assigned a certain indexing of arithmetic units, which is shown below, we will design out ALU system based on that.

ALU Index

Note that we have totally 13 arithmetic units to be performed > add/ and/ or/ xor/ srl/ sra/ sll/ slt/ div/ rem/ mult/ mulh/ sub

5.1.1 ALU Output

Since we already know the output format, let's just put it out: ALU Output

5.1.2 General Output

And indeed I also added a signal of equal which is 1 if two branches are equal (also I didn't really use it in the project, it does look pretty with this little "light"). The general output is as following: ALU General Output

5.1.3 ALU Inputs

Also we'd better define the inputs at the beginning as well: ALU Inputs

5.1.4 Arithmetic Units

Then the last part is just adding arithmetic units for each operation we want. This part is actually easy since we can find really direct Gates or Arithmetic units from the tools in Logisim. So I'll just post here my results: ALU Units

5.1.5 Overview

Now we've finished the designing for the ALU. And here is an overview of the whole picture:


5.2 ALU in CPU

Let's first see what we've achieve for ALU in spec of the CPU system: ALU Section

Obviously the only problem now is how we should deal with the inputs. Let's first review the Datapath in a Single-Cycle CPU: Single-Cycle CPU Datapath

And the instructions sheet: Instructions

5.2.1 Input of ALU [Input X]

Let's first focus on the first input of the ALU, which we denoted as Input X in our circuit. From the Datapath we can see that there are basically two options we need to choose value from. The first one is PC and the second one is Reg[rs1], which corresponds to R1 in our circuit. But when do choose from each of these? Since it is obvious that we'll need to use a Multiplexer here again, the question can also be addressed as "What is the selection controller (ASel) for input 1?" Intuitions for Input X

From the instruction sheet we notice that when the instruction is an SBtype or UJtype, we implement ALU on PC. Thus, we know that the condition to choose PC for input X is when there is an SBtype or UJtype. However, we also notice that when there is an Utype, it seems that we are doing operations at all, which means that there just can not be an ALU input for implementation. Thus, we add on one more option for ASel, zero. Thus, what we've achieved so far is: Input X ASel

Note that since the method we use to generate ASel has the same intuition as how we generated ALUSel in Part

5.2.2 Input of ALU [Input Y]

Then let's focus on the second input of ALU, which we denoted as Input Y. From the Datapath we can learn that, similarly, we have two options for Y, Reg[rs2] and Imm.

Imm: Immidiate, means specific number in RISC-V, opposite to variable

Again, we need to check out the Instruction sheet for intuitions to our selection controller for Input Y, which we call it BSel. Intuitions for Input Y

We noticed that for Itype, SBtype, Utype, UJtype, and sw instructions, we all have operations with registers and immidiates. Thus, we know that when the instruction is one of the above types, we'll use Imm. We may assume that we just select R2 for the rest of instructions. However, we must also notice that there is a special intruction named swge which takes in no second input. This means that we should just pass in 0 for the second input. Thus, we develop a third option for Input Y. Now let's see what have we achieved for the ALU: Input Y BSel

5.3 Imm

Now we almost finished the ALU part in our CPU. You may noticed that there's only one non-defined part in the ALU structure, the Imm.

The Imm depends on the type of the instructions. To get the correct Imm, we need to select the Imm based on the correct instruction.

5.3.1 Intuitions

The intuition here is that we generate different possible Imms for each type (Note that because of the type difference, we have different "grammars" reconstructing the Imm from the instruction).

You should be familiar with this part of information about RISC-V. If it confuses you, please check out HERE(Not-Published) for related information in RISC-V

Then, we may take usage of the same method we generated ALUSel in Part (If the following parts confuses you, you may want to check it out)

5.3.2 Imm Re-Assembling

As what we discussed in Intuitions, we may need to first generate Imm for each possible types of instructions. This is just a simple re-assembling and sign-extending. So I'll just put my results here: Imm Re-Assembling

5.3.3 Indicator

Note: If you are confused about our implementations from this step, you may want to check out Part for an thorough explanation to a similar method.

We use indicators to denote which instruction type we have: Indicator

5.3.4 Counting

We count for the index of the types. This step transforms the index of types into bit-indexes. Counting

5.3.5 Accumulation

We accumulate the index values and get a controller ImmSel for our selection of Imm types of values. Accumulation

5.3.6 Get Imm

Now we have all possible Imms based on each instruction type and have an controller selecting the correct instruction type. We can build an Multiplexer to get our result. Get Imm

In Part 6 we'll be talking about Memory Management and Write Back systems.