ALU Design and Input Selection
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.
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.
Note that we have totally 13 arithmetic units to be performed
add/ and/ or/ xor/ srl/ sra/ sll/ slt/ div/ rem/ mult/ mulh/ sub
Since we already know the output format, let’s just put it out:
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:
Also we’d better define the inputs at the beginning as well:
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:
Now we’ve finished the designing for the
ALU. And here is an overview of the whole picture:
Let’s first see what we’ve achieve for ALU in spec of the CPU system:
Obviously the only problem now is how we should deal with the inputs. Let’s first review the Datapath in a Single-Cycle CPU:
And the instructions sheet:
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?”
From the instruction sheet we notice that when the instruction is an
UJtype, we implement ALU on
PC. Thus, we know that the condition to choose
PC for input X is when there is an
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:
Note that since the method we use to generate
ASel has the same intuition as how we generated
ALUSel in Part 22.214.171.124.
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,
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
We noticed that for
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:
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 depends on the type of the instructions. To get the correct
Imm, we need to select the Imm based on the correct instruction.
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 126.96.36.199. (If the following parts confuses you, you may want to check it out)
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:
Note: If you are confused about our implementations from this step, you may want to check out Part 188.8.131.52 for an thorough explanation to a similar method.
We use indicators to denote which instruction type we have:
We count for the index of the types. This step transforms the index of types into bit-indexes.
We accumulate the index values and get a controller
ImmSel for our selection of
Imm types of values.
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.
In Part 6 we’ll be talking about Memory Management and Write Back systems.