`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, dataMemEn, output reg RegEn, output reg halt, output reg link, output reg [1:0] bank, output reg js); 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; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 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; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 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; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b0100: begin aluOut <= 4'b1011; //zero RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 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; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 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; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 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; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 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; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 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; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b0110: begin aluOut <= 4'b1010; addi <= 1'b1; // addi RegEn <= 1'b0; FU <= 3'b001; // Disable Branching halt <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b1001: begin aluOut <= 4'b0000; FU <= 3'b010; // jf RegEn <= 1'b1; halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b1011: begin aluOut <= 4'b0000; FU <= 3'b010; // jb RegEn <= 1'b1; halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b1; end 4'b0011: begin // link halt <= 1'b0; RegEn <= 1'b0; FU <= 3'b001; addi <= 1'b0; aluOut <= 4'b0000; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b1; bank <= 2'b10; js <= 1'b0; end 4'b1100: begin aluOut <= 4'b1010; FU <= 3'b110; // branch RegEn <= 1'b1; halt <= 1'b0; addi <= 1'b0; mem <= 1'b0; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 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; dataMemEn <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b0001: begin aluOut <= 4'b0000; mem <= 1'b1; // load dataMemEn <= 1'b0; RegEn <= 1'b0; FU <= 3'b001; // Disable Branching addi <= 1'b0; halt <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b0010: begin aluOut <= 4'b0000; mem <= 1'b0; // store dataMemEn <= 1'b1; RegEn <= 1'b1; FU <= 3'b001; // Disable Branching halt <= 1'b0; addi <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end 4'b1010: begin halt <= 1'b0; // bank RegEn <= !functBit; FU <= 3'b001; // Disable Branching addi <= 1'b0; aluOut <= 4'b0000; mem <= 1'b0; link <= 1'b0; bank <= {functBit,functBit}; js <= 1'b0; end 4'b0000: begin halt <= 1'b1; // halt RegEn <= 1'b1; FU <= 3'b001; // Disable Branching addi <= 1'b0; aluOut <= 4'b0000; mem <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 1'b0; end default: begin halt <= 1'b1; RegEn <= 1'b1; FU <= 3'b001; addi <= 1'b0; aluOut <= 4'b0000; mem <= 1'b0; link <= 1'b0; bank <= 2'b10; js <= 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