`timescale 1ns / 1ps module ControlUnit( input wire [3:0] instIn, input wire functBit, output reg [3:0] aluOut, output reg [2:0] FU, output reg addi, output reg mem, output reg RegEn, output reg halt); always @(instIn, functBit)begin case(instIn) 4'b0101: if(functBit == 1) begin aluOut <= 4'b0001; //sub RegEn <= 1'b0; FU <= 3'b001; halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; end else begin aluOut <= 4'b0000; //Add RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; end 4'b1101: begin aluOut <= 4'b0011; //nor RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; end 4'b1110: if(functBit == 1) begin aluOut <= 4'b0100; //and RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; end else begin aluOut <= 4'b0010; //or RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; end 4'b1111: if(functBit == 1) begin aluOut <= 4'b0110; //srl RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; end else begin aluOut <= 4'b0101; //shift left RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; end 4'b0111: begin aluOut <= 4'b1001; //Less than RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; end 4'b0110: begin aluOut <= 4'b0000; addi <= 1'b1; // addi RegEn <= 1'b1; FU <= 3'b001; // Disable Branching halt <= 1'b0; mem <= 1'b0; end 4'b1001: begin //We got it wrong, first bit must always be zero whenever branching happens. Fixed aluOut <= 4'b0000; FU <= 3'b010; // jump RegEn <= 1'b1; halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; end 4'b1010: begin aluOut <= 4'b0000; FU <= 3'b110; // branch RegEn <= 1'b1; halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; end 4'b1000: begin aluOut <= 4'b0000; FU <= 3'b000; // jumpreg RegEn <= 1'b1; halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; end 4'b0001: begin aluOut <= 4'b0000; mem <= 1'b1; // load RegEn <= 1'b0; FU <= 3'b001; // Disable Branching addi <= 1'b0; halt <= 1'b0; end 4'b0010: begin aluOut <= 4'b0000; mem <= 1'b0; // store RegEn <= 1'b1; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; end 4'b0000: begin // regs should initialize at 0, so we shouldn't need to declare it everywhere halt <= 1'b1; // halt RegEn <= 1'b1; FU <= 3'b001; // Disable Branching addi <= 1'b0; aluOut <= 4'b0000; mem <= 1'b0; end default: begin halt <= 1'b1; RegEn <= 1'b1; FU <= 3'b001; addi <= 1'b0; aluOut <= 4'b0000; mem <= 1'b0; end endcase end endmodule module ControlUnit_tb(); reg [3:0] instruction; reg functionB; wire [3:0] aluOutput; wire [2:0] FetchUnit; wire addImmediate; wire memory; wire RegEnable; ControlUnit ControlUnit0( .instIn(instruction), .functBit(functionB), .aluOut(aluOutput), .FU(FetchUnit), .addi(addImmediate), .mem(memory), .RegEn(RegEnable) ); initial begin functionB = 1'b0; instruction = 4'b0101; #5 functionB = 1'b1; #5 functionB = 1'b0; instruction = 4'b1110; #5 functionB = 1'b1; #5 functionB = 1'b0; instruction = 4'b1111; #5 functionB = 1'b1; #5 instruction = 4'b0111; #5 instruction = 4'b0110; #5 instruction = 4'b1001; #5 instruction = 4'b1100; #5 instruction = 4'b1000; #5 instruction = 4'b0001; #5 instruction = 4'b0010; #5 $finish; end endmodule