mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-23 13:47:13 -04:00
CVXIF 1.0.0 (#2340)
This commit is contained in:
parent
5fcc39dbee
commit
8fa590b5c3
45 changed files with 1656 additions and 662 deletions
|
@ -398,7 +398,7 @@ generated_tests:
|
||||||
- mv verif/sim/seedlist.yaml artifacts/coverage
|
- mv verif/sim/seedlist.yaml artifacts/coverage
|
||||||
- python3 .gitlab-ci/scripts/report_pass.py
|
- python3 .gitlab-ci/scripts/report_pass.py
|
||||||
|
|
||||||
generated_xif_tests:
|
.generated_xif_tests:
|
||||||
extends:
|
extends:
|
||||||
- .verif_test
|
- .verif_test
|
||||||
variables:
|
variables:
|
||||||
|
@ -519,7 +519,7 @@ code_coverage-report:
|
||||||
needs:
|
needs:
|
||||||
- generated_tests
|
- generated_tests
|
||||||
- directed_isacov-tests
|
- directed_isacov-tests
|
||||||
- generated_xif_tests
|
# - generated_xif_tests
|
||||||
- csr_embedded_tests
|
- csr_embedded_tests
|
||||||
variables:
|
variables:
|
||||||
DASHBOARD_JOB_TITLE: "Report merge coverage"
|
DASHBOARD_JOB_TITLE: "Report merge coverage"
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
cv32a65x:
|
cv32a65x:
|
||||||
gates: 162197
|
gates: 163431
|
||||||
|
|
|
@ -76,7 +76,6 @@ sources:
|
||||||
- core/include/std_cache_pkg.sv
|
- core/include/std_cache_pkg.sv
|
||||||
|
|
||||||
# Extension Interface
|
# Extension Interface
|
||||||
- core/include/cvxif_pkg.sv
|
|
||||||
- core/cvxif_example/include/cvxif_instr_pkg.sv
|
- core/cvxif_example/include/cvxif_instr_pkg.sv
|
||||||
- core/cvxif_fu.sv
|
- core/cvxif_fu.sv
|
||||||
- core/cvxif_example/cvxif_example_coprocessor.sv
|
- core/cvxif_example/cvxif_example_coprocessor.sv
|
||||||
|
|
|
@ -71,11 +71,14 @@ ${CVA6_REPO_DIR}/core/include/instr_tracer_pkg.sv
|
||||||
${CVA6_REPO_DIR}/core/include/build_config_pkg.sv
|
${CVA6_REPO_DIR}/core/include/build_config_pkg.sv
|
||||||
|
|
||||||
//CVXIF
|
//CVXIF
|
||||||
${CVA6_REPO_DIR}/core/include/cvxif_pkg.sv
|
${CVA6_REPO_DIR}/core/cvxif_compressed_if_driver.sv
|
||||||
|
${CVA6_REPO_DIR}/core/cvxif_issue_register_commit_if_driver.sv
|
||||||
${CVA6_REPO_DIR}/core/cvxif_example/include/cvxif_instr_pkg.sv
|
${CVA6_REPO_DIR}/core/cvxif_example/include/cvxif_instr_pkg.sv
|
||||||
${CVA6_REPO_DIR}/core/cvxif_fu.sv
|
${CVA6_REPO_DIR}/core/cvxif_fu.sv
|
||||||
${CVA6_REPO_DIR}/core/cvxif_example/cvxif_example_coprocessor.sv
|
${CVA6_REPO_DIR}/core/cvxif_example/cvxif_example_coprocessor.sv
|
||||||
${CVA6_REPO_DIR}/core/cvxif_example/instr_decoder.sv
|
${CVA6_REPO_DIR}/core/cvxif_example/instr_decoder.sv
|
||||||
|
${CVA6_REPO_DIR}/core/cvxif_example/compressed_instr_decoder.sv
|
||||||
|
${CVA6_REPO_DIR}/core/cvxif_example/copro_alu.sv
|
||||||
|
|
||||||
// Common Cells
|
// Common Cells
|
||||||
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
|
${CVA6_REPO_DIR}/vendor/pulp-platform/common_cells/src/cf_math_pkg.sv
|
||||||
|
|
|
@ -27,12 +27,11 @@ ${CVA6_REPO_DIR}/core/include/instr_tracer_pkg.sv
|
||||||
${CVA6_REPO_DIR}/core/include/build_config_pkg.sv
|
${CVA6_REPO_DIR}/core/include/build_config_pkg.sv
|
||||||
|
|
||||||
//CVXIF
|
//CVXIF
|
||||||
${CVA6_REPO_DIR}/core/include/cvxif_pkg.sv
|
|
||||||
${CVA6_REPO_DIR}/core/cvxif_example/include/cvxif_instr_pkg.sv
|
${CVA6_REPO_DIR}/core/cvxif_example/include/cvxif_instr_pkg.sv
|
||||||
${CVA6_REPO_DIR}/core/cvxif_fu.sv
|
|
||||||
${CVA6_REPO_DIR}/core/cvxif_example/cvxif_example_coprocessor.sv
|
${CVA6_REPO_DIR}/core/cvxif_example/cvxif_example_coprocessor.sv
|
||||||
${CVA6_REPO_DIR}/core/cvxif_example/instr_decoder.sv
|
${CVA6_REPO_DIR}/core/cvxif_example/instr_decoder.sv
|
||||||
${CVA6_REPO_DIR}/core/cva6_fifo_v3.sv
|
${CVA6_REPO_DIR}/core/cvxif_example/compressed_instr_decoder.sv
|
||||||
|
${CVA6_REPO_DIR}/core/cvxif_example/copro_alu.sv
|
||||||
|
|
||||||
|
|
||||||
// Common Cells
|
// Common Cells
|
||||||
|
|
213
core/cva6.sv
213
core/cva6.sv
|
@ -13,6 +13,7 @@
|
||||||
// Description: CVA6 Top-level module
|
// Description: CVA6 Top-level module
|
||||||
|
|
||||||
`include "rvfi_types.svh"
|
`include "rvfi_types.svh"
|
||||||
|
`include "cvxif_types.svh"
|
||||||
|
|
||||||
module cva6
|
module cva6
|
||||||
import ariane_pkg::*;
|
import ariane_pkg::*;
|
||||||
|
@ -272,8 +273,22 @@ module cva6
|
||||||
//
|
//
|
||||||
parameter type acc_cfg_t = logic,
|
parameter type acc_cfg_t = logic,
|
||||||
parameter acc_cfg_t AccCfg = '0,
|
parameter acc_cfg_t AccCfg = '0,
|
||||||
parameter type cvxif_req_t = cvxif_pkg::cvxif_req_t,
|
// CVXIF Types
|
||||||
parameter type cvxif_resp_t = cvxif_pkg::cvxif_resp_t
|
parameter type readregflags_t = `READREGFLAGS_T(CVA6Cfg),
|
||||||
|
parameter type writeregflags_t = `WRITEREGFLAGS_T(CVA6Cfg),
|
||||||
|
parameter type id_t = `ID_T(CVA6Cfg),
|
||||||
|
parameter type hartid_t = `HARTID_T(CVA6Cfg),
|
||||||
|
parameter type x_compressed_req_t = `X_COMPRESSED_REQ_T(CVA6Cfg, hartid_t),
|
||||||
|
parameter type x_compressed_resp_t = `X_COMPRESSED_RESP_T(CVA6Cfg),
|
||||||
|
parameter type x_issue_req_t = `X_ISSUE_REQ_T(CVA6Cfg, hartit_t, id_t),
|
||||||
|
parameter type x_issue_resp_t = `X_ISSUE_RESP_T(CVA6Cfg, writeregflags_t, readregflags_t),
|
||||||
|
parameter type x_register_t = `X_REGISTER_T(CVA6Cfg, hartid_t, id_t, readregflags_t),
|
||||||
|
parameter type x_commit_t = `X_COMMIT_T(CVA6Cfg, hartid_t, id_t),
|
||||||
|
parameter type x_result_t = `X_RESULT_T(CVA6Cfg, hartid_t, id_t, writeregflags_t),
|
||||||
|
parameter type cvxif_req_t =
|
||||||
|
`CVXIF_REQ_T(CVA6Cfg, x_compressed_req_t, x_issue_req_t, x_register_req_t, x_commit_t),
|
||||||
|
parameter type cvxif_resp_t =
|
||||||
|
`CVXIF_RESP_T(CVA6Cfg, x_compressed_resp_t, x_issue_resp_t, x_result_t)
|
||||||
) (
|
) (
|
||||||
// Subsystem Clock - SUBSYSTEM
|
// Subsystem Clock - SUBSYSTEM
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
|
@ -343,8 +358,27 @@ module cva6
|
||||||
logic [CVA6Cfg.NrCommitPorts-1:0] commit_macro_ack;
|
logic [CVA6Cfg.NrCommitPorts-1:0] commit_macro_ack;
|
||||||
|
|
||||||
localparam NumPorts = 4;
|
localparam NumPorts = 4;
|
||||||
cvxif_pkg::cvxif_req_t cvxif_req;
|
|
||||||
cvxif_pkg::cvxif_resp_t cvxif_resp;
|
// CVXIF
|
||||||
|
cvxif_req_t cvxif_req;
|
||||||
|
// CVXIF OUTPUTS
|
||||||
|
logic x_compressed_valid;
|
||||||
|
x_compressed_req_t x_compressed_req;
|
||||||
|
logic x_issue_valid;
|
||||||
|
x_issue_req_t x_issue_req;
|
||||||
|
logic x_register_valid;
|
||||||
|
x_register_t x_register;
|
||||||
|
logic x_commit_valid;
|
||||||
|
x_commit_t x_commit;
|
||||||
|
logic x_result_ready;
|
||||||
|
// CVXIF INPUTS
|
||||||
|
logic x_compressed_ready;
|
||||||
|
x_compressed_resp_t x_compressed_resp;
|
||||||
|
logic x_issue_ready;
|
||||||
|
x_issue_resp_t x_issue_resp;
|
||||||
|
logic x_register_ready;
|
||||||
|
logic x_result_valid;
|
||||||
|
x_result_t x_result;
|
||||||
|
|
||||||
// --------------
|
// --------------
|
||||||
// PCGEN <-> CSR
|
// PCGEN <-> CSR
|
||||||
|
@ -437,9 +471,11 @@ module cva6
|
||||||
logic x_valid_ex_id;
|
logic x_valid_ex_id;
|
||||||
exception_t x_exception_ex_id;
|
exception_t x_exception_ex_id;
|
||||||
logic x_we_ex_id;
|
logic x_we_ex_id;
|
||||||
|
logic [4:0] x_rd_ex_id;
|
||||||
logic [CVA6Cfg.NrIssuePorts-1:0] x_issue_valid_id_ex;
|
logic [CVA6Cfg.NrIssuePorts-1:0] x_issue_valid_id_ex;
|
||||||
logic x_issue_ready_ex_id;
|
logic x_issue_ready_ex_id;
|
||||||
logic [31:0] x_off_instr_id_ex;
|
logic [31:0] x_off_instr_id_ex;
|
||||||
|
logic x_transaction_rejected;
|
||||||
// --------------
|
// --------------
|
||||||
// EX <-> COMMIT
|
// EX <-> COMMIT
|
||||||
// --------------
|
// --------------
|
||||||
|
@ -633,7 +669,9 @@ module cva6
|
||||||
.irq_ctrl_t(irq_ctrl_t),
|
.irq_ctrl_t(irq_ctrl_t),
|
||||||
.scoreboard_entry_t(scoreboard_entry_t),
|
.scoreboard_entry_t(scoreboard_entry_t),
|
||||||
.interrupts_t(interrupts_t),
|
.interrupts_t(interrupts_t),
|
||||||
.INTERRUPTS(INTERRUPTS)
|
.INTERRUPTS(INTERRUPTS),
|
||||||
|
.x_compressed_req_t(x_compressed_req_t),
|
||||||
|
.x_compressed_resp_t(x_compressed_resp_t)
|
||||||
) id_stage_i (
|
) id_stage_i (
|
||||||
.clk_i,
|
.clk_i,
|
||||||
.rst_ni,
|
.rst_ni,
|
||||||
|
@ -652,20 +690,25 @@ module cva6
|
||||||
|
|
||||||
.rvfi_is_compressed_o(rvfi_is_compressed),
|
.rvfi_is_compressed_o(rvfi_is_compressed),
|
||||||
|
|
||||||
.priv_lvl_i (priv_lvl),
|
.priv_lvl_i (priv_lvl),
|
||||||
.v_i (v),
|
.v_i (v),
|
||||||
.fs_i (fs),
|
.fs_i (fs),
|
||||||
.vfs_i (vfs),
|
.vfs_i (vfs),
|
||||||
.frm_i (frm_csr_id_issue_ex),
|
.frm_i (frm_csr_id_issue_ex),
|
||||||
.vs_i (vs),
|
.vs_i (vs),
|
||||||
.irq_i (irq_i),
|
.irq_i (irq_i),
|
||||||
.irq_ctrl_i (irq_ctrl_csr_id),
|
.irq_ctrl_i (irq_ctrl_csr_id),
|
||||||
.debug_mode_i(debug_mode),
|
.debug_mode_i (debug_mode),
|
||||||
.tvm_i (tvm_csr_id),
|
.tvm_i (tvm_csr_id),
|
||||||
.tw_i (tw_csr_id),
|
.tw_i (tw_csr_id),
|
||||||
.vtw_i (vtw_csr_id),
|
.vtw_i (vtw_csr_id),
|
||||||
.tsr_i (tsr_csr_id),
|
.tsr_i (tsr_csr_id),
|
||||||
.hu_i (hu)
|
.hu_i (hu),
|
||||||
|
.hart_id_i (hart_id_i),
|
||||||
|
.compressed_ready_i(x_compressed_ready),
|
||||||
|
.compressed_resp_i (x_compressed_resp),
|
||||||
|
.compressed_valid_o(x_compressed_valid),
|
||||||
|
.compressed_req_o (x_compressed_req)
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_ex_id;
|
logic [CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_ex_id;
|
||||||
|
@ -693,16 +736,39 @@ module cva6
|
||||||
assign ex_ex_ex_id[FPU_WB] = fpu_exception_ex_id;
|
assign ex_ex_ex_id[FPU_WB] = fpu_exception_ex_id;
|
||||||
assign wt_valid_ex_id[FPU_WB] = fpu_valid_ex_id;
|
assign wt_valid_ex_id[FPU_WB] = fpu_valid_ex_id;
|
||||||
|
|
||||||
|
always_comb begin : gen_cvxif_input_assignement
|
||||||
|
x_compressed_ready = cvxif_resp_i.compressed_ready;
|
||||||
|
x_compressed_resp = cvxif_resp_i.compressed_resp;
|
||||||
|
x_issue_ready = cvxif_resp_i.issue_ready;
|
||||||
|
x_issue_resp = cvxif_resp_i.issue_resp;
|
||||||
|
x_register_ready = cvxif_resp_i.register_ready;
|
||||||
|
x_result_valid = cvxif_resp_i.result_valid;
|
||||||
|
x_result = cvxif_resp_i.result;
|
||||||
|
end
|
||||||
if (CVA6Cfg.CvxifEn) begin
|
if (CVA6Cfg.CvxifEn) begin
|
||||||
|
always_comb begin : gen_cvxif_output_assignement
|
||||||
|
cvxif_req.compressed_valid = x_compressed_valid;
|
||||||
|
cvxif_req.compressed_req = x_compressed_req;
|
||||||
|
cvxif_req.issue_valid = x_issue_valid;
|
||||||
|
cvxif_req.issue_req = x_issue_req;
|
||||||
|
cvxif_req.register_valid = x_register_valid;
|
||||||
|
cvxif_req.register = x_register;
|
||||||
|
cvxif_req.commit_valid = x_commit_valid;
|
||||||
|
cvxif_req.commit = x_commit;
|
||||||
|
cvxif_req.result_ready = x_result_ready;
|
||||||
|
end
|
||||||
assign trans_id_ex_id[X_WB] = x_trans_id_ex_id;
|
assign trans_id_ex_id[X_WB] = x_trans_id_ex_id;
|
||||||
assign wbdata_ex_id[X_WB] = x_result_ex_id;
|
assign wbdata_ex_id[X_WB] = x_result_ex_id;
|
||||||
assign ex_ex_ex_id[X_WB] = x_exception_ex_id;
|
assign ex_ex_ex_id[X_WB] = x_exception_ex_id;
|
||||||
assign wt_valid_ex_id[X_WB] = x_valid_ex_id;
|
assign wt_valid_ex_id[X_WB] = x_valid_ex_id;
|
||||||
end else if (CVA6Cfg.EnableAccelerator) begin
|
end else if (CVA6Cfg.EnableAccelerator) begin
|
||||||
|
assign cvxif_req = '0;
|
||||||
assign trans_id_ex_id[ACC_WB] = acc_trans_id_ex_id;
|
assign trans_id_ex_id[ACC_WB] = acc_trans_id_ex_id;
|
||||||
assign wbdata_ex_id[ACC_WB] = acc_result_ex_id;
|
assign wbdata_ex_id[ACC_WB] = acc_result_ex_id;
|
||||||
assign ex_ex_ex_id[ACC_WB] = acc_exception_ex_id;
|
assign ex_ex_ex_id[ACC_WB] = acc_exception_ex_id;
|
||||||
assign wt_valid_ex_id[ACC_WB] = acc_valid_ex_id;
|
assign wt_valid_ex_id[ACC_WB] = acc_valid_ex_id;
|
||||||
|
end else begin
|
||||||
|
assign cvxif_req = '0;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (CVA6Cfg.CvxifEn && CVA6Cfg.EnableAccelerator) begin : gen_err_xif_and_acc
|
if (CVA6Cfg.CvxifEn && CVA6Cfg.EnableAccelerator) begin : gen_err_xif_and_acc
|
||||||
|
@ -718,63 +784,79 @@ module cva6
|
||||||
.branchpredict_sbe_t(branchpredict_sbe_t),
|
.branchpredict_sbe_t(branchpredict_sbe_t),
|
||||||
.exception_t(exception_t),
|
.exception_t(exception_t),
|
||||||
.fu_data_t(fu_data_t),
|
.fu_data_t(fu_data_t),
|
||||||
.scoreboard_entry_t(scoreboard_entry_t)
|
.scoreboard_entry_t(scoreboard_entry_t),
|
||||||
|
.x_issue_req_t(x_issue_req_t),
|
||||||
|
.x_issue_resp_t(x_issue_resp_t),
|
||||||
|
.x_register_t(x_register_t),
|
||||||
|
.x_commit_t(x_commit_t)
|
||||||
) issue_stage_i (
|
) issue_stage_i (
|
||||||
.clk_i,
|
.clk_i,
|
||||||
.rst_ni,
|
.rst_ni,
|
||||||
.sb_full_o (sb_full),
|
.sb_full_o (sb_full),
|
||||||
.flush_unissued_instr_i(flush_unissued_instr_ctrl_id),
|
.flush_unissued_instr_i (flush_unissued_instr_ctrl_id),
|
||||||
.flush_i (flush_ctrl_id),
|
.flush_i (flush_ctrl_id),
|
||||||
.stall_i (stall_acc_id),
|
.stall_i (stall_acc_id),
|
||||||
// ID Stage
|
// ID Stage
|
||||||
.decoded_instr_i (issue_entry_id_issue),
|
.decoded_instr_i (issue_entry_id_issue),
|
||||||
.orig_instr_i (orig_instr_id_issue),
|
.orig_instr_i (orig_instr_id_issue),
|
||||||
.decoded_instr_valid_i (issue_entry_valid_id_issue),
|
.decoded_instr_valid_i (issue_entry_valid_id_issue),
|
||||||
.is_ctrl_flow_i (is_ctrl_fow_id_issue),
|
.is_ctrl_flow_i (is_ctrl_fow_id_issue),
|
||||||
.decoded_instr_ack_o (issue_instr_issue_id),
|
.decoded_instr_ack_o (issue_instr_issue_id),
|
||||||
// Functional Units
|
// Functional Units
|
||||||
.rs1_forwarding_o (rs1_forwarding_id_ex),
|
.rs1_forwarding_o (rs1_forwarding_id_ex),
|
||||||
.rs2_forwarding_o (rs2_forwarding_id_ex),
|
.rs2_forwarding_o (rs2_forwarding_id_ex),
|
||||||
.fu_data_o (fu_data_id_ex),
|
.fu_data_o (fu_data_id_ex),
|
||||||
.pc_o (pc_id_ex),
|
.pc_o (pc_id_ex),
|
||||||
.is_compressed_instr_o (is_compressed_instr_id_ex),
|
.is_compressed_instr_o (is_compressed_instr_id_ex),
|
||||||
.tinst_o (tinst_ex),
|
.tinst_o (tinst_ex),
|
||||||
// fixed latency unit ready
|
// fixed latency unit ready
|
||||||
.flu_ready_i (flu_ready_ex_id),
|
.flu_ready_i (flu_ready_ex_id),
|
||||||
// ALU
|
// ALU
|
||||||
.alu_valid_o (alu_valid_id_ex),
|
.alu_valid_o (alu_valid_id_ex),
|
||||||
// Branches and Jumps
|
// Branches and Jumps
|
||||||
.branch_valid_o (branch_valid_id_ex), // branch is valid
|
.branch_valid_o (branch_valid_id_ex), // branch is valid
|
||||||
.branch_predict_o (branch_predict_id_ex), // branch predict to ex
|
.branch_predict_o (branch_predict_id_ex), // branch predict to ex
|
||||||
.resolve_branch_i (resolve_branch_ex_id), // in order to resolve the branch
|
.resolve_branch_i (resolve_branch_ex_id), // in order to resolve the branch
|
||||||
// LSU
|
// LSU
|
||||||
.lsu_ready_i (lsu_ready_ex_id),
|
.lsu_ready_i (lsu_ready_ex_id),
|
||||||
.lsu_valid_o (lsu_valid_id_ex),
|
.lsu_valid_o (lsu_valid_id_ex),
|
||||||
// Multiplier
|
// Multiplier
|
||||||
.mult_valid_o (mult_valid_id_ex),
|
.mult_valid_o (mult_valid_id_ex),
|
||||||
// FPU
|
// FPU
|
||||||
.fpu_ready_i (fpu_ready_ex_id),
|
.fpu_ready_i (fpu_ready_ex_id),
|
||||||
.fpu_valid_o (fpu_valid_id_ex),
|
.fpu_valid_o (fpu_valid_id_ex),
|
||||||
.fpu_fmt_o (fpu_fmt_id_ex),
|
.fpu_fmt_o (fpu_fmt_id_ex),
|
||||||
.fpu_rm_o (fpu_rm_id_ex),
|
.fpu_rm_o (fpu_rm_id_ex),
|
||||||
// ALU2
|
// ALU2
|
||||||
.alu2_valid_o (alu2_valid_id_ex),
|
.alu2_valid_o (alu2_valid_id_ex),
|
||||||
// CSR
|
// CSR
|
||||||
.csr_valid_o (csr_valid_id_ex),
|
.csr_valid_o (csr_valid_id_ex),
|
||||||
// CVXIF
|
// CVXIF
|
||||||
.x_issue_valid_o (x_issue_valid_id_ex),
|
.xfu_valid_o (x_issue_valid_id_ex),
|
||||||
.x_issue_ready_i (x_issue_ready_ex_id),
|
.xfu_ready_i (x_issue_ready_ex_id),
|
||||||
.x_off_instr_o (x_off_instr_id_ex),
|
.x_off_instr_o (x_off_instr_id_ex),
|
||||||
|
.hart_id_i (hart_id_i),
|
||||||
|
.x_issue_ready_i (x_issue_ready),
|
||||||
|
.x_issue_resp_i (x_issue_resp),
|
||||||
|
.x_issue_valid_o (x_issue_valid),
|
||||||
|
.x_issue_req_o (x_issue_req),
|
||||||
|
.x_register_ready_i (x_register_ready),
|
||||||
|
.x_register_valid_o (x_register_valid),
|
||||||
|
.x_register_o (x_register),
|
||||||
|
.x_commit_valid_o (x_commit_valid),
|
||||||
|
.x_commit_o (x_commit),
|
||||||
|
.x_transaction_rejected_o(x_transaction_rejected),
|
||||||
// Accelerator
|
// Accelerator
|
||||||
.issue_instr_o (issue_instr_id_acc),
|
.issue_instr_o (issue_instr_id_acc),
|
||||||
.issue_instr_hs_o (issue_instr_hs_id_acc),
|
.issue_instr_hs_o (issue_instr_hs_id_acc),
|
||||||
// Commit
|
// Commit
|
||||||
.resolved_branch_i (resolved_branch),
|
.resolved_branch_i (resolved_branch),
|
||||||
.trans_id_i (trans_id_ex_id),
|
.trans_id_i (trans_id_ex_id),
|
||||||
.wbdata_i (wbdata_ex_id),
|
.wbdata_i (wbdata_ex_id),
|
||||||
.ex_ex_i (ex_ex_ex_id),
|
.ex_ex_i (ex_ex_ex_id),
|
||||||
.wt_valid_i (wt_valid_ex_id),
|
.wt_valid_i (wt_valid_ex_id),
|
||||||
.x_we_i (x_we_ex_id),
|
.x_we_i (x_we_ex_id),
|
||||||
|
.x_rd_i (x_rd_ex_id),
|
||||||
|
|
||||||
.waddr_i (waddr_commit_id),
|
.waddr_i (waddr_commit_id),
|
||||||
.wdata_i (wdata_commit_id),
|
.wdata_i (wdata_commit_id),
|
||||||
|
@ -806,7 +888,8 @@ module cva6
|
||||||
.icache_arsp_t(icache_arsp_t),
|
.icache_arsp_t(icache_arsp_t),
|
||||||
.icache_dreq_t(icache_dreq_t),
|
.icache_dreq_t(icache_dreq_t),
|
||||||
.icache_drsp_t(icache_drsp_t),
|
.icache_drsp_t(icache_drsp_t),
|
||||||
.lsu_ctrl_t(lsu_ctrl_t)
|
.lsu_ctrl_t(lsu_ctrl_t),
|
||||||
|
.x_result_t(x_result_t)
|
||||||
) ex_stage_i (
|
) ex_stage_i (
|
||||||
.clk_i(clk_i),
|
.clk_i(clk_i),
|
||||||
.rst_ni(rst_ni),
|
.rst_ni(rst_ni),
|
||||||
|
@ -877,13 +960,16 @@ module cva6
|
||||||
.x_valid_i (x_issue_valid_id_ex),
|
.x_valid_i (x_issue_valid_id_ex),
|
||||||
.x_ready_o (x_issue_ready_ex_id),
|
.x_ready_o (x_issue_ready_ex_id),
|
||||||
.x_off_instr_i (x_off_instr_id_ex),
|
.x_off_instr_i (x_off_instr_id_ex),
|
||||||
|
.x_transaction_rejected_i(x_transaction_rejected),
|
||||||
.x_trans_id_o (x_trans_id_ex_id),
|
.x_trans_id_o (x_trans_id_ex_id),
|
||||||
.x_exception_o (x_exception_ex_id),
|
.x_exception_o (x_exception_ex_id),
|
||||||
.x_result_o (x_result_ex_id),
|
.x_result_o (x_result_ex_id),
|
||||||
.x_valid_o (x_valid_ex_id),
|
.x_valid_o (x_valid_ex_id),
|
||||||
.x_we_o (x_we_ex_id),
|
.x_we_o (x_we_ex_id),
|
||||||
.cvxif_req_o (cvxif_req),
|
.x_rd_o (x_rd_ex_id),
|
||||||
.cvxif_resp_i (cvxif_resp),
|
.x_result_valid_i (x_result_valid),
|
||||||
|
.x_result_i (x_result),
|
||||||
|
.x_result_ready_o (x_result_ready),
|
||||||
// Accelerator
|
// Accelerator
|
||||||
.acc_valid_i (acc_valid_acc_ex),
|
.acc_valid_i (acc_valid_acc_ex),
|
||||||
// Performance counters
|
// Performance counters
|
||||||
|
@ -1432,7 +1518,6 @@ module cva6
|
||||||
|
|
||||||
// Feed through cvxif
|
// Feed through cvxif
|
||||||
assign cvxif_req_o = cvxif_req;
|
assign cvxif_req_o = cvxif_req;
|
||||||
assign cvxif_resp = cvxif_resp_i;
|
|
||||||
end : gen_no_accelerator
|
end : gen_no_accelerator
|
||||||
|
|
||||||
// -------------------
|
// -------------------
|
||||||
|
|
74
core/cvxif_compressed_if_driver.sv
Normal file
74
core/cvxif_compressed_if_driver.sv
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright 2024 Thales DIS France SAS
|
||||||
|
//
|
||||||
|
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||||
|
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||||
|
//
|
||||||
|
// Original Author: Guillaume Chauvon
|
||||||
|
|
||||||
|
module cvxif_compressed_if_driver #(
|
||||||
|
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
||||||
|
parameter type x_compressed_req_t = logic,
|
||||||
|
parameter type x_compressed_resp_t = logic
|
||||||
|
) (
|
||||||
|
// Subsystem Clock - SUBSYSTEM
|
||||||
|
input logic clk_i,
|
||||||
|
// Asynchronous reset active low - SUBSYSTEM
|
||||||
|
input logic rst_ni,
|
||||||
|
// CVA6 Hart id
|
||||||
|
input logic [CVA6Cfg.XLEN-1:0] hart_id_i,
|
||||||
|
|
||||||
|
input logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_i,
|
||||||
|
input logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_i,
|
||||||
|
input logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction_i,
|
||||||
|
|
||||||
|
output logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_o,
|
||||||
|
output logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_o,
|
||||||
|
output logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction_o,
|
||||||
|
input logic stall_i,
|
||||||
|
output logic stall_o,
|
||||||
|
// CVXIF Compressed interface
|
||||||
|
input logic compressed_ready_i,
|
||||||
|
input x_compressed_resp_t compressed_resp_i,
|
||||||
|
output logic compressed_valid_o,
|
||||||
|
output x_compressed_req_t compressed_req_o
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
is_illegal_o = is_illegal_i;
|
||||||
|
instruction_o = instruction_i;
|
||||||
|
is_compressed_o = is_compressed_i;
|
||||||
|
compressed_valid_o = 1'b0;
|
||||||
|
compressed_req_o.instr = '0;
|
||||||
|
compressed_req_o.hartid = hart_id_i;
|
||||||
|
stall_o = stall_i;
|
||||||
|
if (is_illegal_i[0]) begin
|
||||||
|
compressed_valid_o = is_illegal_i[0];
|
||||||
|
compressed_req_o.instr = instruction_i[0][15:0];
|
||||||
|
is_illegal_o[0] = ~compressed_resp_i.accept;
|
||||||
|
instruction_o[0] = compressed_resp_i.accept ? compressed_resp_i.instr : instruction_i[0];
|
||||||
|
is_compressed_o[0] = compressed_resp_i.accept ? 1'b0 : is_compressed_i[0];
|
||||||
|
if (~stall_i) begin
|
||||||
|
// Propagate stall from macro decoder or wait for compressed ready if compressed transaction is happening.
|
||||||
|
// Stall if both instruction are illegal
|
||||||
|
if (CVA6Cfg.SuperscalarEn) begin
|
||||||
|
stall_o = is_illegal_i[1];
|
||||||
|
end else begin
|
||||||
|
stall_o = (compressed_valid_o && ~compressed_ready_i);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if (CVA6Cfg.SuperscalarEn) begin
|
||||||
|
if (~is_illegal_i[0] && is_illegal_i[1]) begin // 2nd instruction is illegal
|
||||||
|
compressed_valid_o = is_illegal_i[1];
|
||||||
|
compressed_req_o.instr = instruction_i[1][15:0];
|
||||||
|
is_illegal_o[1] = ~compressed_resp_i.accept;
|
||||||
|
instruction_o[1] = compressed_resp_i.accept ? compressed_resp_i.instr : instruction_i[1];
|
||||||
|
is_compressed_o[1] = compressed_resp_i.accept ? 1'b0 : is_compressed_i[1];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
50
core/cvxif_example/compressed_instr_decoder.sv
Normal file
50
core/cvxif_example/compressed_instr_decoder.sv
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// Copyright 2024 Thales DIS France SAS
|
||||||
|
//
|
||||||
|
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||||
|
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||||
|
//
|
||||||
|
// Original Author: Guillaume Chauvon
|
||||||
|
|
||||||
|
module compressed_instr_decoder
|
||||||
|
import cvxif_instr_pkg::*;
|
||||||
|
#(
|
||||||
|
parameter int NbInstr = 1,
|
||||||
|
parameter copro_compressed_resp_t CoproInstr [NbInstr] = {0},
|
||||||
|
parameter type x_compressed_req_t = logic,
|
||||||
|
parameter type x_compressed_resp_t = logic
|
||||||
|
) (
|
||||||
|
input logic clk_i,
|
||||||
|
input logic rst_ni,
|
||||||
|
input logic compressed_valid_i,
|
||||||
|
input x_compressed_req_t compressed_req_i,
|
||||||
|
output logic compressed_ready_o,
|
||||||
|
output x_compressed_resp_t compressed_resp_o
|
||||||
|
);
|
||||||
|
|
||||||
|
logic [NbInstr-1:0] sel;
|
||||||
|
|
||||||
|
for (genvar i = 0; i < NbInstr; i++) begin : gen_predecoder_selector
|
||||||
|
assign sel[i] = ((CoproInstr[i].mask & compressed_req_i.instr) == CoproInstr[i].instr);
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
compressed_ready_o = '1;
|
||||||
|
compressed_resp_o.accept = '0;
|
||||||
|
compressed_resp_o.instr = '0;
|
||||||
|
for (int unsigned i = 0; i < NbInstr; i++) begin
|
||||||
|
if (sel[i] && compressed_valid_i) begin
|
||||||
|
compressed_resp_o.accept = CoproInstr[i].resp.accept;
|
||||||
|
compressed_resp_o.instr = CoproInstr[i].resp.instr;
|
||||||
|
// Remap rs1 and rs2
|
||||||
|
compressed_resp_o.instr[19:15] = compressed_req_i.instr[11:7];
|
||||||
|
compressed_resp_o.instr[24:20] = compressed_req_i.instr[6:2];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert property (@(posedge clk_i) $onehot0(sel))
|
||||||
|
else $warning("This offloaded instruction is valid for multiple coprocessor instructions !");
|
||||||
|
|
||||||
|
endmodule
|
135
core/cvxif_example/copro_alu.sv
Normal file
135
core/cvxif_example/copro_alu.sv
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
// Copyright 2024 Thales DIS France SAS
|
||||||
|
//
|
||||||
|
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||||
|
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||||
|
//
|
||||||
|
// Original Author: Guillaume Chauvon
|
||||||
|
|
||||||
|
module copro_alu
|
||||||
|
import cvxif_instr_pkg::*;
|
||||||
|
#(
|
||||||
|
parameter int unsigned NrRgprPorts = 2,
|
||||||
|
parameter type hartid_t = logic,
|
||||||
|
parameter type id_t = logic,
|
||||||
|
parameter type registers_t = logic
|
||||||
|
|
||||||
|
) (
|
||||||
|
input logic clk_i,
|
||||||
|
input logic rst_ni,
|
||||||
|
input registers_t registers_i,
|
||||||
|
input opcode_t opcode_i,
|
||||||
|
input hartid_t hartid_i,
|
||||||
|
input id_t id_i,
|
||||||
|
input logic [ 4:0] rd_i,
|
||||||
|
output logic [31:0] result_o, // TODO parametrize to 64 bits
|
||||||
|
output hartid_t hartid_o,
|
||||||
|
output id_t id_o,
|
||||||
|
output logic [ 4:0] rd_o,
|
||||||
|
output logic valid_o,
|
||||||
|
output logic we_o
|
||||||
|
);
|
||||||
|
|
||||||
|
logic [31:0] result_n, result_q;
|
||||||
|
hartid_t hartid_n, hartid_q;
|
||||||
|
id_t id_n, id_q;
|
||||||
|
logic valid_n, valid_q;
|
||||||
|
logic [4:0] rd_n, rd_q;
|
||||||
|
logic we_n, we_q;
|
||||||
|
|
||||||
|
assign result_o = result_q;
|
||||||
|
assign hartid_o = hartid_q;
|
||||||
|
assign id_o = id_q;
|
||||||
|
assign valid_o = valid_q;
|
||||||
|
assign rd_o = rd_q;
|
||||||
|
assign we_o = we_q;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
case (opcode_i)
|
||||||
|
cvxif_instr_pkg::NOP: begin
|
||||||
|
result_n = '0;
|
||||||
|
hartid_n = hartid_i;
|
||||||
|
id_n = id_i;
|
||||||
|
valid_n = 1'b1;
|
||||||
|
rd_n = '0;
|
||||||
|
we_n = '0;
|
||||||
|
end
|
||||||
|
cvxif_instr_pkg::ADD: begin
|
||||||
|
result_n = registers_i[1] + registers_i[0];
|
||||||
|
hartid_n = hartid_i;
|
||||||
|
id_n = id_i;
|
||||||
|
valid_n = 1'b1;
|
||||||
|
rd_n = rd_i;
|
||||||
|
we_n = 1'b1;
|
||||||
|
end
|
||||||
|
cvxif_instr_pkg::DOUBLE_RS1: begin
|
||||||
|
result_n = registers_i[0] + registers_i[0];
|
||||||
|
hartid_n = hartid_i;
|
||||||
|
id_n = id_i;
|
||||||
|
valid_n = 1'b1;
|
||||||
|
rd_n = rd_i;
|
||||||
|
we_n = 1'b1;
|
||||||
|
end
|
||||||
|
cvxif_instr_pkg::DOUBLE_RS2: begin
|
||||||
|
result_n = registers_i[1] + registers_i[1];
|
||||||
|
hartid_n = hartid_i;
|
||||||
|
id_n = id_i;
|
||||||
|
valid_n = 1'b1;
|
||||||
|
rd_n = rd_i;
|
||||||
|
we_n = 1'b1;
|
||||||
|
end
|
||||||
|
cvxif_instr_pkg::ADD_MULTI: begin
|
||||||
|
result_n = registers_i[1] + registers_i[0];
|
||||||
|
hartid_n = hartid_i;
|
||||||
|
id_n = id_i;
|
||||||
|
valid_n = 1'b1;
|
||||||
|
rd_n = rd_i;
|
||||||
|
we_n = 1'b1;
|
||||||
|
end
|
||||||
|
cvxif_instr_pkg::ADD_RS3_R4: begin
|
||||||
|
result_n = NrRgprPorts == 3 ? registers_i[2] + registers_i[1] + registers_i[0] : registers_i[1] + registers_i[0];
|
||||||
|
hartid_n = hartid_i;
|
||||||
|
id_n = id_i;
|
||||||
|
valid_n = 1'b1;
|
||||||
|
rd_n = rd_i;
|
||||||
|
we_n = 1'b1;
|
||||||
|
end
|
||||||
|
cvxif_instr_pkg::ADD_RS3_R: begin
|
||||||
|
result_n = NrRgprPorts == 3 ? registers_i[2] + registers_i[1] + registers_i[0] : registers_i[1] + registers_i[0];
|
||||||
|
hartid_n = hartid_i;
|
||||||
|
id_n = id_i;
|
||||||
|
valid_n = 1'b1;
|
||||||
|
rd_n = 5'b01010;
|
||||||
|
we_n = 1'b1;
|
||||||
|
end
|
||||||
|
default: begin
|
||||||
|
result_n = '0;
|
||||||
|
hartid_n = '0;
|
||||||
|
id_n = '0;
|
||||||
|
valid_n = '0;
|
||||||
|
rd_n = '0;
|
||||||
|
we_n = '0;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge clk_i, negedge rst_ni) begin
|
||||||
|
if (~rst_ni) begin
|
||||||
|
result_q <= '0;
|
||||||
|
hartid_q <= '0;
|
||||||
|
id_q <= '0;
|
||||||
|
valid_q <= '0;
|
||||||
|
rd_q <= '0;
|
||||||
|
we_q <= '0;
|
||||||
|
end else begin
|
||||||
|
result_q <= result_n;
|
||||||
|
hartid_q <= hartid_n;
|
||||||
|
id_q <= id_n;
|
||||||
|
valid_q <= valid_n;
|
||||||
|
rd_q <= rd_n;
|
||||||
|
we_q <= we_n;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -1,19 +1,31 @@
|
||||||
// Copyright 2021 Thales DIS design services SAS
|
// Copyright 2024 Thales DIS France SAS
|
||||||
//
|
//
|
||||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||||
//
|
//
|
||||||
// Original Author: Guillaume Chauvon (guillaume.chauvon@thalesgroup.com)
|
// Original Author: Guillaume Chauvon
|
||||||
// Example coprocessor adds rs1,rs2(,rs3) together and gives back the result to the CPU via the CoreV-X-Interface.
|
|
||||||
// Coprocessor delays the sending of the result depending on result least significant bits.
|
|
||||||
|
|
||||||
module cvxif_example_coprocessor
|
module cvxif_example_coprocessor
|
||||||
import cvxif_pkg::*;
|
|
||||||
import cvxif_instr_pkg::*;
|
import cvxif_instr_pkg::*;
|
||||||
#(
|
#(
|
||||||
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty
|
// CVXIF Types
|
||||||
|
parameter int unsigned NrRgprPorts = 2,
|
||||||
|
parameter type readregflags_t = logic,
|
||||||
|
parameter type writeregflags_t = logic,
|
||||||
|
parameter type id_t = logic,
|
||||||
|
parameter type hartid_t = logic,
|
||||||
|
parameter type x_compressed_req_t = logic,
|
||||||
|
parameter type x_compressed_resp_t = logic,
|
||||||
|
parameter type x_issue_req_t = logic,
|
||||||
|
parameter type x_issue_resp_t = logic,
|
||||||
|
parameter type x_register_t = logic,
|
||||||
|
parameter type x_commit_t = logic,
|
||||||
|
parameter type x_result_t = logic,
|
||||||
|
parameter type cvxif_req_t = logic,
|
||||||
|
parameter type cvxif_resp_t = logic,
|
||||||
|
localparam type registers_t = logic [NrRgprPorts-1:0][31:0]
|
||||||
) (
|
) (
|
||||||
input logic clk_i, // Clock
|
input logic clk_i, // Clock
|
||||||
input logic rst_ni, // Asynchronous reset active low
|
input logic rst_ni, // Asynchronous reset active low
|
||||||
|
@ -21,138 +33,115 @@ module cvxif_example_coprocessor
|
||||||
output cvxif_resp_t cvxif_resp_o
|
output cvxif_resp_t cvxif_resp_o
|
||||||
);
|
);
|
||||||
|
|
||||||
//Compressed interface
|
// Compressed interface signals
|
||||||
logic x_compressed_valid_i;
|
x_compressed_req_t compressed_req;
|
||||||
logic x_compressed_ready_o;
|
x_compressed_resp_t compressed_resp;
|
||||||
x_compressed_req_t x_compressed_req_i;
|
logic compressed_valid, compressed_ready;
|
||||||
x_compressed_resp_t x_compressed_resp_o;
|
// Issue interface signals
|
||||||
//Issue interface
|
x_issue_req_t issue_req;
|
||||||
logic x_issue_valid_i;
|
x_issue_resp_t issue_resp;
|
||||||
logic x_issue_ready_o;
|
logic issue_valid, issue_ready;
|
||||||
x_issue_req_t x_issue_req_i;
|
|
||||||
x_issue_resp_t x_issue_resp_o;
|
|
||||||
//Commit interface
|
|
||||||
logic x_commit_valid_i;
|
|
||||||
x_commit_t x_commit_i;
|
|
||||||
//Memory interface
|
|
||||||
logic x_mem_valid_o;
|
|
||||||
logic x_mem_ready_i;
|
|
||||||
x_mem_req_t x_mem_req_o;
|
|
||||||
x_mem_resp_t x_mem_resp_i;
|
|
||||||
//Memory result interface
|
|
||||||
logic x_mem_result_valid_i;
|
|
||||||
x_mem_result_t x_mem_result_i;
|
|
||||||
//Result interface
|
|
||||||
logic x_result_valid_o;
|
|
||||||
logic x_result_ready_i;
|
|
||||||
x_result_t x_result_o;
|
|
||||||
|
|
||||||
assign x_compressed_valid_i = cvxif_req_i.x_compressed_valid;
|
// Register interface signals
|
||||||
assign x_compressed_req_i = cvxif_req_i.x_compressed_req;
|
x_register_t register;
|
||||||
assign x_issue_valid_i = cvxif_req_i.x_issue_valid;
|
logic register_valid;
|
||||||
assign x_issue_req_i = cvxif_req_i.x_issue_req;
|
|
||||||
assign x_commit_valid_i = cvxif_req_i.x_commit_valid;
|
|
||||||
assign x_commit_i = cvxif_req_i.x_commit;
|
|
||||||
assign x_mem_ready_i = cvxif_req_i.x_mem_ready;
|
|
||||||
assign x_mem_resp_i = cvxif_req_i.x_mem_resp;
|
|
||||||
assign x_mem_result_valid_i = cvxif_req_i.x_mem_result_valid;
|
|
||||||
assign x_mem_result_i = cvxif_req_i.x_mem_result;
|
|
||||||
assign x_result_ready_i = cvxif_req_i.x_result_ready;
|
|
||||||
|
|
||||||
assign cvxif_resp_o.x_compressed_ready = x_compressed_ready_o;
|
// Decoder and alu signals
|
||||||
assign cvxif_resp_o.x_compressed_resp = x_compressed_resp_o;
|
registers_t registers;
|
||||||
assign cvxif_resp_o.x_issue_ready = x_issue_ready_o;
|
opcode_t opcode;
|
||||||
assign cvxif_resp_o.x_issue_resp = x_issue_resp_o;
|
hartid_t issue_hartid, hartid;
|
||||||
assign cvxif_resp_o.x_mem_valid = x_mem_valid_o;
|
id_t issue_id, id;
|
||||||
assign cvxif_resp_o.x_mem_req = x_mem_req_o;
|
logic [4:0] issue_rd, rd;
|
||||||
assign cvxif_resp_o.x_result_valid = x_result_valid_o;
|
logic [31:0] result;
|
||||||
assign cvxif_resp_o.x_result = x_result_o;
|
logic we;
|
||||||
|
|
||||||
//Compressed interface
|
// Issue and Register interface
|
||||||
assign x_compressed_ready_o = '0;
|
// Mandatory when X_ISSUE_REGISTER_SPLIT = 0
|
||||||
assign x_compressed_resp_o.instr = '0;
|
assign cvxif_resp_o.compressed_ready = compressed_ready;
|
||||||
assign x_compressed_resp_o.accept = '0;
|
assign cvxif_resp_o.compressed_resp = compressed_resp;
|
||||||
|
assign cvxif_resp_o.issue_ready = issue_ready;
|
||||||
|
assign cvxif_resp_o.issue_resp = issue_resp;
|
||||||
|
assign cvxif_resp_o.register_ready = cvxif_resp_o.issue_ready;
|
||||||
|
|
||||||
|
assign compressed_req = cvxif_req_i.compressed_req;
|
||||||
|
assign compressed_valid = cvxif_req_i.compressed_valid;
|
||||||
|
assign issue_req = cvxif_req_i.issue_req;
|
||||||
|
assign issue_valid = cvxif_req_i.issue_valid;
|
||||||
|
assign register = cvxif_req_i.register;
|
||||||
|
assign register_valid = cvxif_req_i.register_valid;
|
||||||
|
|
||||||
|
compressed_instr_decoder #(
|
||||||
|
.NbInstr(cvxif_instr_pkg::NbCompInstr),
|
||||||
|
.CoproInstr(cvxif_instr_pkg::CoproCompInstr),
|
||||||
|
.x_compressed_req_t(x_compressed_req_t),
|
||||||
|
.x_compressed_resp_t(x_compressed_resp_t)
|
||||||
|
) compressed_instr_decoder_i (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_ni (rst_ni),
|
||||||
|
.compressed_valid_i(compressed_valid),
|
||||||
|
.compressed_req_i (compressed_req),
|
||||||
|
.compressed_ready_o(compressed_ready),
|
||||||
|
.compressed_resp_o (compressed_resp)
|
||||||
|
);
|
||||||
|
|
||||||
instr_decoder #(
|
instr_decoder #(
|
||||||
.NbInstr (cvxif_instr_pkg::NbInstr),
|
.NbInstr (cvxif_instr_pkg::NbInstr),
|
||||||
.CoproInstr(cvxif_instr_pkg::CoproInstr)
|
.CoproInstr(cvxif_instr_pkg::CoproInstr),
|
||||||
|
.NrRgprPorts(NrRgprPorts),
|
||||||
|
.hartid_t (hartid_t),
|
||||||
|
.id_t (id_t),
|
||||||
|
.x_issue_req_t (x_issue_req_t),
|
||||||
|
.x_issue_resp_t (x_issue_resp_t),
|
||||||
|
.x_register_t (x_register_t),
|
||||||
|
.registers_t (registers_t)
|
||||||
) instr_decoder_i (
|
) instr_decoder_i (
|
||||||
.clk_i (clk_i),
|
.clk_i (clk_i),
|
||||||
.x_issue_req_i (x_issue_req_i),
|
.rst_ni (rst_ni),
|
||||||
.x_issue_resp_o(x_issue_resp_o)
|
.issue_valid_i (issue_valid),
|
||||||
|
.issue_req_i (issue_req),
|
||||||
|
.issue_ready_o (issue_ready),
|
||||||
|
.issue_resp_o (issue_resp),
|
||||||
|
.register_valid_i(register_valid),
|
||||||
|
.register_i (register),
|
||||||
|
.registers_o (registers),
|
||||||
|
.opcode_o (opcode),
|
||||||
|
.hartid_o (issue_hartid),
|
||||||
|
.id_o (issue_id),
|
||||||
|
.rd_o (issue_rd)
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef struct packed {
|
logic alu_valid;
|
||||||
x_issue_req_t req;
|
// Result interface
|
||||||
x_issue_resp_t resp;
|
copro_alu #(
|
||||||
} x_issue_t;
|
.NrRgprPorts(NrRgprPorts),
|
||||||
|
.hartid_t(hartid_t),
|
||||||
logic fifo_full, fifo_empty;
|
.id_t(id_t),
|
||||||
logic x_issue_ready_q;
|
.registers_t(registers_t)
|
||||||
logic instr_push, instr_pop;
|
) i_copro_alu (
|
||||||
x_issue_t req_i;
|
.clk_i (clk_i),
|
||||||
x_issue_t req_o;
|
.rst_ni (rst_ni),
|
||||||
|
.registers_i(registers),
|
||||||
|
.opcode_i (opcode),
|
||||||
|
.hartid_i (issue_hartid),
|
||||||
assign instr_push = x_issue_resp_o.accept ? 1 : 0;
|
.id_i (issue_id),
|
||||||
assign instr_pop = (x_commit_i.x_commit_kill && x_commit_valid_i) || x_result_valid_o;
|
.rd_i (issue_rd),
|
||||||
assign x_issue_ready_q = ~fifo_full; // if something is in the fifo, the instruction is being processed
|
.hartid_o (hartid),
|
||||||
// so we can't receive anything else
|
.id_o (id),
|
||||||
assign req_i.req = x_issue_req_i;
|
.result_o (result),
|
||||||
assign req_i.resp = x_issue_resp_o;
|
.valid_o (alu_valid),
|
||||||
|
.rd_o (rd),
|
||||||
always_ff @(posedge clk_i or negedge rst_ni) begin : regs
|
.we_o (we)
|
||||||
if (!rst_ni) begin
|
|
||||||
x_issue_ready_o <= 1;
|
|
||||||
end else begin
|
|
||||||
x_issue_ready_o <= x_issue_ready_q;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
cva6_fifo_v3 #(
|
|
||||||
.FALL_THROUGH(1), //data_o ready and pop in the same cycle
|
|
||||||
.DATA_WIDTH (64),
|
|
||||||
.DEPTH (8),
|
|
||||||
.dtype (x_issue_t),
|
|
||||||
.FPGA_EN (CVA6Cfg.FpgaEn)
|
|
||||||
) fifo_commit_i (
|
|
||||||
.clk_i (clk_i),
|
|
||||||
.rst_ni (rst_ni),
|
|
||||||
.flush_i (1'b0),
|
|
||||||
.testmode_i(1'b0),
|
|
||||||
.full_o (fifo_full),
|
|
||||||
.empty_o (fifo_empty),
|
|
||||||
.usage_o (),
|
|
||||||
.data_i (req_i),
|
|
||||||
.push_i (instr_push),
|
|
||||||
.data_o (req_o),
|
|
||||||
.pop_i (instr_pop)
|
|
||||||
);
|
|
||||||
|
|
||||||
logic [3:0] c;
|
|
||||||
counter #(
|
|
||||||
.WIDTH(4)
|
|
||||||
) counter_i (
|
|
||||||
.clk_i (clk_i),
|
|
||||||
.rst_ni (rst_ni),
|
|
||||||
.clear_i (~x_commit_i.x_commit_kill && x_commit_valid_i),
|
|
||||||
.en_i (1'b1),
|
|
||||||
.load_i (),
|
|
||||||
.down_i (),
|
|
||||||
.d_i (),
|
|
||||||
.q_o (c),
|
|
||||||
.overflow_o()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
x_result_o.data = req_o.req.rs[0] + req_o.req.rs[1] + (X_NUM_RS == 3 ? req_o.req.rs[2] : 0);
|
cvxif_resp_o.result_valid = alu_valid; //TODO Should wait for ready from CPU
|
||||||
x_result_valid_o = (c == x_result_o.data[3:0]) && ~fifo_empty ? 1 : 0;
|
cvxif_resp_o.result.hartid = hartid;
|
||||||
x_result_o.id = req_o.req.id;
|
cvxif_resp_o.result.id = id;
|
||||||
x_result_o.rd = req_o.req.instr[11:7];
|
cvxif_resp_o.result.data = result;
|
||||||
x_result_o.we = req_o.resp.writeback & x_result_valid_o;
|
cvxif_resp_o.result.rd = rd;
|
||||||
x_result_o.exc = 0;
|
cvxif_resp_o.result.we = we;
|
||||||
x_result_o.exccode = 0;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -7,40 +7,144 @@
|
||||||
//
|
//
|
||||||
// Original Author: Guillaume Chauvon (guillaume.chauvon@thalesgroup.com)
|
// Original Author: Guillaume Chauvon (guillaume.chauvon@thalesgroup.com)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
package cvxif_instr_pkg;
|
package cvxif_instr_pkg;
|
||||||
|
|
||||||
|
typedef enum logic [3:0] {
|
||||||
|
ILLEGAL = 4'b0000,
|
||||||
|
NOP = 4'b0001,
|
||||||
|
ADD = 4'b0010,
|
||||||
|
DOUBLE_RS1 = 4'b0011,
|
||||||
|
DOUBLE_RS2 = 4'b0100,
|
||||||
|
ADD_MULTI = 4'b0101,
|
||||||
|
ADD_RS3_R4 = 4'b0110,
|
||||||
|
ADD_RS3_R = 4'b0111
|
||||||
|
} opcode_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
logic [31:0] instr;
|
logic accept;
|
||||||
logic [31:0] mask;
|
logic writeback; // TODO depends on dualwrite
|
||||||
cvxif_pkg::x_issue_resp_t resp;
|
logic [2:0] register_read; // TODO Nr read ports
|
||||||
|
} issue_resp_t;
|
||||||
|
|
||||||
|
typedef struct packed {
|
||||||
|
logic accept;
|
||||||
|
logic [31:0] instr;
|
||||||
|
} compressed_resp_t;
|
||||||
|
|
||||||
|
typedef struct packed {
|
||||||
|
logic [31:0] instr;
|
||||||
|
logic [31:0] mask;
|
||||||
|
issue_resp_t resp;
|
||||||
|
opcode_t opcode;
|
||||||
} copro_issue_resp_t;
|
} copro_issue_resp_t;
|
||||||
|
|
||||||
// 2 Possible RISCV instructions for Coprocessor
|
|
||||||
parameter int unsigned NbInstr = 2;
|
typedef struct packed {
|
||||||
|
logic [15:0] instr;
|
||||||
|
logic [15:0] mask;
|
||||||
|
compressed_resp_t resp;
|
||||||
|
} copro_compressed_resp_t;
|
||||||
|
|
||||||
|
// 4 Possible RISCV instructions for Coprocessor
|
||||||
|
parameter int unsigned NbInstr = 10;
|
||||||
parameter copro_issue_resp_t CoproInstr[NbInstr] = '{
|
parameter copro_issue_resp_t CoproInstr[NbInstr] = '{
|
||||||
'{
|
'{
|
||||||
instr: 32'b00000_00_00000_00000_0_00_00000_0101011, // custom1 opcode
|
// Custom Nop
|
||||||
mask: 32'b00000_00_00000_00000_0_00_00000_1111111,
|
instr:
|
||||||
resp : '{
|
32'b00000_00_00000_00000_0_00_00000_1111011, // custom3 opcode
|
||||||
accept : 1'b1,
|
mask: 32'b11111_11_00000_00000_1_11_00000_1111111,
|
||||||
writeback : 1'b0,
|
resp : '{accept : 1'b1, writeback : 1'b0, register_read : {1'b0, 1'b0, 1'b0}},
|
||||||
dualwrite : 1'b0,
|
opcode : NOP
|
||||||
dualread : 1'b0,
|
|
||||||
loadstore : 1'b0,
|
|
||||||
exc : 1'b0
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
'{
|
'{
|
||||||
instr: 32'b00000_00_00000_00000_0_00_00000_1011011, // custom2 opcode
|
// Custom Add : cus_add rd, rs1, rs2
|
||||||
mask: 32'b00000_00_00000_00000_0_00_00000_1111111,
|
instr:
|
||||||
resp : '{
|
32'b00000_00_00000_00000_0_01_00000_1111011, // custom3 opcode
|
||||||
accept : 1'b1,
|
mask: 32'b11111_11_00000_00000_1_11_00000_1111111,
|
||||||
writeback : 1'b1,
|
resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b0, 1'b1, 1'b1}},
|
||||||
dualwrite : 1'b0,
|
opcode : ADD
|
||||||
dualread : 1'b0,
|
},
|
||||||
loadstore : 1'b0,
|
'{
|
||||||
exc : 1'b0
|
// Custom Add rs1 : cus_add rd, rs1, rs1
|
||||||
}
|
instr:
|
||||||
|
32'b00000_01_00000_00000_0_01_00000_1111011, // custom3 opcode
|
||||||
|
mask: 32'b11111_11_00000_00000_1_11_00000_1111111,
|
||||||
|
resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b0, 1'b0, 1'b1}},
|
||||||
|
opcode : DOUBLE_RS1
|
||||||
|
},
|
||||||
|
'{
|
||||||
|
// Custom Add rs2 : cus_add rd, rs2, rs2
|
||||||
|
instr:
|
||||||
|
32'b00000_10_00000_00000_0_01_00000_1111011, // custom3 opcode
|
||||||
|
mask: 32'b11111_11_00000_00000_1_11_00000_1111111,
|
||||||
|
resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b0, 1'b1, 1'b0}},
|
||||||
|
opcode : DOUBLE_RS2
|
||||||
|
},
|
||||||
|
'{
|
||||||
|
// Custom Add Multi rs1 : cus_add rd, rs1, rs1
|
||||||
|
instr:
|
||||||
|
32'b00000_11_00000_00000_0_01_00000_1111011, // custom3 opcode
|
||||||
|
mask: 32'b11111_11_00000_00000_1_11_00000_1111111,
|
||||||
|
resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b0, 1'b1, 1'b1}},
|
||||||
|
opcode : ADD_MULTI
|
||||||
|
},
|
||||||
|
'{
|
||||||
|
// Custom Add Multi rs1 : cus_add rd, rs1, rs1
|
||||||
|
instr:
|
||||||
|
32'b00001_00_00000_00000_0_01_00000_1111011, // custom3 opcode
|
||||||
|
mask: 32'b11111_11_00000_00000_1_11_00000_1111111,
|
||||||
|
resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b1, 1'b1, 1'b1}},
|
||||||
|
opcode : ADD_RS3_R
|
||||||
|
},
|
||||||
|
'{
|
||||||
|
// Custom Add Multi rs1 : cus_add rd, rs1, rs1
|
||||||
|
instr:
|
||||||
|
32'b00000_00_00000_00000_0_00_00000_1000011, // MADD opcode
|
||||||
|
mask: 32'b00000_11_00000_00000_1_11_00000_1111111,
|
||||||
|
resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b1, 1'b1, 1'b1}},
|
||||||
|
opcode : ADD_RS3_R4
|
||||||
|
},
|
||||||
|
'{
|
||||||
|
// Custom Add Multi rs1 : cus_add rd, rs1, rs1
|
||||||
|
instr:
|
||||||
|
32'b00000_00_00000_00000_0_00_00000_1000111, // MSUB opcode
|
||||||
|
mask: 32'b00000_11_00000_00000_1_11_00000_1111111,
|
||||||
|
resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b1, 1'b1, 1'b1}},
|
||||||
|
opcode : ADD_RS3_R4
|
||||||
|
},
|
||||||
|
'{
|
||||||
|
// Custom Add Multi rs1 : cus_add rd, rs1, rs1
|
||||||
|
instr:
|
||||||
|
32'b00000_00_00000_00000_0_00_00000_1001011, // NMSUB opcode
|
||||||
|
mask: 32'b00000_11_00000_00000_1_11_00000_1111111,
|
||||||
|
resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b1, 1'b1, 1'b1}},
|
||||||
|
opcode : ADD_RS3_R4
|
||||||
|
},
|
||||||
|
'{
|
||||||
|
// Custom Add Multi rs1 : cus_add rd, rs1, rs1
|
||||||
|
instr:
|
||||||
|
32'b00000_00_00000_00000_0_00_00000_1001111, // NMADD opcode
|
||||||
|
mask: 32'b00000_11_00000_00000_1_11_00000_1111111,
|
||||||
|
resp : '{accept : 1'b1, writeback : 1'b1, register_read : {1'b1, 1'b1, 1'b1}},
|
||||||
|
opcode : ADD_RS3_R4
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
parameter int unsigned NbCompInstr = 2;
|
||||||
|
parameter copro_compressed_resp_t CoproCompInstr[NbCompInstr] = '{
|
||||||
|
// C_NOP
|
||||||
|
'{
|
||||||
|
instr : 16'b111_0_00000_00000_00,
|
||||||
|
mask : 16'b111_1_00000_00000_11,
|
||||||
|
resp : '{accept : 1'b1, instr : 32'b00000_00_00000_00000_0_00_00000_1111011}
|
||||||
|
},
|
||||||
|
'{
|
||||||
|
instr : 16'b111_1_00000_00000_00,
|
||||||
|
mask : 16'b111_1_00000_00000_11,
|
||||||
|
resp : '{accept : 1'b1, instr : 32'b00000_00_00000_00000_0_01_01010_1111011}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,46 +1,86 @@
|
||||||
// Copyright 2021 Thales DIS design services SAS
|
// Copyright 2024 Thales DIS France SAS
|
||||||
//
|
//
|
||||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||||
//
|
//
|
||||||
// Original Author: Guillaume Chauvon (guillaume.chauvon@thalesgroup.com)
|
// Original Author: Guillaume Chauvon
|
||||||
|
|
||||||
module instr_decoder
|
module instr_decoder
|
||||||
import cvxif_pkg::*;
|
import cvxif_instr_pkg::*;
|
||||||
#(
|
#(
|
||||||
parameter int NbInstr = 1,
|
parameter int NbInstr = 1,
|
||||||
parameter cvxif_instr_pkg::copro_issue_resp_t CoproInstr[NbInstr] = {0}
|
parameter copro_issue_resp_t CoproInstr [NbInstr] = {0},
|
||||||
|
parameter int unsigned NrRgprPorts = 2,
|
||||||
|
parameter type hartid_t = logic,
|
||||||
|
parameter type id_t = logic,
|
||||||
|
parameter type x_issue_req_t = logic,
|
||||||
|
parameter type x_issue_resp_t = logic,
|
||||||
|
parameter type x_register_t = logic,
|
||||||
|
parameter type registers_t = logic
|
||||||
) (
|
) (
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
input x_issue_req_t x_issue_req_i,
|
input logic rst_ni,
|
||||||
output x_issue_resp_t x_issue_resp_o
|
input logic issue_valid_i,
|
||||||
|
input x_issue_req_t issue_req_i,
|
||||||
|
output logic issue_ready_o,
|
||||||
|
output x_issue_resp_t issue_resp_o,
|
||||||
|
input logic register_valid_i,
|
||||||
|
input x_register_t register_i,
|
||||||
|
output registers_t registers_o,
|
||||||
|
output opcode_t opcode_o,
|
||||||
|
output hartid_t hartid_o,
|
||||||
|
output id_t id_o,
|
||||||
|
output logic [4:0] rd_o
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [NbInstr-1:0] sel;
|
logic [NbInstr-1:0] sel;
|
||||||
|
logic rs1_ready;
|
||||||
|
logic rs2_ready;
|
||||||
|
logic rs3_ready;
|
||||||
|
|
||||||
for (genvar i = 0; i < NbInstr; i++) begin : gen_predecoder_selector
|
for (genvar i = 0; i < NbInstr; i++) begin : gen_predecoder_selector
|
||||||
assign sel[i] = ((CoproInstr[i].mask & x_issue_req_i.instr) == CoproInstr[i].instr);
|
assign sel[i] = ((CoproInstr[i].mask & issue_req_i.instr) == CoproInstr[i].instr);
|
||||||
end
|
end
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
x_issue_resp_o.accept = '0;
|
rs1_ready = '0;
|
||||||
x_issue_resp_o.writeback = '0;
|
rs2_ready = '0;
|
||||||
x_issue_resp_o.dualwrite = '0;
|
rs3_ready = '0;
|
||||||
x_issue_resp_o.dualread = '0;
|
issue_ready_o = '0;
|
||||||
x_issue_resp_o.loadstore = '0;
|
issue_resp_o.accept = '0;
|
||||||
x_issue_resp_o.exc = '0;
|
issue_resp_o.writeback = '0;
|
||||||
|
issue_resp_o.register_read = '0;
|
||||||
|
registers_o = '0;
|
||||||
|
opcode_o = ILLEGAL;
|
||||||
|
hartid_o = '0;
|
||||||
|
id_o = '0;
|
||||||
|
rd_o = '0;
|
||||||
for (int unsigned i = 0; i < NbInstr; i++) begin
|
for (int unsigned i = 0; i < NbInstr; i++) begin
|
||||||
if (sel[i]) begin
|
if (sel[i] && issue_valid_i) begin
|
||||||
x_issue_resp_o.accept = CoproInstr[i].resp.accept;
|
issue_resp_o.accept = CoproInstr[i].resp.accept;
|
||||||
x_issue_resp_o.writeback = CoproInstr[i].resp.writeback;
|
issue_resp_o.writeback = CoproInstr[i].resp.writeback;
|
||||||
x_issue_resp_o.dualwrite = CoproInstr[i].resp.dualwrite;
|
issue_resp_o.register_read = CoproInstr[i].resp.register_read; // Warning : potential 3 bits vector into 2 bits one
|
||||||
x_issue_resp_o.dualread = CoproInstr[i].resp.dualread;
|
if (issue_resp_o.accept) begin
|
||||||
x_issue_resp_o.loadstore = CoproInstr[i].resp.loadstore;
|
rs1_ready = (~CoproInstr[i].resp.register_read[0] || register_i.rs_valid[0]);
|
||||||
x_issue_resp_o.exc = CoproInstr[i].resp.exc;
|
rs2_ready = (~CoproInstr[i].resp.register_read[1] || register_i.rs_valid[1]);
|
||||||
|
rs3_ready = NrRgprPorts == 3 ? (~CoproInstr[i].resp.register_read[2] || register_i.rs_valid[2]) : 1'b1;
|
||||||
|
issue_ready_o = rs1_ready && rs2_ready && rs3_ready;
|
||||||
|
end
|
||||||
|
opcode_o = CoproInstr[i].opcode;
|
||||||
|
id_o = issue_req_i.id;
|
||||||
|
hartid_o = issue_req_i.hartid;
|
||||||
|
rd_o = issue_req_i.instr[11:7];
|
||||||
|
for (int unsigned j = 0; j < NrRgprPorts; j++) begin
|
||||||
|
registers_o[j] = issue_resp_o.register_read[j] ? register_i.rs[j] : '0;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
// Coprocessor could not decode offloaded instruction -> instruction is not accepted
|
||||||
|
if (issue_valid_i && ~(|sel)) begin
|
||||||
|
issue_ready_o = 1'b1;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
assert property (@(posedge clk_i) $onehot0(sel))
|
assert property (@(posedge clk_i) $onehot0(sel))
|
||||||
|
|
143
core/cvxif_fu.sv
143
core/cvxif_fu.sv
|
@ -1,13 +1,14 @@
|
||||||
// Copyright 2021 Thales DIS design services SAS
|
// Copyright 2024 Thales DIS France SAS
|
||||||
//
|
//
|
||||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||||
//
|
//
|
||||||
// Original Author: Guillaume CHAUVON (guillaume.chauvon@thalesgroup.com)
|
// Original Author: Guillaume Chauvon
|
||||||
|
|
||||||
// Functional Unit for the logic of the CoreV-X-Interface
|
// Functional Unit for the CoreV-X-Interface
|
||||||
|
// Handles Result interface and exception forwarding to next stages.
|
||||||
|
|
||||||
|
|
||||||
module cvxif_fu
|
module cvxif_fu
|
||||||
|
@ -15,116 +16,60 @@ module cvxif_fu
|
||||||
#(
|
#(
|
||||||
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
||||||
parameter type exception_t = logic,
|
parameter type exception_t = logic,
|
||||||
parameter type fu_data_t = logic
|
parameter type x_result_t = logic
|
||||||
) (
|
) (
|
||||||
// Subsystem Clock - SUBSYSTEM
|
// Subsystem Clock - SUBSYSTEM
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
// Asynchronous reset active low - SUBSYSTEM
|
// Asynchronous reset active low - SUBSYSTEM
|
||||||
input logic rst_ni,
|
input logic rst_ni,
|
||||||
// FU data needed to execute instruction - ISSUE_STAGE
|
|
||||||
input fu_data_t fu_data_i,
|
|
||||||
// Current privilege mode - CSR_REGFILE
|
|
||||||
input riscv::priv_lvl_t priv_lvl_i,
|
|
||||||
// CVXIF instruction is valid - ISSUE_STAGE
|
// CVXIF instruction is valid - ISSUE_STAGE
|
||||||
input logic x_valid_i,
|
input logic x_valid_i,
|
||||||
// CVXIF is ready - ISSUE_STAGE
|
// Transaction ID - ISSUE_STAGE
|
||||||
output logic x_ready_o,
|
input logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_i,
|
||||||
|
// Instruction is illegal, determined during CVXIF issue transaction - ISSUE_STAGE
|
||||||
|
input logic x_illegal_i,
|
||||||
// Offloaded instruction - ISSUE_STAGE
|
// Offloaded instruction - ISSUE_STAGE
|
||||||
input logic [ 31:0] x_off_instr_i,
|
input logic [ 31:0] x_off_instr_i,
|
||||||
// CVXIF transaction ID - ISSUE_STAGE
|
// CVXIF is ready - ISSUE_STAGE
|
||||||
output logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_o,
|
output logic x_ready_o,
|
||||||
|
// CVXIF result transaction ID - ISSUE_STAGE
|
||||||
|
output logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_o,
|
||||||
// CVXIF exception - ISSUE_STAGE
|
// CVXIF exception - ISSUE_STAGE
|
||||||
output exception_t x_exception_o,
|
output exception_t x_exception_o,
|
||||||
// CVXIF FU result - ISSUE_STAGE
|
// CVXIF FU result - ISSUE_STAGE
|
||||||
output logic [ CVA6Cfg.XLEN-1:0] x_result_o,
|
output logic [ CVA6Cfg.XLEN-1:0] x_result_o,
|
||||||
// CVXIF result valid - ISSUE_STAGE
|
// CVXIF result valid - ISSUE_STAGE
|
||||||
output logic x_valid_o,
|
output logic x_valid_o,
|
||||||
// CVXIF write enable - ISSUE_STAGE
|
// CVXIF write enable - ISSUE_STAGE
|
||||||
output logic x_we_o,
|
output logic x_we_o,
|
||||||
// CVXIF request - SUBSYSTEM
|
// CVXIF destination register - ISSUE_STAGE
|
||||||
output cvxif_pkg::cvxif_req_t cvxif_req_o,
|
output logic [ 4:0] x_rd_o,
|
||||||
// CVXIF response - SUBSYSTEM
|
// CVXIF result interface
|
||||||
input cvxif_pkg::cvxif_resp_t cvxif_resp_i
|
input logic result_valid_i,
|
||||||
|
input x_result_t result_i,
|
||||||
|
output logic result_ready_o
|
||||||
);
|
);
|
||||||
localparam X_NUM_RS = ariane_pkg::NR_RGPR_PORTS;
|
|
||||||
|
|
||||||
logic illegal_n, illegal_q;
|
|
||||||
logic [CVA6Cfg.TRANS_ID_BITS-1:0] illegal_id_n, illegal_id_q;
|
|
||||||
logic [31:0] illegal_instr_n, illegal_instr_q;
|
|
||||||
logic [X_NUM_RS-1:0] rs_valid;
|
|
||||||
|
|
||||||
if (cvxif_pkg::X_NUM_RS == 3) begin : gen_third_operand
|
|
||||||
assign rs_valid = 3'b111;
|
|
||||||
end else begin : gen_no_third_operand
|
|
||||||
assign rs_valid = 2'b11;
|
|
||||||
end
|
|
||||||
|
|
||||||
|
assign result_ready_o = 1'b1;
|
||||||
|
|
||||||
|
assign x_ready_o = 1'b1; // Readyness of cvxif_fu is determined in issue stage by CVXIF issue interface
|
||||||
|
// Result signals
|
||||||
|
assign x_valid_o = x_illegal_i ? 1'b1 : result_valid_i;
|
||||||
|
assign x_result_o = result_i.data;
|
||||||
|
assign x_trans_id_o = x_illegal_i ? x_trans_id_i : result_i.id;
|
||||||
|
assign x_we_o = result_i.we;
|
||||||
|
assign x_rd_o = result_i.rd;
|
||||||
|
|
||||||
|
// Handling of illegal instruction exception
|
||||||
always_comb begin
|
always_comb begin
|
||||||
cvxif_req_o = '0;
|
x_exception_o = '0; // No exception in this interface
|
||||||
cvxif_req_o.x_result_ready = 1'b1;
|
if (x_illegal_i) begin
|
||||||
x_ready_o = cvxif_resp_i.x_issue_ready;
|
x_exception_o.valid = '1;
|
||||||
if (x_valid_i) begin
|
x_exception_o.cause = riscv::ILLEGAL_INSTR;
|
||||||
cvxif_req_o.x_issue_valid = x_valid_i;
|
if (CVA6Cfg.TvalEn)
|
||||||
cvxif_req_o.x_issue_req.instr = x_off_instr_i;
|
x_exception_o.tval = x_off_instr_i; // TODO Optimization : Set exception in IRO.
|
||||||
cvxif_req_o.x_issue_req.mode = priv_lvl_i;
|
|
||||||
cvxif_req_o.x_issue_req.id = fu_data_i.trans_id;
|
|
||||||
cvxif_req_o.x_issue_req.rs[0] = fu_data_i.operand_a;
|
|
||||||
cvxif_req_o.x_issue_req.rs[1] = fu_data_i.operand_b;
|
|
||||||
if (cvxif_pkg::X_NUM_RS == 3) begin
|
|
||||||
cvxif_req_o.x_issue_req.rs[2] = fu_data_i.imm;
|
|
||||||
end
|
|
||||||
cvxif_req_o.x_issue_req.rs_valid = rs_valid;
|
|
||||||
cvxif_req_o.x_commit_valid = x_valid_i;
|
|
||||||
cvxif_req_o.x_commit.id = fu_data_i.trans_id;
|
|
||||||
cvxif_req_o.x_commit.x_commit_kill = 1'b0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
always_comb begin
|
|
||||||
illegal_n = illegal_q;
|
|
||||||
illegal_id_n = illegal_id_q;
|
|
||||||
illegal_instr_n = illegal_instr_q;
|
|
||||||
if (~cvxif_resp_i.x_issue_resp.accept && cvxif_req_o.x_issue_valid && cvxif_resp_i.x_issue_ready && ~illegal_n) begin
|
|
||||||
illegal_n = 1'b1;
|
|
||||||
illegal_id_n = cvxif_req_o.x_issue_req.id;
|
|
||||||
illegal_instr_n = cvxif_req_o.x_issue_req.instr;
|
|
||||||
end
|
|
||||||
x_valid_o = cvxif_resp_i.x_result_valid; //Read result only when CVXIF is enabled
|
|
||||||
x_trans_id_o = x_valid_o ? cvxif_resp_i.x_result.id : '0;
|
|
||||||
x_result_o = x_valid_o ? cvxif_resp_i.x_result.data : '0;
|
|
||||||
x_exception_o.cause = x_valid_o ? {{(CVA6Cfg.XLEN-6){1'b0}}, cvxif_resp_i.x_result.exccode} : '0;
|
|
||||||
x_exception_o.valid = x_valid_o ? cvxif_resp_i.x_result.exc : '0;
|
|
||||||
x_exception_o.tval = '0;
|
|
||||||
x_exception_o.tinst = '0;
|
|
||||||
x_exception_o.tval2 = '0;
|
|
||||||
x_exception_o.gva = '0;
|
|
||||||
x_we_o = x_valid_o ? cvxif_resp_i.x_result.we : '0;
|
|
||||||
if (illegal_n) begin
|
|
||||||
if (~x_valid_o) begin
|
|
||||||
x_trans_id_o = illegal_id_n;
|
|
||||||
x_result_o = '0;
|
|
||||||
x_valid_o = 1'b1;
|
|
||||||
x_exception_o.cause = riscv::ILLEGAL_INSTR;
|
|
||||||
x_exception_o.valid = 1'b1;
|
|
||||||
if (CVA6Cfg.TvalEn) x_exception_o.tval = illegal_instr_n;
|
|
||||||
x_exception_o.tinst = '0;
|
|
||||||
x_exception_o.tval2 = '0;
|
|
||||||
x_exception_o.gva = '0;
|
|
||||||
x_we_o = '0;
|
|
||||||
illegal_n = '0; // Reset flag for illegal instr. illegal_id and illegal instr values are a don't care, no need to reset it.
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
always_ff @(posedge clk_i, negedge rst_ni) begin
|
|
||||||
if (~rst_ni) begin
|
|
||||||
illegal_q <= 1'b0;
|
|
||||||
illegal_id_q <= '0;
|
|
||||||
illegal_instr_q <= '0;
|
|
||||||
end else begin
|
|
||||||
illegal_q <= illegal_n;
|
|
||||||
illegal_id_q <= illegal_id_n;
|
|
||||||
illegal_instr_q <= illegal_instr_n;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
68
core/cvxif_issue_register_commit_if_driver.sv
Normal file
68
core/cvxif_issue_register_commit_if_driver.sv
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
// Copyright 2024 Thales DIS France SAS
|
||||||
|
//
|
||||||
|
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||||
|
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||||
|
//
|
||||||
|
// Original Author: Guillaume Chauvon
|
||||||
|
|
||||||
|
module cvxif_issue_register_commit_if_driver #(
|
||||||
|
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
||||||
|
parameter type x_issue_req_t = logic,
|
||||||
|
parameter type x_issue_resp_t = logic,
|
||||||
|
parameter type x_register_t = logic,
|
||||||
|
parameter type x_commit_t = logic
|
||||||
|
) (
|
||||||
|
// CVA6 inputs
|
||||||
|
input logic clk_i,
|
||||||
|
input logic rst_ni,
|
||||||
|
input logic flush_i,
|
||||||
|
input logic [ CVA6Cfg.XLEN-1:0] hart_id_i,
|
||||||
|
// CVXIF Issue interface
|
||||||
|
input logic issue_ready_i,
|
||||||
|
input x_issue_resp_t issue_resp_i,
|
||||||
|
output logic issue_valid_o,
|
||||||
|
output x_issue_req_t issue_req_o,
|
||||||
|
// CVXIF Register interface
|
||||||
|
input logic register_ready_i,
|
||||||
|
output logic register_valid_o,
|
||||||
|
output x_register_t register_o,
|
||||||
|
// CVXIF Commit interface
|
||||||
|
output logic commit_valid_o,
|
||||||
|
output x_commit_t commit_o,
|
||||||
|
// IRO in/out
|
||||||
|
input logic valid_i,
|
||||||
|
input logic [ 31:0] x_off_instr_i,
|
||||||
|
input logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_i,
|
||||||
|
input logic [ CVA6Cfg.NrRgprPorts-1:0][CVA6Cfg.XLEN-1:0] register_i,
|
||||||
|
input logic [ CVA6Cfg.NrRgprPorts-1:0] rs_valid_i,
|
||||||
|
output logic cvxif_busy_o
|
||||||
|
);
|
||||||
|
// X_ISSUE_REGISTER_SPLIT = 0 : Issue and register transactions are synchrone
|
||||||
|
// Mandatory assignement
|
||||||
|
assign register_valid_o = issue_valid_o;
|
||||||
|
assign register_o.hartid = issue_req_o.hartid;
|
||||||
|
assign register_o.id = issue_req_o.id;
|
||||||
|
// cvxif can not take any more instruction if issue transaction is still up.
|
||||||
|
assign cvxif_busy_o = issue_valid_o && ~issue_ready_i;
|
||||||
|
always_comb begin
|
||||||
|
issue_valid_o = valid_i && ~flush_i;
|
||||||
|
issue_req_o.instr = x_off_instr_i;
|
||||||
|
issue_req_o.hartid = hart_id_i;
|
||||||
|
issue_req_o.id = x_trans_id_i;
|
||||||
|
register_o.rs = register_i;
|
||||||
|
register_o.rs_valid = rs_valid_i;
|
||||||
|
end
|
||||||
|
|
||||||
|
/* WARNING */
|
||||||
|
// Always commit since speculation in execute in not possible : TODO to be verified
|
||||||
|
|
||||||
|
// Always do commit transaction with issue
|
||||||
|
// If instruction goes to execute then it is not speculative
|
||||||
|
assign commit_valid_o = issue_valid_o;
|
||||||
|
assign commit_o.hartid = issue_req_o.hartid;
|
||||||
|
assign commit_o.id = issue_req_o.id;
|
||||||
|
assign commit_o.commit_kill = 1'b0;
|
||||||
|
|
||||||
|
endmodule
|
|
@ -112,7 +112,8 @@ module decoder
|
||||||
SBIMM,
|
SBIMM,
|
||||||
UIMM,
|
UIMM,
|
||||||
JIMM,
|
JIMM,
|
||||||
RS3
|
RS3,
|
||||||
|
MUX_RD_RS3
|
||||||
} imm_select;
|
} imm_select;
|
||||||
|
|
||||||
logic [CVA6Cfg.XLEN-1:0] imm_i_type;
|
logic [CVA6Cfg.XLEN-1:0] imm_i_type;
|
||||||
|
@ -1422,13 +1423,16 @@ module decoder
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
if (CVA6Cfg.CvxifEn) begin
|
if (CVA6Cfg.CvxifEn) begin
|
||||||
if (is_illegal_i || illegal_instr) begin
|
if (~ex_i.valid && (is_illegal_i || illegal_instr)) begin
|
||||||
instruction_o.fu = CVXIF;
|
instruction_o.fu = CVXIF;
|
||||||
instruction_o.rs1[4:0] = instr.r4type.rs1;
|
instruction_o.rs1[4:0] = instr.r4type.rs1;
|
||||||
instruction_o.rs2[4:0] = instr.r4type.rs2;
|
instruction_o.rs2[4:0] = instr.r4type.rs2;
|
||||||
instruction_o.rd[4:0] = instr.r4type.rd;
|
instruction_o.rd[4:0] = instr.r4type.rd;
|
||||||
instruction_o.op = ariane_pkg::OFFLOAD;
|
instruction_o.op = ariane_pkg::OFFLOAD;
|
||||||
imm_select = RS3;
|
imm_select = instr.rtype.opcode == riscv::OpcodeMadd ||
|
||||||
|
instr.rtype.opcode == riscv::OpcodeMsub ||
|
||||||
|
instr.rtype.opcode == riscv::OpcodeNmadd ||
|
||||||
|
instr.rtype.opcode == riscv::OpcodeNmsub ? RS3 : MUX_RD_RS3;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1504,6 +1508,11 @@ module decoder
|
||||||
instruction_o.result = {{CVA6Cfg.XLEN - 5{1'b0}}, instr.r4type.rs3};
|
instruction_o.result = {{CVA6Cfg.XLEN - 5{1'b0}}, instr.r4type.rs3};
|
||||||
instruction_o.use_imm = 1'b0;
|
instruction_o.use_imm = 1'b0;
|
||||||
end
|
end
|
||||||
|
MUX_RD_RS3: begin
|
||||||
|
// result holds address of operand rs3 which is in rd field
|
||||||
|
instruction_o.result = {{CVA6Cfg.XLEN - 5{1'b0}}, instr.rtype.rd};
|
||||||
|
instruction_o.use_imm = 1'b0;
|
||||||
|
end
|
||||||
default: begin
|
default: begin
|
||||||
instruction_o.result = {CVA6Cfg.XLEN{1'b0}};
|
instruction_o.result = {CVA6Cfg.XLEN{1'b0}};
|
||||||
instruction_o.use_imm = 1'b0;
|
instruction_o.use_imm = 1'b0;
|
||||||
|
|
|
@ -28,7 +28,8 @@ module ex_stage
|
||||||
parameter type icache_arsp_t = logic,
|
parameter type icache_arsp_t = logic,
|
||||||
parameter type icache_dreq_t = logic,
|
parameter type icache_dreq_t = logic,
|
||||||
parameter type icache_drsp_t = logic,
|
parameter type icache_drsp_t = logic,
|
||||||
parameter type lsu_ctrl_t = logic
|
parameter type lsu_ctrl_t = logic,
|
||||||
|
parameter type x_result_t = logic
|
||||||
) (
|
) (
|
||||||
// Subsystem Clock - SUBSYSTEM
|
// Subsystem Clock - SUBSYSTEM
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
|
@ -136,7 +137,7 @@ module ex_stage
|
||||||
input logic [CVA6Cfg.NrIssuePorts-1:0] x_valid_i,
|
input logic [CVA6Cfg.NrIssuePorts-1:0] x_valid_i,
|
||||||
// CVXIF is ready - ISSUE_STAGE
|
// CVXIF is ready - ISSUE_STAGE
|
||||||
output logic x_ready_o,
|
output logic x_ready_o,
|
||||||
// undecoded instruction - ISSUE_STAGE
|
// CVXIF undecoded instruction
|
||||||
input logic [31:0] x_off_instr_i,
|
input logic [31:0] x_off_instr_i,
|
||||||
// CVXIF transaction ID - ISSUE_STAGE
|
// CVXIF transaction ID - ISSUE_STAGE
|
||||||
output logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_o,
|
output logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_trans_id_o,
|
||||||
|
@ -148,10 +149,14 @@ module ex_stage
|
||||||
output logic x_valid_o,
|
output logic x_valid_o,
|
||||||
// CVXIF write enable - ISSUE_STAGE
|
// CVXIF write enable - ISSUE_STAGE
|
||||||
output logic x_we_o,
|
output logic x_we_o,
|
||||||
// CVXIF request - SUBSYSTEM
|
// CVXIF destination register - ISSUE_STAGE
|
||||||
output cvxif_pkg::cvxif_req_t cvxif_req_o,
|
output logic [4:0] x_rd_o,
|
||||||
// CVXIF response - SUBSYSTEM
|
// CVXIF Result interface - SUBSYSTEM
|
||||||
input cvxif_pkg::cvxif_resp_t cvxif_resp_i,
|
input logic x_result_valid_i,
|
||||||
|
input x_result_t x_result_i,
|
||||||
|
output logic x_result_ready_o,
|
||||||
|
// CVXIF Issue transaction rejected -> illegal instruction - ISSUE_STAGE
|
||||||
|
input logic x_transaction_rejected_i,
|
||||||
// accelerate port result is valid - ACC_DISPATCHER
|
// accelerate port result is valid - ACC_DISPATCHER
|
||||||
input logic acc_valid_i,
|
input logic acc_valid_i,
|
||||||
// Enable virtual memory translation - CSR_REGFILE
|
// Enable virtual memory translation - CSR_REGFILE
|
||||||
|
@ -592,29 +597,31 @@ module ex_stage
|
||||||
cvxif_fu #(
|
cvxif_fu #(
|
||||||
.CVA6Cfg(CVA6Cfg),
|
.CVA6Cfg(CVA6Cfg),
|
||||||
.exception_t(exception_t),
|
.exception_t(exception_t),
|
||||||
.fu_data_t(fu_data_t)
|
.x_result_t(x_result_t)
|
||||||
) cvxif_fu_i (
|
) cvxif_fu_i (
|
||||||
.clk_i,
|
.clk_i,
|
||||||
.rst_ni,
|
.rst_ni,
|
||||||
.fu_data_i (cvxif_data),
|
.x_valid_i(|x_valid_i),
|
||||||
.priv_lvl_i(ld_st_priv_lvl_i),
|
.x_trans_id_i(cvxif_data.trans_id),
|
||||||
.x_valid_i (|x_valid_i),
|
.x_illegal_i(x_transaction_rejected_i),
|
||||||
.x_ready_o,
|
|
||||||
.x_off_instr_i,
|
.x_off_instr_i,
|
||||||
|
.x_ready_o,
|
||||||
.x_trans_id_o,
|
.x_trans_id_o,
|
||||||
.x_exception_o,
|
.x_exception_o,
|
||||||
.x_result_o,
|
.x_result_o,
|
||||||
.x_valid_o,
|
.x_valid_o,
|
||||||
.x_we_o,
|
.x_we_o,
|
||||||
.cvxif_req_o,
|
.x_rd_o,
|
||||||
.cvxif_resp_i
|
.result_valid_i(x_result_valid_i),
|
||||||
|
.result_i(x_result_i),
|
||||||
|
.result_ready_o(x_result_ready_o)
|
||||||
);
|
);
|
||||||
end else begin : gen_no_cvxif
|
end else begin : gen_no_cvxif
|
||||||
assign cvxif_req_o = '0;
|
assign x_result_ready_o = '0;
|
||||||
assign x_trans_id_o = '0;
|
assign x_trans_id_o = '0;
|
||||||
assign x_exception_o = '0;
|
assign x_exception_o = '0;
|
||||||
assign x_result_o = '0;
|
assign x_result_o = '0;
|
||||||
assign x_valid_o = '0;
|
assign x_valid_o = '0;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (CVA6Cfg.RVS) begin
|
if (CVA6Cfg.RVS) begin
|
||||||
|
|
|
@ -21,7 +21,9 @@ module id_stage #(
|
||||||
parameter type irq_ctrl_t = logic,
|
parameter type irq_ctrl_t = logic,
|
||||||
parameter type scoreboard_entry_t = logic,
|
parameter type scoreboard_entry_t = logic,
|
||||||
parameter type interrupts_t = logic,
|
parameter type interrupts_t = logic,
|
||||||
parameter interrupts_t INTERRUPTS = '0
|
parameter interrupts_t INTERRUPTS = '0,
|
||||||
|
parameter type x_compressed_req_t = logic,
|
||||||
|
parameter type x_compressed_resp_t = logic
|
||||||
) (
|
) (
|
||||||
// Subsystem Clock - SUBSYSTEM
|
// Subsystem Clock - SUBSYSTEM
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
|
@ -76,7 +78,13 @@ module id_stage #(
|
||||||
// Trap sret - CSR_REGFILE
|
// Trap sret - CSR_REGFILE
|
||||||
input logic tsr_i,
|
input logic tsr_i,
|
||||||
// Hypervisor user mode - CSR_REGFILE
|
// Hypervisor user mode - CSR_REGFILE
|
||||||
input logic hu_i
|
input logic hu_i,
|
||||||
|
// CVXIF Compressed interface
|
||||||
|
input logic [CVA6Cfg.XLEN-1:0] hart_id_i,
|
||||||
|
input logic compressed_ready_i,
|
||||||
|
input x_compressed_resp_t compressed_resp_i,
|
||||||
|
output logic compressed_valid_o,
|
||||||
|
output x_compressed_req_t compressed_req_o
|
||||||
);
|
);
|
||||||
// ID/ISSUE register stage
|
// ID/ISSUE register stage
|
||||||
typedef struct packed {
|
typedef struct packed {
|
||||||
|
@ -93,12 +101,17 @@ module id_stage #(
|
||||||
|
|
||||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal;
|
logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal;
|
||||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_cmp;
|
logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_cmp;
|
||||||
|
logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_cvxif;
|
||||||
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction;
|
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction;
|
||||||
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] compressed_instr;
|
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] compressed_instr;
|
||||||
|
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction_cvxif;
|
||||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed;
|
logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed;
|
||||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_cmp;
|
logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_cmp;
|
||||||
|
logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_cvxif;
|
||||||
|
|
||||||
logic [CVA6Cfg.NrIssuePorts-1:0] is_macro_instr_i;
|
logic [CVA6Cfg.NrIssuePorts-1:0] is_macro_instr_i;
|
||||||
logic stall_instr_fetch;
|
logic stall_instr_fetch;
|
||||||
|
logic stall_macro_deco;
|
||||||
logic is_last_macro_instr_o;
|
logic is_last_macro_instr_o;
|
||||||
logic is_double_rd_macro_instr_o;
|
logic is_double_rd_macro_instr_o;
|
||||||
|
|
||||||
|
@ -126,25 +139,64 @@ module id_stage #(
|
||||||
.is_macro_instr_i (is_macro_instr_i[0]),
|
.is_macro_instr_i (is_macro_instr_i[0]),
|
||||||
.clk_i (clk_i),
|
.clk_i (clk_i),
|
||||||
.rst_ni (rst_ni),
|
.rst_ni (rst_ni),
|
||||||
.instr_o (instruction[0]),
|
.instr_o (instruction_cvxif[0]),
|
||||||
.illegal_instr_i (is_illegal[0]),
|
.illegal_instr_i (is_illegal[0]),
|
||||||
.is_compressed_i (is_compressed[0]),
|
.is_compressed_i (is_compressed[0]),
|
||||||
.issue_ack_i (issue_instr_ack_i[0]),
|
.issue_ack_i (issue_instr_ack_i[0]),
|
||||||
.illegal_instr_o (is_illegal_cmp[0]),
|
.illegal_instr_o (is_illegal_cvxif[0]),
|
||||||
.is_compressed_o (is_compressed_cmp[0]),
|
.is_compressed_o (is_compressed_cvxif[0]),
|
||||||
.fetch_stall_o (stall_instr_fetch),
|
.fetch_stall_o (stall_macro_deco),
|
||||||
.is_last_macro_instr_o (is_last_macro_instr_o),
|
.is_last_macro_instr_o (is_last_macro_instr_o),
|
||||||
.is_double_rd_macro_instr_o(is_double_rd_macro_instr_o)
|
.is_double_rd_macro_instr_o(is_double_rd_macro_instr_o)
|
||||||
);
|
);
|
||||||
if (CVA6Cfg.SuperscalarEn) begin
|
if (CVA6Cfg.SuperscalarEn) begin
|
||||||
assign instruction[CVA6Cfg.NrIssuePorts-1] = '0;
|
assign instruction_cvxif[CVA6Cfg.NrIssuePorts-1] = '0;
|
||||||
assign is_illegal_cmp[CVA6Cfg.NrIssuePorts-1] = '0;
|
assign is_illegal_cvxif[CVA6Cfg.NrIssuePorts-1] = '0;
|
||||||
assign is_compressed_cmp[CVA6Cfg.NrIssuePorts-1] = '0;
|
assign is_compressed_cvxif[CVA6Cfg.NrIssuePorts-1] = '0;
|
||||||
end
|
end
|
||||||
|
cvxif_compressed_if_driver #(
|
||||||
|
.CVA6Cfg(CVA6Cfg),
|
||||||
|
.x_compressed_req_t(x_compressed_req_t),
|
||||||
|
.x_compressed_resp_t(x_compressed_resp_t)
|
||||||
|
) i_cvxif_compressed_if_driver_i (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_ni (rst_ni),
|
||||||
|
.hart_id_i (hart_id_i),
|
||||||
|
.is_compressed_i (is_compressed_cvxif),
|
||||||
|
.is_illegal_i (is_illegal_cvxif),
|
||||||
|
.instruction_i (instruction_cvxif),
|
||||||
|
.is_compressed_o (is_compressed_cmp),
|
||||||
|
.is_illegal_o (is_illegal_cmp),
|
||||||
|
.instruction_o (instruction),
|
||||||
|
.stall_i (stall_macro_deco),
|
||||||
|
.stall_o (stall_instr_fetch),
|
||||||
|
.compressed_ready_i(compressed_ready_i),
|
||||||
|
.compressed_resp_i (compressed_resp_i),
|
||||||
|
.compressed_valid_o(compressed_valid_o),
|
||||||
|
.compressed_req_o (compressed_req_o)
|
||||||
|
);
|
||||||
end else begin
|
end else begin
|
||||||
assign instruction = compressed_instr;
|
cvxif_compressed_if_driver #(
|
||||||
assign is_illegal_cmp = is_illegal;
|
.CVA6Cfg(CVA6Cfg),
|
||||||
assign is_compressed_cmp = is_compressed;
|
.x_compressed_req_t(x_compressed_req_t),
|
||||||
|
.x_compressed_resp_t(x_compressed_resp_t)
|
||||||
|
) i_cvxif_compressed_if_driver_i (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_ni (rst_ni),
|
||||||
|
.hart_id_i (hart_id_i),
|
||||||
|
.is_compressed_i (is_compressed),
|
||||||
|
.is_illegal_i (is_illegal),
|
||||||
|
.instruction_i (compressed_instr),
|
||||||
|
.is_compressed_o (is_compressed_cmp),
|
||||||
|
.is_illegal_o (is_illegal_cmp),
|
||||||
|
.instruction_o (instruction),
|
||||||
|
.stall_i (1'b0),
|
||||||
|
.stall_o (stall_instr_fetch),
|
||||||
|
.compressed_ready_i(compressed_ready_i),
|
||||||
|
.compressed_resp_i (compressed_resp_i),
|
||||||
|
.compressed_valid_o(compressed_valid_o),
|
||||||
|
.compressed_req_o (compressed_req_o)
|
||||||
|
);
|
||||||
assign is_last_macro_instr_o = '0;
|
assign is_last_macro_instr_o = '0;
|
||||||
assign is_double_rd_macro_instr_o = '0;
|
assign is_double_rd_macro_instr_o = '0;
|
||||||
end
|
end
|
||||||
|
@ -157,6 +209,11 @@ module id_stage #(
|
||||||
assign is_macro_instr_i = '0;
|
assign is_macro_instr_i = '0;
|
||||||
assign is_last_macro_instr_o = '0;
|
assign is_last_macro_instr_o = '0;
|
||||||
assign is_double_rd_macro_instr_o = '0;
|
assign is_double_rd_macro_instr_o = '0;
|
||||||
|
if (CVA6Cfg.CvxifEn) begin
|
||||||
|
assign compressed_valid_o = '0;
|
||||||
|
assign compressed_req_o.instr = '0;
|
||||||
|
assign compressed_req_o.hartid = hart_id_i;
|
||||||
|
end // TODO Add else to map x_compressed_if outputs to '0 ?
|
||||||
end
|
end
|
||||||
|
|
||||||
assign rvfi_is_compressed_o = is_compressed_cmp;
|
assign rvfi_is_compressed_o = is_compressed_cmp;
|
||||||
|
|
|
@ -84,7 +84,9 @@ package build_config_pkg;
|
||||||
cfg.XF16Vec = bit'(XF16Vec);
|
cfg.XF16Vec = bit'(XF16Vec);
|
||||||
cfg.XF16ALTVec = bit'(XF16ALTVec);
|
cfg.XF16ALTVec = bit'(XF16ALTVec);
|
||||||
cfg.XF8Vec = bit'(XF8Vec);
|
cfg.XF8Vec = bit'(XF8Vec);
|
||||||
|
// Can take 2 or 3 in single issue. 4 or 6 in dual issue.
|
||||||
cfg.NrRgprPorts = unsigned'(CVA6Cfg.SuperscalarEn ? 4 : 2);
|
cfg.NrRgprPorts = unsigned'(CVA6Cfg.SuperscalarEn ? 4 : 2);
|
||||||
|
// cfg.NrRgprPorts = unsigned'(CVA6Cfg.SuperscalarEn ? 6 : 3);
|
||||||
cfg.NrWbPorts = unsigned'(NrWbPorts);
|
cfg.NrWbPorts = unsigned'(NrWbPorts);
|
||||||
cfg.EnableAccelerator = bit'(EnableAccelerator);
|
cfg.EnableAccelerator = bit'(EnableAccelerator);
|
||||||
cfg.PerfCounterEn = CVA6Cfg.PerfCounterEn;
|
cfg.PerfCounterEn = CVA6Cfg.PerfCounterEn;
|
||||||
|
@ -165,6 +167,16 @@ package build_config_pkg;
|
||||||
cfg.VpnLen = VpnLen;
|
cfg.VpnLen = VpnLen;
|
||||||
cfg.PtLevels = PtLevels;
|
cfg.PtLevels = PtLevels;
|
||||||
|
|
||||||
|
cfg.X_NUM_RS = cfg.NrRgprPorts;
|
||||||
|
cfg.X_ID_WIDTH = cfg.TRANS_ID_BITS;
|
||||||
|
cfg.X_RFR_WIDTH = cfg.XLEN;
|
||||||
|
cfg.X_RFW_WIDTH = cfg.XLEN;
|
||||||
|
cfg.X_NUM_HARTS = 1;
|
||||||
|
cfg.X_HARTID_WIDTH = cfg.XLEN;
|
||||||
|
cfg.X_DUALREAD = 0;
|
||||||
|
cfg.X_DUALWRITE = 0;
|
||||||
|
cfg.X_ISSUE_REGISTER_SPLIT = 0;
|
||||||
|
|
||||||
return cfg;
|
return cfg;
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
|
@ -337,6 +337,17 @@ package config_pkg;
|
||||||
vm_mode_t MODE_SV;
|
vm_mode_t MODE_SV;
|
||||||
int unsigned SV;
|
int unsigned SV;
|
||||||
int unsigned SVX;
|
int unsigned SVX;
|
||||||
|
|
||||||
|
int unsigned X_NUM_RS;
|
||||||
|
int unsigned X_ID_WIDTH;
|
||||||
|
int unsigned X_RFR_WIDTH;
|
||||||
|
int unsigned X_RFW_WIDTH;
|
||||||
|
int unsigned X_NUM_HARTS;
|
||||||
|
int unsigned X_HARTID_WIDTH;
|
||||||
|
int unsigned X_DUALREAD;
|
||||||
|
int unsigned X_DUALWRITE;
|
||||||
|
int unsigned X_ISSUE_REGISTER_SPLIT;
|
||||||
|
|
||||||
} cva6_cfg_t;
|
} cva6_cfg_t;
|
||||||
|
|
||||||
/// Empty configuration to sanity check proper parameter passing. Whenever
|
/// Empty configuration to sanity check proper parameter passing. Whenever
|
||||||
|
|
|
@ -18,8 +18,6 @@ package cva6_config_pkg;
|
||||||
localparam CVA6ConfigAxiDataWidth = 64; // axi_pkg.sv
|
localparam CVA6ConfigAxiDataWidth = 64; // axi_pkg.sv
|
||||||
localparam CVA6ConfigDataUserWidth = 32; // axi_pkg.sv
|
localparam CVA6ConfigDataUserWidth = 32; // axi_pkg.sv
|
||||||
|
|
||||||
localparam CVA6ConfigNrScoreboardEntries = 8; // cvxif_pkg.sv
|
|
||||||
|
|
||||||
localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{
|
localparam config_pkg::cva6_user_cfg_t cva6_cfg = '{
|
||||||
XLEN: unsigned'(CVA6ConfigXlen),
|
XLEN: unsigned'(CVA6ConfigXlen),
|
||||||
FpgaEn: bit'(0),
|
FpgaEn: bit'(0),
|
||||||
|
@ -49,7 +47,7 @@ package cva6_config_pkg;
|
||||||
RVZiCond: bit'(0),
|
RVZiCond: bit'(0),
|
||||||
RVZicntr: bit'(0),
|
RVZicntr: bit'(0),
|
||||||
RVZihpm: bit'(0),
|
RVZihpm: bit'(0),
|
||||||
NrScoreboardEntries: unsigned'(CVA6ConfigNrScoreboardEntries),
|
NrScoreboardEntries: unsigned'(8),
|
||||||
PerfCounterEn: bit'(0),
|
PerfCounterEn: bit'(0),
|
||||||
MmuPresent: bit'(0),
|
MmuPresent: bit'(0),
|
||||||
RVS: bit'(0),
|
RVS: bit'(0),
|
||||||
|
|
|
@ -1,110 +0,0 @@
|
||||||
// Copyright 2021 Thales DIS design services SAS
|
|
||||||
//
|
|
||||||
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
|
||||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
|
||||||
//
|
|
||||||
// Original Author: Guillaume CHAUVON (guillaume.chauvon@thalesgroup.com)
|
|
||||||
|
|
||||||
// Package for the CoreV-X-Interface for the CVA6
|
|
||||||
|
|
||||||
package cvxif_pkg;
|
|
||||||
|
|
||||||
localparam X_DATAWIDTH = riscv::XLEN;
|
|
||||||
localparam X_NUM_RS = ariane_pkg::NR_RGPR_PORTS; //2 or 3
|
|
||||||
localparam X_ID_WIDTH = $clog2(cva6_config_pkg::CVA6ConfigNrScoreboardEntries);
|
|
||||||
localparam X_MEM_WIDTH = 64;
|
|
||||||
localparam X_RFR_WIDTH = riscv::XLEN;
|
|
||||||
localparam X_RFW_WIDTH = riscv::XLEN;
|
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic [15:0] instr;
|
|
||||||
logic [1:0] mode;
|
|
||||||
logic [X_ID_WIDTH-1:0] id;
|
|
||||||
} x_compressed_req_t;
|
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic [31:0] instr;
|
|
||||||
logic accept;
|
|
||||||
} x_compressed_resp_t;
|
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic [31:0] instr;
|
|
||||||
logic [1:0] mode;
|
|
||||||
logic [X_ID_WIDTH-1:0] id;
|
|
||||||
logic [X_NUM_RS-1:0][X_RFR_WIDTH-1:0] rs;
|
|
||||||
logic [X_NUM_RS-1:0] rs_valid;
|
|
||||||
} x_issue_req_t;
|
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic accept;
|
|
||||||
logic writeback;
|
|
||||||
logic dualwrite;
|
|
||||||
logic dualread;
|
|
||||||
logic loadstore;
|
|
||||||
logic exc;
|
|
||||||
} x_issue_resp_t;
|
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic [X_ID_WIDTH-1:0] id;
|
|
||||||
logic x_commit_kill;
|
|
||||||
} x_commit_t;
|
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic [X_ID_WIDTH-1:0] id;
|
|
||||||
logic [31:0] addr;
|
|
||||||
logic [1:0] mode;
|
|
||||||
logic we;
|
|
||||||
logic [1:0] size;
|
|
||||||
logic [X_MEM_WIDTH-1:0] wdata;
|
|
||||||
logic last;
|
|
||||||
logic spec;
|
|
||||||
} x_mem_req_t;
|
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic exc;
|
|
||||||
logic [5:0] exccode;
|
|
||||||
} x_mem_resp_t;
|
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic [X_ID_WIDTH-1:0] id;
|
|
||||||
logic [X_MEM_WIDTH-1:0] rdata;
|
|
||||||
logic err;
|
|
||||||
} x_mem_result_t;
|
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic [X_ID_WIDTH-1:0] id;
|
|
||||||
logic [X_RFW_WIDTH-1:0] data;
|
|
||||||
logic [4:0] rd;
|
|
||||||
logic we;
|
|
||||||
logic exc;
|
|
||||||
logic [5:0] exccode;
|
|
||||||
} x_result_t;
|
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic x_compressed_valid;
|
|
||||||
x_compressed_req_t x_compressed_req;
|
|
||||||
logic x_issue_valid;
|
|
||||||
x_issue_req_t x_issue_req;
|
|
||||||
logic x_commit_valid;
|
|
||||||
x_commit_t x_commit;
|
|
||||||
logic x_mem_ready;
|
|
||||||
x_mem_resp_t x_mem_resp;
|
|
||||||
logic x_mem_result_valid;
|
|
||||||
x_mem_result_t x_mem_result;
|
|
||||||
logic x_result_ready;
|
|
||||||
} cvxif_req_t;
|
|
||||||
|
|
||||||
typedef struct packed {
|
|
||||||
logic x_compressed_ready;
|
|
||||||
x_compressed_resp_t x_compressed_resp;
|
|
||||||
logic x_issue_ready;
|
|
||||||
x_issue_resp_t x_issue_resp;
|
|
||||||
logic x_mem_valid;
|
|
||||||
x_mem_req_t x_mem_req;
|
|
||||||
logic x_result_valid;
|
|
||||||
x_result_t x_result;
|
|
||||||
} cvxif_resp_t;
|
|
||||||
|
|
||||||
endpackage
|
|
73
core/include/cvxif_types.svh
Normal file
73
core/include/cvxif_types.svh
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
`ifndef CVXIF_TYPES_SVH
|
||||||
|
`define CVXIF_TYPES_SVH
|
||||||
|
|
||||||
|
//CVXIF
|
||||||
|
`define READREGFLAGS_T(Cfg) logic [Cfg.X_NUM_RS+Cfg.X_DUALREAD-1:0]
|
||||||
|
`define WRITEREGFLAGS_T(Cfg) logic [Cfg.X_DUALWRITE:0]
|
||||||
|
`define ID_T(Cfg) logic [Cfg.X_ID_WIDTH-1:0]
|
||||||
|
`define HARTID_T(Cfg) logic [Cfg.X_HARTID_WIDTH-1:0]
|
||||||
|
|
||||||
|
`define X_COMPRESSED_REQ_T(Cfg, hartid_t) struct packed { \
|
||||||
|
logic [15:0] instr; /*Offloaded compressed instruction*/ \
|
||||||
|
hartid_t hartid; /*Identification of the hart offloading the instruction*/ \
|
||||||
|
}
|
||||||
|
`define X_COMPRESSED_RESP_T(Cfg) struct packed { \
|
||||||
|
logic [31:0] instr; /*Uncompressed instruction*/ \
|
||||||
|
logic accept; /*Is the offloaded compressed instruction (id) accepted by the coprocessor?*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
`define X_ISSUE_REQ_T(Cfg, hartit_t, id_t) struct packed { \
|
||||||
|
logic [31:0] instr; /*Offloaded instruction*/ \
|
||||||
|
hartid_t hartid; /*Identification of the hart offloading the instruction*/ \
|
||||||
|
id_t id; /*Identification of the offloaded instruction*/ \
|
||||||
|
}
|
||||||
|
`define X_ISSUE_RESP_T(Cfg, writeregflags_t, readregflags_t) struct packed { \
|
||||||
|
logic accept; /*Is the offloaded instruction (id) accepted by the coprocessor?*/ \
|
||||||
|
writeregflags_t writeback; /*Will the coprocessor perform a writeback in the core to rd?*/ \
|
||||||
|
readregflags_t register_read; /*Will the coprocessor perform require specific registers to be read?*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
`define X_REGISTER_T(Cfg, hartid_t, id_t, readregflags_t) struct packed { \
|
||||||
|
hartid_t hartid; /*Identification of the hart offloading the instruction*/ \
|
||||||
|
id_t id; /*Identification of the offloaded instruction*/ \
|
||||||
|
logic [Cfg.X_NUM_RS-1:0][Cfg.X_RFR_WIDTH-1:0] rs; /*Register file source operands for the offloaded instruction.*/ \
|
||||||
|
readregflags_t rs_valid; /*Validity of the register file source operand(s).*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
`define X_COMMIT_T(Cfg, hartid_t, id_t) struct packed { \
|
||||||
|
hartid_t hartid; /*Identification of the hart offloading the instruction*/ \
|
||||||
|
id_t id; /*Identification of the offloaded instruction*/ \
|
||||||
|
logic commit_kill; /*Shall an offloaded instruction be killed?*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
`define X_RESULT_T(Cfg, hartid_t, id_t, writeregflags_t) struct packed { \
|
||||||
|
hartid_t hartid; /*Identification of the hart offloading the instruction*/ \
|
||||||
|
id_t id; /*Identification of the offloaded instruction*/ \
|
||||||
|
logic [Cfg.X_RFW_WIDTH-1:0] data; /*Register file write data value(s)*/ \
|
||||||
|
logic [4:0] rd; /*Register file destination address(es)*/ \
|
||||||
|
writeregflags_t we; /*Register file write enable(s)*/ \
|
||||||
|
}
|
||||||
|
|
||||||
|
`define CVXIF_REQ_T(Cfg, x_compressed_req_t, x_issue_req_t, x_register_req_t, x_commit_t) struct packed { \
|
||||||
|
logic compressed_valid; \
|
||||||
|
x_compressed_req_t compressed_req; \
|
||||||
|
logic issue_valid; \
|
||||||
|
x_issue_req_t issue_req; \
|
||||||
|
logic register_valid; \
|
||||||
|
x_register_t register; \
|
||||||
|
logic commit_valid; \
|
||||||
|
x_commit_t commit; \
|
||||||
|
logic result_ready; \
|
||||||
|
}
|
||||||
|
|
||||||
|
`define CVXIF_RESP_T(Cfg, x_compressed_resp_t, x_issue_resp_t, x_result_t) struct packed { \
|
||||||
|
logic compressed_ready; \
|
||||||
|
x_compressed_resp_t compressed_resp; \
|
||||||
|
logic issue_ready; \
|
||||||
|
x_issue_resp_t issue_resp; \
|
||||||
|
logic register_ready; \
|
||||||
|
logic result_valid; \
|
||||||
|
x_result_t result; \
|
||||||
|
}
|
||||||
|
|
||||||
|
`endif // CVXIF_TYPES_SVH
|
|
@ -21,7 +21,12 @@ module issue_read_operands
|
||||||
parameter type branchpredict_sbe_t = logic,
|
parameter type branchpredict_sbe_t = logic,
|
||||||
parameter type fu_data_t = logic,
|
parameter type fu_data_t = logic,
|
||||||
parameter type scoreboard_entry_t = logic,
|
parameter type scoreboard_entry_t = logic,
|
||||||
parameter type rs3_len_t = logic
|
parameter type rs3_len_t = logic,
|
||||||
|
parameter type x_issue_req_t = logic,
|
||||||
|
parameter type x_issue_resp_t = logic,
|
||||||
|
parameter type x_register_t = logic,
|
||||||
|
parameter type x_commit_t = logic
|
||||||
|
|
||||||
) (
|
) (
|
||||||
// Subsystem Clock - SUBSYSTEM
|
// Subsystem Clock - SUBSYSTEM
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
|
@ -106,6 +111,25 @@ module issue_read_operands
|
||||||
input logic cvxif_ready_i,
|
input logic cvxif_ready_i,
|
||||||
// CVXIF offloaded instruction - TO_BE_COMPLETED
|
// CVXIF offloaded instruction - TO_BE_COMPLETED
|
||||||
output logic [31:0] cvxif_off_instr_o,
|
output logic [31:0] cvxif_off_instr_o,
|
||||||
|
// CVA6 Hart ID - SUBSYSTEM
|
||||||
|
input logic [CVA6Cfg.XLEN-1:0] hart_id_i,
|
||||||
|
// CVXIF Issue interface
|
||||||
|
input logic x_issue_ready_i,
|
||||||
|
input x_issue_resp_t x_issue_resp_i,
|
||||||
|
output logic x_issue_valid_o,
|
||||||
|
output x_issue_req_t x_issue_req_o,
|
||||||
|
// CVXIF Register interface
|
||||||
|
input logic x_register_ready_i,
|
||||||
|
output logic x_register_valid_o,
|
||||||
|
output x_register_t x_register_o,
|
||||||
|
// CVXIF Commit interface
|
||||||
|
output logic x_commit_valid_o,
|
||||||
|
output x_commit_t x_commit_o,
|
||||||
|
// Writeback Handling of CVXIF
|
||||||
|
output logic x_transaction_accepted_o,
|
||||||
|
output logic x_transaction_rejected_o,
|
||||||
|
output logic x_issue_writeback_o,
|
||||||
|
output logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_id_o,
|
||||||
// TO_BE_COMPLETED - TO_BE_COMPLETED
|
// TO_BE_COMPLETED - TO_BE_COMPLETED
|
||||||
input logic [CVA6Cfg.NrCommitPorts-1:0][4:0] waddr_i,
|
input logic [CVA6Cfg.NrCommitPorts-1:0][4:0] waddr_i,
|
||||||
// TO_BE_COMPLETED - TO_BE_COMPLETED
|
// TO_BE_COMPLETED - TO_BE_COMPLETED
|
||||||
|
@ -125,7 +149,7 @@ module issue_read_operands
|
||||||
logic none, load, store, alu, alu2, ctrl_flow, mult, csr, fpu, fpu_vec, cvxif, accel;
|
logic none, load, store, alu, alu2, ctrl_flow, mult, csr, fpu, fpu_vec, cvxif, accel;
|
||||||
} fus_busy_t;
|
} fus_busy_t;
|
||||||
|
|
||||||
logic [CVA6Cfg.NrIssuePorts-1:0] stall;
|
logic [CVA6Cfg.NrIssuePorts-1:0] stall, stall_rs1, stall_rs2, stall_rs3;
|
||||||
logic [CVA6Cfg.NrIssuePorts-1:0] fu_busy; // functional unit is busy
|
logic [CVA6Cfg.NrIssuePorts-1:0] fu_busy; // functional unit is busy
|
||||||
fus_busy_t [CVA6Cfg.NrIssuePorts-1:0] fus_busy; // which functional units are considered busy
|
fus_busy_t [CVA6Cfg.NrIssuePorts-1:0] fus_busy; // which functional units are considered busy
|
||||||
// operands coming from regfile
|
// operands coming from regfile
|
||||||
|
@ -148,6 +172,8 @@ module issue_read_operands
|
||||||
logic [CVA6Cfg.NrIssuePorts-1:0] branch_valid_q;
|
logic [CVA6Cfg.NrIssuePorts-1:0] branch_valid_q;
|
||||||
logic [CVA6Cfg.NrIssuePorts-1:0] cvxif_valid_q;
|
logic [CVA6Cfg.NrIssuePorts-1:0] cvxif_valid_q;
|
||||||
logic [ 31:0] cvxif_off_instr_q;
|
logic [ 31:0] cvxif_off_instr_q;
|
||||||
|
logic cvxif_instruction_valid;
|
||||||
|
|
||||||
|
|
||||||
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] tinst_n, tinst_q; // transformed instruction
|
logic [CVA6Cfg.NrIssuePorts-1:0][31:0] tinst_n, tinst_q; // transformed instruction
|
||||||
|
|
||||||
|
@ -158,6 +184,54 @@ module issue_read_operands
|
||||||
riscv::instruction_t orig_instr;
|
riscv::instruction_t orig_instr;
|
||||||
assign orig_instr = riscv::instruction_t'(orig_instr_i[0]);
|
assign orig_instr = riscv::instruction_t'(orig_instr_i[0]);
|
||||||
|
|
||||||
|
// CVXIF Signals
|
||||||
|
logic cvxif_busy;
|
||||||
|
logic x_transaction_rejected;
|
||||||
|
logic [CVA6Cfg.NrRgprPorts-1:0] rs_valid;
|
||||||
|
logic [CVA6Cfg.NrRgprPorts-1:0][CVA6Cfg.XLEN-1:0] rs;
|
||||||
|
|
||||||
|
cvxif_issue_register_commit_if_driver #(
|
||||||
|
.CVA6Cfg (CVA6Cfg),
|
||||||
|
.x_issue_req_t (x_issue_req_t),
|
||||||
|
.x_issue_resp_t(x_issue_resp_t),
|
||||||
|
.x_register_t (x_register_t),
|
||||||
|
.x_commit_t (x_commit_t)
|
||||||
|
) i_cvxif_issue_register_commit_if_driver (
|
||||||
|
.clk_i (clk_i),
|
||||||
|
.rst_ni (rst_ni),
|
||||||
|
.flush_i (flush_i),
|
||||||
|
.hart_id_i (hart_id_i),
|
||||||
|
.issue_ready_i (x_issue_ready_i),
|
||||||
|
.issue_resp_i (x_issue_resp_i),
|
||||||
|
.issue_valid_o (x_issue_valid_o),
|
||||||
|
.issue_req_o (x_issue_req_o),
|
||||||
|
.register_ready_i(x_register_ready_i),
|
||||||
|
.register_valid_o(x_register_valid_o),
|
||||||
|
.register_o (x_register_o),
|
||||||
|
.commit_valid_o (x_commit_valid_o),
|
||||||
|
.commit_o (x_commit_o),
|
||||||
|
.valid_i (cvxif_instruction_valid),
|
||||||
|
.x_off_instr_i (orig_instr_i[0]),
|
||||||
|
.x_trans_id_i (issue_instr_i[0].trans_id),
|
||||||
|
.register_i (rs),
|
||||||
|
.rs_valid_i (rs_valid),
|
||||||
|
.cvxif_busy_o (cvxif_busy)
|
||||||
|
);
|
||||||
|
if (OPERANDS_PER_INSTR == 3) begin
|
||||||
|
assign rs_valid = {~stall_rs3[0], ~stall_rs2[0], ~stall_rs1[0]};
|
||||||
|
assign rs = {fu_data_n[0].imm, fu_data_n[0].operand_b, fu_data_n[0].operand_a};
|
||||||
|
end else begin
|
||||||
|
assign rs_valid = {~stall_rs2[0], ~stall_rs1[0]};
|
||||||
|
assign rs = {fu_data_n[0].operand_b, fu_data_n[0].operand_a};
|
||||||
|
end
|
||||||
|
|
||||||
|
// TODO check only for 1st instruction ??
|
||||||
|
assign cvxif_instruction_valid = (!issue_instr_i[0].ex.valid && issue_instr_valid_i[0] && (issue_instr_i[0].fu == CVXIF));
|
||||||
|
assign x_transaction_accepted_o = x_issue_valid_o && x_issue_ready_i && x_issue_resp_i.accept;
|
||||||
|
assign x_transaction_rejected = x_issue_valid_o && x_issue_ready_i && ~x_issue_resp_i.accept;
|
||||||
|
assign x_issue_writeback_o = x_issue_resp_i.writeback;
|
||||||
|
assign x_id_o = x_issue_req_o.id;
|
||||||
|
|
||||||
// ID <-> EX registers
|
// ID <-> EX registers
|
||||||
|
|
||||||
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
||||||
|
@ -212,7 +286,7 @@ module issue_read_operands
|
||||||
fus_busy[0].store = 1'b1;
|
fus_busy[0].store = 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (!cvxif_ready_i) begin
|
if (cvxif_busy) begin
|
||||||
fus_busy[0].cvxif = 1'b1;
|
fus_busy[0].cvxif = 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -310,6 +384,9 @@ module issue_read_operands
|
||||||
// forward corresponding register
|
// forward corresponding register
|
||||||
always_comb begin : operands_available
|
always_comb begin : operands_available
|
||||||
stall = '{default: stall_i};
|
stall = '{default: stall_i};
|
||||||
|
stall_rs1 = '{default: stall_i};
|
||||||
|
stall_rs2 = '{default: stall_i};
|
||||||
|
stall_rs3 = '{default: stall_i};
|
||||||
// operand forwarding signals
|
// operand forwarding signals
|
||||||
forward_rs1 = '0;
|
forward_rs1 = '0;
|
||||||
forward_rs2 = '0;
|
forward_rs2 = '0;
|
||||||
|
@ -323,12 +400,16 @@ module issue_read_operands
|
||||||
|
|
||||||
// 0. check that we are not using the zimm type in RS1
|
// 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
|
// as this is an immediate we do not have to wait on anything here
|
||||||
|
// 0.bis check that rs1 is required by coprocessor if not do not wait here
|
||||||
// 1. check if the source registers are clobbered --> check appropriate clobber list (gpr/fpr)
|
// 1. check if the source registers are clobbered --> check appropriate clobber list (gpr/fpr)
|
||||||
// 2. poll the scoreboard
|
// 2. poll the scoreboard
|
||||||
if (!issue_instr_i[i].use_zimm && ((CVA6Cfg.FpPresent && is_rs1_fpr(
|
if (!issue_instr_i[i].use_zimm && ((CVA6Cfg.FpPresent && is_rs1_fpr(
|
||||||
issue_instr_i[i].op
|
issue_instr_i[i].op
|
||||||
)) ? rd_clobber_fpr_i[issue_instr_i[i].rs1] != NONE :
|
)) ? rd_clobber_fpr_i[issue_instr_i[i].rs1] != NONE :
|
||||||
rd_clobber_gpr_i[issue_instr_i[i].rs1] != NONE)) begin
|
rd_clobber_gpr_i[issue_instr_i[i].rs1] != NONE) ||
|
||||||
|
((CVA6Cfg.CvxifEn && x_issue_valid_o &&
|
||||||
|
x_issue_resp_i.accept && x_issue_resp_i.register_read[0]) &&
|
||||||
|
rd_clobber_gpr_i[issue_instr_i[i].rs1] != NONE)) begin
|
||||||
// check if the clobbering instruction is not a CSR instruction, CSR instructions can only
|
// check if the clobbering instruction is not a CSR instruction, CSR instructions can only
|
||||||
// be fetched through the register file since they can't be forwarded
|
// be fetched through the register file since they can't be forwarded
|
||||||
// if the operand is available, forward it. CSRs don't write to/from FPR
|
// if the operand is available, forward it. CSRs don't write to/from FPR
|
||||||
|
@ -339,13 +420,17 @@ module issue_read_operands
|
||||||
forward_rs1[i] = 1'b1;
|
forward_rs1[i] = 1'b1;
|
||||||
end else begin // the operand is not available -> stall
|
end else begin // the operand is not available -> stall
|
||||||
stall[i] = 1'b1;
|
stall[i] = 1'b1;
|
||||||
|
stall_rs1[i] = 1'b1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if ((CVA6Cfg.FpPresent && is_rs2_fpr(
|
if (((CVA6Cfg.FpPresent && is_rs2_fpr(
|
||||||
issue_instr_i[i].op
|
issue_instr_i[i].op
|
||||||
)) ? rd_clobber_fpr_i[issue_instr_i[i].rs2] != NONE :
|
)) ? rd_clobber_fpr_i[issue_instr_i[i].rs2] != NONE :
|
||||||
rd_clobber_gpr_i[issue_instr_i[i].rs2] != NONE) begin
|
rd_clobber_gpr_i[issue_instr_i[i].rs2] != NONE) ||
|
||||||
|
((CVA6Cfg.CvxifEn &&
|
||||||
|
x_issue_valid_o && x_issue_resp_i.accept && x_issue_resp_i.register_read[1]) &&
|
||||||
|
rd_clobber_gpr_i[issue_instr_i[i].rs2] != NONE)) begin
|
||||||
// if the operand is available, forward it. CSRs don't write to/from FPR
|
// if the operand is available, forward it. CSRs don't write to/from FPR
|
||||||
if (rs2_valid_i[i] && (CVA6Cfg.FpPresent && is_rs2_fpr(
|
if (rs2_valid_i[i] && (CVA6Cfg.FpPresent && is_rs2_fpr(
|
||||||
issue_instr_i[i].op
|
issue_instr_i[i].op
|
||||||
|
@ -354,20 +439,23 @@ module issue_read_operands
|
||||||
forward_rs2[i] = 1'b1;
|
forward_rs2[i] = 1'b1;
|
||||||
end else begin // the operand is not available -> stall
|
end else begin // the operand is not available -> stall
|
||||||
stall[i] = 1'b1;
|
stall[i] = 1'b1;
|
||||||
|
stall_rs2[i] = 1'b1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// Only check clobbered gpr for OFFLOADED instruction
|
// Only check clobbered gpr for OFFLOADED instruction
|
||||||
if ((CVA6Cfg.FpPresent && is_imm_fpr(
|
if (((CVA6Cfg.FpPresent && is_imm_fpr(
|
||||||
issue_instr_i[i].op
|
issue_instr_i[i].op
|
||||||
)) ? rd_clobber_fpr_i[issue_instr_i[i].result[REG_ADDR_SIZE-1:0]] != NONE :
|
)) ? rd_clobber_fpr_i[issue_instr_i[i].result[REG_ADDR_SIZE-1:0]] != NONE : 0) ||
|
||||||
issue_instr_i[i].op == OFFLOAD && CVA6Cfg.NrRgprPorts == 3 ?
|
((CVA6Cfg.CvxifEn && OPERANDS_PER_INSTR == 3 &&
|
||||||
rd_clobber_gpr_i[issue_instr_i[i].result[REG_ADDR_SIZE-1:0]] != NONE : 0) begin
|
x_issue_valid_o && x_issue_resp_i.accept && x_issue_resp_i.register_read[2]) &&
|
||||||
|
rd_clobber_gpr_i[issue_instr_i[i].result] != NONE)) begin
|
||||||
// if the operand is available, forward it. CSRs don't write to/from FPR so no need to check
|
// if the operand is available, forward it. CSRs don't write to/from FPR so no need to check
|
||||||
if (rs3_valid_i[i]) begin
|
if (rs3_valid_i[i]) begin
|
||||||
forward_rs3[i] = 1'b1;
|
forward_rs3[i] = 1'b1;
|
||||||
end else begin // the operand is not available -> stall
|
end else begin // the operand is not available -> stall
|
||||||
stall[i] = 1'b1;
|
stall[i] = 1'b1;
|
||||||
|
stall_rs3[i] = 1'b1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -395,7 +483,7 @@ module issue_read_operands
|
||||||
)) ? is_rd_fpr(
|
)) ? is_rd_fpr(
|
||||||
issue_instr_i[0].op
|
issue_instr_i[0].op
|
||||||
) && issue_instr_i[0].rd == issue_instr_i[1].result[REG_ADDR_SIZE-1:0] :
|
) && issue_instr_i[0].rd == issue_instr_i[1].result[REG_ADDR_SIZE-1:0] :
|
||||||
issue_instr_i[1].op == OFFLOAD && CVA6Cfg.NrRgprPorts == 3 ?
|
issue_instr_i[1].op == OFFLOAD && OPERANDS_PER_INSTR == 3 ?
|
||||||
issue_instr_i[0].rd == issue_instr_i[1].result[REG_ADDR_SIZE-1:0] : 1'b0) begin
|
issue_instr_i[0].rd == issue_instr_i[1].result[REG_ADDR_SIZE-1:0] : 1'b0) begin
|
||||||
stall[1] = 1'b1;
|
stall[1] = 1'b1;
|
||||||
end
|
end
|
||||||
|
@ -403,7 +491,7 @@ module issue_read_operands
|
||||||
end
|
end
|
||||||
|
|
||||||
// third operand from fp regfile or gp regfile if NR_RGPR_PORTS == 3
|
// third operand from fp regfile or gp regfile if NR_RGPR_PORTS == 3
|
||||||
if (CVA6Cfg.NrRgprPorts == 3) begin : gen_gp_rs3
|
if (OPERANDS_PER_INSTR == 3) begin : gen_gp_rs3
|
||||||
assign imm_forward_rs3 = rs3_i[0];
|
assign imm_forward_rs3 = rs3_i[0];
|
||||||
end else begin : gen_fp_rs3
|
end else begin : gen_fp_rs3
|
||||||
assign imm_forward_rs3 = {{CVA6Cfg.XLEN - CVA6Cfg.FLen{1'b0}}, rs3_i[0]};
|
assign imm_forward_rs3 = {{CVA6Cfg.XLEN - CVA6Cfg.FLen{1'b0}}, rs3_i[0]};
|
||||||
|
@ -418,7 +506,7 @@ module issue_read_operands
|
||||||
|
|
||||||
// immediates are the third operands in the store case
|
// immediates are the third operands in the store case
|
||||||
// for FP operations, the imm field can also be the third operand from the regfile
|
// for FP operations, the imm field can also be the third operand from the regfile
|
||||||
if (CVA6Cfg.NrRgprPorts == 3) begin
|
if (OPERANDS_PER_INSTR == 3) begin
|
||||||
fu_data_n[i].imm = (CVA6Cfg.FpPresent && is_imm_fpr(issue_instr_i[i].op)) ?
|
fu_data_n[i].imm = (CVA6Cfg.FpPresent && is_imm_fpr(issue_instr_i[i].op)) ?
|
||||||
{{CVA6Cfg.XLEN - CVA6Cfg.FLen{1'b0}}, operand_c_regfile[i]} :
|
{{CVA6Cfg.XLEN - CVA6Cfg.FLen{1'b0}}, operand_c_regfile[i]} :
|
||||||
issue_instr_i[i].op == OFFLOAD ? operand_c_regfile[i] : issue_instr_i[i].result;
|
issue_instr_i[i].op == OFFLOAD ? operand_c_regfile[i] : issue_instr_i[i].result;
|
||||||
|
@ -440,7 +528,7 @@ module issue_read_operands
|
||||||
if (forward_rs2[i]) begin
|
if (forward_rs2[i]) begin
|
||||||
fu_data_n[i].operand_b = rs2_i[i];
|
fu_data_n[i].operand_b = rs2_i[i];
|
||||||
end
|
end
|
||||||
if (CVA6Cfg.FpPresent && forward_rs3[i]) begin
|
if ((CVA6Cfg.FpPresent || (CVA6Cfg.CvxifEn && OPERANDS_PER_INSTR == 3)) && forward_rs3[i]) begin
|
||||||
fu_data_n[i].imm = imm_forward_rs3;
|
fu_data_n[i].imm = imm_forward_rs3;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -555,7 +643,7 @@ module issue_read_operands
|
||||||
case (issue_instr_i[i].fu)
|
case (issue_instr_i[i].fu)
|
||||||
CVXIF: begin
|
CVXIF: begin
|
||||||
cvxif_valid_q[i] <= 1'b1;
|
cvxif_valid_q[i] <= 1'b1;
|
||||||
cvxif_off_instr_q <= orig_instr;
|
cvxif_off_instr_q <= orig_instr[i];
|
||||||
end
|
end
|
||||||
default: ;
|
default: ;
|
||||||
endcase
|
endcase
|
||||||
|
@ -619,6 +707,9 @@ module issue_read_operands
|
||||||
if (issue_instr_i[i].fu == NONE) begin
|
if (issue_instr_i[i].fu == NONE) begin
|
||||||
issue_ack_o[i] = 1'b1;
|
issue_ack_o[i] = 1'b1;
|
||||||
end
|
end
|
||||||
|
if (issue_instr_i[i].fu == CVXIF) begin
|
||||||
|
issue_ack_o[i] = (x_transaction_accepted_o || x_transaction_rejected);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -749,14 +840,14 @@ module issue_read_operands
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
if (CVA6Cfg.NrRgprPorts == 3) begin : gen_operand_c
|
if (OPERANDS_PER_INSTR == 3) begin : gen_operand_c
|
||||||
assign operand_c_fpr = {{CVA6Cfg.XLEN - CVA6Cfg.FLen{1'b0}}, fprdata[2]};
|
assign operand_c_fpr = {{CVA6Cfg.XLEN - CVA6Cfg.FLen{1'b0}}, fprdata[2]};
|
||||||
end else begin
|
end else begin
|
||||||
assign operand_c_fpr = fprdata[2];
|
assign operand_c_fpr = fprdata[2];
|
||||||
end
|
end
|
||||||
|
|
||||||
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
for (genvar i = 0; i < CVA6Cfg.NrIssuePorts; i++) begin
|
||||||
if (CVA6Cfg.NrRgprPorts == 3) begin : gen_operand_c
|
if (OPERANDS_PER_INSTR == 3) begin : gen_operand_c
|
||||||
assign operand_c_gpr[i] = rdata[i*OPERANDS_PER_INSTR+2];
|
assign operand_c_gpr[i] = rdata[i*OPERANDS_PER_INSTR+2];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -766,7 +857,7 @@ module issue_read_operands
|
||||||
assign operand_b_regfile[i] = (CVA6Cfg.FpPresent && is_rs2_fpr(
|
assign operand_b_regfile[i] = (CVA6Cfg.FpPresent && is_rs2_fpr(
|
||||||
issue_instr_i[i].op
|
issue_instr_i[i].op
|
||||||
)) ? {{CVA6Cfg.XLEN - CVA6Cfg.FLen{1'b0}}, fprdata[1]} : rdata[i*OPERANDS_PER_INSTR+1];
|
)) ? {{CVA6Cfg.XLEN - CVA6Cfg.FLen{1'b0}}, fprdata[1]} : rdata[i*OPERANDS_PER_INSTR+1];
|
||||||
assign operand_c_regfile[i] = (CVA6Cfg.NrRgprPorts == 3) ? ((CVA6Cfg.FpPresent && is_imm_fpr(
|
assign operand_c_regfile[i] = (OPERANDS_PER_INSTR == 3) ? ((CVA6Cfg.FpPresent && is_imm_fpr(
|
||||||
issue_instr_i[i].op
|
issue_instr_i[i].op
|
||||||
)) ? operand_c_fpr : operand_c_gpr[i]) : operand_c_fpr;
|
)) ? operand_c_fpr : operand_c_gpr[i]) : operand_c_fpr;
|
||||||
end
|
end
|
||||||
|
@ -780,9 +871,10 @@ module issue_read_operands
|
||||||
if (CVA6Cfg.RVH) begin
|
if (CVA6Cfg.RVH) begin
|
||||||
tinst_q <= '0;
|
tinst_q <= '0;
|
||||||
end
|
end
|
||||||
pc_o <= '0;
|
pc_o <= '0;
|
||||||
is_compressed_instr_o <= 1'b0;
|
is_compressed_instr_o <= 1'b0;
|
||||||
branch_predict_o <= {cf_t'(0), {CVA6Cfg.VLEN{1'b0}}};
|
branch_predict_o <= {cf_t'(0), {CVA6Cfg.VLEN{1'b0}}};
|
||||||
|
x_transaction_rejected_o <= 1'b0;
|
||||||
end else begin
|
end else begin
|
||||||
fu_data_q <= fu_data_n;
|
fu_data_q <= fu_data_n;
|
||||||
if (CVA6Cfg.RVH) begin
|
if (CVA6Cfg.RVH) begin
|
||||||
|
@ -800,6 +892,10 @@ module issue_read_operands
|
||||||
is_compressed_instr_o <= issue_instr_i[0].is_compressed;
|
is_compressed_instr_o <= issue_instr_i[0].is_compressed;
|
||||||
branch_predict_o <= issue_instr_i[0].bp;
|
branch_predict_o <= issue_instr_i[0].bp;
|
||||||
end
|
end
|
||||||
|
x_transaction_rejected_o <= 1'b0;
|
||||||
|
if (issue_instr_i[0].fu == CVXIF) begin
|
||||||
|
x_transaction_rejected_o <= x_transaction_rejected;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,11 @@ module issue_stage
|
||||||
parameter type branchpredict_sbe_t = logic,
|
parameter type branchpredict_sbe_t = logic,
|
||||||
parameter type exception_t = logic,
|
parameter type exception_t = logic,
|
||||||
parameter type fu_data_t = logic,
|
parameter type fu_data_t = logic,
|
||||||
parameter type scoreboard_entry_t = logic
|
parameter type scoreboard_entry_t = logic,
|
||||||
|
parameter type x_issue_req_t = logic,
|
||||||
|
parameter type x_issue_resp_t = logic,
|
||||||
|
parameter type x_register_t = logic,
|
||||||
|
parameter type x_commit_t = logic
|
||||||
) (
|
) (
|
||||||
// Subsystem Clock - SUBSYSTEM
|
// Subsystem Clock - SUBSYSTEM
|
||||||
input logic clk_i,
|
input logic clk_i,
|
||||||
|
@ -87,11 +91,27 @@ module issue_stage
|
||||||
// CSR is valid - EX_STAGE
|
// CSR is valid - EX_STAGE
|
||||||
output logic [CVA6Cfg.NrIssuePorts-1:0] csr_valid_o,
|
output logic [CVA6Cfg.NrIssuePorts-1:0] csr_valid_o,
|
||||||
// CVXIF FU is valid - EX_STAGE
|
// CVXIF FU is valid - EX_STAGE
|
||||||
output logic [CVA6Cfg.NrIssuePorts-1:0] x_issue_valid_o,
|
output logic [CVA6Cfg.NrIssuePorts-1:0] xfu_valid_o,
|
||||||
// CVXIF is FU ready - EX_STAGE
|
// CVXIF is FU ready - EX_STAGE
|
||||||
input logic x_issue_ready_i,
|
input logic xfu_ready_i,
|
||||||
// CVXIF offloader instruction value - EX_STAGE
|
// CVXIF offloader instruction value - EX_STAGE
|
||||||
output logic [31:0] x_off_instr_o,
|
output logic [31:0] x_off_instr_o,
|
||||||
|
// CVA6 Hart ID - SUBSYSTEM
|
||||||
|
input logic [CVA6Cfg.XLEN-1:0] hart_id_i,
|
||||||
|
// CVXIF Issue interface
|
||||||
|
input logic x_issue_ready_i,
|
||||||
|
input x_issue_resp_t x_issue_resp_i,
|
||||||
|
output logic x_issue_valid_o,
|
||||||
|
output x_issue_req_t x_issue_req_o,
|
||||||
|
// CVXIF Register interface
|
||||||
|
input logic x_register_ready_i,
|
||||||
|
output logic x_register_valid_o,
|
||||||
|
output x_register_t x_register_o,
|
||||||
|
// CVXIF Commit interface
|
||||||
|
output logic x_commit_valid_o,
|
||||||
|
output x_commit_t x_commit_o,
|
||||||
|
// CVXIF Transaction rejected -> instruction is illegal - EX_STAGE
|
||||||
|
output logic x_transaction_rejected_o,
|
||||||
// Issue scoreboard entry - ACC_DISPATCHER
|
// Issue scoreboard entry - ACC_DISPATCHER
|
||||||
output scoreboard_entry_t issue_instr_o,
|
output scoreboard_entry_t issue_instr_o,
|
||||||
// TO_BE_COMPLETED - ACC_DISPATCHER
|
// TO_BE_COMPLETED - ACC_DISPATCHER
|
||||||
|
@ -108,6 +128,8 @@ module issue_stage
|
||||||
input logic [CVA6Cfg.NrWbPorts-1:0] wt_valid_i,
|
input logic [CVA6Cfg.NrWbPorts-1:0] wt_valid_i,
|
||||||
// CVXIF write enable - EX_STAGE
|
// CVXIF write enable - EX_STAGE
|
||||||
input logic x_we_i,
|
input logic x_we_i,
|
||||||
|
// CVXIF destination register - ISSUE_STAGE
|
||||||
|
input logic [4:0] x_rd_i,
|
||||||
// TO_BE_COMPLETED - EX_STAGE
|
// TO_BE_COMPLETED - EX_STAGE
|
||||||
input logic [CVA6Cfg.NrCommitPorts-1:0][4:0] waddr_i,
|
input logic [CVA6Cfg.NrCommitPorts-1:0][4:0] waddr_i,
|
||||||
// TO_BE_COMPLETED - EX_STAGE
|
// TO_BE_COMPLETED - EX_STAGE
|
||||||
|
@ -165,6 +187,9 @@ module issue_stage
|
||||||
assign issue_instr_o = issue_instr_sb_iro[0];
|
assign issue_instr_o = issue_instr_sb_iro[0];
|
||||||
assign issue_instr_hs_o = issue_instr_valid_sb_iro[0] & issue_ack_iro_sb[0];
|
assign issue_instr_hs_o = issue_instr_valid_sb_iro[0] & issue_ack_iro_sb[0];
|
||||||
|
|
||||||
|
logic x_transaction_accepted_iro_sb, x_issue_writeback_iro_sb;
|
||||||
|
logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_id_iro_sb;
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
// 2. Manage instructions in a scoreboard
|
// 2. Manage instructions in a scoreboard
|
||||||
|
@ -176,18 +201,21 @@ module issue_stage
|
||||||
.exception_t(exception_t),
|
.exception_t(exception_t),
|
||||||
.scoreboard_entry_t(scoreboard_entry_t)
|
.scoreboard_entry_t(scoreboard_entry_t)
|
||||||
) i_scoreboard (
|
) i_scoreboard (
|
||||||
.sb_full_o (sb_full_o),
|
.sb_full_o (sb_full_o),
|
||||||
.rd_clobber_gpr_o(rd_clobber_gpr_sb_iro),
|
.rd_clobber_gpr_o (rd_clobber_gpr_sb_iro),
|
||||||
.rd_clobber_fpr_o(rd_clobber_fpr_sb_iro),
|
.rd_clobber_fpr_o (rd_clobber_fpr_sb_iro),
|
||||||
.rs1_i (rs1_iro_sb),
|
.x_transaction_accepted_i(x_transaction_accepted_iro_sb),
|
||||||
.rs1_o (rs1_sb_iro),
|
.x_issue_writeback_i (x_issue_writeback_iro_sb),
|
||||||
.rs1_valid_o (rs1_valid_sb_iro),
|
.x_id_i (x_id_iro_sb),
|
||||||
.rs2_i (rs2_iro_sb),
|
.rs1_i (rs1_iro_sb),
|
||||||
.rs2_o (rs2_sb_iro),
|
.rs1_o (rs1_sb_iro),
|
||||||
.rs2_valid_o (rs2_valid_iro_sb),
|
.rs1_valid_o (rs1_valid_sb_iro),
|
||||||
.rs3_i (rs3_iro_sb),
|
.rs2_i (rs2_iro_sb),
|
||||||
.rs3_o (rs3_sb_iro),
|
.rs2_o (rs2_sb_iro),
|
||||||
.rs3_valid_o (rs3_valid_iro_sb),
|
.rs2_valid_o (rs2_valid_iro_sb),
|
||||||
|
.rs3_i (rs3_iro_sb),
|
||||||
|
.rs3_o (rs3_sb_iro),
|
||||||
|
.rs3_valid_o (rs3_valid_iro_sb),
|
||||||
|
|
||||||
.decoded_instr_i (decoded_instr_i),
|
.decoded_instr_i (decoded_instr_i),
|
||||||
.decoded_instr_valid_i(decoded_instr_valid_i),
|
.decoded_instr_valid_i(decoded_instr_valid_i),
|
||||||
|
@ -212,38 +240,56 @@ module issue_stage
|
||||||
.branchpredict_sbe_t(branchpredict_sbe_t),
|
.branchpredict_sbe_t(branchpredict_sbe_t),
|
||||||
.fu_data_t(fu_data_t),
|
.fu_data_t(fu_data_t),
|
||||||
.scoreboard_entry_t(scoreboard_entry_t),
|
.scoreboard_entry_t(scoreboard_entry_t),
|
||||||
.rs3_len_t(rs3_len_t)
|
.rs3_len_t(rs3_len_t),
|
||||||
|
.x_issue_req_t(x_issue_req_t),
|
||||||
|
.x_issue_resp_t(x_issue_resp_t),
|
||||||
|
.x_register_t(x_register_t),
|
||||||
|
.x_commit_t(x_commit_t)
|
||||||
) i_issue_read_operands (
|
) i_issue_read_operands (
|
||||||
.flush_i (flush_unissued_instr_i),
|
.flush_i (flush_unissued_instr_i),
|
||||||
.issue_instr_i (issue_instr_sb_iro),
|
.issue_instr_i (issue_instr_sb_iro),
|
||||||
.orig_instr_i (orig_instr_sb_iro),
|
.orig_instr_i (orig_instr_sb_iro),
|
||||||
.issue_instr_valid_i(issue_instr_valid_sb_iro),
|
.issue_instr_valid_i (issue_instr_valid_sb_iro),
|
||||||
.issue_ack_o (issue_ack_iro_sb),
|
.issue_ack_o (issue_ack_iro_sb),
|
||||||
.fu_data_o (fu_data_o),
|
.fu_data_o (fu_data_o),
|
||||||
.flu_ready_i (flu_ready_i),
|
.flu_ready_i (flu_ready_i),
|
||||||
.rs1_o (rs1_iro_sb),
|
.rs1_o (rs1_iro_sb),
|
||||||
.rs1_i (rs1_sb_iro),
|
.rs1_i (rs1_sb_iro),
|
||||||
.rs1_valid_i (rs1_valid_sb_iro),
|
.rs1_valid_i (rs1_valid_sb_iro),
|
||||||
.rs2_o (rs2_iro_sb),
|
.rs2_o (rs2_iro_sb),
|
||||||
.rs2_i (rs2_sb_iro),
|
.rs2_i (rs2_sb_iro),
|
||||||
.rs2_valid_i (rs2_valid_iro_sb),
|
.rs2_valid_i (rs2_valid_iro_sb),
|
||||||
.rs3_o (rs3_iro_sb),
|
.rs3_o (rs3_iro_sb),
|
||||||
.rs3_i (rs3_sb_iro),
|
.rs3_i (rs3_sb_iro),
|
||||||
.rs3_valid_i (rs3_valid_iro_sb),
|
.rs3_valid_i (rs3_valid_iro_sb),
|
||||||
.rd_clobber_gpr_i (rd_clobber_gpr_sb_iro),
|
.rd_clobber_gpr_i (rd_clobber_gpr_sb_iro),
|
||||||
.rd_clobber_fpr_i (rd_clobber_fpr_sb_iro),
|
.rd_clobber_fpr_i (rd_clobber_fpr_sb_iro),
|
||||||
.alu_valid_o (alu_valid_o),
|
.alu_valid_o (alu_valid_o),
|
||||||
.alu2_valid_o (alu2_valid_o),
|
.alu2_valid_o (alu2_valid_o),
|
||||||
.branch_valid_o (branch_valid_o),
|
.branch_valid_o (branch_valid_o),
|
||||||
.csr_valid_o (csr_valid_o),
|
.csr_valid_o (csr_valid_o),
|
||||||
.cvxif_valid_o (x_issue_valid_o),
|
.cvxif_valid_o (xfu_valid_o),
|
||||||
.cvxif_ready_i (x_issue_ready_i),
|
.cvxif_ready_i (xfu_ready_i),
|
||||||
.cvxif_off_instr_o (x_off_instr_o),
|
.hart_id_i (hart_id_i),
|
||||||
.mult_valid_o (mult_valid_o),
|
.x_issue_ready_i (x_issue_ready_i),
|
||||||
.rs1_forwarding_o (rs1_forwarding_xlen),
|
.x_issue_resp_i (x_issue_resp_i),
|
||||||
.rs2_forwarding_o (rs2_forwarding_xlen),
|
.x_issue_valid_o (x_issue_valid_o),
|
||||||
.stall_issue_o (stall_issue_o),
|
.x_issue_req_o (x_issue_req_o),
|
||||||
.tinst_o (tinst_o),
|
.x_register_ready_i (x_register_ready_i),
|
||||||
|
.x_register_valid_o (x_register_valid_o),
|
||||||
|
.x_register_o (x_register_o),
|
||||||
|
.x_commit_valid_o (x_commit_valid_o),
|
||||||
|
.x_commit_o (x_commit_o),
|
||||||
|
.x_transaction_accepted_o(x_transaction_accepted_iro_sb),
|
||||||
|
.x_transaction_rejected_o(x_transaction_rejected_o),
|
||||||
|
.x_issue_writeback_o (x_issue_writeback_iro_sb),
|
||||||
|
.x_id_o (x_id_iro_sb),
|
||||||
|
.cvxif_off_instr_o (x_off_instr_o),
|
||||||
|
.mult_valid_o (mult_valid_o),
|
||||||
|
.rs1_forwarding_o (rs1_forwarding_xlen),
|
||||||
|
.rs2_forwarding_o (rs2_forwarding_xlen),
|
||||||
|
.stall_issue_o (stall_issue_o),
|
||||||
|
.tinst_o (tinst_o),
|
||||||
.*
|
.*
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -33,13 +33,16 @@ module scoreboard #(
|
||||||
output ariane_pkg::fu_t [2**ariane_pkg::REG_ADDR_SIZE-1:0] rd_clobber_gpr_o,
|
output ariane_pkg::fu_t [2**ariane_pkg::REG_ADDR_SIZE-1:0] rd_clobber_gpr_o,
|
||||||
// TO_BE_COMPLETED - TO_BE_COMPLETED
|
// TO_BE_COMPLETED - TO_BE_COMPLETED
|
||||||
output ariane_pkg::fu_t [2**ariane_pkg::REG_ADDR_SIZE-1:0] rd_clobber_fpr_o,
|
output ariane_pkg::fu_t [2**ariane_pkg::REG_ADDR_SIZE-1:0] rd_clobber_fpr_o,
|
||||||
|
// Writeback Handling of CVXIF
|
||||||
|
input logic x_transaction_accepted_i,
|
||||||
|
input logic x_issue_writeback_i,
|
||||||
|
input logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_id_i,
|
||||||
// rs1 operand address - issue_read_operands
|
// rs1 operand address - issue_read_operands
|
||||||
input logic [CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] rs1_i,
|
input logic [CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] rs1_i,
|
||||||
// rs1 operand - issue_read_operands
|
// rs1 operand - issue_read_operands
|
||||||
output logic [CVA6Cfg.NrIssuePorts-1:0][ CVA6Cfg.XLEN-1:0] rs1_o,
|
output logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs1_o,
|
||||||
// rs1 operand is valid - issue_read_operands
|
// rs1 operand is valid - issue_read_operands
|
||||||
output logic [CVA6Cfg.NrIssuePorts-1:0] rs1_valid_o,
|
output logic [CVA6Cfg.NrIssuePorts-1:0] rs1_valid_o,
|
||||||
|
|
||||||
// rs2 operand address - issue_read_operands
|
// rs2 operand address - issue_read_operands
|
||||||
input logic [CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] rs2_i,
|
input logic [CVA6Cfg.NrIssuePorts-1:0][ariane_pkg::REG_ADDR_SIZE-1:0] rs2_i,
|
||||||
|
@ -96,6 +99,8 @@ module scoreboard #(
|
||||||
input logic [CVA6Cfg.NrWbPorts-1:0] wt_valid_i,
|
input logic [CVA6Cfg.NrWbPorts-1:0] wt_valid_i,
|
||||||
// Cvxif we for writeback - TO_BE_COMPLETED
|
// Cvxif we for writeback - TO_BE_COMPLETED
|
||||||
input logic x_we_i,
|
input logic x_we_i,
|
||||||
|
// CVXIF destination register - ISSUE_STAGE
|
||||||
|
input logic [4:0] x_rd_i,
|
||||||
|
|
||||||
// TO_BE_COMPLETED - RVFI
|
// TO_BE_COMPLETED - RVFI
|
||||||
output logic [ CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_issue_pointer_o,
|
output logic [ CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_issue_pointer_o,
|
||||||
|
@ -225,8 +230,9 @@ module scoreboard #(
|
||||||
if (CVA6Cfg.DebugEn) begin
|
if (CVA6Cfg.DebugEn) begin
|
||||||
mem_n[trans_id_i[i]].sbe.bp.predict_address = resolved_branch_i.target_address;
|
mem_n[trans_id_i[i]].sbe.bp.predict_address = resolved_branch_i.target_address;
|
||||||
end
|
end
|
||||||
if (mem_n[trans_id_i[i]].sbe.fu == ariane_pkg::CVXIF && ~x_we_i) begin
|
if (mem_n[trans_id_i[i]].sbe.fu == ariane_pkg::CVXIF) begin
|
||||||
mem_n[trans_id_i[i]].sbe.rd = 5'b0;
|
if (x_we_i) mem_n[trans_id_i[i]].sbe.rd = x_rd_i;
|
||||||
|
else mem_n[trans_id_i[i]].sbe.rd = 5'b0;
|
||||||
end
|
end
|
||||||
// write the exception back if it is valid
|
// write the exception back if it is valid
|
||||||
if (ex_i[i].valid) mem_n[trans_id_i[i]].sbe.ex = ex_i[i];
|
if (ex_i[i].valid) mem_n[trans_id_i[i]].sbe.ex = ex_i[i];
|
||||||
|
@ -492,8 +498,9 @@ module scoreboard #(
|
||||||
commit_pointer_q <= '0;
|
commit_pointer_q <= '0;
|
||||||
issue_pointer_q <= '0;
|
issue_pointer_q <= '0;
|
||||||
end else begin
|
end else begin
|
||||||
issue_pointer_q <= issue_pointer_n;
|
issue_pointer_q <= issue_pointer_n;
|
||||||
mem_q <= mem_n;
|
mem_q <= mem_n;
|
||||||
|
mem_q[x_id_i].sbe.rd <= (x_transaction_accepted_i && ~x_issue_writeback_i) ? 5'b0 : mem_n[x_id_i].sbe.rd;
|
||||||
commit_pointer_q <= commit_pointer_n;
|
commit_pointer_q <= commit_pointer_n;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// Date: 19.03.2017
|
// Date: 19.03.2017
|
||||||
// Description: Ariane Top-level module
|
// Description: Ariane Top-level module
|
||||||
|
|
||||||
|
`include "cvxif_types.svh"
|
||||||
|
|
||||||
module ariane import ariane_pkg::*; #(
|
module ariane import ariane_pkg::*; #(
|
||||||
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
|
||||||
|
@ -21,6 +22,21 @@ module ariane import ariane_pkg::*; #(
|
||||||
logic csr;
|
logic csr;
|
||||||
logic instr;
|
logic instr;
|
||||||
},
|
},
|
||||||
|
// CVXIF Types
|
||||||
|
localparam type readregflags_t = `READREGFLAGS_T(CVA6Cfg),
|
||||||
|
localparam type writeregflags_t = `WRITEREGFLAGS_T(CVA6Cfg),
|
||||||
|
localparam type id_t = `ID_T(CVA6Cfg),
|
||||||
|
localparam type hartid_t = `HARTID_T(CVA6Cfg),
|
||||||
|
localparam type x_compressed_req_t = `X_COMPRESSED_REQ_T(CVA6Cfg, hartid_t),
|
||||||
|
localparam type x_compressed_resp_t = `X_COMPRESSED_RESP_T(CVA6Cfg),
|
||||||
|
localparam type x_issue_req_t = `X_ISSUE_REQ_T(CVA6Cfg, hartit_t, id_t),
|
||||||
|
localparam type x_issue_resp_t = `X_ISSUE_RESP_T(CVA6Cfg, writeregflags_t, readregflags_t),
|
||||||
|
localparam type x_register_t = `X_REGISTER_T(CVA6Cfg, hartid_t, id_t, readregflags_t),
|
||||||
|
localparam type x_commit_t = `X_COMMIT_T(CVA6Cfg, hartid_t, id_t),
|
||||||
|
localparam type x_result_t = `X_RESULT_T(CVA6Cfg, hartid_t, id_t, writeregflags_t),
|
||||||
|
localparam type cvxif_req_t = `CVXIF_REQ_T(CVA6Cfg, x_compressed_req_t, x_issue_req_t, x_register_req_t, x_commit_t),
|
||||||
|
localparam type cvxif_resp_t = `CVXIF_RESP_T(CVA6Cfg, x_compressed_resp_t, x_issue_resp_t, x_result_t),
|
||||||
|
// AXI Types
|
||||||
parameter int unsigned AxiAddrWidth = ariane_axi::AddrWidth,
|
parameter int unsigned AxiAddrWidth = ariane_axi::AddrWidth,
|
||||||
parameter int unsigned AxiDataWidth = ariane_axi::DataWidth,
|
parameter int unsigned AxiDataWidth = ariane_axi::DataWidth,
|
||||||
parameter int unsigned AxiIdWidth = ariane_axi::IdWidth,
|
parameter int unsigned AxiIdWidth = ariane_axi::IdWidth,
|
||||||
|
@ -50,8 +66,8 @@ module ariane import ariane_pkg::*; #(
|
||||||
input noc_resp_t noc_resp_i
|
input noc_resp_t noc_resp_i
|
||||||
);
|
);
|
||||||
|
|
||||||
cvxif_pkg::cvxif_req_t cvxif_req;
|
cvxif_req_t cvxif_req;
|
||||||
cvxif_pkg::cvxif_resp_t cvxif_resp;
|
cvxif_resp_t cvxif_resp;
|
||||||
|
|
||||||
cva6 #(
|
cva6 #(
|
||||||
.CVA6Cfg ( CVA6Cfg ),
|
.CVA6Cfg ( CVA6Cfg ),
|
||||||
|
@ -62,7 +78,20 @@ module ariane import ariane_pkg::*; #(
|
||||||
.axi_aw_chan_t (axi_aw_chan_t),
|
.axi_aw_chan_t (axi_aw_chan_t),
|
||||||
.axi_w_chan_t (axi_w_chan_t),
|
.axi_w_chan_t (axi_w_chan_t),
|
||||||
.noc_req_t (noc_req_t),
|
.noc_req_t (noc_req_t),
|
||||||
.noc_resp_t (noc_resp_t)
|
.noc_resp_t (noc_resp_t),
|
||||||
|
.readregflags_t (readregflags_t),
|
||||||
|
.writeregflags_t (writeregflags_t),
|
||||||
|
.id_t (id_t),
|
||||||
|
.hartid_t (hartid_t),
|
||||||
|
.x_compressed_req_t (x_compressed_req_t),
|
||||||
|
.x_compressed_resp_t (x_compressed_resp_t),
|
||||||
|
.x_issue_req_t (x_issue_req_t),
|
||||||
|
.x_issue_resp_t (x_issue_resp_t),
|
||||||
|
.x_register_t (x_register_t),
|
||||||
|
.x_commit_t (x_commit_t),
|
||||||
|
.x_result_t (x_result_t),
|
||||||
|
.cvxif_req_t (cvxif_req_t),
|
||||||
|
.cvxif_resp_t (cvxif_resp_t)
|
||||||
) i_cva6 (
|
) i_cva6 (
|
||||||
.clk_i ( clk_i ),
|
.clk_i ( clk_i ),
|
||||||
.rst_ni ( rst_ni ),
|
.rst_ni ( rst_ni ),
|
||||||
|
@ -81,7 +110,20 @@ module ariane import ariane_pkg::*; #(
|
||||||
|
|
||||||
if (CVA6Cfg.CvxifEn) begin : gen_example_coprocessor
|
if (CVA6Cfg.CvxifEn) begin : gen_example_coprocessor
|
||||||
cvxif_example_coprocessor #(
|
cvxif_example_coprocessor #(
|
||||||
.CVA6Cfg ( CVA6Cfg )
|
.NrRgprPorts (CVA6Cfg.NrRgprPorts),
|
||||||
|
.readregflags_t (readregflags_t),
|
||||||
|
.writeregflags_t (writeregflags_t),
|
||||||
|
.id_t (id_t),
|
||||||
|
.hartid_t (hartid_t),
|
||||||
|
.x_compressed_req_t (x_compressed_req_t),
|
||||||
|
.x_compressed_resp_t (x_compressed_resp_t),
|
||||||
|
.x_issue_req_t (x_issue_req_t),
|
||||||
|
.x_issue_resp_t (x_issue_resp_t),
|
||||||
|
.x_register_t (x_register_t),
|
||||||
|
.x_commit_t (x_commit_t),
|
||||||
|
.x_result_t (x_result_t),
|
||||||
|
.cvxif_req_t (cvxif_req_t),
|
||||||
|
.cvxif_resp_t (cvxif_resp_t)
|
||||||
) i_cvxif_coprocessor (
|
) i_cvxif_coprocessor (
|
||||||
.clk_i ( clk_i ),
|
.clk_i ( clk_i ),
|
||||||
.rst_ni ( rst_ni ),
|
.rst_ni ( rst_ni ),
|
||||||
|
@ -90,4 +132,6 @@ module ariane import ariane_pkg::*; #(
|
||||||
);
|
);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule // ariane
|
endmodule // ariane
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit ebf2e3a0b402cd56fd4b571b705b31f3be62c2cc
|
Subproject commit c8c8075a6a71be67ac723528070e3e50ff7586b2
|
7
verif/env/uvme/cov/uvme_cva6_cov_model.sv
vendored
7
verif/env/uvme/cov/uvme_cva6_cov_model.sv
vendored
|
@ -30,7 +30,6 @@ class uvme_cva6_cov_model_c extends uvm_component;
|
||||||
uvme_cva6_cntxt_c cntxt;
|
uvme_cva6_cntxt_c cntxt;
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
uvme_cvxif_covg_c cvxif_covg;
|
|
||||||
uvme_isa_cov_model_c isa_covg;
|
uvme_isa_cov_model_c isa_covg;
|
||||||
uvme_cva6_config_covg_c config_covg;
|
uvme_cva6_config_covg_c config_covg;
|
||||||
uvme_illegal_instr_cov_model_c illegal_covg;
|
uvme_illegal_instr_cov_model_c illegal_covg;
|
||||||
|
@ -102,12 +101,6 @@ function void uvme_cva6_cov_model_c::build_phase(uvm_phase phase);
|
||||||
`uvm_fatal("CNTXT", "Context handle is null")
|
`uvm_fatal("CNTXT", "Context handle is null")
|
||||||
end
|
end
|
||||||
|
|
||||||
if (cfg.cvxif_cfg.cov_model_enabled) begin
|
|
||||||
cvxif_covg = uvme_cvxif_covg_c::type_id::create("cvxif_covg", this);
|
|
||||||
uvm_config_db#(uvme_cva6_cfg_c)::set(this, "cvxif_covg", "cfg", cfg);
|
|
||||||
uvm_config_db#(uvme_cva6_cntxt_c)::set(this, "cvxif_covg", "cntxt", cntxt);
|
|
||||||
end
|
|
||||||
|
|
||||||
if (cfg.isacov_cfg.cov_model_enabled) begin
|
if (cfg.isacov_cfg.cov_model_enabled) begin
|
||||||
isa_covg = uvme_isa_cov_model_c::type_id::create("isa_covg", this);
|
isa_covg = uvme_isa_cov_model_c::type_id::create("isa_covg", this);
|
||||||
illegal_covg = uvme_illegal_instr_cov_model_c::type_id::create("illegal_covg", this);
|
illegal_covg = uvme_illegal_instr_cov_model_c::type_id::create("illegal_covg", this);
|
||||||
|
|
137
verif/env/uvme/cvxif_vseq/custom_instructions_cvxif_1_0_0.rst
vendored
Normal file
137
verif/env/uvme/cvxif_vseq/custom_instructions_cvxif_1_0_0.rst
vendored
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
..
|
||||||
|
Copyright (c) 2023 OpenHW Group
|
||||||
|
|
||||||
|
Copyright (c) 2023 Thales DIS design services SAS
|
||||||
|
|
||||||
|
|
||||||
|
SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||||
|
|
||||||
|
..
|
||||||
|
|
||||||
|
Custom Instruction to challenge CV-X-IF protocol
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
This section describes some custom instruction, for stress or challenge the CV-X-IF protocol for the 3 implemented interfaces, it's just to interact with the cvxif agent.
|
||||||
|
All instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011).
|
||||||
|
- **CUS_NOP**: Custom No Operation
|
||||||
|
|
||||||
|
**Format**: cus_nop -> |0000000000000000000000000|111_1011|
|
||||||
|
|
||||||
|
**Description**: do nothing, it's just a hint instruction.
|
||||||
|
|
||||||
|
**Pseudocode**: cus_nop
|
||||||
|
|
||||||
|
**Invalid values**: NONE
|
||||||
|
|
||||||
|
- **CUS_ADD**: Custom Add
|
||||||
|
|
||||||
|
**Format**: cus_add rd, rs1, rs2 -> |0000000|rs2|rs1|001|rd|111_1011|
|
||||||
|
|
||||||
|
**Description**: add register rs1 to rs2, and store the result in rd.
|
||||||
|
|
||||||
|
**Pseudocode**: x[rd] = x[rs1] + x[rs2]
|
||||||
|
|
||||||
|
**Invalid values**: NONE
|
||||||
|
|
||||||
|
- **CUS_DOUBLE_RS1**: Custom Double RS1
|
||||||
|
|
||||||
|
**Format**: cus_add rd, rs1, rs1 -> |0000001|rs2|rs1|001|rd|111_1011|
|
||||||
|
|
||||||
|
**Description**: add register rs1 to rs1, and store the result in rd.
|
||||||
|
Any rs2 value can be given. It should be ignored by CPU.
|
||||||
|
Exists to check that register depedencies is well implemented in CPU.
|
||||||
|
|
||||||
|
**Pseudocode**: x[rd] = x[rs1] + x[rs1]
|
||||||
|
|
||||||
|
**Invalid values**: NONE
|
||||||
|
|
||||||
|
- **CUS_DOUBLE_RS2**: Custom Double RS2
|
||||||
|
|
||||||
|
**Format**: cus_add rd, rs2, rs2 -> |0000010|rs2|rs1|001|rd|111_1011|
|
||||||
|
|
||||||
|
**Description**: add register rs2 to rs2, and store the result in rd.
|
||||||
|
Any rs1 value can be given. It should be ignored by CPU.
|
||||||
|
Exists to check that register depedencies is well implemented in CPU.
|
||||||
|
|
||||||
|
**Pseudocode**: x[rd] = x[rs2] + x[rs2]
|
||||||
|
|
||||||
|
**Invalid values**: NONE
|
||||||
|
|
||||||
|
- **CUS_ADD_MULTI**: Custom Multicycle Add
|
||||||
|
|
||||||
|
**Format**: addi rd, rs1, rs2 -> |0000011|rs2|rs1|001|rd|111_1011|
|
||||||
|
|
||||||
|
**Description**: add register rs1 to rs2, and store the result in rd. Coprocessor should randomly delays the result
|
||||||
|
|
||||||
|
**Pseudocode**: x[rd] = x[rs1] + x[rs2]
|
||||||
|
|
||||||
|
**Invalid values**: NONE
|
||||||
|
|
||||||
|
- **CUS_ADD_RS3_MADD**: Custom Add with RS3 opcode == MADD
|
||||||
|
|
||||||
|
**Format**: addi rd, rs1, rs2, rs3 -> |rs3|00|rs2|rs1|000|rd|100_0011|
|
||||||
|
|
||||||
|
**Description**: add register rs1, rs2 to rs3, and store the result in rd.
|
||||||
|
|
||||||
|
**Pseudocode**: x[rd] = x[rs1] + x[rs2] + x[rs3]
|
||||||
|
|
||||||
|
**Invalid values**: NONE
|
||||||
|
|
||||||
|
- **CUS_ADD_RS3_MSUB**: Custom Add with RS3 opcode == MSUB
|
||||||
|
|
||||||
|
**Format**: addi rd, rs1, rs2, rs3 -> |rs3|00|rs2|rs1|000|rd|100_0111|
|
||||||
|
|
||||||
|
**Description**: add register rs1, rs2 to rs3, and store the result in rd.
|
||||||
|
|
||||||
|
**Pseudocode**: x[rd] = x[rs1] + x[rs2] + x[rs3]
|
||||||
|
|
||||||
|
**Invalid values**: NONE
|
||||||
|
|
||||||
|
- **CUS_ADD_RS3_NMADD**: Custom Add with RS3 opcode == NMADD
|
||||||
|
|
||||||
|
**Format**: addi rd, rs1, rs2, rs3 -> |rs3|00|rs2|rs1|000|rd|100_1111|
|
||||||
|
|
||||||
|
**Description**: add register rs1, rs2 to rs3, and store the result in rd.
|
||||||
|
|
||||||
|
**Pseudocode**: x[rd] = x[rs1] + x[rs2] + x[rs3]
|
||||||
|
|
||||||
|
**Invalid values**: NONE
|
||||||
|
|
||||||
|
- **CUS_ADD_RS3_NMADD**: Custom Add with RS3 opcode == NMSUB
|
||||||
|
|
||||||
|
**Format**: addi rd, rs1, rs2, rs3 -> |rs3|00|rs2|rs1|000|rd|100_0011|
|
||||||
|
|
||||||
|
**Description**: add register rs1, rs2 to rs3, and store the result in rd.
|
||||||
|
|
||||||
|
**Pseudocode**: x[rd] = x[rs1] + x[rs2] + x[rs3]
|
||||||
|
|
||||||
|
**Invalid values**: NONE
|
||||||
|
|
||||||
|
- **CUS_ADD_RS3_RTYPE**: Custom Add with RS3, rd is x10 (a0)
|
||||||
|
|
||||||
|
**Format**: addi a0, rs1, rs2, rs3 -> |0000100|rs2|rs1|001|rs3|100_0011|
|
||||||
|
|
||||||
|
**Description**: add register rs1, rs2 to rs3, and store the result in x10 (a0).
|
||||||
|
|
||||||
|
**Pseudocode**: x[10] = x[rs1] + x[rs2] + x[rs3]
|
||||||
|
|
||||||
|
**Invalid values**: NONE
|
||||||
|
|
||||||
|
- **CUS_CNOP** : Custom Compressed NOP
|
||||||
|
|
||||||
|
**Format**: cus_cnop -> |111|0|00000|00000|00|
|
||||||
|
|
||||||
|
**Description**: Extends to CUS_NOP : do nothing, it's just a hint instruction.
|
||||||
|
|
||||||
|
**Pseudocode**: cus_cnop
|
||||||
|
|
||||||
|
**Invalid values**: NONE
|
||||||
|
|
||||||
|
- **CUS_CADD** : Custom Compressed ADD
|
||||||
|
|
||||||
|
**Format**: cus_cnop -> |111|1|rs1|rs2|00|
|
||||||
|
|
||||||
|
**Description**: Extends to CUS_ADD rs1, rs2 -> x10 : Add rs1 + rs2 into x10 (a0).
|
||||||
|
|
||||||
|
**Pseudocode**: cus_cadd
|
||||||
|
|
||||||
|
**Invalid values**: NONE
|
15
verif/env/uvme/uvme_cva6_cfg.sv
vendored
15
verif/env/uvme/uvme_cva6_cfg.sv
vendored
|
@ -39,7 +39,6 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
|
||||||
|
|
||||||
// Agent cfg handles
|
// Agent cfg handles
|
||||||
rand uvma_clknrst_cfg_c clknrst_cfg;
|
rand uvma_clknrst_cfg_c clknrst_cfg;
|
||||||
rand uvma_cvxif_cfg_c cvxif_cfg;
|
|
||||||
rand uvma_axi_cfg_c axi_cfg;
|
rand uvma_axi_cfg_c axi_cfg;
|
||||||
rand uvma_rvfi_cfg_c#(ILEN,XLEN) rvfi_cfg;
|
rand uvma_rvfi_cfg_c#(ILEN,XLEN) rvfi_cfg;
|
||||||
rand uvma_isacov_cfg_c isacov_cfg;
|
rand uvma_isacov_cfg_c isacov_cfg;
|
||||||
|
@ -75,8 +74,6 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
|
||||||
|
|
||||||
`uvm_field_object(clknrst_cfg, UVM_DEFAULT)
|
`uvm_field_object(clknrst_cfg, UVM_DEFAULT)
|
||||||
|
|
||||||
`uvm_field_object(cvxif_cfg, UVM_DEFAULT)
|
|
||||||
|
|
||||||
`uvm_field_object(axi_cfg, UVM_DEFAULT)
|
`uvm_field_object(axi_cfg, UVM_DEFAULT)
|
||||||
|
|
||||||
`uvm_field_object(rvfi_cfg, UVM_DEFAULT)
|
`uvm_field_object(rvfi_cfg, UVM_DEFAULT)
|
||||||
|
@ -97,19 +94,9 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
|
||||||
soft sys_clk_period == uvme_cva6_sys_default_clk_period; // see uvme_cva6_constants.sv
|
soft sys_clk_period == uvme_cva6_sys_default_clk_period; // see uvme_cva6_constants.sv
|
||||||
}
|
}
|
||||||
|
|
||||||
constraint cvxif_feature { //CV32A65X do not support dual read & write also the memory interface
|
|
||||||
cvxif_cfg.dual_read_write_support_x == 0;
|
|
||||||
cvxif_cfg.load_store_support_x == 0;
|
|
||||||
cvxif_cfg.seq_cus_instr_x2_enabled == 1;
|
|
||||||
cvxif_cfg.reg_cus_crosses_enabled == 0;
|
|
||||||
cvxif_cfg.mode_s_supported == CVA6Cfg.RVS;
|
|
||||||
cvxif_cfg.mode_u_supported == CVA6Cfg.RVU;
|
|
||||||
}
|
|
||||||
|
|
||||||
constraint cva6_riscv_cons {
|
constraint cva6_riscv_cons {
|
||||||
xlen == CVA6Cfg.XLEN;
|
xlen == CVA6Cfg.XLEN;
|
||||||
ilen == 32;
|
ilen == 32;
|
||||||
|
|
||||||
ext_i_supported == 1;
|
ext_i_supported == 1;
|
||||||
ext_a_supported == CVA6Cfg.RVA;
|
ext_a_supported == CVA6Cfg.RVA;
|
||||||
ext_m_supported == 1;
|
ext_m_supported == 1;
|
||||||
|
@ -227,7 +214,6 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cov_model_enabled) {
|
if (cov_model_enabled) {
|
||||||
cvxif_cfg.cov_model_enabled == 1;
|
|
||||||
isacov_cfg.cov_model_enabled == 1;
|
isacov_cfg.cov_model_enabled == 1;
|
||||||
axi_cfg.cov_model_enabled == 1;
|
axi_cfg.cov_model_enabled == 1;
|
||||||
interrupt_cfg.cov_model_enabled == 1;
|
interrupt_cfg.cov_model_enabled == 1;
|
||||||
|
@ -258,7 +244,6 @@ function uvme_cva6_cfg_c::new(string name="uvme_cva6_cfg");
|
||||||
super.new(name);
|
super.new(name);
|
||||||
|
|
||||||
clknrst_cfg = uvma_clknrst_cfg_c::type_id::create("clknrst_cfg");
|
clknrst_cfg = uvma_clknrst_cfg_c::type_id::create("clknrst_cfg");
|
||||||
cvxif_cfg = uvma_cvxif_cfg_c::type_id::create("cvxif_cfg");
|
|
||||||
axi_cfg = uvma_axi_cfg_c::type_id::create("axi_cfg");
|
axi_cfg = uvma_axi_cfg_c::type_id::create("axi_cfg");
|
||||||
rvfi_cfg = uvma_rvfi_cfg_c#(ILEN,XLEN)::type_id::create("rvfi_cfg");
|
rvfi_cfg = uvma_rvfi_cfg_c#(ILEN,XLEN)::type_id::create("rvfi_cfg");
|
||||||
isacov_cfg = uvma_isacov_cfg_c::type_id::create("isacov_cfg");
|
isacov_cfg = uvma_isacov_cfg_c::type_id::create("isacov_cfg");
|
||||||
|
|
1
verif/env/uvme/uvme_cva6_cntxt.sv
vendored
1
verif/env/uvme/uvme_cva6_cntxt.sv
vendored
|
@ -31,7 +31,6 @@ class uvme_cva6_cntxt_c extends uvm_object;
|
||||||
|
|
||||||
// Agent context handles
|
// Agent context handles
|
||||||
uvma_clknrst_cntxt_c clknrst_cntxt;
|
uvma_clknrst_cntxt_c clknrst_cntxt;
|
||||||
uvma_cvxif_cntxt_c cvxif_cntxt;
|
|
||||||
uvma_axi_cntxt_c axi_cntxt;
|
uvma_axi_cntxt_c axi_cntxt;
|
||||||
uvma_cva6_core_cntrl_cntxt_c core_cntrl_cntxt;
|
uvma_cva6_core_cntrl_cntxt_c core_cntrl_cntxt;
|
||||||
uvma_rvfi_cntxt_c rvfi_cntxt;
|
uvma_rvfi_cntxt_c rvfi_cntxt;
|
||||||
|
|
14
verif/env/uvme/uvme_cva6_env.sv
vendored
14
verif/env/uvme/uvme_cva6_env.sv
vendored
|
@ -42,7 +42,6 @@ class uvme_cva6_env_c extends uvm_env;
|
||||||
|
|
||||||
// Agents
|
// Agents
|
||||||
uvma_clknrst_agent_c clknrst_agent;
|
uvma_clknrst_agent_c clknrst_agent;
|
||||||
uvma_cvxif_agent_c cvxif_agent;
|
|
||||||
uvma_axi_agent_c axi_agent;
|
uvma_axi_agent_c axi_agent;
|
||||||
uvma_cva6_core_cntrl_agent_c core_cntrl_agent;
|
uvma_cva6_core_cntrl_agent_c core_cntrl_agent;
|
||||||
uvma_rvfi_agent_c#(ILEN,XLEN) rvfi_agent;
|
uvma_rvfi_agent_c#(ILEN,XLEN) rvfi_agent;
|
||||||
|
@ -246,8 +245,6 @@ function void uvme_cva6_env_c::assign_cfg();
|
||||||
|
|
||||||
uvm_config_db#(uvma_clknrst_cfg_c)::set(this, "*clknrst_agent", "cfg", cfg.clknrst_cfg);
|
uvm_config_db#(uvma_clknrst_cfg_c)::set(this, "*clknrst_agent", "cfg", cfg.clknrst_cfg);
|
||||||
|
|
||||||
uvm_config_db#(uvma_cvxif_cfg_c)::set(this, "*cvxif_agent", "cfg", cfg.cvxif_cfg);
|
|
||||||
|
|
||||||
uvm_config_db#(uvma_axi_cfg_c)::set(this, "*axi_agent", "cfg", cfg.axi_cfg);
|
uvm_config_db#(uvma_axi_cfg_c)::set(this, "*axi_agent", "cfg", cfg.axi_cfg);
|
||||||
|
|
||||||
uvm_config_db#(uvma_core_cntrl_cfg_c)::set(this, "core_cntrl_agent", "cfg", cfg);
|
uvm_config_db#(uvma_core_cntrl_cfg_c)::set(this, "core_cntrl_agent", "cfg", cfg);
|
||||||
|
@ -278,7 +275,6 @@ endfunction: assign_cntxt
|
||||||
function void uvme_cva6_env_c::create_agents();
|
function void uvme_cva6_env_c::create_agents();
|
||||||
|
|
||||||
clknrst_agent = uvma_clknrst_agent_c::type_id::create("clknrst_agent", this);
|
clknrst_agent = uvma_clknrst_agent_c::type_id::create("clknrst_agent", this);
|
||||||
cvxif_agent = uvma_cvxif_agent_c::type_id::create("cvxif_agent", this);
|
|
||||||
axi_agent = uvma_axi_agent_c::type_id::create("axi_agent", this);
|
axi_agent = uvma_axi_agent_c::type_id::create("axi_agent", this);
|
||||||
core_cntrl_agent = uvma_cva6_core_cntrl_agent_c::type_id::create("core_cntrl_agent", this);
|
core_cntrl_agent = uvma_cva6_core_cntrl_agent_c::type_id::create("core_cntrl_agent", this);
|
||||||
rvfi_agent = uvma_rvfi_agent_c#(ILEN,XLEN)::type_id::create("rvfi_agent", this);
|
rvfi_agent = uvma_rvfi_agent_c#(ILEN,XLEN)::type_id::create("rvfi_agent", this);
|
||||||
|
@ -361,7 +357,6 @@ endfunction: connect_scoreboard
|
||||||
function void uvme_cva6_env_c::assemble_vsequencer();
|
function void uvme_cva6_env_c::assemble_vsequencer();
|
||||||
|
|
||||||
vsequencer.clknrst_sequencer = clknrst_agent.sequencer;
|
vsequencer.clknrst_sequencer = clknrst_agent.sequencer;
|
||||||
vsequencer.cvxif_vsequencer = cvxif_agent.vsequencer;
|
|
||||||
vsequencer.axi_vsequencer = axi_agent.vsequencer;
|
vsequencer.axi_vsequencer = axi_agent.vsequencer;
|
||||||
vsequencer.interrupt_sequencer = interrupt_agent.sequencer;
|
vsequencer.interrupt_sequencer = interrupt_agent.sequencer;
|
||||||
|
|
||||||
|
@ -372,12 +367,6 @@ task uvme_cva6_env_c::run_phase(uvm_phase phase);
|
||||||
|
|
||||||
fork
|
fork
|
||||||
|
|
||||||
begin
|
|
||||||
uvme_cvxif_vseq_c cvxif_vseq;
|
|
||||||
cvxif_vseq = uvme_cvxif_vseq_c::type_id::create("cvxif_vseq");
|
|
||||||
cvxif_vseq.start(cvxif_agent.vsequencer);
|
|
||||||
end
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if(cfg.axi_cfg.is_active == UVM_ACTIVE) begin
|
if(cfg.axi_cfg.is_active == UVM_ACTIVE) begin
|
||||||
uvma_axi_vseq_c axi_vseq;
|
uvma_axi_vseq_c axi_vseq;
|
||||||
|
@ -398,9 +387,6 @@ endtask
|
||||||
|
|
||||||
function void uvme_cva6_env_c::connect_coverage_model();
|
function void uvme_cva6_env_c::connect_coverage_model();
|
||||||
|
|
||||||
if (cfg.cvxif_cfg.cov_model_enabled) begin
|
|
||||||
cvxif_agent.monitor.req_ap.connect(cov_model.cvxif_covg.req_item_fifo.analysis_export);
|
|
||||||
end
|
|
||||||
if (cfg.isacov_cfg.cov_model_enabled) begin
|
if (cfg.isacov_cfg.cov_model_enabled) begin
|
||||||
isacov_agent.monitor.ap.connect(cov_model.isa_covg.mon_trn_fifo.analysis_export);
|
isacov_agent.monitor.ap.connect(cov_model.isa_covg.mon_trn_fifo.analysis_export);
|
||||||
isacov_agent.monitor.ap.connect(cov_model.illegal_covg.mon_trn_fifo.analysis_export);
|
isacov_agent.monitor.ap.connect(cov_model.illegal_covg.mon_trn_fifo.analysis_export);
|
||||||
|
|
1
verif/env/uvme/uvme_cva6_pkg.flist
vendored
1
verif/env/uvme/uvme_cva6_pkg.flist
vendored
|
@ -21,7 +21,6 @@
|
||||||
+incdir+${CVA6_UVME_PATH}
|
+incdir+${CVA6_UVME_PATH}
|
||||||
+incdir+${CVA6_UVME_PATH}/cov
|
+incdir+${CVA6_UVME_PATH}/cov
|
||||||
+incdir+${CVA6_UVME_PATH}/vseq
|
+incdir+${CVA6_UVME_PATH}/vseq
|
||||||
+incdir+${CVA6_UVME_PATH}/cvxif_vseq
|
|
||||||
+incdir+${CVA6_UVME_PATH}/uvma_interrupt
|
+incdir+${CVA6_UVME_PATH}/uvma_interrupt
|
||||||
|
|
||||||
// Files
|
// Files
|
||||||
|
|
3
verif/env/uvme/uvme_cva6_pkg.sv
vendored
3
verif/env/uvme/uvme_cva6_pkg.sv
vendored
|
@ -30,7 +30,6 @@
|
||||||
`include "uvml_mem_macros.sv"
|
`include "uvml_mem_macros.sv"
|
||||||
`include "uvma_axi_macros.sv"
|
`include "uvma_axi_macros.sv"
|
||||||
`include "uvma_clknrst_macros.sv"
|
`include "uvma_clknrst_macros.sv"
|
||||||
`include "uvma_cvxif_macros.sv"
|
|
||||||
`include "uvma_isacov_macros.sv"
|
`include "uvma_isacov_macros.sv"
|
||||||
`include "uvme_cva6_macros.sv"
|
`include "uvme_cva6_macros.sv"
|
||||||
|
|
||||||
|
@ -46,7 +45,6 @@ package uvme_cva6_pkg;
|
||||||
import uvml_sb_pkg ::*;
|
import uvml_sb_pkg ::*;
|
||||||
import uvml_trn_pkg ::*;
|
import uvml_trn_pkg ::*;
|
||||||
import uvma_clknrst_pkg::*;
|
import uvma_clknrst_pkg::*;
|
||||||
import uvma_cvxif_pkg::*;
|
|
||||||
import uvma_axi_pkg::*;
|
import uvma_axi_pkg::*;
|
||||||
import uvml_mem_pkg ::*;
|
import uvml_mem_pkg ::*;
|
||||||
import uvma_core_cntrl_pkg::*;
|
import uvma_core_cntrl_pkg::*;
|
||||||
|
@ -100,7 +98,6 @@ package uvme_cva6_pkg;
|
||||||
`include "uvma_cva6_core_cntrl_agent.sv"
|
`include "uvma_cva6_core_cntrl_agent.sv"
|
||||||
`include "uvme_cva6_sb.sv"
|
`include "uvme_cva6_sb.sv"
|
||||||
`include "uvme_cva6_vsqr.sv"
|
`include "uvme_cva6_vsqr.sv"
|
||||||
`include "uvme_cvxif_covg.sv"
|
|
||||||
`include "uvme_isa_covg.sv"
|
`include "uvme_isa_covg.sv"
|
||||||
`include "uvme_illegal_instr_covg.sv"
|
`include "uvme_illegal_instr_covg.sv"
|
||||||
`include "uvme_exception_covg.sv"
|
`include "uvme_exception_covg.sv"
|
||||||
|
|
1
verif/env/uvme/uvme_cva6_vsqr.sv
vendored
1
verif/env/uvme/uvme_cva6_vsqr.sv
vendored
|
@ -36,7 +36,6 @@ class uvme_cva6_vsqr_c extends uvm_sequencer#(
|
||||||
|
|
||||||
// Sequencer handles
|
// Sequencer handles
|
||||||
uvma_clknrst_sqr_c clknrst_sequencer;
|
uvma_clknrst_sqr_c clknrst_sequencer;
|
||||||
uvma_cvxif_vsqr_c cvxif_vsequencer;
|
|
||||||
uvma_axi_vsqr_c axi_vsequencer;
|
uvma_axi_vsqr_c axi_vsequencer;
|
||||||
uvma_interrupt_sqr_c interrupt_sequencer;
|
uvma_interrupt_sqr_c interrupt_sequencer;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ if ! [ -n "$UVM_VERBOSITY" ]; then
|
||||||
export UVM_VERBOSITY=UVM_NONE
|
export UVM_VERBOSITY=UVM_NONE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
export cvxif=1 # For CVXIF in Spike
|
||||||
export DV_OPTS="$DV_OPTS --issrun_opts=+debug_disable=1+UVM_VERBOSITY=$UVM_VERBOSITY"
|
export DV_OPTS="$DV_OPTS --issrun_opts=+debug_disable=1+UVM_VERBOSITY=$UVM_VERBOSITY"
|
||||||
|
|
||||||
CC_OPTS="-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -g ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -lgcc"
|
CC_OPTS="-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -g ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -lgcc"
|
||||||
|
@ -61,6 +62,7 @@ make clean_all
|
||||||
python3 cva6.py --testlist=../tests/testlist_riscv-compliance-cv32a60x.yaml --test rv32i-I-ADD-01 --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS
|
python3 cva6.py --testlist=../tests/testlist_riscv-compliance-cv32a60x.yaml --test rv32i-I-ADD-01 --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS
|
||||||
python3 cva6.py --testlist=../tests/testlist_riscv-tests-cv32a60x-p.yaml --test rv32ui-p-add --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS
|
python3 cva6.py --testlist=../tests/testlist_riscv-tests-cv32a60x-p.yaml --test rv32ui-p-add --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS
|
||||||
python3 cva6.py --testlist=../tests/testlist_riscv-arch-test-cv32a60x.yaml --test rv32im-cadd-01 --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS --linker=../tests/riscv-arch-test/riscv-target/spike/link.ld
|
python3 cva6.py --testlist=../tests/testlist_riscv-arch-test-cv32a60x.yaml --test rv32im-cadd-01 --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS --linker=../tests/riscv-arch-test/riscv-target/spike/link.ld
|
||||||
|
python3 cva6.py --testlist=../tests/testlist_cvxif.yaml --test cvxif_add_nop --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS $DV_OPTS
|
||||||
python3 cva6.py --c_tests ../tests/custom/hello_world/hello_world.c --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS --linker=../tests/custom/common/test.ld --gcc_opts="$CC_OPTS" $DV_OPTS
|
python3 cva6.py --c_tests ../tests/custom/hello_world/hello_world.c --iss_yaml cva6.yaml --target cv32a65x --iss=$DV_SIMULATORS --linker=../tests/custom/common/test.ld --gcc_opts="$CC_OPTS" $DV_OPTS
|
||||||
make -C ../.. clean
|
make -C ../.. clean
|
||||||
make clean_all
|
make clean_all
|
||||||
|
|
|
@ -163,7 +163,6 @@ export DV_UVMA_CORE_CNTRL_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_core_cntrl
|
||||||
export DV_UVMA_RVFI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_rvfi
|
export DV_UVMA_RVFI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_rvfi
|
||||||
export DV_UVMA_ISACOV_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_isacov
|
export DV_UVMA_ISACOV_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_isacov
|
||||||
export DV_UVMA_CLKNRST_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_clknrst
|
export DV_UVMA_CLKNRST_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_clknrst
|
||||||
export DV_UVMA_CVXIF_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_cvxif
|
|
||||||
export DV_UVMA_AXI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_axi5
|
export DV_UVMA_AXI_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_axi5
|
||||||
export DV_UVMA_INTERRUPT_PATH = $(DV_UVME_PATH)/uvma_interrupt
|
export DV_UVMA_INTERRUPT_PATH = $(DV_UVME_PATH)/uvma_interrupt
|
||||||
export DV_UVMA_DEBUG_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_debug
|
export DV_UVMA_DEBUG_PATH = $(CORE_V_VERIF)/lib/uvm_agents/uvma_debug
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
import uvm_pkg::*;
|
import uvm_pkg::*;
|
||||||
|
|
||||||
`include "uvm_macros.svh"
|
`include "uvm_macros.svh"
|
||||||
|
`include "cvxif_types.svh"
|
||||||
|
|
||||||
|
|
||||||
`ifndef DPI_FESVR_SPIKE_UTILS
|
`ifndef DPI_FESVR_SPIKE_UTILS
|
||||||
`define DPI_FESVR_SPIKE_UTILS
|
`define DPI_FESVR_SPIKE_UTILS
|
||||||
|
@ -46,6 +48,20 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
|
||||||
parameter type rvfi_probes_instr_t = logic,
|
parameter type rvfi_probes_instr_t = logic,
|
||||||
parameter type rvfi_probes_csr_t = logic,
|
parameter type rvfi_probes_csr_t = logic,
|
||||||
parameter type rvfi_probes_t = logic,
|
parameter type rvfi_probes_t = logic,
|
||||||
|
// CVXIF Types
|
||||||
|
localparam type readregflags_t = `READREGFLAGS_T(CVA6Cfg),
|
||||||
|
localparam type writeregflags_t = `WRITEREGFLAGS_T(CVA6Cfg),
|
||||||
|
localparam type id_t = `ID_T(CVA6Cfg),
|
||||||
|
localparam type hartid_t = `HARTID_T(CVA6Cfg),
|
||||||
|
localparam type x_compressed_req_t = `X_COMPRESSED_REQ_T(CVA6Cfg, hartid_t),
|
||||||
|
localparam type x_compressed_resp_t = `X_COMPRESSED_RESP_T(CVA6Cfg),
|
||||||
|
localparam type x_issue_req_t = `X_ISSUE_REQ_T(CVA6Cfg, hartit_t, id_t),
|
||||||
|
localparam type x_issue_resp_t = `X_ISSUE_RESP_T(CVA6Cfg, writeregflags_t, readregflags_t),
|
||||||
|
localparam type x_register_t = `X_REGISTER_T(CVA6Cfg, hartid_t, id_t, readregflags_t),
|
||||||
|
localparam type x_commit_t = `X_COMMIT_T(CVA6Cfg, hartid_t, id_t),
|
||||||
|
localparam type x_result_t = `X_RESULT_T(CVA6Cfg, hartid_t, id_t, writeregflags_t),
|
||||||
|
localparam type cvxif_req_t = `CVXIF_REQ_T(CVA6Cfg, x_compressed_req_t, x_issue_req_t, x_register_req_t, x_commit_t),
|
||||||
|
localparam type cvxif_resp_t = `CVXIF_RESP_T(CVA6Cfg, x_compressed_resp_t, x_issue_resp_t, x_result_t),
|
||||||
//
|
//
|
||||||
parameter int unsigned AXI_USER_EN = 0,
|
parameter int unsigned AXI_USER_EN = 0,
|
||||||
parameter int unsigned NUM_WORDS = 2**25
|
parameter int unsigned NUM_WORDS = 2**25
|
||||||
|
@ -56,8 +72,6 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
|
||||||
output logic [31:0] tb_exit_o,
|
output logic [31:0] tb_exit_o,
|
||||||
output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_o,
|
output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_o,
|
||||||
output rvfi_csr_t rvfi_csr_o,
|
output rvfi_csr_t rvfi_csr_o,
|
||||||
input cvxif_pkg::cvxif_resp_t cvxif_resp,
|
|
||||||
output cvxif_pkg::cvxif_req_t cvxif_req,
|
|
||||||
input logic [2:0] irq_i,
|
input logic [2:0] irq_i,
|
||||||
uvma_axi_intf axi_slave,
|
uvma_axi_intf axi_slave,
|
||||||
uvmt_axi_switch_intf axi_switch_vif,
|
uvmt_axi_switch_intf axi_switch_vif,
|
||||||
|
@ -76,6 +90,9 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
|
||||||
assign rvfi_o = rvfi_instr;
|
assign rvfi_o = rvfi_instr;
|
||||||
assign rvfi_csr_o = rvfi_csr;
|
assign rvfi_csr_o = rvfi_csr;
|
||||||
|
|
||||||
|
cvxif_req_t cvxif_req;
|
||||||
|
cvxif_resp_t cvxif_resp;
|
||||||
|
|
||||||
cva6 #(
|
cva6 #(
|
||||||
.CVA6Cfg ( CVA6Cfg ),
|
.CVA6Cfg ( CVA6Cfg ),
|
||||||
.rvfi_probes_instr_t ( rvfi_probes_instr_t ),
|
.rvfi_probes_instr_t ( rvfi_probes_instr_t ),
|
||||||
|
@ -93,10 +110,34 @@ module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
|
||||||
.rvfi_probes_o ( rvfi_probes ),
|
.rvfi_probes_o ( rvfi_probes ),
|
||||||
.cvxif_req_o ( cvxif_req ),
|
.cvxif_req_o ( cvxif_req ),
|
||||||
.cvxif_resp_i ( cvxif_resp ),
|
.cvxif_resp_i ( cvxif_resp ),
|
||||||
.noc_req_o ( axi_ariane_req ),
|
.noc_req_o ( axi_ariane_req ),
|
||||||
.noc_resp_i ( axi_ariane_resp )
|
.noc_resp_i ( axi_ariane_resp )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (CVA6Cfg.CvxifEn) begin : gen_example_coprocessor
|
||||||
|
cvxif_example_coprocessor #(
|
||||||
|
.NrRgprPorts (CVA6Cfg.NrRgprPorts),
|
||||||
|
.readregflags_t (readregflags_t),
|
||||||
|
.writeregflags_t (writeregflags_t),
|
||||||
|
.id_t (id_t),
|
||||||
|
.hartid_t (hartid_t),
|
||||||
|
.x_compressed_req_t (x_compressed_req_t),
|
||||||
|
.x_compressed_resp_t (x_compressed_resp_t),
|
||||||
|
.x_issue_req_t (x_issue_req_t),
|
||||||
|
.x_issue_resp_t (x_issue_resp_t),
|
||||||
|
.x_register_t (x_register_t),
|
||||||
|
.x_commit_t (x_commit_t),
|
||||||
|
.x_result_t (x_result_t),
|
||||||
|
.cvxif_req_t (cvxif_req_t),
|
||||||
|
.cvxif_resp_t (cvxif_resp_t)
|
||||||
|
) i_cvxif_coprocessor (
|
||||||
|
.clk_i ( clk_i ),
|
||||||
|
.rst_ni ( rst_ni ),
|
||||||
|
.cvxif_req_i ( cvxif_req ),
|
||||||
|
.cvxif_resp_o ( cvxif_resp )
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// RVFI
|
// RVFI
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
|
|
||||||
// Agents
|
// Agents
|
||||||
-f ${DV_UVMA_CLKNRST_PATH}/uvma_clknrst_pkg.flist
|
-f ${DV_UVMA_CLKNRST_PATH}/uvma_clknrst_pkg.flist
|
||||||
-f ${DV_UVMA_CVXIF_PATH}/src/uvma_cvxif_pkg.flist
|
|
||||||
-f ${DV_UVMA_AXI_PATH}/src/uvma_axi_pkg.flist
|
-f ${DV_UVMA_AXI_PATH}/src/uvma_axi_pkg.flist
|
||||||
-f ${DV_UVMA_CORE_CNTRL_PATH}/uvma_core_cntrl_pkg.flist
|
-f ${DV_UVMA_CORE_CNTRL_PATH}/uvma_core_cntrl_pkg.flist
|
||||||
-f ${DV_UVMA_RVFI_PATH}/uvma_rvfi_pkg.flist
|
-f ${DV_UVMA_RVFI_PATH}/uvma_rvfi_pkg.flist
|
||||||
|
|
|
@ -29,7 +29,6 @@ module uvmt_cva6_dut_wrap # (
|
||||||
|
|
||||||
(
|
(
|
||||||
uvma_clknrst_if clknrst_if,
|
uvma_clknrst_if clknrst_if,
|
||||||
uvma_cvxif_intf cvxif_if,
|
|
||||||
uvma_axi_intf axi_if,
|
uvma_axi_intf axi_if,
|
||||||
uvmt_axi_switch_intf axi_switch_vif,
|
uvmt_axi_switch_intf axi_switch_vif,
|
||||||
uvmt_default_inputs_intf default_inputs_vif,
|
uvmt_default_inputs_intf default_inputs_vif,
|
||||||
|
@ -59,8 +58,6 @@ module uvmt_cva6_dut_wrap # (
|
||||||
.clk_i ( clknrst_if.clk ),
|
.clk_i ( clknrst_if.clk ),
|
||||||
.rst_ni ( clknrst_if.reset_n ),
|
.rst_ni ( clknrst_if.reset_n ),
|
||||||
.boot_addr_i ( boot_addr ),
|
.boot_addr_i ( boot_addr ),
|
||||||
.cvxif_resp ( cvxif_if.cvxif_resp_o ),
|
|
||||||
.cvxif_req ( cvxif_if.cvxif_req_i ),
|
|
||||||
.irq_i ( interrupt_vif.irq ),
|
.irq_i ( interrupt_vif.irq ),
|
||||||
.axi_slave ( axi_if ),
|
.axi_slave ( axi_if ),
|
||||||
.axi_switch_vif ( axi_switch_vif ),
|
.axi_switch_vif ( axi_switch_vif ),
|
||||||
|
@ -70,16 +67,4 @@ module uvmt_cva6_dut_wrap # (
|
||||||
.rvfi_o ( rvfi_o )
|
.rvfi_o ( rvfi_o )
|
||||||
);
|
);
|
||||||
|
|
||||||
assign cvxif_if.cvxif_resp_o.x_compressed_ready = 0;
|
|
||||||
assign cvxif_if.cvxif_resp_o.x_compressed_resp = 0;
|
|
||||||
assign cvxif_if.cvxif_resp_o.x_issue_ready = 1;
|
|
||||||
assign cvxif_if.cvxif_resp_o.x_issue_resp = 0;
|
|
||||||
assign cvxif_if.cvxif_resp_o.x_result_valid = 0;
|
|
||||||
assign cvxif_if.cvxif_resp_o.x_result.id = 0;
|
|
||||||
assign cvxif_if.cvxif_resp_o.x_result.data = 0;
|
|
||||||
assign cvxif_if.cvxif_resp_o.x_result.rd = 0;
|
|
||||||
assign cvxif_if.cvxif_resp_o.x_result.we = 0;
|
|
||||||
assign cvxif_if.cvxif_resp_o.x_result.exc = 0;
|
|
||||||
assign cvxif_if.cvxif_resp_o.x_result.exccode = 0;
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -59,10 +59,7 @@ module uvmt_cva6_tb;
|
||||||
|
|
||||||
// Agent interfaces
|
// Agent interfaces
|
||||||
uvma_clknrst_if clknrst_if(); // clock and resets from the clknrst agent
|
uvma_clknrst_if clknrst_if(); // clock and resets from the clknrst agent
|
||||||
uvma_cvxif_intf cvxif_if(
|
|
||||||
.clk(clknrst_if.clk),
|
|
||||||
.reset_n(clknrst_if.reset_n)
|
|
||||||
); // cvxif from the cvxif agent
|
|
||||||
uvma_axi_intf axi_if(
|
uvma_axi_intf axi_if(
|
||||||
.clk(clknrst_if.clk),
|
.clk(clknrst_if.clk),
|
||||||
.rst_n(clknrst_if.reset_n)
|
.rst_n(clknrst_if.reset_n)
|
||||||
|
@ -83,12 +80,6 @@ module uvmt_cva6_tb;
|
||||||
|
|
||||||
uvmt_default_inputs_intf default_inputs_vif();
|
uvmt_default_inputs_intf default_inputs_vif();
|
||||||
|
|
||||||
//bind assertion module for cvxif interface
|
|
||||||
bind uvmt_cva6_dut_wrap
|
|
||||||
uvma_cvxif_assert cvxif_assert(.cvxif_assert(cvxif_if),
|
|
||||||
.clk(clknrst_if.clk),
|
|
||||||
.reset_n(clknrst_if.reset_n)
|
|
||||||
);
|
|
||||||
//bind assertion module for axi interface
|
//bind assertion module for axi interface
|
||||||
bind uvmt_cva6_dut_wrap
|
bind uvmt_cva6_dut_wrap
|
||||||
uvmt_axi_assert #(CVA6Cfg.DCacheType) axi_assert(.axi_assert_if(axi_if));
|
uvmt_axi_assert #(CVA6Cfg.DCacheType) axi_assert(.axi_assert_if(axi_if));
|
||||||
|
@ -122,7 +113,6 @@ module uvmt_cva6_tb;
|
||||||
.NUM_WORDS (NUM_WORDS)
|
.NUM_WORDS (NUM_WORDS)
|
||||||
) cva6_dut_wrap (
|
) cva6_dut_wrap (
|
||||||
.clknrst_if(clknrst_if),
|
.clknrst_if(clknrst_if),
|
||||||
.cvxif_if (cvxif_if),
|
|
||||||
.axi_if (axi_if),
|
.axi_if (axi_if),
|
||||||
.axi_switch_vif (axi_switch_vif),
|
.axi_switch_vif (axi_switch_vif),
|
||||||
.default_inputs_vif (default_inputs_vif),
|
.default_inputs_vif (default_inputs_vif),
|
||||||
|
@ -371,7 +361,6 @@ module uvmt_cva6_tb;
|
||||||
|
|
||||||
// Add interfaces handles to uvm_config_db
|
// Add interfaces handles to uvm_config_db
|
||||||
uvm_config_db#(virtual uvma_clknrst_if )::set(.cntxt(null), .inst_name("*.env.clknrst_agent"), .field_name("vif"), .value(clknrst_if));
|
uvm_config_db#(virtual uvma_clknrst_if )::set(.cntxt(null), .inst_name("*.env.clknrst_agent"), .field_name("vif"), .value(clknrst_if));
|
||||||
uvm_config_db#(virtual uvma_cvxif_intf )::set(.cntxt(null), .inst_name("*.env.cvxif_agent"), .field_name("vif"), .value(cvxif_if) );
|
|
||||||
uvm_config_db#(virtual uvma_axi_intf )::set(.cntxt(null), .inst_name("*"), .field_name("axi_vif"), .value(axi_if));
|
uvm_config_db#(virtual uvma_axi_intf )::set(.cntxt(null), .inst_name("*"), .field_name("axi_vif"), .value(axi_if));
|
||||||
uvm_config_db#(virtual uvmt_axi_switch_intf )::set(.cntxt(null), .inst_name("*.env"), .field_name("axi_switch_vif"), .value(axi_switch_vif));
|
uvm_config_db#(virtual uvmt_axi_switch_intf )::set(.cntxt(null), .inst_name("*.env"), .field_name("axi_switch_vif"), .value(axi_switch_vif));
|
||||||
uvm_config_db#(virtual uvmt_rvfi_if#( .CVA6Cfg(CVA6Cfg), .rvfi_instr_t(rvfi_instr_t), .rvfi_csr_t (rvfi_csr_t)))::set(.cntxt(null), .inst_name("*"), .field_name("rvfi_vif"), .value(rvfi_if));
|
uvm_config_db#(virtual uvmt_rvfi_if#( .CVA6Cfg(CVA6Cfg), .rvfi_instr_t(rvfi_instr_t), .rvfi_csr_t (rvfi_csr_t)))::set(.cntxt(null), .inst_name("*"), .field_name("rvfi_vif"), .value(rvfi_if));
|
||||||
|
|
|
@ -21,16 +21,36 @@ main:
|
||||||
|
|
||||||
# core of the test
|
# core of the test
|
||||||
|
|
||||||
|
start0:
|
||||||
LOAD_RS(a0, 0x332211);
|
LOAD_RS(a0, 0x332211);
|
||||||
LOAD_RS(a1, 0xDEADBEEF);
|
LOAD_RS(a1, 0xDEADBEEF);
|
||||||
LOAD_RS(a2, 0xDEADBEEF);
|
LOAD_RS(a2, 0xDEADBEEF);
|
||||||
|
CUS_NOP();
|
||||||
|
CUS_ADD(01010, 01010, 01011);
|
||||||
|
CUS_ADD(01011, 01010, 01011);
|
||||||
|
CUS_ADD(01010, 01011, 01011);
|
||||||
|
lw a0, num1;
|
||||||
|
CUS_ADD_RS1(01000,01010,01011);
|
||||||
|
lw a1, num2;
|
||||||
|
CUS_ADD(01010,01011,00000);
|
||||||
|
|
||||||
CUS_ADD(01010,01010,01010,01011);
|
# Take branch to check for instruction kill
|
||||||
CUS_NOP(00000,00000,00000,00000);
|
li a0, 0xCAFE;
|
||||||
CUS_NOP(00000,00000,00000,00000);
|
li a1, 0xCAFE;
|
||||||
CUS_ADD(01010,01010,01010,01011);
|
xor a2, a0, a1;
|
||||||
CUS_NOP(00000,00000,00000,00000);
|
beqz a2, branch2;
|
||||||
CUS_ADD(01010,01010,01010,01011);
|
|
||||||
|
branch1:
|
||||||
|
CUS_ADD(00000, 00000, 01011);
|
||||||
|
CUS_NOP();
|
||||||
|
CUS_NOP();
|
||||||
|
|
||||||
|
branch2:
|
||||||
|
CUS_ADD(01010, 01010, 01011);
|
||||||
|
lw a0, num1;
|
||||||
|
CUS_ADD_RS1(01000,01010,01011);
|
||||||
|
lw a1, num2;
|
||||||
|
CUS_ADD(01010,01011,00000);
|
||||||
|
|
||||||
# (example of) final self-check test
|
# (example of) final self-check test
|
||||||
li a0, 0xCAFE;
|
li a0, 0xCAFE;
|
||||||
|
@ -47,3 +67,8 @@ pass:
|
||||||
# Success post-processing (messages, ecall setup etc.)
|
# Success post-processing (messages, ecall setup etc.)
|
||||||
li a0, 0x0;
|
li a0, 0x0;
|
||||||
jal exit;
|
jal exit;
|
||||||
|
|
||||||
|
.data
|
||||||
|
num1: .word 5 // First number
|
||||||
|
num2: .word 7 // Second number
|
||||||
|
result: .word 12 // Result
|
104
verif/tests/custom/cv_xif/cvxif_full.S
Normal file
104
verif/tests/custom/cv_xif/cvxif_full.S
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
# See LICENSE for license details.
|
||||||
|
|
||||||
|
#*****************************************************************************
|
||||||
|
# Copyright 2022 Thales DIS design services SAS
|
||||||
|
#
|
||||||
|
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
|
||||||
|
# You may obtain a copy of the License at https:#solderpad.org/licenses/
|
||||||
|
#
|
||||||
|
#----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "cvxif_macros.h"
|
||||||
|
|
||||||
|
#-------------------------------------------------------------
|
||||||
|
# Custom tests
|
||||||
|
#-------------------------------------------------------------
|
||||||
|
|
||||||
|
.globl main
|
||||||
|
main:
|
||||||
|
|
||||||
|
# core of the test
|
||||||
|
|
||||||
|
start0:
|
||||||
|
LOAD_RS(a0, 0x332211);
|
||||||
|
LOAD_RS(a1, 0xDEADBEEF);
|
||||||
|
LOAD_RS(a2, 0xDEADBEEF);
|
||||||
|
CUS_NOP();
|
||||||
|
CUS_ADD(01010, 01010, 01011);
|
||||||
|
CUS_ADD(01011, 01010, 01011);
|
||||||
|
CUS_ADD(01010, 01011, 01011);
|
||||||
|
lw a0, num1;
|
||||||
|
CUS_ADD_RS1(01000,01010,01011);
|
||||||
|
lw a1, num2;
|
||||||
|
CUS_ADD(01010,01011,00000);
|
||||||
|
|
||||||
|
# R4-Type RS3 Instructions
|
||||||
|
LOAD_RS(a0, 0x111111);
|
||||||
|
LOAD_RS(a1, 0x222222);
|
||||||
|
LOAD_RS(a2, 0x333333);
|
||||||
|
CUS_ADD_RS3_MADD(01010,01011,01100,01101);
|
||||||
|
CUS_ADD_RS3_MSUB(01010,01011,01100,01101);
|
||||||
|
CUS_ADD_RS3_NMADD(01010,01011,01100,01101);
|
||||||
|
CUS_ADD_RS3_NMSUB(01010,01011,01100,01101);
|
||||||
|
|
||||||
|
# R-type RS3 Instruction
|
||||||
|
LOAD_RS(a0, 0x111111);
|
||||||
|
LOAD_RS(a1, 0x222222);
|
||||||
|
LOAD_RS(a2, 0x333333);
|
||||||
|
CUS_ADD_RS3_RTYPE(01010,01011,01100); # --> result in 0b01010
|
||||||
|
CUS_ADD_RS3_RTYPE(01010,01011,01100); # --> result in 0b01010
|
||||||
|
CUS_ADD_RS3_RTYPE(01010,01011,01100); # --> result in 0b01010
|
||||||
|
|
||||||
|
# Take branch to check for instruction kill
|
||||||
|
li a0, 0xCAFE;
|
||||||
|
li a1, 0xCAFE;
|
||||||
|
xor a2, a0, a1;
|
||||||
|
beqz a2, branch2;
|
||||||
|
|
||||||
|
branch1:
|
||||||
|
CUS_ADD(00000, 00000, 01011);
|
||||||
|
CUS_NOP();
|
||||||
|
CUS_NOP();
|
||||||
|
|
||||||
|
branch2:
|
||||||
|
CUS_ADD(01010, 01010, 01011);
|
||||||
|
lw a0, num1;
|
||||||
|
CUS_ADD_RS1(01000,01010,01011);
|
||||||
|
lw a1, num2;
|
||||||
|
CUS_ADD(01010,01011,00000);
|
||||||
|
|
||||||
|
# Compressed instruction leads to error in spike
|
||||||
|
LOAD_RS(a0, 0x111111);
|
||||||
|
LOAD_RS(a1, 0x222222);
|
||||||
|
LOAD_RS(a2, 0x333333);
|
||||||
|
CUS_CNOP();
|
||||||
|
CUS_CADD(01011,01010);
|
||||||
|
xor a1, a0, a2;
|
||||||
|
beqz a2, pass;
|
||||||
|
|
||||||
|
# Should raise an exception
|
||||||
|
# .half 0x0000;
|
||||||
|
# .word 0xFFFFFFFF;
|
||||||
|
|
||||||
|
# (example of) final self-check test
|
||||||
|
# li a0, 0xCAFE;
|
||||||
|
# li a1, 0xCAFE;
|
||||||
|
# xor a2, a0, a1;
|
||||||
|
# beqz a2, pass;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
# Failure post-processing (messages, ecall setup etc.)
|
||||||
|
li a0, 0x0;
|
||||||
|
jal exit;
|
||||||
|
|
||||||
|
pass:
|
||||||
|
# Success post-processing (messages, ecall setup etc.)
|
||||||
|
li a0, 0x0;
|
||||||
|
jal exit;
|
||||||
|
|
||||||
|
.data
|
||||||
|
num1: .word 5 // First number
|
||||||
|
num2: .word 7 // Second number
|
||||||
|
result: .word 12 // Result
|
|
@ -6,14 +6,23 @@
|
||||||
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
// You may obtain a copy of the License at https://solderpad.org/licenses/
|
||||||
//
|
//
|
||||||
// Original Author: Zineb EL KACIMI (zineb.el-kacimi@external.thalesgroup.com)
|
// Original Author: Zineb EL KACIMI (zineb.el-kacimi@external.thalesgroup.com)
|
||||||
|
// Contributor : Guillaume Chauvon
|
||||||
|
|
||||||
|
|
||||||
#define LOAD_RS(rs,value) li rs, value
|
#define LOAD_RS(rs,value) li rs, value
|
||||||
#define COMP_RS(rs1,rs2,rd) xor rd, rs1, rs2
|
#define COMP_RS(rs1,rs2,rd) xor rd, rs1, rs2
|
||||||
|
|
||||||
|
#define CUS_NOP() .word 0b##0000000##00000####00000##000##00000##1111011
|
||||||
#define CUS_ADD(rs1,rs2,rd) .word 0b##0000000##rs2####rs1##001##rd##1111011
|
#define CUS_ADD(rs1,rs2,rd) .word 0b##0000000##rs2####rs1##001##rd##1111011
|
||||||
#define CUS_NOP(rs1,rs2,rd) .word 0b##0000000##00000####00000##000##00000##1111011
|
#define CUS_ADD_RS1(rs1,rs2,rd) .word 0b##0000001##rs2####rs1##001##rd##1111011 // only use rs1 : rs1 + rs1 => rd
|
||||||
#define CUS_ADD_RS3(rs1,rs2,rs3,rd) .word 0b##rs3##01##rs2####rs1##000##rd##1111011
|
#define CUS_ADD_RS2(rs1,rs2,rd) .word 0b##0000010##rs2####rs1##001##rd##1111011 // only use rs2 : rs2 + rs2 => rd
|
||||||
#define CUS_ADD_MULTI(rs1,rs2,rd) .word 0b##0001000##rs2####rs1##000##rd##1111011
|
#define CUS_ADD_MULTI(rs1,rs2,rd) .word 0b##0000011##rs2####rs1##001##rd##1111011
|
||||||
#define CUS_EXC(rs1,rs2,rs3,rd) .word 0b####1100000##rs2####rs1##010##rd##1111011
|
|
||||||
#define CUS_U_ADD(rs1,rs2,rd) .word 0b####0000010##rs2####rs1##000##rd##1111011
|
#define CUS_ADD_RS3_MADD(rs1,rs2,rs3,rd) .word 0b##rs3##00##rs2####rs1##000##rd##1000011 //MADD
|
||||||
#define CUS_S_ADD(rs1,rs2,rd) .word 0b####0000110##rs2####rs1##000##rd##1111011
|
#define CUS_ADD_RS3_MSUB(rs1,rs2,rs3,rd) .word 0b##rs3##00##rs2####rs1##000##rd##1000111 //MSUB
|
||||||
|
#define CUS_ADD_RS3_NMSUB(rs1,rs2,rs3,rd) .word 0b##rs3##00##rs2####rs1##000##rd##1001011 //NMSUB
|
||||||
|
#define CUS_ADD_RS3_NMADD(rs1,rs2,rs3,rd) .word 0b##rs3##00##rs2####rs1##000##rd##1001111 //NMADD
|
||||||
|
#define CUS_ADD_RS3_RTYPE(rs1,rs2,rs3) .word 0b##0000100##rs2####rs1##001##rs3##1111011
|
||||||
|
|
||||||
|
#define CUS_CADD(rs1, rs2) .half 0b##111##1##rs1##rs2##00 // -> Extend to CUS_ADD(rs1,rs2,x10)
|
||||||
|
#define CUS_CNOP() .half 0b##111##0##00000##00000##00 // -> Extend to CUS_NOP
|
||||||
|
|
|
@ -36,10 +36,15 @@ common_test_config_lgcc: &common_test_config_lgcc
|
||||||
|
|
||||||
testlist:
|
testlist:
|
||||||
- test: cvxif_add_nop
|
- test: cvxif_add_nop
|
||||||
<<: *common_test_config
|
<<: *common_test_config_lgcc
|
||||||
iterations: 0
|
iterations: 1
|
||||||
asm_tests: <path_var>/custom/cv_xif/cvxif_add_nop.S
|
asm_tests: <path_var>/custom/cv_xif/cvxif_add_nop.S
|
||||||
|
|
||||||
|
- test: cvxif_full
|
||||||
|
<<: *common_test_config_lgcc
|
||||||
|
iterations: 1
|
||||||
|
asm_tests: <path_var>/custom/cv_xif/cvxif_full.S
|
||||||
|
|
||||||
- test: cvxif_multi
|
- test: cvxif_multi
|
||||||
<<: *common_test_config
|
<<: *common_test_config
|
||||||
iterations: 0
|
iterations: 0
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue