Code_coverage: condition RTL with the debug parameter (#1582)

This commit is contained in:
AEzzejjari 2023-10-31 17:35:59 +01:00 committed by GitHub
parent a34aca924e
commit 1faaec09bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 114 additions and 71 deletions

View file

@ -1,2 +1,2 @@
cv32a6_embedded:
gates: 123953
gates: 121071

View file

@ -341,7 +341,9 @@ module wt_dcache_wbuffer
for (genvar k = 0; k < DCACHE_WBUF_DEPTH; k++) begin : gen_flags
// only for debug, will be pruned
assign debug_paddr[k] = {{riscv::XLEN_ALIGN_BYTES{1'b0}}, wbuffer_q[k].wtag << riscv::XLEN_ALIGN_BYTES};
if(CVA6Cfg.DebugEn) begin
assign debug_paddr[k] = {{riscv::XLEN_ALIGN_BYTES{1'b0}}, wbuffer_q[k].wtag << riscv::XLEN_ALIGN_BYTES};
end
// dirty bytes that are ready for transmission.
// note that we cannot retransmit a word that is already in-flight

View file

@ -154,7 +154,7 @@ module controller
// 1. Exception
// 2. Return from exception
// ---------------------------------
if (ex_valid_i || eret_i || set_debug_pc_i) begin
if (ex_valid_i || eret_i || (CVA6Cfg.DebugEn && set_debug_pc_i)) begin
// don't flush pcgen as we want to take the exception: Flush PCGen is not a flush signal
// for the PC Gen stage but instead tells it to take the PC we gave it
set_pc_commit_o = 1'b0;

View file

@ -224,10 +224,18 @@ module csr_regfile
end
end
// debug registers
riscv::CSR_DCSR: csr_rdata = {{riscv::XLEN - 32{1'b0}}, dcsr_q};
riscv::CSR_DPC: csr_rdata = dpc_q;
riscv::CSR_DSCRATCH0: csr_rdata = dscratch0_q;
riscv::CSR_DSCRATCH1: csr_rdata = dscratch1_q;
riscv::CSR_DCSR:
if (CVA6Cfg.DebugEn) csr_rdata = {{riscv::XLEN - 32{1'b0}}, dcsr_q};
else read_access_exception = 1'b1;
riscv::CSR_DPC:
if (CVA6Cfg.DebugEn) csr_rdata = dpc_q;
else read_access_exception = 1'b1;
riscv::CSR_DSCRATCH0:
if (CVA6Cfg.DebugEn) csr_rdata = dscratch0_q;
else read_access_exception = 1'b1;
riscv::CSR_DSCRATCH1:
if (CVA6Cfg.DebugEn) csr_rdata = dscratch1_q;
else read_access_exception = 1'b1;
// trigger module registers
riscv::CSR_TSELECT: read_access_exception = 1'b1; // not implemented
riscv::CSR_TDATA1: read_access_exception = 1'b1; // not implemented
@ -662,17 +670,27 @@ module csr_regfile
end
// debug CSR
riscv::CSR_DCSR: begin
dcsr_d = csr_wdata[31:0];
// debug is implemented
dcsr_d.xdebugver = 4'h4;
// currently not supported
dcsr_d.nmip = 1'b0;
dcsr_d.stopcount = 1'b0;
dcsr_d.stoptime = 1'b0;
if (CVA6Cfg.DebugEn) begin
dcsr_d = csr_wdata[31:0];
// debug is implemented
dcsr_d.xdebugver = 4'h4;
// currently not supported
dcsr_d.nmip = 1'b0;
dcsr_d.stopcount = 1'b0;
dcsr_d.stoptime = 1'b0;
end else begin
update_access_exception = 1'b1;
end
end
riscv::CSR_DPC: dpc_d = csr_wdata;
riscv::CSR_DSCRATCH0: dscratch0_d = csr_wdata;
riscv::CSR_DSCRATCH1: dscratch1_d = csr_wdata;
riscv::CSR_DPC:
if (CVA6Cfg.DebugEn) dpc_d = csr_wdata;
else update_access_exception = 1'b1;
riscv::CSR_DSCRATCH0:
if (CVA6Cfg.DebugEn) dscratch0_d = csr_wdata;
else update_access_exception = 1'b1;
riscv::CSR_DSCRATCH1:
if (CVA6Cfg.DebugEn) dscratch1_d = csr_wdata;
else update_access_exception = 1'b1;
// trigger module CSRs
riscv::CSR_TSELECT: update_access_exception = 1'b1 ; // not implemented
riscv::CSR_TDATA1: update_access_exception = 1'b1; // not implemented
@ -1124,7 +1142,7 @@ module csr_regfile
// trigger module fired
// caused by a breakpoint
if (ex_i.valid && ex_i.cause == riscv::BREAKPOINT) begin
if (CVA6Cfg.DebugEn && ex_i.valid && ex_i.cause == riscv::BREAKPOINT) begin
dcsr_d.prv = priv_lvl_o;
// check that we actually want to enter debug depending on the privilege level we are currently in
unique case (priv_lvl_o)
@ -1152,7 +1170,7 @@ module csr_regfile
end
// we've got a debug request
if (ex_i.valid && ex_i.cause == riscv::DEBUG_REQUEST) begin
if (CVA6Cfg.DebugEn && ex_i.valid && ex_i.cause == riscv::DEBUG_REQUEST) begin
dcsr_d.prv = priv_lvl_o;
// save the PC
dpc_d = {{riscv::XLEN - riscv::VLEN{pc_i[riscv::VLEN-1]}}, pc_i};
@ -1165,7 +1183,7 @@ module csr_regfile
end
// single step enable and we just retired an instruction
if (dcsr_q.step && commit_ack_i[0]) begin
if (CVA6Cfg.DebugEn && dcsr_q.step && commit_ack_i[0]) begin
dcsr_d.prv = priv_lvl_o;
// valid CTRL flow change
if (commit_instr_i[0].fu == CTRL_FLOW) begin
@ -1193,7 +1211,7 @@ module csr_regfile
end
end
// go in halt-state again when we encounter an exception
if (debug_mode_q && ex_i.valid && ex_i.cause == riscv::BREAKPOINT) begin
if (CVA6Cfg.DebugEn && debug_mode_q && ex_i.valid && ex_i.cause == riscv::BREAKPOINT) begin
set_debug_pc_o = 1'b1;
end
@ -1242,7 +1260,7 @@ module csr_regfile
end
// return from debug mode
if (dret) begin
if (CVA6Cfg.DebugEn && dret) begin
// return from exception, IF doesn't care from where we are returning
eret_o = 1'b1;
// restore the previous privilege level
@ -1283,10 +1301,12 @@ module csr_regfile
mret = 1'b1; // signal a return from machine mode
end
DRET: begin
// the return should not have any write or read side-effects
csr_we = 1'b0;
csr_read = 1'b0;
dret = 1'b1; // signal a return from debug mode
if (CVA6Cfg.DebugEn) begin
// the return should not have any write or read side-effects
csr_we = 1'b0;
csr_read = 1'b0;
dret = 1'b1; // signal a return from debug mode
end
end
default: begin
csr_we = 1'b0;
@ -1369,7 +1389,7 @@ module csr_regfile
wfi_d = wfi_q;
// if there is any (enabled) interrupt pending un-stall the core
// also un-stall if we want to enter debug mode
if (|(mip_q & mie_q) || debug_req_i || irq_i[1]) begin
if (|(mip_q & mie_q) || (CVA6Cfg.DebugEn && debug_req_i) || irq_i[1]) begin
wfi_d = 1'b0;
// or alternatively if there is no exception pending and we are not in debug mode wait here
// for the interrupt
@ -1387,7 +1407,7 @@ module csr_regfile
end
// if we are in debug mode jump to a specific address
if (debug_mode_q) begin
if (CVA6Cfg.DebugEn && debug_mode_q) begin
trap_vector_base_o = CVA6Cfg.DmBaseAddress[riscv::VLEN-1:0] + CVA6Cfg.ExceptionAddress[riscv::VLEN-1:0];
end
@ -1408,7 +1428,7 @@ module csr_regfile
epc_o = sepc_q[riscv::VLEN-1:0];
end
// we are returning from debug mode, to take the dpc register
if (dret) begin
if (CVA6Cfg.DebugEn && dret) begin
epc_o = dpc_q[riscv::VLEN-1:0];
end
end
@ -1437,7 +1457,7 @@ module csr_regfile
end
// in debug mode we execute with privilege level M
assign priv_lvl_o = (debug_mode_q) ? riscv::PRIV_LVL_M : priv_lvl_q;
assign priv_lvl_o = (CVA6Cfg.DebugEn && debug_mode_q) ? riscv::PRIV_LVL_M : priv_lvl_q;
// FPU outputs
assign fflags_o = fcsr_q.fflags;
assign frm_o = fcsr_q.frm;
@ -1461,29 +1481,31 @@ module csr_regfile
`else
assign icache_en_o = icache_q[0] & (~debug_mode_q);
`endif
assign dcache_en_o = dcache_q[0];
assign acc_cons_en_o = CVA6Cfg.EnableAccelerator ? acc_cons_q[0] : 1'b0;
assign dcache_en_o = dcache_q[0];
assign acc_cons_en_o = CVA6Cfg.EnableAccelerator ? acc_cons_q[0] : 1'b0;
// determine if mprv needs to be considered if in debug mode
assign mprv = (debug_mode_q && !dcsr_q.mprven) ? 1'b0 : mstatus_q.mprv;
assign debug_mode_o = debug_mode_q;
assign single_step_o = dcsr_q.step;
assign mprv = (CVA6Cfg.DebugEn && debug_mode_q && !dcsr_q.mprven) ? 1'b0 : mstatus_q.mprv;
assign debug_mode_o = debug_mode_q;
assign single_step_o = dcsr_q.step;
assign mcountinhibit_o = {{29 - MHPMCounterNum{1'b0}}, mcountinhibit_q};
// sequential process
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
priv_lvl_q <= riscv::PRIV_LVL_M;
priv_lvl_q <= riscv::PRIV_LVL_M;
// floating-point registers
fcsr_q <= '0;
fcsr_q <= '0;
// debug signals
debug_mode_q <= 1'b0;
dcsr_q <= '0;
dcsr_q.prv <= riscv::PRIV_LVL_M;
dcsr_q.xdebugver <= 4'h4;
dpc_q <= '0;
dscratch0_q <= {riscv::XLEN{1'b0}};
dscratch1_q <= {riscv::XLEN{1'b0}};
debug_mode_q <= 1'b0;
if (CVA6Cfg.DebugEn) begin
dcsr_q <= '0;
dcsr_q.prv <= riscv::PRIV_LVL_M;
dcsr_q.xdebugver <= 4'h4;
dpc_q <= '0;
dscratch0_q <= {riscv::XLEN{1'b0}};
dscratch1_q <= {riscv::XLEN{1'b0}};
end
// machine mode registers
mstatus_q <= 64'b0;
// set to boot address + direct mode + 4 byte offset which is the initial trap
@ -1523,15 +1545,17 @@ module csr_regfile
pmpcfg_q <= '0;
pmpaddr_q <= '0;
end else begin
priv_lvl_q <= priv_lvl_d;
priv_lvl_q <= priv_lvl_d;
// floating-point registers
fcsr_q <= fcsr_d;
fcsr_q <= fcsr_d;
// debug signals
debug_mode_q <= debug_mode_d;
dcsr_q <= dcsr_d;
dpc_q <= dpc_d;
dscratch0_q <= dscratch0_d;
dscratch1_q <= dscratch1_d;
if (CVA6Cfg.DebugEn) begin
debug_mode_q <= debug_mode_d;
dcsr_q <= dcsr_d;
dpc_q <= dpc_d;
dscratch0_q <= dscratch0_d;
dscratch1_q <= dscratch1_d;
end
// machine mode registers
mstatus_q <= mstatus_d;
mtvec_rst_load_q <= 1'b0;

View file

@ -213,7 +213,8 @@ module cva6
CVA6Cfg.NrCachedRegionRules,
CVA6Cfg.CachedRegionAddrBase,
CVA6Cfg.CachedRegionLength,
CVA6Cfg.MaxOutstandingStores
CVA6Cfg.MaxOutstandingStores,
CVA6Cfg.DebugEn
};
@ -1304,7 +1305,7 @@ module cva6
cycles <= 0;
end else begin
byte mode = "";
if (debug_mode) mode = "D";
if (CVA6Cfg.DebugEn && debug_mode) mode = "D";
else begin
case (priv_lvl)
riscv::PRIV_LVL_M: mode = "M";
@ -1322,7 +1323,7 @@ module cva6
$fwrite(f, "Exception Cause: Illegal Instructions, DASM(%h) PC=%h\n",
commit_instr_id_commit[i].ex.tval[31:0], commit_instr_id_commit[i].pc);
end else begin
if (debug_mode) begin
if (CVA6Cfg.DebugEn && debug_mode) begin
$fwrite(f, "%d 0x%0h %s (0x%h) DASM(%h)\n", cycles, commit_instr_id_commit[i].pc,
mode, commit_instr_id_commit[i].ex.tval[31:0],
commit_instr_id_commit[i].ex.tval[31:0]);
@ -1369,7 +1370,7 @@ module cva6
// when trap, the instruction is not executed
rvfi_o[i].trap = mem_exception;
rvfi_o[i].cause = ex_commit.cause;
rvfi_o[i].mode = debug_mode ? 2'b10 : priv_lvl;
rvfi_o[i].mode = (CVA6Cfg.DebugEn && debug_mode) ? 2'b10 : priv_lvl;
rvfi_o[i].ixl = riscv::XLEN == 64 ? 2 : 1;
rvfi_o[i].rs1_addr = commit_instr_id_commit[i].rs1[4:0];
rvfi_o[i].rs2_addr = commit_instr_id_commit[i].rs2[4:0];

View file

@ -1405,7 +1405,7 @@ module decoder
end
// a debug request has precendece over everything else
if (debug_req_i && !debug_mode_i) begin
if (CVA6Cfg.DebugEn && debug_req_i && !debug_mode_i) begin
instruction_o.ex.valid = 1'b1;
instruction_o.ex.cause = riscv::DEBUG_REQUEST;
end

View file

@ -361,7 +361,7 @@ module frontend
end
// 7. Debug
// enter debug on a hard-coded base-address
if (set_debug_pc_i)
if (CVA6Cfg.DebugEn && set_debug_pc_i)
npc_d = CVA6Cfg.DmBaseAddress[riscv::VLEN-1:0] + CVA6Cfg.HaltAddress[riscv::VLEN-1:0];
icache_dreq_o.vaddr = fetch_address;
end

View file

@ -111,6 +111,7 @@ package config_pkg;
logic [NrMaxRules-1:0][63:0] CachedRegionLength;
/// Maximum number of outstanding stores.
int unsigned MaxOutstandingStores;
bit DebugEn;
} cva6_cfg_t;

View file

@ -137,7 +137,8 @@ package cva6_config_pkg;
),
CachedRegionAddrBase: 1024'({64'h8000_0000}),
CachedRegionLength: 1024'({64'h40000000}),
MaxOutstandingStores: unsigned'(7)
MaxOutstandingStores: unsigned'(7),
DebugEn: bit'(1)
};
endpackage

View file

@ -136,7 +136,8 @@ package cva6_config_pkg;
),
CachedRegionAddrBase: 1024'({64'h8000_0000}),
CachedRegionLength: 1024'({64'h40000000}),
MaxOutstandingStores: unsigned'(7)
MaxOutstandingStores: unsigned'(7),
DebugEn: bit'(0)
};
endpackage

View file

@ -137,7 +137,8 @@ package cva6_config_pkg;
),
CachedRegionAddrBase: 1024'({64'h8000_0000}),
CachedRegionLength: 1024'({64'h40000000}),
MaxOutstandingStores: unsigned'(7)
MaxOutstandingStores: unsigned'(7),
DebugEn: bit'(1)
};
endpackage

View file

@ -137,6 +137,7 @@ package cva6_config_pkg;
),
CachedRegionAddrBase: 1024'({64'h8000_0000}),
CachedRegionLength: 1024'({64'h40000000}),
MaxOutstandingStores: unsigned'(7)
MaxOutstandingStores: unsigned'(7),
DebugEn: bit'(1)
};
endpackage

