diff --git a/src/ariane.sv b/src/ariane.sv index dd5fddf18..361983db9 100644 --- a/src/ariane.sv +++ b/src/ariane.sv @@ -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); diff --git a/src/util/instruction_tracer.svh b/src/util/instruction_tracer.svh index 3f428470e..918ce734a 100755 --- a/src/util/instruction_tracer.svh +++ b/src/util/instruction_tracer.svh @@ -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; diff --git a/src/util/instruction_tracer_if.sv b/src/util/instruction_tracer_if.sv index 0c6219e4b..30c5ff185 100755 --- a/src/util/instruction_tracer_if.sv +++ b/src/util/instruction_tracer_if.sv @@ -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 diff --git a/test/add_test.S b/test/add_test.S index 65fc3b628..02010e3af 100755 --- a/test/add_test.S +++ b/test/add_test.S @@ -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