diff --git a/include/ariane_pkg.svh b/include/ariane_pkg.svh index 8e9297f06..91cd8a384 100644 --- a/include/ariane_pkg.svh +++ b/include/ariane_pkg.svh @@ -86,7 +86,8 @@ package ariane_pkg; logic [63:0] result; // for unfinished instructions this field also holds the immediate logic valid; // is the result valid logic use_imm; // should we use the immediate as operand b? - logic use_pc; // set if we need to use the PC as operand A, PC from exception + logic use_zimm; // use zimm as operand a + logic use_pc; // set if we need to use the PC as operand a, PC from exception exception ex; // exception has occurred logic is_compressed; // signals a compressed instructions, we need this information at the commit stage if // we want jump accordingly e.g.: +4, +2 diff --git a/src/commit_stage.sv b/src/commit_stage.sv index c3b6236c9..529f5e62a 100644 --- a/src/commit_stage.sv +++ b/src/commit_stage.sv @@ -50,6 +50,7 @@ module commit_stage ( assign waddr_a_o = commit_instr_i.rd; assign wdata_a_o = commit_instr_i.result; assign pc_o = commit_instr_i.pc; + // commit instruction // write register file always_comb begin : commit diff --git a/src/decoder.sv b/src/decoder.sv index 3dddef91e..f36736972 100644 --- a/src/decoder.sv +++ b/src/decoder.sv @@ -30,7 +30,7 @@ module decoder ( } imm_select; logic [63:0] imm_i_type; - logic [63:0] imm_iz_type; + logic [11:0] imm_iz_type; logic [63:0] imm_s_type; logic [63:0] imm_sb_type; logic [63:0] imm_u_type; @@ -44,26 +44,90 @@ module decoder ( always_comb begin : decoder - imm_select = NOIMM; - illegal_instr = 1'b0; - instruction_o.pc = pc_i; - instruction_o.fu = NONE; - instruction_o.op = ADD; - instruction_o.rs1 = 5'b0; - instruction_o.rs2 = 5'b0; - instruction_o.rd = 5'b0; - instruction_o.use_pc = 1'b0; - instruction_o.trans_id = 5'b0; + imm_select = NOIMM; + illegal_instr = 1'b0; + instruction_o.pc = pc_i; + instruction_o.fu = NONE; + instruction_o.op = ADD; + instruction_o.rs1 = 5'b0; + instruction_o.rs2 = 5'b0; + instruction_o.rd = 5'b0; + instruction_o.use_pc = 1'b0; + instruction_o.trans_id = 5'b0; instruction_o.is_compressed = is_compressed_i; - // TODO end + instruction_o.use_zimm = 1'b0; + if (~ex_i.valid) begin case (instr.rtype.opcode) OPCODE_SYSTEM: begin - // TODO: Implement + instruction_o.fu = CSR; + instruction_o.rs1 = instr.itype.rs1; + instruction_o.rd = instr.itype.rd; + + unique case (instr.itype.funct3) + 3'b000: begin + // TODO: + // ECALL, EBREAK, SFEBCE.VM + // MRET/SRET/URET, WFI + illegal_instr = 1'b1; + end + // atomically swaps values in the CSR and integer register + 3'b001: begin// CSRRW + imm_select = IIMM; + instruction_o.op = CSR_WRITE; + end + // atomically set values in the CSR and write back to rd + 3'b010: begin// CSRRS + imm_select = IIMM; + // this is just a read + if (instr.itype.rs1 == 5'b0) + instruction_o.op = CSR_READ; + else + instruction_o.op = CSR_SET; + end + // atomically clear values in the CSR and write back to rd + 3'b011: begin// CSRRC + imm_select = IIMM; + // this is just a read + if (instr.itype.rs1 == 5'b0) + instruction_o.op = CSR_READ; + else + instruction_o.op = CSR_SET; + end + // use zimm and iimm + 3'b101: begin// CSRRWI + instruction_o.rs1 = 5'b0; + imm_select = IIMM; + instruction_o.use_zimm = 1'b1; + instruction_o.op = CSR_WRITE; + end + 3'b110: begin// CSRRSI + instruction_o.rs1 = 5'b0; + imm_select = IIMM; + instruction_o.use_zimm = 1'b1; + // this is just a read + if (instr.itype.rs1 == 5'b0) + instruction_o.op = CSR_READ; + else + instruction_o.op = CSR_SET; + end + 3'b111: begin// CSRRCI + instruction_o.rs1 = 5'b0; + imm_select = IIMM; + instruction_o.use_zimm = 1'b1; + // this is just a read + if (instr.itype.rs1 == 5'b0) + instruction_o.op = CSR_READ; + else + instruction_o.op = CSR_CLEAR; + end + default: illegal_instr = 1'b1; + endcase end OPCODE_FENCE: begin // TODO: Implement + // FENCE, FENCE.I, end // -------------------------- @@ -269,7 +333,6 @@ module decoder ( imm_sb_type = { {51 {instruction_i[31]}}, instruction_i[31], instruction_i[7], instruction_i[30:25], instruction_i[11:8], 1'b0 }; imm_u_type = { {32 {instruction_i[31]}}, instruction_i[31:12], 12'b0 }; // JAL, AUIPC, sign extended to 64 bit imm_uj_type = { {44 {instruction_i[31]}}, instruction_i[19:12], instruction_i[20], instruction_i[30:21], 1'b0 }; - // imm_z_type = { 59'b0, instruction_i[`REG_S1] }; imm_s2_type = { 59'b0, instruction_i[24:20] }; imm_bi_type = { {59{instruction_i[24]}}, instruction_i[24:20] }; imm_s3_type = { 59'b0, instruction_i[29:25] }; diff --git a/src/issue_read_operands.sv b/src/issue_read_operands.sv index ed329593d..5bfdbf1c1 100644 --- a/src/issue_read_operands.sv +++ b/src/issue_read_operands.sv @@ -61,7 +61,7 @@ module issue_read_operands ( input logic [63:0] wdata_a_i, input logic we_a_i ); - logic stall; // stall signal, we do not want to fetch any more entries + logic stall; // stall signal, we do not want to fetch any more entries logic fu_busy; // functional unit is busy logic [63:0] operand_a_regfile, operand_b_regfile; // operands coming from regfile @@ -146,9 +146,11 @@ module issue_read_operands ( // poll the scoreboard for those values rs1_o = issue_instr_i.rs1; rs2_o = issue_instr_i.rs2; + // 0. check that we are not using the zimm type in rs1 + // as this is an immediate we do not have to wait on anything here // 1. check if the source registers are clobberd // 2. poll the scoreboard - if (rd_clobber_i[issue_instr_i.rs1] != NONE) begin + if (~issue_instr_i.use_zimm && rd_clobber_i[issue_instr_i.rs1] != NONE) begin // the operand is available, forward it if (rs1_valid_i) forward_rs1 = 1'b1; @@ -164,8 +166,6 @@ module issue_read_operands ( else // the operand is not available -> stall stall = 1'b1; end - - end // Forwarding/Output MUX always_comb begin : forwarding @@ -187,6 +187,11 @@ module issue_read_operands ( operand_a_n = issue_instr_i.pc; end + // use the zimm as operand a + if (issue_instr_i.use_zimm) begin + // zero extend operand a + operand_a_n = {52'b0, issue_instr_i.rs1}; + end // or is it an immediate (including PC), this is not the case for a store if (issue_instr_i.use_imm && issue_instr_i.op != SD && issue_instr_i.op != SW