mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-24 14:17:16 -04:00
WIP: add dual commit and instruction tracer
This commit is contained in:
parent
8697c11dd3
commit
2e1b70247a
4 changed files with 53 additions and 40 deletions
|
@ -613,12 +613,12 @@ module ariane
|
|||
assign tracer_if.issue_ack = issue_stage_i.scoreboard_i.issue_ack_i;
|
||||
assign tracer_if.issue_sbe = issue_stage_i.scoreboard_i.issue_instr_o;
|
||||
// write-back
|
||||
assign tracer_if.waddr = waddr_commit_id[0];
|
||||
assign tracer_if.wdata = wdata_commit_id[0];
|
||||
assign tracer_if.we = we_commit_id[0];
|
||||
assign tracer_if.waddr = waddr_commit_id;
|
||||
assign tracer_if.wdata = wdata_commit_id;
|
||||
assign tracer_if.we = we_commit_id;
|
||||
// commit
|
||||
assign tracer_if.commit_instr = commit_instr_id_commit[0];
|
||||
assign tracer_if.commit_ack = commit_ack[0];
|
||||
assign tracer_if.commit_instr = commit_instr_id_commit;
|
||||
assign tracer_if.commit_ack = commit_ack;
|
||||
// address translation
|
||||
// stores
|
||||
assign tracer_if.st_valid = ex_stage_i.lsu_i.store_unit_i.store_buffer_i.valid_i;
|
||||
|
|
|
@ -70,6 +70,7 @@ module commit_stage #(
|
|||
commit_lsu_o = 1'b0;
|
||||
commit_csr_o = 1'b0;
|
||||
wdata_o[0] = commit_instr_i[0].result;
|
||||
wdata_o[1] = commit_instr_i[1].result;
|
||||
csr_op_o = ADD; // this corresponds to a CSR NOP
|
||||
csr_wdata_o = 64'b0;
|
||||
fence_i_o = 1'b0;
|
||||
|
@ -145,6 +146,16 @@ module commit_stage #(
|
|||
fence_o = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// check if the second instruction can be committed as well and the first wasn't a CSR instruction
|
||||
if (commit_ack_o[0] && commit_instr_i[1].valid && !halt_i && !(commit_instr_i[0].fu inside {CSR})) begin
|
||||
// only if the first instruction didn't throw an exception and this instruction won't throw an exception
|
||||
// and the operator is of type ALU, LOAD
|
||||
if (!exception_o.valid && !commit_instr_i[1].ex.valid && (commit_instr_i[1].fu inside {ALU, LOAD, CTRL_FLOW, MULT})) begin
|
||||
we_o[1] = 1'b1;
|
||||
commit_ack_o[1] = 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// -----------------------------
|
||||
|
|
|
@ -39,7 +39,7 @@ class instruction_tracer;
|
|||
logic display_instructions;
|
||||
logic [63:0] store_mapping[$], load_mapping[$], address_mapping;
|
||||
|
||||
static uvm_cmdline_processor uvcl = uvm_cmdline_processor::get_inst();
|
||||
// static uvm_cmdline_processor uvcl = uvm_cmdline_processor::get_inst();
|
||||
|
||||
|
||||
function new(virtual instruction_tracer_if tracer_if, logic display_instructions);
|
||||
|
@ -104,38 +104,40 @@ class instruction_tracer;
|
|||
// Commit
|
||||
// --------------
|
||||
// we are committing an instruction
|
||||
if (tracer_if.pck.commit_ack) begin
|
||||
commit_instruction = scoreboard_entry'(tracer_if.pck.commit_instr);
|
||||
issue_commit_instruction = issue_queue.pop_front();
|
||||
issue_sbe = issue_sbe_queue.pop_front();
|
||||
// check if the instruction retiring is a load or store, get the physical address accordingly
|
||||
if (tracer_if.pck.commit_instr.fu == LOAD)
|
||||
address_mapping = load_mapping.pop_front();
|
||||
else if (tracer_if.pck.commit_instr.fu == STORE)
|
||||
address_mapping = store_mapping.pop_front();
|
||||
// the scoreboards issue entry still contains the immediate value as a result
|
||||
// check if the write back is valid, if not we need to source the result from the register file
|
||||
// as the most recent version of this register will be there.
|
||||
if (tracer_if.pck.we) begin
|
||||
printInstr(issue_sbe, issue_commit_instruction, tracer_if.pck.wdata, address_mapping, tracer_if.pck.priv_lvl);
|
||||
end else
|
||||
printInstr(issue_sbe, issue_commit_instruction, reg_file[commit_instruction.rd], address_mapping, tracer_if.pck.priv_lvl);
|
||||
for (int i = 0; i < 2; i++) begin
|
||||
if (tracer_if.pck.commit_ack[i]) begin
|
||||
commit_instruction = scoreboard_entry'(tracer_if.pck.commit_instr[i]);
|
||||
issue_commit_instruction = issue_queue.pop_front();
|
||||
issue_sbe = issue_sbe_queue.pop_front();
|
||||
// check if the instruction retiring is a load or store, get the physical address accordingly
|
||||
if (tracer_if.pck.commit_instr[i].fu == LOAD)
|
||||
address_mapping = load_mapping.pop_front();
|
||||
else if (tracer_if.pck.commit_instr[i].fu == STORE)
|
||||
address_mapping = store_mapping.pop_front();
|
||||
// the scoreboards issue entry still contains the immediate value as a result
|
||||
// check if the write back is valid, if not we need to source the result from the register file
|
||||
// as the most recent version of this register will be there.
|
||||
if (tracer_if.pck.we[i]) begin
|
||||
printInstr(issue_sbe, issue_commit_instruction, tracer_if.pck.wdata[i], address_mapping, tracer_if.pck.priv_lvl);
|
||||
end else
|
||||
printInstr(issue_sbe, issue_commit_instruction, reg_file[commit_instruction.rd], address_mapping, tracer_if.pck.priv_lvl);
|
||||
end
|
||||
end
|
||||
|
||||
// --------------
|
||||
// Exceptions
|
||||
// --------------
|
||||
if (tracer_if.pck.exception.valid) begin
|
||||
// print exception
|
||||
printException(tracer_if.pck.commit_instr.pc, tracer_if.pck.exception.cause, tracer_if.pck.exception.tval);
|
||||
printException(tracer_if.pck.commit_instr[0].pc, tracer_if.pck.exception.cause, tracer_if.pck.exception.tval);
|
||||
end
|
||||
// ----------------------
|
||||
// Commit Registers
|
||||
// ----------------------
|
||||
// update shadow reg file here
|
||||
if (tracer_if.pck.we && tracer_if.pck.waddr != 5'b0) begin
|
||||
reg_file[tracer_if.pck.waddr] = tracer_if.pck.wdata;
|
||||
end
|
||||
for (int i = 0; i < 2; i++)
|
||||
if (tracer_if.pck.we[i] && tracer_if.pck.waddr[i] != 5'b0) begin
|
||||
reg_file[tracer_if.pck.waddr[i]] = tracer_if.pck.wdata[i];
|
||||
end
|
||||
|
||||
// --------------
|
||||
// Flush Signals
|
||||
|
|
|
@ -22,23 +22,23 @@ import ariane_pkg::*;
|
|||
interface instruction_tracer_if (
|
||||
input clk
|
||||
);
|
||||
logic rstn;
|
||||
logic flush_unissued;
|
||||
logic flush;
|
||||
logic rstn;
|
||||
logic flush_unissued;
|
||||
logic flush;
|
||||
// Decode
|
||||
logic [31:0] instruction;
|
||||
logic fetch_valid;
|
||||
logic fetch_ack;
|
||||
logic [31:0] instruction;
|
||||
logic fetch_valid;
|
||||
logic fetch_ack;
|
||||
// Issue stage
|
||||
logic issue_ack; // issue acknowledged
|
||||
scoreboard_entry issue_sbe; // issue scoreboard entry
|
||||
logic issue_ack; // issue acknowledged
|
||||
scoreboard_entry issue_sbe; // issue scoreboard entry
|
||||
// WB stage
|
||||
logic [4:0] waddr;
|
||||
logic [63:0] wdata;
|
||||
logic we;
|
||||
logic [1:0][4:0] waddr;
|
||||
logic [1:0][63:0] wdata;
|
||||
logic [1:0] we;
|
||||
// commit stage
|
||||
scoreboard_entry commit_instr; // commit instruction
|
||||
logic commit_ack;
|
||||
scoreboard_entry [1:0] commit_instr; // commit instruction
|
||||
logic [1:0] commit_ack;
|
||||
|
||||
// address translation
|
||||
// stores
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue