diff options
Diffstat (limited to 'src/control_unit.v')
-rw-r--r-- | src/control_unit.v | 305 |
1 files changed, 103 insertions, 202 deletions
diff --git a/src/control_unit.v b/src/control_unit.v index 494737e..9a5b413 100644 --- a/src/control_unit.v +++ b/src/control_unit.v @@ -23,27 +23,7 @@ module control_unit ( output reg [1:0] result_src ); -parameter s00_fetch = 4'h0, - s01_decode = 4'h1, - s02_mem_addr = 4'h2, - s03_mem_read = 4'h3, - s04_mem_wb = 4'h4, - s05_mem_write = 4'h5, - s06_execute_r = 4'h6, - s07_alu_wb = 4'h7, - s08_execute_i = 4'h8, - s09_jal = 4'h9, - s10_jalr = 4'ha, - s11_br = 4'hb; - - -parameter INSTRUCTION_FORMAT_UNKNOWN = 3'b000, - INSTRUCTION_FORMAT_R = 3'b001, - INSTRUCTION_FORMAT_I = 3'b010, - INSTRUCTION_FORMAT_S = 3'b011, - INSTRUCTION_FORMAT_B = 3'b100, - INSTRUCTION_FORMAT_U = 3'b101, - INSTRUCTION_FORMAT_J = 3'b110; +`include "include/consts.vh" wire [6:0] opcode; wire [2:0] funct3; @@ -60,56 +40,56 @@ assign wa3 = instr[11:7]; always @ (*) begin case (opcode) - 7'b0110011: imm_src <= INSTRUCTION_FORMAT_R; // ADD, SUB, SLL, SLT, SLTU, XOR, SRL, SRA, OR, AND - 7'b0010011: imm_src <= INSTRUCTION_FORMAT_I; // ADDI, SLTI, SLTIU, XORI, ORI, ANDI, SLLI, SRLI, SRAI - 7'b0000011: imm_src <= INSTRUCTION_FORMAT_I; // LB, LH, LW, LBU, LHU - 7'b1100111: imm_src <= INSTRUCTION_FORMAT_I; // JALR - 7'b0100011: imm_src <= INSTRUCTION_FORMAT_S; // SB, SH, SW - 7'b1100011: imm_src <= INSTRUCTION_FORMAT_B; // BEQ, BNE, BLT, BGE, BLTU, BGEU - 7'b0110111: imm_src <= INSTRUCTION_FORMAT_U; // LUI - 7'b0010111: imm_src <= INSTRUCTION_FORMAT_U; // AUIPC - 7'b1101111: imm_src <= INSTRUCTION_FORMAT_J; // JAL - 7'b0001111: imm_src <= INSTRUCTION_FORMAT_I; // FENCE, FENCE.I - 7'b1110011: imm_src <= INSTRUCTION_FORMAT_I; // ECALL, EBREAK, CSRRW, CSRRS, CSRRC, CSRRWI, CSRRSI, CSRRCI - default: imm_src <= INSTRUCTION_FORMAT_UNKNOWN; + OPCODE_REG: imm_src <= INSTR_FORMAT_R; // ADD, SUB, SLL, SLT, SLTU, XOR, SRL, SRA, OR, AND + OPCODE_IMM: imm_src <= INSTR_FORMAT_I; // ADDI, SLTI, SLTIU, XORI, ORI, ANDI, SLLI, SRLI, SRAI + OPCODE_LOAD: imm_src <= INSTR_FORMAT_I; // LB, LH, LW, LBU, LHU + OPCODE_JALR: imm_src <= INSTR_FORMAT_I; // JALR + OPCODE_STORE: imm_src <= INSTR_FORMAT_S; // SB, SH, SW + OPCODE_BRANCH: imm_src <= INSTR_FORMAT_B; // BEQ, BNE, BLT, BGE, BLTU, BGEU + OPCODE_LUI: imm_src <= INSTR_FORMAT_U; // LUI + OPCODE_AUIPC: imm_src <= INSTR_FORMAT_U; // AUIPC + OPCODE_JAL: imm_src <= INSTR_FORMAT_J; // JAL + OPCODE_SYNC: imm_src <= INSTR_FORMAT_I; // FENCE + OPCODE_SYS: imm_src <= INSTR_FORMAT_I; // ECALL, EBREAK + default: imm_src <= INSTR_FORMAT_UNKNOWN; endcase end reg [3:0] state, next_state; always @ (posedge clk or negedge rstn) begin - if (!rstn) state <= s00_fetch; + if (!rstn) state <= STATE_FETCH; else state <= next_state; end always @ (*) begin case(state) - s00_fetch: next_state <= s01_decode; - s01_decode: case(opcode) - 7'b0000011: next_state <= s02_mem_addr; - 7'b0100011: next_state <= s02_mem_addr; - 7'b0110011: next_state <= s06_execute_r; - 7'b0010011: next_state <= s08_execute_i; - 7'b1101111: next_state <= s09_jal; - 7'b1100111: next_state <= s10_jalr; - 7'b1100011: next_state <= s11_br; - default: next_state <= s00_fetch; + STATE_FETCH: next_state <= STATE_DECODE; + STATE_DECODE: case(opcode) + OPCODE_LOAD: next_state <= STATE_MEM_ADDR; + OPCODE_STORE: next_state <= STATE_MEM_ADDR; + OPCODE_REG: next_state <= STATE_EXECUTE_R; + OPCODE_IMM: next_state <= STATE_EXECUTE_I; + OPCODE_JAL: next_state <= STATE_JAL; + OPCODE_JALR: next_state <= STATE_JALR; + OPCODE_BRANCH: next_state <= STATE_BRANCH; + default: next_state <= STATE_FETCH; endcase - s02_mem_addr: case(opcode) - 7'b0000011: next_state <= s03_mem_read; - 7'b0100011: next_state <= s05_mem_write; - default: next_state <= s00_fetch; + STATE_MEM_ADDR: case(opcode) + OPCODE_LOAD: next_state <= STATE_MEM_LOAD; + OPCODE_STORE: next_state <= STATE_MEM_STORE; + default: next_state <= STATE_FETCH; endcase - s03_mem_read: next_state <= s04_mem_wb; - s04_mem_wb: next_state <= s00_fetch; - s05_mem_write: next_state <= s00_fetch; - s06_execute_r: next_state <= s07_alu_wb; - s07_alu_wb: next_state <= s00_fetch; - s08_execute_i: next_state <= s07_alu_wb; - s09_jal: next_state <= s07_alu_wb; - s10_jalr: next_state <= s07_alu_wb; - s11_br: next_state <= s00_fetch; - default: next_state <= s00_fetch; + STATE_MEM_LOAD: next_state <= STATE_MEM_WB; + STATE_MEM_WB: next_state <= STATE_FETCH; + STATE_MEM_STORE: next_state <= STATE_FETCH; + STATE_EXECUTE_R: next_state <= STATE_ALU_WB; + STATE_ALU_WB: next_state <= STATE_FETCH; + STATE_EXECUTE_I: next_state <= STATE_ALU_WB; + STATE_JAL: next_state <= STATE_ALU_WB; + STATE_JALR: next_state <= STATE_ALU_WB; + STATE_BRANCH: next_state <= STATE_FETCH; + default: next_state <= STATE_FETCH; endcase end @@ -120,162 +100,83 @@ reg alu_ctrl; assign pc_we = ((alu_zero ^ funct3[0] ^ funct3[2]) & branch) | pc_update; always @ (*) begin + mem_addr_src = MEM_ADDR_SRC_RESULT; + alu_a_src = ALU_A_SRC_RD1_BUF; + alu_b_src = ALU_B_SRC_RD2_BUF; + alu_ctrl = ALU_CTRL_OP; + result_src = RESULT_SRC_ALU_RESULT; + mem_we = MEM_WE_DISABLE; + rf_we = RF_WE_DISABLE; + instr_we = INSTR_WE_DISABLE; + pc_update = PC_UPDATE_DISABLE; + branch = BRANCH_DISABLE; case(state) - s00_fetch: begin - mem_addr_src <= 1'b0; - alu_a_src <= 2'b00; - alu_b_src <= 2'b10; - alu_ctrl <= 1'b1; - result_src <= 2'b10; - mem_we <= 1'b0; - rf_we <= 1'b0; - instr_we <= 1'b1; - pc_update <= 1'b1; - branch <= 1'b0; - end - s01_decode: begin - mem_addr_src <= 1'b0; - alu_a_src <= 2'b01; - alu_b_src <= 2'b01; - alu_ctrl <= 1'b1; - result_src <= 2'b00; - mem_we <= 1'b0; - rf_we <= 1'b0; - instr_we <= 1'b0; - pc_update <= 1'b0; - branch <= 1'b0; + STATE_FETCH: begin + mem_addr_src = MEM_ADDR_SRC_PC; + alu_a_src = ALU_A_SRC_PC; + alu_b_src = ALU_B_SRC_4; + alu_ctrl = ALU_CTRL_ADD; + result_src = RESULT_SRC_ALU_RESULT; + instr_we = INSTR_WE_ENABLE; + pc_update = PC_UPDATE_ENABLE; end - s02_mem_addr: begin - mem_addr_src <= 1'b0; - alu_a_src <= 2'b10; - alu_b_src <= 2'b01; - alu_ctrl <= 1'b1; - result_src <= 2'b00; - mem_we <= 1'b0; - rf_we <= 1'b0; - instr_we <= 1'b0; - pc_update <= 1'b0; - branch <= 1'b0; + STATE_DECODE: begin + alu_a_src = ALU_A_SRC_PC_BUF; + alu_b_src = ALU_B_SRC_IMM; + alu_ctrl = ALU_CTRL_ADD; end - s03_mem_read: begin - mem_addr_src <= 1'b1; - alu_a_src <= 2'b00; - alu_b_src <= 2'b00; - alu_ctrl <= 1'b0; - result_src <= 2'b00; - mem_we <= 1'b0; - rf_we <= 1'b0; - instr_we <= 1'b0; - pc_update <= 1'b0; - branch <= 1'b0; + STATE_MEM_ADDR: begin + alu_a_src = ALU_A_SRC_RD1_BUF; + alu_b_src = ALU_B_SRC_IMM; + alu_ctrl = ALU_CTRL_ADD; end - s04_mem_wb: begin - mem_addr_src <= 1'b0; - alu_a_src <= 2'b00; - alu_b_src <= 2'b00; - alu_ctrl <= 1'b0; - result_src <= 2'b01; - mem_we <= 1'b0; - rf_we <= 1'b1; - instr_we <= 1'b0; - pc_update <= 1'b0; - branch <= 1'b0; + STATE_MEM_LOAD: begin + mem_addr_src = MEM_ADDR_SRC_RESULT; + result_src = RESULT_SRC_ALU_RESULT_BUF; end - s05_mem_write: begin - mem_addr_src <= 1'b1; - alu_a_src <= 2'b00; - alu_b_src <= 2'b00; - alu_ctrl <= 1'b0; - result_src <= 2'b00; - mem_we <= 1'b1; - rf_we <= 1'b0; - instr_we <= 1'b0; - pc_update <= 1'b0; - branch <= 1'b0; + STATE_MEM_WB: begin + result_src = RESULT_SRC_DATA_BUF; + rf_we = RF_WE_ENABLE; end - s06_execute_r: begin - mem_addr_src <= 1'b0; - alu_a_src <= 2'b10; - alu_b_src <= 2'b00; - alu_ctrl <= 1'b0; - result_src <= 2'b00; - mem_we <= 1'b0; - rf_we <= 1'b0; - instr_we <= 1'b0; - pc_update <= 1'b0; - branch <= 1'b0; + STATE_MEM_STORE: begin + mem_addr_src = MEM_ADDR_SRC_RESULT; + result_src = RESULT_SRC_ALU_RESULT_BUF; + mem_we = MEM_WE_ENABLE; end - s07_alu_wb: begin - mem_addr_src <= 1'b0; - alu_a_src <= 2'b00; - alu_b_src <= 2'b00; - alu_ctrl <= 1'b0; - result_src <= 2'b00; - mem_we <= 1'b0; - rf_we <= 1'b1; - instr_we <= 1'b0; - pc_update <= 1'b0; - branch <= 1'b0; + STATE_EXECUTE_R: begin + alu_a_src = ALU_A_SRC_RD1_BUF; + alu_b_src = ALU_B_SRC_RD2_BUF; + alu_ctrl = ALU_CTRL_OP; end - s08_execute_i: begin - mem_addr_src <= 1'b0; - alu_a_src <= 2'b10; - alu_b_src <= 2'b01; - alu_ctrl <= 1'b0; - result_src <= 2'b00; - mem_we <= 1'b0; - rf_we <= 1'b0; - instr_we <= 1'b0; - pc_update <= 1'b0; - branch <= 1'b0; + STATE_ALU_WB: begin + result_src = RESULT_SRC_ALU_RESULT_BUF; + rf_we = RF_WE_ENABLE; end - s09_jal: begin - mem_addr_src <= 1'b0; - alu_a_src <= 2'b01; - alu_b_src <= 2'b10; - alu_ctrl <= 1'b1; - result_src <= 2'b00; - mem_we <= 1'b0; - rf_we <= 1'b0; - instr_we <= 1'b0; - pc_update <= 1'b1; - branch <= 1'b0; + STATE_EXECUTE_I: begin + alu_a_src = ALU_A_SRC_RD1_BUF; + alu_b_src = ALU_B_SRC_IMM; + alu_ctrl = ALU_CTRL_OP; end - s10_jalr: begin - mem_addr_src <= 1'b0; - alu_a_src <= 2'b10; - alu_b_src <= 2'b01; - alu_ctrl <= 1'b1; - result_src <= 2'b10; - mem_we <= 1'b0; - rf_we <= 1'b0; - instr_we <= 1'b0; - pc_update <= 1'b1; - branch <= 1'b0; + STATE_JAL: begin + alu_a_src = ALU_A_SRC_PC_BUF; + alu_b_src = ALU_B_SRC_4; + alu_ctrl = ALU_CTRL_ADD; + result_src = RESULT_SRC_ALU_RESULT_BUF; + pc_update = PC_UPDATE_ENABLE; end - s11_br: begin - mem_addr_src <= 1'b0; - alu_a_src <= 2'b10; - alu_b_src <= 2'b00; - alu_ctrl <= 1'b0; - result_src <= 2'b00; - mem_we <= 1'b0; - rf_we <= 1'b0; - instr_we <= 1'b0; - pc_update <= 1'b0; - branch <= 1'b1; + STATE_JALR: begin + alu_a_src = ALU_A_SRC_RD1_BUF; + alu_b_src = ALU_B_SRC_IMM; + alu_ctrl = ALU_CTRL_ADD; + result_src = RESULT_SRC_ALU_RESULT; + pc_update = PC_UPDATE_ENABLE; end - default: begin - mem_addr_src <= 1'b0; - alu_a_src <= 2'b00; - alu_b_src <= 2'b00; - alu_ctrl <= 1'b0; - result_src <= 2'b00; - mem_we <= 1'b0; - rf_we <= 1'b0; - instr_we <= 1'b0; - pc_update <= 1'b0; - branch <= 1'b0; + STATE_BRANCH: begin + alu_a_src = ALU_A_SRC_RD1_BUF; + alu_b_src = ALU_B_SRC_RD2_BUF; + alu_ctrl = ALU_CTRL_OP; + result_src = RESULT_SRC_ALU_RESULT_BUF; + branch = BRANCH_ENABLE; end endcase end |