-
Notifications
You must be signed in to change notification settings - Fork 1
/
control_unit.v
188 lines (153 loc) · 5.83 KB
/
control_unit.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 09/28/2017 02:54:41 AM
// Design Name:
// Module Name: control_unit
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module control unit {
instruction,
data_mem_wren,
alu_mux_select,
alu_control,
alu_zero,
pc_control
}
// INPUT PORT TO THE CONTROL UNIT.
// This is the 32 bit instructions that will be sent to the control unit for interpretation.
input [31:0] instruction;
// OUTPUT PORT OF THE CONTROL UNIT
// Will be sent to the data memory for write enable access. It is a 4 bit wire since the design involves using 4 RAM blocks
output [3:0] data_mem_wren;
// Enables write action on the register file
output reg_file_wren;
//output reg_file_dmux_select;
//output reg_file_rmux_select;
// This is the wire to select the ALU if it is being called in the instruction.
output alu_mux_select;
output [3:0] alu_control;
// PC has 4 functions which necessiates the usage of a 3 bit addressing scheme.
output [2:0] pc_control;
// Setting the names of the instruction field as follows;
reg [4:0] rs;
reg [4:0] rt;
reg [4:0] rd;
reg [4:0] shamt;
reg [5:0] funct;
//reg [2:0] type;
reg [25:0] address;
reg [15:0] immediate;
//6 bit opcode
wire [5:0] op;
// Demarcating the instruction set
// This design makes sure that the the last 6 bits of an instruction are the opcode. So assigning the last 6 bits of an
// instruction as the opcode.
assign op = instruction[31:26];
always @(instruction)
begin
// R Format instruction. We are assigning it a opcode of 000000 for the decoder to understand that it is a R format instruction
if (op == 6'b000000) begin
address = 26'b00000000000000000000000000; // Since there is no address to go to
immediate = 16'b0000000000000000;
rs = instruction[25:21];
rt = instruction[20:16];
rd = instruction[15:11];
shamt = instruction[10:6];
//type = 3'b001;
funct = instruction[5:0];
end
// J Format instruction. We are assigning it an opcode of 000010 for the decoder to understand that it is a J format instruction
else if (op == 6'b000010 || op == 6'b000011) begin
address = instruction[25:0]; // Jumping to the address that is given.
immediate = 16'b0000000000000000;
rs = 5'b00000;
rt = 5'b00000;
rd = 5'b00000;
shamt = 5'b00000;
//type = 3'b100;
funct = 6'b000000;
end
// I format instruction. This is used for an immediate addition wherein the immediate part will be sign extended to 32 bits for proper operation.
else begin
address = 26'b00000000000000000000000000;
immediate = instruction[15:0];
rs = instruction[25:21];
rt = instruction[20:16];
rd = 5'b00000;
shamt = instruction[10:6];
//type = 3'b010;
funct = instruction[5:0];
end
// ALU MUX SELECT
// ALU needs to be selected for R-Format and I-Format instructions so ALU_MUX_SELECT gets set to 1 and and gets set to 0 for
// J-Format instructions.
if (!(op == 6'h0 || op == 6'b000010 || op == 6'b000011)) begin // J format
alu_mux_select = 1;
end
else begin // R or I format
alu_mux_select = 0;
end
// ALU CONTROL UNIT
// ALU format is synchronized with the control unit wherein the alu_control specifies the type of the operaation that the ALU
// will perform given the signal it receives from the control unit.
// Op code specifies the type of instruction that will be performed, and funct is an additional 6 bit instruction to tell the
// computer about the type of instruction that has to be performed by the ALU. The funct bits have been allotted in an
// arbitrary manner.
if (op == 6'h0 && funct == 6'h24) begin // AND
alu_control = 4'b0000;
end else if (op == 6'h0 && funct == 6'h25) begin // OR
alu_control = 4'b0001;
end else if (op == 6'h0 && funct == 6'h21) begin // ADD - unsigned
alu_control = 4'b0010;
end else if (op == 6'h0 && funct == 6'h26) begin // XOR
alu_control = 4'b0011;
end else if (op == 6'h0 && funct == 6'h27) begin // NOR
alu_control = 4'b0100;
end else if (op == 6'h0 && funct == 6'h22) begin // SUBTRACT - unsigned
alu_control = 4'b0110;
end else if (op == 6'h0 && funct == 6'h2A) begin // SLT
alu_control = 4'b0111;
end else if (op == 6'h0 && funct == 6'h0) begin // SLL
alu_control = 4'b1000;
end else if (op == 6'h0 && funct == 6'h2) begin // SRL
alu_control = 4'b1001;
end else if ((op == 6'h0 && funct == 6'h20) || op == 6'h8 || op == 6'h2B || op == 6'h23) begin // ADD - signed
alu_control = 4'b1011;
end else if ((op == 6'h0 && funct == 6'h22) || op == 6'h4 || op == 6'h5) begin // SUB - signed - AND bne, beq
alu_control = 4'b1100;
end else begin
alu_control = 4'b1111;
end
// This is the control unit for the PC register, the 4 bit instructions specify the type of the function that the program
// counter will perform, these are and not limited to the following, for a J-ype instruction, fora normal increment,
// gets incremented by 4 for next instruction, for a write enable to the registers.
if (op == 6'h2 || op == 6'h3) begin // j, jal
pc_control = 3'b001;
end
else if (op == 6'h0 && funct == 6'h8) begin // jr
pc_control = 3'b010;
end
else if (op == 6'h4 && alu_zero == 1) begin // beq
pc_control = 3'b011;
end
else if (op == 6'h5 && alu_zero == 0) begin // bne
pc_control = 3'b011;
end
else begin // Default
pc_control = 3'b000;
end
end
end module