Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zcmp extension support #1779

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/Flist.cva6
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ ${CVA6_REPO_DIR}/core/alu.sv
${CVA6_REPO_DIR}/core/fpu_wrap.sv
${CVA6_REPO_DIR}/core/branch_unit.sv
${CVA6_REPO_DIR}/core/compressed_decoder.sv
${CVA6_REPO_DIR}/core/macro_decoder.sv
${CVA6_REPO_DIR}/core/controller.sv
${CVA6_REPO_DIR}/core/csr_buffer.sv
${CVA6_REPO_DIR}/core/csr_regfile.sv
Expand Down
12 changes: 12 additions & 0 deletions core/commit_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ module commit_stage
input scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr_i,
// Acknowledge that we are indeed committing - ISSUE_STAGE
output logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack_o,
// Acknowledge that we are indeed committing - CSR_REGFILE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why CSR_REGFILE and not ISSUE_STAGE as destination of commit_macro_ack_o?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The goal was to increment the CSR register only once for a macro instruction. We still want to be able to Issue and Execute the decoded sequence of instructions. Please note here that commit_macro_ack_o is asserted only when we execute the last decoded 32bit instruction in the macro definition, otherwise it behaves exactly like commit_ack_o.

output logic [CVA6Cfg.NrCommitPorts-1:0] commit_macro_ack_o,
// Register file write address - ISSUE_STAGE
output logic [CVA6Cfg.NrCommitPorts-1:0][4:0] waddr_o,
// Register file write data - ISSUE_STAGE
Expand Down Expand Up @@ -116,6 +118,7 @@ module commit_stage
assign commit_tran_id_o = commit_instr_i[0].trans_id;

logic instr_0_is_amo;
logic [CVA6Cfg.NrCommitPorts-1:0] commit_macro_ack;
assign instr_0_is_amo = is_amo(commit_instr_i[0].op);
// -------------------
// Commit Instruction
Expand All @@ -124,6 +127,7 @@ module commit_stage
always_comb begin : commit
// default assignments
commit_ack_o[0] = 1'b0;
commit_macro_ack[0] = 1'b0;

amo_valid_commit_o = 1'b0;

Expand All @@ -144,6 +148,9 @@ module commit_stage
// we will not commit the instruction if we took an exception
// and we do not commit the instruction if we requested a halt
if (commit_instr_i[0].valid && !commit_instr_i[0].ex.valid && !halt_i) begin
if (commit_instr_i[0].is_macro_instr && commit_instr_i[0].is_last_macro_instr)
commit_macro_ack[0] = 1'b1;
else commit_macro_ack[0] = 1'b0;
// we can definitely write the register file
// if the instruction is not committing anything the destination
commit_ack_o[0] = 1'b1;
Expand Down Expand Up @@ -264,6 +271,10 @@ module commit_stage
if (CVA6Cfg.FpPresent && ariane_pkg::is_rd_fpr(commit_instr_i[1].op)) we_fpr_o[1] = 1'b1;
else we_gpr_o[1] = 1'b1;

if (commit_instr_i[1].is_macro_instr && commit_instr_i[1].is_last_macro_instr)
commit_macro_ack[1] = 1'b1;
else commit_macro_ack[1] = 1'b0;

commit_ack_o[1] = 1'b1;

// additionally check if we are retiring an FPU instruction because we need to make sure that we write all
Expand All @@ -281,6 +292,7 @@ module commit_stage
end
end
end
commit_macro_ack_o = (commit_instr_i[0].is_macro_instr || commit_instr_i[1].is_macro_instr) ? commit_macro_ack : commit_ack_o;
end

// -----------------------------
Expand Down
19 changes: 15 additions & 4 deletions core/compressed_decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ module compressed_decoder #(
output logic [31:0] instr_o,
// Input instruction is illegal - decoder
output logic illegal_instr_o,
// Output instruction is macro - decoder
output logic is_macro_instr_o,
// Output instruction is compressed - decoder
output logic is_compressed_o
);
Expand All @@ -36,10 +38,11 @@ module compressed_decoder #(
// Compressed Decoder
// -------------------
always_comb begin
illegal_instr_o = 1'b0;
instr_o = '0;
is_compressed_o = 1'b1;
instr_o = instr_i;
illegal_instr_o = 1'b0;
instr_o = '0;
is_compressed_o = 1'b1;
instr_o = instr_i;
is_macro_instr_o = 0;

