module controller( input clk, input[3:0] instr, output reg[11:0] ctrl_word); localparam SIG_HLT = 11; localparam SIG_PC_INC = 10; localparam SIG_PC_EN = 9; localparam SIG_MEM_LOAD = 8; localparam SIG_MEM_EN = 7; localparam SIG_IR_LOAD = 6; localparam SIG_IR_EN = 5; localparam SIG_A_LOAD = 4; localparam SIG_A_EN = 3; localparam SIG_B_LOAD = 2; localparam SIG_ADDER_SUB = 1; localparam SIG_ADDER_EN = 0; localparam OP_LDA = 4'b0000; localparam OP_ADD = 4'b0001; localparam OP_SUB = 4'b0010; localparam OP_HLT = 4'b1111; reg[2:0] stage = 0; always @(negedge clk) begin if (stage == 6) begin stage <= 1; end else begin stage <= stage + 1; end end always @(*) begin case (stage) 1: begin ctrl_word = 12'b0; ctrl_word[SIG_PC_EN] = 1; ctrl_word[SIG_MEM_LOAD] = 1; end 2: begin ctrl_word = 12'b0; ctrl_word[SIG_PC_INC] = 1; end 3: begin ctrl_word = 12'b0; ctrl_word[SIG_MEM_EN] = 1; ctrl_word[SIG_IR_LOAD] = 1; end 4: begin case (instr) OP_LDA: begin ctrl_word = 12'b0; ctrl_word[SIG_IR_EN] = 1; ctrl_word[SIG_MEM_LOAD] = 1; end OP_ADD: begin ctrl_word = 12'b0; ctrl_word[SIG_IR_EN] = 1; ctrl_word[SIG_MEM_LOAD] = 1; end OP_SUB: begin ctrl_word = 12'b0; ctrl_word[SIG_IR_EN] = 1; ctrl_word[SIG_MEM_LOAD] = 1; end OP_HLT: begin ctrl_word = 12'b0; ctrl_word[SIG_HLT] = 1; end default: begin ctrl_word = 12'b0; end endcase end 5: begin case (instr) OP_LDA: begin ctrl_word = 12'b0; ctrl_word[SIG_MEM_EN] = 1; ctrl_word[SIG_A_LOAD] = 1; end OP_ADD: begin ctrl_word = 12'b0; ctrl_word[SIG_MEM_EN] = 1; ctrl_word[SIG_B_LOAD] = 1; end OP_SUB: begin ctrl_word = 12'b0; ctrl_word[SIG_MEM_EN] = 1; ctrl_word[SIG_B_LOAD] = 1; end default: begin ctrl_word = 12'b0; end endcase end 6: begin case (instr) OP_ADD: begin ctrl_word = 12'b0; ctrl_word[SIG_ADDER_EN] = 1; ctrl_word[SIG_A_LOAD] = 1; end OP_SUB: begin ctrl_word = 12'b0; ctrl_word[SIG_ADDER_SUB] = 1; ctrl_word[SIG_ADDER_EN] = 1; ctrl_word[SIG_A_LOAD] = 1; end default: begin ctrl_word = 12'b0; end endcase end default: begin ctrl_word = 12'b0; end endcase end endmodule