aboutsummaryrefslogtreecommitdiff
path: root/src/control_unit.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/control_unit.v')
-rw-r--r--src/control_unit.v122
1 files changed, 70 insertions, 52 deletions
diff --git a/src/control_unit.v b/src/control_unit.v
index 9a5b413..dfed9cc 100644
--- a/src/control_unit.v
+++ b/src/control_unit.v
@@ -16,7 +16,7 @@ module control_unit (
output reg rf_we,
output [4:0] ra1, ra2, wa3,
- output reg [1:0] alu_a_src,
+ output reg [2:0] alu_a_src,
output reg [1:0] alu_b_src,
output [3:0] alu_op,
@@ -29,6 +29,10 @@ wire [6:0] opcode;
wire [2:0] funct3;
wire [6:0] funct7;
+reg branch;
+reg pc_update;
+reg alu_ctrl;
+
assign opcode = instr[6:0];
assign funct3 = instr[14:12];
assign funct7 = instr[31:25];
@@ -37,26 +41,35 @@ assign ra1 = instr[19:15];
assign ra2 = instr[24:20];
assign wa3 = instr[11:7];
+assign pc_we = ((alu_zero ^ funct3[0] ^ funct3[2]) & branch) | pc_update;
+
+reg [3:0] state, next_state;
+
+alu_op_decode alu_op_decode (
+ .opcode(opcode),
+ .alu_ctrl(alu_ctrl),
+ .funct3(funct3),
+ .funct7(funct7),
+ .alu_op(alu_op)
+);
always @ (*) begin
case (opcode)
- 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;
+ 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 <= STATE_FETCH;
else state <= next_state;
@@ -64,40 +77,40 @@ end
always @ (*) begin
case(state)
- STATE_FETCH: next_state <= STATE_DECODE;
+ 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;
+ 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_LUI: next_state = STATE_LUI;
+ OPCODE_AUIPC: next_state = STATE_AUIPC;
+ OPCODE_BRANCH: next_state = STATE_BRANCH;
+ default: next_state = STATE_FETCH;
endcase
STATE_MEM_ADDR: case(opcode)
- OPCODE_LOAD: next_state <= STATE_MEM_LOAD;
- OPCODE_STORE: next_state <= STATE_MEM_STORE;
- default: next_state <= STATE_FETCH;
+ OPCODE_LOAD: next_state = STATE_MEM_LOAD;
+ OPCODE_STORE: next_state = STATE_MEM_STORE;
+ default: next_state = STATE_FETCH;
endcase
- 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;
+ 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_LUI: next_state = STATE_ALU_WB;
+ STATE_AUIPC: next_state = STATE_FETCH;
+ STATE_BRANCH: next_state = STATE_FETCH;
+ default: next_state = STATE_FETCH;
endcase
end
-reg branch;
-reg pc_update;
-reg alu_ctrl;
-assign pc_we = ((alu_zero ^ funct3[0] ^ funct3[2]) & branch) | pc_update;
always @ (*) begin
mem_addr_src = MEM_ADDR_SRC_RESULT;
@@ -121,7 +134,7 @@ always @ (*) begin
pc_update = PC_UPDATE_ENABLE;
end
STATE_DECODE: begin
- alu_a_src = ALU_A_SRC_PC_BUF;
+ alu_a_src = (opcode == OPCODE_JALR) ? ALU_A_SRC_RD1 : ALU_A_SRC_PC_BUF;
alu_b_src = ALU_B_SRC_IMM;
alu_ctrl = ALU_CTRL_ADD;
end
@@ -165,11 +178,24 @@ always @ (*) begin
pc_update = PC_UPDATE_ENABLE;
end
STATE_JALR: begin
- alu_a_src = ALU_A_SRC_RD1_BUF;
+ 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
+ STATE_LUI: begin
+ alu_a_src = ALU_A_SRC_0;
alu_b_src = ALU_B_SRC_IMM;
alu_ctrl = ALU_CTRL_ADD;
- result_src = RESULT_SRC_ALU_RESULT;
+ end
+ STATE_AUIPC: begin
+ alu_a_src = ALU_A_SRC_PC_BUF;
+ alu_b_src = ALU_B_SRC_IMM;
+ alu_ctrl = ALU_CTRL_ADD;
+ result_src = RESULT_SRC_ALU_RESULT_BUF;
pc_update = PC_UPDATE_ENABLE;
+
end
STATE_BRANCH: begin
alu_a_src = ALU_A_SRC_RD1_BUF;
@@ -181,12 +207,4 @@ always @ (*) begin
endcase
end
-alu_op_decode alu_op_decode (
- .opcode(opcode),
- .alu_ctrl(alu_ctrl),
- .funct3(funct3),
- .funct7(funct7),
- .alu_op(alu_op)
-);
-
endmodule