View file

@ -137,7 +137,8 @@ package cva6_config_pkg;
),
CachedRegionAddrBase: 1024'({64'h8000_0000}),
CachedRegionLength: 1024'({64'h40000000}),
MaxOutstandingStores: unsigned'(7)
MaxOutstandingStores: unsigned'(7),
DebugEn: bit'(1)
};
endpackage

View file

@ -137,7 +137,8 @@ package cva6_config_pkg;
),
CachedRegionAddrBase: 1024'({64'h8000_0000}),
CachedRegionLength: 1024'({64'h40000000}),
MaxOutstandingStores: unsigned'(7)
MaxOutstandingStores: unsigned'(7),
DebugEn: bit'(1)
};
endpackage

View file

@ -136,7 +136,8 @@ package cva6_config_pkg;
),
CachedRegionAddrBase: 1024'({64'h8000_0000}),
CachedRegionLength: 1024'({64'h40000000}),
MaxOutstandingStores: unsigned'(7)
MaxOutstandingStores: unsigned'(7),
DebugEn: bit'(1)
};
endpackage

View file

@ -137,7 +137,8 @@ package cva6_config_pkg;
),
CachedRegionAddrBase: 1024'({64'h8000_0000}),
CachedRegionLength: 1024'({64'h40000000}),
MaxOutstandingStores: unsigned'(7)
MaxOutstandingStores: unsigned'(7),
DebugEn: bit'(1)
};
endpackage

