Skip to content

Commit

Permalink
Update ID stage to support ZCMP, ZCMT and CVXIF with Superscalar (#2756)
Browse files Browse the repository at this point in the history
Add support for Superscalar with ZCMP, ZCMT and CVXIF.
ZCMP decoder, ZCMT decoder and CVXIF interface driver are using port 0.
Standard RVC and 32 bits instruction can take port 0 or 1.
  • Loading branch information
Gchauvon authored Feb 3, 2025
1 parent fd8c890 commit 2ef1c1b
Show file tree
Hide file tree
Showing 11 changed files with 320 additions and 240 deletions.
15 changes: 7 additions & 8 deletions core/commit_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,10 @@ module commit_stage
end

if (CVA6Cfg.NrCommitPorts > 1) begin

commit_ack_o[1] = 1'b0;
we_gpr_o[1] = 1'b0;
wdata_o[1] = commit_instr_i[1].result;
commit_macro_ack[1] = 1'b0;
commit_ack_o[1] = 1'b0;
we_gpr_o[1] = 1'b0;
wdata_o[1] = commit_instr_i[1].result;

// -----------------
// Commit Port 2
Expand Down Expand Up @@ -350,10 +350,9 @@ module commit_stage
end
end
if (CVA6Cfg.RVZCMP) begin
if (CVA6Cfg.NrCommitPorts > 1)
commit_macro_ack_o = (commit_instr_i[0].is_macro_instr || commit_instr_i[1].is_macro_instr) ? commit_macro_ack : commit_ack_o;
else
commit_macro_ack_o = (commit_instr_i[0].is_macro_instr) ? commit_macro_ack : commit_ack_o;
for (int i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin
commit_macro_ack_o[i] = commit_instr_i[i].is_macro_instr ? commit_macro_ack[i] : commit_ack_o[i];
end
end else commit_macro_ack_o = commit_ack_o;
end

Expand Down
60 changes: 25 additions & 35 deletions core/cvxif_compressed_if_driver.sv
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,24 @@ module cvxif_compressed_if_driver #(
input logic clk_i,
// Asynchronous reset active low - SUBSYSTEM
input logic rst_ni,
input logic flush_i,
// 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] instruction_valid_i,
input logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction_i,
input logic is_compressed_i,
input logic is_illegal_i,
input logic [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 [CVA6Cfg.NrIssuePorts-1:0] stall_o,
output logic is_compressed_o,
output logic is_illegal_o,
output logic [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
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
);


Expand All @@ -44,32 +44,22 @@ module cvxif_compressed_if_driver #(
compressed_valid_o = 1'b0;
compressed_req_o.instr = '0;
compressed_req_o.hartid = hart_id_i;
stall_o[0] = stall_i;
stall_o[1] = 1'b0;
if (is_illegal_i[0]) begin
compressed_valid_o = is_illegal_i[0] && instruction_valid_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];
stall_o = stall_i;
if (is_illegal_i) begin
compressed_valid_o = is_illegal_i;
compressed_req_o.instr = instruction_i[15:0];
is_illegal_o = ~compressed_resp_i.accept;
instruction_o = compressed_resp_i.accept ? compressed_resp_i.instr : instruction_i;
is_compressed_o = compressed_resp_i.accept ? 1'b0 : is_compressed_i;
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
stall_o[0] = (compressed_valid_o && ~compressed_ready_i);
if (CVA6Cfg.SuperscalarEn) begin
stall_o[1] = is_illegal_i[1];
end
stall_o = (compressed_valid_o && ~compressed_ready_i);
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] && instruction_valid_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];
stall_o[1] = (compressed_valid_o && ~compressed_ready_i);
end
if (flush_i) begin
compressed_valid_o = 1'b0;
compressed_req_o.instr = '0;
compressed_req_o.hartid = hart_id_i;
end
end

Expand Down
13 changes: 5 additions & 8 deletions core/cvxif_fu.sv
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,18 @@ module cvxif_fu

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 && x_valid_i ? 1'b1 : result_valid_i;
assign x_valid_o = x_illegal_i || 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
x_exception_o = '0; // No exception in this interface
if (x_illegal_i && x_valid_i) begin
x_exception_o.valid = '1;
x_exception_o.cause = riscv::ILLEGAL_INSTR;
if (CVA6Cfg.TvalEn)
x_exception_o.tval = x_off_instr_i; // TODO Optimization : Set exception in IRO.
end
x_exception_o.valid = x_illegal_i;
x_exception_o.cause = x_illegal_i ? riscv::ILLEGAL_INSTR : '0;
if (CVA6Cfg.TvalEn)
x_exception_o.tval = x_off_instr_i; // TODO Optimization : Set exception in IRO.
end

endmodule
Loading

0 comments on commit 2ef1c1b

Please sign in to comment.