// I: | imm[11:0] | rs1 | funct3 | rd | opcode |
// S: | imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode |
Expand Down Expand Up @@ -865,6 +868,13 @@ module compressed_decoder #(
3'b000,
riscv::OpcodeStoreFp
};
end else if (CVA6Cfg.RVZCMP) begin
if (instr_i[12:10] == 3'b110 || instr_i[12:10] == 3'b111 || instr_i[12:10] == 3'b011) begin //is a push/pop instruction
is_macro_instr_o = 1;
instr_o = instr_i;
end else begin
illegal_instr_o = 1'b1;
end
end else begin
illegal_instr_o = 1'b1;
end
Expand Down Expand Up @@ -937,3 +947,4 @@ module compressed_decoder #(
end
end
endmodule

9 changes: 7 additions & 2 deletions core/cva6.sv
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ module cva6
branchpredict_sbe_t bp; // branch predict scoreboard data structure
logic is_compressed; // signals a compressed instructions, we need this information at the commit stage if
// we want jump accordingly e.g.: +4, +2
logic is_macro_instr; // is an instruction executed as predefined sequence of instructions called macro definition
logic is_last_macro_instr; // is last decoded 32bit instruction of macro definition
logic is_double_rd_macro_instr; // is double move decoded 32bit instruction of macro definition
logic vfp; // is this a vector floating-point instruction?
},

Expand Down Expand Up @@ -302,6 +305,7 @@ module cva6
logic [ riscv::VLEN-1:0] pc_commit;
logic eret;
logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack;
logic [CVA6Cfg.NrCommitPorts-1:0] commit_macro_ack;

localparam NumPorts = 4;
cvxif_pkg::cvxif_req_t cvxif_req;
Expand Down Expand Up @@ -884,6 +888,7 @@ module cva6
.single_step_i (single_step_csr_commit || single_step_acc_commit),
.commit_instr_i (commit_instr_id_commit),
.commit_ack_o (commit_ack),
.commit_macro_ack_o(commit_macro_ack),
.no_st_pending_i (no_st_pending_commit),
.waddr_o (waddr_commit_id),
.wdata_o (wdata_commit_id),
Expand Down Expand Up @@ -923,7 +928,7 @@ module cva6
.flush_o (flush_csr_ctrl),
.halt_csr_o (halt_csr_ctrl),
.commit_instr_i (commit_instr_id_commit),
.commit_ack_i (commit_ack),
.commit_ack_i (commit_macro_ack),
.boot_addr_i (boot_addr_i[riscv::VLEN-1:0]),
.hart_id_i (hart_id_i[riscv::XLEN-1:0]),
.ex_i (ex_commit),
Expand Down Expand Up @@ -1548,7 +1553,7 @@ module cva6

.lsu_ctrl_i (rvfi_lsu_ctrl),
.wbdata_i (wbdata_ex_id),
.commit_ack_i(commit_ack),
.commit_ack_i(commit_macro_ack),
.mem_paddr_i (rvfi_mem_paddr),
.debug_mode_i(debug_mode),
.wdata_i (wdata_commit_id),
Expand Down
51 changes: 30 additions & 21 deletions core/decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ module decoder
input logic is_illegal_i,
// Instruction from fetch stage - FRONTEND
input logic [31:0] instruction_i,
// Is a macro instruction - macro_decoder
input logic is_macro_instr_i,
// Is a last macro instruction - macro_decoder
input logic is_last_macro_instr_i,
// Is mvsa01/mva01s macro instruction - macro_decoder
input logic is_double_rd_macro_instr_i,
// Is a branch predict instruction - FRONTEND
input branchpredict_sbe_t branch_predict_i,
// If an exception occured in fetch stage - FRONTEND
Expand Down Expand Up @@ -128,27 +134,30 @@ module decoder

always_comb begin : decoder

