Output using logger
This commit is contained in:
parent
e319d70709
commit
cb6ab414b9
|
|
@ -3,6 +3,7 @@ split_verilogs
|
|||
.vscode
|
||||
**/__pycache__/
|
||||
*.fst
|
||||
*.log
|
||||
*.dat
|
||||
**/UT_*
|
||||
NemuBR/
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from .uftb_model import uFTBModel
|
|||
|
||||
def assert_equal(a, b):
|
||||
if a != b:
|
||||
print(f"[Error] Expected is {a}, but actual is {b}")
|
||||
logger.error(f"[Error] Expected is {a}, but actual is {b}")
|
||||
exit(1)
|
||||
|
||||
def compare_uftb_full_pred(uftb_output, std_output):
|
||||
|
|
@ -148,27 +148,27 @@ class BPUTop:
|
|||
else:
|
||||
self.s1_hit_way = None
|
||||
|
||||
# print("-" * 30)
|
||||
logger.debug("-" * 30)
|
||||
if self.s1_fire:
|
||||
# Debug Imformation
|
||||
# print("[BPU]")
|
||||
# print("New prediction at", hex(self.s1_pc))
|
||||
# if bpu_output["s1"]["full_pred"]["hit"]:
|
||||
# print("Dut Hit")
|
||||
logger.debug("[BPU]")
|
||||
logger.debug(f"New prediction at {hex(self.s1_pc)}")
|
||||
if bpu_output["s1"]["full_pred"]["hit"]:
|
||||
logger.debug("Dut Hit")
|
||||
|
||||
# print("FTB Entry in pred result: ")
|
||||
# if bpu_output["s1"]["full_pred"]["hit"]:
|
||||
# ftb_entry.print(self.s1_pc)
|
||||
# else:
|
||||
# print("No FTB Entry")
|
||||
# print("br_taken_mask:", bpu_output["s1"]["full_pred"]["br_taken_mask_0"], bpu_output["s1"]["full_pred"]["br_taken_mask_1"])
|
||||
logger.debug("FTB Entry in pred result: ")
|
||||
if bpu_output["s1"]["full_pred"]["hit"]:
|
||||
logger.debug(ftb_entry.__str__(self.s1_pc))
|
||||
else:
|
||||
logger.debug("No FTB Entry")
|
||||
logger.debug(f"br_taken_mask: {bpu_output['s1']['full_pred']['br_taken_mask_0']}, {bpu_output['s1']['full_pred']['br_taken_mask_1']}")
|
||||
|
||||
# print("FTB Entry in uFTB Model: ")
|
||||
# if model_output:
|
||||
# model_output[0].print(self.s1_pc)
|
||||
# print("br_taken_mask:", model_output[1])
|
||||
# else:
|
||||
# print("No FTB Entry")
|
||||
logger.debug("FTB Entry in uFTB Model: ")
|
||||
if model_output:
|
||||
logger.debug(model_output[0].__str__(self.s1_pc))
|
||||
logger.debug(f"br_taken_mask: {model_output[1]}")
|
||||
else:
|
||||
logger.debug("No FTB Entry")
|
||||
|
||||
# Compare dut output and uFTB model output
|
||||
expected_hit = model_output is not None
|
||||
|
|
|
|||
|
|
@ -8,15 +8,18 @@ class FTBSlot:
|
|||
self.tarStart = 0
|
||||
self.sharing = 0
|
||||
|
||||
def print(self, pc, is_cond_branch):
|
||||
def __str__(self, pc, is_cond_branch):
|
||||
str = ""
|
||||
if not self.valid:
|
||||
print("*\tInvalid FTBSlot")
|
||||
return
|
||||
str += "*\tInvalid FTBSlot\n"
|
||||
return str
|
||||
|
||||
if is_cond_branch:
|
||||
print(f"*\t[Conditional Branch Inst] at PC {hex(get_slot_addr(pc, self.offset))}: Target: {hex(get_target_addr(pc, self.tarStart, self.lower, 12))}")
|
||||
str += f"*\t[Conditional Branch Inst] at PC {hex(get_slot_addr(pc, self.offset))}: Target: {hex(get_target_addr(pc, self.tarStart, self.lower, 12))}\n"
|
||||
else:
|
||||
print(f"*\t[Jump Inst] PC {hex(get_slot_addr(pc, self.offset))}: Target: {hex(get_target_addr(pc, self.tarStart, self.lower, 20))}")
|
||||
str += f"*\t[Jump Inst] PC {hex(get_slot_addr(pc, self.offset))}: Target: {hex(get_target_addr(pc, self.tarStart, self.lower, 20))}\n"
|
||||
|
||||
return str
|
||||
|
||||
|
||||
class FTBEntry:
|
||||
|
|
@ -165,16 +168,17 @@ class FTBEntry:
|
|||
|
||||
return entry
|
||||
|
||||
|
||||
def print(self, pc):
|
||||
print(f"[FTBEntry at {hex(pc)}]")
|
||||
print(f"* Slots:")
|
||||
self.brSlot.print(pc, True)
|
||||
self.tailSlot.print(pc, self.tailSlot.sharing)
|
||||
print("* Other Info:")
|
||||
print(f"*\tFallthrough Addr: {hex(get_fallthrough_addr(pc, self.pftAddr, self.carry))}")
|
||||
print(f"*\tisCall: {self.isCall}, isRet: {self.isRet}, isJalr: {self.isJalr}, isJal: {self.isJal}")
|
||||
print(f"*\tlast_may_be_rvi_call: {self.last_may_be_rvi_call}, always_taken: {self.always_taken}")
|
||||
def __str__(self, pc) -> str:
|
||||
str = ""
|
||||
str += f"[FTBEntry] at {hex(pc)}\n"
|
||||
str += f"* Slots:\n"
|
||||
str += self.brSlot.__str__(pc, True)
|
||||
str += self.tailSlot.__str__(pc, self.tailSlot.sharing)
|
||||
str += "* Other Info:\n"
|
||||
str += f"*\tFallthrough Addr: {hex(get_fallthrough_addr(pc, self.pftAddr, self.carry))}\n"
|
||||
str += f"*\tisCall: {self.isCall}, isRet: {self.isRet}, isJalr: {self.isJalr}, isJal: {self.isJal}\n"
|
||||
str += f"*\tlast_may_be_rvi_call: {self.last_may_be_rvi_call}, always_taken: {self.always_taken}\n"
|
||||
return str
|
||||
|
||||
class FTBProvider():
|
||||
def __init__(self):
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from mlvp import *
|
||||
from random import random
|
||||
from .bundle import *
|
||||
from .config import *
|
||||
|
|
@ -31,27 +32,30 @@ class PredictionStatistician:
|
|||
self.jmp_branches_list[pc] = [branch_type, 1, int(correct)]
|
||||
|
||||
def summary(self):
|
||||
print("=" * 30)
|
||||
print("Summary")
|
||||
print("[Conditional Branches]")
|
||||
summary_str = ""
|
||||
summary_str += "=" * 30 + "\n"
|
||||
summary_str += "Summary\n"
|
||||
summary_str += "[Conditional Branches]\n"
|
||||
cond_branches_total = sum([record[0] for record in self.cond_branches_list.values()])
|
||||
cond_branches_correct = sum([record[1] for record in self.cond_branches_list.values()])
|
||||
print(f"Total: {cond_branches_total}, Correct: {cond_branches_correct}, Accuracy: {cond_branches_correct / cond_branches_total}")
|
||||
summary_str += f"Total: {cond_branches_total}, Correct: {cond_branches_correct}, Accuracy: {cond_branches_correct / cond_branches_total}\n"
|
||||
|
||||
for pc, record in self.cond_branches_list.items():
|
||||
print(f"PC: {hex(pc)}\tTotal: {record[0]}\tCorrect: {record[1]}\tAccuracy: {record[1] / record[0]}")
|
||||
summary_str += f"PC: {hex(pc)}\tTotal: {record[0]}\tCorrect: {record[1]}\tAccuracy: {record[1] / record[0]}\n"
|
||||
|
||||
print("[Jump Branches]")
|
||||
summary_str += "[Jump Branches]\n"
|
||||
jmp_branches_total = sum([record[1] for record in self.jmp_branches_list.values()])
|
||||
jmp_branches_correct = sum([record[2] for record in self.jmp_branches_list.values()])
|
||||
print(f"Total: {jmp_branches_total}, Correct: {jmp_branches_correct}, Accuracy: {jmp_branches_correct / jmp_branches_total}")
|
||||
summary_str += f"Total: {jmp_branches_total}, Correct: {jmp_branches_correct}, Accuracy: {jmp_branches_correct / jmp_branches_total}\n"
|
||||
for pc, record in self.jmp_branches_list.items():
|
||||
print(f"PC: {hex(pc)}\tType: {record[0]}\tTotal: {record[1]}\tCorrect: {record[2]}\tAccuracy: {record[2] / record[1]}")
|
||||
summary_str += f"PC: {hex(pc)}\tType: {record[0]}\tTotal: {record[1]}\tCorrect: {record[2]}\tAccuracy: {record[2] / record[1]}\n"
|
||||
|
||||
print("[All Branches]")
|
||||
summary_str += "[All Branches]\n"
|
||||
total = cond_branches_total + jmp_branches_total
|
||||
correct = cond_branches_correct + jmp_branches_correct
|
||||
print(f"Total: {total}, Correct: {correct}, Accuracy: {correct / total}")
|
||||
summary_str += f"Total: {total}, Correct: {correct}, Accuracy: {correct / total}\n"
|
||||
|
||||
logger.info(summary_str)
|
||||
|
||||
@staticmethod
|
||||
def get_type(is_call, is_ret, is_jalr, is_jal):
|
||||
|
|
@ -104,13 +108,12 @@ class FTQ:
|
|||
update_request, redirect_request = None, None
|
||||
if self.update_queue:
|
||||
update_request = self._generate_update_request(self.update_queue.pop(0))
|
||||
# print("Send Update Request: %s" % hex(update_request['bits_pc']), \
|
||||
# "br_taken_mask:", update_request["bits_br_taken_mask_0"], update_request["bits_br_taken_mask_1"])
|
||||
|
||||
logger.debug(f"Send Update Request: {hex(update_request['bits_pc'])}\
|
||||
br_taken_mask: {update_request['bits_br_taken_mask_0']}, {update_request['bits_br_taken_mask_1']}")
|
||||
if self.redirect_queue:
|
||||
cfi_target = self.redirect_queue.pop(0)
|
||||
redirect_request = self._generate_redirect_request(cfi_target)
|
||||
# print("Send Redirect Request: (target: %s)" % hex(cfi_target))
|
||||
logger.debug("Send Redirect Request: (target: %s)" % hex(cfi_target))
|
||||
|
||||
return (update_request, redirect_request)
|
||||
|
||||
|
|
@ -129,18 +132,18 @@ class FTQ:
|
|||
entry = self._get_entry(self.exec_ptr)
|
||||
executor_current_pc = self.executor.current_inst()[0]
|
||||
self.exec_ptr += 1
|
||||
# print("Executing FTQ entry at pc %s" % hex(entry.pc))
|
||||
logger.debug("Executing FTQ entry at pc %s" % hex(entry.pc))
|
||||
|
||||
# Prediction Block Hit
|
||||
if entry.full_pred["hit"] and entry.pc == executor_current_pc:
|
||||
# print("Prediction Block Hit")
|
||||
logger.debug("Prediction Block Hit")
|
||||
|
||||
# Execute the prediction block
|
||||
all_branches, redirect_addr, br_taken_mask = self._execute_this_pred_block(entry.pc, entry.full_pred)
|
||||
# if redirect_addr is None:
|
||||
# print("Predicition is correct")
|
||||
# else:
|
||||
# print("Prediction is wrong, redirect to %s" % hex(redirect_addr))
|
||||
if redirect_addr is None:
|
||||
logger.debug("Predicition is correct")
|
||||
else:
|
||||
logger.debug("Prediction is wrong, redirect to %s" % hex(redirect_addr))
|
||||
new_ftb_entry = self._update_ftb_entry_from_branches(entry.pc, entry.ftb, all_branches, br_taken_mask)
|
||||
self.update_queue.append((entry.pc, new_ftb_entry, br_taken_mask))
|
||||
if redirect_addr is not None:
|
||||
|
|
@ -148,9 +151,9 @@ class FTQ:
|
|||
|
||||
# Prediction Block Miss
|
||||
else:
|
||||
# print("Prediction Block Miss")
|
||||
# if entry.pc != executor_current_pc:
|
||||
# print("Target Error: actual: %s expected: %s" % (hex(entry.pc), hex(executor_current_pc)))
|
||||
logger.debug("Prediction Block Miss")
|
||||
if entry.pc != executor_current_pc:
|
||||
logger.debug("Target Error: actual: %s expected: %s" % (hex(entry.pc), hex(executor_current_pc)))
|
||||
|
||||
# Create a new FTB entry and update & redirect
|
||||
new_ftb_entry, br_taken_mask = self._generate_new_ftb_entry(executor_current_pc)
|
||||
|
|
@ -288,14 +291,14 @@ class FTQ:
|
|||
ftb_entry.pftAddr = get_pftaddr(fallthrough_addr)
|
||||
ftb_entry.carry = get_pftaddr_carry(pc, fallthrough_addr)
|
||||
|
||||
# print("Generate FTB Entry")
|
||||
# ftb_entry.print(pc)
|
||||
logger.debug("Generate FTB Entry")
|
||||
logger.debug(ftb_entry.__str__(pc))
|
||||
|
||||
return ftb_entry, br_taken_mask
|
||||
|
||||
def _update_entries(self, bpu_out, ftb_entry):
|
||||
if bpu_out["s1"]["valid"]:
|
||||
# print("Add ftq entry (pc: %s)" % hex(bpu_out["s1"]["pc_3"]))
|
||||
logger.debug("Add ftq entry (pc: %s)" % hex(bpu_out["s1"]["pc_3"]))
|
||||
entry = self._get_entry(self.bpu_ptr)
|
||||
entry.full_pred = bpu_out["s1"]["full_pred"]
|
||||
entry.pc = bpu_out["s1"]["pc_3"]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from mlvp.utils import PLRU, TwoBitsCounter
|
||||
from mlvp import logger
|
||||
from .ftb import *
|
||||
|
||||
class uFTBWay:
|
||||
|
|
@ -42,7 +43,7 @@ class uFTBModel:
|
|||
|
||||
def print_all_ftb_ways(self):
|
||||
for i in range(UFTB_WAYS_NUM):
|
||||
print(f"way {i}: valid: {self.ftbways[i].valid}, tag: {hex(self.ftbways[i].tag << 1)}")
|
||||
logger.debug(f"way {i}: valid: {self.ftbways[i].valid}, tag: {hex(self.ftbways[i].tag << 1)}")
|
||||
|
||||
def _generate_br_taken_mask(self, hit_way):
|
||||
ftb_entry = self.ftbways[hit_way].ftb_entry
|
||||
|
|
@ -91,7 +92,7 @@ class uFTBModel:
|
|||
if selected_way is None or way < selected_way:
|
||||
selected_way = way
|
||||
break
|
||||
# print(f"Hit selected way is {selected_way}")
|
||||
logger.debug(f"Hit selected way is {selected_way}")
|
||||
|
||||
new_update_queue.append((self.update_queue[i][0], self.update_queue[i][1] - 1, selected_way))
|
||||
self.update_queue = new_update_queue
|
||||
|
|
@ -107,7 +108,7 @@ class uFTBModel:
|
|||
if not update_request["valid"]:
|
||||
return
|
||||
|
||||
# print(f"ftb entry {hex(update_request['bits_pc'])} is put into way {selected_way}")
|
||||
logger.debug(f"ftb entry {hex(update_request['bits_pc'])} is put into way {selected_way}")
|
||||
self.ftbways[selected_way].valid = 1
|
||||
self.ftbways[selected_way].tag = uFTBWay.get_tag(update_request["bits_pc"])
|
||||
self.ftbways[selected_way].ftb_entry = FTBEntry.from_dict(update_request["ftb_entry"])
|
||||
|
|
|
|||
|
|
@ -62,6 +62,9 @@ def test_uftb(request):
|
|||
set_func_coverage(request, g)
|
||||
set_line_coverage(request, "VFauFTB_coverage.dat")
|
||||
|
||||
import logging
|
||||
mlvp.setup_logging(log_level=logging.INFO, log_file="uftb_with_ftq.log")
|
||||
|
||||
mlvp.run(uftb_test())
|
||||
|
||||
uFTB.finalize()
|
||||
|
|
|
|||
Loading…
Reference in New Issue