From ed6c44d6dc8ed88a029beafda9218e33bf76d953 Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Fri, 6 May 2022 12:08:36 +0530 Subject: [PATCH 01/19] Instruction aliases --- riscv_isac/data/instr_alias.yaml | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 riscv_isac/data/instr_alias.yaml diff --git a/riscv_isac/data/instr_alias.yaml b/riscv_isac/data/instr_alias.yaml new file mode 100644 index 00000000..fcf93da3 --- /dev/null +++ b/riscv_isac/data/instr_alias.yaml @@ -0,0 +1,36 @@ +# This file holds aliases for groups of instructions + +RV32I_Arith: + - add + - sub + - slt + - sltu + - xor + - or + - and + - addi + - slti + - sltiu + - xori + - ori + - andi + +RV32I_Shift: +- sll +- slli +- srl +- srli +- sra +- srai + +RV64I_Arith: + - subw + - addw + - addiw + +RV64I_Shift: + - sllw + - srlw + - sraw + - slliw + - srliw \ No newline at end of file From 305c762c8e224f4d4179201627feef650135e4cd Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Fri, 6 May 2022 12:13:45 +0530 Subject: [PATCH 02/19] Format update --- riscv_isac/data/instr_alias.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/riscv_isac/data/instr_alias.yaml b/riscv_isac/data/instr_alias.yaml index fcf93da3..c31d3936 100644 --- a/riscv_isac/data/instr_alias.yaml +++ b/riscv_isac/data/instr_alias.yaml @@ -1,6 +1,6 @@ # This file holds aliases for groups of instructions -RV32I_Arith: +rv32i_arith: - add - sub - slt @@ -15,7 +15,7 @@ RV32I_Arith: - ori - andi -RV32I_Shift: +rv32i_shift: - sll - slli - srl @@ -23,12 +23,12 @@ RV32I_Shift: - sra - srai -RV64I_Arith: +rv64i_arith: - subw - addw - addiw -RV64I_Shift: +rv64i_shift: - sllw - srlw - sraw From 3c6863e99bbf575f286bdb346f3f2581e9cfdf8c Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Fri, 6 May 2022 15:00:44 +0530 Subject: [PATCH 03/19] Format update --- riscv_isac/data/instr_alias.yaml | 54 ++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/riscv_isac/data/instr_alias.yaml b/riscv_isac/data/instr_alias.yaml index c31d3936..ecc4a3ee 100644 --- a/riscv_isac/data/instr_alias.yaml +++ b/riscv_isac/data/instr_alias.yaml @@ -1,6 +1,6 @@ # This file holds aliases for groups of instructions -rv32i_arith: +rv32i_arith_reg: &rv32i_arith_reg - add - sub - slt @@ -8,6 +8,8 @@ rv32i_arith: - xor - or - and + +rv32i_arith_imm: &rv32i_arith_imm - addi - slti - sltiu @@ -15,22 +17,48 @@ rv32i_arith: - ori - andi -rv32i_shift: -- sll -- slli -- srl -- srli -- sra -- srai +rv32i_shift_reg: &rv32i_shift_reg + - sll + - srl + - sra -rv64i_arith: - - subw +rv32i_shift_imm: &rv32i_shift_imm + - slli + - srli + - srai + +rv32i_arith: &rv32i_arith + - *rv32i_arith_reg + - *rv32i_arith_imm + +rv32i_shift: &rv32i_shift + - *rv32i_shift_reg + - *rv32i_shift_imm + +rv64i_arith_reg: &rv64i_arith_reg + - *rv32i_arith_reg - addw + - subw + +rv64i_arith_imm: &rv64i_arith_imm + - *rv32i_arith_imm - addiw - -rv64i_shift: + +rv64i_shift_reg: &rv64i_shift_reg + - *rv32i_shift_reg - sllw - srlw - sraw + +rv64i_shift_imm: &rv64i_shift_imm + - *rv32i_shift_imm - slliw - - srliw \ No newline at end of file + - srliw + +rv64i_arith: &rv64i_arith + - *rv64i_arith_reg + - *rv64i_arith_imm + +rv64i_shift: &rv64i_shift + - *rv64i_shift_reg + - *rv64i_shift_imm \ No newline at end of file From a5b0424615f6bede5e073b4b4fc4c6e8afae82f0 Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Thu, 12 May 2022 12:26:55 +0530 Subject: [PATCH 04/19] Format update --- riscv_isac/data/instr_alias.yaml | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/riscv_isac/data/instr_alias.yaml b/riscv_isac/data/instr_alias.yaml index ecc4a3ee..1ff6ea7e 100644 --- a/riscv_isac/data/instr_alias.yaml +++ b/riscv_isac/data/instr_alias.yaml @@ -22,18 +22,14 @@ rv32i_shift_reg: &rv32i_shift_reg - srl - sra -rv32i_shift_imm: &rv32i_shift_imm +rv32i_shift_imm: &rv32i_shift_imm - slli - srli - srai -rv32i_arith: &rv32i_arith - - *rv32i_arith_reg - - *rv32i_arith_imm +rv32i_arith: &rv32i_arith [*rv32i_arith_reg, *rv32i_arith_imm] -rv32i_shift: &rv32i_shift - - *rv32i_shift_reg - - *rv32i_shift_imm +rv32i_shift: &rv32i_shift [*rv32i_shift_reg, *rv32i_shift_imm] rv64i_arith_reg: &rv64i_arith_reg - *rv32i_arith_reg @@ -50,15 +46,11 @@ rv64i_shift_reg: &rv64i_shift_reg - srlw - sraw -rv64i_shift_imm: &rv64i_shift_imm +rv64i_shift_imm: &rv64i_shift_imm - *rv32i_shift_imm - slliw - srliw -rv64i_arith: &rv64i_arith - - *rv64i_arith_reg - - *rv64i_arith_imm +rv64i_arith: &rv64i_arith [*rv64i_arith_reg, *rv64i_arith_imm] -rv64i_shift: &rv64i_shift - - *rv64i_shift_reg - - *rv64i_shift_imm \ No newline at end of file +rv64i_shift: &rv64i_shift [*rv64i_shift_reg, *rv64i_shift_imm] \ No newline at end of file From 0b94e7a60b8ae570499453b9092786f52fdaec44 Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Thu, 12 May 2022 12:27:10 +0530 Subject: [PATCH 05/19] Function to import instructions of an alias --- riscv_isac/utils.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/riscv_isac/utils.py b/riscv_isac/utils.py index 83dbdcd6..dcc312f3 100644 --- a/riscv_isac/utils.py +++ b/riscv_isac/utils.py @@ -388,3 +388,24 @@ def sys_command_file(command, filename): stdout, stderr = out.communicate() fp.close() +def import_instr_alias(alias): + ''' + Return instructions pertaining to a particular alias + + alias: (string) The alias to be imported + + ''' + + # Function to flatten nested lists + from collections import Iterable + def flatten(lis): + for item in lis: + if isinstance(item, Iterable) and not isinstance(item, str): + for x in flatten(item): + yield x + else: + yield item + + alias_dict = load_yaml_file('./data/instr_alias.yaml') + return list(flatten(alias_dict[alias])) + From 00e22ab846c94bf753109e96ceeb5491deb099df Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Thu, 12 May 2022 14:10:06 +0530 Subject: [PATCH 06/19] Additional checks --- riscv_isac/utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/riscv_isac/utils.py b/riscv_isac/utils.py index dcc312f3..37aab03d 100644 --- a/riscv_isac/utils.py +++ b/riscv_isac/utils.py @@ -407,5 +407,8 @@ def flatten(lis): yield item alias_dict = load_yaml_file('./data/instr_alias.yaml') - return list(flatten(alias_dict[alias])) + if alias in alias_dict: + return list(flatten(alias_dict[alias])) + else: + return None From 9b76c34565fd7ef2d4a101fdadc251d35212079a Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Thu, 12 May 2022 14:47:16 +0530 Subject: [PATCH 07/19] Path bug fix --- riscv_isac/utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/riscv_isac/utils.py b/riscv_isac/utils.py index 37aab03d..8e655b84 100644 --- a/riscv_isac/utils.py +++ b/riscv_isac/utils.py @@ -5,6 +5,7 @@ import os import subprocess import shlex +import riscv_isac from riscv_isac.log import logger import ruamel from ruamel.yaml import YAML @@ -406,7 +407,8 @@ def flatten(lis): else: yield item - alias_dict = load_yaml_file('./data/instr_alias.yaml') + isac_path = os.path.dirname(riscv_isac.__file__) + alias_dict = load_yaml_file(isac_path + '/data/instr_alias.yaml') if alias in alias_dict: return list(flatten(alias_dict[alias])) else: From 7c98efb57fa37b386ec3559f74e9110628b3cfd5 Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Wed, 25 May 2022 22:40:19 +0530 Subject: [PATCH 08/19] Update cross_comb parser --- riscv_isac/coverage.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index 1f78245d..e0681a96 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -56,9 +56,9 @@ def __init__(self,label,coverpoint): ## Extract relevant information from coverpt self.data = self.coverpoint.split('::') - self.ops = [i for i in self.data[0][1:-1].split(':')] - self.assign_lst = [i for i in self.data[1][1:-1].split(':')] - self.cond_lst = [i for i in self.data[2][1:-1].split(':')] + self.ops = self.data[0].replace(' ', '')[1:-1].split(':') + self.assign_lst = self.data[1].replace(' ', '')[1:-1].split(':') + self.cond_lst = self.data[2].lstrip().rstrip()[1:-1].split(':') def process(self, queue, window_size, addr_pairs): From f43d35ddae110d2040f8918119494268437e7487 Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Thu, 26 May 2022 08:44:30 +0530 Subject: [PATCH 09/19] Cross comb parsing update --- riscv_isac/coverage.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index e0681a96..b8cbcc7c 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -116,18 +116,24 @@ def process(self, queue, window_size, addr_pairs): if instr.rm is not None: rm = int(instr.rm) - - if(self.ops[index] != '?'): - check_lst = [i for i in self.ops[index][1:-1].split(',')] + if self.ops[index].find('?') == -1: + # Handle instruction tuple + if self.ops[index].find('(') != -1: + check_lst = self.ops[index].replace('(', '').replace(')', '').split(',') + else: + check_lst = [self.ops[index]] + #TODO: Handle instuction alias if (instr_name not in check_lst): break - if (self.cond_lst[index] != '?'): + + if self.cond_lst[index].find('?') == -1: if(eval(self.cond_lst[index])): if(index==len(self.ops)-1): self.result = self.result + 1 else: break - if(self.assign_lst[index] != '?'): + + if self.assign_lst[index].find('?') == -1: exec(self.assign_lst[index]) def get_metric(self): @@ -567,7 +573,6 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs # List to hold hit coverpoints hit_covpts = [] rcgf = copy.deepcopy(cgf) - # Enter the loop only when Event is not set or when the # instruction object queue is not empty while (event.is_set() == False) or (queue.empty() == False): @@ -1069,7 +1074,6 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle iterator = iter(parser.__iter__()[0]) - # If number of processes to be spawned is more than that available, # allot number of processes to be equal to one less than maximum available_cores = mp.cpu_count() @@ -1106,6 +1110,7 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle ) ) ) + #Start each processes for each in process_list: each.start() @@ -1164,7 +1169,7 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle for d in cgf_list: for key, val in d.items(): rcgf[key] = val - + ## Check for cross coverage for end instructions ## All metric is stored in objects of obj_dict while(len(cross_cover_queue)>1): From f431ca62cdead2979d2405b9fd2d7d0ea2b3f7c7 Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Fri, 27 May 2022 00:27:21 +0530 Subject: [PATCH 10/19] Parser update --- riscv_isac/coverage.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index b8cbcc7c..22963c29 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -48,6 +48,8 @@ class cross(): + BASE_REG_DICT = { 'x'+str(i) : 'x'+str(i) for i in range(32)} + def __init__(self,label,coverpoint): self.label = label @@ -61,19 +63,19 @@ def __init__(self,label,coverpoint): self.cond_lst = self.data[2].lstrip().rstrip()[1:-1].split(':') def process(self, queue, window_size, addr_pairs): - ''' Check whether the coverpoint is a hit or not and update the metric ''' if(len(self.ops)>window_size or len(self.ops)>len(queue)): return - for index in range(len(self.ops)): + for index in range(len(self.ops)): + instr = queue[index] instr_name = instr.instr_name if addr_pairs: if not (any([instr.instr_addr >= saddr and instr.instr_addr < eaddr for saddr,eaddr in addr_pairs])): - continue + break rd = None rs1 = None @@ -90,13 +92,13 @@ def process(self, queue, window_size, addr_pairs): rm = None if instr.rd is not None: - rd = int(instr.rd[0]) + rd = instr.rd[1] + str(instr.rd[0]) if instr.rs1 is not None: - rs1 = int(instr.rs1[0]) + rs1 = instr.rs1[1] + str(instr.rs1[0]) if instr.rs2 is not None: - rs2 = int(instr.rs2[0]) + rs2 = instr.rs2[1] + str(instr.rs2[0]) if instr.rs3 is not None: - rs3 = int(instr.rs3[0]) + rs3 = instr.rs3[1] + str(instr.rs3[0]) if instr.imm is not None: imm = int(instr.imm) if instr.zimm is not None: @@ -115,8 +117,8 @@ def process(self, queue, window_size, addr_pairs): aq = int(instr.aq) if instr.rm is not None: rm = int(instr.rm) - - if self.ops[index].find('?') == -1: + + if self.ops[index].find('?') == -1: # Handle instruction tuple if self.ops[index].find('(') != -1: check_lst = self.ops[index].replace('(', '').replace(')', '').split(',') @@ -125,16 +127,16 @@ def process(self, queue, window_size, addr_pairs): #TODO: Handle instuction alias if (instr_name not in check_lst): break - + if self.cond_lst[index].find('?') == -1: - if(eval(self.cond_lst[index])): + if(eval(self.cond_lst[index], locals(), cross.BASE_REG_DICT)): if(index==len(self.ops)-1): self.result = self.result + 1 else: break if self.assign_lst[index].find('?') == -1: - exec(self.assign_lst[index]) + exec(self.assign_lst[index], locals(), cross.BASE_REG_DICT) def get_metric(self): return self.result @@ -1110,11 +1112,11 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle ) ) ) - + #Start each processes for each in process_list: each.start() - + # This loop facilitates parsing, disassembly and generation of instruction objects for instrObj_temp in iterator: instr = instrObj_temp.instr From 18acecfc9eb75f6111f6962c6c96967702e11735 Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Fri, 27 May 2022 00:31:05 +0530 Subject: [PATCH 11/19] Added instruction alias support --- riscv_isac/coverage.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index 22963c29..e37ed9be 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -119,12 +119,14 @@ def process(self, queue, window_size, addr_pairs): rm = int(instr.rm) if self.ops[index].find('?') == -1: + alias = utils.import_instr_alias(self.ops[index]) # Handle instruction tuple if self.ops[index].find('(') != -1: check_lst = self.ops[index].replace('(', '').replace(')', '').split(',') + elif alias: + check_lst = alias else: check_lst = [self.ops[index]] - #TODO: Handle instuction alias if (instr_name not in check_lst): break From 60ab03117e5285fe24229e8409d0febcec0081fc Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Thu, 2 Jun 2022 10:50:47 +0530 Subject: [PATCH 12/19] Add load/store/jal instruction aliases --- riscv_isac/data/instr_alias.yaml | 39 +++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/riscv_isac/data/instr_alias.yaml b/riscv_isac/data/instr_alias.yaml index 1ff6ea7e..a005daf2 100644 --- a/riscv_isac/data/instr_alias.yaml +++ b/riscv_isac/data/instr_alias.yaml @@ -53,4 +53,41 @@ rv64i_shift_imm: &rv64i_shift_imm rv64i_arith: &rv64i_arith [*rv64i_arith_reg, *rv64i_arith_imm] -rv64i_shift: &rv64i_shift [*rv64i_shift_reg, *rv64i_shift_imm] \ No newline at end of file +rv64i_shift: &rv64i_shift [*rv64i_shift_reg, *rv64i_shift_imm] + +rv32i_branch: &rv32i_branch + - beq + - bge + - bgeu + - blt + - bltu + - bne + +rv64i_branch: &rv64i_branch [*rv32i_branch] + +rv32i_jal: &rv32i_jal + - jal + - jalr + +rv64i_jal: &rv64i_jal [*rv32i_jal] + +rv32i_load: &rv32i_load + - lw + - lhu + - lh + - lbu + - lb + +rv64i_load: &rv364i_load + - *rv32i_load + - ld + - lwu + +rv32i_store: &rv32i_store + - sw + - sh + - sb + +rv64i_store: &rv64i_store + - *rv32i_store + - sd \ No newline at end of file From 9392e840995d1aa2c45960553d052485671ae0a3 Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Tue, 7 Jun 2022 05:44:00 +0530 Subject: [PATCH 13/19] Remove instruction alias handling from coverage.py --- riscv_isac/coverage.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index e37ed9be..c597c63a 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -119,12 +119,9 @@ def process(self, queue, window_size, addr_pairs): rm = int(instr.rm) if self.ops[index].find('?') == -1: - alias = utils.import_instr_alias(self.ops[index]) # Handle instruction tuple if self.ops[index].find('(') != -1: check_lst = self.ops[index].replace('(', '').replace(')', '').split(',') - elif alias: - check_lst = alias else: check_lst = [self.ops[index]] if (instr_name not in check_lst): @@ -959,12 +956,15 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs stats.stat2.append(_log + '\n\n') stats.last_meta = [store_address, store_val, stats.covpt, stats.code_seq] else: + ''' _log = 'Last Coverpoint : ' + str(stats.last_meta[2]) + '\n' _log += 'Last Code Sequence : \n\t-' + '\n\t-'.join(stats.last_meta[3]) + '\n' _log +='Current Store : [{0}] : {1} -- Store: [{2}]:{3}\n'.format(\ str(hex(instr.instr_addr)), mnemonic, str(hex(store_address)), store_val) + ''' + _log = '' logger.error(_log) stats.stat4.append(_log + '\n\n') @@ -1129,7 +1129,7 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle # Pass instrObjs to queues pertaining to each processes for each in queue_list: each.put_nowait(instrObj) - + logger.debug(instrObj) cross_cover_queue.append(instrObj) if(len(cross_cover_queue)>=window_size): @@ -1137,14 +1137,14 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle obj_dict[(label,coverpt)].process(cross_cover_queue, window_size,addr_pairs) cross_cover_queue.pop(0) + # Signal each processes that instruction list is over + for each in event_list: + each.set() + # Close all instruction queues for each in queue_list: each.close() each.join_thread() - - # Signal each processes that instruction list is over - for each in event_list: - each.set() # Get the renewed cgfs cgf_list = [] From 2d55c081efbd56e2f8d5dec4934d172f6db9559d Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Tue, 7 Jun 2022 05:52:25 +0530 Subject: [PATCH 14/19] Specification for instruction aliases in cross_comb --- docs/source/cgf.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/source/cgf.rst b/docs/source/cgf.rst index 2372a6d3..8d2ae006 100644 --- a/docs/source/cgf.rst +++ b/docs/source/cgf.rst @@ -376,6 +376,8 @@ A covergroup contains the following nodes: This string is divided into three parts - opcode list, assign list and condition list separated by :: symbol. It is parsed and all the three lists are obtained separately. The variables available for use in the expression are as follows: * ``instr_name`` : The instruction names in the opcode list + + * ``instruction_alias``: The instruction alias for a set of instructions as defined in ``/riscv_isac/data/instr_alias.yaml`` * ``rs1`` : The register number of source register 1 of the current instruction in the assign list. @@ -383,6 +385,7 @@ A covergroup contains the following nodes: * ``rd`` : The register number of destination register of the current instruction in the assign list. + Instruction aliases when used will be expanded into a tuple of instruction unded the given alias. Along with the above mentioned variable any valid python comparison operators can be used in the condition list. @@ -401,7 +404,7 @@ A covergroup contains the following nodes: .. code-block:: python - [(add,sub) : ? : (add,sub) ] :: [a=rd : ? : ? ] :: [rd==x10 : rd!=a and rs1!=a and rs2!=a : rs1==a or rs2==a ] + [(add,sub) : rv32i_arith : (add,sub) ] :: [a=rd : ? : ? ] :: [rd==x10 : rd!=a and rs1!=a and rs2!=a : rs1==a or rs2==a ] 3. WAW for an add instruction followed by a subtract instruction with 3 non-consuming instructions in between. From e05d1c9fc6c9d1d3cdbe7a3dae136644f7bff53f Mon Sep 17 00:00:00 2001 From: Edwin Joy <43539365+edwin7026@users.noreply.github.com> Date: Tue, 7 Jun 2022 10:00:35 +0530 Subject: [PATCH 15/19] Spelling error --- docs/source/cgf.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/cgf.rst b/docs/source/cgf.rst index 8d2ae006..25a48143 100644 --- a/docs/source/cgf.rst +++ b/docs/source/cgf.rst @@ -385,7 +385,7 @@ A covergroup contains the following nodes: * ``rd`` : The register number of destination register of the current instruction in the assign list. - Instruction aliases when used will be expanded into a tuple of instruction unded the given alias. + Instruction aliases when used will be expanded into a tuple of instruction under the given alias. Along with the above mentioned variable any valid python comparison operators can be used in the condition list. From 0735d21600859437f922fa43e29215088e573acd Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Tue, 7 Jun 2022 13:37:30 +0530 Subject: [PATCH 16/19] Expand instruction aliases --- riscv_isac/cgf_normalize.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/riscv_isac/cgf_normalize.py b/riscv_isac/cgf_normalize.py index 0dba691b..1a60eb95 100644 --- a/riscv_isac/cgf_normalize.py +++ b/riscv_isac/cgf_normalize.py @@ -1,5 +1,6 @@ # See LICENSE.incore for details from math import * +import pprint import riscv_isac.utils as utils import itertools import random @@ -577,6 +578,26 @@ def expand_cgf(cgf_files, xlen): if len(cgf[labels]['mnemonics'].keys()) > 1: logger.error(f'Multiple instruction mnemonics found when base_op label defined in {labels} label.') + # Substitute instruction aliases with equivalent tuple of instructions + if 'cross_comb' in cats: + temp = cats['cross_comb'] + + for covp, covge in dict(temp).items(): + data = covp.split('::') + ops = data[0].replace(' ', '')[1:-1].split(':') + # Substitute with tuple of instructions + for i in range(len(ops)): + exp_alias = utils.import_instr_alias(ops[i]) + if exp_alias != None: + ops[i] = tuple(exp_alias).__str__().replace("'", '').replace(" ", '') + + data[0] = '[' + ':'.join(ops) + ']' + data = '::'.join(data) + del temp[covp] + temp[data] = covge + + cgf[labels].insert(1, 'cross_comb', temp) + for label,node in cats.items(): if isinstance(node,dict): if 'abstract_comb' in node: @@ -592,5 +613,7 @@ def expand_cgf(cgf_files, xlen): else: for cp,comment in exp_cp: cgf[labels][label].insert(1,cp,coverage,comment=comment) + + return dict(cgf) From 69df17f76996bb72e2be9c2c460ac4a63b0e1dfa Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Thu, 25 Aug 2022 12:26:43 +0530 Subject: [PATCH 17/19] instruction alias changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29b8bbdc..5ae6aa63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.15.0] - 2022-08-25 +- Added support for instruction aliases + ## [0.14.0] - 2022-08-08 - Add fields to instruction object - Enable generic coverage evaluation mechanisms for floating point instructions From 250810e972b2674d47b7c46430f1677722988671 Mon Sep 17 00:00:00 2001 From: Edwin Joy Date: Thu, 25 Aug 2022 12:28:40 +0530 Subject: [PATCH 18/19] =?UTF-8?q?Bump=20version:=200.14.0=20=E2=86=92=200.?= =?UTF-8?q?15.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- riscv_isac/__init__.py | 2 +- setup.cfg | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/riscv_isac/__init__.py b/riscv_isac/__init__.py index b3fa5993..326f1a73 100644 --- a/riscv_isac/__init__.py +++ b/riscv_isac/__init__.py @@ -4,4 +4,4 @@ __author__ = """InCore Semiconductors Pvt Ltd""" __email__ = 'info@incoresemi.com' -__version__ = '0.14.0' +__version__ = '0.15.0' diff --git a/setup.cfg b/setup.cfg index e5e72ba9..509e02dd 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.14.0 +current_version = 0.15.0 commit = True tag = True diff --git a/setup.py b/setup.py index f2b0e324..aa7538ef 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ def read_requires(): setup( name='riscv_isac', - version='0.14.0', + version='0.15.0', description="RISC-V ISAC", long_description=readme + '\n\n', classifiers=[ From 0727704f64d40c0a97c4a10ec56cbd0e64c8f312 Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Mon, 29 Aug 2022 09:39:56 +0530 Subject: [PATCH 19/19] Bug fixes for register defaults. --- riscv_isac/coverage.py | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index 2e908b03..32c6402d 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -71,8 +71,8 @@ def process(self, queue, window_size, addr_pairs): if(len(self.ops)>window_size or len(self.ops)>len(queue)): return - for index in range(len(self.ops)): - + for index in range(len(self.ops)): + instr = queue[index] instr_name = instr.instr_name if addr_pairs: @@ -119,8 +119,8 @@ def process(self, queue, window_size, addr_pairs): aq = int(instr.aq) if instr.rm is not None: rm = int(instr.rm) - - if self.ops[index].find('?') == -1: + + if self.ops[index].find('?') == -1: # Handle instruction tuple if self.ops[index].find('(') != -1: check_lst = self.ops[index].replace('(', '').replace(')', '').split(',') @@ -135,7 +135,7 @@ def process(self, queue, window_size, addr_pairs): self.result = self.result + 1 else: break - + if self.assign_lst[index].find('?') == -1: exec(self.assign_lst[index], locals(), cross.BASE_REG_DICT) @@ -603,7 +603,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr # List to hold hit coverpoints hit_covpts = [] rcgf = copy.deepcopy(cgf) - + # Enter the loop only when Event is not set or when the # instruction object queue is not empty while (event.is_set() == False) or (queue.empty() == False): @@ -617,14 +617,14 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr commitvalue = instr.reg_commit # assign default values to operands - nxf_rs1 = None - nxf_rs2 = None - nxf_rs3 = None - nxf_rd = None - rs1_type = None - rs2_type = None - rs3_type = None - rd_type = None + nxf_rs1 = 0 + nxf_rs2 = 0 + nxf_rs3 = 0 + nxf_rd = 0 + rs1_type = 'x' + rs2_type = 'x' + rs3_type = 'x' + rd_type = 'x' csr_addr = None @@ -1017,7 +1017,7 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle cgf = temp # If cgf does not have the covergroup pertaining to the cover-label, throw error - # and exit + # and exit if not cgf: logger.err('Covergroup(s) for ' + str(cov_labels) + ' not found') sys.exit(1) @@ -1124,7 +1124,7 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle # Pass instrObjs to queues pertaining to each processes for each in queue_list: each.put_nowait(instrObj) - + logger.debug(instrObj) cross_cover_queue.append(instrObj) if(len(cross_cover_queue)>=window_size): @@ -1132,15 +1132,16 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle obj_dict[(label,coverpt)].process(cross_cover_queue, window_size,addr_pairs) cross_cover_queue.pop(0) - # Signal each processes that instruction list is over - for each in event_list: - each.set() + # Close all instruction queues for each in queue_list: each.close() each.join_thread() + # Signal each processes that instruction list is over + for each in event_list: + each.set() # Get the renewed cgfs cgf_list = [] @@ -1169,7 +1170,7 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle for d in cgf_list: for key, val in d.items(): rcgf[key] = val - + ## Check for cross coverage for end instructions ## All metric is stored in objects of obj_dict while(len(cross_cover_queue)>1):