mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-20 12:17:19 -04:00
instruction_tracer: Fix compressed tracing (fix #134)
The built-in tracer now supports tracing compressed instructions. The Spike commit log feature has been adapted and is now a 100% aligned.
This commit is contained in:
parent
720910dad0
commit
e312b226de
2 changed files with 152 additions and 71 deletions
|
@ -40,7 +40,6 @@ class instruction_trace_item;
|
|||
this.cycle = cycle;
|
||||
this.pc = sbe.pc;
|
||||
this.sbe = sbe;
|
||||
this.instr = instr;
|
||||
this.gp_reg_file = gp_reg_file;
|
||||
this.fp_reg_file = fp_reg_file;
|
||||
this.result = result;
|
||||
|
@ -51,6 +50,11 @@ class instruction_trace_item;
|
|||
this.rs2 = sbe.rs2[4:0];
|
||||
this.rs3 = instr[31:27];
|
||||
this.rd = sbe.rd[4:0];
|
||||
if (instr[1:0] != 2'b11) begin
|
||||
this.instr = {16'b0, instr[15:0]};
|
||||
end else begin
|
||||
this.instr = instr;
|
||||
end
|
||||
endfunction
|
||||
|
||||
// convert gp register address to ABI compatible form
|
||||
|
@ -186,8 +190,8 @@ class instruction_trace_item;
|
|||
// Regular opcodes
|
||||
INSTR_LUI: s = this.printUInstr("lui");
|
||||
INSTR_AUIPC: s = this.printUInstr("auipc");
|
||||
INSTR_JAL: s = this.printJump();
|
||||
INSTR_JALR: s = this.printJump();
|
||||
INSTR_JAL: s = this.printJump("jal");
|
||||
INSTR_JALR: s = this.printJump("jalr");
|
||||
// BRANCH
|
||||
INSTR_BEQZ: s = this.printSBInstr("beqz");
|
||||
INSTR_BEQ: s = this.printSBInstr("beq");
|
||||
|
@ -288,15 +292,68 @@ class instruction_trace_item;
|
|||
INSTR_WFI: s = this.printMnemonic("wfi");
|
||||
INSTR_SFENCE: s = this.printMnemonic("sfence.vma");
|
||||
// loads and stores
|
||||
INSTR_LOAD,
|
||||
INSTR_LOAD_FP: s = this.printLoadInstr();
|
||||
INSTR_STORE,
|
||||
INSTR_STORE_FP: s = this.printStoreInstr();
|
||||
LB: s = this.printLoadInstr("lb");
|
||||
LH: s = this.printLoadInstr("lh");
|
||||
LW: s = this.printLoadInstr("lw");
|
||||
LD: s = this.printLoadInstr("ld");
|
||||
LBU: s = this.printLoadInstr("lbu");
|
||||
LHU: s = this.printLoadInstr("lhu");
|
||||
LWU: s = this.printLoadInstr("lwu");
|
||||
FLW: s = this.printLoadInstr("flw");
|
||||
FLD: s = this.printLoadInstr("fld");
|
||||
FLQ: s = this.printLoadInstr("flq");
|
||||
FSW: s = this.printLoadInstr("fsw");
|
||||
FSD: s = this.printLoadInstr("fsd");
|
||||
FSQ: s = this.printLoadInstr("fsq");
|
||||
SB: s = this.printStoreInstr("sb");
|
||||
SH: s = this.printStoreInstr("sh");
|
||||
SW: s = this.printStoreInstr("sw");
|
||||
SD: s = this.printStoreInstr("sd");
|
||||
FSW: s = this.printStoreInstr("fsw");
|
||||
FSD: s = this.printStoreInstr("fsd");
|
||||
FSQ: s = this.printStoreInstr("fsq");
|
||||
INSTR_AMO: s = this.printAMOInstr();
|
||||
// Compressed Instructions
|
||||
C_FLD: s = this.printLoadInstr("c.fld");
|
||||
C_LW: s = this.printLoadInstr("c.lw");
|
||||
C_LD: s = this.printLoadInstr("c.ld");
|
||||
C_LWSP: s = this.printLoadInstr("c.lwsp");
|
||||
C_LDSP: s = this.printLoadInstr("c.ldsp");
|
||||
C_FLDSP: s = this.printLoadInstr("c.fldsp");
|
||||
C_SDSP: s = this.printStoreInstr("c.sdsp");
|
||||
C_SWSP: s = this.printStoreInstr("c.swsp");
|
||||
C_FSDSP: s = this.printStoreInstr("c.fsdsp");
|
||||
C_SW: s = this.printStoreInstr("c.sw");
|
||||
C_SD: s = this.printStoreInstr("c.sd");
|
||||
C_FSD: s = this.printStoreInstr("c.fsd");
|
||||
C_J: s = this.printJump("c.j");
|
||||
C_JR: s = this.printJump("c.jr");
|
||||
C_JALR: s = this.printJump("c.jalr");
|
||||
C_MV: s = this.printRInstr("c.mv");
|
||||
C_ADD: s = this.printRInstr("c.add");
|
||||
C_BEQZ: s = this.printSBInstr("c.beqz");
|
||||
C_BNEZ: s = this.printSBInstr("c.bnez");
|
||||
C_LUI: s = this.printUInstr("c.lui");
|
||||
C_LI: s = this.printIInstr("c.li");
|
||||
C_ADDI: s = this.printIInstr("c.addi");
|
||||
C_ADDI16SP: s = this.printIInstr("c.addi16sp");
|
||||
C_ADDIW: s = this.printIInstr("c.addiw");
|
||||
C_SLLI: s = this.printIInstr("c.slli");
|
||||
C_SRLI: s = this.printIInstr("c.srli");
|
||||
C_SRAI: s = this.printIInstr("c.srai");
|
||||
C_ANDI: s = this.printIInstr("c.andi");
|
||||
C_ADDI4SPN: s = this.printIInstr("c.addi4spn");
|
||||
C_SUB: s = this.printRInstr("c.sub");
|
||||
C_XOR: s = this.printRInstr("c.xor");
|
||||
C_OR: s = this.printRInstr("c.or");
|
||||
C_AND: s = this.printRInstr("c.and");
|
||||
C_SUBW: s = this.printRInstr("c.subw");
|
||||
C_ADDW: s = this.printRInstr("c.addw");
|
||||
C_NOP: s = this.printMnemonic("c.nop");
|
||||
C_EBREAK: s = this.printMnemonic("c.ebreak");
|
||||
default: s = this.printMnemonic("INVALID");
|
||||
endcase
|
||||
|
||||
|
||||
s = $sformatf("%8dns %8d %s %h %h %h %-36s", simtime,
|
||||
cycle,
|
||||
priv_lvl,
|
||||
|
@ -326,14 +383,14 @@ class instruction_trace_item;
|
|||
end
|
||||
|
||||
case (instr) inside
|
||||
// check of the instrction was a load or store
|
||||
INSTR_STORE,
|
||||
INSTR_STORE_FP: begin
|
||||
// check of the instruction was a load or store
|
||||
C_SDSP, C_SWSP, C_FSWSP, C_FSDSP, C_SW, C_SD, C_FSW, C_FSD,
|
||||
SB, SH, SW, SD, FSW, FSD, FSQ: begin
|
||||
logic [63:0] vaddress = gp_reg_file[read_regs[1]] + this.imm;
|
||||
s = $sformatf("%s VA: %x PA: %x", s, vaddress, this.paddr);
|
||||
end
|
||||
INSTR_LOAD,
|
||||
INSTR_LOAD_FP: begin
|
||||
C_FLD, C_FLW, C_LW, C_LD, C_LWSP, C_LDSP, C_FLWSP, C_FLDSP,
|
||||
LB, LH, LW, LD, LBU, LHU, LWU, FLW, FLD, FLQ: begin
|
||||
logic [63:0] vaddress = gp_reg_file[read_regs[0]] + this.imm;
|
||||
s = $sformatf("%s VA: %x PA: %x", s, vaddress, this.paddr);
|
||||
end
|
||||
|
@ -469,10 +526,11 @@ class instruction_trace_item;
|
|||
read_regs.push_back(rs2);
|
||||
read_fpr.push_back(1'b0);
|
||||
|
||||
if (rs2 == 0)
|
||||
return $sformatf("%-12s %4s, pc + %0d", mnemonic, regAddrToStr(rs1), $signed(sbe.result));
|
||||
else
|
||||
return $sformatf("%-12s %4s, %s, pc + %0d", mnemonic, regAddrToStr(rs1), regAddrToStr(rs2), $signed(sbe.result));
|
||||
if (rs2 == 0) begin
|
||||
return $sformatf("%-12s %4s, %s", mnemonic, regAddrToStr(rs1), printPCexpr(sbe.result));
|
||||
end else begin
|
||||
return $sformatf("%-12s %4s, %s, %s", mnemonic, regAddrToStr(rs1), regAddrToStr(rs2), printPCexpr(sbe.result));
|
||||
end
|
||||
endfunction // printIuInstr
|
||||
|
||||
function string printUInstr(input string mnemonic);
|
||||
|
@ -483,26 +541,17 @@ class instruction_trace_item;
|
|||
return $sformatf("%-12s %4s, 0x%0h", mnemonic, regAddrToStr(rd), sbe.result[31:12]);
|
||||
endfunction // printUInstr
|
||||
|
||||
function string printJump();
|
||||
string mnemonic;
|
||||
function string printJump(input string mnemonic);
|
||||
case (instr[6:0])
|
||||
riscv::OpcodeJalr: begin
|
||||
// is this a return?
|
||||
if (rd == 'b0 && (rs1 == 'h1 || rs1 == 'h5)) begin
|
||||
return this.printMnemonic("ret");
|
||||
end else begin
|
||||
return this.printIInstr("jalr");
|
||||
end
|
||||
if (rd == 'b0 && (rs1 == 'h1 || rs1 == 'h5)) return this.printMnemonic("ret");
|
||||
end
|
||||
|
||||
riscv::OpcodeJal: begin
|
||||
if (rd == 'b0)
|
||||
return this.printUJInstr("j");
|
||||
else
|
||||
return this.printUJInstr("jal");
|
||||
if (rd == 'b0) return this.printUJInstr("j");
|
||||
end
|
||||
endcase
|
||||
|
||||
return this.printIInstr(mnemonic);
|
||||
endfunction
|
||||
|
||||
function string printUJInstr(input string mnemonic);
|
||||
|
@ -511,9 +560,9 @@ class instruction_trace_item;
|
|||
result_fpr.push_back(1'b0);
|
||||
// jump instruction
|
||||
if (rd == 0)
|
||||
return $sformatf("%-12s pc + %0d", mnemonic, $signed(sbe.result));
|
||||
return $sformatf("%-12s %s", mnemonic, printPCexpr(sbe.result));
|
||||
else
|
||||
return $sformatf("%-12s %4s, pc + %0d", mnemonic, regAddrToStr(rd), $signed(sbe.result));
|
||||
return $sformatf("%-12s %4s, %s", mnemonic, regAddrToStr(rd), printPCexpr(sbe.result));
|
||||
endfunction // printUJInstr
|
||||
|
||||
function string printCSRInstr(input string mnemonic);
|
||||
|
@ -543,23 +592,7 @@ class instruction_trace_item;
|
|||
end
|
||||
endfunction // printCSRInstr
|
||||
|
||||
function string printLoadInstr();
|
||||
string mnemonic;
|
||||
|
||||
case (instr[14:12])
|
||||
3'b000: mnemonic = "lb";
|
||||
3'b001: mnemonic = "lh";
|
||||
3'b010: mnemonic = "lw";
|
||||
3'b100: mnemonic = "lbu";
|
||||
3'b101: mnemonic = "lhu";
|
||||
3'b110: mnemonic = "lwu";
|
||||
3'b011: mnemonic = "ld";
|
||||
default: return printMnemonic("INVALID");
|
||||
endcase
|
||||
|
||||
if (instr[6:0] == riscv::OpcodeLoadFp)
|
||||
mnemonic = $sformatf("f%s",mnemonic);
|
||||
|
||||
function string printLoadInstr(input string mnemonic);
|
||||
result_regs.push_back(rd);
|
||||
result_fpr.push_back(is_rd_fpr(sbe.op));
|
||||
read_regs.push_back(rs1);
|
||||
|
@ -573,19 +606,7 @@ class instruction_trace_item;
|
|||
return $sformatf("%-12s %4s, %0d(%s)", mnemonic, regAddrToStr(rd), $signed(sbe.result), regAddrToStr(rs1));
|
||||
endfunction
|
||||
|
||||
function string printStoreInstr();
|
||||
string mnemonic;
|
||||
case (instr[14:12])
|
||||
3'b000: mnemonic = "sb";
|
||||
3'b001: mnemonic = "sh";
|
||||
3'b010: mnemonic = "sw";
|
||||
3'b011: mnemonic = "sd";
|
||||
default: return printMnemonic("INVALID");
|
||||
endcase
|
||||
|
||||
if (instr[6:0] == riscv::OpcodeStoreFp)
|
||||
mnemonic = $sformatf("f%s",mnemonic);
|
||||
|
||||
function string printStoreInstr(input string mnemonic);
|
||||
read_regs.push_back(rs2);
|
||||
read_fpr.push_back(is_rs2_fpr(sbe.op));
|
||||
read_regs.push_back(rs1);
|
||||
|
@ -646,7 +667,6 @@ class instruction_trace_item;
|
|||
|
||||
function string printMulInstr(logic is_op32);
|
||||
string s = "";
|
||||
|
||||
case (this.instr[14:12])
|
||||
3'b000: s = "mul";
|
||||
3'b001: s = "mulh";
|
||||
|
@ -658,10 +678,16 @@ class instruction_trace_item;
|
|||
3'b111: s = "remu";
|
||||
endcase
|
||||
// if it is a 32 bit instruction concatenate a w on it
|
||||
if (is_op32)
|
||||
s = {s, "w"};
|
||||
|
||||
if (is_op32) s = {s, "w"};
|
||||
return this.printRInstr(s);
|
||||
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
function string printPCexpr(input logic [63:0] imm);
|
||||
// check if the sign bit is set
|
||||
if ($signed(imm) > 0) begin
|
||||
return $sformatf("pc + %0d", $signed(imm));
|
||||
end else begin
|
||||
return $sformatf("pc - %0d", $signed(-imm));
|
||||
end
|
||||
endfunction
|
||||
|
|
|
@ -133,7 +133,62 @@ parameter INSTR_FCVT_I2F = { 5'b11010, 2'b?, 5'b000??, 5'b?, 3'b?, 5'b?, riscv:
|
|||
parameter INSTR_AMO = {25'b?, riscv::OpcodeAmo };
|
||||
|
||||
// Load/Stores
|
||||
parameter INSTR_LOAD = {25'b?, riscv::OpcodeLoad};
|
||||
parameter INSTR_LOAD_FP = {25'b?, riscv::OpcodeLoadFp};
|
||||
parameter INSTR_STORE = {25'b?, riscv::OpcodeStore};
|
||||
parameter INSTR_STORE_FP = {25'b?, riscv::OpcodeStoreFp};
|
||||
parameter [31:0] LB = 32'b?????????????????000?????0000011;
|
||||
parameter [31:0] LH = 32'b?????????????????001?????0000011;
|
||||
parameter [31:0] LW = 32'b?????????????????010?????0000011;
|
||||
parameter [31:0] LD = 32'b?????????????????011?????0000011;
|
||||
parameter [31:0] LBU = 32'b?????????????????100?????0000011;
|
||||
parameter [31:0] LHU = 32'b?????????????????101?????0000011;
|
||||
parameter [31:0] LWU = 32'b?????????????????110?????0000011;
|
||||
parameter [31:0] FLW = 32'b?????????????????010?????0000111;
|
||||
parameter [31:0] FLD = 32'b?????????????????011?????0000111;
|
||||
parameter [31:0] FLQ = 32'b?????????????????100?????0000111;
|
||||
parameter [31:0] SB = 32'b?????????????????000?????0100011;
|
||||
parameter [31:0] SH = 32'b?????????????????001?????0100011;
|
||||
parameter [31:0] SW = 32'b?????????????????010?????0100011;
|
||||
parameter [31:0] SD = 32'b?????????????????011?????0100011;
|
||||
parameter [31:0] FSW = 32'b?????????????????010?????0100111;
|
||||
parameter [31:0] FSD = 32'b?????????????????011?????0100111;
|
||||
parameter [31:0] FSQ = 32'b?????????????????100?????0100111;
|
||||
parameter [31:0] C_ADDI4SPN = 32'b????????????????000???????????00;
|
||||
parameter [31:0] C_FLD = 32'b????????????????001???????????00;
|
||||
parameter [31:0] C_LW = 32'b????????????????010???????????00;
|
||||
parameter [31:0] C_FLW = 32'b????????????????011???????????00;
|
||||
parameter [31:0] C_FSD = 32'b????????????????101???????????00;
|
||||
parameter [31:0] C_SW = 32'b????????????????110???????????00;
|
||||
parameter [31:0] C_FSW = 32'b????????????????111???????????00;
|
||||
parameter [31:0] C_ADDI = 32'b????????????????000???????????01;
|
||||
parameter [31:0] C_JAL = 32'b????????????????001???????????01;
|
||||
parameter [31:0] C_LI = 32'b????????????????010???????????01;
|
||||
parameter [31:0] C_LUI = 32'b????????????????011???????????01;
|
||||
parameter [31:0] C_SRLI = 32'b????????????????100?00????????01;
|
||||
parameter [31:0] C_SRAI = 32'b????????????????100?01????????01;
|
||||
parameter [31:0] C_ANDI = 32'b????????????????100?10????????01;
|
||||
parameter [31:0] C_SUB = 32'b????????????????100011???00???01;
|
||||
parameter [31:0] C_XOR = 32'b????????????????100011???01???01;
|
||||
parameter [31:0] C_OR = 32'b????????????????100011???10???01;
|
||||
parameter [31:0] C_AND = 32'b????????????????100011???11???01;
|
||||
parameter [31:0] C_SUBW = 32'b????????????????100111???00???01;
|
||||
parameter [31:0] C_ADDW = 32'b????????????????100111???01???01;
|
||||
parameter [31:0] C_J = 32'b????????????????101???????????01;
|
||||
parameter [31:0] C_BEQZ = 32'b????????????????110???????????01;
|
||||
parameter [31:0] C_BNEZ = 32'b????????????????111???????????01;
|
||||
parameter [31:0] C_SLLI = 32'b????????????????000???????????10;
|
||||
parameter [31:0] C_FLDSP = 32'b????????????????001???????????10;
|
||||
parameter [31:0] C_LWSP = 32'b????????????????010???????????10;
|
||||
parameter [31:0] C_FLWSP = 32'b????????????????011???????????10;
|
||||
parameter [31:0] C_MV = 32'b????????????????1000??????????10;
|
||||
parameter [31:0] C_ADD = 32'b????????????????1001??????????10;
|
||||
parameter [31:0] C_FSDSP = 32'b????????????????101???????????10;
|
||||
parameter [31:0] C_SWSP = 32'b????????????????110???????????10;
|
||||
parameter [31:0] C_FSWSP = 32'b????????????????111???????????10;
|
||||
parameter [31:0] C_NOP = 32'b????????????????0000000000000001;
|
||||
parameter [31:0] C_ADDI16SP = 32'b????????????????011?00010?????01;
|
||||
parameter [31:0] C_JR = 32'b????????????????1000?????0000010;
|
||||
parameter [31:0] C_JALR = 32'b????????????????1001?????0000010;
|
||||
parameter [31:0] C_EBREAK = 32'b????????????????1001000000000010;
|
||||
parameter [31:0] C_LD = 32'b????????????????011???????????00;
|
||||
parameter [31:0] C_SD = 32'b????????????????111???????????00;
|
||||
parameter [31:0] C_ADDIW = 32'b????????????????001???????????01;
|
||||
parameter [31:0] C_LDSP = 32'b????????????????011???????????10;
|
||||
parameter [31:0] C_SDSP = 32'b????????????????111???????????10;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue