Add decode, issue, flush and commit logic to tracer

This commit is contained in:
Florian Zaruba 2017-05-30 15:44:01 +02:00
parent e29a923ca2
commit da62924f81
4 changed files with 94 additions and 27 deletions

View file

@ -212,6 +212,7 @@ module ariane
assign flush = 1'b0;
assign halt_if = 1'b0;
// --------------
// NPC Generation
// --------------
@ -251,6 +252,7 @@ module ariane
.ex_o ( exception_if_id ),
.*
);
// ---------
// ID
// ---------
@ -308,6 +310,7 @@ module ariane
.commit_ack_i ( commit_ack_commit_id ),
.*
);
// ---------
// EX
// ---------
@ -368,6 +371,7 @@ module ariane
.mult_valid_i ( mult_valid_id_ex ),
.*
);
// ---------
// Commit
// ---------
@ -388,6 +392,7 @@ module ariane
.irq_enable_i ( irq_enable_csr_commit ),
.*
);
// ---------
// CSR
// ---------
@ -415,10 +420,12 @@ module ariane
.asid_o ( asid_csr_ex ),
.*
);
// ------------
// Controller
// ------------
logic flush_commit_i;
logic flush_controller_ex;
controller controller_i (
.flush_bp_o ( ),
@ -426,7 +433,7 @@ module ariane
.flush_unissued_instr_o ( flush_unissued_instr_ctrl_id ),
.flush_if_o ( flush_ctrl_if ),
.flush_id_o ( ),
.flush_ex_o ( ),
.flush_ex_o ( flush_controller_ex ),
.flush_ready_lsu_i ( ),
.flush_commit_i ( flush_commit_i ),
@ -434,21 +441,31 @@ module ariane
.resolved_branch_i ( resolved_branch ),
.*
);
// -------------------
// Instruction Tracer
// -------------------
`ifndef SYNTHESIS
instruction_tracer_if tracer_if (clk_i);
// assign instruction tracer interface
// control signals
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.flush_unissued = flush_unissued_instr_ctrl_id;
assign tracer_if.flush = flush_controller_ex;
// fetch
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;
// Issue
assign tracer_if.issue_ack = id_stage_i.scoreboard_i.issue_ack_i;
assign tracer_if.issue_sbe = id_stage_i.scoreboard_i.issue_instr_o;
// write-back
assign tracer_if.waddr = waddr_a_commit_id;
assign tracer_if.wdata = wdata_a_commit_id;
assign tracer_if.we = we_a_commit_id;
// commit
assign tracer_if.commit_instr = commit_instr_id_commit;
assign tracer_if.commit_ack = commit_ack_commit_id;
program instr_tracer (instruction_tracer_if tracer_if);
instruction_tracer it = new (tracer_if);

View file

@ -17,13 +17,20 @@
// University of Bologna.
//
// keep the instruction and scoreboard entry together
typedef struct {
fetch_entry fetch_entry;
scoreboard_entry sbe;
} issue_entry;
class instruction_tracer;
// interface to the core
virtual instruction_tracer_if tracer_if;
// keep the decoded instructions in a queue
fetch_entry decode_queue [$];
// keep the issued instructions in a queue
issue_entry issue_queue [$];
// shadow copy of the register file
logic [63:0] reg_file [31];
// 64 bit clock tick count
@ -34,44 +41,83 @@ class instruction_tracer;
endfunction : new
task trace();
fetch_entry issue_instruction;
fetch_entry decode_instruction;
issue_entry issue_instruction;
forever begin
// new cycle, we are only interested if reset is de-asserted
@(tracer_if.pck iff tracer_if.pck.rstn);
// increment clock tick
clk_ticks++;
// We are decoding an instruction
// -------------------
// Instruction Decode
// -------------------
// 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);
decode_instruction = fetch_entry'(tracer_if.pck.fetch);
decode_queue.push_back(decode_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
// -------------------
// Instruction Issue
// -------------------
// we got a new issue ack, so put the element from the decode queue to
// the issue queue
if (tracer_if.pck.issue_ack) begin
issue_instruction.fetch_entry = decode_queue.pop_front();
issue_instruction.sbe = scoreboard_entry'(tracer_if.pck.issue_sbe);
issue_queue.push_back(issue_instruction);
printInstr(issue_instruction.sbe.pc, issue_instruction.fetch_entry.instruction);
end
// -----------
// Write Back
// -----------
// 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
// --------------
// Commit
// --------------
// we are committing an instruction
if (tracer_if.pck.commit_ack) begin
// printInstr(issue_instruction.instruction);
// $display("Committing: %0h", tracer_if.pck.commit_instr);
end
// --------------
// Flush Signals
// --------------
// flush un-issued instructions
if (tracer_if.pck.flush_unissued) begin
this.flushDecode();
end
// flush whole pipeline
if (tracer_if.pck.flush) begin
this.flush();
end
end
endtask
function void flushIssue ();
// flush all decoded instructions
function void flushDecode ();
for (int i = 0; i < decode_queue.size(); i++) begin
decode_queue.delete(i);
end
endfunction;
// flush everything, we took an exception/interrupt
function void flush ();
this.flushDecode();
for (int i = 0; i < issue_queue.size(); i++) begin
issue_queue.delete(i);
end
endfunction;
function void printInstr(logic [63:0] instr);
function void printInstr(logic [63:0] pc, logic [63:0] instr);
instruction_trace_item iti = new;
$display(iti.printInstr(instr));
$display("Time: %t Cycle: %d PC: %h Instruction: %s Instr: %0h", $time(), clk_ticks, pc, iti.printInstr(instr), instr);
endfunction;

View file

@ -23,25 +23,26 @@ interface instruction_tracer_if (
input clk
);
logic rstn;
logic flush_issue;
logic flush_unissued;
logic flush;
// decode
// Decode
fetch_entry fetch;
logic fetch_valid;
logic fetch_ack;
// Issue stage
logic issue_ack; // issue acknowledged
scoreboard_entry issue_sbe; // issue scoreboard entry
// 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;
input rstn, flush_unissued, flush, fetch, fetch_valid, fetch_ack, issue_ack, issue_sbe, waddr, wdata, we, commit_instr, commit_ack;
endclocking
endinterface

View file

@ -16,7 +16,10 @@
lui x8, 0xDEAD
sd x8, 0(x7)
add x6, x4, x5
add x15, x4, x5
ld x9, 0(x7)
add x15, x4, x5
add x14, x4, x5
nop
L0: jal x0, L1
nop