diff options
author | Flavian Kaufmann <flavian@flaviankaufmann.ch> | 2024-05-13 18:33:28 +0200 |
---|---|---|
committer | Flavian Kaufmann <flavian@flaviankaufmann.ch> | 2024-05-13 18:33:28 +0200 |
commit | 59bc2fc1f75dbda7f8c36409bcf3f5198bfc3eaa (patch) | |
tree | 85092182470cece8cbbf446d15cc513900ab6c5b | |
parent | 9c7d7fd782f70d99120ce6ac45a897606b52c878 (diff) | |
download | riscv_cpu-59bc2fc1f75dbda7f8c36409bcf3f5198bfc3eaa.tar.gz riscv_cpu-59bc2fc1f75dbda7f8c36409bcf3f5198bfc3eaa.zip |
refactored fsm output logic
-rw-r--r-- | include/consts.vh | 13 | ||||
-rw-r--r-- | src/control_unit.v | 305 | ||||
-rw-r--r-- | src/immediate_extend.v | 13 |
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 |