diff --git a/hardware/include/ara_pkg.sv b/hardware/include/ara_pkg.sv index f4ccfe08b..a98c31822 100644 --- a/hardware/include/ara_pkg.sv +++ b/hardware/include/ara_pkg.sv @@ -289,11 +289,18 @@ package ara_pkg; fp64_from_fp32 = fp64; endfunction - ///////////////////////////// - // Accelerator interface // - ///////////////////////////// + //////////////////// + // CVA6 commons // + //////////////////// - // See CVA6 and Ara main modules + // Definitions common to CVA6 + typedef cva6_config_pkg::exception_t exception_t; + typedef cva6_config_pkg::accelerator_req_t accelerator_req_t; + typedef cva6_config_pkg::accelerator_resp_t accelerator_resp_t; + typedef cva6_config_pkg::acc_mmu_req_t acc_mmu_req_t; + typedef cva6_config_pkg::acc_mmu_resp_t acc_mmu_resp_t; + typedef cva6_config_pkg::cva6_to_acc_t cva6_to_acc_t; + typedef cva6_config_pkg::acc_to_cva6_t acc_to_cva6_t; //////////////////// // PE interface // diff --git a/hardware/src/ara.sv b/hardware/src/ara.sv index 26bd57f95..6fbd1a530 100644 --- a/hardware/src/ara.sv +++ b/hardware/src/ara.sv @@ -34,66 +34,7 @@ module ara import ara_pkg::*; #( // vector store unit, the slide unit, and the mask unit. localparam int unsigned NrPEs = NrLanes + 4, localparam type vlen_t = logic[$clog2(VLEN+1)-1:0], - localparam int unsigned VLENB = VLEN / 8, - // Exception type: should be the same as in CVA6 - localparam type exception_t = struct packed { - logic [CVA6Cfg.XLEN-1:0] cause; // cause of exception - logic [CVA6Cfg.XLEN-1:0] tval; // additional information of causing exception (e.g.: instruction causing it), - // address of LD/ST fault - logic [CVA6Cfg.GPLEN-1:0] tval2; // additional information when the causing exception in a guest exception - logic [31:0] tinst; // transformed instruction information - logic gva; // signals when a guest virtual address is written to tval - logic valid; - }, - // Interfaces (they need the CVA6Cfg) - localparam type acc_mmu_req_t = struct packed { - logic acc_mmu_misaligned_ex; - logic acc_mmu_req; - logic [CVA6Cfg.VLEN-1:0] acc_mmu_vaddr; - logic acc_mmu_is_store; - }, - localparam type acc_mmu_resp_t = struct packed { - logic acc_mmu_dtlb_hit; - logic [CVA6Cfg.PPNW-1:0] acc_mmu_dtlb_ppn; - logic acc_mmu_valid; - logic [CVA6Cfg.PLEN-1:0] acc_mmu_paddr; - exception_t acc_mmu_exception; - }, - localparam type accelerator_req_t = struct packed { - logic req_valid; - logic resp_ready; - riscv::instruction_t insn; - logic [CVA6Cfg.XLEN-1:0] rs1; - logic [CVA6Cfg.XLEN-1:0] rs2; - fpnew_pkg::roundmode_e frm; - logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id; - logic store_pending; - logic acc_cons_en; // Invalidation interface - logic inval_ready; // Invalidation interface - }, - localparam type accelerator_resp_t = struct packed { - logic req_ready; - logic resp_valid; - logic [CVA6Cfg.XLEN-1:0] result; - logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id; - exception_t exception; - logic store_pending; - logic store_complete; - logic load_complete; - logic [4:0] fflags; - logic fflags_valid; - logic inval_valid; // Invalidation interface - logic [63:0] inval_addr; // Invalidation interface - }, - localparam type cva6_to_acc_t = struct packed { - accelerator_req_t acc_req; // Insn/mem - logic acc_mmu_en; // MMU - acc_mmu_resp_t acc_mmu_resp; // MMU - }, - localparam type acc_to_cva6_t = struct packed { - accelerator_resp_t acc_resp; // Insn/mem - acc_mmu_req_t acc_mmu_req; // MMU - } + localparam int unsigned VLENB = VLEN / 8 ) ( // Clock and Reset input logic clk_i, diff --git a/hardware/src/ara_dispatcher.sv b/hardware/src/ara_dispatcher.sv index 19d061a78..86f8c4ffa 100644 --- a/hardware/src/ara_dispatcher.sv +++ b/hardware/src/ara_dispatcher.sv @@ -169,6 +169,9 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( logic [4:0] vs_buffer_d, vs_buffer_q; // Keep track of the registers to be reshuffled |vs1|vs2|vd| logic [2:0] reshuffle_req_d, reshuffle_req_q; + // Easily handle the riscv incoming instruction + riscv::instruction_t instr; + assign instr = riscv::instruction_t'(acc_req_i.insn); always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin @@ -348,7 +351,7 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( // Inject a reshuffle instruction RESHUFFLE: begin // Instruction is of one of the RVV types - automatic rvv_instruction_t insn = rvv_instruction_t'(acc_req_i.insn.instr); + automatic rvv_instruction_t insn = rvv_instruction_t'(instr.instr); // Stall the interface, wait for the backend to accept the injected uop acc_resp_o.req_ready = 1'b0; @@ -475,14 +478,14 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( acc_resp_o.req_ready = 1'b1; // Decode the instructions based on their opcode - unique case (acc_req_i.insn.itype.opcode) + unique case (instr.itype.opcode) ////////////////////////////////////// // Vector Arithmetic instructions // ////////////////////////////////////// riscv::OpcodeVec: begin // Instruction is of one of the RVV types - automatic rvv_instruction_t insn = rvv_instruction_t'(acc_req_i.insn.instr); + automatic rvv_instruction_t insn = rvv_instruction_t'(instr.instr); // These (mostly) always respond at the same cycle acc_resp_o.resp_valid = 1'b1; @@ -2513,7 +2516,7 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( riscv::OpcodeLoadFp: begin // Instruction is of one of the RVV types - automatic rvv_instruction_t insn = rvv_instruction_t'(acc_req_i.insn.instr); + automatic rvv_instruction_t insn = rvv_instruction_t'(instr.instr); // The instruction is a load is_vload = 1'b1; @@ -2708,7 +2711,7 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( riscv::OpcodeStoreFp: begin // Instruction is of one of the RVV types - automatic rvv_instruction_t insn = rvv_instruction_t'(acc_req_i.insn.instr); + automatic rvv_instruction_t insn = rvv_instruction_t'(instr.instr); // The instruction is a store is_vstore = 1'b1; @@ -2919,10 +2922,10 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( acc_resp_o.resp_valid = 1'b1; is_config = 1'b1; - unique case (acc_req_i.insn.itype.funct3) + unique case (instr.itype.funct3) 3'b001: begin // csrrw // Decode the CSR. - case (riscv::csr_addr_t'(acc_req_i.insn.itype.imm)) + case (riscv::csr_addr_t'(instr.itype.imm)) // Only vstart can be written with CSR instructions. riscv::CSR_VSTART: begin csr_vstart_d = acc_req_i.rs1; @@ -2946,24 +2949,24 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( end 3'b010: begin // csrrs // Decode the CSR. - case (riscv::csr_addr_t'(acc_req_i.insn.itype.imm)) + case (riscv::csr_addr_t'(instr.itype.imm)) riscv::CSR_VSTART: begin csr_vstart_d = csr_vstart_q | vlen_t'(acc_req_i.rs1); acc_resp_o.result = csr_vstart_q; end riscv::CSR_VTYPE: begin // Only reads are allowed - if (acc_req_i.insn.itype.rs1 == '0) acc_resp_o.result = xlen_vtype(csr_vtype_q); + if (instr.itype.rs1 == '0) acc_resp_o.result = xlen_vtype(csr_vtype_q); else illegal_insn = 1'b1; end riscv::CSR_VL: begin // Only reads are allowed - if (acc_req_i.insn.itype.rs1 == '0) acc_resp_o.result = csr_vl_q; + if (instr.itype.rs1 == '0) acc_resp_o.result = csr_vl_q; else illegal_insn = 1'b1; end riscv::CSR_VLENB: begin // Only reads are allowed - if (acc_req_i.insn.itype.rs1 == '0) acc_resp_o.result = VLENB; + if (instr.itype.rs1 == '0) acc_resp_o.result = VLENB; else illegal_insn = 1'b1; end riscv::CSR_VXRM: begin @@ -2984,24 +2987,24 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( end 3'b011: begin // csrrc // Decode the CSR. - case (riscv::csr_addr_t'(acc_req_i.insn.itype.imm)) + case (riscv::csr_addr_t'(instr.itype.imm)) riscv::CSR_VSTART: begin csr_vstart_d = csr_vstart_q & ~vlen_t'(acc_req_i.rs1); acc_resp_o.result = csr_vstart_q; end riscv::CSR_VTYPE: begin // Only reads are allowed - if (acc_req_i.insn.itype.rs1 == '0) acc_resp_o.result = xlen_vtype(csr_vtype_q); + if (instr.itype.rs1 == '0) acc_resp_o.result = xlen_vtype(csr_vtype_q); else illegal_insn = 1'b1; end riscv::CSR_VL: begin // Only reads are allowed - if (acc_req_i.insn.itype.rs1 == '0) acc_resp_o.result = csr_vl_q; + if (instr.itype.rs1 == '0) acc_resp_o.result = csr_vl_q; else illegal_insn = 1'b1; end riscv::CSR_VLENB: begin // Only reads are allowed - if (acc_req_i.insn.itype.rs1 == '0) acc_resp_o.result = VLENB; + if (instr.itype.rs1 == '0) acc_resp_o.result = VLENB; else illegal_insn = 1'b1; end riscv::CSR_VXSAT: begin @@ -3022,7 +3025,7 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( end 3'b101: begin // csrrwi // Decode the CSR. - case (riscv::csr_addr_t'(acc_req_i.insn.itype.imm)) + case (riscv::csr_addr_t'(instr.itype.imm)) // Only vstart can be written with CSR instructions. riscv::CSR_VSTART: begin csr_vstart_d = vlen_t'(acc_req_i.rs1); @@ -3047,24 +3050,24 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( end 3'b110: begin // csrrsi // Decode the CSR. - case (riscv::csr_addr_t'(acc_req_i.insn.itype.imm)) + case (riscv::csr_addr_t'(instr.itype.imm)) riscv::CSR_VSTART: begin csr_vstart_d = csr_vstart_q | vlen_t'(acc_req_i.rs1); acc_resp_o.result = csr_vstart_q; end riscv::CSR_VTYPE: begin // Only reads are allowed - if (acc_req_i.insn.itype.rs1 == '0) acc_resp_o.result = xlen_vtype(csr_vtype_q); + if (instr.itype.rs1 == '0) acc_resp_o.result = xlen_vtype(csr_vtype_q); else illegal_insn = 1'b1; end riscv::CSR_VL: begin // Only reads are allowed - if (acc_req_i.insn.itype.rs1 == '0) acc_resp_o.result = csr_vl_q; + if (instr.itype.rs1 == '0) acc_resp_o.result = csr_vl_q; else illegal_insn = 1'b1; end riscv::CSR_VLENB: begin // Only reads are allowed - if (acc_req_i.insn.itype.rs1 == '0) acc_resp_o.result = VLENB; + if (instr.itype.rs1 == '0) acc_resp_o.result = VLENB; else illegal_insn = 1'b1; end riscv::CSR_VXSAT: begin @@ -3088,24 +3091,24 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( end 3'b111: begin // csrrci // Decode the CSR. - unique case (riscv::csr_addr_t'(acc_req_i.insn.itype.imm)) + unique case (riscv::csr_addr_t'(instr.itype.imm)) riscv::CSR_VSTART: begin csr_vstart_d = csr_vstart_q & ~vlen_t'(acc_req_i.rs1); acc_resp_o.result = csr_vstart_q; end riscv::CSR_VTYPE: begin // Only reads are allowed - if (acc_req_i.insn.itype.rs1 == '0) acc_resp_o.result = xlen_vtype(csr_vtype_q); + if (instr.itype.rs1 == '0) acc_resp_o.result = xlen_vtype(csr_vtype_q); else illegal_insn = 1'b1; end riscv::CSR_VL: begin // Only reads are allowed - if (acc_req_i.insn.itype.rs1 == '0) acc_resp_o.result = csr_vl_q; + if (instr.itype.rs1 == '0) acc_resp_o.result = csr_vl_q; else illegal_insn = 1'b1; end riscv::CSR_VLENB: begin // Only reads are allowed - if (acc_req_i.insn.itype.rs1 == '0) acc_resp_o.result = VLENB; + if (instr.itype.rs1 == '0) acc_resp_o.result = VLENB; else illegal_insn = 1'b1; end riscv::CSR_VXSAT: begin @@ -3129,7 +3132,7 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( // Trigger an illegal instruction illegal_insn = 1'b1; end - endcase // acc_req_i.insn.itype.funct3 + endcase // instr.itype.funct3 end end @@ -3156,13 +3159,13 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( acc_resp_o.resp_valid = 1'b1; acc_resp_o.exception.valid = 1'b1; acc_resp_o.exception.cause = riscv::ILLEGAL_INSTR; - acc_resp_o.exception.tval = acc_req_i.insn; + acc_resp_o.exception.tval = instr; end // Check if we need to reshuffle our vector registers involved in the operation // This operation is costly when occurs, so avoid it if possible if ( ara_req_valid_d && !acc_resp_o.exception.valid ) begin - automatic rvv_instruction_t insn = rvv_instruction_t'(acc_req_i.insn.instr); + automatic rvv_instruction_t insn = rvv_instruction_t'(instr.instr); // Is the instruction an in-lane one and could it be subject to reshuffling? in_lane_op = ara_req_d.op inside {[VADD:VMERGE]} || ara_req_d.op inside {[VREDSUM:VMSBC]} || @@ -3205,7 +3208,7 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( // Reshuffle if at least one of the three registers needs a reshuffle if (|reshuffle_req_d) begin // Instruction is of one of the RVV types - automatic rvv_instruction_t insn = rvv_instruction_t'(acc_req_i.insn.instr); + automatic rvv_instruction_t insn = rvv_instruction_t'(instr.instr); // Stall the interface, and inject a reshuffling instruction acc_resp_o.req_ready = 1'b0; @@ -3287,7 +3290,7 @@ module ara_dispatcher import ara_pkg::*; import rvv_pkg::*; #( // * CSR operations are not considered vector instructions if ( acc_resp_o.resp_valid & !acc_resp_o.exception.valid - & (acc_req_i.insn.itype.opcode != riscv::OpcodeSystem) + & (instr.itype.opcode != riscv::OpcodeSystem) ) begin csr_vstart_d = '0; end diff --git a/hardware/src/ara_system.sv b/hardware/src/ara_system.sv index e75b0abb1..574e70674 100644 --- a/hardware/src/ara_system.sv +++ b/hardware/src/ara_system.sv @@ -43,66 +43,7 @@ module ara_system import axi_pkg::*; import ara_pkg::*; #( parameter type system_axi_w_t = logic, parameter type system_axi_b_t = logic, parameter type system_axi_req_t = logic, - parameter type system_axi_resp_t = logic, - // Interfaces (they need the CVA6Cfg) - // Exception type: should be the same as in CVA6 - localparam type exception_t = struct packed { - logic [CVA6Cfg.XLEN-1:0] cause; // cause of exception - logic [CVA6Cfg.XLEN-1:0] tval; // additional information of causing exception (e.g.: instruction causing it), - // address of LD/ST fault - logic [CVA6Cfg.GPLEN-1:0] tval2; // additional information when the causing exception in a guest exception - logic [31:0] tinst; // transformed instruction information - logic gva; // signals when a guest virtual address is written to tval - logic valid; - }, - localparam type acc_mmu_req_t = struct packed { - logic acc_mmu_misaligned_ex; - logic acc_mmu_req; - logic [CVA6Cfg.VLEN-1:0] acc_mmu_vaddr; - logic acc_mmu_is_store; - }, - localparam type acc_mmu_resp_t = struct packed { - logic acc_mmu_dtlb_hit; - logic [CVA6Cfg.PPNW-1:0] acc_mmu_dtlb_ppn; - logic acc_mmu_valid; - logic [CVA6Cfg.PLEN-1:0] acc_mmu_paddr; - exception_t acc_mmu_exception; - }, - localparam type accelerator_req_t = struct packed { - logic req_valid; - logic resp_ready; - riscv::instruction_t insn; - logic [CVA6Cfg.XLEN-1:0] rs1; - logic [CVA6Cfg.XLEN-1:0] rs2; - fpnew_pkg::roundmode_e frm; - logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id; - logic store_pending; - logic acc_cons_en; // Invalidation interface - logic inval_ready; // Invalidation interface - }, - localparam type accelerator_resp_t = struct packed { - logic req_ready; - logic resp_valid; - logic [CVA6Cfg.XLEN-1:0] result; - logic [CVA6Cfg.TRANS_ID_BITS-1:0] trans_id; - exception_t exception; - logic store_pending; - logic store_complete; - logic load_complete; - logic [4:0] fflags; - logic fflags_valid; - logic inval_valid; // Invalidation interface - logic [63:0] inval_addr; // Invalidation interface - }, - localparam type cva6_to_acc_t = struct packed { - accelerator_req_t acc_req; // Insn/mem - logic acc_mmu_en; // MMU - acc_mmu_resp_t acc_mmu_resp; // MMU - }, - localparam type acc_to_cva6_t = struct packed { - accelerator_resp_t acc_resp; // Insn/mem - acc_mmu_req_t acc_mmu_req; // MMU - } + parameter type system_axi_resp_t = logic ) ( input logic clk_i, input logic rst_ni, @@ -134,8 +75,8 @@ module ara_system import axi_pkg::*; import ara_pkg::*; #( ////////////////////// // Accelerator ports - cva6_to_acc_t acc_req; - acc_to_cva6_t acc_resp; + cva6_to_acc_t acc_req; + acc_to_cva6_t acc_resp; logic acc_resp_valid; logic acc_resp_ready; logic acc_cons_en; @@ -173,16 +114,20 @@ module ara_system import axi_pkg::*; import ara_pkg::*; #( ); `else cva6 #( - .CVA6Cfg (CVA6Cfg), - .cvxif_req_t (cva6_to_acc_t ), - .cvxif_resp_t (acc_to_cva6_t ), - .axi_ar_chan_t (ariane_axi_ar_t ), - .axi_aw_chan_t (ariane_axi_aw_t ), - .axi_w_chan_t (ariane_axi_w_t ), - .b_chan_t (ariane_axi_b_t ), - .r_chan_t (ariane_axi_r_t ), - .noc_req_t (ariane_axi_req_t ), - .noc_resp_t (ariane_axi_resp_t ) + .CVA6Cfg (CVA6Cfg ), + .cvxif_req_t (cva6_to_acc_t ), + .cvxif_resp_t (acc_to_cva6_t ), + .axi_ar_chan_t (ariane_axi_ar_t ), + .axi_aw_chan_t (ariane_axi_aw_t ), + .axi_w_chan_t (ariane_axi_w_t ), + .b_chan_t (ariane_axi_b_t ), + .r_chan_t (ariane_axi_r_t ), + .noc_req_t (ariane_axi_req_t ), + .noc_resp_t (ariane_axi_resp_t ), + .accelerator_req_t (accelerator_req_t), + .accelerator_resp_t(accelerator_resp_t), + .acc_mmu_req_t (acc_mmu_req_t), + .acc_mmu_resp_t (acc_mmu_resp_t) ) i_ariane ( .clk_i (clk_i ), .rst_ni (rst_ni ), @@ -274,7 +219,7 @@ module ara_system import axi_pkg::*; import ara_pkg::*; #( .FPUSupport (FPUSupport ), .FPExtSupport(FPExtSupport ), .FixPtSupport(FixPtSupport ), - .CVA6Cfg (CVA6Cfg), + .CVA6Cfg (CVA6Cfg ), .AxiDataWidth(AxiWideDataWidth), .AxiAddrWidth(AxiAddrWidth ), .axi_ar_t (ara_axi_ar_t ),