imm_select = NOIMM;
is_control_flow_instr_o = 1'b0;
illegal_instr = 1'b0;
illegal_instr_non_bm = 1'b0;
illegal_instr_bm = 1'b0;
illegal_instr_zic = 1'b0;
instruction_o.pc = pc_i;
instruction_o.trans_id = '0;
instruction_o.fu = NONE;
instruction_o.op = ariane_pkg::ADD;
instruction_o.rs1 = '0;
instruction_o.rs2 = '0;
instruction_o.rd = '0;
instruction_o.use_pc = 1'b0;
instruction_o.is_compressed = is_compressed_i;
instruction_o.use_zimm = 1'b0;
instruction_o.bp = branch_predict_i;
instruction_o.vfp = 1'b0;
ecall = 1'b0;
ebreak = 1'b0;
check_fprm = 1'b0;
imm_select = NOIMM;
is_control_flow_instr_o = 1'b0;
illegal_instr = 1'b0;
illegal_instr_non_bm = 1'b0;
illegal_instr_bm = 1'b0;
illegal_instr_zic = 1'b0;
instruction_o.pc = pc_i;
instruction_o.trans_id = '0;
instruction_o.fu = NONE;
instruction_o.op = ariane_pkg::ADD;
instruction_o.rs1 = '0;
instruction_o.rs2 = '0;
instruction_o.rd = '0;
instruction_o.use_pc = 1'b0;
instruction_o.is_compressed = is_compressed_i;
instruction_o.is_macro_instr = is_macro_instr_i;
instruction_o.is_last_macro_instr = is_last_macro_instr_i;
instruction_o.is_double_rd_macro_instr = is_double_rd_macro_instr_i;
instruction_o.use_zimm = 1'b0;
instruction_o.bp = branch_predict_i;
instruction_o.vfp = 1'b0;
ecall = 1'b0;
ebreak = 1'b0;
check_fprm = 1'b0;

if (~ex_i.valid) begin
case (instr.rtype.opcode)
Expand Down
84 changes: 64 additions & 20 deletions core/id_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,15 @@ module id_stage #(
logic [31:0] orig_instr;

logic is_illegal;
logic is_illegal_cmp;
logic [31:0] instruction;
logic [31:0] compressed_instr;
logic is_compressed;
logic is_compressed_cmp;
logic is_macro_instr_i;
logic stall_instr_fetch;
logic is_last_macro_instr_o;
logic is_double_rd_macro_instr_o;

if (CVA6Cfg.RVC) begin
// ---------------------------------------------------------
Expand All @@ -92,18 +99,48 @@ module id_stage #(
compressed_decoder #(
.CVA6Cfg(CVA6Cfg)
) compressed_decoder_i (
.instr_i (fetch_entry_i.instruction),
.instr_o (instruction),
.illegal_instr_o(is_illegal),
.is_compressed_o(is_compressed)
.instr_i (fetch_entry_i.instruction),
.instr_o (compressed_instr),
.illegal_instr_o (is_illegal),
.is_compressed_o (is_compressed),
.is_macro_instr_o(is_macro_instr_i)
);
if (CVA6Cfg.RVZCMP) begin
//sequencial decoder
macro_decoder #(
.CVA6Cfg(CVA6Cfg)
) macro_decoder_i (
.instr_i (compressed_instr),
.is_macro_instr_i (is_macro_instr_i),
.clk_i (clk_i),
.rst_ni (rst_ni),
.instr_o (instruction),
.illegal_instr_i (is_illegal),
.is_compressed_i (is_compressed),
.issue_ack_i (issue_instr_ack_i),
.illegal_instr_o (is_illegal_cmp),
.is_compressed_o (is_compressed_cmp),
.fetch_stall_o (stall_instr_fetch),
.is_last_macro_instr_o (is_last_macro_instr_o),
.is_double_rd_macro_instr_o(is_double_rd_macro_instr_o)
);
end else begin
assign instruction = compressed_instr;
assign is_illegal_cmp = is_illegal;
assign is_compressed_cmp = is_compressed;
assign is_last_macro_instr_o = '0;
assign is_double_rd_macro_instr_o = '0;
end
end else begin
assign instruction = fetch_entry_i.instruction;
assign is_illegal = '0;
assign is_compressed = '0;
assign is_illegal_cmp = '0;
assign is_compressed_cmp = '0;
assign is_macro_instr_i = '0;
assign is_last_macro_instr_o = '0;
assign is_double_rd_macro_instr_o = '0;
end

assign rvfi_is_compressed_o = is_compressed;
assign rvfi_is_compressed_o = is_compressed_cmp;
// ---------------------------------------------------------
// 2. Decode and emit instruction to issue stage
// ---------------------------------------------------------
Expand All @@ -117,24 +154,27 @@ module id_stage #(
.debug_req_i,
.irq_ctrl_i,
.irq_i,
.pc_i (fetch_entry_i.address),
.is_compressed_i (is_compressed),
.is_illegal_i (is_illegal),
.instruction_i (instruction),
.compressed_instr_i (fetch_entry_i.instruction[15:0]),
.branch_predict_i (fetch_entry_i.branch_predict),
.ex_i (fetch_entry_i.ex),
.priv_lvl_i (priv_lvl_i),
.debug_mode_i (debug_mode_i),
.pc_i (fetch_entry_i.address),
.is_compressed_i (is_compressed_cmp),
.is_macro_instr_i (is_macro_instr_i),
.is_last_macro_instr_i (is_last_macro_instr_o),
.is_double_rd_macro_instr_i(is_double_rd_macro_instr_o),
.is_illegal_i (is_illegal_cmp),
.instruction_i (instruction),
.compressed_instr_i (fetch_entry_i.instruction[15:0]),
.branch_predict_i (fetch_entry_i.branch_predict),
.ex_i (fetch_entry_i.ex),
.priv_lvl_i (priv_lvl_i),
.debug_mode_i (debug_mode_i),
.fs_i,
.frm_i,
.vs_i,
.tvm_i,
.tw_i,
.tsr_i,
.instruction_o (decoded_instruction),
.orig_instr_o (orig_instr),
.is_control_flow_instr_o(is_control_flow_instr)
.instruction_o (decoded_instruction),
.orig_instr_o (orig_instr),
.is_control_flow_instr_o (is_control_flow_instr)
);

