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

Add support for Trace Ingress Port (TIP) on CVA6 V5.1.0 #2601

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
3 changes: 2 additions & 1 deletion .gitlab-ci/expected_synth.yml
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
cv32a65x:
gates: 179027
gates: 178510

6 changes: 6 additions & 0 deletions core/Flist.cva6
Original file line number Diff line number Diff line change
Expand Up @@ -193,4 +193,10 @@ ${CVA6_REPO_DIR}/core/cva6_mmu/cva6_ptw.sv
${CVA6_REPO_DIR}/core/cva6_mmu/cva6_tlb.sv
${CVA6_REPO_DIR}/core/cva6_mmu/cva6_shared_tlb.sv



//For TIP
${CVA6_REPO_DIR}/core/cva6_tip.sv
${CVA6_REPO_DIR}/core/encoder_16_4.sv

// end of manifest
47 changes: 47 additions & 0 deletions core/cva6.sv
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@ module cva6
rvfi_probes_instr_t instr;
},


//TIP
parameter bit IsTIP = bit'(0),

parameter type tip_instr_t = struct packed {
logic [config_pkg::NRET-1:0] iretire;
logic [config_pkg::NRET*riscv::XLEN-1:0] iaddr; //PC address
logic [config_pkg::NRET*riscv::XLEN-1:0] time_t;
logic [config_pkg::NRET*3-1:0] priv;
logic [config_pkg::NRET*riscv::XLEN-1:0] cause;
logic [config_pkg::NRET*riscv::XLEN-1:0] tval;
logic [config_pkg::NRET*(riscv::XLEN/2)-1:0] itype;
},

// branchpredict scoreboard entry
// this is the struct which we will inject into the pipeline to guide the various
// units towards the correct branch decision and resolve
Expand Down Expand Up @@ -314,6 +328,8 @@ module cva6
input logic debug_req_i,
// Probes to build RVFI, can be left open when not used - RVFI
output rvfi_probes_t rvfi_probes_o,
//TIP interface
output tip_instr_t [CVA6Cfg.NrCommitPorts-1:0] tip_o,
// CVXIF request - SUBSYSTEM
output cvxif_req_t cvxif_req_o,
// CVXIF response - SUBSYSTEM
Expand Down Expand Up @@ -1739,4 +1755,35 @@ module cva6
end
//pragma translate_on


if (IsTIP) begin

//CVA6 Trace Ingress Port
cva6_tip #(
.CVA6Cfg (CVA6Cfg),
.exception_t (exception_t),
.scoreboard_entry_t (scoreboard_entry_t),
.rvfi_probes_csr_t (rvfi_probes_csr_t),
.bp_resolve_t (bp_resolve_t),
.tip_instr_t (tip_instr_t),
.rvfi_probes_instr_t(rvfi_probes_instr_t),
.rvfi_probes_t (rvfi_probes_t)
) i_cva6_tip (
.clk_i (clk_i),
.commit_instr_i (commit_instr_id_commit),
.ex_commit_i (ex_commit),
.priv_lvl_i (priv_lvl),
.commit_ack_i (commit_macro_ack),
.debug_mode_i (debug_mode),
.csr_i (rvfi_csr),
.eret_i (eret),
.ipi_i (ipi_i),
.debug_req_i (debug_req_i),
.resolved_branch_i(resolved_branch),
.rvfi_probes_i (rvfi_probes_o),
.tip_o (tip_o)
);

end

endmodule // ariane
144 changes: 144 additions & 0 deletions core/cva6_tip.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// Copyright (c), 2024 Darshak Sheladiya, SYSGO GmbH
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1

module cva6_tip
import ariane_pkg::*;
#(
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
parameter type exception_t = logic,
parameter type scoreboard_entry_t = logic,
parameter type rvfi_probes_csr_t = logic,
parameter type bp_resolve_t = logic,
parameter type rvfi_probes_instr_t = logic,
parameter type rvfi_probes_t = logic,
parameter type tip_instr_t = logic

) (
input logic clk_i,
input scoreboard_entry_t [CVA6Cfg.NrCommitPorts-1:0] commit_instr_i,
input exception_t ex_commit_i,
input riscv::priv_lvl_t priv_lvl_i,
input logic [CVA6Cfg.NrCommitPorts-1:0] commit_ack_i,
input logic debug_mode_i,
input rvfi_probes_csr_t csr_i,
input logic eret_i,
input logic ipi_i,
input logic debug_req_i, // debug request (async)
input bp_resolve_t resolved_branch_i,
input rvfi_probes_t rvfi_probes_i,
output tip_instr_t [CVA6Cfg.NrCommitPorts-1:0] tip_o
);



