Skip to content

Instantly share code, notes, and snippets.

@askvortsov1
Created July 8, 2021 13:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save askvortsov1/80f756d33c034f70e8ac04c0f732461e to your computer and use it in GitHub Desktop.
Save askvortsov1/80f756d33c034f70e8ac04c0f732461e to your computer and use it in GitHub Desktop.
`timescale 1ns/1ps
module control_unit (
input [5:0] op,
input [5:0] funct,
input preinputs_equal,
output reg use_rt_for_dest,
output reg reg_write,
output reg mem_write,
output reg use_imm_for_alu_src,
output reg jal,
output reg shift,
output reg [3:0] alu_control,
output reg mem_to_reg,
output reg [1:0] pc_selector
);
initial pc_selector = 0;
always @ (*) begin
// R-Type
if (op == 'b000000) begin
use_rt_for_dest <= 0;
use_imm_for_alu_src <= 0;
jal <= 0;
mem_to_reg <= 0;
reg_write <= 1;
mem_write <= 0;
// And
if (funct == 'b100100) begin
shift <= 0;
alu_control <= 'b0000;
end
// Or
else if (funct == 'b100101) begin
shift <= 0;
alu_control <= 'b0001;
end
// Add
else if (funct == 'b100000) begin
shift <= 0;
alu_control <= 'b0010;
end
// Subtract
else if (funct == 'b100010) begin
shift <= 0;
alu_control <= 'b0110;
end
// SLT
else if (funct == 'b101010) begin
shift <= 0;
alu_control <= 'b0111;
end
// Xor
else if (funct == 'b100110) begin
shift <= 0;
alu_control <= 'b1101;
end
// SLL (and nop)
else if (funct == 'b000000) begin
shift <= 1;
alu_control <= 'b0100;
end
// SRL
else if (funct == 'b000010) begin
shift <= 1;
alu_control <= 'b0101;
end
// SRA
else if (funct == 'b000011) begin
shift <= 1;
alu_control <= 'b1101;
end
// JR
else if (funct == 'b001000) begin
reg_write <= 0;
shift <= 0;
alu_control <= 'b1111;
end
// Ignore this, done to avoid latch
else begin
shift <= 0;
alu_control <= 'b0000;
end
end
// -------------------------------------------------------
// I-Type
// lui
else if (op == 'b001111) begin
use_rt_for_dest <= 1;
use_imm_for_alu_src <= 1;
jal <= 0;
shift <= 0;
mem_to_reg <= 0;
reg_write <= 1;
mem_write <= 0;
alu_control <= 'b0011;
end
// ori
else if (op == 'b001101) begin
use_rt_for_dest <= 1;
use_imm_for_alu_src <= 1;
jal <= 0;
shift <= 0;
mem_to_reg <= 0;
reg_write <= 1;
mem_write <= 0;
alu_control <= 'b0001;
end
// andi
else if (op == 'b001100) begin
use_rt_for_dest <= 1;
use_imm_for_alu_src <= 1;
jal <= 0;
shift <= 0;
mem_to_reg <= 0;
reg_write <= 1;
mem_write <= 0;
alu_control <= 'b0000;
end
// addi
else if (op == 'b001000) begin
use_rt_for_dest <= 1;
use_imm_for_alu_src <= 1;
jal <= 0;
shift <= 0;
mem_to_reg <= 0;
reg_write <= 1;
mem_write <= 0;
alu_control <= 'b0010;
end
// xori
else if (op == 'b001110) begin
use_rt_for_dest <= 1;
use_imm_for_alu_src <= 1;
jal <= 0;
shift <= 0;
mem_to_reg <= 0;
reg_write <= 1;
mem_write <= 0;
alu_control <= 'b1101;
end
// Data Access
// lw
else if (op == 'b100011) begin
use_rt_for_dest <= 1;
use_imm_for_alu_src <= 1;
jal <= 0;
shift <= 0;
mem_to_reg <= 1;
reg_write <= 1;
mem_write <= 0;
alu_control <= 'b0010;
end
// sw
else if (op == 'b101011) begin
use_rt_for_dest <= 1;
use_imm_for_alu_src <= 1;
jal <= 0;
shift <= 0;
mem_to_reg <= 0;
reg_write <= 0;
mem_write <= 1;
alu_control <= 'b0010;
end
// -------------------------------------------------------
// Branching
// beq
else if (op == 'b000100) begin
use_rt_for_dest <= 0; // doesnt matter
use_imm_for_alu_src <= 0; // doesnt matter
jal <= 0;
shift <= 0;
mem_to_reg <= 0;
reg_write <= 0;
mem_write <= 0;
alu_control <= 'b1111;
end
// bne
else if (op == 'b000101) begin
use_rt_for_dest <= 1; // doesnt matter
use_imm_for_alu_src <= 0; // doesnt matter
jal <= 0;
shift <= 0;
mem_to_reg <= 0;
reg_write <= 0;
mem_write <= 0;
alu_control <= 'b1111;
end
// -------------------------------------------------------
// Jumping
// j
else if (op == 'b000010) begin
use_rt_for_dest <= 0; // doesnt matter
use_imm_for_alu_src <= 0; // doesnt matter
jal <= 0;
shift <= 0;
mem_to_reg <= 0;
reg_write <= 0;
mem_write <= 0;
alu_control <= 'b1111;
end
// jal
else if (op == 'b000011) begin
use_rt_for_dest <= 0; // doesnt matter
use_imm_for_alu_src <= 0; // doesnt matter
jal <= 1;
shift <= 0;
mem_to_reg <= 0;
reg_write <= 1;
mem_write <= 0;
alu_control <= 'b1111;
end
// -------------------------------------------------------
// Ignore this, done to avoid latch
else begin
use_rt_for_dest <= 1;
use_imm_for_alu_src <= 0;
jal <= 0;
shift <= 0;
mem_to_reg <= 0;
reg_write <= 0;
mem_write <= 0;
alu_control <= 'b1111;
end
if (op == 'b000000 && funct == 'b001000) begin
// jr
pc_selector <= 'b10;
end
else if ((op == 'b000100 && preinputs_equal) || (op == 'b000101 && ~preinputs_equal)) begin
// branch
pc_selector <= 'b01;
end
else if (op == 'b000010 || op == 'b000011) begin
// jump
pc_selector <= 'b11;
end
else begin
// regular advance
pc_selector <= 'b00;
end
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment