Skip to content

Commit

Permalink
[hardware] Re-parametrize the interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
mp-17 committed Dec 4, 2024
1 parent 86eff40 commit cf760e8
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 166 deletions.
15 changes: 11 additions & 4 deletions hardware/include/ara_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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 //
Expand Down
61 changes: 1 addition & 60 deletions hardware/src/ara.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
61 changes: 32 additions & 29 deletions hardware/src/ara_dispatcher.sv
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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);
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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

Expand All @@ -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]} ||
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit cf760e8

Please sign in to comment.