aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlavian Kaufmann <flavian@flaviankaufmann.ch>2024-05-13 18:33:28 +0200
committerFlavian Kaufmann <flavian@flaviankaufmann.ch>2024-05-13 18:33:28 +0200
commit59bc2fc1f75dbda7f8c36409bcf3f5198bfc3eaa (patch)
tree85092182470cece8cbbf446d15cc513900ab6c5b
parent9c7d7fd782f70d99120ce6ac45a897606b52c878 (diff)
downloadriscv_cpu-59bc2fc1f75dbda7f8c36409bcf3f5198bfc3eaa.tar.gz
riscv_cpu-59bc2fc1f75dbda7f8c36409bcf3f5198bfc3eaa.zip
refactored fsm output logic
-rw-r--r--include/consts.vh13
-rw-r--r--src/control_unit.v305
-rw-r--r--src/immediate_extend.v13
3 files changed, 122 insertions, 209 deletions
diff --git a/include/consts.vh b/include/consts.vh
index 49133a7..8c31c7d 100644
--- a/include/consts.vh
+++ b/include/consts.vh
@@ -105,4 +105,15 @@ parameter FUNCT7_ALU_SRL = 7'b0000000;
parameter FUNCT7_ALU_SRA = 7'b0100000;
parameter ALU_CTRL_OP = 1'b0;
-parameter ALU_CTRL_ADD = 1'b1; \ No newline at end of file
+parameter ALU_CTRL_ADD = 1'b1;
+
+parameter MEM_WE_ENABLE = 1'b1;
+parameter MEM_WE_DISABLE = 1'b0;
+parameter RF_WE_ENABLE = 1'b1;
+parameter RF_WE_DISABLE = 1'b0;
+parameter INSTR_WE_ENABLE = 1'b1;
+parameter INSTR_WE_DISABLE = 1'b0;
+parameter PC_UPDATE_ENABLE = 1'b1;
+parameter PC_UPDATE_DISABLE = 1'b0;
+parameter BRANCH_ENABLE = 1'b1;
+parameter BRANCH_DISABLE = 1'b0; \ No newline at end of file
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
diff --git a/src/immediate_extend.v b/src/immediate_extend.v
index 404c43d..6e39e7d 100644
--- a/src/immediate_extend.v
+++ b/src/immediate_extend.v
@@ -5,15 +5,16 @@ module immediate_extend (
output reg [31:0] imm
);
+`include "include/consts.vh"
always @ (*) begin
case (imm_src)
- 3'b010: imm <= { {21{instr[31]}}, instr[30:20] }; // I
- 3'b011: imm <= { {21{instr[31]}}, instr[30:25], instr[11:7] }; // S
- 3'b100: imm <= { {20{instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0 }; // B
- 3'b101: imm <= { instr[31:12], 12'b0 }; // U
- 3'b110: imm <= { {12{instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0 }; // J
- default: imm <= 32'b0; // Unknown
+ INSTR_FORMAT_I: imm <= { {21{instr[31]}}, instr[30:20] }; // I
+ INSTR_FORMAT_S: imm <= { {21{instr[31]}}, instr[30:25], instr[11:7] }; // S
+ INSTR_FORMAT_B: imm <= { {20{instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0 }; // B
+ INSTR_FORMAT_U: imm <= { instr[31:12], 12'b0 }; // U
+ INSTR_FORMAT_J: imm <= { {12{instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0 }; // J
+ default: imm <= 32'b0; // Unknown
endcase
end