import cpu_types::*; module control_unit( input [31:0] instruction, output memory_mask_t memory_mask, output memory_sign_extension, // whether to save alu to memory output memory_we, // going to pc (pc+4/imm, alu) output pc_source_t pc_src, // if alu output zero(negated if zero_negate), jump (pc source pc + imm instead od pc + 4) output jump_instruction, output jump_negate_zero, output [31:0] immediate, // register file or pc output alu_1_source_t alu_src_1, // register file or immediate output alu_2_source_t alu_src_2, // going to alu output [2:0] alu_op, output alu_signed, output alu_negate, output alu_add_one, // going to register file output [4:0] reg_rs1, output [4:0] reg_rs2, // alu or memory output reg_rd_source_t reg_rd_src, output [4:0] reg_rd, output reg_we, output ebreak ); wire use_immediate; wire load_immediate; wire load_memory; wire load_pc, store_pc; wire conditional_jump, unconditional_jump; wire [2:0] alu_reg_op, alu_jump_op; wire alu_reg_add_one, alu_reg_negate, alu_reg_signed; wire alu_jump_add_one, alu_jump_negate; wire alu_override; assign jump_instruction = conditional_jump; instruction_decoder decoder( .instruction(instruction), .ebreak(ebreak), .store_memory(memory_we), .load_memory(load_memory), .memory_mask(memory_mask), .memory_sign_extension(memory_sign_extension), .load_pc(load_pc), .store_pc(store_pc), .alu_reg_op(alu_reg_op), .alu_reg_add_one(alu_reg_add_one), .alu_reg_negate(alu_reg_negate), .alu_reg_signed(alu_reg_signed), .alu_jump_op(alu_jump_op), .alu_jump_add_one(alu_jump_add_one), .alu_jump_negate(alu_jump_negate), .jump_negate_zero(jump_negate_zero), .conditional_jump(conditional_jump), .unconditional_jump(unconditional_jump), .immediate(immediate), .use_immediate(use_immediate), .load_immediate(load_immediate), .reg_rs1(reg_rs1), .reg_rs2(reg_rs2), .reg_rd(reg_rd), .reg_we(reg_we) ); // in these cases, alu is used just for addition, nothing else, // so use neither alu_jump, neither alu_reg, use zeros assign alu_override = load_memory || memory_we || load_pc || unconditional_jump || load_immediate; assign alu_op = conditional_jump ? alu_jump_op : alu_override ? 3'b000 : alu_reg_op; assign alu_add_one = conditional_jump ? alu_jump_add_one : alu_override ? 0'b0 : alu_reg_add_one; assign alu_negate = conditional_jump ? alu_jump_negate : alu_override ? 0'b0 : alu_reg_negate; assign alu_signed = conditional_jump ? 0'b0 : alu_override ? 0'b0 : alu_reg_signed; assign pc_src = unconditional_jump ? PC_ALU : PC_PLUS; assign alu_src_1 = load_pc ? PC : REG_FILE_RS1; assign reg_rd_src = store_pc ? RD_PC_PLUS : (load_memory ? RD_MEMORY : RD_ALU); assign alu_src_2 = use_immediate ? IMMEDIATE : REG_FILE_RS2; endmodule