View file

@ -143,7 +143,8 @@ package cva6_config_pkg;
1
),
CachedRegionAddrBase: 1024'({64'h8000_0000}),
CachedRegionLength: 1024'({64'h40000000})
CachedRegionLength: 1024'({64'h40000000}),
DebugEn: bit'(1)
};
endpackage

View file

@ -137,7 +137,8 @@ package cva6_config_pkg;
),
CachedRegionAddrBase: 1024'({64'h8000_0000}),
CachedRegionLength: 1024'({64'h40000000}),
MaxOutstandingStores: unsigned'(7)
MaxOutstandingStores: unsigned'(7),
DebugEn: bit'(1)
};
endpackage

View file

@ -137,7 +137,8 @@ package cva6_config_pkg;
),
CachedRegionAddrBase: 1024'({64'h8000_0000}),
CachedRegionLength: 1024'({64'h40000000}),
MaxOutstandingStores: unsigned'(7)
MaxOutstandingStores: unsigned'(7),
DebugEn: bit'(1)
};
endpackage

View file

@ -136,6 +136,7 @@ package cva6_config_pkg;
),
CachedRegionAddrBase: 1024'({64'h8000_0000}),
CachedRegionLength: 1024'({64'h40000000}),
MaxOutstandingStores: unsigned'(7)
MaxOutstandingStores: unsigned'(7),
DebugEn: bit'(1)
};
endpackage

View file

@ -176,7 +176,9 @@ module scoreboard #(
mem_n[trans_id_i[i]].sbe.valid = 1'b1;
mem_n[trans_id_i[i]].sbe.result = wbdata_i[i];
// save the target address of a branch (needed for debug in commit stage)
mem_n[trans_id_i[i]].sbe.bp.predict_address = resolved_branch_i.target_address;
if(CVA6Cfg.DebugEn) begin
mem_n[trans_id_i[i]].sbe.bp.predict_address = resolved_branch_i.target_address;
end
if (mem_n[trans_id_i[i]].sbe.fu == ariane_pkg::CVXIF && ~x_we_i) begin
mem_n[trans_id_i[i]].sbe.rd = 5'b0;
end

View file

@ -208,7 +208,8 @@ localparam config_pkg::cva6_cfg_t CVA6Cfg = '{
NrCachedRegionRules: unsigned'(1),
CachedRegionAddrBase: 1024'({ariane_soc::DRAMBase}),
CachedRegionLength: 1024'({ariane_soc::DRAMLength}),
MaxOutstandingStores: unsigned'(7)
MaxOutstandingStores: unsigned'(7),
DebugEn: bit'(1)
};
localparam type rvfi_instr_t = logic;