// ------------------
Expand All @@ -156,7 +196,11 @@ module id_stage #(
// or the issue stage is currently acknowledging an instruction, which means that we will have space
// for a new instruction
if ((!issue_q.valid || issue_instr_ack_i) && fetch_entry_valid_i) begin
fetch_entry_ready_o = 1'b1;
if (stall_instr_fetch) begin
fetch_entry_ready_o = 1'b0;
end else begin
fetch_entry_ready_o = 1'b1;
end
issue_n = '{1'b1, decoded_instruction, orig_instr, is_control_flow_instr};
end

Expand Down
1 change: 1 addition & 0 deletions core/include/build_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ package build_config_pkg;
cfg.RVV = CVA6Cfg.RVV;
cfg.RVC = CVA6Cfg.RVC;
cfg.RVZCB = CVA6Cfg.RVZCB;
cfg.RVZCMP = CVA6Cfg.RVZCMP;
cfg.XFVec = CVA6Cfg.XFVec;
cfg.CvxifEn = CVA6Cfg.CvxifEn;
cfg.ZiCondExtEn = CVA6Cfg.ZiCondExtEn;
Expand Down
3 changes: 3 additions & 0 deletions core/include/config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ package config_pkg;
bit RVC;
// Zcb RISC-V extension
bit RVZCB;
// Zcmp RISC-V extension
bit RVZCMP;
// Non standard Vector Floating Point
bit XFVec;
// CV-X-IF coprocessor interface is supported
Expand Down Expand Up @@ -150,6 +152,7 @@ package config_pkg;
bit RVV;
bit RVC;
bit RVZCB;
bit RVZCMP;
bit XFVec;
bit CvxifEn;
bit ZiCondExtEn;
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv32a60x_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package cva6_config_pkg;
localparam CVA6ConfigCvxifEn = 1;
localparam CVA6ConfigCExtEn = 1;
localparam CVA6ConfigZcbExtEn = 1;
localparam CVA6ConfigZcmpExtEn = 1;
localparam CVA6ConfigAExtEn = 1;
localparam CVA6ConfigBExtEn = 1;
localparam CVA6ConfigVExtEn = 0;
Expand Down Expand Up @@ -91,6 +92,7 @@ package cva6_config_pkg;
RVV: bit'(CVA6ConfigVExtEn),
RVC: bit'(CVA6ConfigCExtEn),
RVZCB: bit'(CVA6ConfigZcbExtEn),
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
XFVec: bit'(CVA6ConfigFVecEn),
CvxifEn: bit'(CVA6ConfigCvxifEn),
ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn),
Expand Down
2 changes: 2 additions & 0 deletions core/include/cv32a65x_config_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package cva6_config_pkg;
localparam CVA6ConfigCvxifEn = 1;
localparam CVA6ConfigCExtEn = 1;
localparam CVA6ConfigZcbExtEn = 1;
localparam CVA6ConfigZcmpExtEn = 0;
localparam CVA6ConfigAExtEn = 0;
localparam CVA6ConfigBExtEn = 1;
localparam CVA6ConfigVExtEn = 0;
Expand Down Expand Up @@ -90,6 +91,7 @@ package cva6_config_pkg;
RVV: bit'(CVA6ConfigVExtEn),
RVC: bit'(CVA6ConfigCExtEn),
RVZCB: bit'(CVA6ConfigZcbExtEn),
RVZCMP: bit'(CVA6ConfigZcmpExtEn),
XFVec: bit'(CVA6ConfigFVecEn),
CvxifEn: bit'(CVA6ConfigCvxifEn),
ZiCondExtEn: bit'(CVA6ConfigZiCondExtEn),
Expand Down
Loading
Loading