mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-23 13:47:13 -04:00
Add very preliminary instruction tracer
This commit is contained in:
parent
d601cef6c6
commit
cc421d8fa5
7 changed files with 569 additions and 2 deletions
8
Makefile
8
Makefile
|
@ -7,6 +7,9 @@ library = work
|
|||
# Top level module to compile
|
||||
top_level = core_tb
|
||||
test_top_level = core_tb
|
||||
|
||||
# utility modules
|
||||
util = $(wildcard src/util/*.sv)
|
||||
# test targets
|
||||
tests = alu scoreboard fifo mem_arbiter store_queue lsu core fetch_fifo
|
||||
# UVM agents
|
||||
|
@ -21,9 +24,9 @@ sequences = $(wildcard tb/sequences/*/*.sv)
|
|||
test_pkg = $(wildcard tb/test/*/*sequence_pkg.sv) $(wildcard tb/test/*/*_pkg.sv)
|
||||
|
||||
# this list contains the standalone components
|
||||
src = $(wildcard src/util/*.sv) $(wildcard src/*.sv)
|
||||
src = $(wildcard src/*.sv)
|
||||
# look for testbenches
|
||||
tbs = $(wildcard tb/*_tb.sv)
|
||||
tbs = $(wildcard tb/*_tb.sv)
|
||||
|
||||
# Search here for include files (e.g.: non-standalone components)
|
||||
incdir = ./includes
|
||||
|
@ -46,6 +49,7 @@ $(library):
|
|||
# Build the TB and module using QuestaSim
|
||||
build: $(library) build-agents build-interfaces
|
||||
# Suppress message that always_latch may not be checked thoroughly by QuestaSim.
|
||||
vlog${questa_version} ${compile_flag} -incr ${util} ${list_incdir} -suppress 2583
|
||||
# Compile agents, interfaces and environments
|
||||
vlog${questa_version} ${compile_flag} -incr ${envs} ${sequences} ${test_pkg} ${list_incdir} -suppress 2583
|
||||
# Compile source files
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
// University of Bologna.
|
||||
//
|
||||
import ariane_pkg::*;
|
||||
`ifndef SYNTHESIS
|
||||
import instruction_tracer_pkg::*;
|
||||
`endif
|
||||
|
||||
module ariane
|
||||
#(
|
||||
|
@ -428,7 +431,32 @@ module ariane
|
|||
.resolved_branch_i ( resolved_branch ),
|
||||
.*
|
||||
);
|
||||
// -------------------
|
||||
// Instruction Tracer
|
||||
// -------------------
|
||||
`ifndef SYNTHESIS
|
||||
instruction_tracer_if tracer_if (clk_i);
|
||||
// assign instruction tracer interface
|
||||
assign tracer_if.rstn = rst_ni;
|
||||
assign tracer_if.commit_instr = commit_instr_id_commit;
|
||||
assign tracer_if.commit_ack = commit_ack_commit_id;
|
||||
assign tracer_if.fetch = fetch_entry_if_id;
|
||||
assign tracer_if.fetch_valid = fetch_valid_if_id;
|
||||
assign tracer_if.fetch_ack = decode_ack_id_if;
|
||||
assign tracer_if.waddr = waddr_a_commit_id;
|
||||
assign tracer_if.wdata = wdata_a_commit_id;
|
||||
assign tracer_if.we = we_a_commit_id;
|
||||
|
||||
program instr_tracer (instruction_tracer_if tracer_if);
|
||||
instruction_tracer it = new (tracer_if);
|
||||
|
||||
initial begin
|
||||
it.trace();
|
||||
end
|
||||
endprogram
|
||||
|
||||
instr_tracer instr_tracer_i (tracer_if);
|
||||
`endif
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if(~rst_ni) begin
|
||||
|
|
311
src/util/instruction_trace_item.svh
Executable file
311
src/util/instruction_trace_item.svh
Executable file
|
@ -0,0 +1,311 @@
|
|||
class instruction_trace_item;
|
||||
time simtime;
|
||||
integer cycles;
|
||||
logic [31:0] pc;
|
||||
logic [31:0] instr;
|
||||
string str;
|
||||
|
||||
function new ();
|
||||
|
||||
endfunction
|
||||
|
||||
function string regAddrToStr(logic [5:0] addr);
|
||||
return $sformatf("x%0d", addr);
|
||||
endfunction
|
||||
|
||||
function string printInstr(logic [63:0] instr);
|
||||
string s;
|
||||
|
||||
casex (instr)
|
||||
// Aliases
|
||||
32'h00_00_00_13: s = this.printMnemonic("nop");
|
||||
// Regular opcodes
|
||||
INSTR_LUI: s = this.printUInstr("lui");
|
||||
INSTR_AUIPC: s = this.printUInstr("auipc");
|
||||
INSTR_JAL: s = this.printUJInstr("jal");
|
||||
INSTR_JALR: s = this.printIInstr("jalr");
|
||||
// BRANCH
|
||||
INSTR_BEQ: s = this.printSBInstr("beq");
|
||||
INSTR_BNE: s = this.printSBInstr("bne");
|
||||
INSTR_BLT: s = this.printSBInstr("blt");
|
||||
INSTR_BGE: s = this.printSBInstr("bge");
|
||||
INSTR_BLTU: s = this.printSBInstr("bltu");
|
||||
INSTR_BGEU: s = this.printSBInstr("bgeu");
|
||||
// OPIMM
|
||||
INSTR_ADDI: s = this.printIInstr("addi");
|
||||
INSTR_SLTI: s = this.printIInstr("slti");
|
||||
INSTR_SLTIU: s = this.printIInstr("sltiu");
|
||||
INSTR_XORI: s = this.printIInstr("xori");
|
||||
INSTR_ORI: s = this.printIInstr("ori");
|
||||
INSTR_ANDI: s = this.printIInstr("andi");
|
||||
INSTR_SLLI: s = this.printIuInstr("slli");
|
||||
INSTR_SRLI: s = this.printIuInstr("srli");
|
||||
INSTR_SRAI: s = this.printIuInstr("srai");
|
||||
// OP
|
||||
INSTR_ADD: s = this.printRInstr("add");
|
||||
INSTR_SUB: s = this.printRInstr("sub");
|
||||
INSTR_SLL: s = this.printRInstr("sll");
|
||||
INSTR_SLT: s = this.printRInstr("slt");
|
||||
INSTR_SLTU: s = this.printRInstr("sltu");
|
||||
INSTR_XOR: s = this.printRInstr("xor");
|
||||
INSTR_SRL: s = this.printRInstr("srl");
|
||||
INSTR_SRA: s = this.printRInstr("sra");
|
||||
INSTR_OR: s = this.printRInstr("or");
|
||||
INSTR_AND: s = this.printRInstr("and");
|
||||
// FENCE
|
||||
INSTR_FENCE: s = this.printMnemonic("fence");
|
||||
INSTR_FENCEI: s = this.printMnemonic("fencei");
|
||||
// SYSTEM (CSR man ipulation)
|
||||
INSTR_CSRRW: s = this.printCSRInstr("csrrw");
|
||||
INSTR_CSRRS: s = this.printCSRInstr("csrrs");
|
||||
INSTR_CSRRC: s = this.printCSRInstr("csrrc");
|
||||
INSTR_CSRRWI: s = this.printCSRInstr("csrrwi");
|
||||
INSTR_CSRRSI: s = this.printCSRInstr("csrrsi");
|
||||
INSTR_CSRRCI: s = this.printCSRInstr("csrrci");
|
||||
// SYSTEM (others)
|
||||
INSTR_ECALL: s = this.printMnemonic("ecall");
|
||||
INSTR_EBREAK: s = this.printMnemonic("ebreak");
|
||||
INSTR_ERET: s = this.printMnemonic("eret");
|
||||
INSTR_WFI: s = this.printMnemonic("wfi");
|
||||
// opcodes with custom decoding
|
||||
{25'b?, OPCODE_LOAD}: s = this.printLoadInstr();
|
||||
{25'b?, OPCODE_STORE}: s = this.printStoreInstr();
|
||||
default: s = this.printMnemonic("INVALID");
|
||||
endcase
|
||||
|
||||
return s;
|
||||
// $fwrite(f, "%t %15d %h %h %-36s", simtime,
|
||||
// cycles,
|
||||
// pc,
|
||||
// instr,
|
||||
// str);
|
||||
|
||||
// foreach(regs_write[i]) begin
|
||||
// if (regs_write[i].addr != 0)
|
||||
// $fwrite(f, " %s=%08x", regAddrToStr(regs_write[i].addr), regs_write[i].value);
|
||||
// end
|
||||
|
||||
// foreach(regs_read[i]) begin
|
||||
// if (regs_read[i].addr != 0)
|
||||
// $fwrite(f, " %s:%08x", regAddrToStr(regs_read[i].addr), regs_read[i].value);
|
||||
// end
|
||||
|
||||
// if (mem_access.size() > 0) begin
|
||||
// mem_acc = mem_access.pop_front();
|
||||
|
||||
// $fwrite(f, " PA:%08x", mem_acc.addr);
|
||||
// end
|
||||
|
||||
// $fwrite(f, "\n");
|
||||
endfunction
|
||||
|
||||
function string printMnemonic(input string mnemonic);
|
||||
return mnemonic;
|
||||
endfunction // printMnemonic
|
||||
|
||||
function string printRInstr(input string mnemonic);
|
||||
// return $sformatf("%-16s x%0d, x%0d, x%0d", mnemonic, rd, rs1, rs2);
|
||||
return mnemonic;
|
||||
endfunction // printRInstr
|
||||
|
||||
function string printIInstr(input string mnemonic);
|
||||
// begin
|
||||
// regs_read.push_back('{rs1, rs1_value});
|
||||
// regs_write.push_back('{rd, 'x});
|
||||
// str = $sformatf("%-16s x%0d, x%0d, %0d", mnemonic, rd, rs1, $signed(imm_i_type));
|
||||
// end
|
||||
return mnemonic;
|
||||
endfunction // printIInstr
|
||||
|
||||
function string printIuInstr(input string mnemonic);
|
||||
// begin
|
||||
// regs_read.push_back('{rs1, rs1_value});
|
||||
// regs_write.push_back('{rd, 'x});
|
||||
// str = $sformatf("%-16s x%0d, x%0d, 0x%0x", mnemonic, rd, rs1, imm_i_type);
|
||||
// end
|
||||
return mnemonic;
|
||||
endfunction // printIuInstr
|
||||
|
||||
function string printSBInstr(input string mnemonic);
|
||||
// begin
|
||||
// regs_read.push_back('{rs1, rs1_value});
|
||||
// regs_write.push_back('{rd, 'x});
|
||||
// str = $sformatf("%-16s x%0d, x%0d, 0x%0x", mnemonic, rd, rs1, imm_i_type);
|
||||
// end
|
||||
return mnemonic;
|
||||
endfunction // printIuInstr
|
||||
|
||||
function string printUInstr(input string mnemonic);
|
||||
// begin
|
||||
// regs_write.push_back('{rd, 'x});
|
||||
// str = $sformatf("%-16s x%0d, 0x%0h", mnemonic, rd, {imm_u_type[31:12], 12'h000});
|
||||
// end
|
||||
return mnemonic;
|
||||
endfunction // printUInstr
|
||||
|
||||
function string printUJInstr(input string mnemonic);
|
||||
// begin
|
||||
// regs_write.push_back('{rd, 'x});
|
||||
// str = $sformatf("%-16s x%0d, %0d", mnemonic, rd, $signed(imm_uj_type));
|
||||
// end
|
||||
return mnemonic;
|
||||
endfunction // printUJInstr
|
||||
|
||||
function string printCSRInstr(input string mnemonic);
|
||||
// logic [11:0] csr;
|
||||
// begin
|
||||
// csr = instr[31:20];
|
||||
|
||||
// regs_write.push_back('{rd, 'x});
|
||||
|
||||
// if (instr[14] == 1'b0) begin
|
||||
// regs_read.push_back('{rs1, rs1_value});
|
||||
// str = $sformatf("%-16s x%0d, x%0d, 0x%h", mnemonic, rd, rs1, csr);
|
||||
// end else begin
|
||||
// str = $sformatf("%-16s x%0d, 0x%h, 0x%h", mnemonic, rd, imm_z_type, csr);
|
||||
// end
|
||||
// end
|
||||
return mnemonic;
|
||||
endfunction // printCSRInstr
|
||||
|
||||
function string printLoadInstr();
|
||||
// string mnemonic;
|
||||
// logic [2:0] size;
|
||||
// begin
|
||||
// // detect reg-reg load and find size
|
||||
// size = instr[14:12];
|
||||
// if (instr[14:12] == 3'b111)
|
||||
// size = instr[30:28];
|
||||
|
||||
// case (size)
|
||||
// 3'b000: mnemonic = "lb";
|
||||
// 3'b001: mnemonic = "lh";
|
||||
// 3'b010: mnemonic = "lw";
|
||||
// 3'b100: mnemonic = "lbu";
|
||||
// 3'b101: mnemonic = "lhu";
|
||||
// 3'b110: mnemonic = "p.elw";
|
||||
// 3'b011,
|
||||
// 3'b111: begin
|
||||
// printMnemonic("INVALID");
|
||||
// return;
|
||||
// end
|
||||
// endcase
|
||||
|
||||
// regs_write.push_back('{rd, 'x});
|
||||
|
||||
// if (instr[14:12] != 3'b111) begin
|
||||
// // regular load
|
||||
// if (instr[6:0] != OPCODE_LOAD_POST) begin
|
||||
// regs_read.push_back('{rs1, rs1_value});
|
||||
// str = $sformatf("%-16s x%0d, %0d(x%0d)", mnemonic, rd, $signed(imm_i_type), rs1);
|
||||
// end else begin
|
||||
// regs_read.push_back('{rs1, rs1_value});
|
||||
// regs_write.push_back('{rs1, 'x});
|
||||
// str = $sformatf("p.%-14s x%0d, %0d(x%0d!)", mnemonic, rd, $signed(imm_i_type), rs1);
|
||||
// end
|
||||
// end else begin
|
||||
// // reg-reg load
|
||||
// if (instr[6:0] != OPCODE_LOAD_POST) begin
|
||||
// regs_read.push_back('{rs2, rs2_value});
|
||||
// regs_read.push_back('{rs1, rs1_value});
|
||||
// str = $sformatf("%-16s x%0d, x%0d(x%0d)", mnemonic, rd, rs2, rs1);
|
||||
// end else begin
|
||||
// regs_read.push_back('{rs2, rs2_value});
|
||||
// regs_read.push_back('{rs1, rs1_value});
|
||||
// regs_write.push_back('{rs1, 'x});
|
||||
// str = $sformatf("p.%-14s x%0d, x%0d(x%0d!)", mnemonic, rd, rs2, rs1);
|
||||
// end
|
||||
// end
|
||||
// end
|
||||
return "";
|
||||
endfunction
|
||||
|
||||
function string printStoreInstr();
|
||||
// string mnemonic;
|
||||
// begin
|
||||
|
||||
// case (instr[13:12])
|
||||
// 2'b00: mnemonic = "sb";
|
||||
// 2'b01: mnemonic = "sh";
|
||||
// 2'b10: mnemonic = "sw";
|
||||
// 2'b11: begin
|
||||
// printMnemonic("INVALID");
|
||||
// return;
|
||||
// end
|
||||
// endcase
|
||||
|
||||
// if (instr[14] == 1'b0) begin
|
||||
// // regular store
|
||||
// if (instr[6:0] != OPCODE_STORE_POST) begin
|
||||
// regs_read.push_back('{rs2, rs2_value});
|
||||
// regs_read.push_back('{rs1, rs1_value});
|
||||
// str = $sformatf("%-16s x%0d, %0d(x%0d)", mnemonic, rs2, $signed(imm_s_type), rs1);
|
||||
// end else begin
|
||||
// regs_read.push_back('{rs2, rs2_value});
|
||||
// regs_read.push_back('{rs1, rs1_value});
|
||||
// regs_write.push_back('{rs1, 'x});
|
||||
// str = $sformatf("p.%-14s x%0d, %0d(x%0d!)", mnemonic, rs2, $signed(imm_s_type), rs1);
|
||||
// end
|
||||
// end else begin
|
||||
// // reg-reg store
|
||||
// if (instr[6:0] != OPCODE_STORE_POST) begin
|
||||
// regs_read.push_back('{rs2, rs2_value});
|
||||
// regs_read.push_back('{rs3, rs3_value});
|
||||
// regs_read.push_back('{rs1, rs1_value});
|
||||
// str = $sformatf("p.%-14s x%0d, x%0d(x%0d)", mnemonic, rs2, rs3, rs1);
|
||||
// end else begin
|
||||
// regs_read.push_back('{rs2, rs2_value});
|
||||
// regs_read.push_back('{rs3, rs3_value});
|
||||
// regs_read.push_back('{rs1, rs1_value});
|
||||
// regs_write.push_back('{rs1, 'x});
|
||||
// str = $sformatf("p.%-14s x%0d, x%0d(x%0d!)", mnemonic, rs2, rs3, rs1);
|
||||
// end
|
||||
// end
|
||||
// end
|
||||
return "";
|
||||
endfunction // printSInstr
|
||||
|
||||
function string printMulInstr();
|
||||
// string mnemonic;
|
||||
// string str_suf;
|
||||
// string str_imm;
|
||||
// string str_asm;
|
||||
// begin
|
||||
|
||||
// // always read rs1 and rs2 and write rd
|
||||
// regs_read.push_back('{rs1, rs1_value});
|
||||
// regs_read.push_back('{rs2, rs2_value});
|
||||
// regs_write.push_back('{rd, 'x});
|
||||
|
||||
// if (instr[12])
|
||||
// regs_read.push_back('{rd, rs3_value});
|
||||
|
||||
// case ({instr[31:30], instr[14]})
|
||||
// 3'b000: str_suf = "u";
|
||||
// 3'b001: str_suf = "uR";
|
||||
// 3'b010: str_suf = "hhu";
|
||||
// 3'b011: str_suf = "hhuR";
|
||||
// 3'b100: str_suf = "s";
|
||||
// 3'b101: str_suf = "sR";
|
||||
// 3'b110: str_suf = "hhs";
|
||||
// 3'b111: str_suf = "hhsR";
|
||||
// endcase
|
||||
|
||||
// if (instr[12])
|
||||
// mnemonic = "p.mac";
|
||||
// else
|
||||
// mnemonic = "p.mul";
|
||||
|
||||
// if (imm_s3_type[4:0] != 5'b00000)
|
||||
// str_asm = $sformatf("%s%sN", mnemonic, str_suf);
|
||||
// else
|
||||
// str_asm = $sformatf("%s%s", mnemonic, str_suf);
|
||||
|
||||
// if (instr[29:25] != 5'b00000)
|
||||
// str = $sformatf("%-16s x%0d, x%0d, x%0d, %0d", str_asm, rd, rs1, rs2, $unsigned(imm_s3_type[4:0]));
|
||||
// else
|
||||
// str = $sformatf("%-16s x%0d, x%0d, x%0d", str_asm, rd, rs1, rs2);
|
||||
// end
|
||||
return "";
|
||||
endfunction
|
||||
endclass
|
78
src/util/instruction_tracer.svh
Executable file
78
src/util/instruction_tracer.svh
Executable file
|
@ -0,0 +1,78 @@
|
|||
// Author: Florian Zaruba, ETH Zurich
|
||||
// Date: 16.05.2017
|
||||
// Description: Instruction Tracer Main Class
|
||||
//
|
||||
// Copyright (C) 2017 ETH Zurich, University of Bologna
|
||||
// All rights reserved.
|
||||
//
|
||||
// This code is under development and not yet released to the public.
|
||||
// Until it is released, the code is under the copyright of ETH Zurich and
|
||||
// the University of Bologna, and may contain confidential and/or unpublished
|
||||
// work. Any reuse/redistribution is strictly forbidden without written
|
||||
// permission from ETH Zurich.
|
||||
//
|
||||
// Bug fixes and contributions will eventually be released under the
|
||||
// SolderPad open hardware license in the context of the PULP platform
|
||||
// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the
|
||||
// University of Bologna.
|
||||
//
|
||||
|
||||
class instruction_tracer;
|
||||
|
||||
// interface to the core
|
||||
virtual instruction_tracer_if tracer_if;
|
||||
|
||||
// keep the decoded instructions in a queue
|
||||
fetch_entry decode_queue [$];
|
||||
// shadow copy of the register file
|
||||
logic [63:0] reg_file [31];
|
||||
// 64 bit clock tick count
|
||||
longint unsigned clk_ticks;
|
||||
|
||||
function new(virtual instruction_tracer_if tracer_if);
|
||||
this.tracer_if = tracer_if;
|
||||
endfunction : new
|
||||
|
||||
task trace();
|
||||
fetch_entry issue_instruction;
|
||||
forever begin
|
||||
// new cycle, we are only interested if reset is de-asserted
|
||||
@(tracer_if.pck iff tracer_if.pck.rstn);
|
||||
clk_ticks++;
|
||||
|
||||
// We are decoding an instruction
|
||||
if (tracer_if.pck.fetch_valid && tracer_if.pck.fetch_ack) begin
|
||||
decode_queue.push_back(tracer_if.pck.fetch);
|
||||
issue_instruction = fetch_entry'(tracer_if.pck.fetch);
|
||||
printInstr(issue_instruction.instruction);
|
||||
end
|
||||
// we are committing an instruction
|
||||
|
||||
// if (tracer_if.pck.commit_instr.valid) begin
|
||||
// $display("Committing: %0h", tracer_if.pck.commit_instr);
|
||||
// end
|
||||
|
||||
// write back
|
||||
if (tracer_if.pck.we && tracer_if.pck.waddr != 5'b0) begin
|
||||
reg_file[tracer_if.pck.waddr] = tracer_if.pck.wdata;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
endtask
|
||||
|
||||
function void flushIssue ();
|
||||
|
||||
endfunction;
|
||||
|
||||
function void flush ();
|
||||
|
||||
endfunction;
|
||||
|
||||
function void printInstr(logic [63:0] instr);
|
||||
instruction_trace_item iti = new;
|
||||
$display(iti.printInstr(instr));
|
||||
|
||||
endfunction;
|
||||
|
||||
endclass : instruction_tracer
|
73
src/util/instruction_tracer_defines.svh
Executable file
73
src/util/instruction_tracer_defines.svh
Executable file
|
@ -0,0 +1,73 @@
|
|||
// Author: Florian Zaruba, ETH Zurich
|
||||
// Date: 16.05.2017
|
||||
// Description: Instruction Tracer Defines
|
||||
//
|
||||
// Copyright (C) 2017 ETH Zurich, University of Bologna
|
||||
// All rights reserved.
|
||||
//
|
||||
// This code is under development and not yet released to the public.
|
||||
// Until it is released, the code is under the copyright of ETH Zurich and
|
||||
// the University of Bologna, and may contain confidential and/or unpublished
|
||||
// work. Any reuse/redistribution is strictly forbidden without written
|
||||
// permission from ETH Zurich.
|
||||
//
|
||||
// Bug fixes and contributions will eventually be released under the
|
||||
// SolderPad open hardware license in the context of the PULP platform
|
||||
// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the
|
||||
// University of Bologna.
|
||||
//
|
||||
|
||||
parameter INSTR_LUI = { 25'b?, OPCODE_LUI };
|
||||
parameter INSTR_AUIPC = { 25'b?, OPCODE_AUIPC };
|
||||
parameter INSTR_JAL = { 25'b?, OPCODE_JAL };
|
||||
parameter INSTR_JALR = { 17'b?, 3'b000, 5'b?, OPCODE_JALR };
|
||||
// BRANCH
|
||||
parameter INSTR_BEQ = { 17'b?, 3'b000, 5'b?, OPCODE_BRANCH };
|
||||
parameter INSTR_BNE = { 17'b?, 3'b001, 5'b?, OPCODE_BRANCH };
|
||||
parameter INSTR_BLT = { 17'b?, 3'b100, 5'b?, OPCODE_BRANCH };
|
||||
parameter INSTR_BGE = { 17'b?, 3'b101, 5'b?, OPCODE_BRANCH };
|
||||
parameter INSTR_BLTU = { 17'b?, 3'b110, 5'b?, OPCODE_BRANCH };
|
||||
parameter INSTR_BGEU = { 17'b?, 3'b111, 5'b?, OPCODE_BRANCH };
|
||||
|
||||
// OPIMM
|
||||
parameter INSTR_ADDI = { 17'b?, 3'b000, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_SLTI = { 17'b?, 3'b010, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_SLTIU = { 17'b?, 3'b011, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_XORI = { 17'b?, 3'b100, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_ORI = { 17'b?, 3'b110, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_ANDI = { 17'b?, 3'b111, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_SLLI = { 7'b0000000, 10'b?, 3'b001, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_SRLI = { 7'b0000000, 10'b?, 3'b101, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_SRAI = { 7'b0100000, 10'b?, 3'b101, 5'b?, OPCODE_OPIMM };
|
||||
// OP
|
||||
parameter INSTR_ADD = { 7'b0000000, 10'b?, 3'b000, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_SUB = { 7'b0100000, 10'b?, 3'b000, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_SLL = { 7'b0000000, 10'b?, 3'b001, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_SLT = { 7'b0000000, 10'b?, 3'b010, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_SLTU = { 7'b0000000, 10'b?, 3'b011, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_XOR = { 7'b0000000, 10'b?, 3'b100, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_SRL = { 7'b0000000, 10'b?, 3'b101, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_SRA = { 7'b0100000, 10'b?, 3'b101, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_OR = { 7'b0000000, 10'b?, 3'b110, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_AND = { 7'b0000000, 10'b?, 3'b111, 5'b?, OPCODE_OP };
|
||||
// FENCE
|
||||
parameter INSTR_FENCE = { 4'b0, 8'b?, 13'b0, OPCODE_FENCE };
|
||||
parameter INSTR_FENCEI = { 17'b0, 3'b001, 5'b0, OPCODE_FENCE };
|
||||
// SYSTEM
|
||||
parameter INSTR_CSRRW = { 17'b?, 3'b001, 5'b?, OPCODE_SYSTEM };
|
||||
parameter INSTR_CSRRS = { 17'b?, 3'b010, 5'b?, OPCODE_SYSTEM };
|
||||
parameter INSTR_CSRRC = { 17'b?, 3'b011, 5'b?, OPCODE_SYSTEM };
|
||||
parameter INSTR_CSRRWI = { 17'b?, 3'b101, 5'b?, OPCODE_SYSTEM };
|
||||
parameter INSTR_CSRRSI = { 17'b?, 3'b110, 5'b?, OPCODE_SYSTEM };
|
||||
parameter INSTR_CSRRCI = { 17'b?, 3'b111, 5'b?, OPCODE_SYSTEM };
|
||||
parameter INSTR_ECALL = { 12'b000000000000, 13'b0, OPCODE_SYSTEM };
|
||||
parameter INSTR_EBREAK = { 12'b000000000001, 13'b0, OPCODE_SYSTEM };
|
||||
parameter INSTR_ERET = { 12'b000100000000, 13'b0, OPCODE_SYSTEM };
|
||||
parameter INSTR_WFI = { 12'b000100000010, 13'b0, OPCODE_SYSTEM };
|
||||
|
||||
// RV32M
|
||||
parameter INSTR_PMUL = { 7'b0000001, 10'b?, 3'b000, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_DIV = { 7'b0000001, 10'b?, 3'b100, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_DIVU = { 7'b0000001, 10'b?, 3'b101, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_REM = { 7'b0000001, 10'b?, 3'b110, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_REMU = { 7'b0000001, 10'b?, 3'b111, 5'b?, OPCODE_OP };
|
48
src/util/instruction_tracer_if.sv
Executable file
48
src/util/instruction_tracer_if.sv
Executable file
|
@ -0,0 +1,48 @@
|
|||
// Author: Florian Zaruba, ETH Zurich
|
||||
// Date: 16.05.2017
|
||||
// Description: Instruction Tracer Interface
|
||||
//
|
||||
// Copyright (C) 2017 ETH Zurich, University of Bologna
|
||||
// All rights reserved.
|
||||
//
|
||||
// This code is under development and not yet released to the public.
|
||||
// Until it is released, the code is under the copyright of ETH Zurich and
|
||||
// the University of Bologna, and may contain confidential and/or unpublished
|
||||
// work. Any reuse/redistribution is strictly forbidden without written
|
||||
// permission from ETH Zurich.
|
||||
//
|
||||
// Bug fixes and contributions will eventually be released under the
|
||||
// SolderPad open hardware license in the context of the PULP platform
|
||||
// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the
|
||||
// University of Bologna.
|
||||
//
|
||||
import ariane_pkg::*;
|
||||
`ifndef INSTR_TRACER_IF_SV
|
||||
`define INSTR_TRACER_IF_SV
|
||||
interface instruction_tracer_if (
|
||||
input clk
|
||||
);
|
||||
logic rstn;
|
||||
logic flush_issue;
|
||||
logic flush;
|
||||
// decode
|
||||
fetch_entry fetch;
|
||||
logic fetch_valid;
|
||||
logic fetch_ack;
|
||||
|
||||
// WB stage
|
||||
logic [4:0] waddr;
|
||||
logic [63:0] wdata;
|
||||
logic we;
|
||||
|
||||
// commit stage
|
||||
scoreboard_entry commit_instr; // commit instruction
|
||||
logic commit_ack;
|
||||
|
||||
// the tracer just has a passive interface we do not drive anything with it
|
||||
clocking pck @(posedge clk);
|
||||
input rstn, flush, fetch, fetch_valid, fetch_ack, waddr, wdata, we, commit_instr, commit_ack;
|
||||
endclocking
|
||||
|
||||
endinterface
|
||||
`endif
|
25
src/util/instruction_tracer_pkg.sv
Executable file
25
src/util/instruction_tracer_pkg.sv
Executable file
|
@ -0,0 +1,25 @@
|
|||
// Author: Florian Zaruba, ETH Zurich
|
||||
// Date: 16.05.2017
|
||||
// Description: Instruction Tracer Package
|
||||
//
|
||||
// Copyright (C) 2017 ETH Zurich, University of Bologna
|
||||
// All rights reserved.
|
||||
//
|
||||
// This code is under development and not yet released to the public.
|
||||
// Until it is released, the code is under the copyright of ETH Zurich and
|
||||
// the University of Bologna, and may contain confidential and/or unpublished
|
||||
// work. Any reuse/redistribution is strictly forbidden without written
|
||||
// permission from ETH Zurich.
|
||||
//
|
||||
// Bug fixes and contributions will eventually be released under the
|
||||
// SolderPad open hardware license in the context of the PULP platform
|
||||
// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the
|
||||
// University of Bologna.
|
||||
//
|
||||
package instruction_tracer_pkg;
|
||||
import ariane_pkg::*;
|
||||
|
||||
`include "instruction_tracer_defines.svh"
|
||||
`include "instruction_trace_item.svh"
|
||||
`include "instruction_tracer.svh"
|
||||
endpackage
|
Loading…
Add table
Add a link
Reference in a new issue