rvfi_probes_instr_t instr = rvfi_probes_i.instr;
logic debug_mode;

logic [15:0] itype_signals[0:CVA6Cfg.NrCommitPorts-1];
logic [3:0] itype_o[0:CVA6Cfg.NrCommitPorts-1];

riscv::priv_lvl_t priv_lvl;
//debug_mode
assign debug_mode = instr.debug_mode;
assign priv_lvl = instr.priv_lvl;


logic [CVA6Cfg.VLEN-1:0] taken_branch_pc_reg, not_taken_branch_pc_reg, uninforable_jump_pc_reg;

// branch
always @(posedge clk_i) begin
if (resolved_branch_i.cf_type == Branch && resolved_branch_i.is_taken == 1) begin
taken_branch_pc_reg <= resolved_branch_i.pc; // taken branch
end else if (resolved_branch_i.cf_type == Branch && resolved_branch_i.is_taken == 0) begin
not_taken_branch_pc_reg <= resolved_branch_i.pc; //not taken branch
end else if (resolved_branch_i.cf_type == JumpR) begin
uninforable_jump_pc_reg <= resolved_branch_i.pc; //JumpR
end
end


// itype signals encoding
generate
for (genvar i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin
assign itype_signals[i][1] = commit_instr_i[i].valid && ex_commit_i.valid; //Exception. An exception that traps occurred following the final retired instruction in the block
assign itype_signals [i][2] = ( ipi_i || debug_req_i ); //time_irq_i (commit_ack_i[0] && !ex_commit_i.valid) && //Interrupt. An interrupt that traps occurred following the final retired instruction in the block
assign itype_signals[i][3] = eret_i; //Exception or interrupt return
assign itype_signals [i][4] = ((not_taken_branch_pc_reg == commit_instr_i[i].pc) && ~(commit_instr_i[i].pc == 0));//Nontaken branch
assign itype_signals [i][5] = ( (taken_branch_pc_reg == commit_instr_i[i].pc) && ~(commit_instr_i[i].pc == 0)); //Taken branch
assign itype_signals [i][6] = ( (uninforable_jump_pc_reg == commit_instr_i[i].pc) && ~(commit_instr_i[i].pc == 0)); //Uninferable jump
end
endgenerate

generate
for (genvar i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin

encoder_16_4 ec_0 (
.in(itype_signals[i]),
.out(itype_o[i]),
.valid()
);

end
endgenerate



dassheladiya marked this conversation as resolved.
Show resolved Hide resolved

//TIP signals
always_comb begin
for (int i = 0; i < CVA6Cfg.NrCommitPorts; i++) begin
logic exception, mem_exception;
exception = commit_instr_i[i].valid && ex_commit_i.valid;
mem_exception = exception &&
(ex_commit_i.cause == riscv::INSTR_ADDR_MISALIGNED ||
ex_commit_i.cause == riscv::INSTR_ACCESS_FAULT ||
ex_commit_i.cause == riscv::ILLEGAL_INSTR ||
ex_commit_i.cause == riscv::LD_ADDR_MISALIGNED ||
ex_commit_i.cause == riscv::LD_ACCESS_FAULT ||
ex_commit_i.cause == riscv::ST_ADDR_MISALIGNED ||
ex_commit_i.cause == riscv::ST_ACCESS_FAULT ||
ex_commit_i.cause == riscv::INSTR_PAGE_FAULT ||
ex_commit_i.cause == riscv::LOAD_PAGE_FAULT ||
ex_commit_i.cause == riscv::STORE_PAGE_FAULT);
tip_o[i].iretire = (commit_ack_i[i] && !ex_commit_i.valid) ||
(exception && (ex_commit_i.cause == riscv::ENV_CALL_MMODE ||
ex_commit_i.cause == riscv::ENV_CALL_SMODE ||
ex_commit_i.cause == riscv::ENV_CALL_UMODE));
tip_o[i].iaddr = commit_instr_i[i].pc;
tip_o[i].time_t = csr_i.cycle_q;
tip_o[i].priv = (((CVA6Cfg.DebugEn && debug_mode) ? 2'b10 : priv_lvl) == 2'b10) ? 2'b01:((CVA6Cfg.DebugEn && debug_mode) ? 2'b10 : priv_lvl) ;//(CVA6Cfg.DebugEn && debug_mode) ? 2'b10 : priv_lvl;//debug_mode_i ? 3'b100 : priv_lvl_i;
tip_o[i].cause = ex_commit_i.cause;
tip_o[i].tval = csr_i.mtval_q;
tip_o[i].itype = itype_o[i];

end
end



//*************************** TIP Signal dumping **************************//

// int fd = $fopen("./tip_port_0_signals_dump.txt", "w");
// int fj = $fopen("./tip_port_1_signals_dump.txt", "w");

// always@(tip_o[0].iretire == 1) begin

// if (fd) begin
// $fwrite(fd, "tip_o_[0].iretire= 0x%h, tip_o_[0].iaddr= 0x%h, tip_o_[0].time_t= 0x%h, tip_o_[0].priv= 0x%h, tip_o_[0].cause= 0x%h, tip_o_[0].tval= 0x%h, tip_o_[0].itype= %h\n", tip_o[0].iretire, tip_o[0].iaddr,tip_o[0].time_t, tip_o[0].priv, tip_o[0].cause, tip_o[0].tval, tip_o[0].itype );
// end else begin
// $display("Error opening the file.");
// end
// end

// always@(tip_o[1].iretire == 1) begin

// if (fj) begin
// $fwrite(fj, "tip_o_[1].iretire= 0x%h, tip_o_[1].iaddr= 0x%h, tip_o_[1].time_t= 0x%h, tip_o_[1].priv= 0x%h, tip_o_[1].cause= 0x%h, tip_o_[1].tval= 0x%h, tip_o_[1].itype= %h\n", tip_o[1].iretire, tip_o[1].iaddr,tip_o[1].time_t, tip_o[1].priv, tip_o[1].cause, tip_o[1].tval, tip_o[1].itype );
// end else begin
// $display("Error opening the file.");
// end
// end



endmodule
70 changes: 70 additions & 0 deletions core/encoder_16_4.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c), 2024 Darshak Sheladiya, SYSGO GmbH
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1

Copy link
Contributor

Choose a reason for hiding this comment

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

[verible-verilog-format] reported by reviewdog 🐶

Suggested change



module encoder_16_4 (
input logic [15:0] in, // 16-bit input
output logic [ 3:0] out, // 4-bit output
output logic valid // Indicates if there is any active input
);

always_comb begin
// Initialize output and valid signal
out = 4'b0000;
valid = 1'b0;

// Priority encoding (highest priority at the highest bit)
if (in[15]) begin
out = 4'b1111;
valid = 1'b1;
end else if (in[14]) begin
out = 4'b1110;
valid = 1'b1;
end else if (in[13]) begin
out = 4'b1101;
valid = 1'b1;
end else if (in[12]) begin
out = 4'b1100;
valid = 1'b1;
end else if (in[11]) begin
out = 4'b1011;
valid = 1'b1;
end else if (in[10]) begin
out = 4'b1010;
valid = 1'b1;
end else if (in[9]) begin
out = 4'b1001;
valid = 1'b1;
end else if (in[8]) begin
out = 4'b1000;
valid = 1'b1;
end else if (in[7]) begin
out = 4'b0111;
valid = 1'b1;
end else if (in[6]) begin
out = 4'b0110;
valid = 1'b1;
end else if (in[5]) begin
out = 4'b0101;
valid = 1'b1;
end else if (in[4]) begin
out = 4'b0100;
valid = 1'b1;
end else if (in[3]) begin
out = 4'b0011;
valid = 1'b1;
end else if (in[2]) begin
out = 4'b0010;
valid = 1'b1;
end else if (in[1]) begin
out = 4'b0001;
valid = 1'b1;
end else if (in[0]) begin
out = 4'b0000;
valid = 1'b1;
end else begin
valid = 1'b0; // No active input
end
end
endmodule
dassheladiya marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading