Skip to content
This repository has been archived by the owner on Nov 4, 2024. It is now read-only.

Support for coverage of Privilged Architecture #80

Merged
merged 24 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3394d08
Support for read_csr added, mstatush error resolved, immediate and rs…
MuhammadHammad001 Nov 13, 2023
03b7d07
Issues resolved for hitcovpt and any_hitcovpt when read_csr accessed
MuhammadHammad001 Nov 13, 2023
3c636da
update to check only the register of interest for the old_fn_csr_comb
MuhammadHammad001 Nov 18, 2023
6fbf910
label_to_addr and mode check support added
MuhammadHammad001 Nov 20, 2023
bb54cbf
physical address, virtual address, page table walk variables added, i…
MuhammadHammad001 Dec 2, 2023
b10a44a
Support for values from memory using mem_val
MuhammadHammad001 Dec 2, 2023
80a19d4
PTE Permission access function added
MuhammadHammad001 Dec 3, 2023
b402d0f
Issue with the option resolved
MuhammadHammad001 Dec 4, 2023
bbc0349
get_pte_per updated to take only three arguments. Useless pte_size re…
MuhammadHammad001 Dec 4, 2023
4363e0a
Virtual memory implementation changed. Now, depends on satp register,…
MuhammadHammad001 Dec 18, 2023
33b0a6e
macro support added
MuhammadHammad001 Dec 18, 2023
346aa75
False exception removed for virtual memory support
MuhammadHammad001 Jan 12, 2024
f08a623
Trap Registers Variables added in instr_vars
MuhammadHammad001 Jan 18, 2024
ac4f342
trap registers updated to maintain the arch-state
MuhammadHammad001 Jan 25, 2024
44d2a47
Merge branch 'dev' into read_csr_support
MuhammadHammad001 Jan 31, 2024
4c15ffd
Support for mnemonic flag and error resolved for inxflg
MuhammadHammad001 Feb 15, 2024
2ca4caa
Support for lr/sc added and also rd_val track added
MuhammadHammad001 Feb 19, 2024
32d0b84
Remove the feature for rs2_val and imm_val skip for csrs in val_comb …
MuhammadHammad001 Feb 21, 2024
b1489b8
Feature for read_csr removed
MuhammadHammad001 Mar 16, 2024
d7da4f5
Update the trap registers state logic and add support for fetch acces…
MuhammadHammad001 Apr 10, 2024
13571b0
Initial Support for Translator added
MuhammadHammad001 Apr 10, 2024
3d897df
Translator function added for merge coverage
MuhammadHammad001 Apr 13, 2024
86c54ff
Documentation added for priv arch functions, translator, macros
MuhammadHammad001 Apr 16, 2024
fbb62e9
Merge branch 'dev' into read_csr_support
UmerShahidengr Jul 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 51 additions & 9 deletions riscv_isac/InstructionObject.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,18 @@
'bset','zext.h','sext.h','sext.b','zext.b','zext.w','minu','maxu','orc.b','add.uw','sh1add.uw',\
'sh2add.uw','sh3add.uw','slli.uw','clz','clzw','ctz','ctzw','cpop','cpopw','rev8',\
'bclri','bexti','binvi','bseti','fcvt.d.wu','fcvt.s.wu','fcvt.d.lu','fcvt.s.lu','c.flwsp',\
'c.not', 'c.sext.b','c.sext.h','c.zext.b','c.zext.h','c.zext.w']
'c.not', 'c.sext.b','c.sext.h','c.zext.b','c.zext.h','c.zext.w','sc.w','lr.w','sc.d','lr.d']
unsgn_rs2 = ['bgeu', 'bltu', 'sltiu', 'sltu', 'sll', 'srl', 'sra','mulhu',\
'mulhsu','divu','remu','divuw','remuw','aes64ds','aes64dsm','aes64es',\
'aes64esm','aes64ks2','sm4ed','sm4ks','ror','rol','rorw','rolw','clmul',\
'clmulh','clmulr','andn','orn','xnor','pack','packh','packu','packuw','packw',\
'xperm.n','xperm.b', 'aes32esmi', 'aes32esi', 'aes32dsmi', 'aes32dsi',\
'sha512sum1r','sha512sum0r','sha512sig1l','sha512sig1h','sha512sig0l','sha512sig0h','fsw',\
'bclr','bext','binv','bset','minu','maxu','add.uw','sh1add.uw','sh2add.uw','sh3add.uw']
'bclr','bext','binv','bset','minu','maxu','add.uw','sh1add.uw','sh2add.uw','sh3add.uw','sc.w', 'sc.d']
f_instrs_pref = ['fadd', 'fclass', 'fcvt', 'fdiv', 'feq', 'fld', 'fle', 'flt', 'flw', 'fmadd',\
'fmax', 'fmin', 'fmsub', 'fmul', 'fmv', 'fnmadd', 'fnmsub', 'fsd', 'fsgnj', 'fsqrt',\
'fsub', 'fsw']
unsgn_rd = ['lr.w','sc.w','lr.d','sc.d']


instr_var_evaluator_funcs = {} # dictionary for holding registered evaluator funcs
Expand Down Expand Up @@ -87,7 +88,9 @@ def __init__(
mode = None,
vm_addr_dict = None,
mem_val = None,
trap_dict = None
trap_dict = None,
inxFlag = None,
is_sgn_extd = None
):

'''
Expand Down Expand Up @@ -152,6 +155,7 @@ def evaluate_instr_vars(self, xlen, flen, arch_state, csr_regfile, instr_vars):
instr_vars['xlen'] = xlen
instr_vars['flen'] = flen
instr_vars['mode'] = self.mode
instr_vars['mnemonic'] = self.instr_name

instr_vars['iflen'] = flen
if self.instr_name.endswith(".s") or 'fmv.x.w' in self.instr_name:
Expand All @@ -175,6 +179,10 @@ def evaluate_instr_vars(self, xlen, flen, arch_state, csr_regfile, instr_vars):
instr_vars['imm_val'] = self.imm
if self.shamt is not None:
instr_vars['imm_val'] = self.shamt
if self.rl is not None:
instr_vars['rl'] = self.rl
if self.aq is not None:
instr_vars['aq'] = self.aq

imm_val = instr_vars.get('imm_val', None)

Expand All @@ -185,6 +193,7 @@ def evaluate_instr_vars(self, xlen, flen, arch_state, csr_regfile, instr_vars):
rs1_val = self.evaluate_instr_var("rs1_val", instr_vars, arch_state)
rs2_val = self.evaluate_instr_var("rs2_val", instr_vars, arch_state)
rs3_val = self.evaluate_instr_var("rs3_val", instr_vars, arch_state)
rd_val = self.evaluate_instr_var("rd_val", instr_vars, arch_state)

ea_align = None
# the ea_align variable is used by the eval statements of the
Expand All @@ -204,6 +213,7 @@ def evaluate_instr_vars(self, xlen, flen, arch_state, csr_regfile, instr_vars):
'rs1_val': rs1_val,
'rs2_val': rs2_val,
'rs3_val': rs3_val,
'rd_val' : rd_val,
'rm_val': self.rm,
'ea_align': ea_align,
})
Expand Down Expand Up @@ -313,9 +323,8 @@ def update_arch_state(self, arch_state, csr_regfile, mem_vals):
csr_commit = self.csr_commit
if csr_commit is not None:
for commit in csr_commit:
if (commit[0] == "CSR") and commit[2] != '->':
csr_regfile[commit[1]] = str(commit[3][2:])

if (commit[0] == "CSR"):
csr_regfile[commit[1]] = str(commit[2][2:])

mem_val = self.mem_val
if mem_val is not None:
Expand All @@ -335,6 +344,7 @@ def evaluate_instr_var(self, instr_var_name, *args):
rs1 = self.rs1,
rs2 = self.rs2,
rs3 = self.rs3,
rd = self.rd,
is_rvp = self.is_rvp,
inxFlag = self.inxFlg
): # could just instr_name suffice?
Expand Down Expand Up @@ -466,11 +476,28 @@ def trap_registers_update(self, instr_vars, trap_dict):
: param instr_vars: Dictionary holding the values of current instruction state
: param trap_dict : Values for the trap registers for current instruction
'''

instr_vars['mode_change'] = trap_dict['mode_change']
instr_vars['exc_num'] = trap_dict['exc_num']
instr_vars['call_type'] = trap_dict['call_type']
instr_vars['tval'] = trap_dict['tval']


if trap_dict["mode_change"] is not None:
#update the registers depending upon the mode change
if trap_dict["mode_change"].split()[2] == "M":
instr_vars['mcause'] = trap_dict['exc_num']
instr_vars['mtval'] = trap_dict['tval']
instr_vars['scause'] = '0'
MuhammadHammad001 marked this conversation as resolved.
Show resolved Hide resolved
instr_vars['stval'] = '0'
elif trap_dict["mode_change"].split()[2] == "S":
instr_vars['scause'] = trap_dict['exc_num']
instr_vars['stval'] = trap_dict['tval']
instr_vars['mcause'] = '0'
instr_vars['mtval'] = '0'
else:
instr_vars['mcause'] = '0'
instr_vars['mtval'] = '0'
instr_vars['scause'] = '0'
instr_vars['stval'] = '0'

return None

'''
Expand Down Expand Up @@ -537,6 +564,21 @@ def evaluate_rs3_val_fsgn(self, instr_vars, arch_state):
return self.evaluate_reg_val_fsgn(self.rs3[0], instr_vars['flen'], instr_vars['xlen'], arch_state)


'''
Evaluator funcs for rd_val

:param arch_state: Architectural state
:param instr_vars: Dictionary of instruction variables already evaluated
'''
@evaluator_func("rd_val", lambda **params: params['instr_name'] in unsgn_rd and params['rd'] is not None)
def evaluate_rd_val_unsgn(self, instr_vars, arch_state):
return self.evaluate_reg_val_unsgn(self.rd[0], instr_vars['xlen'], arch_state)

@evaluator_func("rd_val", lambda **params: not params['instr_name'] in unsgn_rd and params['rd'] is not None and params['rd'][1] == 'x')
def evaluate_rd_val_sgn(self, instr_vars, arch_state):
return self.evaluate_reg_val_sgn(self.rd[0], instr_vars['xlen'], arch_state)


'''
Evaluator funcs for extension specific variables

Expand Down
43 changes: 15 additions & 28 deletions riscv_isac/coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ def compute(self, is_part_of_covpt=False):

del self.instr_stat_meta_at_addr[key_instr_addr]

instr.update_arch_state(self.arch_state, self.csr_regfile, self.iptw_dict, self.mem_vals)
instr.update_arch_state(self.arch_state, self.csr_regfile, self.mem_vals)

def get_metric(self):
return self.result
Expand Down Expand Up @@ -947,15 +947,25 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr

instr_vars = {}
instr_vars['inxFlag'] = instr.inxFlg
instr.evaluate_instr_vars(xlen, flen, arch_state, csr_regfile, instr_vars)

#csr regfile track for the previous instruction(old_csr_regfile)
old_csr_regfile = {}
for i in csr_regfile.csr_regs:
old_csr_regfile[i] = int(csr_regfile[i],16)
def old_fn_csr_comb_covpt(csr_reg):
return old_csr_regfile[csr_reg]

#update the arch state and csr_regfile for the current instruction
instr.update_arch_state(arch_state, csr_regfile, mem_vals)
#update instr_vars using updated arch state and updated csr_regfile
instr.evaluate_instr_vars(xlen, flen, arch_state, csr_regfile, instr_vars)

#update the state of trap registers in csr_reg file using instr_vars
if instr_vars["mode_change"] is not None: #change the state only on the instruction
csr_regfile["mcause"] = instr_vars["mcause"]
csr_regfile["scause"] = instr_vars["scause"]
csr_regfile["mtval"] = instr_vars["mtval"]
csr_regfile["stval"] = instr_vars["stval"]

if 'rs1' in instr_vars:
rs1 = instr_vars['rs1']
Expand All @@ -981,24 +991,13 @@ def old_fn_csr_comb_covpt(csr_reg):
csr_write_vals = {}
if instr.csr_commit is not None:
for commit in instr.csr_commit:
if commit[0] == "CSR" and commit[4] and commit[2] == '<-':
csr_write_vals[commit[1]] = int(commit[4],16)
if commit[0] == "CSR" and commit[3]:
csr_write_vals[commit[1]] = int(commit[3],16)
def write_fn_csr_comb_covpt(csr_reg):
if csr_reg in csr_write_vals:
return csr_write_vals[csr_reg]
else:
return int(csr_regfile[csr_reg],16)

csr_read_vals = {}
if instr.csr_commit is not None:
for csr_commit in instr.csr_commit:
if(csr_commit[0] == "CSR") and (csr_commit[3]) and (csr_commit[2] == '->'):
csr_read_vals[csr_commit[1]] = int(csr_commit[3],16)
def read_fn_csr_comb_covpt(csr_reg):
if instr.csr_commit is not None and csr_reg in csr_read_vals:
return csr_read_vals.get(csr_reg)
else:
return None

def check_label_address(label):
return utils.collect_label_address(elf, label)
Expand Down Expand Up @@ -1155,16 +1154,6 @@ def get_pte_prop(prop_name,pa, pte_addr, pgtb_addr):
simd_val_unpack(value['val_comb'], op_width, "rs2", rs2_val, lcls)
instr_vars.update(lcls)
for coverpoints in value['val_comb']:
pattern_imm = r'\bimm_val\b'
pattern_rs1 = r'\brs1_val\b'
pattern_rs2 = r'\brs2_val\b'
match_imm = bool(re.search(pattern_imm, coverpoints))
match_rs1 = bool(re.search(pattern_rs1, coverpoints))
match_rs2 = bool(re.search(pattern_rs2, coverpoints))
if (instr_vars['rs2_val'] == None) and match_rs2:
continue
if ('imm_val' not in instr_vars) and match_imm:
continue
if eval(coverpoints, globals(), instr_vars):
if cgf[cov_labels]['val_comb'][coverpoints] == 0:
ucovpt.append(str(coverpoints))
Expand Down Expand Up @@ -1211,7 +1200,6 @@ def get_key_from_value(dictionary, target_value):
"__builtins__":None,
"old": old_fn_csr_comb_covpt,
"write": write_fn_csr_comb_covpt,
"read_csr": read_fn_csr_comb_covpt,
"get_addr": check_label_address,
"get_mem_val":get_mem_val,
"get_pte":get_pte,
Expand Down Expand Up @@ -1243,7 +1231,6 @@ def get_key_from_value(dictionary, target_value):
"__builtins__":None,
"old": old_fn_csr_comb_covpt,
"write": write_fn_csr_comb_covpt,
"read_csr": read_fn_csr_comb_covpt,
"get_addr": check_label_address,
"get_mem_val":get_mem_val,
"get_pte":get_pte,
Expand Down Expand Up @@ -1502,7 +1489,7 @@ def get_key_from_value(dictionary, target_value):
stats_queue.close()

def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xlen, flen, addr_pairs
, dump, cov_labels, sig_addrs, window_size, elf, no_count=False, procs=1):
, dump, cov_labels, sig_addrs, window_size, inxFlg, elf, no_count=False, procs=1):
'''Compute the Coverage'''

global arch_state
Expand Down
4 changes: 2 additions & 2 deletions riscv_isac/isac.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def preprocessing(cgf, header_file, cgf_macros):
return cgf

def isac(output_file,elf ,trace_file, window_size, cgf, parser_name, decoder_name, parser_path, decoder_path, detailed, test_labels,
sig_labels, dump, cov_labels, xlen, flen, inxFlg, no_count, procs, logging=False):
sig_labels, dump, cov_labels, xlen, flen, no_count, procs, *inxFlg, logging=False):
test_addr = []
sig_addr = []
if parser_path:
Expand Down Expand Up @@ -89,7 +89,7 @@ def isac(output_file,elf ,trace_file, window_size, cgf, parser_name, decoder_nam
sig_addr.append((start_address,end_address))
else:
test_name = trace_file.rsplit(',',1)[0]
rpt = cov.compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xlen, flen, test_addr, dump, cov_labels, sig_addr, window_size, elf, no_count, procs)
rpt = cov.compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xlen, flen, test_addr, dump, cov_labels, sig_addr, window_size, inxFlg, elf, no_count, procs)
if output_file is not None and logging:
logger.info('Coverage Report:')
#logger.info('\n\n' + rpt)
Expand Down
8 changes: 4 additions & 4 deletions riscv_isac/plugins/c_sail.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def setup(self, trace, arch):
instr_pattern_c_sail= re.compile(
'\[\d*\]\s\[(?P<mode>.*?)\]:\s(?P<addr>[0-9xABCDEF]+)\s\((?P<instr>[0-9xABCDEF]+)\)\s*(?P<mnemonic>.*)')
instr_pattern_c_sail_regt_reg_val = re.compile('(?P<regt>[xf])(?P<reg>[\d]+)\s<-\s(?P<val>[0-9xABCDEF]+)')
instr_pattern_c_sail_csr_reg_val = re.compile('(?P<CSR>CSR|clint::tick)\s(?P<reg>[a-z0-9]+)\s(.*?)\s(?P<val>[0-9xABCDEF]+)(?:\s\(input:\s(?P<input_val>[0-9xABCDEF]+)\))?')
instr_pattern_c_sail_csr_reg_val = re.compile('(?P<CSR>CSR|clint::tick)\s(?P<reg>[a-z0-9]+)\s<-\s(?P<val>[0-9xABCDEF]+)(?:\s\(input:\s(?P<input_val>[0-9xABCDEF]+)\))?')
instr_pattern_c_sail_mem_val = re.compile('mem\[(?P<addr>[0-9xABCDEF]+)\]\s<-\s(?P<val>[0-9xABCDEF]+)')
instr_pattern_c_sail_trap = re.compile(r'trapping\sfrom\s(?P<mode_change>\w+\sto\s\w+)\sto\shandle\s(?P<call_type>\w+.*)\shandling\sexc#(?P<exc_num>0x[0-9a-fA-F]+)\sat\spriv\s\w\swith\stval\s(?P<tval>0x[0-9a-fA-F]+)')
def extractInstruction(self, line):
Expand Down Expand Up @@ -117,9 +117,9 @@ def extracttrapvals(self, line):
if instr_trap_pattern:
trap_dict["mode_change"] = instr_trap_pattern.group("mode_change")
trap_dict["call_type"] = instr_trap_pattern.group("call_type")
trap_dict["exc_num"] = int(instr_trap_pattern.group("exc_num"),16)
trap_dict["tval"] = int(instr_trap_pattern.group("tval"),16)
trap_dict["exc_num"] = instr_trap_pattern.group("exc_num")
trap_dict["tval"] = instr_trap_pattern.group("tval")

return trap_dict

@plugins.parserHookImpl
Expand Down