From 9052153a4378bfb0a581d6f2a842706bfc50dfae Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Tue, 10 May 2022 23:29:19 +0530 Subject: [PATCH 01/20] Initial porting of changes in coverage.py for FP and add fcsr and nan_prefix based coverpoints in fp_dataset functions. --- riscv_isac/cgf_normalize.py | 12 +- riscv_isac/coverage.py | 98 +- riscv_isac/fp_dataset.py | 8093 ++++++++++++++++++----------------- riscv_isac/isac.py | 4 +- riscv_isac/main.py | 12 +- 5 files changed, 4161 insertions(+), 4058 deletions(-) diff --git a/riscv_isac/cgf_normalize.py b/riscv_isac/cgf_normalize.py index 0dba691b..4463aeed 100644 --- a/riscv_isac/cgf_normalize.py +++ b/riscv_isac/cgf_normalize.py @@ -548,16 +548,18 @@ def alternate(var, size, signed=True, fltr_func=None,scale_func=None): #return [(coverpoint,"Alternate") for coverpoint in coverpoints] -def expand_cgf(cgf_files, xlen): +def expand_cgf(cgf_files, xlen,flen): ''' This function will replace all the abstract functions with their unrolled coverpoints. It replaces node :param cgf_files: list of yaml file paths which together define the coverpoints - :param xlen: XLEN of the riscv-trace + :param xlen: XLEN of the DUT/Configuration + :param flen: FLEN of the DUT/Configuration :type cgf: list :type xlen: int + :type flen: int ''' cgf = utils.load_cgf(cgf_files) for labels, cats in cgf.items(): @@ -565,7 +567,7 @@ def expand_cgf(cgf_files, xlen): # If 'opcode' found, rename it to 'mnemonics' if 'opcode' in cats: logger.warning("Deprecated node used: 'opcode'. Use 'mnemonics' instead") - + temp = cgf[labels]['opcode'] del cgf[labels]['opcode'] cgf[labels].insert(1, 'mnemonics', temp) @@ -582,13 +584,13 @@ def expand_cgf(cgf_files, xlen): if 'abstract_comb' in node: temp = node['abstract_comb'] del node['abstract_comb'] - for coverpoints, coverage in temp.items(): i = 0 try: exp_cp = eval(coverpoints) except Exception as e: - pass + logger.error("Error evaluating abstract comb: "+(coverpoints)\ + +" in "+labels) else: for cp,comment in exp_cp: cgf[labels][label].insert(1,cp,coverage,comment=comment) diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index 1f78245d..bf731851 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -324,7 +324,7 @@ def __init__(self, xlen, flen): self.ucovpt = [] self.cov_pt_sig = [] self.last_meta = [] - + def __add__(self, o): temp = statistics(self.xlen, self.flen) temp.stat1 = self.stat1 + o.stat1 @@ -341,7 +341,7 @@ def __add__(self, o): temp.last_meta = self.last_meta + o.last_meta return temp - + def pretty_print_yaml(yaml): res = '''''' @@ -531,7 +531,7 @@ def simd_val_unpack(val_comb, op_width, op_name, val, local_dict): if simd_size == op_width: local_dict[f"{op_name}_val"]=elm_val -def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs, sig_addrs, stats, arch_state, csr_regfile, result_count, no_count): +def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr_pairs, sig_addrs, stats, arch_state, csr_regfile, result_count, no_count): ''' This function checks if the current instruction under scrutiny matches a particular coverpoint of interest. If so, it updates the coverpoints and @@ -540,10 +540,11 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs :param queue: A queue thread to push instructionObject :param event: Event object to signal completion of decoding :param cgf_queue: A queue thread to push updated cgf - :param stats_queue: A queue thread to push updated `stats` object - + :param stats_queue: A queue thread to push updated `stats` object + :param cgf: a cgf against which coverpoints need to be checked for. :param xlen: Max xlen of the trace + :param flen: Max flen of the trace :param addr_pairs: pairs of start and end addresses for which the coverage needs to be updated :param sig_addrs: pairs of start and end addresses for which signature update needs to be checked :param stats: `stats` object @@ -557,6 +558,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs :type instr: :class:`instructionObject` :type cgf: dict :type xlen: int + :type flen: int :type addr_pairs: (int, int) :type sig_addrs: (int, int) :type stats: class `statistics` @@ -568,15 +570,15 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs hit_covpts = [] rcgf = copy.deepcopy(cgf) - # Enter the loop only when Event is not set or when the - # instruction object queue is not empty + # 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): # If there are instructions in queue, compute coverage if queue.empty() is False: - + instr = queue.get_nowait() - + mnemonic = instr.mnemonic commitvalue = instr.reg_commit @@ -599,11 +601,13 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs else: unsgn_sz = '>Q' sgn_sz = '>q' - + + fsgn_sz = '>Q' if flen==64 else '>I' + # if instruction is empty then return if instr is None: return cgf - + # check if instruction lies within the valid region of interest if addr_pairs: if any([instr.instr_addr >= saddr and instr.instr_addr < eaddr for saddr,eaddr in addr_pairs]): @@ -612,7 +616,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs enable = False else: enable=True - + # capture the operands and their values from the regfile if instr.rs1 is not None: rs1_type = instr.rs1[1] @@ -641,7 +645,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs imm_val = instr.imm if instr.shamt is not None: imm_val = instr.shamt - + # special value conversion based on signed/unsigned operations if instr.instr_name in unsgn_rs1: rs1_val = struct.unpack(unsgn_sz, bytes.fromhex(arch_state.x_rf[nxf_rs1]))[0] @@ -655,10 +659,8 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs if instr.instr_name in ["fmv.w.x"]: rs1_val = '0x' + (arch_state.x_rf[nxf_rs1]).lower() elif rs1_type == 'f': - rs1_val = struct.unpack(sgn_sz, bytes.fromhex(arch_state.f_rf[nxf_rs1]))[0] - if instr.instr_name in ["fadd.s","fsub.s","fmul.s","fdiv.s","fsqrt.s","fmadd.s","fmsub.s","fnmadd.s","fnmsub.s","fmax.s","fmin.s","feq.s","flt.s","fle.s","fmv.x.w","fmv.w.x","fcvt.wu.s","fcvt.s.wu","fcvt.w.s","fcvt.s.w","fsgnj.s","fsgnjn.s","fsgnjx.s","fclass.s"]: - rs1_val = '0x' + (arch_state.f_rf[nxf_rs1]).lower() - + rs1_val = struct.unpack(fsgn_sz, bytes.fromhex(arch_state.f_rf[nxf_rs1]))[0] + if instr.instr_name in unsgn_rs2: rs2_val = struct.unpack(unsgn_sz, bytes.fromhex(arch_state.x_rf[nxf_rs2]))[0] elif instr.is_rvp: @@ -669,9 +671,11 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs elif rs2_type == 'x': rs2_val = struct.unpack(sgn_sz, bytes.fromhex(arch_state.x_rf[nxf_rs2]))[0] elif rs2_type == 'f': - rs2_val = struct.unpack(sgn_sz, bytes.fromhex(arch_state.f_rf[nxf_rs2]))[0] - if instr.instr_name in ["fadd.s","fsub.s","fmul.s","fdiv.s","fmadd.s","fmsub.s","fnmadd.s","fnmsub.s","fmax.s","fmin.s","feq.s","flt.s","fle.s","fsgnj.s","fsgnjn.s","fsgnjx.s"]: - rs2_val = '0x' + (arch_state.f_rf[nxf_rs2]).lower() + rs2_val = struct.unpack(fsgn_sz, bytes.fromhex(arch_state.f_rf[nxf_rs2]))[0] + + rs3_val = 0 + if rs3_type == 'f': + rs3_val = struct.unpack(fsgn_sz, bytes.fromhex(arch_state.f_rf[nxf_rs3]))[0] sig_update = False if instr.instr_name in ['sh','sb','sw','sd','c.sw','c.sd','c.swsp','c.sdsp'] and sig_addrs: @@ -719,30 +723,30 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs local_dict[i] = int(csr_regfile[i],16) local_dict['xlen'] = xlen - + if enable : for cov_labels,value in cgf.items(): if cov_labels != 'datasets': if 'mnemonics' in value: - + req_node = 'mnemonics' is_found = False - + # Check if there is a base opcode if 'base_op' in value: # If base-op is the current instruction name, check for the p_op_cond node # If conditions satisfy, the instruction is equivalent to the mnemonic if instr.instr_name == value['base_op']: - + conds = value['p_op_cond'] # Construct and evaluate conditions is_found = True if not eval(conds): is_found = False - + mnemonic = list(value[req_node].keys()) mnemonic = mnemonic[0] - + # Update hit statistics of the mnemonic if is_found: if value[req_node][mnemonic] == 0: @@ -759,7 +763,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs stats.covpt = [] stats.ucovpt = [] stats.ucode_seq = [] - + # If mnemonic not detected via base-op if not is_found: if value[req_node][instr.instr_name] == 0: @@ -767,7 +771,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs stats.covpt.append('mnemonic : ' + instr.instr_name) value[req_node][instr.instr_name] += 1 rcgf[cov_labels][req_node][instr.instr_name] += 1 - + if 'rs1' in value and rs1 in value['rs1']: if value['rs1'][rs1] == 0: stats.ucovpt.append('rs1 : ' + rs1) @@ -775,7 +779,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs hit_covpts.append((cov_labels, 'rs1', rs1)) stats.covpt.append('rs1 : ' + rs1) value['rs1'][rs1] += 1 - + if 'rs2' in value and rs2 in value['rs2']: if value['rs2'][rs2] == 0: stats.ucovpt.append('rs2 : ' + rs2) @@ -783,7 +787,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs hit_covpts.append((cov_labels, 'rs2', rs2)) stats.covpt.append('rs2 : ' + rs2) value['rs2'][rs2] += 1 - + if 'rd' in value and is_rd_valid and rd in value['rd']: if value['rd'][rd] == 0: stats.ucovpt.append('rd : ' + rd) @@ -791,7 +795,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs hit_covpts.append((cov_labels, 'rd', rd)) stats.covpt.append('rd : ' + rd) value['rd'][rd] += 1 - + if 'rs3' in value and rs3 in value['rs3']: if value['rs3'][rs3] == 0: stats.ucovpt.append('rs3 : ' + rs3) @@ -934,7 +938,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs stats.stat1.append((store_address, store_val, stats.ucovpt, stats.ucode_seq)) stats.last_meta = [store_address, store_val, stats.ucovpt, stats.ucode_seq] - + stats.ucovpt = [] elif stats.covpt: _log = 'Op without unique coverpoint updates Signature\n' @@ -995,7 +999,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, addr_pairs cgf_queue.close() stats_queue.close() -def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xlen, addr_pairs +def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xlen, flen, addr_pairs , dump, cov_labels, sig_addrs, window_size, no_count=False, procs=1): '''Compute the Coverage''' @@ -1024,9 +1028,9 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle dump_f.close() sys.exit(0) - arch_state = archState(xlen,32) + arch_state = archState(xlen,flen) csr_regfile = csr_registers(xlen) - stats = statistics(xlen, 32) + stats = statistics(xlen, flen) cross_cover_queue = [] result_count = 0 @@ -1068,8 +1072,8 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle decoder.setup(arch="rv"+str(xlen)) 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() @@ -1079,13 +1083,13 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle # Partiton cgf to chunks chunk_len = math.ceil(len(cgf) / procs) chunks = [{k:cgf[k] for k in islice(iter(cgf), chunk_len)} for i in range(0, len(cgf), chunk_len)] - + queue_list = [] # List of queues to pass instructions to daughter processes process_list = [] # List of processes to be spawned event_list = [] # List of Event objects to signal exhaustion of instruction list to daughter processes cgf_queue_list = [] # List of queues to retrieve the updated CGF dictionary from each processes stats_queue_list = [] # List of queues to retrieve coverpoint hit statistics from each processes - + # For each chunk of cgf dictionary, spawn a new queue thread to pass instrObj, # to retrieve updated cgf, to retrieve statistics. An Event object is appended for # each processes spawned. A Process object is appended against every cgf chunk and initialized. @@ -1095,11 +1099,11 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle stats_queue_list.append(mp.Queue()) event_list.append(mp.Event()) process_list.append( - mp.Process(target=compute_per_line, + mp.Process(target=compute_per_line, args=(queue_list[i], event_list[i], cgf_queue_list[i], stats_queue_list[i], - chunks[i], xlen, addr_pairs, sig_addrs, - stats, - arch_state, + chunks[i], xlen, flen, addr_pairs, sig_addrs, + stats, + arch_state, csr_regfile, result_count, no_count @@ -1109,14 +1113,14 @@ 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 if instr is None: continue instrObj = (decoder.decode(instrObj_temp = instrObj_temp))[0] - + # Pass instrObjs to queues pertaining to each processes for each in queue_list: each.put_nowait(instrObj) @@ -1127,12 +1131,12 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle for (label,coverpt) in obj_dict.keys(): obj_dict[(label,coverpt)].process(cross_cover_queue, window_size,addr_pairs) cross_cover_queue.pop(0) - + # 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() diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index e461b1bd..009415b1 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -34,53 +34,56 @@ rounding_modes = ['0','1','2','3','4'] +sanitise_cvpt = lambda rm,x,iflen,flen: x + ' fcsr == '+hex(rm<<5) \ + + ('' if iflen == flen else (' and nan_prefix == 0x' + 'f'*int((flen-iflen)/4))) + def num_explain(flen,num): - num_dict = { - tuple(fzero) : 'fzero', - tuple(fminsubnorm) : 'fminsubnorm', - tuple(fsubnorm) : 'fsubnorm', - tuple(fmaxsubnorm) : 'fmaxsubnorm', - tuple(fminnorm) : 'fminnorm', - tuple(fnorm) : 'fnorm', - tuple(fmaxnorm) : 'fmaxnorm', - tuple(finfinity) : 'finfinity', - tuple(fdefaultnan) : 'fdefaultnan', - tuple(fqnan) : 'fqnan', - tuple(fsnan) : 'fsnan', - tuple(fone) : 'fone', - tuple(dzero) : 'dzero', - tuple(dminsubnorm) : 'dminsubnorm', - tuple(dsubnorm) : 'dsubnorm', - tuple(dmaxsubnorm) : 'dmaxsubnorm', - tuple(dminnorm) : 'dminnorm', - tuple(dnorm) : 'dnorm', - tuple(dmaxnorm) : 'dmaxnorm', - tuple(dinfinity) : 'dinfinity', - tuple(ddefaultnan) : 'ddefaultnan', - tuple(dqnan) : 'dqnan', - tuple(dsnan) : 'dsnan', - tuple(done) : 'done' - } - num_list = list(num_dict.items()) - for i in range(len(num_list)): - if(('0x'+num[2:].upper()) in num_list[i][0]): - return(num_list[i][1]) - - if flen == 32: - e_sz = 8 - m_sz = 23 - else: - e_sz = 11 - m_sz = 52 - bin_val = bin(int('1'+num[2:],16))[3:] - sgn = bin_val[0] - exp = bin_val[1:e_sz+1] - man = bin_val[e_sz+1:] - - if(int(exp,2)!=0): - return('fnorm' if flen==32 else 'dnorm') - else: - return('fsubnorm' if flen==32 else 'dsubnorm') + num_dict = { + tuple(fzero) : 'fzero', + tuple(fminsubnorm) : 'fminsubnorm', + tuple(fsubnorm) : 'fsubnorm', + tuple(fmaxsubnorm) : 'fmaxsubnorm', + tuple(fminnorm) : 'fminnorm', + tuple(fnorm) : 'fnorm', + tuple(fmaxnorm) : 'fmaxnorm', + tuple(finfinity) : 'finfinity', + tuple(fdefaultnan) : 'fdefaultnan', + tuple(fqnan) : 'fqnan', + tuple(fsnan) : 'fsnan', + tuple(fone) : 'fone', + tuple(dzero) : 'dzero', + tuple(dminsubnorm) : 'dminsubnorm', + tuple(dsubnorm) : 'dsubnorm', + tuple(dmaxsubnorm) : 'dmaxsubnorm', + tuple(dminnorm) : 'dminnorm', + tuple(dnorm) : 'dnorm', + tuple(dmaxnorm) : 'dmaxnorm', + tuple(dinfinity) : 'dinfinity', + tuple(ddefaultnan) : 'ddefaultnan', + tuple(dqnan) : 'dqnan', + tuple(dsnan) : 'dsnan', + tuple(done) : 'done' + } + num_list = list(num_dict.items()) + for i in range(len(num_list)): + if(('0x'+num[2:].upper()) in num_list[i][0]): + return(num_list[i][1]) + + if flen == 32: + e_sz = 8 + m_sz = 23 + else: + e_sz = 11 + m_sz = 52 + bin_val = bin(int('1'+num[2:],16))[3:] + sgn = bin_val[0] + exp = bin_val[1:e_sz+1] + man = bin_val[e_sz+1:] + + if(int(exp,2)!=0): + return('fnorm' if flen==32 else 'dnorm') + else: + return('fsubnorm' if flen==32 else 'dsubnorm') def extract_fields(flen, hexstr, postfix): if flen == 32: @@ -104,581 +107,588 @@ def extract_fields(flen, hexstr, postfix): return string -def fields_dec_converter(flen, hexstr): # IEEE-754 Hex -> Decimal Converter - - if flen == 32: - e_sz = 8 - m_sz = 23 - elif flen == 64: - e_sz = 11 - m_sz = 52 - bin_val = bin(int('1'+hexstr[2:],16))[3:] - sgn = bin_val[0] - exp = bin_val[1:e_sz+1] - man = bin_val[e_sz+1:] - - num='' - if(int(sgn)==1): - sign = '-' - elif(int(sgn)==0): - sign = '+' - - exp_str = '*pow(2,' - - if(flen == 32): - if((int(exp,2)-127)<-126): - conv_num = 0.0 - exp_str+= str(-126)+')' - elif((int(exp,2)-127)>=-126): - conv_num = 1.0 - exp_str+= str(int(exp,2)-127)+')' - elif(flen == 64): - if((int(exp,2)-1023)<-1022): - conv_num = 0.0 - exp_str+= str(-1022)+')' - elif((int(exp,2)-1023)>=-1022): - conv_num = 1.0 - exp_str+= str(int(exp,2)-1023)+')' - for i in range(len(man)): - conv_num+= (1/(pow(2,i+1)))*int(man[i]) - - num = sign + str(conv_num) + exp_str - if(flen == 32): - if(eval(num) > 1e-45 or eval(num)<-1e-45): - return(eval(num)) - else: - return(eval(sign+'1e-45')) - elif(flen == 64): - return(eval(num)) - -def floatingPoint_tohex(flen,float_no): # Decimal -> IEEE-754 Hex Converter - - if(flen==32): - if(str(float_no)=='-inf'): - return(finfinity[1]) - elif(str(float_no)=='inf'): - return(finfinity[0]) - elif(flen==64): - if(str(float_no)=='-inf'): - return(dinfinity[1]) - elif(str(float_no)=='inf'): - return(dinfinity[0]) - - float_no=float.hex(float_no) - num="N" - - a=float.fromhex(float_no) - - sign=0 - if(a<0 or str(a)[0]=='-'): - sign=1 - nor=float.hex(a) # Normalized Number - - if(flen==32): - if(int(nor.split("p")[1])<-126): # Checking Underflow of Exponent - exp_bin=('0'*8) # Exponent of Subnormal numbers - exp_sn=int(nor.split("p")[1]) - num="SN" - elif(int(nor.split("p")[1])>127): # Checking Overflow of Exponent - if(sign==0): - return "0x7f7fffff" # Most Positive Value - else: - return "0xff7fffff" # Most Negative Value - else: # Converting Exponent to 8-Bit Binary - exp=int(nor.split("p")[1])+127 - exp_bin=('0'*(8-(len(bin(exp))-2)))+bin(exp)[2:] - elif(flen==64): - check_sn = nor.split("p")[0].split(".")[0] - if(int(check_sn[len(check_sn)-1])==0): # Checking Underflow of Exponent - exp_bin=('0'*11) # Exponent of Subnormal numbers - exp_sn=int(nor.split("p")[1]) - num="SN" - elif(int(nor.split("p")[1])>1023): # Checking Overflow of Exponent - if(sign==0): - return "0x7FEFFFFFFFFFFFFF" # Most Positive Value - else: - return "0x0xFFEFFFFFFFFFFFFF" # Most Negative Value - else: # Converting Exponent to 8-Bit Binary - exp=int(nor.split("p")[1])+1023 - exp_bin=('0'*(11-(len(bin(exp))-2)))+bin(exp)[2:] - - if(num=="SN"): - if(sign==0): - mant="0x"+float_no.split("p")[0][4:] - else: - mant="0x"+float_no.split("p")[0][5:] - else: - if(sign==0): - mant="0x"+nor.split("p")[0][4:] - else: - mant="0x"+nor.split("p")[0][5:] - - if(flen==32): - mant_bin=bin(int('1'+mant[2:],16))[3:] - if(num == "SN"): - mant_bin='1'+bin(int('1'+mant[2:],16))[3:] - while(exp_sn!=-127): - exp_sn+=1 - mant_bin = '0'+mant_bin - binary="0b" - binary=binary+str(sign)+exp_bin+mant_bin[0:23] - hex_tp=hex(int(binary,2)) - hex_tp=hex_tp.replace('0x','0x'+'0'*(8-(len(hex_tp)-2))) - elif(flen==64): - mant_bin=bin(int('1'+mant[2:],16))[3:] - if(num == "SN"): - mant_bin=bin(int('1'+mant[2:],16))[3:] - binary="0b" - binary=binary+str(sign)+exp_bin+mant_bin[0:52] - hex_tp=hex(int(binary,2)) - hex_tp=hex_tp.replace('0x','0x'+'0'*(16-(len(hex_tp)-2))) - - return(hex_tp) +def fields_dec_converter(flen, hexstr): # IEEE-754 Hex -> Decimal Converter + + if flen == 32: + e_sz = 8 + m_sz = 23 + elif flen == 64: + e_sz = 11 + m_sz = 52 + bin_val = bin(int('1'+hexstr[2:],16))[3:] + sgn = bin_val[0] + exp = bin_val[1:e_sz+1] + man = bin_val[e_sz+1:] + + num='' + if(int(sgn)==1): + sign = '-' + elif(int(sgn)==0): + sign = '+' + + exp_str = '*pow(2,' + + if(flen == 32): + if((int(exp,2)-127)<-126): + conv_num = 0.0 + exp_str+= str(-126)+')' + elif((int(exp,2)-127)>=-126): + conv_num = 1.0 + exp_str+= str(int(exp,2)-127)+')' + elif(flen == 64): + if((int(exp,2)-1023)<-1022): + conv_num = 0.0 + exp_str+= str(-1022)+')' + elif((int(exp,2)-1023)>=-1022): + conv_num = 1.0 + exp_str+= str(int(exp,2)-1023)+')' + for i in range(len(man)): + conv_num+= (1/(pow(2,i+1)))*int(man[i]) + + num = sign + str(conv_num) + exp_str + if(flen == 32): + if(eval(num) > 1e-45 or eval(num)<-1e-45): + return(eval(num)) + else: + return(eval(sign+'1e-45')) + elif(flen == 64): + return(eval(num)) + +def floatingPoint_tohex(flen,float_no): # Decimal -> IEEE-754 Hex Converter + + if(flen==32): + if(str(float_no)=='-inf'): + return(finfinity[1]) + elif(str(float_no)=='inf'): + return(finfinity[0]) + elif(flen==64): + if(str(float_no)=='-inf'): + return(dinfinity[1]) + elif(str(float_no)=='inf'): + return(dinfinity[0]) + + float_no=float.hex(float_no) + num="N" + + a=float.fromhex(float_no) + + sign=0 + if(a<0 or str(a)[0]=='-'): + sign=1 + nor=float.hex(a) # Normalized Number + + if(flen==32): + if(int(nor.split("p")[1])<-126): # Checking Underflow of Exponent + exp_bin=('0'*8) # Exponent of Subnormal numbers + exp_sn=int(nor.split("p")[1]) + num="SN" + elif(int(nor.split("p")[1])>127): # Checking Overflow of Exponent + if(sign==0): + return "0x7f7fffff" # Most Positive Value + else: + return "0xff7fffff" # Most Negative Value + else: # Converting Exponent to 8-Bit Binary + exp=int(nor.split("p")[1])+127 + exp_bin=('0'*(8-(len(bin(exp))-2)))+bin(exp)[2:] + elif(flen==64): + check_sn = nor.split("p")[0].split(".")[0] + if(int(check_sn[len(check_sn)-1])==0): # Checking Underflow of Exponent + exp_bin=('0'*11) # Exponent of Subnormal numbers + exp_sn=int(nor.split("p")[1]) + num="SN" + elif(int(nor.split("p")[1])>1023): # Checking Overflow of Exponent + if(sign==0): + return "0x7FEFFFFFFFFFFFFF" # Most Positive Value + else: + return "0x0xFFEFFFFFFFFFFFFF" # Most Negative Value + else: # Converting Exponent to 8-Bit Binary + exp=int(nor.split("p")[1])+1023 + exp_bin=('0'*(11-(len(bin(exp))-2)))+bin(exp)[2:] + + if(num=="SN"): + if(sign==0): + mant="0x"+float_no.split("p")[0][4:] + else: + mant="0x"+float_no.split("p")[0][5:] + else: + if(sign==0): + mant="0x"+nor.split("p")[0][4:] + else: + mant="0x"+nor.split("p")[0][5:] + + if(flen==32): + mant_bin=bin(int('1'+mant[2:],16))[3:] + if(num == "SN"): + mant_bin='1'+bin(int('1'+mant[2:],16))[3:] + while(exp_sn!=-127): + exp_sn+=1 + mant_bin = '0'+mant_bin + binary="0b" + binary=binary+str(sign)+exp_bin+mant_bin[0:23] + hex_tp=hex(int(binary,2)) + hex_tp=hex_tp.replace('0x','0x'+'0'*(8-(len(hex_tp)-2))) + elif(flen==64): + mant_bin=bin(int('1'+mant[2:],16))[3:] + if(num == "SN"): + mant_bin=bin(int('1'+mant[2:],16))[3:] + binary="0b" + binary=binary+str(sign)+exp_bin+mant_bin[0:52] + hex_tp=hex(int(binary,2)) + hex_tp=hex_tp.replace('0x','0x'+'0'*(16-(len(hex_tp)-2))) + + return(hex_tp) def unique_cpts(x): - d = {} - for i in range(len(x)): # Returning a List Of Unique Coverpoints - if(d.get(x[i],"None") == "None"): - d[x[i]] = 1 - else: - d[x[i]]+=1 - return(list(d.keys())) + d = {} + for i in range(len(x)): # Returning a List Of Unique Coverpoints + if(d.get(x[i],"None") == "None"): + d[x[i]] = 1 + else: + d[x[i]]+=1 + return(list(d.keys())) def comments_parser(coverpoints): - cvpts = [] - for coverpoint in coverpoints: - cvpt = coverpoint.split("#")[0] - comment = coverpoint.split("#")[1] - cvpts.append((cvpt+ " #nosat",comment)) - return cvpts - -def ibm_b1(flen, opcode, ops): - ''' - IBM Model B1 Definition: - Test all combinations of floating-point basic types, positive and negative, for - each of the inputs. The basic types are Zero, One, MinSubNorm, SubNorm, - MaxSubNorm, MinNorm, Norm, MaxNorm, Infinity, DefaultNaN, QNaN, and - SNaN. - - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - - :type flen: int - :type opcode: str - :type ops: int - - Abstract Dataset Description: - Operands => - [Zero, One, MinSubNorm, SubNorm, MaxSubNorm, MinNorm, Norm, MaxNorm, Infinity, DefaultNaN, QNaN, SNaN] - - Implementation: - - Dependent on the value of flen, a predefined dataset of floating point values are added. - - Using the itertools package, an iterative multiplication is performed with two lists to create an exhaustive combination of all the operand values. - - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - - Coverpoints are then appended with the respective rounding mode for that particular opcode. - - ''' - if flen == 32: - basic_types = fzero + fminsubnorm + [fsubnorm[0], fsubnorm[3]] +\ - fmaxsubnorm + fminnorm + [fnorm[0], fnorm[3]] + fmaxnorm + \ - finfinity + fdefaultnan + [fqnan[0], fqnan[3]] + \ - [fsnan[0], fsnan[3]] + fone - elif flen == 64: - basic_types = dzero + dminsubnorm + [dsubnorm[0], dsubnorm[1]] +\ - dmaxsubnorm + dminnorm + [dnorm[0], dnorm[1]] + dmaxnorm + \ - dinfinity + ddefaultnan + [dqnan[0], dqnan[1]] + \ - [dsnan[0], dsnan[1]] + done - else: - logger.error('Invalid flen value!') - sys.exit(1) + cvpts = [] + for coverpoint in coverpoints: + cvpt = coverpoint.split("#")[0] + comment = coverpoint.split("#")[1] + cvpts.append((cvpt+ " #nosat",comment)) + return cvpts + +def ibm_b1(flen, iflen, opcode, ops): + ''' + IBM Model B1 Definition: + Test all combinations of floating-point basic types, positive and negative, for + each of the inputs. The basic types are Zero, One, MinSubNorm, SubNorm, + MaxSubNorm, MinNorm, Norm, MaxNorm, Infinity, DefaultNaN, QNaN, and + SNaN. + + :param iflen: Size of the floating point source operands for the instruction + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + + Abstract Dataset Description: + Operands => + [Zero, One, MinSubNorm, SubNorm, MaxSubNorm, MinNorm, Norm, MaxNorm, Infinity, DefaultNaN, QNaN, SNaN] + + Implementation: + - Dependent on the value of iflen, a predefined dataset of floating point values are added. + - Using the itertools package, an iterative multiplication is performed with two lists to create an exhaustive combination of all the operand values. + - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). + - Coverpoints are then appended with the respective rounding mode for that particular opcode. + + ''' + if iflen == 32: + basic_types = fzero + fminsubnorm + [fsubnorm[0], fsubnorm[3]] +\ + fmaxsubnorm + fminnorm + [fnorm[0], fnorm[3]] + fmaxnorm + \ + finfinity + fdefaultnan + [fqnan[0], fqnan[3]] + \ + [fsnan[0], fsnan[3]] + fone + elif iflen == 64: + basic_types = dzero + dminsubnorm + [dsubnorm[0], dsubnorm[1]] +\ + dmaxsubnorm + dminnorm + [dnorm[0], dnorm[1]] + dmaxnorm + \ + dinfinity + ddefaultnan + [dqnan[0], dqnan[1]] + \ + [dsnan[0], dsnan[1]] + done + else: + logger.error('Invalid iflen value!') + sys.exit(1) # the following creates a cross product for ops number of variables - b1_comb = list(itertools.product(*ops*[basic_types])) - coverpoints = [] - for c in b1_comb: - cvpt = "" - for x in range(1, ops+1): + b1_comb = list(itertools.product(*ops*[basic_types])) + coverpoints = [] + for c in b1_comb: + cvpt = "" + for x in range(1, ops+1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - if opcode.split('.')[0] in ["fadd","fsub","fmul","fdiv","fsqrt","fmadd","fnmadd","fmsub","fnmsub","fcvt","fmv","fle","fmv","fmin","fsgnj"]: - cvpt += 'rm_val == 0' - elif opcode.split('.')[0] in ["fclass","flt","fmax","fsgnjn"]: - cvpt += 'rm_val == 1' - elif opcode.split('.')[0] in ["feq","flw","fsw","fsgnjx"]: - cvpt += 'rm_val == 2' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - coverpoints.append(cvpt) - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B1 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b2(flen, opcode, ops, int_val = 100, seed = -1): - ''' - IBM Model B2 Definition: + cvpt += (extract_fields(iflen,c[x-1],str(x))) + " and " + if opcode.split('.')[0] in ["fadd","fsub","fmul","fdiv","fsqrt","fmadd","fnmadd","fmsub","fnmsub","fcvt","fmv","fle","fmv","fmin","fsgnj"]: + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + elif opcode.split('.')[0] in ["fclass","flt","fmax","fsgnjn"]: + cvpt = sanitise_cvpt(1,cvpt,iflen,flen) + elif opcode.split('.')[0] in ["feq","flw","fsw","fsgnjx"]: + cvpt = sanitise_cvpt(2,cvpt,iflen,flen) + + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + coverpoints.append(cvpt) + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B1 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b2(flen, iflen, opcode, ops, int_val = 100, seed = -1): + ''' + IBM Model B2 Definition: This model tests final results that are very close, measured in Hamming distance, to the specified boundary values. Each boundary value is taken as a base value, and the model enumerates over small deviations from the base, by flipping one bit of the significand. - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param int_val: Number to define the range in which the random value is to be generated. (Predefined to 100) - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param iflen: Size of the floating point source operands + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param int_val: Number to define the range in which the random value is to be generated. (Predefined to 100) + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :type int_val: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :type int_val: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Final Results = [Zero, One, MinSubNorm, MaxSubNorm, MinNorm, MaxNorm] Operand1 {operation} Operand2 = Final Results - Implementation: + Implementation: - Hamming distance is calculated using an xor operation between a number in the dataset and a number generated using walking ones operation. - A random operand value for one of the operands is assigned and based on the result and operation under consideration, the next operand is calculated. - These operand values are treated as decimal numbers until their derivation after which they are converted into their respective IEEE754 hexadecimal floating point formats using the “floatingPoint_tohex” function. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with the respective rounding mode for that particular opcode. - ''' - if flen == 32: - flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm - b = '0x00000010' - e_sz=8 - m_sz = 23 - elif flen == 64: - flip_types = dzero + done + dminsubnorm + dmaxsubnorm + dminnorm + dmaxnorm - b = '0x0000000000000010' - e_sz=11 - m_sz = 52 - - result = [] - b2_comb = [] - opcode = opcode.split('.')[0] - - if seed == -1: - if opcode in 'fadd': - random.seed(0) - elif opcode in 'fsub': - random.seed(1) - elif opcode in 'fmul': - random.seed(2) - elif opcode in 'fdiv': - random.seed(3) - elif opcode in 'fsqrt': - random.seed(4) - elif opcode in 'fmadd': - random.seed(5) - elif opcode in 'fnmadd': - random.seed(6) - elif opcode in 'fmsub': - random.seed(7) - elif opcode in 'fnmsub': - random.seed(8) - else: - random.seed(seed) - - for i in range(len(flip_types)): - k=1 - for j in range (1,24): - #print('{:010b}'.format(k)) - result.append(['0x'+hex(eval(bin(int('1'+flip_types[i][2:], 16))) ^ eval('0b'+'{:023b}'.format(k)))[3:],' | Result = '+num_explain(flen, '0x'+str(hex(eval(bin(int('1'+flip_types[i][2:], 16))))[3:]))+'(0x'+str(hex(eval(bin(int('1'+flip_types[i][2:], 16))))[3:])+')^'+str('0x'+hex(eval('0b'+'1'+'{:024b}'.format(k)))[3:])]) - k=k*2 - - for i in range(len(result)): - bin_val = bin(int('1'+result[i][0][2:],16))[3:] - rsgn = bin_val[0] - rexp = bin_val[1:e_sz+1] - rman = bin_val[e_sz+1:] - rs1_exp = rs3_exp = rexp - rs1_bin = bin(random.randrange(1,int_val)) - rs3_bin = bin(random.randrange(1,int_val)) - rs1_bin = ('0b0'+rexp+('0'*(m_sz-(len(rs1_bin)-2)))+rs1_bin[2:]) - rs3_bin = ('0b0'+rexp+('0'*(m_sz-(len(rs3_bin)-2)))+rs3_bin[2:]) - rs1 = fields_dec_converter(flen,'0x'+hex(int('1'+rs1_bin[2:],2))[3:]) - rs3 = fields_dec_converter(flen,'0x'+hex(int('1'+rs3_bin[2:],2))[3:]) - if opcode in 'fadd': - rs2 = fields_dec_converter(flen,result[i][0]) - rs1 - elif opcode in 'fsub': - rs2 = rs1 - fields_dec_converter(flen,result[i][0]) - elif opcode in 'fmul': - rs2 = fields_dec_converter(flen,result[i][0])/rs1 - elif opcode in 'fdiv': - if fields_dec_converter(flen,result[i][0]) != 0: - rs2 = rs1/fields_dec_converter(flen,result[i][0]) - elif opcode in 'fsqrt': - rs2 = fields_dec_converter(flen,result[i][0])*fields_dec_converter(flen,result[i][0]) - elif opcode in 'fmadd': - rs2 = (fields_dec_converter(flen,result[i][0]) - rs3)/rs1 - elif opcode in 'fnmadd': - rs2 = (rs3 - fields_dec_converter(flen,result[i][0]))/rs1 - elif opcode in 'fmsub': - rs2 = (fields_dec_converter(flen,result[i][0]) + rs3)/rs1 - elif opcode in 'fnmsub': - rs2 = -1*(rs3 + fields_dec_converter(flen,result[i][0]))/rs1 - - if(flen==32): - m = struct.unpack('f', struct.pack('f', rs2))[0] - elif(flen==64): - m = rs2 - - if opcode in ['fadd','fsub','fmul','fdiv']: - b2_comb.append((floatingPoint_tohex(flen,rs1),floatingPoint_tohex(flen,m))) - elif opcode in 'fsqrt': - b2_comb.append((floatingPoint_tohex(flen,m),)) - elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: - b2_comb.append((floatingPoint_tohex(flen,rs1),floatingPoint_tohex(flen,m),floatingPoint_tohex(flen,rs3))) - #print("b2_comb",b2_comb) - coverpoints = [] - k=0 - for c in b2_comb: - cvpt = "" - for x in range(1, ops+1): + ''' + if iflen == 32: + flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm + b = '0x00000010' + e_sz=8 + m_sz = 23 + elif iflen == 64: + flip_types = dzero + done + dminsubnorm + dmaxsubnorm + dminnorm + dmaxnorm + b = '0x0000000000000010' + e_sz=11 + m_sz = 52 + + result = [] + b2_comb = [] + opcode = opcode.split('.')[0] + + if seed == -1: + if opcode in 'fadd': + random.seed(0) + elif opcode in 'fsub': + random.seed(1) + elif opcode in 'fmul': + random.seed(2) + elif opcode in 'fdiv': + random.seed(3) + elif opcode in 'fsqrt': + random.seed(4) + elif opcode in 'fmadd': + random.seed(5) + elif opcode in 'fnmadd': + random.seed(6) + elif opcode in 'fmsub': + random.seed(7) + elif opcode in 'fnmsub': + random.seed(8) + else: + random.seed(seed) + + for i in range(len(flip_types)): + k=1 + for j in range (1,24): + #print('{:010b}'.format(k)) + result.append(['0x'+hex(eval(bin(int('1'+flip_types[i][2:], 16))) ^ eval('0b'+'{:023b}'.format(k)))[3:],' | Result = '+num_explain(iflen, '0x'+str(hex(eval(bin(int('1'+flip_types[i][2:], 16))))[3:]))+'(0x'+str(hex(eval(bin(int('1'+flip_types[i][2:], 16))))[3:])+')^'+str('0x'+hex(eval('0b'+'1'+'{:024b}'.format(k)))[3:])]) + k=k*2 + + for i in range(len(result)): + bin_val = bin(int('1'+result[i][0][2:],16))[3:] + rsgn = bin_val[0] + rexp = bin_val[1:e_sz+1] + rman = bin_val[e_sz+1:] + rs1_exp = rs3_exp = rexp + rs1_bin = bin(random.randrange(1,int_val)) + rs3_bin = bin(random.randrange(1,int_val)) + rs1_bin = ('0b0'+rexp+('0'*(m_sz-(len(rs1_bin)-2)))+rs1_bin[2:]) + rs3_bin = ('0b0'+rexp+('0'*(m_sz-(len(rs3_bin)-2)))+rs3_bin[2:]) + rs1 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs1_bin[2:],2))[3:]) + rs3 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs3_bin[2:],2))[3:]) + if opcode in 'fadd': + rs2 = fields_dec_converter(iflen,result[i][0]) - rs1 + elif opcode in 'fsub': + rs2 = rs1 - fields_dec_converter(iflen,result[i][0]) + elif opcode in 'fmul': + rs2 = fields_dec_converter(iflen,result[i][0])/rs1 + elif opcode in 'fdiv': + if fields_dec_converter(iflen,result[i][0]) != 0: + rs2 = rs1/fields_dec_converter(iflen,result[i][0]) + elif opcode in 'fsqrt': + rs2 = fields_dec_converter(iflen,result[i][0])*fields_dec_converter(iflen,result[i][0]) + elif opcode in 'fmadd': + rs2 = (fields_dec_converter(iflen,result[i][0]) - rs3)/rs1 + elif opcode in 'fnmadd': + rs2 = (rs3 - fields_dec_converter(iflen,result[i][0]))/rs1 + elif opcode in 'fmsub': + rs2 = (fields_dec_converter(iflen,result[i][0]) + rs3)/rs1 + elif opcode in 'fnmsub': + rs2 = -1*(rs3 + fields_dec_converter(iflen,result[i][0]))/rs1 + + if(iflen==32): + m = struct.unpack('f', struct.pack('f', rs2))[0] + elif(iflen==64): + m = rs2 + + if opcode in ['fadd','fsub','fmul','fdiv']: + b2_comb.append((floatingPoint_tohex(iflen,rs1),floatingPoint_tohex(iflen,m))) + elif opcode in 'fsqrt': + b2_comb.append((floatingPoint_tohex(iflen,m),)) + elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: + b2_comb.append((floatingPoint_tohex(iflen,rs1),floatingPoint_tohex(iflen,m),floatingPoint_tohex(iflen,rs3))) + #print("b2_comb",b2_comb) + coverpoints = [] + k=0 + for c in b2_comb: + cvpt = "" + for x in range(1, ops+1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += result[k][1] - coverpoints.append(cvpt) - k=k+1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B2 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b3(flen, opcode, ops, seed=-1): - ''' - IBM Model B3 Definition: + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += result[k][1] + coverpoints.append(cvpt) + k=k+1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B2 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b3(flen,iflen, opcode, ops, seed=-1): + ''' + IBM Model B3 Definition: This model tests all combinations of the sign, significand’s LSB, guard bit & sticky bit of the intermediate result. - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param iflen: Size of the floating source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Intermediate Result is chosen at random Intermediate Result = [All possible combinations of Sign, LSB, Guard and Sticky are taken] Operand1 {operation} Operand2 = Intermediate Results - Implementation: + Implementation: - The Sticky bit is 1 if there were non-zero digits to the right of the guard digit, hence the lsb list is subjected to that condition. - Float_val [ a list of numbers ] extracted from the fields_dec_converter is checked for the LSB. If it is a negative number, then the list ieee754_num is appended with splitting the p character and first 10 characters in the 0th split + ‘p’ + other part of the split. “p” specifies the maximum available number in python and used in 64 bit architecture. If we require a digit more than thea number, then we represent it using a string because an int - Now the ir_dataset is initialized and since the ieee754_num list has the same element twice [ first is just the number and second is with sign ], hence we loop that array, considering only multiples of 2 elements from it. If the sign is ‘-’, then then the index is updated with 1 else if it is ‘+’, then it is updated with 0 complying with the IEEE standards. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - opcode = opcode.split('.')[0] - getcontext().prec = 40 - - if seed == -1: - if opcode in 'fadd': - random.seed(0) - elif opcode in 'fsub': - random.seed(1) - elif opcode in 'fmul': - random.seed(2) - elif opcode in 'fdiv': - random.seed(3) - elif opcode in 'fsqrt': - random.seed(4) - elif opcode in 'fmadd': - random.seed(5) - elif opcode in 'fnmadd': - random.seed(6) - elif opcode in 'fmsub': - random.seed(7) - elif opcode in 'fnmsub': - random.seed(8) - else: - random.seed(seed) - - if flen == 32: - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_num = [] - lsb = [] - for i in fsubnorm+fnorm: - if int(i[-1],16)%2 == 1: - lsb.append('1') - lsb.append('1') - else: - lsb.append('0') - lsb.append('0') - float_val = float.hex(fields_dec_converter(32,i)) - if float_val[0] != '-': - ieee754_num.append(float_val.split('p')[0][0:10]+'p'+float_val.split('p')[1]) - ieee754_num.append('-'+float_val.split('p')[0][0:10]+'p'+float_val.split('p')[1]) - else: - ieee754_num.append(float_val.split('p')[0][0:11]+'p'+float_val.split('p')[1]) - ieee754_num.append(float_val.split('p')[0][1:11]+'p'+float_val.split('p')[1]) - - ir_dataset = [] - for k in range(len(ieee754_num)): - for i in range(2,16,2): - grs = '{:04b}'.format(i) - if ieee754_num[k][0] == '-': sign = '1' - else: sign = '0' - ir_dataset.append([ieee754_num[k].split('p')[0]+str(i)+'p'+ieee754_num[k].split('p')[1],' | Guard = '+grs[0]+' Sticky = '+grs[2]+' Sign = '+sign+' LSB = '+lsb[k]]) - - for i in range(len(ir_dataset)): - ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) - - elif flen == 64: - maxdec = '1.7976931348623157e+308' - maxnum = float.fromhex('0x1.fffffffffffffp+1023') - ieee754_num = [] - lsb = [] - for i in dsubnorm+dnorm: - if int(i[-1],16)%2 == 1: - lsb.append('1') - lsb.append('1') - else: - lsb.append('0') - lsb.append('0') - float_val = str(fields_dec_converter(64,i)) - if float_val[0] != '-': - ieee754_num.append(float_val) - ieee754_num.append('-'+float_val) - else: - ieee754_num.append(float_val) - ieee754_num.append(float_val[1:]) - - ir_dataset = [] - for k in range(len(ieee754_num)): - for i in range(2,16,2): - grs = '{:04b}'.format(i) - if ieee754_num[k][0] == '-': sign = '1' - else: sign = '0' - ir_dataset.append([str(Decimal(ieee754_num[k].split('e')[0])+Decimal(pow(i*16,-14)))+'e'+ieee754_num[k].split('e')[1],' | Guard = '+grs[0]+' Sticky = '+grs[2]+' Sign = '+sign+' LSB = '+lsb[k]]) - - b4_comb = [] - - for i in range(len(ir_dataset)): - rs1 = random.uniform(1,maxnum) - rs3 = random.uniform(1,maxnum) - if opcode in 'fadd': - if flen == 32: - rs2 = ir_dataset[i][0] - rs1 - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0]) - Decimal(rs1) - elif opcode in 'fsub': - if flen == 32: - rs2 = rs1 - ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(rs1) - Decimal(ir_dataset[i][0]) - elif opcode in 'fmul': - if flen == 32: - rs2 = ir_dataset[i][0]/rs1 - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) - elif opcode in 'fdiv': - if flen == 32: - rs2 = rs1/ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) - elif opcode in 'fsqrt': - if flen == 32: - rs2 = ir_dataset[i][0]*ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])*Decimal(ir_dataset[i][0]) - elif opcode in 'fmadd': - if flen == 32: - rs2 = (ir_dataset[i][0] - rs3)/rs1 - elif flen == 64: - rs2 = (Decimal(ir_dataset[i][0]) - Decimal(rs3))/Decimal(rs1) - elif opcode in 'fnmadd': - if flen == 32: - rs2 = (rs3 - ir_dataset[i][0])/rs1 - elif flen == 64: - rs2 = (Decimal(rs3) - Decimal(ir_dataset[i][0]))/Decimal(rs1) - elif opcode in 'fmsub': - if flen == 32: - rs2 = (ir_dataset[i][0] + rs3)/rs1 - elif flen == 64: - rs2 = (Decimal(ir_dataset[i][0]) + Decimal(rs3))/Decimal(rs1) - elif opcode in 'fnmsub': - if flen == 32: - rs2 = -1*(rs3 + ir_dataset[i][0])/rs1 - elif flen == 64: - rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) - - if(flen==32): - x1 = struct.unpack('f', struct.pack('f', rs1))[0] - x2 = struct.unpack('f', struct.pack('f', rs2))[0] - x3 = struct.unpack('f', struct.pack('f', rs3))[0] - elif(flen==64): - x1 = rs1 - x2 = rs2 - x3 = rs3 - - if opcode in ['fadd','fsub','fmul','fdiv']: - b4_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - elif opcode in 'fsqrt': - b4_comb.append((floatingPoint_tohex(flen,float(rs2)),)) - elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: - b4_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - - coverpoints = [] - k = 0 - for c in b4_comb: - for rm in range(5): - cvpt = "" - for x in range(1, ops+1): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == '+str(rm) - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += ir_dataset[k][1] - coverpoints.append(cvpt) - k=k+1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B3 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b4(flen, opcode, ops, seed=-1): - ''' - IBM Model B4 Definition: + ''' + opcode = opcode.split('.')[0] + getcontext().prec = 40 + + if seed == -1: + if opcode in 'fadd': + random.seed(0) + elif opcode in 'fsub': + random.seed(1) + elif opcode in 'fmul': + random.seed(2) + elif opcode in 'fdiv': + random.seed(3) + elif opcode in 'fsqrt': + random.seed(4) + elif opcode in 'fmadd': + random.seed(5) + elif opcode in 'fnmadd': + random.seed(6) + elif opcode in 'fmsub': + random.seed(7) + elif opcode in 'fnmsub': + random.seed(8) + else: + random.seed(seed) + + if iflen == 32: + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_num = [] + lsb = [] + for i in fsubnorm+fnorm: + if int(i[-1],16)%2 == 1: + lsb.append('1') + lsb.append('1') + else: + lsb.append('0') + lsb.append('0') + float_val = float.hex(fields_dec_converter(32,i)) + if float_val[0] != '-': + ieee754_num.append(float_val.split('p')[0][0:10]+'p'+float_val.split('p')[1]) + ieee754_num.append('-'+float_val.split('p')[0][0:10]+'p'+float_val.split('p')[1]) + else: + ieee754_num.append(float_val.split('p')[0][0:11]+'p'+float_val.split('p')[1]) + ieee754_num.append(float_val.split('p')[0][1:11]+'p'+float_val.split('p')[1]) + + ir_dataset = [] + for k in range(len(ieee754_num)): + for i in range(2,16,2): + grs = '{:04b}'.format(i) + if ieee754_num[k][0] == '-': sign = '1' + else: sign = '0' + ir_dataset.append([ieee754_num[k].split('p')[0]+str(i)+'p'+ieee754_num[k].split('p')[1],' | Guard = '+grs[0]+' Sticky = '+grs[2]+' Sign = '+sign+' LSB = '+lsb[k]]) + + for i in range(len(ir_dataset)): + ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) + + elif iflen == 64: + maxdec = '1.7976931348623157e+308' + maxnum = float.fromhex('0x1.fffffffffffffp+1023') + ieee754_num = [] + lsb = [] + for i in dsubnorm+dnorm: + if int(i[-1],16)%2 == 1: + lsb.append('1') + lsb.append('1') + else: + lsb.append('0') + lsb.append('0') + float_val = str(fields_dec_converter(64,i)) + if float_val[0] != '-': + ieee754_num.append(float_val) + ieee754_num.append('-'+float_val) + else: + ieee754_num.append(float_val) + ieee754_num.append(float_val[1:]) + + ir_dataset = [] + for k in range(len(ieee754_num)): + for i in range(2,16,2): + grs = '{:04b}'.format(i) + if ieee754_num[k][0] == '-': sign = '1' + else: sign = '0' + ir_dataset.append([str(Decimal(ieee754_num[k].split('e')[0])+Decimal(pow(i*16,-14)))+'e'+ieee754_num[k].split('e')[1],' | Guard = '+grs[0]+' Sticky = '+grs[2]+' Sign = '+sign+' LSB = '+lsb[k]]) + + b4_comb = [] + + for i in range(len(ir_dataset)): + rs1 = random.uniform(1,maxnum) + rs3 = random.uniform(1,maxnum) + if opcode in 'fadd': + if iflen == 32: + rs2 = ir_dataset[i][0] - rs1 + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0]) - Decimal(rs1) + elif opcode in 'fsub': + if iflen == 32: + rs2 = rs1 - ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(rs1) - Decimal(ir_dataset[i][0]) + elif opcode in 'fmul': + if iflen == 32: + rs2 = ir_dataset[i][0]/rs1 + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) + elif opcode in 'fdiv': + if iflen == 32: + rs2 = rs1/ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) + elif opcode in 'fsqrt': + if iflen == 32: + rs2 = ir_dataset[i][0]*ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])*Decimal(ir_dataset[i][0]) + elif opcode in 'fmadd': + if iflen == 32: + rs2 = (ir_dataset[i][0] - rs3)/rs1 + elif iflen == 64: + rs2 = (Decimal(ir_dataset[i][0]) - Decimal(rs3))/Decimal(rs1) + elif opcode in 'fnmadd': + if iflen == 32: + rs2 = (rs3 - ir_dataset[i][0])/rs1 + elif iflen == 64: + rs2 = (Decimal(rs3) - Decimal(ir_dataset[i][0]))/Decimal(rs1) + elif opcode in 'fmsub': + if iflen == 32: + rs2 = (ir_dataset[i][0] + rs3)/rs1 + elif iflen == 64: + rs2 = (Decimal(ir_dataset[i][0]) + Decimal(rs3))/Decimal(rs1) + elif opcode in 'fnmsub': + if iflen == 32: + rs2 = -1*(rs3 + ir_dataset[i][0])/rs1 + elif iflen == 64: + rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) + + if(iflen==32): + x1 = struct.unpack('f', struct.pack('f', rs1))[0] + x2 = struct.unpack('f', struct.pack('f', rs2))[0] + x3 = struct.unpack('f', struct.pack('f', rs3))[0] + elif(iflen==64): + x1 = rs1 + x2 = rs2 + x3 = rs3 + + if opcode in ['fadd','fsub','fmul','fdiv']: + b4_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + elif opcode in 'fsqrt': + b4_comb.append((floatingPoint_tohex(iflen,float(rs2)),)) + elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: + b4_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)),floatingPoint_tohex(iflen,float(rs3)))) + + coverpoints = [] + k = 0 + for c in b4_comb: + for rm in range(5): + cvpt = "" + for x in range(1, ops+1): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + # cvpt += 'rm_val == '+str(rm) + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += ir_dataset[k][1] + coverpoints.append(cvpt) + k=k+1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B3 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b4(flen, iflen, opcode, ops, seed=-1): + ''' + IBM Model B4 Definition: This model creates a test-case for each of the following constraints on the intermediate results: @@ -688,175 +698,178 @@ def ibm_b4(flen, opcode, ops, seed=-1): 4. A random number that is smaller than -MaxNorm – 3 ulp 5. One number for every exponent in the range [MaxNorm.exp - 3, MaxNorm.exp + 3] for positive and negative numbers - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param flen: Size of the floating point registers + :param iflen: Size of the floating point source operands for the operation + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Intermediate Results = [[MaxNorm-3 ulp, MaxNorm+3 ulp], [-MaxNorm-3 ulp, -MaxNorm+3 ulp], Random Num > MaxNorm+3 ulp, Random Num < -MaxNorm-3 ulp, [MaxNorm.exp-3, MaxNorm.exp+3]] Operand1 {operation} Operand2 = Intermediate Results - Implementation: + Implementation: - The intermediate results dataset is populated in accordance with the abstract dataset defined above. - Intermediate results can be out of the range of what is representable in the specified format; they should only be viewed numerically. Inorder to represent numbers that went out of range of the maximum representable number in python, the “Decimal” module was utilized. - These operand values are treated as decimal numbers until their derivation after which they are converted into their respective IEEE754 hexadecimal floating point formats using the “floatingPoint_tohex” function. - ''' - opcode = opcode.split('.')[0] - getcontext().prec = 40 - - if seed == -1: - if opcode in 'fadd': - random.seed(0) - elif opcode in 'fsub': - random.seed(1) - elif opcode in 'fmul': - random.seed(2) - elif opcode in 'fdiv': - random.seed(3) - elif opcode in 'fsqrt': - random.seed(4) - elif opcode in 'fmadd': - random.seed(5) - elif opcode in 'fnmadd': - random.seed(6) - elif opcode in 'fmsub': - random.seed(7) - elif opcode in 'fnmsub': - random.seed(8) - else: - random.seed(seed) - - if flen == 32: - ieee754_maxnorm_p = '0x1.7fffffp+127' - ieee754_maxnorm_n = '0x1.7ffffep+127' - maxnum = float.fromhex(ieee754_maxnorm_p) - ir_dataset = [] - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([ieee754_maxnorm_p.split('p')[0]+str(i)+'p'+ieee754_maxnorm_p.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm + '+str(int(grs[0:3],2))+' ulp']) - ir_dataset.append([ieee754_maxnorm_n.split('p')[0]+str(i)+'p'+ieee754_maxnorm_n.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm - '+str(int(grs[0:3],2))+' ulp']) - for i in range(-3,4): - ir_dataset.append([ieee754_maxnorm_p.split('p')[0]+'p'+str(127+i),' | Exponent = '+str(127+i)+' Number = +ve']) - ir_dataset.append(['-'+ieee754_maxnorm_n.split('p')[0]+'p'+str(127+i),' | Exponent = '+str(127+i)+' Number = -ve']) - for i in range(len(ir_dataset)): - ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) - elif flen == 64: - maxnum = float.fromhex('0x1.fffffffffffffp+1023') - maxdec_p = str(maxnum) - maxdec_n = str(float.fromhex('0x1.ffffffffffffep+1023')) - ir_dataset = [] - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([str(Decimal(maxdec_p.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+maxdec_p.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm + '+str(int(grs[0:3],2))+' ulp']) - ir_dataset.append([str(Decimal(maxdec_n.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+maxdec_n.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm - '+str(int(grs[0:3],2))+' ulp']) - for i in range(-3,4): - ir_dataset.append([str(random.uniform(1,maxnum)).split('e')[0]+'e'+str(int(math.log(pow(2,1023+i),10))),' | Exponent = '+str(1023+i)+' Number = +ve']) - ir_dataset.append([str(-1*random.uniform(1,maxnum)).split('e')[0]+'e'+str(int(math.log(pow(2,1023+i),10))),' | Exponent = '+str(1023+i)+' Number = -ve']) - - b4_comb = [] - - for i in range(len(ir_dataset)): - rs1 = random.uniform(1,maxnum) - rs3 = random.uniform(1,maxnum) - if opcode in 'fadd': - if flen == 32: - rs2 = ir_dataset[i][0] - rs1 - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0]) - Decimal(rs1) - elif opcode in 'fsub': - if flen == 32: - rs2 = rs1 - ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(rs1) - Decimal(ir_dataset[i][0]) - elif opcode in 'fmul': - if flen == 32: - rs2 = ir_dataset[i][0]/rs1 - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) - elif opcode in 'fdiv': - if flen == 32: - rs2 = rs1/ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) - elif opcode in 'fsqrt': - if flen == 32: - rs2 = ir_dataset[i][0]*ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])*Decimal(ir_dataset[i][0]) - elif opcode in 'fmadd': - if flen == 32: - rs2 = (ir_dataset[i][0] - rs3)/rs1 - elif flen == 64: - rs2 = (Decimal(ir_dataset[i][0]) - Decimal(rs3))/Decimal(rs1) - elif opcode in 'fnmadd': - if flen == 32: - rs2 = (rs3 - ir_dataset[i][0])/rs1 - elif flen == 64: - rs2 = (Decimal(rs3) - Decimal(ir_dataset[i][0]))/Decimal(rs1) - elif opcode in 'fmsub': - if flen == 32: - rs2 = (ir_dataset[i][0] + rs3)/rs1 - elif flen == 64: - rs2 = (Decimal(ir_dataset[i][0]) + Decimal(rs3))/Decimal(rs1) - elif opcode in 'fnmsub': - if flen == 32: - rs2 = -1*(rs3 + ir_dataset[i][0])/rs1 - elif flen == 64: - rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) - - if(flen==32): - x1 = struct.unpack('f', struct.pack('f', rs1))[0] - x2 = struct.unpack('f', struct.pack('f', rs2))[0] - x3 = struct.unpack('f', struct.pack('f', rs3))[0] - elif(flen==64): - x1 = rs1 - x2 = rs2 - x3 = rs3 - - if opcode in ['fadd','fsub','fmul','fdiv']: - b4_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - elif opcode in 'fsqrt': - b4_comb.append((floatingPoint_tohex(flen,float(rs2)),)) - elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: - b4_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - - coverpoints = [] - k = 0 - for c in b4_comb: - for rm in range(5): - cvpt = "" - for x in range(1, ops+1): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == '+str(rm) - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += ir_dataset[k][1] - coverpoints.append(cvpt) - k=k+1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B4 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b5(flen, opcode, ops, seed=-1): - ''' - IBM Model B5 Definition: + ''' + opcode = opcode.split('.')[0] + getcontext().prec = 40 + + if seed == -1: + if opcode in 'fadd': + random.seed(0) + elif opcode in 'fsub': + random.seed(1) + elif opcode in 'fmul': + random.seed(2) + elif opcode in 'fdiv': + random.seed(3) + elif opcode in 'fsqrt': + random.seed(4) + elif opcode in 'fmadd': + random.seed(5) + elif opcode in 'fnmadd': + random.seed(6) + elif opcode in 'fmsub': + random.seed(7) + elif opcode in 'fnmsub': + random.seed(8) + else: + random.seed(seed) + + if iflen == 32: + ieee754_maxnorm_p = '0x1.7fffffp+127' + ieee754_maxnorm_n = '0x1.7ffffep+127' + maxnum = float.fromhex(ieee754_maxnorm_p) + ir_dataset = [] + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([ieee754_maxnorm_p.split('p')[0]+str(i)+'p'+ieee754_maxnorm_p.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm + '+str(int(grs[0:3],2))+' ulp']) + ir_dataset.append([ieee754_maxnorm_n.split('p')[0]+str(i)+'p'+ieee754_maxnorm_n.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm - '+str(int(grs[0:3],2))+' ulp']) + for i in range(-3,4): + ir_dataset.append([ieee754_maxnorm_p.split('p')[0]+'p'+str(127+i),' | Exponent = '+str(127+i)+' Number = +ve']) + ir_dataset.append(['-'+ieee754_maxnorm_n.split('p')[0]+'p'+str(127+i),' | Exponent = '+str(127+i)+' Number = -ve']) + for i in range(len(ir_dataset)): + ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) + elif iflen == 64: + maxnum = float.fromhex('0x1.fffffffffffffp+1023') + maxdec_p = str(maxnum) + maxdec_n = str(float.fromhex('0x1.ffffffffffffep+1023')) + ir_dataset = [] + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([str(Decimal(maxdec_p.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+maxdec_p.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm + '+str(int(grs[0:3],2))+' ulp']) + ir_dataset.append([str(Decimal(maxdec_n.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+maxdec_n.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm - '+str(int(grs[0:3],2))+' ulp']) + for i in range(-3,4): + ir_dataset.append([str(random.uniform(1,maxnum)).split('e')[0]+'e'+str(int(math.log(pow(2,1023+i),10))),' | Exponent = '+str(1023+i)+' Number = +ve']) + ir_dataset.append([str(-1*random.uniform(1,maxnum)).split('e')[0]+'e'+str(int(math.log(pow(2,1023+i),10))),' | Exponent = '+str(1023+i)+' Number = -ve']) + + b4_comb = [] + + for i in range(len(ir_dataset)): + rs1 = random.uniform(1,maxnum) + rs3 = random.uniform(1,maxnum) + if opcode in 'fadd': + if iflen == 32: + rs2 = ir_dataset[i][0] - rs1 + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0]) - Decimal(rs1) + elif opcode in 'fsub': + if iflen == 32: + rs2 = rs1 - ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(rs1) - Decimal(ir_dataset[i][0]) + elif opcode in 'fmul': + if iflen == 32: + rs2 = ir_dataset[i][0]/rs1 + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) + elif opcode in 'fdiv': + if iflen == 32: + rs2 = rs1/ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) + elif opcode in 'fsqrt': + if iflen == 32: + rs2 = ir_dataset[i][0]*ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])*Decimal(ir_dataset[i][0]) + elif opcode in 'fmadd': + if iflen == 32: + rs2 = (ir_dataset[i][0] - rs3)/rs1 + elif iflen == 64: + rs2 = (Decimal(ir_dataset[i][0]) - Decimal(rs3))/Decimal(rs1) + elif opcode in 'fnmadd': + if iflen == 32: + rs2 = (rs3 - ir_dataset[i][0])/rs1 + elif iflen == 64: + rs2 = (Decimal(rs3) - Decimal(ir_dataset[i][0]))/Decimal(rs1) + elif opcode in 'fmsub': + if iflen == 32: + rs2 = (ir_dataset[i][0] + rs3)/rs1 + elif iflen == 64: + rs2 = (Decimal(ir_dataset[i][0]) + Decimal(rs3))/Decimal(rs1) + elif opcode in 'fnmsub': + if iflen == 32: + rs2 = -1*(rs3 + ir_dataset[i][0])/rs1 + elif iflen == 64: + rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) + + if(iflen==32): + x1 = struct.unpack('f', struct.pack('f', rs1))[0] + x2 = struct.unpack('f', struct.pack('f', rs2))[0] + x3 = struct.unpack('f', struct.pack('f', rs3))[0] + elif(iflen==64): + x1 = rs1 + x2 = rs2 + x3 = rs3 + + if opcode in ['fadd','fsub','fmul','fdiv']: + b4_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + elif opcode in 'fsqrt': + b4_comb.append((floatingPoint_tohex(iflen,float(rs2)),)) + elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: + b4_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)),floatingPoint_tohex(iflen,float(rs3)))) + + coverpoints = [] + k = 0 + for c in b4_comb: + for rm in range(5): + cvpt = "" + for x in range(1, ops+1): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + # cvpt += 'rm_val == '+str(rm) + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += ir_dataset[k][1] + coverpoints.append(cvpt) + k=k+1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B4 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b5(flen, iflen, opcode, ops, seed=-1): + ''' + IBM Model B5 Definition: This model creates a test-case for each of the following constraints on the intermediate results: 1. All the numbers in the range [+MinSubNorm – 3 ulp, +MinSubNorm + 3 ulp] 2. All the numbers in the range [-MinSubNorm - 3 ulp, -MinSubNorm + 3 ulp] @@ -868,193 +881,196 @@ def ibm_b5(flen, opcode, ops, seed=-1): 8. A random number in the range (-MinSubNorm, -0) 9. One number for every exponent in the range [MinNorm.exp, MinNorm.exp + 5] - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Intermediate Results = [+MinSubNorm – 3 ulp, +MinSubNorm + 3 ulp], [-MinSubNorm - 3 ulp, -MinSubNorm + 3 ulp] , [MinNorm – 3 ulp, MinNorm + 3 ulp] , [-MinNorm - 3 ulp, -MinNorm + 3 ulp] , Random Num in (0, MinSubNorm), Random Num in (-MinSubNorm, -0), One Num for every exp in [MinNorm.exp, MinNorm.exp + 5]] Operand1 {operation} Operand2 = Intermediate Results - Implementation: + Implementation: - The intermediate results dataset is populated in accordance with the abstract dataset defined above. - Intermediate results can be out of the range of what is representable in the specified format; they should only be viewed numerically. Inorder to represent numbers that went out of range of the maximum representable number in python, the “Decimal” module was utilized. - These operand values are treated as decimal numbers until their derivation after which they are converted into their respective IEEE754 hexadecimal floating point formats using the “floatingPoint_tohex” function. - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - - opcode = opcode.split('.')[0] - getcontext().prec = 40 - if flen == 32: - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.000001p-126' - ir_dataset = [] - for i in range(0,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([ieee754_minsubnorm.split('p')[0]+str(i)+'p'+ieee754_minsubnorm.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minsubnorm + '+str(int(grs[0:3],2))+' ulp']) - ieee754_minnorm = '0x1.000000p-126' - for i in range(0,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([ieee754_minnorm.split('p')[0]+str(i)+'p'+ieee754_minnorm.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minnorm + '+str(int(grs[0:3],2))+' ulp']) - minnorm_Exp = ['0x1.000000p-126','0x1.000000p-125','0x1.000000p-124','0x1.000000p-123','0x1.000000p-122','0x1.000000p-121'] - for i in minnorm_Exp: - ir_dataset.append([i,' | Exponent = MinNorm.exp + '+str(126+int(i.split('p')[1]))]) - n = len(ir_dataset) - for i in range(n): - ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) - ir_dataset.append([-1*ir_dataset[i][0],ir_dataset[i][1]]) - - elif flen == 64: - maxdec = '1.7976931348623157e+308' - maxnum = float.fromhex('0x1.fffffffffffffp+1023') - minsubdec = '5e-324' - ir_dataset = [] - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([str(Decimal(minsubdec.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+minsubdec.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minsubnorm + '+str(int(grs[0:3],2))+' ulp']) - minnormdec = '2.2250738585072014e-308' - ir_dataset.append([minsubdec, ' | Guard = 0 Round = 0 Sticky = 0 --> Minsubnorm + 0 ulp']) - ir_dataset.append([minnormdec,' | Guard = 0 Round = 0 Sticky = 0 --> Minnorm + 0 ulp']) - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([str(Decimal(minnormdec.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+minnormdec.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minnorm + '+str(int(grs[0:3],2))+' ulp']) - minnorm_Exp = ['4.450147717014403e-308','8.900295434028806e-308','1.780059086805761e-307','3.560118173611522e-307','7.120236347223044e-307'] - - k = 1 - for i in minnorm_Exp: - ir_dataset.append([i,' | Exponent = MinNorm.exp + '+str(k)]) - k += 1 - n = len(ir_dataset) - for i in range(n): - ir_dataset.append(['-'+ir_dataset[i][0],ir_dataset[i][1]]) - - if seed == -1: - if opcode in 'fadd': - random.seed(0) - elif opcode in 'fsub': - random.seed(1) - elif opcode in 'fmul': - random.seed(2) - elif opcode in 'fdiv': - random.seed(3) - elif opcode in 'fsqrt': - random.seed(4) - elif opcode in 'fmadd': - random.seed(5) - elif opcode in 'fnmadd': - random.seed(6) - elif opcode in 'fmsub': - random.seed(7) - elif opcode in 'fnmsub': - random.seed(8) - else: - random.seed(seed) - - b5_comb = [] - - for i in range(len(ir_dataset)): - rs1 = random.uniform(1,maxnum) - rs3 = random.uniform(1,maxnum) - if opcode in 'fadd': - if flen == 32: - rs2 = ir_dataset[i][0] - rs1 - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0]) - Decimal(rs1) - elif opcode in 'fsub': - if flen == 32: - rs2 = rs1 - ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(rs1) - Decimal(ir_dataset[i][0]) - elif opcode in 'fmul': - if flen == 32: - rs2 = ir_dataset[i][0]/rs1 - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) - elif opcode in 'fdiv': - if flen == 32: - rs2 = rs1/ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) - elif opcode in 'fsqrt': - if flen == 32: - rs2 = ir_dataset[i][0]*ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])*Decimal(ir_dataset[i][0]) - elif opcode in 'fmadd': - if flen == 32: - rs2 = (ir_dataset[i][0] - rs3)/rs1 - elif flen == 64: - rs2 = (Decimal(ir_dataset[i][0]) - Decimal(rs3))/Decimal(rs1) - elif opcode in 'fnmadd': - if flen == 32: - rs2 = (rs3 - ir_dataset[i][0])/rs1 - elif flen == 64: - rs2 = (Decimal(rs3) - Decimal(ir_dataset[i][0]))/Decimal(rs1) - elif opcode in 'fmsub': - if flen == 32: - rs2 = (ir_dataset[i][0] + rs3)/rs1 - elif flen == 64: - rs2 = (Decimal(ir_dataset[i][0]) + Decimal(rs3))/Decimal(rs1) - elif opcode in 'fnmsub': - if flen == 32: - rs2 = -1*(rs3 + ir_dataset[i][0])/rs1 - elif flen == 64: - rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) - - if(flen==32): - x1 = struct.unpack('f', struct.pack('f', rs1))[0] - x2 = struct.unpack('f', struct.pack('f', rs2))[0] - x3 = struct.unpack('f', struct.pack('f', rs3))[0] - elif(flen==64): - x1 = rs1 - x2 = rs2 - x3 = rs3 - - if opcode in ['fadd','fsub','fmul','fdiv']: - b5_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - elif opcode in 'fsqrt': - b5_comb.append((floatingPoint_tohex(flen,float(rs2)),)) - elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: - b5_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - - coverpoints = [] - k = 0 - for c in b5_comb: - for rm in range(5): - cvpt = "" - for x in range(1, ops+1): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == '+str(rm) - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += ir_dataset[k][1] - coverpoints.append(cvpt) - k=k+1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B5 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b6(flen, opcode, ops, seed=-1): - ''' - IBM Model B6 Definition: + ''' + + opcode = opcode.split('.')[0] + getcontext().prec = 40 + if iflen == 32: + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.000001p-126' + ir_dataset = [] + for i in range(0,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([ieee754_minsubnorm.split('p')[0]+str(i)+'p'+ieee754_minsubnorm.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minsubnorm + '+str(int(grs[0:3],2))+' ulp']) + ieee754_minnorm = '0x1.000000p-126' + for i in range(0,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([ieee754_minnorm.split('p')[0]+str(i)+'p'+ieee754_minnorm.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minnorm + '+str(int(grs[0:3],2))+' ulp']) + minnorm_Exp = ['0x1.000000p-126','0x1.000000p-125','0x1.000000p-124','0x1.000000p-123','0x1.000000p-122','0x1.000000p-121'] + for i in minnorm_Exp: + ir_dataset.append([i,' | Exponent = MinNorm.exp + '+str(126+int(i.split('p')[1]))]) + n = len(ir_dataset) + for i in range(n): + ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) + ir_dataset.append([-1*ir_dataset[i][0],ir_dataset[i][1]]) + + elif iflen == 64: + maxdec = '1.7976931348623157e+308' + maxnum = float.fromhex('0x1.fffffffffffffp+1023') + minsubdec = '5e-324' + ir_dataset = [] + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([str(Decimal(minsubdec.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+minsubdec.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minsubnorm + '+str(int(grs[0:3],2))+' ulp']) + minnormdec = '2.2250738585072014e-308' + ir_dataset.append([minsubdec, ' | Guard = 0 Round = 0 Sticky = 0 --> Minsubnorm + 0 ulp']) + ir_dataset.append([minnormdec,' | Guard = 0 Round = 0 Sticky = 0 --> Minnorm + 0 ulp']) + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([str(Decimal(minnormdec.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+minnormdec.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minnorm + '+str(int(grs[0:3],2))+' ulp']) + minnorm_Exp = ['4.450147717014403e-308','8.900295434028806e-308','1.780059086805761e-307','3.560118173611522e-307','7.120236347223044e-307'] + + k = 1 + for i in minnorm_Exp: + ir_dataset.append([i,' | Exponent = MinNorm.exp + '+str(k)]) + k += 1 + n = len(ir_dataset) + for i in range(n): + ir_dataset.append(['-'+ir_dataset[i][0],ir_dataset[i][1]]) + + if seed == -1: + if opcode in 'fadd': + random.seed(0) + elif opcode in 'fsub': + random.seed(1) + elif opcode in 'fmul': + random.seed(2) + elif opcode in 'fdiv': + random.seed(3) + elif opcode in 'fsqrt': + random.seed(4) + elif opcode in 'fmadd': + random.seed(5) + elif opcode in 'fnmadd': + random.seed(6) + elif opcode in 'fmsub': + random.seed(7) + elif opcode in 'fnmsub': + random.seed(8) + else: + random.seed(seed) + + b5_comb = [] + + for i in range(len(ir_dataset)): + rs1 = random.uniform(1,maxnum) + rs3 = random.uniform(1,maxnum) + if opcode in 'fadd': + if iflen == 32: + rs2 = ir_dataset[i][0] - rs1 + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0]) - Decimal(rs1) + elif opcode in 'fsub': + if iflen == 32: + rs2 = rs1 - ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(rs1) - Decimal(ir_dataset[i][0]) + elif opcode in 'fmul': + if iflen == 32: + rs2 = ir_dataset[i][0]/rs1 + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) + elif opcode in 'fdiv': + if iflen == 32: + rs2 = rs1/ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) + elif opcode in 'fsqrt': + if iflen == 32: + rs2 = ir_dataset[i][0]*ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])*Decimal(ir_dataset[i][0]) + elif opcode in 'fmadd': + if iflen == 32: + rs2 = (ir_dataset[i][0] - rs3)/rs1 + elif iflen == 64: + rs2 = (Decimal(ir_dataset[i][0]) - Decimal(rs3))/Decimal(rs1) + elif opcode in 'fnmadd': + if iflen == 32: + rs2 = (rs3 - ir_dataset[i][0])/rs1 + elif iflen == 64: + rs2 = (Decimal(rs3) - Decimal(ir_dataset[i][0]))/Decimal(rs1) + elif opcode in 'fmsub': + if iflen == 32: + rs2 = (ir_dataset[i][0] + rs3)/rs1 + elif iflen == 64: + rs2 = (Decimal(ir_dataset[i][0]) + Decimal(rs3))/Decimal(rs1) + elif opcode in 'fnmsub': + if iflen == 32: + rs2 = -1*(rs3 + ir_dataset[i][0])/rs1 + elif iflen == 64: + rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) + + if(iflen==32): + x1 = struct.unpack('f', struct.pack('f', rs1))[0] + x2 = struct.unpack('f', struct.pack('f', rs2))[0] + x3 = struct.unpack('f', struct.pack('f', rs3))[0] + elif(iflen==64): + x1 = rs1 + x2 = rs2 + x3 = rs3 + + if opcode in ['fadd','fsub','fmul','fdiv']: + b5_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + elif opcode in 'fsqrt': + b5_comb.append((floatingPoint_tohex(iflen,float(rs2)),)) + elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: + b5_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)),floatingPoint_tohex(iflen,float(rs3)))) + + coverpoints = [] + k = 0 + for c in b5_comb: + for rm in range(5): + cvpt = "" + for x in range(1, ops+1): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + # cvpt += 'rm_val == '+str(rm) + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += ir_dataset[k][1] + coverpoints.append(cvpt) + k=k+1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B5 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b6(flen, iflen, opcode, ops, seed=-1): + ''' + IBM Model B6 Definition: This model tests intermediate results in the space between –MinSubNorm and +MinSubNorm. For each of the following ranges, we select 8 random test cases, one for every combination of the LSB, guard bit, and sticky bit. @@ -1064,154 +1080,157 @@ def ibm_b6(flen, opcode, ops, seed=-1): 3. 0 < intermediate <= +MinSubNorm / 2 4. +MinSubNorm / 2 < intermediate < +MinSubNorm - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Intermediate Results = [Random number ∈ (-MinSubNorm, -MinSubNorm/2), Random number ∈ (-MinSubNorm/2, 0), Random number ∈ (0, +MinSubNorm/2), Random number ∈ (+MinSubNorm/2, +MinSubNorm)] {All 8 combinations of guard, round and sticky bit are tested for every number} Operand1 {operation} Operand2 = Intermediate Results - Implementation: + Implementation: - The intermediate results dataset is populated in accordance with the abstract dataset defined above. - Intermediate results can be out of the range of what is representable in the specified format; they should only be viewed numerically. Inorder to represent numbers that went out of range of the maximum representable number in python, the “Decimal” module was utilized. - These operand values are treated as decimal numbers until their derivation after which they are converted into their respective IEEE754 hexadecimal floating point formats using the “floatingPoint_tohex” function. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - opcode = opcode.split('.')[0] - getcontext().prec = 40 - - if seed == -1: - if opcode in 'fmul': - random.seed(0) - elif opcode in 'fdiv': - random.seed(1) - elif opcode in 'fmadd': - random.seed(2) - elif opcode in 'fnmadd': - random.seed(3) - elif opcode in 'fmsub': - random.seed(4) - elif opcode in 'fnmsub': - random.seed(5) - else: - random.seed(seed) - - if flen == 32: - ir_dataset = [] - ieee754_minsubnorm_n = '-0x0.000001p-127' - minnum = float.fromhex(ieee754_minsubnorm_n) - r=str(random.uniform(minnum,minnum/2)) - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-7)))+'e'+r.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (-MinSubNorm, -MinSubNorm / 2)']) - r=str(random.uniform(minnum/2,0)) - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-7)))+'e'+r.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (-MinSubNorm / 2, 0)']) - r=str(random.uniform(0,abs(minnum/2))) - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-7)))+'e'+r.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (0, +MinSubNorm / 2)']) - r=str(random.uniform(abs(minnum/2),abs(minnum))) - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-7)))+'e'+r.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (+MinSubNorm / 2, +MinSubNorm)']) - elif flen == 64: - ir_dataset = [] - ieee754_minsubnorm_n = '-0x0.0000000000001p-1022' - minnum = float.fromhex(ieee754_minsubnorm_n) - r=str("{:.2e}".format(random.uniform(minnum,minnum/2))) - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-14))),' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (-MinSubNorm, -MinSubNorm / 2)']) - r=str("{:.2e}".format(random.uniform(minnum/2,0))) - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-14))),' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (-MinSubNorm / 2, 0)']) - r=str("{:.2e}".format(random.uniform(0,abs(minnum/2)))) - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-14))),' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (0, +MinSubNorm / 2)']) - r=str("{:.2e}".format(random.uniform(abs(minnum/2),abs(minnum)))) - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-14))),' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (+MinSubNorm / 2, +MinSubNorm)']) - - b6_comb = [] - - for i in range(len(ir_dataset)): - rs1 = random.uniform(0,1e-30) - rs3 = random.uniform(0,1e-30) - - if opcode in 'fmul': - rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) - elif opcode in 'fdiv': - rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) - elif opcode in 'fmadd': - rs2 = (Decimal(ir_dataset[i][0]) - Decimal(rs3))/Decimal(rs1) - elif opcode in 'fnmadd': - rs2 = (Decimal(rs3) - Decimal(ir_dataset[i][0]))/Decimal(rs1) - elif opcode in 'fmsub': - rs2 = (Decimal(ir_dataset[i][0]) + Decimal(rs3))/Decimal(rs1) - elif opcode in 'fnmsub': - rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) - - if(flen==32): - x1 = struct.unpack('f', struct.pack('f', rs1))[0] - x2 = struct.unpack('f', struct.pack('f', rs2))[0] - x3 = struct.unpack('f', struct.pack('f', rs3))[0] - elif(flen==64): - x1 = rs1 - x2 = rs2 - x3 = rs3 - - if opcode in ['fmul','fdiv']: - b6_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: - b6_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - - #print(*b6_comb,sep='\n') - coverpoints = [] - k=0 - - for c in b6_comb: - for rm in range(5): - cvpt = "" - for x in range(1, ops+1): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == '+str(rm) - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += ir_dataset[k][1] - coverpoints.append(cvpt) - k=k+1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B6 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b7(flen, opcode, ops, seed=-1): - ''' - IBM Model B7 Definition: + ''' + opcode = opcode.split('.')[0] + getcontext().prec = 40 + + if seed == -1: + if opcode in 'fmul': + random.seed(0) + elif opcode in 'fdiv': + random.seed(1) + elif opcode in 'fmadd': + random.seed(2) + elif opcode in 'fnmadd': + random.seed(3) + elif opcode in 'fmsub': + random.seed(4) + elif opcode in 'fnmsub': + random.seed(5) + else: + random.seed(seed) + + if iflen == 32: + ir_dataset = [] + ieee754_minsubnorm_n = '-0x0.000001p-127' + minnum = float.fromhex(ieee754_minsubnorm_n) + r=str(random.uniform(minnum,minnum/2)) + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-7)))+'e'+r.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (-MinSubNorm, -MinSubNorm / 2)']) + r=str(random.uniform(minnum/2,0)) + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-7)))+'e'+r.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (-MinSubNorm / 2, 0)']) + r=str(random.uniform(0,abs(minnum/2))) + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-7)))+'e'+r.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (0, +MinSubNorm / 2)']) + r=str(random.uniform(abs(minnum/2),abs(minnum))) + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-7)))+'e'+r.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (+MinSubNorm / 2, +MinSubNorm)']) + elif iflen == 64: + ir_dataset = [] + ieee754_minsubnorm_n = '-0x0.0000000000001p-1022' + minnum = float.fromhex(ieee754_minsubnorm_n) + r=str("{:.2e}".format(random.uniform(minnum,minnum/2))) + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-14))),' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (-MinSubNorm, -MinSubNorm / 2)']) + r=str("{:.2e}".format(random.uniform(minnum/2,0))) + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-14))),' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (-MinSubNorm / 2, 0)']) + r=str("{:.2e}".format(random.uniform(0,abs(minnum/2)))) + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-14))),' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (0, +MinSubNorm / 2)']) + r=str("{:.2e}".format(random.uniform(abs(minnum/2),abs(minnum)))) + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-14))),' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (+MinSubNorm / 2, +MinSubNorm)']) + + b6_comb = [] + + for i in range(len(ir_dataset)): + rs1 = random.uniform(0,1e-30) + rs3 = random.uniform(0,1e-30) + + if opcode in 'fmul': + rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) + elif opcode in 'fdiv': + rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) + elif opcode in 'fmadd': + rs2 = (Decimal(ir_dataset[i][0]) - Decimal(rs3))/Decimal(rs1) + elif opcode in 'fnmadd': + rs2 = (Decimal(rs3) - Decimal(ir_dataset[i][0]))/Decimal(rs1) + elif opcode in 'fmsub': + rs2 = (Decimal(ir_dataset[i][0]) + Decimal(rs3))/Decimal(rs1) + elif opcode in 'fnmsub': + rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) + + if(iflen==32): + x1 = struct.unpack('f', struct.pack('f', rs1))[0] + x2 = struct.unpack('f', struct.pack('f', rs2))[0] + x3 = struct.unpack('f', struct.pack('f', rs3))[0] + elif(iflen==64): + x1 = rs1 + x2 = rs2 + x3 = rs3 + + if opcode in ['fmul','fdiv']: + b6_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: + b6_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)),floatingPoint_tohex(iflen,float(rs3)))) + + #print(*b6_comb,sep='\n') + coverpoints = [] + k=0 + + for c in b6_comb: + for rm in range(5): + cvpt = "" + for x in range(1, ops+1): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + cvpt = santise_cvpt(rm,cvpt,iflen,flen) + # cvpt += 'rm_val == '+str(rm) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += ir_dataset[k][1] + coverpoints.append(cvpt) + k=k+1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B6 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b7(flen, iflen, opcode, ops, seed=-1): + ''' + IBM Model B7 Definition: This model checks that the sticky bit is calculated correctly in each of the following cases (for every possible combination in the table). The Guard bit should always be 0, and the sign positive, so that miscalculation of the sticky bit will alter the final result. Mask in Extra bits @@ -1224,182 +1243,185 @@ def ibm_b7(flen, opcode, ops, seed=-1): 0000...001 0000000000 - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param flen: Size of the floating point registers + :param iflen: Size of the floating point source operands for the operation + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Intermediate Results = [ieee754_maxnorm, maxnum, maxdec, maxnum] {It assures the calculation of sticky bit for every possible combination in the table} Operand1 {operation} Operand2 = Intermediate Results - Implementation: + Implementation: - The Sticky bit is calculated in each case. The guard bit here is always assumed to be zero and the sign is positive, so that miscalculation of the sticky bit will alter the final result. - In the intermediate result dataset, the elements are appended as elements before the character ‘p’ and then the binary equivalent of ‘010’ + pow(2,i). - Finally on the extra bits, it is masked with the comment created in the previous point. All the first character of each element is converted to its floating point equivalent in a loop - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - opcode = opcode.split('.')[0] - getcontext().prec = 60 - if flen == 32: - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_num = [] - for i in fsubnorm+fnorm: - float_val = float.hex(fields_dec_converter(32,i)) - if float_val[0] != '-': - ieee754_num.append(float_val.split('p')[0][0:10]+'p'+float_val.split('p')[1]) - ir_dataset = [] - for k in range(len(ieee754_num)): - for i in range(0,20): - comment = (20-i)*'0' + '1' + i*'0' - ir_dataset.append([ieee754_num[k].split('p')[0]+hex(int('010'+'{:021b}'.format(pow(2,i)),2))[2:]+'p'+ieee754_num[k].split('p')[1],' | Mask on extra bits ---> ' + comment]) - n = len(ir_dataset) - for i in range(n): - ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) - - elif flen == 64: - maxdec = '1.7976931348623157e+308' - maxnum = float.fromhex('0x1.fffffffffffffp+1023') - ieee754_num = [] - for i in dsubnorm+dnorm: - float_val = fields_dec_converter(64,i) - if float_val > 0: - ieee754_num.append(str(float_val)) - - ir_dataset = [] - for l in range(len(ieee754_num)): - for k in range(1,13): - for i in range(4): - comment = (k*(i+1))*'0' + '1' + (51-(k*(i+1)))*'0' - ir_dataset.append([str(Decimal(ieee754_num[l].split('e')[0])+Decimal(pow(16,-14))+Decimal(pow(pow(2,3-i)*16,-14-k)))+'e'+ieee754_num[l].split('e')[1],' | Mask on extra bits ---> ' + comment]) - - if seed == -1: - if opcode in 'fadd': - random.seed(0) - elif opcode in 'fsub': - random.seed(1) - elif opcode in 'fmul': - random.seed(2) - elif opcode in 'fdiv': - random.seed(3) - elif opcode in 'fsqrt': - random.seed(4) - elif opcode in 'fmadd': - random.seed(5) - elif opcode in 'fnmadd': - random.seed(6) - elif opcode in 'fmsub': - random.seed(7) - elif opcode in 'fnmsub': - random.seed(8) - else: - random.seed(seed) - - b7_comb = [] - - for i in range(len(ir_dataset)): - rs1 = random.uniform(1,maxnum) - rs3 = random.uniform(1,maxnum) - if opcode in 'fadd': - if flen == 32: - rs2 = ir_dataset[i][0] - rs1 - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0]) - Decimal(rs1) - elif opcode in 'fsub': - if flen == 32: - rs2 = rs1 - ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(rs1) - Decimal(ir_dataset[i][0]) - elif opcode in 'fmul': - if flen == 32: - rs2 = ir_dataset[i][0]/rs1 - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) - elif opcode in 'fdiv': - if flen == 32: - rs2 = rs1/ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) - elif opcode in 'fsqrt': - if flen == 32: - rs2 = ir_dataset[i][0]*ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])*Decimal(ir_dataset[i][0]) - elif opcode in 'fmadd': - if flen == 32: - rs2 = (ir_dataset[i][0] - rs3)/rs1 - elif flen == 64: - rs2 = (Decimal(ir_dataset[i][0]) - Decimal(rs3))/Decimal(rs1) - elif opcode in 'fnmadd': - if flen == 32: - rs2 = (rs3 - ir_dataset[i][0])/rs1 - elif flen == 64: - rs2 = (Decimal(rs3) - Decimal(ir_dataset[i][0]))/Decimal(rs1) - elif opcode in 'fmsub': - if flen == 32: - rs2 = (ir_dataset[i][0] + rs3)/rs1 - elif flen == 64: - rs2 = (Decimal(ir_dataset[i][0]) + Decimal(rs3))/Decimal(rs1) - elif opcode in 'fnmsub': - if flen == 32: - rs2 = -1*(rs3 + ir_dataset[i][0])/rs1 - elif flen == 64: - rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) - - if(flen==32): - x1 = struct.unpack('f', struct.pack('f', rs1))[0] - x2 = struct.unpack('f', struct.pack('f', rs2))[0] - x3 = struct.unpack('f', struct.pack('f', rs3))[0] - elif(flen==64): - x1 = rs1 - x2 = rs2 - x3 = rs3 - - if opcode in ['fadd','fsub','fmul','fdiv']: - b7_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - elif opcode in 'fsqrt': - b7_comb.append((floatingPoint_tohex(flen,float(rs2)),)) - elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: - b7_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - - coverpoints = [] - k = 0 - for c in b7_comb: - cvpt = "" - for x in range(1, ops+1): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == 3' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += ir_dataset[k][1] - coverpoints.append(cvpt) - k=k+1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B7 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b8(flen, opcode, ops, seed=-1): - ''' - IBM Model B8 Definition: + ''' + opcode = opcode.split('.')[0] + getcontext().prec = 60 + if iflen == 32: + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_num = [] + for i in fsubnorm+fnorm: + float_val = float.hex(fields_dec_converter(32,i)) + if float_val[0] != '-': + ieee754_num.append(float_val.split('p')[0][0:10]+'p'+float_val.split('p')[1]) + ir_dataset = [] + for k in range(len(ieee754_num)): + for i in range(0,20): + comment = (20-i)*'0' + '1' + i*'0' + ir_dataset.append([ieee754_num[k].split('p')[0]+hex(int('010'+'{:021b}'.format(pow(2,i)),2))[2:]+'p'+ieee754_num[k].split('p')[1],' | Mask on extra bits ---> ' + comment]) + n = len(ir_dataset) + for i in range(n): + ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) + + elif iflen == 64: + maxdec = '1.7976931348623157e+308' + maxnum = float.fromhex('0x1.fffffffffffffp+1023') + ieee754_num = [] + for i in dsubnorm+dnorm: + float_val = fields_dec_converter(64,i) + if float_val > 0: + ieee754_num.append(str(float_val)) + + ir_dataset = [] + for l in range(len(ieee754_num)): + for k in range(1,13): + for i in range(4): + comment = (k*(i+1))*'0' + '1' + (51-(k*(i+1)))*'0' + ir_dataset.append([str(Decimal(ieee754_num[l].split('e')[0])+Decimal(pow(16,-14))+Decimal(pow(pow(2,3-i)*16,-14-k)))+'e'+ieee754_num[l].split('e')[1],' | Mask on extra bits ---> ' + comment]) + + if seed == -1: + if opcode in 'fadd': + random.seed(0) + elif opcode in 'fsub': + random.seed(1) + elif opcode in 'fmul': + random.seed(2) + elif opcode in 'fdiv': + random.seed(3) + elif opcode in 'fsqrt': + random.seed(4) + elif opcode in 'fmadd': + random.seed(5) + elif opcode in 'fnmadd': + random.seed(6) + elif opcode in 'fmsub': + random.seed(7) + elif opcode in 'fnmsub': + random.seed(8) + else: + random.seed(seed) + + b7_comb = [] + + for i in range(len(ir_dataset)): + rs1 = random.uniform(1,maxnum) + rs3 = random.uniform(1,maxnum) + if opcode in 'fadd': + if iflen == 32: + rs2 = ir_dataset[i][0] - rs1 + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0]) - Decimal(rs1) + elif opcode in 'fsub': + if iflen == 32: + rs2 = rs1 - ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(rs1) - Decimal(ir_dataset[i][0]) + elif opcode in 'fmul': + if iflen == 32: + rs2 = ir_dataset[i][0]/rs1 + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) + elif opcode in 'fdiv': + if iflen == 32: + rs2 = rs1/ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) + elif opcode in 'fsqrt': + if iflen == 32: + rs2 = ir_dataset[i][0]*ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])*Decimal(ir_dataset[i][0]) + elif opcode in 'fmadd': + if iflen == 32: + rs2 = (ir_dataset[i][0] - rs3)/rs1 + elif iflen == 64: + rs2 = (Decimal(ir_dataset[i][0]) - Decimal(rs3))/Decimal(rs1) + elif opcode in 'fnmadd': + if iflen == 32: + rs2 = (rs3 - ir_dataset[i][0])/rs1 + elif iflen == 64: + rs2 = (Decimal(rs3) - Decimal(ir_dataset[i][0]))/Decimal(rs1) + elif opcode in 'fmsub': + if iflen == 32: + rs2 = (ir_dataset[i][0] + rs3)/rs1 + elif iflen == 64: + rs2 = (Decimal(ir_dataset[i][0]) + Decimal(rs3))/Decimal(rs1) + elif opcode in 'fnmsub': + if iflen == 32: + rs2 = -1*(rs3 + ir_dataset[i][0])/rs1 + elif iflen == 64: + rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) + + if(iflen==32): + x1 = struct.unpack('f', struct.pack('f', rs1))[0] + x2 = struct.unpack('f', struct.pack('f', rs2))[0] + x3 = struct.unpack('f', struct.pack('f', rs3))[0] + elif(iflen==64): + x1 = rs1 + x2 = rs2 + x3 = rs3 + + if opcode in ['fadd','fsub','fmul','fdiv']: + b7_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + elif opcode in 'fsqrt': + b7_comb.append((floatingPoint_tohex(iflen,float(rs2)),)) + elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: + b7_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)),floatingPoint_tohex(iflen,float(rs3)))) + + coverpoints = [] + k = 0 + for c in b7_comb: + cvpt = "" + for x in range(1, ops+1): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + # cvpt += 'rm_val == 3' + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += ir_dataset[k][1] + coverpoints.append(cvpt) + k=k+1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B7 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b8(flen, iflen, opcode, ops, seed=-1): + ''' + IBM Model B8 Definition: This model targets numbers that are on the edge of a rounding boundary. These boundaries may vary depending on the rounding mode. These numbers include floating-point numbers and midpoints between floating-point numbers. In order to target the vicinity of these numbers, we test the following constraints on the extra bits of the intermediate result: 1. All values of extra-bits in the range [000...00001, 000...00011] @@ -1407,188 +1429,191 @@ def ibm_b8(flen, opcode, ops, seed=-1): For each value selected above, test all the combinations on the LSB of the significand, the guard bit, and the sticky bit (if the number of extra bits is not finite). - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Intermediate Results = [For every Subnormal and Normal number, 8 combinations of guard, round and sticky bit are appended, along with 6 combinations(3 positive, 3 negative) of the mask on extra bits] Operand1 {operation} Operand2 = Intermediate Results - Implementation: + Implementation: - The intermediate results dataset is populated in accordance with the abstract dataset defined above. The coverpoints can be increased by increasing the dataset of normal and subnormal numbers. - Intermediate results can be out of the range of what is representable in the specified format; they should only be viewed numerically. Inorder to represent numbers that went out of range of the maximum representable number in python, the “Decimal” module was utilized. - These operand values are treated as decimal numbers until their derivation after which they are converted into their respective IEEE754 hexadecimal floating point formats using the “floatingPoint_tohex” function. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - opcode = opcode.split('.')[0] - getcontext().prec = 60 - if flen == 32: - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_num = [] - for i in fsubnorm+fnorm: - float_val = float.hex(fields_dec_converter(32,i)) - if float_val[0] != '-': - ieee754_num.append(float_val.split('p')[0][0:10]+'p'+float_val.split('p')[1]) - ir_dataset = [] - # print(*ieee754_num, sep = '\n') - for k in range(len(ieee754_num)): - for i in range(1,4): - for j in range(1,8): - grs = '{:03b}'.format(j) - ir_dataset.append([ieee754_num[k].split('p')[0]+hex(int('{:03b}'.format(j)+19*'0'+'{:02b}'.format(i),2))[2:]+'p'+ieee754_num[k].split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Mask On Extra Bits: '+19*'0'+'{:02b}'.format(i)]) - ir_dataset.append([ieee754_num[k].split('p')[0]+hex(int('{:03b}'.format(j)+19*'1'+'{:02b}'.format(i),2))[2:]+'p'+ieee754_num[k].split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Mask On Extra Bits: '+19*'1'+'{:02b}'.format(i)]) - n = len(ir_dataset) - for i in range(n): - ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) - - elif flen == 64: - maxdec = '1.7976931348623157e+308' - maxnum = float.fromhex('0x1.fffffffffffffp+1023') - ieee754_num = [] - for i in dsubnorm+dnorm: - float_val = float.hex(fields_dec_converter(64,i)) - if float_val[0] != '-': - ieee754_num.append(float_val.split('p')[0][0:17]+'p'+float_val.split('p')[1]) - ir_dataset = [] - for k in range(len(ieee754_num)): - for i in range(1,4): - for j in range(1,8): - grs = '{:03b}'.format(j) - ir_dataset.append([ieee754_num[k].split('p')[0]+hex(int('010'+19*'0'+'{:02b}'.format(i),2))[2:]+'p'+ieee754_num[k].split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Mask On Extra Bits: '+19*'0'+'{:02b}'.format(i)]) - ir_dataset.append([ieee754_num[k].split('p')[0]+hex(int('010'+19*'1'+'{:02b}'.format(i),2))[2:]+'p'+ieee754_num[k].split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Mask On Extra Bits: '+19*'1'+'{:02b}'.format(i)]) - n = len(ir_dataset) - for i in range(n): - ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) - - if seed == -1: - if opcode in 'fadd': - random.seed(0) - elif opcode in 'fsub': - random.seed(1) - elif opcode in 'fmul': - random.seed(2) - elif opcode in 'fdiv': - random.seed(3) - elif opcode in 'fsqrt': - random.seed(4) - elif opcode in 'fmadd': - random.seed(5) - elif opcode in 'fnmadd': - random.seed(6) - elif opcode in 'fmsub': - random.seed(7) - elif opcode in 'fnmsub': - random.seed(8) - else: - random.seed(seed) - - b8_comb = [] - - for i in range(len(ir_dataset)): - rs1 = random.uniform(1,ir_dataset[i][0]) - rs3 = random.uniform(1,ir_dataset[i][0]) - if opcode in 'fadd': - if flen == 32: - rs2 = ir_dataset[i][0] - rs1 - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0]) - Decimal(rs1) - elif opcode in 'fsub': - if flen == 32: - rs2 = rs1 - ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(rs1) - Decimal(ir_dataset[i][0]) - elif opcode in 'fmul': - if flen == 32: - rs2 = ir_dataset[i][0]/rs1 - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) - elif opcode in 'fdiv': - if flen == 32: - rs2 = rs1/ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) - elif opcode in 'fsqrt': - if flen == 32: - rs2 = ir_dataset[i][0]*ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])*Decimal(ir_dataset[i][0]) - elif opcode in 'fmadd': - if flen == 32: - rs2 = (ir_dataset[i][0] - rs3)/rs1 - elif flen == 64: - rs2 = (Decimal(ir_dataset[i][0]) - Decimal(rs3))/Decimal(rs1) - elif opcode in 'fnmadd': - if flen == 32: - rs2 = (rs3 - ir_dataset[i][0])/rs1 - elif flen == 64: - rs2 = (Decimal(rs3) - Decimal(ir_dataset[i][0]))/Decimal(rs1) - elif opcode in 'fmsub': - if flen == 32: - rs2 = (ir_dataset[i][0] + rs3)/rs1 - elif flen == 64: - rs2 = (Decimal(ir_dataset[i][0]) + Decimal(rs3))/Decimal(rs1) - elif opcode in 'fnmsub': - if flen == 32: - rs2 = -1*(rs3 + ir_dataset[i][0])/rs1 - elif flen == 64: - rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) - - if(flen==32): - x1 = struct.unpack('f', struct.pack('f', rs1))[0] - x2 = struct.unpack('f', struct.pack('f', rs2))[0] - x3 = struct.unpack('f', struct.pack('f', rs3))[0] - elif(flen==64): - x1 = rs1 - x2 = rs2 - x3 = rs3 - - if opcode in ['fadd','fsub','fmul','fdiv']: - b8_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - elif opcode in 'fsqrt': - b8_comb.append((floatingPoint_tohex(flen,float(rs2)),)) - elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: - b8_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - - coverpoints = [] - k=0 - for c in b8_comb: - for rm in range(5): - cvpt = "" - for x in range(1, ops+1): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == '+str(rm) - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += ir_dataset[k][1] - coverpoints.append(cvpt) - k=k+1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B8 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b9(flen, opcode, ops): - ''' - IBM Model B9 Definition: + ''' + opcode = opcode.split('.')[0] + getcontext().prec = 60 + if iflen == 32: + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_num = [] + for i in fsubnorm+fnorm: + float_val = float.hex(fields_dec_converter(32,i)) + if float_val[0] != '-': + ieee754_num.append(float_val.split('p')[0][0:10]+'p'+float_val.split('p')[1]) + ir_dataset = [] + # print(*ieee754_num, sep = '\n') + for k in range(len(ieee754_num)): + for i in range(1,4): + for j in range(1,8): + grs = '{:03b}'.format(j) + ir_dataset.append([ieee754_num[k].split('p')[0]+hex(int('{:03b}'.format(j)+19*'0'+'{:02b}'.format(i),2))[2:]+'p'+ieee754_num[k].split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Mask On Extra Bits: '+19*'0'+'{:02b}'.format(i)]) + ir_dataset.append([ieee754_num[k].split('p')[0]+hex(int('{:03b}'.format(j)+19*'1'+'{:02b}'.format(i),2))[2:]+'p'+ieee754_num[k].split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Mask On Extra Bits: '+19*'1'+'{:02b}'.format(i)]) + n = len(ir_dataset) + for i in range(n): + ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) + + elif iflen == 64: + maxdec = '1.7976931348623157e+308' + maxnum = float.fromhex('0x1.fffffffffffffp+1023') + ieee754_num = [] + for i in dsubnorm+dnorm: + float_val = float.hex(fields_dec_converter(64,i)) + if float_val[0] != '-': + ieee754_num.append(float_val.split('p')[0][0:17]+'p'+float_val.split('p')[1]) + ir_dataset = [] + for k in range(len(ieee754_num)): + for i in range(1,4): + for j in range(1,8): + grs = '{:03b}'.format(j) + ir_dataset.append([ieee754_num[k].split('p')[0]+hex(int('010'+19*'0'+'{:02b}'.format(i),2))[2:]+'p'+ieee754_num[k].split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Mask On Extra Bits: '+19*'0'+'{:02b}'.format(i)]) + ir_dataset.append([ieee754_num[k].split('p')[0]+hex(int('010'+19*'1'+'{:02b}'.format(i),2))[2:]+'p'+ieee754_num[k].split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Mask On Extra Bits: '+19*'1'+'{:02b}'.format(i)]) + n = len(ir_dataset) + for i in range(n): + ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) + + if seed == -1: + if opcode in 'fadd': + random.seed(0) + elif opcode in 'fsub': + random.seed(1) + elif opcode in 'fmul': + random.seed(2) + elif opcode in 'fdiv': + random.seed(3) + elif opcode in 'fsqrt': + random.seed(4) + elif opcode in 'fmadd': + random.seed(5) + elif opcode in 'fnmadd': + random.seed(6) + elif opcode in 'fmsub': + random.seed(7) + elif opcode in 'fnmsub': + random.seed(8) + else: + random.seed(seed) + + b8_comb = [] + + for i in range(len(ir_dataset)): + rs1 = random.uniform(1,ir_dataset[i][0]) + rs3 = random.uniform(1,ir_dataset[i][0]) + if opcode in 'fadd': + if iflen == 32: + rs2 = ir_dataset[i][0] - rs1 + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0]) - Decimal(rs1) + elif opcode in 'fsub': + if iflen == 32: + rs2 = rs1 - ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(rs1) - Decimal(ir_dataset[i][0]) + elif opcode in 'fmul': + if iflen == 32: + rs2 = ir_dataset[i][0]/rs1 + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) + elif opcode in 'fdiv': + if iflen == 32: + rs2 = rs1/ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) + elif opcode in 'fsqrt': + if iflen == 32: + rs2 = ir_dataset[i][0]*ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])*Decimal(ir_dataset[i][0]) + elif opcode in 'fmadd': + if iflen == 32: + rs2 = (ir_dataset[i][0] - rs3)/rs1 + elif iflen == 64: + rs2 = (Decimal(ir_dataset[i][0]) - Decimal(rs3))/Decimal(rs1) + elif opcode in 'fnmadd': + if iflen == 32: + rs2 = (rs3 - ir_dataset[i][0])/rs1 + elif iflen == 64: + rs2 = (Decimal(rs3) - Decimal(ir_dataset[i][0]))/Decimal(rs1) + elif opcode in 'fmsub': + if iflen == 32: + rs2 = (ir_dataset[i][0] + rs3)/rs1 + elif iflen == 64: + rs2 = (Decimal(ir_dataset[i][0]) + Decimal(rs3))/Decimal(rs1) + elif opcode in 'fnmsub': + if iflen == 32: + rs2 = -1*(rs3 + ir_dataset[i][0])/rs1 + elif iflen == 64: + rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) + + if(iflen==32): + x1 = struct.unpack('f', struct.pack('f', rs1))[0] + x2 = struct.unpack('f', struct.pack('f', rs2))[0] + x3 = struct.unpack('f', struct.pack('f', rs3))[0] + elif(iflen==64): + x1 = rs1 + x2 = rs2 + x3 = rs3 + + if opcode in ['fadd','fsub','fmul','fdiv']: + b8_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + elif opcode in 'fsqrt': + b8_comb.append((floatingPoint_tohex(iflen,float(rs2)),)) + elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: + b8_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)),floatingPoint_tohex(iflen,float(rs3)))) + + coverpoints = [] + k=0 + for c in b8_comb: + for rm in range(5): + cvpt = "" + for x in range(1, ops+1): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + # cvpt += 'rm_val == '+str(rm) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += ir_dataset[k][1] + coverpoints.append(cvpt) + k=k+1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B8 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b9(flen, iflen, opcode, ops): + ''' + IBM Model B9 Definition: This model tests special patterns in the significands of the input operands. Each of the input operands should contain one of the following patterns (each sequence can be of length 0 up to the number of bits in the significand – the @@ -1604,295 +1629,301 @@ def ibm_b9(flen, opcode, ops): 8. Long sequences of 1s 9. Long sequences of 0s - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode - :type flen: int - :type opcode: str - :type ops: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int - Abstract Dataset Description: + Abstract Dataset Description: Operand1, Operand2 ∈ [A sequence of leading zeroes, A sequence of leading ones, A sequence of trailing zeroes, A sequence of trailing ones, A small number of 1s as compared to 0s, A small number of 0s as compared to 1s, A "checkerboard" pattern (for example 00110011... or 011011011...), Long sequences of 1s, Long sequences of 0s] - Implementation: + Implementation: - The rs1 array is appended with the elements of flip types and then for each iteration, the respective sign, mantissa and exponent is computed. - A nested loop is initialized, assuming the rs1 mantissa as the base number and rs2 sign and rs2 exponent is obtained directly from the rs1 sign and rs1 exponent. Rs2 mantissa is calculated by adding the iteration number in the beginning of rs1 mantissa. This is done respectively for each repeating pattern. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - opcode = opcode.split('.')[0] - - if flen == 32: - flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm - e_sz=8 - elif flen == 64: - flip_types = dzero + done + dminsubnorm + dmaxsubnorm + dminnorm + dmaxnorm - e_sz=11 - - rs1 = [] - b9_comb = [] - comment = [] - if ops == 2: - for i in range(len(flip_types)): - rs1.append(flip_types[i]) - for i in range(len(rs1)): - bin_val = bin(int('1'+rs1[i][2:],16))[3:] - rs1_sgn = bin_val[0] - rs1_exp = bin_val[1:e_sz+1] - rs1_man = bin_val[e_sz+1:] - - for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = '0'*j + rs1_man[j:] # Leading 0s - rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b9_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(' | Leading zeroes ---> rs2_man = '+rs2_man) - b9_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(' | Leading zeroes ---> rs1_man = '+rs2_man) - - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s - rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b9_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(' | Leading ones ---> rs2_man = '+rs2_man) - b9_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(' | Leading ones ---> rs1_man = '+rs2_man) - - rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s - rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b9_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(' | Trailing zeroes ---> rs2_man = '+rs2_man) - b9_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(' | Trailing zeroes ---> rs1_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s - rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b9_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(' | Trailing ones ---> rs2_man = '+rs2_man) - b9_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(' | Trailing ones ---> rs1_man = '+rs2_man) - - for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s - rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b9_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(' | Long sequence of ones ---> rs2_man = '+rs2_man) - b9_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(' | Long sequence of ones ---> rs1_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s - rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b9_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(' | Long sequence of zeroes ---> rs2_man = '+rs2_man) - b9_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(' | Long sequence of zeroes ---> rs1_man = '+rs2_man) - - chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] - for j in chkrbrd: - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = j - for k in range(math.ceil(len(rs1_man)/len(j))): - rs2_man += j - rs2_man = rs2_man[0:flen-e_sz-1] - rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b9_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(' | Checkerboard pattern ---> rs2_man = '+rs2_man) - b9_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(' | Checkerboard pattern ---> rs1_man = '+rs2_man) - - else: - for i in range(len(flip_types)): - rs1.append(flip_types[i]) - for i in range(len(rs1)): - bin_val = bin(int('1'+rs1[i][2:],16))[3:] - rs1_sgn = bin_val[0] - rs1_exp = bin_val[1:e_sz+1] - rs1_man = bin_val[e_sz+1:] - - if rs1_sgn != '1': - for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = '0'*j + rs1_man[j:] # Leading 0s - rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b9_comb.append((floatingPoint_tohex(flen,rs2),)) - comment.append(' | Leading zeroes ---> rs1_man = '+rs2_man) - - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s - rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b9_comb.append((floatingPoint_tohex(flen,rs2),)) - comment.append(' | Leading ones ---> rs1_man = '+rs2_man) - - rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s - rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b9_comb.append((floatingPoint_tohex(flen,rs2),)) - comment.append(' | Trailing zeroes ---> rs1_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s - rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b9_comb.append((floatingPoint_tohex(flen,rs2),)) - comment.append(' | Trailing ones ---> rs1_man = '+rs2_man) - rs1_sgn = '0' - for j in range(flen-e_sz-1-math.ceil(0.1*(flen-e_sz-1)), flen-e_sz-1): - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s - rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b9_comb.append((floatingPoint_tohex(flen,rs2),)) - comment.append(' | Long sequence of ones ---> rs1_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s - rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b9_comb.append((floatingPoint_tohex(flen,rs2),)) - comment.append(' | Long sequence of zeroes ---> rs1_man = '+rs2_man) - - chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] - for j in chkrbrd: - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = j - for k in range(math.ceil(len(rs1_man)/len(j))): - rs2_man += j - rs2_man = rs2_man[0:flen-e_sz-1] - rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b9_comb.append((floatingPoint_tohex(flen,rs2),)) - comment.append(' | Checkerboard pattern ---> rs1_man = '+rs2_man) - - coverpoints = [] - k = 0 - for c in b9_comb: - cvpt = "" - for x in range(1, ops+1): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += comment[k] - coverpoints.append(cvpt) - k += 1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B9 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b10(flen, opcode, ops, N=-1, seed=-1): - ''' - IBM Model B10 Definition: + ''' + opcode = opcode.split('.')[0] + + if iflen == 32: + flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm + e_sz=8 + elif iflen == 64: + flip_types = dzero + done + dminsubnorm + dmaxsubnorm + dminnorm + dmaxnorm + e_sz=11 + + rs1 = [] + b9_comb = [] + comment = [] + if ops == 2: + for i in range(len(flip_types)): + rs1.append(flip_types[i]) + for i in range(len(rs1)): + bin_val = bin(int('1'+rs1[i][2:],16))[3:] + rs1_sgn = bin_val[0] + rs1_exp = bin_val[1:e_sz+1] + rs1_man = bin_val[e_sz+1:] + + for j in range(len(rs1_man)): + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = '0'*j + rs1_man[j:] # Leading 0s + rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b9_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(' | Leading zeroes ---> rs2_man = '+rs2_man) + b9_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(' | Leading zeroes ---> rs1_man = '+rs2_man) + + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s + rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b9_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(' | Leading ones ---> rs2_man = '+rs2_man) + b9_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(' | Leading ones ---> rs1_man = '+rs2_man) + + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s + rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b9_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(' | Trailing zeroes ---> rs2_man = '+rs2_man) + b9_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(' | Trailing zeroes ---> rs1_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s + rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b9_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(' | Trailing ones ---> rs2_man = '+rs2_man) + b9_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(' | Trailing ones ---> rs1_man = '+rs2_man) + + for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s + rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b9_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(' | Long sequence of ones ---> rs2_man = '+rs2_man) + b9_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(' | Long sequence of ones ---> rs1_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s + rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b9_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(' | Long sequence of zeroes ---> rs2_man = '+rs2_man) + b9_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(' | Long sequence of zeroes ---> rs1_man = '+rs2_man) + + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] + for j in chkrbrd: + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = j + for k in range(math.ceil(len(rs1_man)/len(j))): + rs2_man += j + rs2_man = rs2_man[0:iflen-e_sz-1] + rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b9_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(' | Checkerboard pattern ---> rs2_man = '+rs2_man) + b9_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(' | Checkerboard pattern ---> rs1_man = '+rs2_man) + + else: + for i in range(len(flip_types)): + rs1.append(flip_types[i]) + for i in range(len(rs1)): + bin_val = bin(int('1'+rs1[i][2:],16))[3:] + rs1_sgn = bin_val[0] + rs1_exp = bin_val[1:e_sz+1] + rs1_man = bin_val[e_sz+1:] + + if rs1_sgn != '1': + for j in range(len(rs1_man)): + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = '0'*j + rs1_man[j:] # Leading 0s + rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b9_comb.append((floatingPoint_tohex(iflen,rs2),)) + comment.append(' | Leading zeroes ---> rs1_man = '+rs2_man) + + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s + rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b9_comb.append((floatingPoint_tohex(iflen,rs2),)) + comment.append(' | Leading ones ---> rs1_man = '+rs2_man) + + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s + rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b9_comb.append((floatingPoint_tohex(iflen,rs2),)) + comment.append(' | Trailing zeroes ---> rs1_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s + rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b9_comb.append((floatingPoint_tohex(iflen,rs2),)) + comment.append(' | Trailing ones ---> rs1_man = '+rs2_man) + rs1_sgn = '0' + for j in range(iflen-e_sz-1-math.ceil(0.1*(iflen-e_sz-1)), iflen-e_sz-1): + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s + rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b9_comb.append((floatingPoint_tohex(iflen,rs2),)) + comment.append(' | Long sequence of ones ---> rs1_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s + rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b9_comb.append((floatingPoint_tohex(iflen,rs2),)) + comment.append(' | Long sequence of zeroes ---> rs1_man = '+rs2_man) + + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] + for j in chkrbrd: + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = j + for k in range(math.ceil(len(rs1_man)/len(j))): + rs2_man += j + rs2_man = rs2_man[0:iflen-e_sz-1] + rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b9_comb.append((floatingPoint_tohex(iflen,rs2),)) + comment.append(' | Checkerboard pattern ---> rs1_man = '+rs2_man) + + coverpoints = [] + k = 0 + for c in b9_comb: + cvpt = "" + for x in range(1, ops+1): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + # cvpt += 'rm_val == 0' + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += comment[k] + coverpoints.append(cvpt) + k += 1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B9 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b10(flen, iflen, opcode, ops, N=-1, seed=-1): + ''' + IBM Model B10 Definition: This model tests every possible value for a shift between the input operands. 1. A value smaller than -(p + 4) 2. All the values in the range [-(p + 4) , (p + 4)] 3. A value larger than (p + 4) - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param N: No. of sets of coverpoints to be generated. (Predefined to -1. Set to 2) - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - - :type flen: int - :type opcode: str - :type ops: int - :type N: int - :param seed: int - - Abstract Dataset Description: + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param N: No. of sets of coverpoints to be generated. (Predefined to -1. Set to 2) + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :type N: int + :param seed: int + + Abstract Dataset Description: Operand1 = [Random Number] Operand2 = [A value smaller than -(op1.exp+4), All values in the range [-(op1.exp+4), (op1.exp+4)], A value larger than +(op1.exp+4)] - Implementation: + Implementation: - The exponent values of operand 1 and operand 2 obey the shift defined above. The mantissa value is randomly chosen and appended with the exponent derived. - Simultaneously, we convert these numbers into their corresponding IEEE754 floating point formats. - These operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with rounding mode ‘0’ for that particular opcode. - ''' - opcode = opcode.split('.')[0] - - if flen == 32: - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - exp_max = 255 - elif flen == 64: - maxdec = '1.7976931348623157e+308' - maxnum = float.fromhex('0x1.fffffffffffffp+1023') - exp_max = 1023 - - if N == -1: - N = 2 - - if seed == -1: - if opcode in 'fadd': - random.seed(0) - elif opcode in 'fsub': - random.seed(1) - else: - random.seed(seed) - - b10_comb = [] - comment = [] - for i in range(1,N): - rs1 = random.uniform(1,maxnum/1000) - rs2 = random.uniform(1,maxnum/1000) - rs1_exp = str(rs1).split('e')[1] - - rs2_exp = -1*random.randrange(int(math.log(pow(10,int(rs1_exp)),2))+4, exp_max) - rs2_num = str(rs2).split('e')[0] + 'e' + str(int(math.log(pow(2,int(rs2_exp)),10))) - b10_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2_num)))) - comment.append(' | Exponent = '+ str(rs2_exp) + ' --> A value smaller than -(p + 4)') - - for j in range(-(int(math.log(pow(10,int(rs1_exp)),2))+4),+(int(math.log(pow(10,int(rs1_exp)),2))+4)): - rs2_num = str(rs2).split('e')[0] + 'e' + str(int(math.log(pow(2,int(j)),10))) - b10_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2_num)))) - comment.append(' | Exponent = '+ str(j) + ' --> Values in the range [-(p + 4) , (p + 4)]') - - rs2_exp = random.randrange(int(math.log(pow(10,int(rs1_exp)),2))+4, exp_max) - rs2_num = str(rs2).split('e')[0] + 'e' + str(int(math.log(pow(2,int(rs2_exp)),10))) - b10_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2_num)))) - comment.append(' | Exponent = '+ str(rs2_exp) + ' --> A value larger than (p + 4)') - - coverpoints = [] - k = 0 - for c in b10_comb: - cvpt = "" - for x in range(1, ops+1): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += comment[k] - coverpoints.append(cvpt) - k += 1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B10 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b11(flen, opcode, ops, N=-1, seed=-1): - ''' - IBM Model B11 Definition: + ''' + opcode = opcode.split('.')[0] + + if iflen == 32: + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + exp_max = 255 + elif iflen == 64: + maxdec = '1.7976931348623157e+308' + maxnum = float.fromhex('0x1.fffffffffffffp+1023') + exp_max = 1023 + + if N == -1: + N = 2 + + if seed == -1: + if opcode in 'fadd': + random.seed(0) + elif opcode in 'fsub': + random.seed(1) + else: + random.seed(seed) + + b10_comb = [] + comment = [] + for i in range(1,N): + rs1 = random.uniform(1,maxnum/1000) + rs2 = random.uniform(1,maxnum/1000) + rs1_exp = str(rs1).split('e')[1] + + rs2_exp = -1*random.randrange(int(math.log(pow(10,int(rs1_exp)),2))+4, exp_max) + rs2_num = str(rs2).split('e')[0] + 'e' + str(int(math.log(pow(2,int(rs2_exp)),10))) + b10_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2_num)))) + comment.append(' | Exponent = '+ str(rs2_exp) + ' --> A value smaller than -(p + 4)') + + for j in range(-(int(math.log(pow(10,int(rs1_exp)),2))+4),+(int(math.log(pow(10,int(rs1_exp)),2))+4)): + rs2_num = str(rs2).split('e')[0] + 'e' + str(int(math.log(pow(2,int(j)),10))) + b10_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2_num)))) + comment.append(' | Exponent = '+ str(j) + ' --> Values in the range [-(p + 4) , (p + 4)]') + + rs2_exp = random.randrange(int(math.log(pow(10,int(rs1_exp)),2))+4, exp_max) + rs2_num = str(rs2).split('e')[0] + 'e' + str(int(math.log(pow(2,int(rs2_exp)),10))) + b10_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2_num)))) + comment.append(' | Exponent = '+ str(rs2_exp) + ' --> A value larger than (p + 4)') + + coverpoints = [] + k = 0 + for c in b10_comb: + cvpt = "" + for x in range(1, ops+1): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + # cvpt += 'rm_val == 0' + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += comment[k] + coverpoints.append(cvpt) + k += 1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B10 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b11(flen, iflen, opcode, ops, N=-1, seed=-1): + ''' + IBM Model B11 Definition: In this model we test the combination of different shift values between the inputs, with special patterns in the significands of the inputs. Significands of Input1 and Input2: as in model (B9) "Special Significands on @@ -1901,502 +1932,511 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): Shift: as in model (B10) "Shift - Add" We test both effective operations: addition and subtraction. - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Operand1, Operand2 ∈ Abstract Dataset in B9 + Abstract Dataset in B10 - Implementation: + Implementation: - A culmination of the techniques used in the implementations of Model B9 and Model B10 are used to form the dataset. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - opcode = opcode.split('.')[0] - - if flen == 32: - flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm - e_sz=8 - exp_max = 255 - elif flen == 64: - flip_types = dzero + done + dminsubnorm + dmaxsubnorm + dminnorm + dmaxnorm - e_sz=11 - exp_max = 1023 - - if seed == -1: - if opcode in 'fadd': - random.seed(0) - elif opcode in 'fsub': - random.seed(1) - else: - random.seed(seed) - - rs1 = [] - b11_comb = [] - comment = [] - if ops == 2: - for i in range(len(flip_types)): - rs1.append(flip_types[i]) - for i in range(len(rs1)): - bin_val = bin(int('1'+rs1[i][2:],16))[3:] - rs1_sgn = bin_val[0] - rs1_exp = bin_val[1:e_sz+1] - rs1_man = bin_val[e_sz+1:] - - if int(rs1_exp,2) < 4: rs2_exp = -127 - else : rs2_exp = random.randrange(-127,int(rs1_exp,2)-131) - comment_str = ' | Exponent = '+ str(rs2_exp) + ' --> A value smaller than (p - 4)' - rs2_exp += 127 - if flen == 32: rs2_exp = '{:08b}'.format(rs2_exp) - elif flen == 64: rs2_exp = '{:011b}'.format(rs2_exp) - for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn - rs2_man = '0'*j + rs1_man[j:] # Leading 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Leading zeroes ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Leading zeroes ---> rs1_man = '+rs2_man) - - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Leading ones ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Leading ones ---> rs1_man = '+rs2_man) - - rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Trailing zeroes ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Trailing zeroes ---> rs1_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Trailing ones ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Trailing ones ---> rs1_man = '+rs2_man) - - for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Long sequence of ones ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Long sequence of ones ---> rs1_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Long sequence of zeroes ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Long sequence of zeroes ---> rs1_man = '+rs2_man) - - chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] - for j in chkrbrd: - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = j - for k in range(math.ceil(len(rs1_man)/len(j))): - rs2_man += j - rs2_man = rs2_man[0:flen-e_sz-1] - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Checkerboard pattern ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Checkerboard pattern ---> rs1_man = '+rs2_man) - - if int(rs1_exp,2) >= 250: rs2_exp = 127 - else : rs2_exp = random.randrange(int(rs1_exp,2)-123,127) - comment_str = ' | Exponent = '+ str(rs2_exp) + ' --> A value greater than (p + 4)' - rs2_exp += 127 - if flen == 32: rs2_exp = '{:08b}'.format(rs2_exp) - elif flen == 64: rs2_exp = '{:011b}'.format(rs2_exp) - for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn - rs2_man = '0'*j + rs1_man[j:] # Leading 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Leading zeroes ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Leading zeroes ---> rs1_man = '+rs2_man) - - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Leading ones ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Leading ones ---> rs1_man = '+rs2_man) - - rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Trailing zeroes ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Trailing zeroes ---> rs1_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Trailing ones ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Trailing ones ---> rs1_man = '+rs2_man) - - for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Long sequence of ones ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Long sequence of ones ---> rs1_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Long sequence of zeroes ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Long sequence of zeroes ---> rs1_man = '+rs2_man) - - chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] - for j in chkrbrd: - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = j - for k in range(math.ceil(len(rs1_man)/len(j))): - rs2_man += j - rs2_man = rs2_man[0:flen-e_sz-1] - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Checkerboard pattern ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Checkerboard pattern ---> rs1_man = '+rs2_man) - - ul = int(rs1_exp,2)-123 - ll = int(rs1_exp,2)-131 - if int(rs1_exp,2) >= 250: ul = 127 - if int(rs1_exp,2) < 4: ll = -127 - for expval in range (ll, ul): - rs2_exp = expval - comment_str = ' | Exponent = '+ str(rs2_exp) + ' --> Values in the range (p - 4) to (p + 4)' - rs2_exp += 127 - if flen == 32: rs2_exp = '{:08b}'.format(rs2_exp) - elif flen == 64: rs2_exp = '{:011b}'.format(rs2_exp) - for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn - rs2_man = '0'*j + rs1_man[j:] # Leading 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Leading zeroes ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Leading zeroes ---> rs1_man = '+rs2_man) - - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Leading ones ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Leading ones ---> rs1_man = '+rs2_man) - - rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Trailing zeroes ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Trailing zeroes ---> rs1_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Trailing ones ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Trailing ones ---> rs1_man = '+rs2_man) - - for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Long sequence of ones ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Long sequence of ones ---> rs1_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Long sequence of zeroes ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Long sequence of zeroes ---> rs1_man = '+rs2_man) - - chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] - for j in chkrbrd: - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = j - for k in range(math.ceil(len(rs1_man)/len(j))): - rs2_man += j - rs2_man = rs2_man[0:flen-e_sz-1] - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) - comment.append(comment_str + ' | Checkerboard pattern ---> rs2_man = '+rs2_man) - b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) - comment.append(comment_str + ' | Checkerboard pattern ---> rs1_man = '+rs2_man) - - coverpoints = [] - k = 0 - for c in b11_comb: - cvpt = "" - for x in range(1, ops+1): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += comment[k] - coverpoints.append(cvpt) - k += 1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B11 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b12(flen, opcode, ops, seed=-1): - ''' - IBM Model B12 Definition: + ''' + opcode = opcode.split('.')[0] + + if iflen == 32: + flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm + e_sz=8 + exp_max = 255 + elif iflen == 64: + flip_types = dzero + done + dminsubnorm + dmaxsubnorm + dminnorm + dmaxnorm + e_sz=11 + exp_max = 1023 + + if seed == -1: + if opcode in 'fadd': + random.seed(0) + elif opcode in 'fsub': + random.seed(1) + else: + random.seed(seed) + + rs1 = [] + b11_comb = [] + comment = [] + if ops == 2: + for i in range(len(flip_types)): + rs1.append(flip_types[i]) + for i in range(len(rs1)): + bin_val = bin(int('1'+rs1[i][2:],16))[3:] + rs1_sgn = bin_val[0] + rs1_exp = bin_val[1:e_sz+1] + rs1_man = bin_val[e_sz+1:] + + if int(rs1_exp,2) < 4: rs2_exp = -127 + else : rs2_exp = random.randrange(-127,int(rs1_exp,2)-131) + comment_str = ' | Exponent = '+ str(rs2_exp) + ' --> A value smaller than (p - 4)' + rs2_exp += 127 + if iflen == 32: rs2_exp = '{:08b}'.format(rs2_exp) + elif iflen == 64: rs2_exp = '{:011b}'.format(rs2_exp) + for j in range(len(rs1_man)): + rs2_sgn = rs1_sgn + rs2_man = '0'*j + rs1_man[j:] # Leading 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Leading zeroes ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Leading zeroes ---> rs1_man = '+rs2_man) + + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Leading ones ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Leading ones ---> rs1_man = '+rs2_man) + + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Trailing zeroes ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Trailing zeroes ---> rs1_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Trailing ones ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Trailing ones ---> rs1_man = '+rs2_man) + + for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Long sequence of ones ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Long sequence of ones ---> rs1_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Long sequence of zeroes ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Long sequence of zeroes ---> rs1_man = '+rs2_man) + + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] + for j in chkrbrd: + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = j + for k in range(math.ceil(len(rs1_man)/len(j))): + rs2_man += j + rs2_man = rs2_man[0:iflen-e_sz-1] + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Checkerboard pattern ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Checkerboard pattern ---> rs1_man = '+rs2_man) + + if int(rs1_exp,2) >= 250: rs2_exp = 127 + else : rs2_exp = random.randrange(int(rs1_exp,2)-123,127) + comment_str = ' | Exponent = '+ str(rs2_exp) + ' --> A value greater than (p + 4)' + rs2_exp += 127 + if iflen == 32: rs2_exp = '{:08b}'.format(rs2_exp) + elif iflen == 64: rs2_exp = '{:011b}'.format(rs2_exp) + for j in range(len(rs1_man)): + rs2_sgn = rs1_sgn + rs2_man = '0'*j + rs1_man[j:] # Leading 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Leading zeroes ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Leading zeroes ---> rs1_man = '+rs2_man) + + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Leading ones ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Leading ones ---> rs1_man = '+rs2_man) + + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Trailing zeroes ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Trailing zeroes ---> rs1_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Trailing ones ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Trailing ones ---> rs1_man = '+rs2_man) + + for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Long sequence of ones ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Long sequence of ones ---> rs1_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Long sequence of zeroes ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Long sequence of zeroes ---> rs1_man = '+rs2_man) + + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] + for j in chkrbrd: + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = j + for k in range(math.ceil(len(rs1_man)/len(j))): + rs2_man += j + rs2_man = rs2_man[0:iflen-e_sz-1] + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Checkerboard pattern ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Checkerboard pattern ---> rs1_man = '+rs2_man) + + ul = int(rs1_exp,2)-123 + ll = int(rs1_exp,2)-131 + if int(rs1_exp,2) >= 250: ul = 127 + if int(rs1_exp,2) < 4: ll = -127 + for expval in range (ll, ul): + rs2_exp = expval + comment_str = ' | Exponent = '+ str(rs2_exp) + ' --> Values in the range (p - 4) to (p + 4)' + rs2_exp += 127 + if iflen == 32: rs2_exp = '{:08b}'.format(rs2_exp) + elif iflen == 64: rs2_exp = '{:011b}'.format(rs2_exp) + for j in range(len(rs1_man)): + rs2_sgn = rs1_sgn + rs2_man = '0'*j + rs1_man[j:] # Leading 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Leading zeroes ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Leading zeroes ---> rs1_man = '+rs2_man) + + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Leading ones ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Leading ones ---> rs1_man = '+rs2_man) + + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Trailing zeroes ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Trailing zeroes ---> rs1_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Trailing ones ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Trailing ones ---> rs1_man = '+rs2_man) + + for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Long sequence of ones ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Long sequence of ones ---> rs1_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Long sequence of zeroes ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Long sequence of zeroes ---> rs1_man = '+rs2_man) + + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] + for j in chkrbrd: + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = j + for k in range(math.ceil(len(rs1_man)/len(j))): + rs2_man += j + rs2_man = rs2_man[0:iflen-e_sz-1] + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b11_comb.append((rs1[i],floatingPoint_tohex(iflen,rs2))) + comment.append(comment_str + ' | Checkerboard pattern ---> rs2_man = '+rs2_man) + b11_comb.append((floatingPoint_tohex(iflen,rs2),rs1[i])) + comment.append(comment_str + ' | Checkerboard pattern ---> rs1_man = '+rs2_man) + + coverpoints = [] + k = 0 + for c in b11_comb: + cvpt = "" + for x in range(1, ops+1): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + # cvpt += 'rm_val == 0' + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += comment[k] + coverpoints.append(cvpt) + k += 1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B11 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b12(flen, iflen, opcode, ops, seed=-1): + ''' + IBM Model B12 Definition: This model tests every possible value for cancellation. For the difference between the exponent of the intermediate result and the maximum between the exponents of the inputs, test all values in the range: [-p, +1]. - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Intermediate Result - Operand.Exp ∈ [-p, +1] Operand1 {operation} Operand2 = Intermediate Results - Implementation: + Implementation: - The exponent values of operand 1 and operand 2 obey the shift defined above. The mantissa value is randomly chosen and appended with the exponent derived. - Simultaneously, we convert these numbers into their corresponding IEEE754 floating point formats. - These operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with rounding mode ‘0’ for that particular opcode. - ''' - - opcode = opcode.split('.')[0] - getcontext().prec = 40 - if flen == 32: - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.000001p-126' - minsubnorm = float.fromhex(ieee754_minsubnorm) - ieee754_maxsubnorm = '0x0.7fffffp-126' - maxsubnorm = float.fromhex(ieee754_maxsubnorm) - - elif flen == 64: - ieee754_maxnorm = '0x1.fffffffffffffp+1023' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.0000000000001p-1022' - minsubnorm = float.fromhex(ieee754_minsubnorm) - ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' - maxsubnorm = float.fromhex(ieee754_maxsubnorm) - - if seed == -1: - if opcode in 'fadd': - random.seed(0) - elif opcode in 'fsub': - random.seed(1) - else: - random.seed(seed) - - b12_comb = [] - - for i in range(50): - if opcode in 'fadd': rs1 = -1*random.uniform(minsubnorm,maxnum) - elif opcode in 'fsub': rs1 = random.uniform(minsubnorm,maxnum) - ir = random.uniform(1,maxnum) - if opcode in 'fadd': - if flen == 32: - rs2 = ir - rs1 - elif flen == 64: - rs2 = Decimal(ir) - Decimal(rs1) - elif opcode in 'fsub': - if flen == 32: - rs2 = rs1 - ir - elif flen == 64: - rs2 = Decimal(rs1) - Decimal(ir) - - if(flen==32): - x1 = struct.unpack('f', struct.pack('f', rs1))[0] - x2 = struct.unpack('f', struct.pack('f', rs2))[0] - elif(flen==64): - x1 = rs1 - x2 = rs2 - - if opcode in ['fadd','fsub']: - b12_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - - coverpoints = [] - comment = ' | Add: Cancellation' - for c in b12_comb: - cvpt = "" - for x in range(1, ops+1): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, 3): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += comment - coverpoints.append(cvpt) - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B12 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b13(flen, opcode, ops, seed=-1): - ''' - IBM Model B13 Definition: + ''' + + opcode = opcode.split('.')[0] + getcontext().prec = 40 + if iflen == 32: + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.000001p-126' + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = '0x0.7fffffp-126' + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + + elif iflen == 64: + ieee754_maxnorm = '0x1.fffffffffffffp+1023' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.0000000000001p-1022' + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + + if seed == -1: + if opcode in 'fadd': + random.seed(0) + elif opcode in 'fsub': + random.seed(1) + else: + random.seed(seed) + + b12_comb = [] + + for i in range(50): + if opcode in 'fadd': rs1 = -1*random.uniform(minsubnorm,maxnum) + elif opcode in 'fsub': rs1 = random.uniform(minsubnorm,maxnum) + ir = random.uniform(1,maxnum) + if opcode in 'fadd': + if iflen == 32: + rs2 = ir - rs1 + elif iflen == 64: + rs2 = Decimal(ir) - Decimal(rs1) + elif opcode in 'fsub': + if iflen == 32: + rs2 = rs1 - ir + elif iflen == 64: + rs2 = Decimal(rs1) - Decimal(ir) + + if(iflen==32): + x1 = struct.unpack('f', struct.pack('f', rs1))[0] + x2 = struct.unpack('f', struct.pack('f', rs2))[0] + elif(iflen==64): + x1 = rs1 + x2 = rs2 + + if opcode in ['fadd','fsub']: + b12_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + + coverpoints = [] + comment = ' | Add: Cancellation' + for c in b12_comb: + cvpt = "" + for x in range(1, ops+1): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + # cvpt += 'rm_val == 0' + cvpt += ' # ' + for y in range(1, 3): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += comment + coverpoints.append(cvpt) + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B12 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b13(flen, iflen, opcode, ops, seed=-1): + ''' + IBM Model B13 Definition: This model tests all combinations of cancellation values as in model (B12), with all possible unbiased exponent values of subnormal results. - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Intermediate Result - Operand.Exp ∈ [-p, +1] (The exponent for the intermediate result is chosen such that it is a subnormal number) Operand1 {operation} Operand2 = Intermediate Results - Implementation: + Implementation: - The implementation procedure for Model B12 is repeated with a revised exponent range as defined above. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - - opcode = opcode.split('.')[0] - getcontext().prec = 40 - if flen == 32: - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.000001p-126' - minsubnorm = float.fromhex(ieee754_minsubnorm) - ieee754_maxsubnorm = '0x0.7fffffp-126' - maxsubnorm = float.fromhex(ieee754_maxsubnorm) - - elif flen == 64: - ieee754_maxnorm = '0x1.fffffffffffffp+1023' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.0000000000001p-1022' - minsubnorm = float.fromhex(ieee754_minsubnorm) - ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' - maxsubnorm = float.fromhex(ieee754_maxsubnorm) - - if seed == -1: - if opcode in 'fadd': - random.seed(0) - elif opcode in 'fsub': - random.seed(1) - else: - random.seed(seed) - - b13_comb = [] - - for i in range(200): - rs1 = random.uniform(minsubnorm,maxnum) - ir = random.uniform(minsubnorm,maxsubnorm) - if opcode in 'fadd': - if flen == 32: - rs2 = ir - rs1 - elif flen == 64: - rs2 = Decimal(ir) - Decimal(rs1) - elif opcode in 'fsub': - if flen == 32: - rs2 = rs1 - ir - elif flen == 64: - rs2 = Decimal(rs1) - Decimal(ir) - - if(flen==32): - x1 = struct.unpack('f', struct.pack('f', rs1))[0] - x2 = struct.unpack('f', struct.pack('f', rs2))[0] - elif(flen==64): - x1 = rs1 - x2 = rs2 - - if opcode in ['fadd','fsub']: - b13_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - - coverpoints = [] - comment = ' | Add: Cancellation ---> Subnormal result' - for c in b13_comb: - cvpt = "" - for x in range(1, 3): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += comment - coverpoints.append(cvpt) - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B13 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b14(flen, opcode, ops, N=-1, seed=-1): - ''' - IBM Model B14 Definition: + ''' + + opcode = opcode.split('.')[0] + getcontext().prec = 40 + if iflen == 32: + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.000001p-126' + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = '0x0.7fffffp-126' + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + + elif iflen == 64: + ieee754_maxnorm = '0x1.fffffffffffffp+1023' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.0000000000001p-1022' + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + + if seed == -1: + if opcode in 'fadd': + random.seed(0) + elif opcode in 'fsub': + random.seed(1) + else: + random.seed(seed) + + b13_comb = [] + + for i in range(200): + rs1 = random.uniform(minsubnorm,maxnum) + ir = random.uniform(minsubnorm,maxsubnorm) + if opcode in 'fadd': + if iflen == 32: + rs2 = ir - rs1 + elif iflen == 64: + rs2 = Decimal(ir) - Decimal(rs1) + elif opcode in 'fsub': + if iflen == 32: + rs2 = rs1 - ir + elif iflen == 64: + rs2 = Decimal(rs1) - Decimal(ir) + + if(iflen==32): + x1 = struct.unpack('f', struct.pack('f', rs1))[0] + x2 = struct.unpack('f', struct.pack('f', rs2))[0] + elif(iflen==64): + x1 = rs1 + x2 = rs2 + + if opcode in ['fadd','fsub']: + b13_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + + coverpoints = [] + comment = ' | Add: Cancellation ---> Subnormal result' + for c in b13_comb: + cvpt = "" + for x in range(1, 3): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + # cvpt += 'rm_val == 0' + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += comment + coverpoints.append(cvpt) + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B13 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b14(flen, iflen, opcode, ops, N=-1, seed=-1): + ''' + IBM Model B14 Definition: This model tests every possible value for a shift between the addends of the multiply-add operation. For the difference between the unbiased exponent of the addend and the unbiased exponent of the result of the multiplication, test the following values: @@ -2408,669 +2448,681 @@ def ibm_b14(flen, opcode, ops, N=-1, seed=-1): We test both effective operations: addition and subtraction. The end values tested are selected to be greater by one than the largest possible shift in which the smaller addend may affect the result. - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param N: No. of sets of coverpoints to be generated. (Predefined to -1. Set to 2) - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - - :type flen: int - :type opcode: str - :type ops: int - :type N: int - :param seed: int - - Abstract Dataset Description: + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param N: No. of sets of coverpoints to be generated. (Predefined to -1. Set to 2) + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :type N: int + :param seed: int + + Abstract Dataset Description: Shift between the addends of the multiply-add operation = [ A value smaller than -(2* p + 1), All the values in the range [-(2*p +1), (p +1), A value larger than (p + 1) ] → Condition 1 Operand 1, 2 = Random Operand 3 = Condition 1 - Implementation: + Implementation: - The shift between the two addends are constrained by the conditions mentioned in the dataset above. - Operands 1 and 2 are randomly obtained. But Operand 3 is obtained by ensuring the shift conditions. - Once the dataset is formed, these operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with rounding mode ‘0’ for that particular opcode. - ''' - opcode = opcode.split('.')[0] - - if flen == 32: - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - exp_max = 127 - mant_bits = 23 - limnum = maxnum - - elif flen == 64: - maxdec = '1.7976931348623157e+308' - maxnum = float.fromhex('0x1.fffffffffffffp+1023') - exp_max = 1022 - ieee754_limnum = '0x1.fffffffffffffp+507' - mant_bits = 52 - limnum = float.fromhex(ieee754_limnum) - - if N == -1: - N = 2 - - if seed == -1: - if opcode in 'fmadd': - random.seed(0) - elif opcode in 'fmsub': - random.seed(1) - elif opcode in 'fnmadd': - random.seed(2) - elif opcode in 'fnmsub': - random.seed(3) - else: - random.seed(seed) - - b14_comb = [] - comment = [] - for i in range(1,N): - rs1 = random.uniform(1,limnum) - rs2 = random.uniform(1,limnum) - rs3 = random.uniform(1,limnum) - mul_exp = int(str(rs1*rs2).split('e')[1]) - mul_exp = int(math.log(pow(2,int(mul_exp)),10)) - - if mul_exp-((2*mant_bits)+1) > -1*exp_max: - rs3_exp = random.randrange(-1*exp_max,mul_exp-((2*mant_bits)+1)) - rs3_num = float.hex(float(str(rs3).split('e')[0])).split('p')[0]+'p'+str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+rs3_exp) - rs3_num = float.fromhex(rs3_num) - b14_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3_num)))) - comment.append(' | Multiplicand Exponent = '+str(mul_exp)+', Addend exponent = '+ str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+rs3_exp) + ' --> Difference smaller than -(2*p + 1)') - - if mul_exp-((2*mant_bits)+1) < -1*exp_max: exp1 = -1*exp_max - else: exp1 = mul_exp-((2*mant_bits)+1) - if mul_exp+mant_bits+1 > exp_max: exp2 = exp_max - else: exp2 = mul_exp+mant_bits+1 - for j in range(exp1, exp2): - rs3_num = float.hex(float(str(rs3).split('e')[0])).split('p')[0]+'p'+str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+j) - rs3_num = float.fromhex(rs3_num) - b14_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3_num)))) - comment.append(' | Multiplicand Exponent = '+str(mul_exp)+', Addend exponent = '+ str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+j) + ' --> Values in the range [-(2*p + 1) , (p + 1)]') - - rs3_exp = random.randrange(exp2, exp_max) - rs3_num = float.hex(float(str(rs3).split('e')[0])).split('p')[0]+'p'+str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+rs3_exp) - rs3_num = float.fromhex(rs3_num) - b14_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3_num)))) - comment.append(' | Multiplicand Exponent = '+str(mul_exp)+', Addend exponent = '+ str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+rs3_exp) + ' --> A value larger than (p + 1)') - - coverpoints = [] - k = 0 - for c in b14_comb: - cvpt = "" - for x in range(1, 4): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, 4): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += comment[k] - coverpoints.append(cvpt) - k += 1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B14 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b15(flen, opcode, ops, N=-1, seed=-1): - ''' - IBM Model B15 Definition: + ''' + opcode = opcode.split('.')[0] + + if iflen == 32: + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + exp_max = 127 + mant_bits = 23 + limnum = maxnum + + elif iflen == 64: + maxdec = '1.7976931348623157e+308' + maxnum = float.fromhex('0x1.fffffffffffffp+1023') + exp_max = 1022 + ieee754_limnum = '0x1.fffffffffffffp+507' + mant_bits = 52 + limnum = float.fromhex(ieee754_limnum) + + if N == -1: + N = 2 + + if seed == -1: + if opcode in 'fmadd': + random.seed(0) + elif opcode in 'fmsub': + random.seed(1) + elif opcode in 'fnmadd': + random.seed(2) + elif opcode in 'fnmsub': + random.seed(3) + else: + random.seed(seed) + + b14_comb = [] + comment = [] + for i in range(1,N): + rs1 = random.uniform(1,limnum) + rs2 = random.uniform(1,limnum) + rs3 = random.uniform(1,limnum) + mul_exp = int(str(rs1*rs2).split('e')[1]) + mul_exp = int(math.log(pow(2,int(mul_exp)),10)) + + if mul_exp-((2*mant_bits)+1) > -1*exp_max: + rs3_exp = random.randrange(-1*exp_max,mul_exp-((2*mant_bits)+1)) + rs3_num = float.hex(float(str(rs3).split('e')[0])).split('p')[0]+'p'+str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+rs3_exp) + rs3_num = float.fromhex(rs3_num) + b14_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)),floatingPoint_tohex(iflen,float(rs3_num)))) + comment.append(' | Multiplicand Exponent = '+str(mul_exp)+', Addend exponent = '+ str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+rs3_exp) + ' --> Difference smaller than -(2*p + 1)') + + if mul_exp-((2*mant_bits)+1) < -1*exp_max: exp1 = -1*exp_max + else: exp1 = mul_exp-((2*mant_bits)+1) + if mul_exp+mant_bits+1 > exp_max: exp2 = exp_max + else: exp2 = mul_exp+mant_bits+1 + for j in range(exp1, exp2): + rs3_num = float.hex(float(str(rs3).split('e')[0])).split('p')[0]+'p'+str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+j) + rs3_num = float.fromhex(rs3_num) + b14_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)),floatingPoint_tohex(iflen,float(rs3_num)))) + comment.append(' | Multiplicand Exponent = '+str(mul_exp)+', Addend exponent = '+ str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+j) + ' --> Values in the range [-(2*p + 1) , (p + 1)]') + + rs3_exp = random.randrange(exp2, exp_max) + rs3_num = float.hex(float(str(rs3).split('e')[0])).split('p')[0]+'p'+str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+rs3_exp) + rs3_num = float.fromhex(rs3_num) + b14_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)),floatingPoint_tohex(iflen,float(rs3_num)))) + comment.append(' | Multiplicand Exponent = '+str(mul_exp)+', Addend exponent = '+ str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+rs3_exp) + ' --> A value larger than (p + 1)') + + coverpoints = [] + k = 0 + for c in b14_comb: + cvpt = "" + for x in range(1, 4): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + # cvpt += 'rm_val == 0' + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt += ' # ' + for y in range(1, 4): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += comment[k] + coverpoints.append(cvpt) + k += 1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B14 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b15(flen, iflen, opcode, ops, N=-1, seed=-1): + ''' + IBM Model B15 Definition: In this model we test the combination of different shift values between the addends, with special patterns in the significands of the addends. For the significand of the addend and for the multiplication result we take the cases defined in model (B9) "Special Significands on Inputs" For the shift we take the cases defined in model (B14) "Shift – multiply-add". - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Operand 1, 2 = Random Operand 3 ∈ Abstract Dataset in B9 + Abstract Dataset in B14 - Implementation: + Implementation: - Here the condition is imposed that if the value of the ops variable is 3, then each of the elements in the flip types is iterated and split into their respective sign, mantissa and exponent part. - A mul variable is initialized and parsed to the field_dec_converter for each rs1 value in the list. Next the loop is run for the mantissa parts generated for rs1 values, where it is checked for certain patterns like the leading 0’s, leading 1’s, trailing 0’s and trailing 1’s. - - The checkerboard list is declared with the probable sequences for rs2. Here the sign and exponent are extracted from the rs1 values. Mantissa part is derived from the checkerboard list. Consecutively, if the flen value differs, then the range available varies. + - The checkerboard list is declared with the probable sequences for rs2. Here the sign and exponent are extracted from the rs1 values. Mantissa part is derived from the checkerboard list. Consecutively, if the iflen value differs, then the range available varies. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with rounding mode “0” for that particular opcode. - ''' - opcode = opcode.split('.')[0] - - if flen == 32: - flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm - e_sz=8 - exp_max = 255 - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - exp_max = 127 - mant_bits = 23 - limnum = maxnum - elif flen == 64: - flip_types = dzero + done + dminsubnorm + dmaxsubnorm + dminnorm + dmaxnorm - e_sz=11 - exp_max = 1023 - maxdec = '1.7976931348623157e+308' - maxnum = float.fromhex('0x1.fffffffffffffp+1023') - exp_max = 1022 - ieee754_limnum = '0x1.fffffffffffffp+507' - mant_bits = 52 - limnum = float.fromhex(ieee754_limnum) - - if seed == -1: - if opcode in 'fmadd': - random.seed(0) - elif opcode in 'fnmadd': - random.seed(1) - elif opcode in 'fmsub': - random.seed(2) - elif opcode in 'fnmsub': - random.seed(3) - else: - random.seed(seed) - - rs1 = [] - b15_comb = [] - comment = [] - if ops == 3: - for i in range(len(flip_types)): - rs1.append(flip_types[i]) - for i in range(len(rs1)): - bin_val = bin(int('1'+rs1[i][2:],16))[3:] - rs1_sgn = bin_val[0] - rs1_exp = bin_val[1:e_sz+1] - rs1_man = bin_val[e_sz+1:] - - if flen == 32: - if int(rs1_exp,2) < 65: rs2_exp = 0 - else : rs2_exp = random.randrange(0,int(rs1_exp,2)-65) - comment_str = ' | Exponent = '+ str(rs2_exp-127) + ' --> Difference smaller than -(2p + 1)' - rs2_exp = '{:08b}'.format(rs2_exp) - elif flen == 64: - if int(rs1_exp,2) < 129: rs2_exp = 0 - else : rs2_exp = random.randrange(0,int(rs1_exp,2)-129) - comment_str = ' | Exponent = '+ str(rs2_exp-1023) + ' --> Difference smaller than -(2p + 1)' - rs2_exp = '{:011b}'.format(rs2_exp) - mul = fields_dec_converter(flen,rs1[i]) - rs1_act = random.uniform(1,limnum) - rs2_act = mul/rs1_act - for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn - rs2_man = '0'*j + rs1_man[j:] # Leading 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Leading zeroes ---> rs3_man = '+rs2_man) - - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Leading ones ---> rs3_man = '+rs2_man) - - rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Trailing zeroes ---> rs3_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Trailing ones ---> rs3_man = '+rs2_man) - - for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Long sequence of ones ---> rs3_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Long sequence of zeroes ---> rs3_man = '+rs2_man) - - chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] - for j in chkrbrd: - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = j - for k in range(math.ceil(len(rs1_man)/len(j))): - rs2_man += j - rs2_man = rs2_man[0:flen-e_sz-1] - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Checkerboard pattern ---> rs3_man = '+rs2_man) - - if flen == 32: - if int(rs1_exp,2) > 222: rs2_exp = 255 - else : rs2_exp = random.randrange(int(rs1_exp,2)+33, 255) - comment_str = ' | Exponent = '+ str(rs2_exp-127) + ' --> Difference greater than (p + 1)' - rs2_exp = '{:08b}'.format(rs2_exp) - elif flen == 64: - if int(rs1_exp,2) > 958: rs2_exp = 1023 - else : rs2_exp = random.randrange(int(rs1_exp,2)+65, 1023) - comment_str = ' | Exponent = '+ str(rs2_exp-1023) + ' --> Difference greater than (p + 1)' - rs2_exp = '{:011b}'.format(rs2_exp) - mul = fields_dec_converter(flen,rs1[i]) - rs1_act = random.uniform(1,limnum) - rs2_act = mul/rs1_act - for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn - rs2_man = '0'*j + rs1_man[j:] # Leading 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Leading zeroes ---> rs3_man = '+rs2_man) - - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Leading ones ---> rs3_man = '+rs2_man) - - rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Trailing zeroes ---> rs3_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Trailing ones ---> rs3_man = '+rs2_man) - - for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Long sequence of ones ---> rs3_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Long sequence of zeroes ---> rs3_man = '+rs2_man) - - chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] - for j in chkrbrd: - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = j - for k in range(math.ceil(len(rs1_man)/len(j))): - rs2_man += j - rs2_man = rs2_man[0:flen-e_sz-1] - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Checkerboard pattern ---> rs3_man = '+rs2_man) - - if flen == 32: - ul = int(rs1_exp,2)+33 - ll = int(rs1_exp,2)-65 - if int(rs1_exp,2) >= 222: ul = 255 - if int(rs1_exp,2) < 65: ll = 0 - elif flen == 64: - ul = int(rs1_exp,2)+65 - ll = int(rs1_exp,2)-129 - if int(rs1_exp,2) >= 958: ul = 1023 - if int(rs1_exp,2) < 129: ll = 0 - for expval in range (ll, ul): - rs2_exp = expval - if flen == 32: - comment_str = ' | Exponent = '+ str(rs2_exp-127) + ' --> Difference between -(2p+1) and (p+1)' - rs2_exp = '{:08b}'.format(rs2_exp) - elif flen == 64: - comment_str = ' | Exponent = '+ str(rs2_exp-1023) + ' --> Difference between -(2p+1) and (p+1)' - rs2_exp = '{:011b}'.format(rs2_exp) - mul = fields_dec_converter(flen,rs1[i]) - rs1_act = random.uniform(1,limnum) - rs2_act = mul/rs1_act - - for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn - rs2_man = '0'*j + rs1_man[j:] # Leading 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Leading zeroes ---> rs3_man = '+rs2_man) - - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Leading ones ---> rs3_man = '+rs2_man) - - rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Trailing zeroes ---> rs3_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Trailing ones ---> rs3_man = '+rs2_man) - - for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Long sequence of ones ---> rs3_man = '+rs2_man) - - rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Long sequence of zeroes ---> rs3_man = '+rs2_man) - - chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] - for j in chkrbrd: - rs2_sgn = rs1_sgn - rs2_exp = rs1_exp - rs2_man = j - for k in range(math.ceil(len(rs1_man)/len(j))): - rs2_man += j - rs2_man = rs2_man[0:flen-e_sz-1] - rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) - b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(comment_str + ' | Checkerboard pattern ---> rs3_man = '+rs2_man) - - coverpoints = [] - k = 0 - for c in b15_comb: - cvpt = "" - for x in range(1, 4): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += comment[k] - coverpoints.append(cvpt) - k += 1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B15 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b16(flen, opcode, ops, seed=-1): - ''' - IBM Model B16 Definition: + ''' + opcode = opcode.split('.')[0] + + if iflen == 32: + flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm + e_sz=8 + exp_max = 255 + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + exp_max = 127 + mant_bits = 23 + limnum = maxnum + elif iflen == 64: + flip_types = dzero + done + dminsubnorm + dmaxsubnorm + dminnorm + dmaxnorm + e_sz=11 + exp_max = 1023 + maxdec = '1.7976931348623157e+308' + maxnum = float.fromhex('0x1.fffffffffffffp+1023') + exp_max = 1022 + ieee754_limnum = '0x1.fffffffffffffp+507' + mant_bits = 52 + limnum = float.fromhex(ieee754_limnum) + + if seed == -1: + if opcode in 'fmadd': + random.seed(0) + elif opcode in 'fnmadd': + random.seed(1) + elif opcode in 'fmsub': + random.seed(2) + elif opcode in 'fnmsub': + random.seed(3) + else: + random.seed(seed) + + rs1 = [] + b15_comb = [] + comment = [] + if ops == 3: + for i in range(len(flip_types)): + rs1.append(flip_types[i]) + for i in range(len(rs1)): + bin_val = bin(int('1'+rs1[i][2:],16))[3:] + rs1_sgn = bin_val[0] + rs1_exp = bin_val[1:e_sz+1] + rs1_man = bin_val[e_sz+1:] + + if iflen == 32: + if int(rs1_exp,2) < 65: rs2_exp = 0 + else : rs2_exp = random.randrange(0,int(rs1_exp,2)-65) + comment_str = ' | Exponent = '+ str(rs2_exp-127) + ' --> Difference smaller than -(2p + 1)' + rs2_exp = '{:08b}'.format(rs2_exp) + elif iflen == 64: + if int(rs1_exp,2) < 129: rs2_exp = 0 + else : rs2_exp = random.randrange(0,int(rs1_exp,2)-129) + comment_str = ' | Exponent = '+ str(rs2_exp-1023) + ' --> Difference smaller than -(2p + 1)' + rs2_exp = '{:011b}'.format(rs2_exp) + mul = fields_dec_converter(iflen,rs1[i]) + rs1_act = random.uniform(1,limnum) + rs2_act = mul/rs1_act + for j in range(len(rs1_man)): + rs2_sgn = rs1_sgn + rs2_man = '0'*j + rs1_man[j:] # Leading 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Leading zeroes ---> rs3_man = '+rs2_man) + + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Leading ones ---> rs3_man = '+rs2_man) + + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Trailing zeroes ---> rs3_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Trailing ones ---> rs3_man = '+rs2_man) + + for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Long sequence of ones ---> rs3_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Long sequence of zeroes ---> rs3_man = '+rs2_man) + + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] + for j in chkrbrd: + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = j + for k in range(math.ceil(len(rs1_man)/len(j))): + rs2_man += j + rs2_man = rs2_man[0:iflen-e_sz-1] + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Checkerboard pattern ---> rs3_man = '+rs2_man) + + if iflen == 32: + if int(rs1_exp,2) > 222: rs2_exp = 255 + else : rs2_exp = random.randrange(int(rs1_exp,2)+33, 255) + comment_str = ' | Exponent = '+ str(rs2_exp-127) + ' --> Difference greater than (p + 1)' + rs2_exp = '{:08b}'.format(rs2_exp) + elif iflen == 64: + if int(rs1_exp,2) > 958: rs2_exp = 1023 + else : rs2_exp = random.randrange(int(rs1_exp,2)+65, 1023) + comment_str = ' | Exponent = '+ str(rs2_exp-1023) + ' --> Difference greater than (p + 1)' + rs2_exp = '{:011b}'.format(rs2_exp) + mul = fields_dec_converter(iflen,rs1[i]) + rs1_act = random.uniform(1,limnum) + rs2_act = mul/rs1_act + for j in range(len(rs1_man)): + rs2_sgn = rs1_sgn + rs2_man = '0'*j + rs1_man[j:] # Leading 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Leading zeroes ---> rs3_man = '+rs2_man) + + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Leading ones ---> rs3_man = '+rs2_man) + + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Trailing zeroes ---> rs3_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Trailing ones ---> rs3_man = '+rs2_man) + + for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Long sequence of ones ---> rs3_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Long sequence of zeroes ---> rs3_man = '+rs2_man) + + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] + for j in chkrbrd: + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = j + for k in range(math.ceil(len(rs1_man)/len(j))): + rs2_man += j + rs2_man = rs2_man[0:iflen-e_sz-1] + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Checkerboard pattern ---> rs3_man = '+rs2_man) + + if iflen == 32: + ul = int(rs1_exp,2)+33 + ll = int(rs1_exp,2)-65 + if int(rs1_exp,2) >= 222: ul = 255 + if int(rs1_exp,2) < 65: ll = 0 + elif iflen == 64: + ul = int(rs1_exp,2)+65 + ll = int(rs1_exp,2)-129 + if int(rs1_exp,2) >= 958: ul = 1023 + if int(rs1_exp,2) < 129: ll = 0 + for expval in range (ll, ul): + rs2_exp = expval + if iflen == 32: + comment_str = ' | Exponent = '+ str(rs2_exp-127) + ' --> Difference between -(2p+1) and (p+1)' + rs2_exp = '{:08b}'.format(rs2_exp) + elif iflen == 64: + comment_str = ' | Exponent = '+ str(rs2_exp-1023) + ' --> Difference between -(2p+1) and (p+1)' + rs2_exp = '{:011b}'.format(rs2_exp) + mul = fields_dec_converter(iflen,rs1[i]) + rs1_act = random.uniform(1,limnum) + rs2_act = mul/rs1_act + + for j in range(len(rs1_man)): + rs2_sgn = rs1_sgn + rs2_man = '0'*j + rs1_man[j:] # Leading 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Leading zeroes ---> rs3_man = '+rs2_man) + + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Leading ones ---> rs3_man = '+rs2_man) + + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Trailing zeroes ---> rs3_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Trailing ones ---> rs3_man = '+rs2_man) + + for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Long sequence of 1s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Long sequence of ones ---> rs3_man = '+rs2_man) + + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Long sequence of zeroes ---> rs3_man = '+rs2_man) + + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] + for j in chkrbrd: + rs2_sgn = rs1_sgn + rs2_exp = rs1_exp + rs2_man = j + for k in range(math.ceil(len(rs1_man)/len(j))): + rs2_man += j + rs2_man = rs2_man[0:iflen-e_sz-1] + rs2 = fields_dec_converter(iflen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) + b15_comb.append((floatingPoint_tohex(iflen,float(rs1_act)),floatingPoint_tohex(iflen,float(rs2_act)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(comment_str + ' | Checkerboard pattern ---> rs3_man = '+rs2_man) + + coverpoints = [] + k = 0 + for c in b15_comb: + cvpt = "" + for x in range(1, 4): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + # cvpt += 'rm_val == 0' + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += comment[k] + coverpoints.append(cvpt) + k += 1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B15 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b16(flen, iflen, opcode, ops, seed=-1): + ''' + IBM Model B16 Definition: This model tests every possible value for cancellation. For the difference between the exponent of the intermediate result and the maximum between the exponents of the addend and the multiplication result, test all values in the range: [-(2 * p + 1), 1]. - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Intermediate Result.exp - max(addend.exp, multiplication result.exp) ∈ [-(2 * p + 1), 1] → Condition 1 Operand 1 {operation 1} Operand 2 {operation 2} Operand 3 = Condition 1 - Implementation: + Implementation: - Random values of operands 1 and 2 are obtained from the random library. - Since the objective of the test is to cancel the operands among each other constrained by the above condition, the intermediate result is calculated by the multiplication of operand 1 and 2. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with rounding mode “0” for that particular opcode. - ''' - - opcode = opcode.split('.')[0] - getcontext().prec = 40 - if flen == 32: - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.000001p-126' - minsubnorm = float.fromhex(ieee754_minsubnorm) - ieee754_maxsubnorm = '0x0.7fffffp-126' - maxsubnorm = float.fromhex(ieee754_maxsubnorm) - limnum = maxnum - - elif flen == 64: - ieee754_maxnorm = '0x1.fffffffffffffp+1023' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.0000000000001p-1022' - minsubnorm = float.fromhex(ieee754_minsubnorm) - ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' - maxsubnorm = float.fromhex(ieee754_maxsubnorm) - ieee754_limnum = '0x1.fffffffffffffp+507' - limnum = float.fromhex(ieee754_limnum) - - if seed == -1: - if opcode in 'fmadd': - random.seed(0) - elif opcode in 'fmsub': - random.seed(1) - elif opcode in 'fnmadd': - random.seed(2) - elif opcode in 'fnmsub': - random.seed(3) - else: - random.seed(seed) - - b17_comb = [] - - for i in range(200): - rs1 = random.uniform(minsubnorm,limnum) - rs2 = random.uniform(minsubnorm,limnum) - ir = random.uniform(minsubnorm,rs1*rs2) - - if opcode in 'fmadd': - if flen == 32: - rs3 = ir - rs1*rs2 - elif flen == 64: - rs3 = Decimal(ir) - Decimal(rs1)*Decimal(rs2) - elif opcode in 'fnmadd': - if flen == 32: - rs3 = -1*rs1*rs2 - ir - elif flen == 64: - rs3 = -1*Decimal(rs1)*Decimal(rs2) - Decimal(ir) - elif opcode in 'fmsub': - if flen == 32: - rs3 = rs1*rs2 - ir - elif flen == 64: - rs3 = Decimal(rs1)*Decimal(rs2) - Decimal(ir) - elif opcode in 'fnmsub': - if flen == 32: - rs3 = ir + rs1*rs2 - elif flen == 64: - rs3 = Decimal(ir) + Decimal(rs1)*Decimal(rs2) - - if(flen==32): - x1 = struct.unpack('f', struct.pack('f', rs1))[0] - x2 = struct.unpack('f', struct.pack('f', rs2))[0] - elif(flen==64): - x1 = rs1 - x2 = rs2 - - result = [] - if opcode in ['fmadd','fmsub','fnmadd','fnmsub']: - b17_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - - coverpoints = [] - comment = ' | Multiply-Add: Cancellation' - for c in b17_comb: - cvpt = "" - for x in range(1, 4): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += comment - coverpoints.append(cvpt) - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B16 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b17(flen, opcode, ops, seed=-1): - ''' - IBM Model B17 Definition: + ''' + + opcode = opcode.split('.')[0] + getcontext().prec = 40 + if iflen == 32: + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.000001p-126' + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = '0x0.7fffffp-126' + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + limnum = maxnum + + elif iflen == 64: + ieee754_maxnorm = '0x1.fffffffffffffp+1023' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.0000000000001p-1022' + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + ieee754_limnum = '0x1.fffffffffffffp+507' + limnum = float.fromhex(ieee754_limnum) + + if seed == -1: + if opcode in 'fmadd': + random.seed(0) + elif opcode in 'fmsub': + random.seed(1) + elif opcode in 'fnmadd': + random.seed(2) + elif opcode in 'fnmsub': + random.seed(3) + else: + random.seed(seed) + + b17_comb = [] + + for i in range(200): + rs1 = random.uniform(minsubnorm,limnum) + rs2 = random.uniform(minsubnorm,limnum) + ir = random.uniform(minsubnorm,rs1*rs2) + + if opcode in 'fmadd': + if iflen == 32: + rs3 = ir - rs1*rs2 + elif iflen == 64: + rs3 = Decimal(ir) - Decimal(rs1)*Decimal(rs2) + elif opcode in 'fnmadd': + if iflen == 32: + rs3 = -1*rs1*rs2 - ir + elif iflen == 64: + rs3 = -1*Decimal(rs1)*Decimal(rs2) - Decimal(ir) + elif opcode in 'fmsub': + if iflen == 32: + rs3 = rs1*rs2 - ir + elif iflen == 64: + rs3 = Decimal(rs1)*Decimal(rs2) - Decimal(ir) + elif opcode in 'fnmsub': + if iflen == 32: + rs3 = ir + rs1*rs2 + elif iflen == 64: + rs3 = Decimal(ir) + Decimal(rs1)*Decimal(rs2) + + if(iflen==32): + x1 = struct.unpack('f', struct.pack('f', rs1))[0] + x2 = struct.unpack('f', struct.pack('f', rs2))[0] + elif(iflen==64): + x1 = rs1 + x2 = rs2 + + result = [] + if opcode in ['fmadd','fmsub','fnmadd','fnmsub']: + b17_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)),floatingPoint_tohex(iflen,float(rs3)))) + + coverpoints = [] + comment = ' | Multiply-Add: Cancellation' + for c in b17_comb: + cvpt = "" + for x in range(1, 4): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + # cvpt += 'rm_val == 0' + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += comment + coverpoints.append(cvpt) + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B16 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b17(flen, iflen, opcode, ops, seed=-1): + ''' + IBM Model B17 Definition: This model tests all combinations of cancellation values as in model (B16), with all possible unbiased exponent values of subnormal results. - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Intermediate Result.exp - max(addend.exp, multiplication result.exp) ∈ [-(2 * p + 1), 1] → Condition 1 (Exponents are subnormal) Operand 1 {operation 1} Operand 2 {operation 2} Operand 3 = Condition 1 - Implementation: + Implementation: - It functions the same as model B16 with calculating the additional unbiased exponent values of subnormal results. - Operands 1 and 2 are randomly initialized in the range and the subsequent operator value is found. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with rounding mode “0” for that particular opcode. - ''' - - opcode = opcode.split('.')[0] - getcontext().prec = 40 - if flen == 32: - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.000001p-126' - minsubnorm = float.fromhex(ieee754_minsubnorm) - ieee754_maxsubnorm = '0x0.7fffffp-126' - maxsubnorm = float.fromhex(ieee754_maxsubnorm) - limnum = maxnum - - elif flen == 64: - ieee754_maxnorm = '0x1.fffffffffffffp+1023' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.0000000000001p-1022' - minsubnorm = float.fromhex(ieee754_minsubnorm) - ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' - maxsubnorm = float.fromhex(ieee754_maxsubnorm) - ieee754_limnum = '0x1.fffffffffffffp+507' - limnum = float.fromhex(ieee754_limnum) - - if seed == -1: - if opcode in 'fmadd': - random.seed(0) - elif opcode in 'fmsub': - random.seed(1) - elif opcode in 'fnmadd': - random.seed(2) - elif opcode in 'fnmsub': - random.seed(3) - else: - random.seed(seed) - - b17_comb = [] - - for i in range(200): - rs1 = random.uniform(minsubnorm,limnum) - rs2 = random.uniform(minsubnorm,limnum) - ir = random.uniform(minsubnorm,maxsubnorm) - if ir > rs1*rs2: ir = random.uniform(minsubnorm,rs1*rs2) - - if opcode in 'fmadd': - if flen == 32: - rs3 = ir - rs1*rs2 - elif flen == 64: - rs3 = Decimal(ir) - Decimal(rs1)*Decimal(rs2) - elif opcode in 'fnmadd': - if flen == 32: - rs3 = -1*rs1*rs2 - ir - elif flen == 64: - rs3 = -1*Decimal(rs1)*Decimal(rs2) - Decimal(ir) - elif opcode in 'fmsub': - if flen == 32: - rs3 = rs1*rs2 - ir - elif flen == 64: - rs3 = Decimal(rs1)*Decimal(rs2) - Decimal(ir) - elif opcode in 'fnmsub': - if flen == 32: - rs3 = ir + rs1*rs2 - elif flen == 64: - rs3 = Decimal(ir) + Decimal(rs1)*Decimal(rs2) - - if(flen==32): - x1 = struct.unpack('f', struct.pack('f', rs1))[0] - x2 = struct.unpack('f', struct.pack('f', rs2))[0] - elif(flen==64): - x1 = rs1 - x2 = rs2 - - result = [] - if opcode in ['fmadd','fmsub','fnmadd','fnmsub']: - b17_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - - coverpoints = [] - comment = ' | Multiply-Add: Cancellation ---> Subnormal result ' - for c in b17_comb: - cvpt = "" - for x in range(1, 4): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += comment - coverpoints.append(cvpt) - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B17 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b18(flen, opcode, ops, seed=-1): - ''' - IBM Model B18 Definition: + ''' + + opcode = opcode.split('.')[0] + getcontext().prec = 40 + if iflen == 32: + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.000001p-126' + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = '0x0.7fffffp-126' + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + limnum = maxnum + + elif iflen == 64: + ieee754_maxnorm = '0x1.fffffffffffffp+1023' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.0000000000001p-1022' + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + ieee754_limnum = '0x1.fffffffffffffp+507' + limnum = float.fromhex(ieee754_limnum) + + if seed == -1: + if opcode in 'fmadd': + random.seed(0) + elif opcode in 'fmsub': + random.seed(1) + elif opcode in 'fnmadd': + random.seed(2) + elif opcode in 'fnmsub': + random.seed(3) + else: + random.seed(seed) + + b17_comb = [] + + for i in range(200): + rs1 = random.uniform(minsubnorm,limnum) + rs2 = random.uniform(minsubnorm,limnum) + ir = random.uniform(minsubnorm,maxsubnorm) + if ir > rs1*rs2: ir = random.uniform(minsubnorm,rs1*rs2) + + if opcode in 'fmadd': + if iflen == 32: + rs3 = ir - rs1*rs2 + elif iflen == 64: + rs3 = Decimal(ir) - Decimal(rs1)*Decimal(rs2) + elif opcode in 'fnmadd': + if iflen == 32: + rs3 = -1*rs1*rs2 - ir + elif iflen == 64: + rs3 = -1*Decimal(rs1)*Decimal(rs2) - Decimal(ir) + elif opcode in 'fmsub': + if iflen == 32: + rs3 = rs1*rs2 - ir + elif iflen == 64: + rs3 = Decimal(rs1)*Decimal(rs2) - Decimal(ir) + elif opcode in 'fnmsub': + if iflen == 32: + rs3 = ir + rs1*rs2 + elif iflen == 64: + rs3 = Decimal(ir) + Decimal(rs1)*Decimal(rs2) + + if(iflen==32): + x1 = struct.unpack('f', struct.pack('f', rs1))[0] + x2 = struct.unpack('f', struct.pack('f', rs2))[0] + elif(iflen==64): + x1 = rs1 + x2 = rs2 + + result = [] + if opcode in ['fmadd','fmsub','fnmadd','fnmsub']: + b17_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)),floatingPoint_tohex(iflen,float(rs3)))) + + coverpoints = [] + comment = ' | Multiply-Add: Cancellation ---> Subnormal result ' + for c in b17_comb: + cvpt = "" + for x in range(1, 4): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + # cvpt += 'rm_val == 0' + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += comment + coverpoints.append(cvpt) + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B17 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b18(flen, iflen, opcode, ops, seed=-1): + ''' + IBM Model B18 Definition: This model checks different cases where the multiplication causes some event in the product while the addition cancels this event. @@ -3078,327 +3130,330 @@ def ibm_b18(flen, opcode, ops, seed=-1): 2. Product: Take overflow values from (B4) "Overflow". Intermediate Result: No overflow 3. Product: Take underflow values from model (B5) "Underflow". Intermediate Result: No underflow - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Implementation: + Implementation: - Firstly, cancellation using the B3 model as base is performed. - Next model is the replica of the B4 model which takes into account the overflow of value for guard, round and sticky bits - The final model is obtained from the B5 model and different operations are done for underflow in decimal format. - The operand values are calculated using the intermediate results dataset and then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with rounding mode “0” for that particular opcode. - ''' - opcode = opcode.split('.')[0] - getcontext().prec = 40 - - if seed == -1: - if opcode in 'fmadd': - random.seed(0) - elif opcode in 'fnmadd': - random.seed(1) - elif opcode in 'fmsub': - random.seed(2) - elif opcode in 'fnmsub': - random.seed(3) - else: - random.seed(seed) - - # Cancellation of B3 - if flen == 32: - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_num = [] - lsb = [] - for i in fsubnorm+fnorm: - if int(i[-1],16)%2 == 1: - lsb.append('1') - lsb.append('1') - else: - lsb.append('0') - lsb.append('0') - float_val = float.hex(fields_dec_converter(32,i)) - if float_val[0] != '-': - ieee754_num.append(float_val.split('p')[0][0:10]+'p'+float_val.split('p')[1]) - ieee754_num.append('-'+float_val.split('p')[0][0:10]+'p'+float_val.split('p')[1]) - else: - ieee754_num.append(float_val.split('p')[0][0:11]+'p'+float_val.split('p')[1]) - ieee754_num.append(float_val.split('p')[0][1:11]+'p'+float_val.split('p')[1]) - - ir_dataset = [] - for k in range(len(ieee754_num)): - for i in range(2,16,2): - grs = '{:04b}'.format(i) - if ieee754_num[k][0] == '-': sign = '1' - else: sign = '0' - ir_dataset.append([ieee754_num[k].split('p')[0]+str(i)+'p'+ieee754_num[k].split('p')[1],' | Guard = '+grs[0]+' Sticky = '+grs[2]+' Sign = '+sign+' LSB = '+lsb[k] + ': Multiply add - Guard & Sticky Cancellation']) - - for i in range(len(ir_dataset)): - ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) - - elif flen == 64: - maxdec = '1.7976931348623157e+308' - maxnum = float.fromhex('0x1.fffffffffffffp+1023') - ieee754_num = [] - lsb = [] - for i in dsubnorm+dnorm: - if int(i[-1],16)%2 == 1: - lsb.append('1') - lsb.append('1') - else: - lsb.append('0') - lsb.append('0') - float_val = str(fields_dec_converter(64,i)) - if float_val[0] != '-': - ieee754_num.append(float_val) - ieee754_num.append('-'+float_val) - else: - ieee754_num.append(float_val) - ieee754_num.append(float_val[1:]) - - ir_dataset = [] - for k in range(len(ieee754_num)): - for i in range(2,16,2): - grs = '{:04b}'.format(i) - if ieee754_num[k][0] == '-': sign = '1' - else: sign = '0' - ir_dataset.append([str(Decimal(ieee754_num[k].split('e')[0])+Decimal(pow(i*16,-14)))+'e'+ieee754_num[k].split('e')[1],' | Guard = '+grs[0]+' Sticky = '+grs[2]+' Sign = '+sign+' LSB = '+lsb[k] + ': Multiply add - Guard & Sticky Cancellation']) - - b18_comb = [] - - for i in range(len(ir_dataset)): - rs1 = random.uniform(1,maxnum) - res = '0x1.7ffff0p+100' - res = float.fromhex(res) - if opcode in 'fmadd': - if flen == 32: - rs2 = ir_dataset[i][0]/rs1 - rs3 = res - ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) - rs3 = Decimal(res) - Decimal(ir_dataset[i][0]) - elif opcode in 'fnmadd': - if flen == 32: - rs2 = -1*ir_dataset[i][0]/rs1 - rs3 = -1*res + ir_dataset[i][0] - elif flen == 64: - rs2 = -1*Decimal(ir_dataset[i][0])/Decimal(rs1) - rs3 = -1*Decimal(res) - Decimal(ir_dataset[i][0]) - elif opcode in 'fmsub': - if flen == 32: - rs2 = ir_dataset[i][0]/rs1 - rs3 = ir_dataset[i][0] - res - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) - rs3 = Decimal(ir_dataset[i][0]) - Decimal(res) - elif opcode in 'fnmsub': - if flen == 32: - rs2 = -1*ir_dataset[i][0]/rs1 - rs3 = res - ir_dataset[i][0] - elif flen == 64: - rs2 = -1*Decimal(ir_dataset[i][0])/Decimal(rs1) - rs3 = Decimal(res) - Decimal(ir_dataset[i][0]) - - if(flen==32): - x1 = struct.unpack('f', struct.pack('f', rs1))[0] - x2 = struct.unpack('f', struct.pack('f', rs2))[0] - x3 = struct.unpack('f', struct.pack('f', rs3))[0] - elif(flen==64): - x1 = rs1 - x2 = rs2 - x3 = rs3 - - if opcode in ['fmadd','fnmadd','fmsub','fnmsub']: - b18_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - ir_dataset1 = ir_dataset + ''' + opcode = opcode.split('.')[0] + getcontext().prec = 40 + + if seed == -1: + if opcode in 'fmadd': + random.seed(0) + elif opcode in 'fnmadd': + random.seed(1) + elif opcode in 'fmsub': + random.seed(2) + elif opcode in 'fnmsub': + random.seed(3) + else: + random.seed(seed) + + # Cancellation of B3 + if iflen == 32: + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_num = [] + lsb = [] + for i in fsubnorm+fnorm: + if int(i[-1],16)%2 == 1: + lsb.append('1') + lsb.append('1') + else: + lsb.append('0') + lsb.append('0') + float_val = float.hex(fields_dec_converter(32,i)) + if float_val[0] != '-': + ieee754_num.append(float_val.split('p')[0][0:10]+'p'+float_val.split('p')[1]) + ieee754_num.append('-'+float_val.split('p')[0][0:10]+'p'+float_val.split('p')[1]) + else: + ieee754_num.append(float_val.split('p')[0][0:11]+'p'+float_val.split('p')[1]) + ieee754_num.append(float_val.split('p')[0][1:11]+'p'+float_val.split('p')[1]) + + ir_dataset = [] + for k in range(len(ieee754_num)): + for i in range(2,16,2): + grs = '{:04b}'.format(i) + if ieee754_num[k][0] == '-': sign = '1' + else: sign = '0' + ir_dataset.append([ieee754_num[k].split('p')[0]+str(i)+'p'+ieee754_num[k].split('p')[1],' | Guard = '+grs[0]+' Sticky = '+grs[2]+' Sign = '+sign+' LSB = '+lsb[k] + ': Multiply add - Guard & Sticky Cancellation']) + + for i in range(len(ir_dataset)): + ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) + + elif iflen == 64: + maxdec = '1.7976931348623157e+308' + maxnum = float.fromhex('0x1.fffffffffffffp+1023') + ieee754_num = [] + lsb = [] + for i in dsubnorm+dnorm: + if int(i[-1],16)%2 == 1: + lsb.append('1') + lsb.append('1') + else: + lsb.append('0') + lsb.append('0') + float_val = str(fields_dec_converter(64,i)) + if float_val[0] != '-': + ieee754_num.append(float_val) + ieee754_num.append('-'+float_val) + else: + ieee754_num.append(float_val) + ieee754_num.append(float_val[1:]) + + ir_dataset = [] + for k in range(len(ieee754_num)): + for i in range(2,16,2): + grs = '{:04b}'.format(i) + if ieee754_num[k][0] == '-': sign = '1' + else: sign = '0' + ir_dataset.append([str(Decimal(ieee754_num[k].split('e')[0])+Decimal(pow(i*16,-14)))+'e'+ieee754_num[k].split('e')[1],' | Guard = '+grs[0]+' Sticky = '+grs[2]+' Sign = '+sign+' LSB = '+lsb[k] + ': Multiply add - Guard & Sticky Cancellation']) + + b18_comb = [] + + for i in range(len(ir_dataset)): + rs1 = random.uniform(1,maxnum) + res = '0x1.7ffff0p+100' + res = float.fromhex(res) + if opcode in 'fmadd': + if iflen == 32: + rs2 = ir_dataset[i][0]/rs1 + rs3 = res - ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) + rs3 = Decimal(res) - Decimal(ir_dataset[i][0]) + elif opcode in 'fnmadd': + if iflen == 32: + rs2 = -1*ir_dataset[i][0]/rs1 + rs3 = -1*res + ir_dataset[i][0] + elif iflen == 64: + rs2 = -1*Decimal(ir_dataset[i][0])/Decimal(rs1) + rs3 = -1*Decimal(res) - Decimal(ir_dataset[i][0]) + elif opcode in 'fmsub': + if iflen == 32: + rs2 = ir_dataset[i][0]/rs1 + rs3 = ir_dataset[i][0] - res + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) + rs3 = Decimal(ir_dataset[i][0]) - Decimal(res) + elif opcode in 'fnmsub': + if iflen == 32: + rs2 = -1*ir_dataset[i][0]/rs1 + rs3 = res - ir_dataset[i][0] + elif iflen == 64: + rs2 = -1*Decimal(ir_dataset[i][0])/Decimal(rs1) + rs3 = Decimal(res) - Decimal(ir_dataset[i][0]) + + if(iflen==32): + x1 = struct.unpack('f', struct.pack('f', rs1))[0] + x2 = struct.unpack('f', struct.pack('f', rs2))[0] + x3 = struct.unpack('f', struct.pack('f', rs3))[0] + elif(iflen==64): + x1 = rs1 + x2 = rs2 + x3 = rs3 + + if opcode in ['fmadd','fnmadd','fmsub','fnmsub']: + b18_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)),floatingPoint_tohex(iflen,float(rs3)))) + ir_dataset1 = ir_dataset # Cancellation of B4 - if flen == 32: - ieee754_maxnorm_p = '0x1.7fffffp+127' - ieee754_maxnorm_n = '0x1.7ffffep+127' - maxnum = float.fromhex(ieee754_maxnorm_p) - ir_dataset = [] - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([ieee754_maxnorm_p.split('p')[0]+str(i)+'p'+ieee754_maxnorm_p.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm + '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Overflow Cancellation']) - ir_dataset.append([ieee754_maxnorm_n.split('p')[0]+str(i)+'p'+ieee754_maxnorm_n.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm - '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Overflow Cancellation']) - for i in range(len(ir_dataset)): - ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) - elif flen == 64: - maxnum = float.fromhex('0x1.fffffffffffffp+1023') - maxdec_p = str(maxnum) - maxdec_n = str(float.fromhex('0x1.ffffffffffffep+1023')) - ir_dataset = [] - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([str(Decimal(maxdec_p.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+maxdec_p.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm + '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Overflow Cancellation']) - ir_dataset.append([str(Decimal(maxdec_n.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+maxdec_n.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm - '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Overflow Cancellation']) - - for i in range(len(ir_dataset)): - rs1 = random.uniform(1,maxnum) - res = '0x1.7ffff0p+100' - res = float.fromhex(res) - if opcode in 'fmadd': - if flen == 32: - rs2 = ir_dataset[i][0]/rs1 - rs3 = res - ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) - rs3 = Decimal(res) - Decimal(ir_dataset[i][0]) - elif opcode in 'fnmadd': - if flen == 32: - rs2 = -1*ir_dataset[i][0]/rs1 - rs3 = -1*res + ir_dataset[i][0] - elif flen == 64: - rs2 = -1*Decimal(ir_dataset[i][0])/Decimal(rs1) - rs3 = -1*Decimal(res) - Decimal(ir_dataset[i][0]) - elif opcode in 'fmsub': - if flen == 32: - rs2 = ir_dataset[i][0]/rs1 - rs3 = ir_dataset[i][0] - res - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) - rs3 = Decimal(ir_dataset[i][0]) - Decimal(res) - elif opcode in 'fnmsub': - if flen == 32: - rs2 = -1*ir_dataset[i][0]/rs1 - rs3 = res - ir_dataset[i][0] - elif flen == 64: - rs2 = -1*Decimal(ir_dataset[i][0])/Decimal(rs1) - rs3 = Decimal(res) - Decimal(ir_dataset[i][0]) - - if(flen==32): - x1 = struct.unpack('f', struct.pack('f', rs1))[0] - x2 = struct.unpack('f', struct.pack('f', rs2))[0] - x3 = struct.unpack('f', struct.pack('f', rs3))[0] - elif(flen==64): - x1 = rs1 - x2 = rs2 - x3 = rs3 - - if opcode in ['fmadd','fnmadd','fmsub','fnmsub']: - b18_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - ir_dataset2 = ir_dataset - - # Cancellation of B5 - if flen == 32: - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.000001p-126' - ir_dataset = [] - for i in range(0,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([ieee754_minsubnorm.split('p')[0]+str(i)+'p'+ieee754_minsubnorm.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minsubnorm + '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Underflow Cancellation']) - ieee754_minnorm = '0x1.000000p-126' - for i in range(0,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([ieee754_minnorm.split('p')[0]+str(i)+'p'+ieee754_minnorm.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minnorm + '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Underflow Cancellation']) - n = len(ir_dataset) - for i in range(n): - ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) - ir_dataset.append([-1*ir_dataset[i][0],ir_dataset[i][1]]) - - elif flen == 64: - maxdec = '1.7976931348623157e+308' - maxnum = float.fromhex('0x1.fffffffffffffp+1023') - minsubdec = '5e-324' - ir_dataset = [] - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([str(Decimal(minsubdec.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+minsubdec.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minsubnorm + '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Underflow Cancellation']) - minnormdec = '2.2250738585072014e-308' - ir_dataset.append([minsubdec, ' | Guard = 0 Round = 0 Sticky = 0 --> Minsubnorm + 0 ulp']) - ir_dataset.append([minnormdec,' | Guard = 0 Round = 0 Sticky = 0 --> Minnorm + 0 ulp']) - for i in range(2,16,2): - grs = '{:04b}'.format(i) - ir_dataset.append([str(Decimal(minnormdec.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+minnormdec.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minnorm + '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Underflow Cancellation']) - n = len(ir_dataset) - for i in range(n): - ir_dataset.append(['-'+ir_dataset[i][0],ir_dataset[i][1]]) - - for i in range(len(ir_dataset)): - rs1 = random.uniform(1,maxnum) - res = '0x1.7ffff0p+100' - res = float.fromhex(res) - if opcode in 'fmadd': - if flen == 32: - rs2 = ir_dataset[i][0]/rs1 - rs3 = res - ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) - rs3 = Decimal(res) - Decimal(ir_dataset[i][0]) - elif opcode in 'fnmadd': - if flen == 32: - rs2 = -1*ir_dataset[i][0]/rs1 - rs3 = -1*res + ir_dataset[i][0] - elif flen == 64: - rs2 = -1*Decimal(ir_dataset[i][0])/Decimal(rs1) - rs3 = -1*Decimal(res) - Decimal(ir_dataset[i][0]) - elif opcode in 'fmsub': - if flen == 32: - rs2 = ir_dataset[i][0]/rs1 - rs3 = ir_dataset[i][0] - res - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) - rs3 = Decimal(ir_dataset[i][0]) - Decimal(res) - elif opcode in 'fnmsub': - if flen == 32: - rs2 = -1*ir_dataset[i][0]/rs1 - rs3 = res - ir_dataset[i][0] - elif flen == 64: - rs2 = -1*Decimal(ir_dataset[i][0])/Decimal(rs1) - rs3 = Decimal(res) - Decimal(ir_dataset[i][0]) - - if(flen==32): - x1 = struct.unpack('f', struct.pack('f', rs1))[0] - x2 = struct.unpack('f', struct.pack('f', rs2))[0] - x3 = struct.unpack('f', struct.pack('f', rs3))[0] - elif(flen==64): - x1 = rs1 - x2 = rs2 - x3 = rs3 - - if opcode in ['fmadd','fnmadd','fmsub','fnmsub']: - b18_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - ir_dataset3 = ir_dataset - - ir_dataset = ir_dataset1 + ir_dataset2 + ir_dataset3 - coverpoints = [] - k = 0 - for c in b18_comb: - cvpt = "" - for x in range(1, ops+1): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += ir_dataset[k][1] - coverpoints.append(cvpt) - k=k+1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B18 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b19(flen, opcode, ops, seed=-1): - ''' - IBM Model B19 Definition: + if iflen == 32: + ieee754_maxnorm_p = '0x1.7fffffp+127' + ieee754_maxnorm_n = '0x1.7ffffep+127' + maxnum = float.fromhex(ieee754_maxnorm_p) + ir_dataset = [] + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([ieee754_maxnorm_p.split('p')[0]+str(i)+'p'+ieee754_maxnorm_p.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm + '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Overflow Cancellation']) + ir_dataset.append([ieee754_maxnorm_n.split('p')[0]+str(i)+'p'+ieee754_maxnorm_n.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm - '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Overflow Cancellation']) + for i in range(len(ir_dataset)): + ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) + elif iflen == 64: + maxnum = float.fromhex('0x1.fffffffffffffp+1023') + maxdec_p = str(maxnum) + maxdec_n = str(float.fromhex('0x1.ffffffffffffep+1023')) + ir_dataset = [] + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([str(Decimal(maxdec_p.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+maxdec_p.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm + '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Overflow Cancellation']) + ir_dataset.append([str(Decimal(maxdec_n.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+maxdec_n.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm - '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Overflow Cancellation']) + + for i in range(len(ir_dataset)): + rs1 = random.uniform(1,maxnum) + res = '0x1.7ffff0p+100' + res = float.fromhex(res) + if opcode in 'fmadd': + if iflen == 32: + rs2 = ir_dataset[i][0]/rs1 + rs3 = res - ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) + rs3 = Decimal(res) - Decimal(ir_dataset[i][0]) + elif opcode in 'fnmadd': + if iflen == 32: + rs2 = -1*ir_dataset[i][0]/rs1 + rs3 = -1*res + ir_dataset[i][0] + elif iflen == 64: + rs2 = -1*Decimal(ir_dataset[i][0])/Decimal(rs1) + rs3 = -1*Decimal(res) - Decimal(ir_dataset[i][0]) + elif opcode in 'fmsub': + if iflen == 32: + rs2 = ir_dataset[i][0]/rs1 + rs3 = ir_dataset[i][0] - res + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) + rs3 = Decimal(ir_dataset[i][0]) - Decimal(res) + elif opcode in 'fnmsub': + if iflen == 32: + rs2 = -1*ir_dataset[i][0]/rs1 + rs3 = res - ir_dataset[i][0] + elif iflen == 64: + rs2 = -1*Decimal(ir_dataset[i][0])/Decimal(rs1) + rs3 = Decimal(res) - Decimal(ir_dataset[i][0]) + + if(iflen==32): + x1 = struct.unpack('f', struct.pack('f', rs1))[0] + x2 = struct.unpack('f', struct.pack('f', rs2))[0] + x3 = struct.unpack('f', struct.pack('f', rs3))[0] + elif(iflen==64): + x1 = rs1 + x2 = rs2 + x3 = rs3 + + if opcode in ['fmadd','fnmadd','fmsub','fnmsub']: + b18_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)),floatingPoint_tohex(iflen,float(rs3)))) + ir_dataset2 = ir_dataset + + # Cancellation of B5 + if iflen == 32: + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.000001p-126' + ir_dataset = [] + for i in range(0,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([ieee754_minsubnorm.split('p')[0]+str(i)+'p'+ieee754_minsubnorm.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minsubnorm + '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Underflow Cancellation']) + ieee754_minnorm = '0x1.000000p-126' + for i in range(0,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([ieee754_minnorm.split('p')[0]+str(i)+'p'+ieee754_minnorm.split('p')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minnorm + '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Underflow Cancellation']) + n = len(ir_dataset) + for i in range(n): + ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) + ir_dataset.append([-1*ir_dataset[i][0],ir_dataset[i][1]]) + + elif iflen == 64: + maxdec = '1.7976931348623157e+308' + maxnum = float.fromhex('0x1.fffffffffffffp+1023') + minsubdec = '5e-324' + ir_dataset = [] + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([str(Decimal(minsubdec.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+minsubdec.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minsubnorm + '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Underflow Cancellation']) + minnormdec = '2.2250738585072014e-308' + ir_dataset.append([minsubdec, ' | Guard = 0 Round = 0 Sticky = 0 --> Minsubnorm + 0 ulp']) + ir_dataset.append([minnormdec,' | Guard = 0 Round = 0 Sticky = 0 --> Minnorm + 0 ulp']) + for i in range(2,16,2): + grs = '{:04b}'.format(i) + ir_dataset.append([str(Decimal(minnormdec.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+minnormdec.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minnorm + '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Underflow Cancellation']) + n = len(ir_dataset) + for i in range(n): + ir_dataset.append(['-'+ir_dataset[i][0],ir_dataset[i][1]]) + + for i in range(len(ir_dataset)): + rs1 = random.uniform(1,maxnum) + res = '0x1.7ffff0p+100' + res = float.fromhex(res) + if opcode in 'fmadd': + if iflen == 32: + rs2 = ir_dataset[i][0]/rs1 + rs3 = res - ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) + rs3 = Decimal(res) - Decimal(ir_dataset[i][0]) + elif opcode in 'fnmadd': + if iflen == 32: + rs2 = -1*ir_dataset[i][0]/rs1 + rs3 = -1*res + ir_dataset[i][0] + elif iflen == 64: + rs2 = -1*Decimal(ir_dataset[i][0])/Decimal(rs1) + rs3 = -1*Decimal(res) - Decimal(ir_dataset[i][0]) + elif opcode in 'fmsub': + if iflen == 32: + rs2 = ir_dataset[i][0]/rs1 + rs3 = ir_dataset[i][0] - res + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) + rs3 = Decimal(ir_dataset[i][0]) - Decimal(res) + elif opcode in 'fnmsub': + if iflen == 32: + rs2 = -1*ir_dataset[i][0]/rs1 + rs3 = res - ir_dataset[i][0] + elif iflen == 64: + rs2 = -1*Decimal(ir_dataset[i][0])/Decimal(rs1) + rs3 = Decimal(res) - Decimal(ir_dataset[i][0]) + + if(iflen==32): + x1 = struct.unpack('f', struct.pack('f', rs1))[0] + x2 = struct.unpack('f', struct.pack('f', rs2))[0] + x3 = struct.unpack('f', struct.pack('f', rs3))[0] + elif(iflen==64): + x1 = rs1 + x2 = rs2 + x3 = rs3 + + if opcode in ['fmadd','fnmadd','fmsub','fnmsub']: + b18_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)),floatingPoint_tohex(iflen,float(rs3)))) + ir_dataset3 = ir_dataset + + ir_dataset = ir_dataset1 + ir_dataset2 + ir_dataset3 + coverpoints = [] + k = 0 + for c in b18_comb: + cvpt = "" + for x in range(1, ops+1): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + # cvpt += 'rm_val == 0' + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += ir_dataset[k][1] + coverpoints.append(cvpt) + k=k+1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B18 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b19(flen, iflen, opcode, ops, seed=-1): + ''' + IBM Model B19 Definition: This model checks various possible differences between the two inputs. A test-case will be created for each combination of the following table:: @@ -3409,154 +3464,159 @@ def ibm_b19(flen, opcode, ops, seed=-1): -SubNormal -SubNormal 0 0 - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Operand1 {operation} Operand2 = Derived from the table above - Implementation: + Implementation: - Normal (positive and negative), subnormal (positive and negative) arrays are randomly initialized within their respectively declared ranges. - The difference between exponents and significands are formed as per the conditions in the table. - All possible combinations of the table are used in creating the test-cases. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - - opcode = opcode.split('.')[0] - getcontext().prec = 40 - if flen == 32: - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.000001p-126' - minsubnorm = float.fromhex(ieee754_minsubnorm) - ieee754_maxsubnorm = '0x0.7fffffp-126' - maxsubnorm = float.fromhex(ieee754_maxsubnorm) - limnum = maxnum - - elif flen == 64: - ieee754_maxnorm = '0x1.fffffffffffffp+1023' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.0000000000001p-1022' - minsubnorm = float.fromhex(ieee754_minsubnorm) - ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' - maxsubnorm = float.fromhex(ieee754_maxsubnorm) - ieee754_limnum = '0x1.fffffffffffffp+507' - limnum = float.fromhex(ieee754_limnum) - - if seed == -1: - if opcode in 'fmin': - random.seed(0) - elif opcode in 'fmax': - random.seed(1) - elif opcode in 'flt': - random.seed(2) - elif opcode in 'feq': - random.seed(3) - elif opcode in 'fle': - random.seed(3) - else: - random.seed(seed) - - b19_comb = [] - comment = [] - normal = [] - normal_neg = [] - sub_normal = [] - sub_normal_neg = [] - zero = [[0e0,'Zero']] - for i in range(5): - normal.append([random.uniform(1,maxnum),'Normal']) - normal_neg.append([random.uniform(-1*maxnum,-1),'-Normal']) - sub_normal.append([random.uniform(minsubnorm,maxsubnorm),'Subnormal']) - sub_normal_neg.append([random.uniform(-1*maxsubnorm,-1*minsubnorm),'-Subnormal']) - - all_num = normal + normal_neg + sub_normal + sub_normal_neg + zero - for i in all_num: - for j in all_num: - if i[0] != 0: - i_sig = str(i[0]).split('e')[0] - i_exp = str(i[0]).split('e')[1] - else: - i_sig = '0' - i_exp = '0' - if j[0] != 0: - j_sig = str(j[0]).split('e')[0] - j_exp = str(j[0]).split('e')[1] - else: - j_sig = '0' - j_exp = '0' - if float(i_sig) >= float(j_sig): sig_sign = '>=' - else: sig_sign = '<' - if float(i_exp) >= float(j_exp): exp_sign = '>=' - else: exp_sign = '<' - rs1 = float(i_sig+'e'+i_exp) - rs2 = float(j_sig+'e'+j_exp) - b19_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(' | rs1 --> ' + i[1] + ', rs2 --> ' + j[1] + ', rs1_sigificand ' + sig_sign + ' rs2_significand' + ', rs1_exp ' + exp_sign + ' rs2_exp') - rs1 = float(i_sig+'e'+j_exp) - rs2 = float(j_sig+'e'+i_exp) - b19_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(' | rs1 --> ' + j[1] + ', rs2 --> ' + i[1] + ', rs1_sigificand ' + sig_sign + ' rs2_significand' + ', rs2_exp ' + exp_sign + ' rs1_exp') - rs1 = float(j_sig+'e'+i_exp) - rs2 = float(i_sig+'e'+j_exp) - b19_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(' | rs1 --> ' + j[1] + ', rs2 --> ' + i[1] + ', rs2_sigificand ' + sig_sign + ' rs1_significand' + ', rs1_exp ' + exp_sign + ' rs2_exp') - rs1 = float(i_sig+'e'+j_exp) - rs2 = float(j_sig+'e'+j_exp) - b19_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(' | rs1 --> ' + j[1] + ', rs2 --> ' + j[1] + ', rs1_sigificand ' + sig_sign + ' rs2_significand' + ', rs1_exp = rs2_exp') - rs1 = float(i_sig+'e'+i_exp) - rs2 = float(i_sig+'e'+j_exp) - b19_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(' | rs1 --> ' + i[1] + ', rs2 --> ' + j[1] + ', rs1_sigificand = rs2_significand' + ', rs1_exp ' + exp_sign + ' rs2_exp') - rs1 = float(i_sig+'e'+i_exp) - rs2 = float(i_sig+'e'+i_exp) - b19_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - comment.append(' | rs1 --> ' + i[1] + ', rs2 --> ' + i[1] + ', rs1_sigificand = rs2_significand, rs1_exp = rs2_exp') - - coverpoints = [] - k = 0 - for c in b19_comb: - cvpt = "" - for x in range(1, 3): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - if opcode in ["fadd","fsub","fmul","fdiv","fsqrt","fmadd","fnmadd","fmsub","fnmsub","fcvt","fmv","fle","fmv","fmin","fsgnj"]: - cvpt += 'rm_val == 0' - elif opcode in ["fclass","flt","fmax","fsgnjn"]: - cvpt += 'rm_val == 1' - elif opcode in ["feq","flw","fsw","fsgnjx"]: - cvpt += 'rm_val == 2' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += comment[k] - coverpoints.append(cvpt) - k += 1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B19 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b20(flen, opcode, ops, seed=-1): - ''' - IBM Model B20 Definition: + ''' + + opcode = opcode.split('.')[0] + getcontext().prec = 40 + if iflen == 32: + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.000001p-126' + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = '0x0.7fffffp-126' + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + limnum = maxnum + + elif iflen == 64: + ieee754_maxnorm = '0x1.fffffffffffffp+1023' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.0000000000001p-1022' + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + ieee754_limnum = '0x1.fffffffffffffp+507' + limnum = float.fromhex(ieee754_limnum) + + if seed == -1: + if opcode in 'fmin': + random.seed(0) + elif opcode in 'fmax': + random.seed(1) + elif opcode in 'flt': + random.seed(2) + elif opcode in 'feq': + random.seed(3) + elif opcode in 'fle': + random.seed(3) + else: + random.seed(seed) + + b19_comb = [] + comment = [] + normal = [] + normal_neg = [] + sub_normal = [] + sub_normal_neg = [] + zero = [[0e0,'Zero']] + for i in range(5): + normal.append([random.uniform(1,maxnum),'Normal']) + normal_neg.append([random.uniform(-1*maxnum,-1),'-Normal']) + sub_normal.append([random.uniform(minsubnorm,maxsubnorm),'Subnormal']) + sub_normal_neg.append([random.uniform(-1*maxsubnorm,-1*minsubnorm),'-Subnormal']) + + all_num = normal + normal_neg + sub_normal + sub_normal_neg + zero + for i in all_num: + for j in all_num: + if i[0] != 0: + i_sig = str(i[0]).split('e')[0] + i_exp = str(i[0]).split('e')[1] + else: + i_sig = '0' + i_exp = '0' + if j[0] != 0: + j_sig = str(j[0]).split('e')[0] + j_exp = str(j[0]).split('e')[1] + else: + j_sig = '0' + j_exp = '0' + if float(i_sig) >= float(j_sig): sig_sign = '>=' + else: sig_sign = '<' + if float(i_exp) >= float(j_exp): exp_sign = '>=' + else: exp_sign = '<' + rs1 = float(i_sig+'e'+i_exp) + rs2 = float(j_sig+'e'+j_exp) + b19_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(' | rs1 --> ' + i[1] + ', rs2 --> ' + j[1] + ', rs1_sigificand ' + sig_sign + ' rs2_significand' + ', rs1_exp ' + exp_sign + ' rs2_exp') + rs1 = float(i_sig+'e'+j_exp) + rs2 = float(j_sig+'e'+i_exp) + b19_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(' | rs1 --> ' + j[1] + ', rs2 --> ' + i[1] + ', rs1_sigificand ' + sig_sign + ' rs2_significand' + ', rs2_exp ' + exp_sign + ' rs1_exp') + rs1 = float(j_sig+'e'+i_exp) + rs2 = float(i_sig+'e'+j_exp) + b19_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(' | rs1 --> ' + j[1] + ', rs2 --> ' + i[1] + ', rs2_sigificand ' + sig_sign + ' rs1_significand' + ', rs1_exp ' + exp_sign + ' rs2_exp') + rs1 = float(i_sig+'e'+j_exp) + rs2 = float(j_sig+'e'+j_exp) + b19_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(' | rs1 --> ' + j[1] + ', rs2 --> ' + j[1] + ', rs1_sigificand ' + sig_sign + ' rs2_significand' + ', rs1_exp = rs2_exp') + rs1 = float(i_sig+'e'+i_exp) + rs2 = float(i_sig+'e'+j_exp) + b19_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(' | rs1 --> ' + i[1] + ', rs2 --> ' + j[1] + ', rs1_sigificand = rs2_significand' + ', rs1_exp ' + exp_sign + ' rs2_exp') + rs1 = float(i_sig+'e'+i_exp) + rs2 = float(i_sig+'e'+i_exp) + b19_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + comment.append(' | rs1 --> ' + i[1] + ', rs2 --> ' + i[1] + ', rs1_sigificand = rs2_significand, rs1_exp = rs2_exp') + + coverpoints = [] + k = 0 + for c in b19_comb: + cvpt = "" + for x in range(1, 3): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + if opcode in ["fadd","fsub","fmul","fdiv","fsqrt","fmadd","fnmadd","fmsub","fnmsub","fcvt","fmv","fle","fmv","fmin","fsgnj"]: + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + # cvpt += 'rm_val == 0' + elif opcode in ["fclass","flt","fmax","fsgnjn"]: + cvpt = sanitise_cvpt(1,cvpt,iflen,flen) + # cvpt += 'rm_val == 1' + elif opcode in ["feq","flw","fsw","fsgnjx"]: + cvpt = sanitise_cvpt(2,cvpt,iflen,flen) + # cvpt += 'rm_val == 2' + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += comment[k] + coverpoints.append(cvpt) + k += 1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B19 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b20(flen, iflen, opcode, ops, seed=-1): + ''' + IBM Model B20 Definition: This model will create test-cases such that the significand of the intermediate results will cover each of the following patterns: Mask on the intermediate result significand (excluding the leading “1” ) @@ -3575,187 +3635,190 @@ def ibm_b20(flen, opcode, ops, seed=-1): The sticky bit of the intermediate result should always be 0. In case of the remainder operation, we will look at the result of the division in order to find the interesting test-cases. Operation: Divide, Square-root. - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Intermediate Results = [Random bits are taken initially to form xxx...xxx10. The pattern described above is then formed] Operand1 {operation} Operand2 = Intermediate Results - Implementation: + Implementation: - A loop is initiated where random bits are obtained for which the subsequent sign, exponent is calculated for the intermediate value and stored in the ir_dataset. - Operand 1 (rs1) is randomly initialized in the range (1, limnum) and the subsequent operator value is found. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - opcode = opcode.split('.')[0] - getcontext().prec = 60 - - if seed == -1: - if opcode in 'fdiv': - random.seed(1) - elif opcode in 'fsqrt': - random.seed(2) - else: - random.seed(seed) - - if flen == 32: - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.000001p-126' - minsubnorm = float.fromhex(ieee754_minsubnorm) - ieee754_maxsubnorm = '0x0.7fffffp-126' - maxsubnorm = float.fromhex(ieee754_maxsubnorm) - limnum = maxnum - ir_dataset = [] - for i in range(1,21,1): - for k in range(5): - bits = random.getrandbits(i) - bits = bin(bits)[2:] - front_zero = i-len(bits) - bits = '0'*front_zero + bits - trailing_zero = 22-i - sig = bits+'1'+'0'*trailing_zero - - exp = random.getrandbits(8) - exp = '{:08b}'.format(exp) - - sgn = random.getrandbits(1) - sgn = '{:01b}'.format(sgn) - - ir_bin = ('0b'+sgn+exp+sig) - ir = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) - ir_dataset.append([ir, ' | Intermediate result significand: ' + sig + ' Pattern: ' + 'X'*i + '1' + '0'*trailing_zero]) - - sig = '1'+'0'*22 - exp = random.getrandbits(8) - exp = '{:08b}'.format(exp) - sgn = random.getrandbits(1) - sgn = '{:01b}'.format(sgn) - ir_bin = ('0b'+sgn+exp+sig) - ir = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) - ir_dataset.append([ir, 'Intermediate result significand: '+ sig + ' Pattern: ' + '1' + '0'*22]) - - sig = '0'*23 - exp = random.getrandbits(8) - exp = '{:08b}'.format(exp) - sgn = random.getrandbits(1) - sgn = '{:01b}'.format(sgn) - ir_bin = ('0b'+sgn+exp+sig) - ir = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) - ir_dataset.append([ir, 'Intermediate result significand: '+ sig + ' Pattern: ' + '0' + '0'*22]) - - elif flen == 64: - ieee754_maxnorm = '0x1.fffffffffffffp+1023' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.0000000000001p-1022' - minsubnorm = float.fromhex(ieee754_minsubnorm) - ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' - maxsubnorm = float.fromhex(ieee754_maxsubnorm) - ieee754_limnum = '0x1.fffffffffffffp+507' - limnum = float.fromhex(ieee754_limnum) - ieee754_num = [] - ir_dataset = [] - for i in range(1,50,1): - for k in range(5): - bits = random.getrandbits(i) - bits = bin(bits)[2:] - front_zero = i-len(bits) - bits = '0'*front_zero + bits - trailing_zero = 51-i - sig = bits+'1'+'0'*trailing_zero - - exp = random.getrandbits(11) - exp = '{:011b}'.format(exp) - - sgn = random.getrandbits(1) - sgn = '{:01b}'.format(sgn) - - ir_bin = ('0b'+sgn+exp+sig) - ir = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) - ir_dataset.append([ir, ' | Intermediate result significand: ' + sig + ' Pattern: ' + 'X'*i + '1' + '0'*trailing_zero]) - - sig = '1'+'0'*51 - exp = random.getrandbits(8) - exp = '{:08b}'.format(exp) - sgn = random.getrandbits(1) - sgn = '{:01b}'.format(sgn) - ir_bin = ('0b'+sgn+exp+sig) - ir = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) - ir_dataset.append([ir, 'Intermediate result significand: '+ sig + ' Pattern: ' + '1' + '0'*51]) - - sig = '0'*52 - exp = random.getrandbits(8) - exp = '{:08b}'.format(exp) - sgn = random.getrandbits(1) - sgn = '{:01b}'.format(sgn) - ir_bin = ('0b'+sgn+exp+sig) - ir = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) - ir_dataset.append([ir, 'Intermediate result significand: ' + sig + ' Pattern: ' + '0' + '0'*52]) - - b8_comb = [] - for i in range(len(ir_dataset)): - rs1 = random.uniform(1, limnum) - if opcode in 'fdiv': - if flen == 32: - rs2 = rs1/ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) - elif opcode in 'fsqrt': - if flen == 32: - rs2 = ir_dataset[i][0]*ir_dataset[i][0] - elif flen == 64: - rs2 = Decimal(ir_dataset[i][0])*Decimal(ir_dataset[i][0]) - - if(flen==32): - x1 = struct.unpack('f', struct.pack('f', rs1))[0] - x2 = struct.unpack('f', struct.pack('f', rs2))[0] - elif(flen==64): - x1 = rs1 - x2 = rs2 - - if opcode in ['fdiv']: - b8_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - elif opcode in 'fsqrt': - b8_comb.append((floatingPoint_tohex(flen,float(rs2)),)) - - coverpoints = [] - k=0 - for c in b8_comb: - cvpt = "" - for x in range(1, ops+1): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += ir_dataset[k][1] - coverpoints.append(cvpt) - k=k+1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B20 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b21(flen, opcode, ops): - ''' - IBM Model B21 Definition: + ''' + opcode = opcode.split('.')[0] + getcontext().prec = 60 + + if seed == -1: + if opcode in 'fdiv': + random.seed(1) + elif opcode in 'fsqrt': + random.seed(2) + else: + random.seed(seed) + + if iflen == 32: + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.000001p-126' + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = '0x0.7fffffp-126' + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + limnum = maxnum + ir_dataset = [] + for i in range(1,21,1): + for k in range(5): + bits = random.getrandbits(i) + bits = bin(bits)[2:] + front_zero = i-len(bits) + bits = '0'*front_zero + bits + trailing_zero = 22-i + sig = bits+'1'+'0'*trailing_zero + + exp = random.getrandbits(8) + exp = '{:08b}'.format(exp) + + sgn = random.getrandbits(1) + sgn = '{:01b}'.format(sgn) + + ir_bin = ('0b'+sgn+exp+sig) + ir = fields_dec_converter(iflen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) + ir_dataset.append([ir, ' | Intermediate result significand: ' + sig + ' Pattern: ' + 'X'*i + '1' + '0'*trailing_zero]) + + sig = '1'+'0'*22 + exp = random.getrandbits(8) + exp = '{:08b}'.format(exp) + sgn = random.getrandbits(1) + sgn = '{:01b}'.format(sgn) + ir_bin = ('0b'+sgn+exp+sig) + ir = fields_dec_converter(iflen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) + ir_dataset.append([ir, 'Intermediate result significand: '+ sig + ' Pattern: ' + '1' + '0'*22]) + + sig = '0'*23 + exp = random.getrandbits(8) + exp = '{:08b}'.format(exp) + sgn = random.getrandbits(1) + sgn = '{:01b}'.format(sgn) + ir_bin = ('0b'+sgn+exp+sig) + ir = fields_dec_converter(iflen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) + ir_dataset.append([ir, 'Intermediate result significand: '+ sig + ' Pattern: ' + '0' + '0'*22]) + + elif iflen == 64: + ieee754_maxnorm = '0x1.fffffffffffffp+1023' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.0000000000001p-1022' + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + ieee754_limnum = '0x1.fffffffffffffp+507' + limnum = float.fromhex(ieee754_limnum) + ieee754_num = [] + ir_dataset = [] + for i in range(1,50,1): + for k in range(5): + bits = random.getrandbits(i) + bits = bin(bits)[2:] + front_zero = i-len(bits) + bits = '0'*front_zero + bits + trailing_zero = 51-i + sig = bits+'1'+'0'*trailing_zero + + exp = random.getrandbits(11) + exp = '{:011b}'.format(exp) + + sgn = random.getrandbits(1) + sgn = '{:01b}'.format(sgn) + + ir_bin = ('0b'+sgn+exp+sig) + ir = fields_dec_converter(iflen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) + ir_dataset.append([ir, ' | Intermediate result significand: ' + sig + ' Pattern: ' + 'X'*i + '1' + '0'*trailing_zero]) + + sig = '1'+'0'*51 + exp = random.getrandbits(8) + exp = '{:08b}'.format(exp) + sgn = random.getrandbits(1) + sgn = '{:01b}'.format(sgn) + ir_bin = ('0b'+sgn+exp+sig) + ir = fields_dec_converter(iflen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) + ir_dataset.append([ir, 'Intermediate result significand: '+ sig + ' Pattern: ' + '1' + '0'*51]) + + sig = '0'*52 + exp = random.getrandbits(8) + exp = '{:08b}'.format(exp) + sgn = random.getrandbits(1) + sgn = '{:01b}'.format(sgn) + ir_bin = ('0b'+sgn+exp+sig) + ir = fields_dec_converter(iflen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) + ir_dataset.append([ir, 'Intermediate result significand: ' + sig + ' Pattern: ' + '0' + '0'*52]) + + b8_comb = [] + for i in range(len(ir_dataset)): + rs1 = random.uniform(1, limnum) + if opcode in 'fdiv': + if iflen == 32: + rs2 = rs1/ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) + elif opcode in 'fsqrt': + if iflen == 32: + rs2 = ir_dataset[i][0]*ir_dataset[i][0] + elif iflen == 64: + rs2 = Decimal(ir_dataset[i][0])*Decimal(ir_dataset[i][0]) + + if(iflen==32): + x1 = struct.unpack('f', struct.pack('f', rs1))[0] + x2 = struct.unpack('f', struct.pack('f', rs2))[0] + elif(iflen==64): + x1 = rs1 + x2 = rs2 + + if opcode in ['fdiv']: + b8_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + elif opcode in 'fsqrt': + b8_comb.append((floatingPoint_tohex(iflen,float(rs2)),)) + + coverpoints = [] + k=0 + for c in b8_comb: + cvpt = "" + for x in range(1, ops+1): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + # cvpt += 'rm_val == 0' + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += ir_dataset[k][1] + coverpoints.append(cvpt) + k=k+1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B20 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b21(flen, iflen, opcode, ops): + ''' + IBM Model B21 Definition: This model will test the Divide By Zero exception flag. For the operations divide and remainder, a test case will be created for each of the possible combinations from the following table: First Operand : 0, Random non-zero number, Infinity, NaN @@ -3763,63 +3826,65 @@ def ibm_b21(flen, opcode, ops): Operation: Divide, Remainder - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode - :type flen: int - :type opcode: str - :type ops: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int - Abstract Dataset Description: + Abstract Dataset Description: Final Results = [ Zero, Subnorm, Norm, Infinity, DefaultNaN, QNaN, SNaN ] - Implementation: + Implementation: - The basic_types dataset is accumulated with the combinations of the abstract dataset description. - Using python’s package itertools, a permutation of all possible combinations as a pair is computed for basic_types dataset.. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - if flen == 32: - basic_types = fzero + fsubnorm + fnorm + finfinity + fdefaultnan + [fqnan[0], fqnan[3]] + \ - [fsnan[0], fsnan[3]] - elif flen == 64: - basic_types = dzero + dsubnorm + dnorm +\ - dinfinity + ddefaultnan + [dqnan[0], dqnan[1]] + \ - [dsnan[0], dsnan[1]] - else: - logger.error('Invalid flen value!') - sys.exit(1) + ''' + if iflen == 32: + basic_types = fzero + fsubnorm + fnorm + finfinity + fdefaultnan + [fqnan[0], fqnan[3]] + \ + [fsnan[0], fsnan[3]] + elif iflen == 64: + basic_types = dzero + dsubnorm + dnorm +\ + dinfinity + ddefaultnan + [dqnan[0], dqnan[1]] + \ + [dsnan[0], dsnan[1]] + else: + logger.error('Invalid iflen value!') + sys.exit(1) # the following creates a cross product for ops number of variables - b21_comb = list(itertools.product(*ops*[basic_types])) - coverpoints = [] - for c in b21_comb: - cvpt = "" - for x in range(1, ops+1): + b21_comb = list(itertools.product(*ops*[basic_types])) + coverpoints = [] + for c in b21_comb: + cvpt = "" + for x in range(1, ops+1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - if opcode.split('.')[0] in ["fdiv"]: - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - coverpoints.append(cvpt) - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B21 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b22(flen, opcode, ops, seed=10): - ''' - IBM Model B22 Definition: + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + if opcode.split('.')[0] in ["fdiv"]: + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + coverpoints.append(cvpt) + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B21 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b22(flen, iflen, opcode, ops, seed=10): + ''' + IBM Model B22 Definition: This model creates test cases for each of the following exponents (unbiased): 1. Smaller than -3 @@ -3828,190 +3893,193 @@ def ibm_b22(flen, opcode, ops, seed=10): For each exponent two cases will be randomly chosen, positive and negative. - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Operand1 = [Smaller than -3, All the values in the range [-3, integer width+3], Larger than integer width + 3] - Implementation: + Implementation: - Random bits are calculated and appended to obtain the exponent ranges defined in case 2. - To satisfy case 1 and case 3, similar steps are performed outside the loop and hence updated in the loop. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - - opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] - if opcode[2] == 's': flen = 32 - elif opcode[2] == 'd': flen = 64 - getcontext().prec = 40 - xlen = 0 - - if opcode in 'fcvt.w': - xlen = 32 - elif opcode in 'fcvt.l': - xlen = 64 - elif opcode in 'fcvt.wu': - xlen = 32 - elif opcode in 'fcvt.lu': - xlen = 64 - - if seed == -1: - if opcode in 'fcvt.w': - random.seed(0) - elif opcode in 'fcvt.l': - random.seed(1) - elif opcode in 'fcvt.wu': - random.seed(2) - elif opcode in 'fcvt.lu': - random.seed(3) - else: - random.seed(seed) - - b22_comb = [] - - if flen == 32: - ieee754_maxnorm = '0x1.7fffffp+127' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.000001p-126' - minsubnorm = float.fromhex(ieee754_minsubnorm) - ieee754_maxsubnorm = '0x0.7fffffp-126' - maxsubnorm = float.fromhex(ieee754_maxsubnorm) - limnum = maxnum - op_dataset = [] - for i in range(124,xlen+130,1): - bits = random.getrandbits(23) - bits = bin(bits)[2:] - front_zero = 23-len(bits) - sig = '0'*front_zero + bits - - exp = i - exp = '{:08b}'.format(exp) - - sgn = random.getrandbits(1) - sgn = '{:01b}'.format(sgn) - - ir_bin = ('0b'+sgn+exp+sig) - op = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) - op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-127) + ', Exponent in the range [-3, integer width+3]']) - b22_comb.append((floatingPoint_tohex(flen,float(op)),)) - - bits = random.getrandbits(23) - bits = bin(bits)[2:] - front_zero = 23-len(bits) - sig = '0'*front_zero + bits - exp = random.randint(0,124) - exp = '{:08b}'.format(exp) - sgn = random.getrandbits(1) - sgn = '{:01b}'.format(sgn) - ir_bin = ('0b'+sgn+exp+sig) - op = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) - op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-127) + ', Exponent less than -3']) - b22_comb.append((floatingPoint_tohex(flen,float(op)),)) - - bits = random.getrandbits(23) - bits = bin(bits)[2:] - front_zero = 23-len(bits) - sig = '0'*front_zero + bits - exp = random.randint(xlen+130,255) - exp = '{:08b}'.format(exp) - sgn = random.getrandbits(1) - sgn = '{:01b}'.format(sgn) - ir_bin = ('0b'+sgn+exp+sig) - op = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) - op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-127) + ', Exponent greater than (integer width+3)']) - b22_comb.append((floatingPoint_tohex(flen,float(op)),)) - - elif flen == 64: - ieee754_maxnorm = '0x1.fffffffffffffp+1023' - maxnum = float.fromhex(ieee754_maxnorm) - ieee754_minsubnorm = '0x0.0000000000001p-1022' - minsubnorm = float.fromhex(ieee754_minsubnorm) - ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' - maxsubnorm = float.fromhex(ieee754_maxsubnorm) - ieee754_limnum = '0x1.fffffffffffffp+507' - limnum = float.fromhex(ieee754_limnum) - op_dataset = [] - for i in range(1020,xlen+1026,1): - bits = random.getrandbits(52) - bits = bin(bits)[2:] - front_zero = 52-len(bits) - sig = '0'*front_zero + bits - - exp = i - exp = '{:011b}'.format(exp) - - sgn = random.getrandbits(1) - sgn = '{:01b}'.format(sgn) - - ir_bin = ('0b'+sgn+exp+sig) - op = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) - op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-1023) + ', Exponent in the range [-3, integer width+3]']) - b22_comb.append((floatingPoint_tohex(flen,float(op)),)) - - bits = random.getrandbits(52) - bits = bin(bits)[2:] - front_zero = 52-len(bits) - sig = '0'*front_zero + bits - exp = random.randint(0,1020) - exp = '{:011b}'.format(exp) - sgn = random.getrandbits(1) - sgn = '{:01b}'.format(sgn) - ir_bin = ('0b'+sgn+exp+sig) - op = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) - op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-1023) + ', Exponent less than -3']) - b22_comb.append((floatingPoint_tohex(flen,float(op)),)) - - bits = random.getrandbits(52) - bits = bin(bits)[2:] - front_zero = 52-len(bits) - sig = '0'*front_zero + bits - exp = random.randint(xlen+1026,2047) - exp = '{:011b}'.format(exp) - sgn = random.getrandbits(1) - sgn = '{:01b}'.format(sgn) - ir_bin = ('0b'+sgn+exp+sig) - op = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) - op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-1023) + ', Exponent greater than (integer width+3)']) - b22_comb.append((floatingPoint_tohex(flen,float(op)),)) - - coverpoints = [] - k=0 - for c in b22_comb: - cvpt = "" - for x in range(1, 2): -# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += op_dataset[k][1] - coverpoints.append(cvpt) - k=k+1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B22 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b23(flen, opcode, ops): - ''' - IBM Model B23 Definition: + ''' + + opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] + if opcode[2] == 's': iflen = 32 + elif opcode[2] == 'd': iflen = 64 + getcontext().prec = 40 + xlen = 0 + + if opcode in 'fcvt.w': + xlen = 32 + elif opcode in 'fcvt.l': + xlen = 64 + elif opcode in 'fcvt.wu': + xlen = 32 + elif opcode in 'fcvt.lu': + xlen = 64 + + if seed == -1: + if opcode in 'fcvt.w': + random.seed(0) + elif opcode in 'fcvt.l': + random.seed(1) + elif opcode in 'fcvt.wu': + random.seed(2) + elif opcode in 'fcvt.lu': + random.seed(3) + else: + random.seed(seed) + + b22_comb = [] + + if iflen == 32: + ieee754_maxnorm = '0x1.7fffffp+127' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.000001p-126' + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = '0x0.7fffffp-126' + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + limnum = maxnum + op_dataset = [] + for i in range(124,xlen+130,1): + bits = random.getrandbits(23) + bits = bin(bits)[2:] + front_zero = 23-len(bits) + sig = '0'*front_zero + bits + + exp = i + exp = '{:08b}'.format(exp) + + sgn = random.getrandbits(1) + sgn = '{:01b}'.format(sgn) + + ir_bin = ('0b'+sgn+exp+sig) + op = fields_dec_converter(iflen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) + op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-127) + ', Exponent in the range [-3, integer width+3]']) + b22_comb.append((floatingPoint_tohex(iflen,float(op)),)) + + bits = random.getrandbits(23) + bits = bin(bits)[2:] + front_zero = 23-len(bits) + sig = '0'*front_zero + bits + exp = random.randint(0,124) + exp = '{:08b}'.format(exp) + sgn = random.getrandbits(1) + sgn = '{:01b}'.format(sgn) + ir_bin = ('0b'+sgn+exp+sig) + op = fields_dec_converter(iflen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) + op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-127) + ', Exponent less than -3']) + b22_comb.append((floatingPoint_tohex(iflen,float(op)),)) + + bits = random.getrandbits(23) + bits = bin(bits)[2:] + front_zero = 23-len(bits) + sig = '0'*front_zero + bits + exp = random.randint(xlen+130,255) + exp = '{:08b}'.format(exp) + sgn = random.getrandbits(1) + sgn = '{:01b}'.format(sgn) + ir_bin = ('0b'+sgn+exp+sig) + op = fields_dec_converter(iflen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) + op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-127) + ', Exponent greater than (integer width+3)']) + b22_comb.append((floatingPoint_tohex(iflen,float(op)),)) + + elif iflen == 64: + ieee754_maxnorm = '0x1.fffffffffffffp+1023' + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = '0x0.0000000000001p-1022' + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + ieee754_limnum = '0x1.fffffffffffffp+507' + limnum = float.fromhex(ieee754_limnum) + op_dataset = [] + for i in range(1020,xlen+1026,1): + bits = random.getrandbits(52) + bits = bin(bits)[2:] + front_zero = 52-len(bits) + sig = '0'*front_zero + bits + + exp = i + exp = '{:011b}'.format(exp) + + sgn = random.getrandbits(1) + sgn = '{:01b}'.format(sgn) + + ir_bin = ('0b'+sgn+exp+sig) + op = fields_dec_converter(iflen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) + op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-1023) + ', Exponent in the range [-3, integer width+3]']) + b22_comb.append((floatingPoint_tohex(iflen,float(op)),)) + + bits = random.getrandbits(52) + bits = bin(bits)[2:] + front_zero = 52-len(bits) + sig = '0'*front_zero + bits + exp = random.randint(0,1020) + exp = '{:011b}'.format(exp) + sgn = random.getrandbits(1) + sgn = '{:01b}'.format(sgn) + ir_bin = ('0b'+sgn+exp+sig) + op = fields_dec_converter(iflen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) + op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-1023) + ', Exponent less than -3']) + b22_comb.append((floatingPoint_tohex(iflen,float(op)),)) + + bits = random.getrandbits(52) + bits = bin(bits)[2:] + front_zero = 52-len(bits) + sig = '0'*front_zero + bits + exp = random.randint(xlen+1026,2047) + exp = '{:011b}'.format(exp) + sgn = random.getrandbits(1) + sgn = '{:01b}'.format(sgn) + ir_bin = ('0b'+sgn+exp+sig) + op = fields_dec_converter(iflen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) + op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-1023) + ', Exponent greater than (integer width+3)']) + b22_comb.append((floatingPoint_tohex(iflen,float(op)),)) + + coverpoints = [] + k=0 + for c in b22_comb: + cvpt = "" + for x in range(1, 2): +# cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + # cvpt += 'rm_val == 0' + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += op_dataset[k][1] + coverpoints.append(cvpt) + k=k+1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B22 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b23(flen, iflen, opcode, ops): + ''' + IBM Model B23 Definition: This model creates boundary cases for the rounding to integers that might cause Overflow. A test case will be created with inputs equal to the maximum integer number in the destination's format (MaxInt), or close to it. In particular, the following FP numbers will be used: @@ -4023,78 +4091,82 @@ def ibm_b23(flen, opcode, ops): Rounding Mode: All - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode - :type flen: int - :type opcode: str - :type ops: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int - Abstract Dataset Description: + Abstract Dataset Description: Operand 1 = [ MaxInt-4, MaxInt+5 ] - Implementation: + Implementation: - In the range of (-4,5), the dataset array is appended with the hexadecimal equivalent of maxnum plus the iteration number in a string format. The next highest encoding of the hexadecimal value is calculated. - - This is done with different values of maxnum for flen=32 or flen=64. + - This is done with different values of maxnum for iflen=32 or iflen=64. - Since this model is meant for floating point conversion instructions, only one operand is expected. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - - opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] - - getcontext().prec = 40 - - operations = ['+','-'] - nums = [0,100,200,800,1600] - dataset = [] - - if flen == 32: - maxnum = 0x4f000000 # MaxInt (2**31-1) in IEEE 754 Floating Point Representation - - for i in range(-4,5): - dataset.append((hex(int(maxnum)+i),"| MaxInt + ({})".format(str(i)))) - elif flen == 64: - maxnum = 0x43e0000000000000 - - for i in range(-4,5): - dataset.append((hex(int(maxnum)+i),"| MaxInt + ({})".format(str(i)))) - - coverpoints = [] - k=0 - for c in dataset: - for rm in range(0,5): - cvpt = "" - for x in range(1, ops+1): - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == ' - if "fmv" in opcode or opcode in "fcvt.d.s": - cvpt += '0' - else: - cvpt += str(rm) - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += " "+c[1] - coverpoints.append(cvpt) - k=k+1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B23 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return (coverpoints) - -def ibm_b24(flen, opcode, ops): - ''' - IBM Model B24 Definition: + ''' + + opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] + + getcontext().prec = 40 + + operations = ['+','-'] + nums = [0,100,200,800,1600] + dataset = [] + + if iflen == 32: + maxnum = 0x4f000000 # MaxInt (2**31-1) in IEEE 754 Floating Point Representation + + for i in range(-4,5): + dataset.append((hex(int(maxnum)+i),"| MaxInt + ({})".format(str(i)))) + elif iflen == 64: + maxnum = 0x43e0000000000000 + + for i in range(-4,5): + dataset.append((hex(int(maxnum)+i),"| MaxInt + ({})".format(str(i)))) + + coverpoints = [] + k=0 + for c in dataset: + for rm in range(0,5): + cvpt = "" + for x in range(1, ops+1): + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + # cvpt += 'rm_val == ' + if "fmv" in opcode or opcode in "fcvt.d.s": + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + # cvpt += '0' + else: + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + # cvpt += str(rm) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += " "+c[1] + coverpoints.append(cvpt) + k=k+1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B23 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return (coverpoints) + +def ibm_b24(flen,iflen, opcode, ops): + ''' + IBM Model B24 Definition: This model creates boundary cases for rounding to integer that might cause major loss of accuracy. A test-case will be created for each of the following inputs: @@ -4110,81 +4182,85 @@ def ibm_b24(flen, opcode, ops): Rounding Mode: All - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode - :type flen: int - :type opcode: str - :type ops: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int - Abstract Dataset Description: + Abstract Dataset Description: Operand 1 = [±0, ±0 ± 0.01, ±0 ± 0.1, ±0 ± 0.11, ±1, ±1 + 0.01, ±1 + 0.1, ±1 + 0.11] - Implementation: + Implementation: - A nested loop with 4 stages is initiated to iterate each element in minimums, nums, operations1 and operations2 for the two operands. This is done to form the dataset defined above. - - Depending on the value of flen, these values are then converted into their respective IEEE 754 hexadecimal values. + - Depending on the value of iflen, these values are then converted into their respective IEEE 754 hexadecimal values. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - - opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] - - getcontext().prec = 40 - - operations = ['+','-'] - nums = [0,0.01,0.1,0.11] - minnums = [0,1] - dataset = [] - - for minnum in minnums: - for num in nums: - for op1 in operations: - for op2 in operations: - dataset.append((eval(op1+str(minnum)+op2+str(num)),op1+str(minnum)+op2+str(num))) - - b24_comb = [] - - for data in dataset: - t = "{:e}".format(data[0]) - b24_comb.append((floatingPoint_tohex(flen,float(t)),data[1])) - - b24_comb = set(b24_comb) - - coverpoints = [] - k=0 - for c in b24_comb: - for rm in range(0,5): - cvpt = "" - for x in range(1, ops+1): - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == ' - if "fmv" in opcode or opcode in "fcvt.d.s": - cvpt += '0' - else: - cvpt += str(rm) - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += " | "+c[1] - coverpoints.append(cvpt) - k=k+1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B24 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return (coverpoints) - -def ibm_b25(flen, opcode, ops, seed=10): - ''' - IBM Model B25 Definition: + ''' + + opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] + + getcontext().prec = 40 + + operations = ['+','-'] + nums = [0,0.01,0.1,0.11] + minnums = [0,1] + dataset = [] + + for minnum in minnums: + for num in nums: + for op1 in operations: + for op2 in operations: + dataset.append((eval(op1+str(minnum)+op2+str(num)),op1+str(minnum)+op2+str(num))) + + b24_comb = [] + + for data in dataset: + t = "{:e}".format(data[0]) + b24_comb.append((floatingPoint_tohex(iflen,float(t)),data[1])) + + b24_comb = set(b24_comb) + + coverpoints = [] + k=0 + for c in b24_comb: + for rm in range(0,5): + cvpt = "" + for x in range(1, ops+1): + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + # cvpt += 'rm_val == ' + if "fmv" in opcode or opcode in "fcvt.d.s": + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + # cvpt += '0' + else: + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + # cvpt += str(rm) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += " | "+c[1] + coverpoints.append(cvpt) + k=k+1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B24 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return (coverpoints) + +def ibm_b25(flen, iflen, opcode, ops, seed=10): + ''' + IBM Model B25 Definition: This model creates a test-case for each of the following inputs: 1. ±MaxInt @@ -4192,202 +4268,211 @@ def ibm_b25(flen, opcode, ops, seed=10): 3. ±1 4. Random number - :param xlen: Size of the integer registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to 10) + :param flen: Size of the floating point registers + :param iflen: Size of the floating point source operands for the operation + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to 10) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Operand 1 = [±MaxInt, ±0, ±1, Random number] - Implementation: + Implementation: - The dataset is formed as per the dataset description. - rand_num is initialized to a random number in the range (1, maxnum). - Since this model is for an integer to floating point conversion instruction, the operands are presented in decimal format. - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - random.seed(seed) - opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] - - getcontext().prec = 40 - - operations = ['+','-'] - nums = [0,0.01,0.1,0.11] - - dataset = [(0,"0"),(1,"1"),(-1,"-1")] - - if flen == 32: - maxnum = 2**31-1 - elif flen == 64: - maxnum = 2**63-1 - - dataset.append((maxnum,"MaxInt")) - dataset.append((-1*maxnum,"-MaxInt")) - rand_num = int(random.uniform(1,maxnum)) - dataset.append((rand_num,"+ve Random Number")) - dataset.append((-1*rand_num,"-ve Random Number")) - - b25_comb = [] - - for data in dataset: - b25_comb.append((int(data[0]),data[1])) - - coverpoints = [] - k=0 - for c in b25_comb: - for rm in range(0,5): - cvpt = "" - for x in range(1, ops+1): - cvpt += "rs1_val == "+str(c[x-1]) - cvpt += " and " - cvpt += 'rm_val == ' - if "fmv" in opcode or opcode in "fcvt.d.wu": - cvpt += str(0) - else: - cvpt += str(rm) - cvpt += ' # Number = ' - cvpt += c[1] - coverpoints.append(cvpt) - k=k+1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B25 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return (coverpoints) + ''' + random.seed(seed) + opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] + + getcontext().prec = 40 + + operations = ['+','-'] + nums = [0,0.01,0.1,0.11] + + dataset = [(0,"0"),(1,"1"),(-1,"-1")] + + if iflen == 32: + maxnum = 2**31-1 + elif iflen == 64: + maxnum = 2**63-1 + + dataset.append((maxnum,"MaxInt")) + dataset.append((-1*maxnum,"-MaxInt")) + rand_num = int(random.uniform(1,maxnum)) + dataset.append((rand_num,"+ve Random Number")) + dataset.append((-1*rand_num,"-ve Random Number")) + + b25_comb = [] + + for data in dataset: + b25_comb.append((int(data[0]),data[1])) + + coverpoints = [] + k=0 + for c in b25_comb: + for rm in range(0,5): + cvpt = "" + for x in range(1, ops+1): + cvpt += "rs1_val == "+str(c[x-1]) + cvpt += " and " + # cvpt += 'rm_val == ' + if "fmv" in opcode or opcode in "fcvt.d.wu": + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + # cvpt += str(0) + else: + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + # cvpt += str(rm) + cvpt += ' # Number = ' + cvpt += c[1] + coverpoints.append(cvpt) + k=k+1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B25 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return (coverpoints) def ibm_b26(xlen, opcode, ops, seed=10): - ''' - IBM Model B26 Definition: + ''' + IBM Model B26 Definition: This model creates a test-case for each possible value of the number of significant bits in the input operand (which is an integer). A test is created with an example from each of the following ranges: [0], [1], [2,3], [4,7], [8,15], …, [(MaxInt+1)/2, MaxInt] - :param xlen: Size of the integer registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to 10) + :param xlen: Size of the integer registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to 10) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type xlen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Operand 1 = Random number in [0], [1], [2,3], [4,7], [8,15], …, [(MaxInt+1)/2, MaxInt] - Implementation: + Implementation: - A random number is chosen in the ranges defined above. - Since this model is for an integer to floating point conversion instruction, the operands are presented in decimal format. - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - random.seed(seed) - opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] - - dataset = [(0," # Number in [0]"),(1," # Number in [1]")] - - i = 3 - while(i<=2**(xlen-1)-1): - rand_num = random.randint(int((i+1)/2),i) - dataset.append((rand_num," # Random number chosen in the range: ["+str(int((i+1)/2))+", "+str(i)+"]")) - i = i*2+1 - - coverpoints = [] - k=0 - for c in dataset: - for rm in range(0,5): - cvpt = "" - for x in range(1, ops+1): - cvpt += "rs1_val == "+str(c[x-1]) - cvpt += " and " - cvpt += 'rm_val == ' - if "fmv" in opcode or opcode in "fcvt.d.wu": - cvpt += str(0) - else: - cvpt += str(rm) - cvpt += c[1] - coverpoints.append(cvpt) - k=k+1 - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ - (str(32) if xlen == 32 else str(64)) + '-bit coverpoints using Model B26 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b27(flen, opcode, ops, seed=10): - ''' - IBM Model B27 Definition: + ''' + random.seed(seed) + opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] + + dataset = [(0," # Number in [0]"),(1," # Number in [1]")] + + i = 3 + while(i<=2**(xlen-1)-1): + rand_num = random.randint(int((i+1)/2),i) + dataset.append((rand_num," # Random number chosen in the range: ["+str(int((i+1)/2))+", "+str(i)+"]")) + i = i*2+1 + + coverpoints = [] + k=0 + for c in dataset: + for rm in range(0,5): + cvpt = "" + for x in range(1, ops+1): + cvpt += "rs1_val == "+str(c[x-1]) + cvpt += " and " + # cvpt += 'rm_val == ' + if "fmv" in opcode or opcode in "fcvt.d.wu": + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + # cvpt += str(0) + else: + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + # cvpt += str(rm) + cvpt += c[1] + coverpoints.append(cvpt) + k=k+1 + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ + (str(32) if xlen == 32 else str(64)) + '-bit coverpoints using Model B26 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b27(flen, iflen, opcode, ops, seed=10): + ''' + IBM Model B27 Definition: This model tests the conversion of NaNs from a wider format to a narrow one. Each combination from the following table will create one test case (N represents the number of bits in the significand of the destination's format): [SNaN, QNaN] ==================== ========================================================= ===================== Value of the operand The N-1 MSB bits of the significand (excluding the first) The rest of the bits ==================== ========================================================= ===================== - QNaN All 0 All 0 + QNaN All 0 All 0 SNan Not all 0 Not all 0 ==================== ========================================================= ===================== - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to 10) + :param iflen: Size of the floating point source operands for the operation + :param flen: Size of the floating point registers + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to 10) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Operand 1 = [ SNaN, QNaN ] - Implementation: + Implementation: - Dataset is the combination of snan and qnan values predefined at random initially. - - Depending on the value of flen, these values are then converted into their respective IEEE 754 hexadecimal values. + - Depending on the value of iflen, these values are then converted into their respective IEEE 754 hexadecimal values. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] - - if flen == 32: - dataset = fsnan + fqnan - elif flen == 64: - dataset = dsnan + dqnan - - coverpoints = [] - for c in dataset: - cvpt = "" - for x in range(1, ops+1): - cvpt += (extract_fields(flen,c,str(x))) - cvpt += " and " - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c) + '(' + str(c) + ')' - if(y != ops): - cvpt += " and " - coverpoints.append(cvpt) - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B27 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b28(flen, opcode, ops, seed=10): - ''' - IBM Model B28 Definition: + ''' + opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] + + if iflen == 32: + dataset = fsnan + fqnan + elif iflen == 64: + dataset = dsnan + dqnan + + coverpoints = [] + for c in dataset: + cvpt = "" + for x in range(1, ops+1): + cvpt += (extract_fields(iflen,c,str(x))) + cvpt += " and " + # cvpt += 'rm_val == 0' + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c) + '(' + str(c) + ')' + if(y != ops): + cvpt += " and " + coverpoints.append(cvpt) + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B27 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b28(flen, iflen, opcode, ops, seed=10): + ''' + IBM Model B28 Definition: This model tests the conversion of a floating point number to an integral value, represented in floating-point format. A test case will be created for each of the following inputs: 1. +0 @@ -4406,171 +4491,177 @@ def ibm_b28(flen, opcode, ops, seed=10): 14.-1.11..11*2^precision 15. –Infinity - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to 10. Actual value is set with respect to the opcode calling the function) + :param flen: Size of the floating point registers + :param iflen: Size of the floating point source operands for the operation + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to 10. Actual value is set with respect to the opcode calling the function) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Operand 1 = [ ±0, ±1, ±Infinity, Default NaN, A random number in the range (+0, +1), Every value in the range (1.00, 10.11] (1 to 2.75 in jumps of 0.25), A random number in the range (+1, +1.11..11*2^precision), ±1.11..11*2^precision, A random number in the range (-1, -0), Every value in the range [-10.11, -1.00), A random number in the range (-1.11..11*2^precision , -1) ] - Implementation: - - According to the given inputs, all cases are declared and appended to the dataset for flen=32 and flen=64. + Implementation: + - According to the given inputs, all cases are declared and appended to the dataset for iflen=32 and iflen=64. - Random numbers are obtained in the respective ranges and for absolute values, it is inherited from the dataset definition. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with rounding mode “0” for that particular opcode. - ''' - random.seed(seed) - opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] - dataset = [] - - if flen == 32: - dataset.append((fzero[0],"+0")) - dataset.append((floatingPoint_tohex(32,float(random.uniform(0,1))),"A random number in the range (+0, +1)")) - dataset.append((fone[0],"+1")) - for i in range(125,300,25): - dataset.append((floatingPoint_tohex(32, i/100),"Number = "+str(i/100)+" => Number ∈ (1,2.75]")) - dataset.append((floatingPoint_tohex(32,float(random.uniform(1,2**31-1))),"A random number in the range (+1, +1.11..11*2^precision)")) - dataset.append((floatingPoint_tohex(32,float(2**31-1)),"MaxInt")) - dataset.append((finfinity[0],"+Infinity")) - - dataset.append((fsnan[0],"Signaling NaN")) - dataset.append((fqnan[0],"Quiet NaN")) - - dataset.append((fzero[1],"-0")) - dataset.append((floatingPoint_tohex(32,float(random.uniform(-1,0))),"A random number in the range (-1, -0)")) - dataset.append((fone[1],"-1")) - for i in range(-275,-100,25): - dataset.append((floatingPoint_tohex(32, i/100),"Number = "+str(i/100)+" => Number ∈ [-2.75,-1)")) - dataset.append((floatingPoint_tohex(32,float(random.uniform(-2**31-1,-1))),"A random number in the range (-1.11..11*2^precision, -1)")) - dataset.append((floatingPoint_tohex(32,float(-2**31-1)),"-MaxInt")) - dataset.append((finfinity[1],"-Infinity")) - - elif flen == 64: - dataset.append((dzero[0],"+0")) - dataset.append((floatingPoint_tohex(64,float(random.uniform(0,1))),"A random number in the range (+0, +1)")) - dataset.append((done[0],"+1")) - for i in range(125,300,25): - dataset.append((floatingPoint_tohex(64, i/100),"Number = "+str(i/100)+" => Number ∈ (1,2.75]")) - dataset.append((floatingPoint_tohex(64,float(random.uniform(1,2**63-1))),"A random number in the range (+1, +1.11..11*2^precision)")) - dataset.append((floatingPoint_tohex(64,float(2**63-1)),"MaxInt")) - dataset.append((dinfinity[0],"+Infinity")) - - dataset.append((dsnan[0],"Signaling NaN")) - dataset.append((dqnan[0],"Quiet NaN")) - - dataset.append((dzero[1],"-0")) - dataset.append((floatingPoint_tohex(64,float(random.uniform(-1,0))),"A random number in the range (-1, -0)")) - dataset.append((done[1],"-1")) - for i in range(-275,-100,25): - dataset.append((floatingPoint_tohex(64, i/100),"Number = "+str(i/100)+" => Number ∈ [-2.75,-1)")) - dataset.append((floatingPoint_tohex(64,float(random.uniform(-2**63-1,-1))),"A random number in the range (-1.11..11*2^precision, -1)")) - dataset.append((floatingPoint_tohex(64,float(-2**63-1)),"-MaxInt")) - dataset.append((dinfinity[1],"-Infinity")) - - coverpoints = [] - for c in dataset: - cvpt = "" - for x in range(1, ops+1): - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == 0' - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += " | "+c[1] - coverpoints.append(cvpt) - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B28 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints - -def ibm_b29(flen, opcode, ops, seed=10): - ''' - IBM Model B29 Definition: + ''' + random.seed(seed) + opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] + dataset = [] + + if iflen == 32: + dataset.append((fzero[0],"+0")) + dataset.append((floatingPoint_tohex(32,float(random.uniform(0,1))),"A random number in the range (+0, +1)")) + dataset.append((fone[0],"+1")) + for i in range(125,300,25): + dataset.append((floatingPoint_tohex(32, i/100),"Number = "+str(i/100)+" => Number ∈ (1,2.75]")) + dataset.append((floatingPoint_tohex(32,float(random.uniform(1,2**31-1))),"A random number in the range (+1, +1.11..11*2^precision)")) + dataset.append((floatingPoint_tohex(32,float(2**31-1)),"MaxInt")) + dataset.append((finfinity[0],"+Infinity")) + + dataset.append((fsnan[0],"Signaling NaN")) + dataset.append((fqnan[0],"Quiet NaN")) + + dataset.append((fzero[1],"-0")) + dataset.append((floatingPoint_tohex(32,float(random.uniform(-1,0))),"A random number in the range (-1, -0)")) + dataset.append((fone[1],"-1")) + for i in range(-275,-100,25): + dataset.append((floatingPoint_tohex(32, i/100),"Number = "+str(i/100)+" => Number ∈ [-2.75,-1)")) + dataset.append((floatingPoint_tohex(32,float(random.uniform(-2**31-1,-1))),"A random number in the range (-1.11..11*2^precision, -1)")) + dataset.append((floatingPoint_tohex(32,float(-2**31-1)),"-MaxInt")) + dataset.append((finfinity[1],"-Infinity")) + + elif iflen == 64: + dataset.append((dzero[0],"+0")) + dataset.append((floatingPoint_tohex(64,float(random.uniform(0,1))),"A random number in the range (+0, +1)")) + dataset.append((done[0],"+1")) + for i in range(125,300,25): + dataset.append((floatingPoint_tohex(64, i/100),"Number = "+str(i/100)+" => Number ∈ (1,2.75]")) + dataset.append((floatingPoint_tohex(64,float(random.uniform(1,2**63-1))),"A random number in the range (+1, +1.11..11*2^precision)")) + dataset.append((floatingPoint_tohex(64,float(2**63-1)),"MaxInt")) + dataset.append((dinfinity[0],"+Infinity")) + + dataset.append((dsnan[0],"Signaling NaN")) + dataset.append((dqnan[0],"Quiet NaN")) + + dataset.append((dzero[1],"-0")) + dataset.append((floatingPoint_tohex(64,float(random.uniform(-1,0))),"A random number in the range (-1, -0)")) + dataset.append((done[1],"-1")) + for i in range(-275,-100,25): + dataset.append((floatingPoint_tohex(64, i/100),"Number = "+str(i/100)+" => Number ∈ [-2.75,-1)")) + dataset.append((floatingPoint_tohex(64,float(random.uniform(-2**63-1,-1))),"A random number in the range (-1.11..11*2^precision, -1)")) + dataset.append((floatingPoint_tohex(64,float(-2**63-1)),"-MaxInt")) + dataset.append((dinfinity[1],"-Infinity")) + + coverpoints = [] + for c in dataset: + cvpt = "" + for x in range(1, ops+1): + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + # cvpt += 'rm_val == 0' + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += " | "+c[1] + coverpoints.append(cvpt) + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B28 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints + +def ibm_b29(flen, iflen, opcode, ops, seed=10): + ''' + IBM Model B29 Definition: This model checks different cases of rounding of the floating point number. A test will be created for each possible combination of the Sign, LSB, Guard bit and the Sticky bit (16 cases for each operation). Rounding Mode: All - :param flen: Size of the floating point registers - :param opcode: Opcode for which the coverpoints are to be generated - :param ops: No. of Operands taken by the opcode - :param seed: Initial seed value of the random library. (Predefined to 10) + :param flen: Size of the floating point registers + :param iflen: Size of the floating point source operands for the operation + :param opcode: Opcode for which the coverpoints are to be generated + :param ops: No. of Operands taken by the opcode + :param seed: Initial seed value of the random library. (Predefined to 10) - :type flen: int - :type opcode: str - :type ops: int - :param seed: int + :type iflen: int + :type flen: int + :type opcode: str + :type ops: int + :param seed: int - Abstract Dataset Description: + Abstract Dataset Description: Operand 1 = [All possible combinations of Sign, LSB, Guard and Sticky are taken] - Implementation: + Implementation: - A random mantissa is obtained and is iterated for each sign in each digit in the binary number. - The exponent is always maintained at -3, in order to facilitate the shift process that occurs during the actual conversion. - The respective hexadecimal values are appended to the dataset along with the respective Least, Guard and Sticky bit value wherever available. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. - ''' - random.seed(seed) - sgns = ["0","1"] - dataset = [] - if flen == 32: - mant = random.getrandbits(20) - mant = '{:020b}'.format(mant) - for sgn in sgns: - for i in range(8): - LeastGuardSticky = '{:03b}'.format(i) - hexnum = "0x" + hex(int("1"+sgn + "01111100" + mant + LeastGuardSticky,2))[3:] - dataset.append((hexnum,"Exp = -3; Sign = {}; LSB = {}; Guard = {}; Sticky = {}"\ - .format(sgn,LeastGuardSticky[0],LeastGuardSticky[1],LeastGuardSticky[2]))) - elif flen == 64: - mant = random.getrandbits(49) - mant = '{:049b}'.format(mant) - for sgn in sgns: - for i in range(8): - LeastGuardSticky = '{:03b}'.format(i) - hexnum = "0x" + hex(int("1"+sgn + "01111111100" + mant + LeastGuardSticky,2))[3:] - dataset.append((hexnum,"Exp = -3; Sign = {}; LSB = {}; Guard = {}; Sticky = {}"\ - .format(sgn,LeastGuardSticky[0],LeastGuardSticky[1],LeastGuardSticky[2]))) - - coverpoints = [] - for c in dataset: - for rm in range(0,5): - cvpt = "" - for x in range(1, ops+1): - cvpt += (extract_fields(flen,c[x-1],str(x))) - cvpt += " and " - cvpt += 'rm_val == ' - if "fmv" in opcode or "fcvt.d.s" in opcode: - cvpt += '0' - else: - cvpt += str(rm) - cvpt += ' # ' - for y in range(1, ops+1): - cvpt += 'rs'+str(y)+'_val==' - cvpt += num_explain(flen, c[y-1]) + '(' + str(c[y-1]) + ')' - if(y != ops): - cvpt += " and " - cvpt += " | "+c[1] - coverpoints.append(cvpt) - - mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ - (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B29 for '+opcode+' !' - logger.debug(mess) - coverpoints = comments_parser(coverpoints) - - return coverpoints + ''' + random.seed(seed) + sgns = ["0","1"] + dataset = [] + if iflen == 32: + mant = random.getrandbits(20) + mant = '{:020b}'.format(mant) + for sgn in sgns: + for i in range(8): + LeastGuardSticky = '{:03b}'.format(i) + hexnum = "0x" + hex(int("1"+sgn + "01111100" + mant + LeastGuardSticky,2))[3:] + dataset.append((hexnum,"Exp = -3; Sign = {}; LSB = {}; Guard = {}; Sticky = {}"\ + .format(sgn,LeastGuardSticky[0],LeastGuardSticky[1],LeastGuardSticky[2]))) + elif iflen == 64: + mant = random.getrandbits(49) + mant = '{:049b}'.format(mant) + for sgn in sgns: + for i in range(8): + LeastGuardSticky = '{:03b}'.format(i) + hexnum = "0x" + hex(int("1"+sgn + "01111111100" + mant + LeastGuardSticky,2))[3:] + dataset.append((hexnum,"Exp = -3; Sign = {}; LSB = {}; Guard = {}; Sticky = {}"\ + .format(sgn,LeastGuardSticky[0],LeastGuardSticky[1],LeastGuardSticky[2]))) + + coverpoints = [] + for c in dataset: + for rm in range(0,5): + cvpt = "" + for x in range(1, ops+1): + cvpt += (extract_fields(iflen,c[x-1],str(x))) + cvpt += " and " + cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + # cvpt += 'rm_val == ' + if "fmv" in opcode or "fcvt.d.s" in opcode: + cvpt += '0' + else: + cvpt += str(rm) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1]) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + cvpt += " | "+c[1] + coverpoints.append(cvpt) + + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ + (str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B29 for '+opcode+' !' + logger.debug(mess) + coverpoints = comments_parser(coverpoints) + + return coverpoints diff --git a/riscv_isac/isac.py b/riscv_isac/isac.py index 2055efc0..c766681b 100644 --- a/riscv_isac/isac.py +++ b/riscv_isac/isac.py @@ -6,7 +6,7 @@ from elftools.elf.elffile import ELFFile 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, no_count, procs, logging=False): + sig_labels, dump, cov_labels, xlen, flen, no_count, procs, logging=False): test_addr = [] sig_addr = [] if parser_path: @@ -37,7 +37,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, test_addr, dump, cov_labels, sig_addr, window_size, 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, no_count, procs) if output_file is not None and logging: logger.info('Coverage Report:') logger.info('\n\n' + rpt) diff --git a/riscv_isac/main.py b/riscv_isac/main.py index aa55b0f8..2a0223d4 100644 --- a/riscv_isac/main.py +++ b/riscv_isac/main.py @@ -113,6 +113,11 @@ def cli(verbose): default='32', help="XLEN value for the ISA." ) +@click.option('--flen','-f', + type=click.Choice(['32','64']), + default='32', + help="FLEN value for the ISA." +) @click.option('--no-count', is_flag = True, help = "This option removes hit coverpoints during coverage computation" @@ -123,7 +128,7 @@ def cli(verbose): ) def coverage(elf,trace_file, window_size, cgf_file, detailed,parser_name, decoder_name, parser_path, decoder_path,output_file, test_label, - sig_label, dump,cov_label, xlen, no_count, procs): + sig_label, dump,cov_label, xlen, flen, no_count, procs): isac(output_file,elf,trace_file, window_size, expand_cgf(cgf_file,int(xlen)), parser_name, decoder_name, parser_path, decoder_path, detailed, test_label, sig_label, dump, cov_label, int(xlen), no_count, procs) @@ -180,10 +185,11 @@ def merge(files,detailed,p,cgf_file,output_file,xlen): required = True ) @click.option('--xlen','-x',type=click.Choice(['32','64']),default='32',help="XLEN value for the ISA.") -def normalize(cgf_file,output_file,xlen): +@click.option('--flen','-f',type=click.Choice(['32','64']),default='32',help="FLEN value for the ISA.") +def normalize(cgf_file,output_file,xlen,flen): logger.info("Writing normalized CGF to "+str(output_file)) with open(output_file,"w") as outfile: - utils.dump_yaml(expand_cgf(cgf_file,int(xlen)),outfile) + utils.dump_yaml(expand_cgf(cgf_file,int(xlen),int(flen)),outfile) @cli.command(help = 'Setup the plugin which uses the information from RISCV Opcodes repository to decode.') @click.option('--url', From 825ff76c72bc50a9654d4c836970b589c4d078d3 Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Thu, 26 May 2022 00:18:38 +0530 Subject: [PATCH 02/20] Speed up CGF normalisation and fixed minor bugs in fp_dataset gen. --- riscv_isac/cgf_normalize.py | 7 +++++-- riscv_isac/fp_dataset.py | 33 ++++++++++++++++++--------------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/riscv_isac/cgf_normalize.py b/riscv_isac/cgf_normalize.py index 4463aeed..7224f018 100644 --- a/riscv_isac/cgf_normalize.py +++ b/riscv_isac/cgf_normalize.py @@ -579,6 +579,8 @@ def expand_cgf(cgf_files, xlen,flen): if len(cgf[labels]['mnemonics'].keys()) > 1: logger.error(f'Multiple instruction mnemonics found when base_op label defined in {labels} label.') + l = len(cats.items()) + i = 0 for label,node in cats.items(): if isinstance(node,dict): if 'abstract_comb' in node: @@ -590,9 +592,10 @@ def expand_cgf(cgf_files, xlen,flen): exp_cp = eval(coverpoints) except Exception as e: logger.error("Error evaluating abstract comb: "+(coverpoints)\ - +" in "+labels) + +" in "+labels+": "+str(e) ) else: for cp,comment in exp_cp: - cgf[labels][label].insert(1,cp,coverage,comment=comment) + cgf[labels][label].insert(l+i,cp,coverage,comment=comment) + i += 1 return dict(cgf) diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index 009415b1..6118ce06 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -34,7 +34,10 @@ rounding_modes = ['0','1','2','3','4'] -sanitise_cvpt = lambda rm,x,iflen,flen: x + ' fcsr == '+hex(rm<<5) \ +sanitise_cvpt = lambda rm,x,iflen,flen: x + ' fcsr == '+hex(rm<<5) + ' and rm_val == 7 ' \ + + ('' if iflen == flen else (' and nan_prefix == 0x' + 'f'*int((flen-iflen)/4))) + +sanitise_norm = lambda x,iflen,flen: x + ' fcsr == 0'\ + ('' if iflen == flen else (' and nan_prefix == 0x' + 'f'*int((flen-iflen)/4))) def num_explain(flen,num): @@ -306,12 +309,11 @@ def ibm_b1(flen, iflen, opcode, ops): for x in range(1, ops+1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) + " and " - if opcode.split('.')[0] in ["fadd","fsub","fmul","fdiv","fsqrt","fmadd","fnmadd","fmsub","fnmsub","fcvt","fmv","fle","fmv","fmin","fsgnj"]: + if opcode.split('.')[0] in ["fadd","fsub","fmul","fdiv","fsqrt","fmadd","fnmadd","fmsub","fnmsub","fcvt","fmv"]: cvpt = sanitise_cvpt(0,cvpt,iflen,flen) - elif opcode.split('.')[0] in ["fclass","flt","fmax","fsgnjn"]: - cvpt = sanitise_cvpt(1,cvpt,iflen,flen) - elif opcode.split('.')[0] in ["feq","flw","fsw","fsgnjx"]: - cvpt = sanitise_cvpt(2,cvpt,iflen,flen) + elif opcode.split('.')[0] in \ + ["fclass","flt","fmax","fsgnjn","fmin","fsgnj","feq","flw","fsw","fsgnjx","fld","fle"]: + cvpt = sanitise_norm(cvpt,iflen,flen) cvpt += ' # ' for y in range(1, ops+1): @@ -1209,7 +1211,7 @@ def ibm_b6(flen, iflen, opcode, ops, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = santise_cvpt(rm,cvpt,iflen,flen) + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) # cvpt += 'rm_val == '+str(rm) cvpt += ' # ' for y in range(1, ops+1): @@ -1401,7 +1403,7 @@ def ibm_b7(flen, iflen, opcode, ops, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 3' - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + cvpt = sanitise_cvpt(3,cvpt,iflen,flen) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3588,14 +3590,15 @@ def ibm_b19(flen, iflen, opcode, ops, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - if opcode in ["fadd","fsub","fmul","fdiv","fsqrt","fmadd","fnmadd","fmsub","fnmsub","fcvt","fmv","fle","fmv","fmin","fsgnj"]: + if opcode in ["fadd","fsub","fmul","fdiv","fsqrt","fmadd","fnmadd","fmsub","fnmsub","fcvt","fmv"]: cvpt = sanitise_cvpt(0,cvpt,iflen,flen) # cvpt += 'rm_val == 0' - elif opcode in ["fclass","flt","fmax","fsgnjn"]: - cvpt = sanitise_cvpt(1,cvpt,iflen,flen) + elif opcode in ["fclass","flt","fmax","fsgnjn","fle","fmin","fsgnj","feq", + "flw","fsw","fsgnjx","fld","fsd"]: + cvpt = sanitise_norm(cvpt,iflen,flen) # cvpt += 'rm_val == 1' - elif opcode in ["feq","flw","fsw","fsgnjx"]: - cvpt = sanitise_cvpt(2,cvpt,iflen,flen) + # elif opcode in []: + # cvpt = sanitise_cvpt(2,cvpt,iflen,flen) # cvpt += 'rm_val == 2' cvpt += ' # ' for y in range(1, ops+1): @@ -4389,10 +4392,10 @@ def ibm_b26(xlen, opcode, ops, seed=10): cvpt += " and " # cvpt += 'rm_val == ' if "fmv" in opcode or opcode in "fcvt.d.wu": - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,xlen,xlen) # cvpt += str(0) else: - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + cvpt = sanitise_cvpt(rm,cvpt,xlen,xlen) # cvpt += str(rm) cvpt += c[1] coverpoints.append(cvpt) From cc97afac75dd003f2af45542425d87bde4c0aed3 Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Mon, 30 May 2022 22:28:26 +0530 Subject: [PATCH 03/20] Fix nan_box variable generation in cvpts. --- riscv_isac/fp_dataset.py | 80 ++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index 6118ce06..0a42da1a 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -34,11 +34,13 @@ rounding_modes = ['0','1','2','3','4'] -sanitise_cvpt = lambda rm,x,iflen,flen: x + ' fcsr == '+hex(rm<<5) + ' and rm_val == 7 ' \ - + ('' if iflen == flen else (' and nan_prefix == 0x' + 'f'*int((flen-iflen)/4))) +sanitise_cvpt = lambda rm,x,iflen,flen,c: x + ' fcsr == '+hex(rm<<5) + ' and rm_val == 7 ' \ + + ('' if iflen == flen else ''.join([' and rs'+str(x)+'_nan_prefix == 0x' \ + + 'f'*int((flen-iflen)/4) for x in range(1,c+1)])) -sanitise_norm = lambda x,iflen,flen: x + ' fcsr == 0'\ - + ('' if iflen == flen else (' and nan_prefix == 0x' + 'f'*int((flen-iflen)/4))) +sanitise_norm = lambda x,iflen,flen,c: x + ' fcsr == 0'\ + + ('' if iflen == flen else ''.join([' and rs'+str(x)+'_nan_prefix == 0x' \ + + 'f'*int((flen-iflen)/4) for x in range(1,c+1)])) def num_explain(flen,num): num_dict = { @@ -310,10 +312,10 @@ def ibm_b1(flen, iflen, opcode, ops): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) + " and " if opcode.split('.')[0] in ["fadd","fsub","fmul","fdiv","fsqrt","fmadd","fnmadd","fmsub","fnmsub","fcvt","fmv"]: - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) elif opcode.split('.')[0] in \ ["fclass","flt","fmax","fsgnjn","fmin","fsgnj","feq","flw","fsw","fsgnjx","fld","fle"]: - cvpt = sanitise_norm(cvpt,iflen,flen) + cvpt = sanitise_norm(cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): @@ -461,7 +463,7 @@ def ibm_b2(flen, iflen, opcode, ops, int_val = 100, seed = -1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -670,7 +672,7 @@ def ibm_b3(flen,iflen, opcode, ops, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == '+str(rm) - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -851,7 +853,7 @@ def ibm_b4(flen, iflen, opcode, ops, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == '+str(rm) - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1052,7 +1054,7 @@ def ibm_b5(flen, iflen, opcode, ops, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == '+str(rm) - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1211,7 +1213,7 @@ def ibm_b6(flen, iflen, opcode, ops, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) # cvpt += 'rm_val == '+str(rm) cvpt += ' # ' for y in range(1, ops+1): @@ -1403,7 +1405,7 @@ def ibm_b7(flen, iflen, opcode, ops, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 3' - cvpt = sanitise_cvpt(3,cvpt,iflen,flen) + cvpt = sanitise_cvpt(3,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1594,7 +1596,7 @@ def ibm_b8(flen, iflen, opcode, ops, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) # cvpt += 'rm_val == '+str(rm) cvpt += ' # ' for y in range(1, ops+1): @@ -1801,7 +1803,7 @@ def ibm_b9(flen, iflen, opcode, ops): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1904,7 +1906,7 @@ def ibm_b10(flen, iflen, opcode, ops, N=-1, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == 0' cvpt += ' # ' for y in range(1, ops+1): @@ -2200,7 +2202,7 @@ def ibm_b11(flen, iflen, opcode, ops, N=-1, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -2311,7 +2313,7 @@ def ibm_b12(flen, iflen, opcode, ops, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == 0' cvpt += ' # ' for y in range(1, 3): @@ -2418,7 +2420,7 @@ def ibm_b13(flen, iflen, opcode, ops, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == 0' cvpt += ' # ' for y in range(1, ops+1): @@ -2549,7 +2551,7 @@ def ibm_b14(flen, iflen, opcode, ops, N=-1, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, 4): cvpt += 'rs'+str(y)+'_val==' @@ -2844,7 +2846,7 @@ def ibm_b15(flen, iflen, opcode, ops, N=-1, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -2976,7 +2978,7 @@ def ibm_b16(flen, iflen, opcode, ops, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3104,7 +3106,7 @@ def ibm_b17(flen, iflen, opcode, ops, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == 0' cvpt += ' # ' for y in range(1, ops+1): @@ -3435,7 +3437,7 @@ def ibm_b18(flen, iflen, opcode, ops, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3591,11 +3593,11 @@ def ibm_b19(flen, iflen, opcode, ops, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " if opcode in ["fadd","fsub","fmul","fdiv","fsqrt","fmadd","fnmadd","fmsub","fnmsub","fcvt","fmv"]: - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == 0' elif opcode in ["fclass","flt","fmax","fsgnjn","fle","fmin","fsgnj","feq", "flw","fsw","fsgnjx","fld","fsd"]: - cvpt = sanitise_norm(cvpt,iflen,flen) + cvpt = sanitise_norm(cvpt,iflen,flen,ops) # cvpt += 'rm_val == 1' # elif opcode in []: # cvpt = sanitise_cvpt(2,cvpt,iflen,flen) @@ -3800,7 +3802,7 @@ def ibm_b20(flen, iflen, opcode, ops, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == 0' cvpt += ' # ' for y in range(1, ops+1): @@ -3869,7 +3871,7 @@ def ibm_b21(flen, iflen, opcode, ops): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " if opcode.split('.')[0] in ["fdiv"]: - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4062,7 +4064,7 @@ def ibm_b22(flen, iflen, opcode, ops, seed=10): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4145,10 +4147,10 @@ def ibm_b23(flen, iflen, opcode, ops): cvpt += " and " # cvpt += 'rm_val == ' if "fmv" in opcode or opcode in "fcvt.d.s": - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) # cvpt += '0' else: - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) # cvpt += str(rm) cvpt += ' # ' for y in range(1, ops+1): @@ -4239,10 +4241,10 @@ def ibm_b24(flen,iflen, opcode, ops): cvpt += " and " # cvpt += 'rm_val == ' if "fmv" in opcode or opcode in "fcvt.d.s": - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) # cvpt += '0' else: - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) # cvpt += str(rm) cvpt += ' # ' for y in range(1, ops+1): @@ -4329,10 +4331,10 @@ def ibm_b25(flen, iflen, opcode, ops, seed=10): cvpt += " and " # cvpt += 'rm_val == ' if "fmv" in opcode or opcode in "fcvt.d.wu": - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) # cvpt += str(0) else: - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen) + cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) # cvpt += str(rm) cvpt += ' # Number = ' cvpt += c[1] @@ -4392,10 +4394,10 @@ def ibm_b26(xlen, opcode, ops, seed=10): cvpt += " and " # cvpt += 'rm_val == ' if "fmv" in opcode or opcode in "fcvt.d.wu": - cvpt = sanitise_cvpt(0,cvpt,xlen,xlen) + cvpt = sanitise_cvpt(0,cvpt,xlen,xlen,ops) # cvpt += str(0) else: - cvpt = sanitise_cvpt(rm,cvpt,xlen,xlen) + cvpt = sanitise_cvpt(rm,cvpt,xlen,xlen,ops) # cvpt += str(rm) cvpt += c[1] coverpoints.append(cvpt) @@ -4457,7 +4459,7 @@ def ibm_b27(flen, iflen, opcode, ops, seed=10): cvpt += (extract_fields(iflen,c,str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4571,7 +4573,7 @@ def ibm_b28(flen, iflen, opcode, ops, seed=10): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4647,7 +4649,7 @@ def ibm_b29(flen, iflen, opcode, ops, seed=10): for x in range(1, ops+1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(0,cvpt,iflen,flen) + cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == ' if "fmv" in opcode or "fcvt.d.s" in opcode: cvpt += '0' From addb48303bcfe79acb10aaf088dd8d2f8884b4b8 Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Wed, 8 Jun 2022 00:07:54 +0530 Subject: [PATCH 04/20] Fixes for fext. Define new variables(fcsr and nan_prefixes) --- riscv_isac/coverage.py | 172 ++++++++++++-------------- riscv_isac/plugins/internaldecoder.py | 20 +-- 2 files changed, 88 insertions(+), 104 deletions(-) diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index bf731851..4fef537b 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -3,6 +3,9 @@ # See LICENSE.iitm for details from itertools import islice +from threading import local + +from hamcrest import ends_with import ruamel from ruamel.yaml import YAML import riscv_isac.utils as utils @@ -172,6 +175,9 @@ def __init__ (self, xlen): self.csr[int('320',16)] = '00000000' # mcounterinhibit self.csr[int('B80',16)] = '00000000' # mcycleh self.csr[int('B82',16)] = '00000000' # minstreth + self.csr[int('001',16)] = '00000000' + self.csr[int('002',16)] = '00000000' + self.csr[int('003',16)] = '00000000' ## mtime, mtimecmp => 64 bits, platform defined memory mapping @@ -224,7 +230,10 @@ def __init__ (self, xlen): "stval": int('143',16), "sip": int('144',16), "satp": int('180',16), - "vxsat": int('009',16) + "vxsat": int('009',16), + "fflags":int('1',16), + "frm":int('2',16), + "fcsr":int('3',16) } for i in range(16): self.csr_regs["pmpaddr"+str(i)] = int('3B0',16)+i @@ -292,6 +301,7 @@ def __init__ (self, xlen, flen): self.f_rf = ['0000000000000000']*32 self.fcsr = 0 self.pc = 0 + self.flen = flen class statistics: ''' @@ -342,6 +352,28 @@ def __add__(self, o): return temp +def define_sem(flen, iflen, rsval, postfix,local_dict): + ''' + This function expands the rsval and defining the respective sign, exponent and mantissa correspondence + :param flen: Floating point length + :param rsval: base rs value used to expand it's respective sign, exponent and mantissa + :postfix: Register number that is part of the instruction + :local_dict: Holding the copy of all the local variables from the function calling this function + :return: The dictionary of variables with it's values + ''' + if iflen == 32: + e_sz = 8 + m_sz = 23 + else: + e_sz = 11 + m_sz = 52 + bin_val = ('{:0'+str(flen)+'b}').format(rsval) + if flen > iflen: + local_dict['rs'+postfix+'_nan_prefix'] = int(bin_val[0:flen-iflen]) + bin_val = bin_val[flen-iflen:] + local_dict['fs'+postfix] = int(bin_val[0],2) + local_dict['fe'+postfix] = int(bin_val[1:e_sz+1],2) + local_dict['fm'+postfix] = int(bin_val[e_sz+1:],2) def pretty_print_yaml(yaml): res = '''''' @@ -602,6 +634,13 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr unsgn_sz = '>Q' sgn_sz = '>q' + iflen = flen + + if instr.instr_name.ends_with(".s"): + iflen = 32 + elif instr.instr_name.ends_with(".d"): + iflen = 64 + fsgn_sz = '>Q' if flen==64 else '>I' # if instruction is empty then return @@ -646,6 +685,9 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr if instr.shamt is not None: imm_val = instr.shamt + + instr_vars = {} + # special value conversion based on signed/unsigned operations if instr.instr_name in unsgn_rs1: rs1_val = struct.unpack(unsgn_sz, bytes.fromhex(arch_state.x_rf[nxf_rs1]))[0] @@ -655,11 +697,10 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr rs1_hi_val = struct.unpack(unsgn_sz, bytes.fromhex(arch_state.x_rf[nxf_rs1+1]))[0] rs1_val = (rs1_hi_val << 32) | rs1_val elif rs1_type == 'x': - rs1_val = struct.unpack(sgn_sz, bytes.fromhex(arch_state.x_rf[nxf_rs1]))[0] - if instr.instr_name in ["fmv.w.x"]: - rs1_val = '0x' + (arch_state.x_rf[nxf_rs1]).lower() + rs1_val = struct.unpack(sgn_sz, bytes.fromhex(arch_state.x_rf[nxf_rs1]))[0] elif rs1_type == 'f': rs1_val = struct.unpack(fsgn_sz, bytes.fromhex(arch_state.f_rf[nxf_rs1]))[0] + define_sem(flen,iflen,rs1_val,"1",instr_vars) if instr.instr_name in unsgn_rs2: rs2_val = struct.unpack(unsgn_sz, bytes.fromhex(arch_state.x_rf[nxf_rs2]))[0] @@ -672,10 +713,12 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr rs2_val = struct.unpack(sgn_sz, bytes.fromhex(arch_state.x_rf[nxf_rs2]))[0] elif rs2_type == 'f': rs2_val = struct.unpack(fsgn_sz, bytes.fromhex(arch_state.f_rf[nxf_rs2]))[0] + define_sem(flen,iflen,rs2_val,"2",instr_vars) rs3_val = 0 if rs3_type == 'f': rs3_val = struct.unpack(fsgn_sz, bytes.fromhex(arch_state.f_rf[nxf_rs3]))[0] + define_sem(flen,iflen,rs3_val,"3",instr_vars) sig_update = False if instr.instr_name in ['sh','sb','sw','sd','c.sw','c.sd','c.swsp','c.sdsp'] and sig_addrs: @@ -690,18 +733,8 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr else: result_count = instr.rd_nregs - if instr.instr_name in ["fmadd.s","fmsub.s","fnmadd.s","fnmsub.s"]: - rs3_val = '0x' + (arch_state.f_rf[nxf_rs3]).lower() - - if instr.instr_name in ['csrrwi']: - arch_state.fcsr = instr.zimm - - if instr.instr_name in ["fadd.s","fsub.s","fmul.s","fdiv.s","fsqrt.s","fmadd.s","fmsub.s","fnmadd.s","fnmsub.s","fmax.s","fmin.s","feq.s","flt.s","fle.s","fmv.x.w","fmv.w.x","fcvt.wu.s","fcvt.s.wu","fcvt.w.s","fcvt.s.w","fsgnj.s","fsgnjn.s","fsgnjx.s","fclass.s"]: - rm = instr.rm - if(rm==7 or rm==None): - rm_val = arch_state.fcsr - else: - rm_val = rm + instr_vars["rm_val"] = instr.rm + instr_vars['fcsr'] = arch_state.fcsr arch_state.pc = instr.instr_addr @@ -715,14 +748,17 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr if instr.instr_name in ['sw','sh','sb','lw','lhu','lh','lb','lbu','lwu','flw','fsw']: ea_align = (rs1_val + imm_val) % 4 - if instr.instr_name in ['ld','sd']: + if instr.instr_name in ['ld','sd','fld','fsd']: ea_align = (rs1_val + imm_val) % 8 - local_dict={} + instr_vars.extend(locals()) + + local_dict = {} for i in csr_regfile.csr_regs: local_dict[i] = int(csr_regfile[i],16) local_dict['xlen'] = xlen + local_dict['flen'] = flen if enable : for cov_labels,value in cgf.items(): @@ -815,74 +851,21 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr cgf[cov_labels]['op_comb'][coverpoints] += 1 if 'val_comb' in value and len(value['val_comb']) != 0: - if instr.instr_name in ['fadd.s',"fsub.s","fmul.s","fdiv.s","fmax.s","fmin.s","feq.s","flt.s","fle.s","fsgnj.s","fsgnjn.s","fsgnjx.s"]: - val_key = fmt.extract_fields(32, rs1_val, str(1)) - val_key+= " and " - val_key+= fmt.extract_fields(32, rs2_val, str(2)) - val_key+= " and " - val_key+= 'rm == '+ str(rm_val) - l=[0] - l[0] = val_key - val_key = l - if(val_key[0] in cgf[cov_labels]['val_comb']): - if cgf[cov_labels]['val_comb'][val_key[0]] == 0: - stats.ucovpt.append(str(val_key[0])) - if no_count: - hit_covpts.append((cov_labels, 'val_comb', val_key[0])) - - stats.covpt.append(str(val_key[0])) - cgf[cov_labels]['val_comb'][val_key[0]] += 1 - elif instr.instr_name in ["fsqrt.s","fmv.x.w","fmv.w.x","fcvt.wu.s","fcvt.s.wu","fcvt.w.s","fcvt.s.w","fclass.s"]: - val_key = fmt.extract_fields(32, rs1_val, str(1)) - val_key+= " and " - val_key+= 'rm == '+ str(rm_val) - l=[0] - l[0] = val_key - val_key = l - if(val_key[0] in cgf[cov_labels]['val_comb']): - if cgf[cov_labels]['val_comb'][val_key[0]] == 0: - stats.ucovpt.append(str(val_key[0])) - if no_count: - hit_covpts.append((cov_labels, 'val_comb', val_key[0])) - - stats.covpt.append(str(val_key[0])) - cgf[cov_labels]['val_comb'][val_key[0]] += 1 - elif instr.instr_name in ["fmadd.s","fmsub.s","fnmadd.s","fnmsub.s"]: - val_key = fmt.extract_fields(32, rs1_val, str(1)) - val_key+= " and " - val_key+= fmt.extract_fields(32, rs2_val, str(2)) - val_key+= " and " - val_key+= fmt.extract_fields(32, rs3_val, str(3)) - val_key+= " and " - val_key+= 'rm == '+ str(rm_val) - l=[0] - l[0] = val_key - val_key = l - if(val_key[0] in cgf[cov_labels]['val_comb']): - if cgf[cov_labels]['val_comb'][val_key[0]] == 0: - stats.ucovpt.append(str(val_key[0])) - if no_count: - hit_covpts.append((cov_labels, 'val_comb', val_key[0])) - - stats.covpt.append(str(val_key[0])) - cgf[cov_labels]['val_comb'][val_key[0]] += 1 - else: - lcls=locals().copy() - if instr.is_rvp and "rs1" in value: - op_width = 64 if instr.rs1_nregs == 2 else xlen - simd_val_unpack(value['val_comb'], op_width, "rs1", rs1_val, lcls) - if instr.is_rvp and "rs2" in value: - op_width = 64 if instr.rs2_nregs == 2 else xlen - simd_val_unpack(value['val_comb'], op_width, "rs2", rs2_val, lcls) - for coverpoints in value['val_comb']: - if eval(coverpoints, globals(), lcls): - if cgf[cov_labels]['val_comb'][coverpoints] == 0: - stats.ucovpt.append(str(coverpoints)) - if no_count: - hit_covpts.append((cov_labels, 'val_comb', coverpoints)) - - stats.covpt.append(str(coverpoints)) - cgf[cov_labels]['val_comb'][coverpoints] += 1 + lcls={} + if instr.is_rvp and "rs1" in value: + op_width = 64 if instr.rs1_nregs == 2 else xlen + simd_val_unpack(value['val_comb'], op_width, "rs1", rs1_val, lcls) + if instr.is_rvp and "rs2" in value: + op_width = 64 if instr.rs2_nregs == 2 else xlen + simd_val_unpack(value['val_comb'], op_width, "rs2", rs2_val, lcls) + for coverpoints in value['val_comb']: + if eval(coverpoints, globals(), instr_vars.extend(lcls)): + if cgf[cov_labels]['val_comb'][coverpoints] == 0: + stats.ucovpt.append(str(coverpoints)) + if no_count: + hit_covpts.append((cov_labels, 'val_comb', coverpoints)) + stats.covpt.append(str(coverpoints)) + cgf[cov_labels]['val_comb'][coverpoints] += 1 if 'abstract_comb' in value \ and len(value['abstract_comb']) != 0 : for coverpoints in value['abstract_comb']: @@ -954,14 +937,15 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr 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) - logger.error(_log) - stats.stat4.append(_log + '\n\n') + if len(stats.last_meta): + _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) + logger.error(_log) + stats.stat4.append(_log + '\n\n') stats.covpt = [] stats.code_seq = [] diff --git a/riscv_isac/plugins/internaldecoder.py b/riscv_isac/plugins/internaldecoder.py index d9cb2887..557d9de7 100644 --- a/riscv_isac/plugins/internaldecoder.py +++ b/riscv_isac/plugins/internaldecoder.py @@ -1635,7 +1635,7 @@ def fsw_fsd(self, instrObj): funct3 = (instr & self.FUNCT3_MASK) >> 12 instrObj.rs1 = rs1 - instrObj.rs2 = rs1 + instrObj.rs2 = rs2 instrObj.imm = imm if funct3 == 0b010: @@ -1655,7 +1655,7 @@ def fmadd(self, instrObj): size_bit = (instr >> 25) & 0x00000001 instrObj.rs1 = rs1 - instrObj.rs2 = rs1 + instrObj.rs2 = rs2 instrObj.rd = rd instrObj.rm = rm @@ -1678,7 +1678,7 @@ def fmsub(self, instrObj): size_bit = (instr >> 25) & 0x00000001 instrObj.rs1 = rs1 - instrObj.rs2 = rs1 + instrObj.rs2 = rs2 instrObj.rd = rd instrObj.rm = rm @@ -1701,7 +1701,7 @@ def fnmsub(self, instrObj): size_bit = (instr >> 25) & 0x00000001 instrObj.rs1 = rs1 - instrObj.rs2 = rs1 + instrObj.rs2 = rs2 instrObj.rd = rd instrObj.rm = rm @@ -1724,7 +1724,7 @@ def fnmadd(self, instrObj): size_bit = (instr >> 25) & 0x00000001 instrObj.rs1 = rs1 - instrObj.rs2 = rs1 + instrObj.rs2 = rs2 instrObj.rd = rd instrObj.rm = rm instrObj.rs3 = rs3 @@ -1745,7 +1745,7 @@ def rv32_rv64_float_ops(self, instrObj): funct7 = (instr >> 25) instrObj.rs1 = rs1 - instrObj.rs2 = rs1 + instrObj.rs2 = rs2 instrObj.rd = rd instrObj.rm = rm @@ -1767,9 +1767,6 @@ def rv32_rv64_float_ops(self, instrObj): elif funct7 == 0b0001101: instrObj.instr_name = 'fdiv.d' - if instrObj.instr_name is not None: - return instrObj - # fsqrt if funct7 == 0b0101100: instrObj.instr_name = 'fsqrt.s' @@ -1890,7 +1887,7 @@ def rv32_rv64_float_ops(self, instrObj): return instrObj # fcvt.s.w, fcvt.s.wu, fcvt.s.l, fcvt.s.lu - if funct7 == 0b1100100: + if funct7 == 0b1101000: mode = rs2[0] instrObj.rs1 = (rs1[0], 'x') instrObj.rs2 = None @@ -1975,6 +1972,9 @@ def rv32_rv64_float_ops(self, instrObj): instrObj.rs1 = (rs1[0], 'x') instrObj.rs2 = None return instrObj + + if instrObj.instr_name != 'None': + return instrObj ''' Compressed Instruction Parsing Functions ''' C_FUNCT3_MASK = 0xe000 From 7ce6c6a5b22d9fbc41b9e4c2b127d0b53171f758 Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Fri, 10 Jun 2022 11:35:43 +0530 Subject: [PATCH 05/20] Bug fixes for fp. --- riscv_isac/coverage.py | 56 ++++++++++++++------- riscv_isac/fp_dataset.py | 106 +++++++++++++++++++++++++-------------- riscv_isac/main.py | 4 +- 3 files changed, 109 insertions(+), 57 deletions(-) diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index 4fef537b..8ca44e0a 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -5,7 +5,6 @@ from itertools import islice from threading import local -from hamcrest import ends_with import ruamel from ruamel.yaml import YAML import riscv_isac.utils as utils @@ -231,7 +230,7 @@ def __init__ (self, xlen): "sip": int('144',16), "satp": int('180',16), "vxsat": int('009',16), - "fflags":int('1',16), + "fflags":int('1',16), "frm":int('2',16), "fcsr":int('3',16) } @@ -369,7 +368,7 @@ def define_sem(flen, iflen, rsval, postfix,local_dict): m_sz = 52 bin_val = ('{:0'+str(flen)+'b}').format(rsval) if flen > iflen: - local_dict['rs'+postfix+'_nan_prefix'] = int(bin_val[0:flen-iflen]) + local_dict['rs'+postfix+'_nan_prefix'] = int(bin_val[0:flen-iflen],2) bin_val = bin_val[flen-iflen:] local_dict['fs'+postfix] = int(bin_val[0],2) local_dict['fe'+postfix] = int(bin_val[1:e_sz+1],2) @@ -615,16 +614,16 @@ 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 = 0 - nxf_rs2 = 0 - nxf_rs3 = 0 - nxf_rd = 0 - rs1_type = 'x' - rs2_type = 'x' - rs3_type = 'f' - rd_type = 'x' + nxf_rs1 = None + nxf_rs2 = None + nxf_rs3 = None + nxf_rd = None + rs1_type = None + rs2_type = None + rs3_type = None + rd_type = None - csr_addr = 0 + csr_addr = None # create signed/unsigned conversion params if xlen == 32: @@ -636,9 +635,9 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr iflen = flen - if instr.instr_name.ends_with(".s"): + if instr.instr_name.endswith(".s"): iflen = 32 - elif instr.instr_name.ends_with(".d"): + elif instr.instr_name.endswith(".d"): iflen = 64 fsgn_sz = '>Q' if flen==64 else '>I' @@ -686,9 +685,12 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr imm_val = instr.shamt + print(instr) + instr_vars = {} # special value conversion based on signed/unsigned operations + rs1_val = None if instr.instr_name in unsgn_rs1: rs1_val = struct.unpack(unsgn_sz, bytes.fromhex(arch_state.x_rf[nxf_rs1]))[0] elif instr.is_rvp: @@ -697,11 +699,13 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr rs1_hi_val = struct.unpack(unsgn_sz, bytes.fromhex(arch_state.x_rf[nxf_rs1+1]))[0] rs1_val = (rs1_hi_val << 32) | rs1_val elif rs1_type == 'x': - rs1_val = struct.unpack(sgn_sz, bytes.fromhex(arch_state.x_rf[nxf_rs1]))[0] + rs1_val = struct.unpack(sgn_sz, bytes.fromhex(arch_state.x_rf[nxf_rs1]))[0] elif rs1_type == 'f': + print(bytes.fromhex(arch_state.f_rf[nxf_rs1])) rs1_val = struct.unpack(fsgn_sz, bytes.fromhex(arch_state.f_rf[nxf_rs1]))[0] define_sem(flen,iflen,rs1_val,"1",instr_vars) + rs2_val = None if instr.instr_name in unsgn_rs2: rs2_val = struct.unpack(unsgn_sz, bytes.fromhex(arch_state.x_rf[nxf_rs2]))[0] elif instr.is_rvp: @@ -715,7 +719,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr rs2_val = struct.unpack(fsgn_sz, bytes.fromhex(arch_state.f_rf[nxf_rs2]))[0] define_sem(flen,iflen,rs2_val,"2",instr_vars) - rs3_val = 0 + rs3_val = None if rs3_type == 'f': rs3_val = struct.unpack(fsgn_sz, bytes.fromhex(arch_state.f_rf[nxf_rs3]))[0] define_sem(flen,iflen,rs3_val,"3",instr_vars) @@ -738,6 +742,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr arch_state.pc = instr.instr_addr + ea_align = None # the ea_align variable is used by the eval statements of the # coverpoints for conditional ops and memory ops if instr.instr_name in ['jal','bge','bgeu','blt','bltu','beq','bne']: @@ -751,7 +756,19 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr if instr.instr_name in ['ld','sd','fld','fsd']: ea_align = (rs1_val + imm_val) % 8 - instr_vars.extend(locals()) + if rs1_val is not None: + instr_vars['rs1_val'] = rs1_val + if rs2_val is not None: + instr_vars['rs2_val'] = rs2_val + if rs3_val is not None: + instr_vars['rs3_val'] = rs3_val + if imm_val is not None: + instr_vars['imm_val'] = imm_val + if ea_align is not None: + instr_vars['ea_align'] = ea_align + instr_vars['xlen'] = xlen + instr_vars['flen'] = flen + instr_vars['iflen'] = iflen local_dict = {} for i in csr_regfile.csr_regs: @@ -858,8 +875,11 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr if instr.is_rvp and "rs2" in value: op_width = 64 if instr.rs2_nregs == 2 else xlen simd_val_unpack(value['val_comb'], op_width, "rs2", rs2_val, lcls) + instr_vars.update(lcls) + print(instr_vars) for coverpoints in value['val_comb']: - if eval(coverpoints, globals(), instr_vars.extend(lcls)): + print(coverpoints, eval(coverpoints, globals(), instr_vars)) + if eval(coverpoints, globals(), instr_vars): if cgf[cov_labels]['val_comb'][coverpoints] == 0: stats.ucovpt.append(str(coverpoints)) if no_count: diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index 0a42da1a..15135f53 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -38,10 +38,13 @@ + ('' if iflen == flen else ''.join([' and rs'+str(x)+'_nan_prefix == 0x' \ + 'f'*int((flen-iflen)/4) for x in range(1,c+1)])) -sanitise_norm = lambda x,iflen,flen,c: x + ' fcsr == 0'\ +sanitise_norm = lambda rm,x,iflen,flen,c: x + ' fcsr == 0'\ + ('' if iflen == flen else ''.join([' and rs'+str(x)+'_nan_prefix == 0x' \ + 'f'*int((flen-iflen)/4) for x in range(1,c+1)])) +get_sanitise_func = lambda opcode: sanitise_norm if any([x in opcode for x in \ + ['fsgnj','fle','flt','feq','fclass','fmv','flw','fsw','fld','fsd','fmin','fmax']]) else sanitise_cvpt + def num_explain(flen,num): num_dict = { tuple(fzero) : 'fzero', @@ -289,6 +292,7 @@ def ibm_b1(flen, iflen, opcode, ops): - Coverpoints are then appended with the respective rounding mode for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) if iflen == 32: basic_types = fzero + fminsubnorm + [fsubnorm[0], fsubnorm[3]] +\ fmaxsubnorm + fminnorm + [fnorm[0], fnorm[3]] + fmaxnorm + \ @@ -312,10 +316,10 @@ def ibm_b1(flen, iflen, opcode, ops): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) + " and " if opcode.split('.')[0] in ["fadd","fsub","fmul","fdiv","fsqrt","fmadd","fnmadd","fmsub","fnmsub","fcvt","fmv"]: - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) elif opcode.split('.')[0] in \ ["fclass","flt","fmax","fsgnjn","fmin","fsgnj","feq","flw","fsw","fsgnjx","fld","fle"]: - cvpt = sanitise_norm(cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): @@ -367,6 +371,7 @@ def ibm_b2(flen, iflen, opcode, ops, int_val = 100, seed = -1): - Coverpoints are then appended with the respective rounding mode for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) if iflen == 32: flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm b = '0x00000010' @@ -463,7 +468,7 @@ def ibm_b2(flen, iflen, opcode, ops, int_val = 100, seed = -1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -511,6 +516,7 @@ def ibm_b3(flen,iflen, opcode, ops, seed=-1): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] getcontext().prec = 40 @@ -672,7 +678,7 @@ def ibm_b3(flen,iflen, opcode, ops, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == '+str(rm) - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -724,6 +730,7 @@ def ibm_b4(flen, iflen, opcode, ops, seed=-1): - These operand values are treated as decimal numbers until their derivation after which they are converted into their respective IEEE754 hexadecimal floating point formats using the “floatingPoint_tohex” function. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] getcontext().prec = 40 @@ -853,7 +860,7 @@ def ibm_b4(flen, iflen, opcode, ops, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == '+str(rm) - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -908,6 +915,7 @@ def ibm_b5(flen, iflen, opcode, ops, seed=-1): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] getcontext().prec = 40 @@ -1054,7 +1062,7 @@ def ibm_b5(flen, iflen, opcode, ops, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == '+str(rm) - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1109,6 +1117,7 @@ def ibm_b6(flen, iflen, opcode, ops, seed=-1): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] getcontext().prec = 40 @@ -1213,7 +1222,7 @@ def ibm_b6(flen, iflen, opcode, ops, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops) # cvpt += 'rm_val == '+str(rm) cvpt += ' # ' for y in range(1, ops+1): @@ -1272,6 +1281,7 @@ def ibm_b7(flen, iflen, opcode, ops, seed=-1): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] getcontext().prec = 60 if iflen == 32: @@ -1405,7 +1415,7 @@ def ibm_b7(flen, iflen, opcode, ops, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 3' - cvpt = sanitise_cvpt(3,cvpt,iflen,flen,ops) + cvpt = sanitise(3,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1457,6 +1467,7 @@ def ibm_b8(flen, iflen, opcode, ops, seed=-1): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] getcontext().prec = 60 if iflen == 32: @@ -1596,7 +1607,7 @@ def ibm_b8(flen, iflen, opcode, ops, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops) # cvpt += 'rm_val == '+str(rm) cvpt += ' # ' for y in range(1, ops+1): @@ -1653,6 +1664,7 @@ def ibm_b9(flen, iflen, opcode, ops): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] if iflen == 32: @@ -1803,7 +1815,7 @@ def ibm_b9(flen, iflen, opcode, ops): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1854,6 +1866,7 @@ def ibm_b10(flen, iflen, opcode, ops, N=-1, seed=-1): - Coverpoints are then appended with rounding mode ‘0’ for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] if iflen == 32: @@ -1906,7 +1919,7 @@ def ibm_b10(flen, iflen, opcode, ops, N=-1, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == 0' cvpt += ' # ' for y in range(1, ops+1): @@ -1957,6 +1970,7 @@ def ibm_b11(flen, iflen, opcode, ops, N=-1, seed=-1): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] if iflen == 32: @@ -2202,7 +2216,7 @@ def ibm_b11(flen, iflen, opcode, ops, N=-1, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -2251,6 +2265,7 @@ def ibm_b12(flen, iflen, opcode, ops, seed=-1): - Coverpoints are then appended with rounding mode ‘0’ for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] getcontext().prec = 40 @@ -2313,7 +2328,7 @@ def ibm_b12(flen, iflen, opcode, ops, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == 0' cvpt += ' # ' for y in range(1, 3): @@ -2359,6 +2374,7 @@ def ibm_b13(flen, iflen, opcode, ops, seed=-1): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] getcontext().prec = 40 @@ -2420,7 +2436,7 @@ def ibm_b13(flen, iflen, opcode, ops, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == 0' cvpt += ' # ' for y in range(1, ops+1): @@ -2478,6 +2494,7 @@ def ibm_b14(flen, iflen, opcode, ops, N=-1, seed=-1): - Coverpoints are then appended with rounding mode ‘0’ for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] if iflen == 32: @@ -2551,7 +2568,7 @@ def ibm_b14(flen, iflen, opcode, ops, N=-1, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, 4): cvpt += 'rs'+str(y)+'_val==' @@ -2602,6 +2619,7 @@ def ibm_b15(flen, iflen, opcode, ops, N=-1, seed=-1): - Coverpoints are then appended with rounding mode “0” for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] if iflen == 32: @@ -2846,7 +2864,7 @@ def ibm_b15(flen, iflen, opcode, ops, N=-1, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -2896,6 +2914,7 @@ def ibm_b16(flen, iflen, opcode, ops, seed=-1): - Coverpoints are then appended with rounding mode “0” for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] getcontext().prec = 40 @@ -2978,7 +2997,7 @@ def ibm_b16(flen, iflen, opcode, ops, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3024,6 +3043,7 @@ def ibm_b17(flen, iflen, opcode, ops, seed=-1): - Coverpoints are then appended with rounding mode “0” for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] getcontext().prec = 40 @@ -3106,7 +3126,7 @@ def ibm_b17(flen, iflen, opcode, ops, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == 0' cvpt += ' # ' for y in range(1, ops+1): @@ -3154,6 +3174,7 @@ def ibm_b18(flen, iflen, opcode, ops, seed=-1): - Coverpoints are then appended with rounding mode “0” for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] getcontext().prec = 40 @@ -3437,7 +3458,7 @@ def ibm_b18(flen, iflen, opcode, ops, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3491,6 +3512,7 @@ def ibm_b19(flen, iflen, opcode, ops, seed=-1): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] getcontext().prec = 40 @@ -3593,14 +3615,14 @@ def ibm_b19(flen, iflen, opcode, ops, seed=-1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " if opcode in ["fadd","fsub","fmul","fdiv","fsqrt","fmadd","fnmadd","fmsub","fnmsub","fcvt","fmv"]: - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == 0' elif opcode in ["fclass","flt","fmax","fsgnjn","fle","fmin","fsgnj","feq", "flw","fsw","fsgnjx","fld","fsd"]: - cvpt = sanitise_norm(cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == 1' # elif opcode in []: - # cvpt = sanitise_cvpt(2,cvpt,iflen,flen) + # cvpt = sanitise(2,cvpt,iflen,flen) # cvpt += 'rm_val == 2' cvpt += ' # ' for y in range(1, ops+1): @@ -3663,6 +3685,7 @@ def ibm_b20(flen, iflen, opcode, ops, seed=-1): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] getcontext().prec = 60 @@ -3802,7 +3825,7 @@ def ibm_b20(flen, iflen, opcode, ops, seed=-1): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == 0' cvpt += ' # ' for y in range(1, ops+1): @@ -3850,6 +3873,7 @@ def ibm_b21(flen, iflen, opcode, ops): - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) if iflen == 32: basic_types = fzero + fsubnorm + fnorm + finfinity + fdefaultnan + [fqnan[0], fqnan[3]] + \ [fsnan[0], fsnan[3]] @@ -3871,7 +3895,7 @@ def ibm_b21(flen, iflen, opcode, ops): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " if opcode.split('.')[0] in ["fdiv"]: - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3920,6 +3944,7 @@ def ibm_b22(flen, iflen, opcode, ops, seed=10): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] if opcode[2] == 's': iflen = 32 @@ -4064,7 +4089,7 @@ def ibm_b22(flen, iflen, opcode, ops, seed=10): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4117,6 +4142,7 @@ def ibm_b23(flen, iflen, opcode, ops): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] @@ -4147,10 +4173,10 @@ def ibm_b23(flen, iflen, opcode, ops): cvpt += " and " # cvpt += 'rm_val == ' if "fmv" in opcode or opcode in "fcvt.d.s": - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) # cvpt += '0' else: - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops) # cvpt += str(rm) cvpt += ' # ' for y in range(1, ops+1): @@ -4207,6 +4233,7 @@ def ibm_b24(flen,iflen, opcode, ops): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] @@ -4241,10 +4268,10 @@ def ibm_b24(flen,iflen, opcode, ops): cvpt += " and " # cvpt += 'rm_val == ' if "fmv" in opcode or opcode in "fcvt.d.s": - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) # cvpt += '0' else: - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops) # cvpt += str(rm) cvpt += ' # ' for y in range(1, ops+1): @@ -4295,6 +4322,7 @@ def ibm_b25(flen, iflen, opcode, ops, seed=10): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) random.seed(seed) opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] @@ -4331,10 +4359,10 @@ def ibm_b25(flen, iflen, opcode, ops, seed=10): cvpt += " and " # cvpt += 'rm_val == ' if "fmv" in opcode or opcode in "fcvt.d.wu": - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) # cvpt += str(0) else: - cvpt = sanitise_cvpt(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops) # cvpt += str(rm) cvpt += ' # Number = ' cvpt += c[1] @@ -4373,6 +4401,7 @@ def ibm_b26(xlen, opcode, ops, seed=10): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) random.seed(seed) opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] @@ -4394,10 +4423,10 @@ def ibm_b26(xlen, opcode, ops, seed=10): cvpt += " and " # cvpt += 'rm_val == ' if "fmv" in opcode or opcode in "fcvt.d.wu": - cvpt = sanitise_cvpt(0,cvpt,xlen,xlen,ops) + cvpt = sanitise(0,cvpt,xlen,xlen,ops) # cvpt += str(0) else: - cvpt = sanitise_cvpt(rm,cvpt,xlen,xlen,ops) + cvpt = sanitise(rm,cvpt,xlen,xlen,ops) # cvpt += str(rm) cvpt += c[1] coverpoints.append(cvpt) @@ -4445,6 +4474,7 @@ def ibm_b27(flen, iflen, opcode, ops, seed=10): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] if iflen == 32: @@ -4459,7 +4489,7 @@ def ibm_b27(flen, iflen, opcode, ops, seed=10): cvpt += (extract_fields(iflen,c,str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4518,6 +4548,7 @@ def ibm_b28(flen, iflen, opcode, ops, seed=10): - Coverpoints are then appended with rounding mode “0” for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) random.seed(seed) opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] dataset = [] @@ -4573,7 +4604,7 @@ def ibm_b28(flen, iflen, opcode, ops, seed=10): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4620,6 +4651,7 @@ def ibm_b29(flen, iflen, opcode, ops, seed=10): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' + sanitise = get_sanitise_func(opcode) random.seed(seed) sgns = ["0","1"] dataset = [] @@ -4649,7 +4681,7 @@ def ibm_b29(flen, iflen, opcode, ops, seed=10): for x in range(1, ops+1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise_cvpt(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == ' if "fmv" in opcode or "fcvt.d.s" in opcode: cvpt += '0' diff --git a/riscv_isac/main.py b/riscv_isac/main.py index 2a0223d4..f32ba3c4 100644 --- a/riscv_isac/main.py +++ b/riscv_isac/main.py @@ -129,8 +129,8 @@ def cli(verbose): def coverage(elf,trace_file, window_size, cgf_file, detailed,parser_name, decoder_name, parser_path, decoder_path,output_file, test_label, sig_label, dump,cov_label, xlen, flen, no_count, procs): - isac(output_file,elf,trace_file, window_size, expand_cgf(cgf_file,int(xlen)), parser_name, decoder_name, parser_path, decoder_path, detailed, test_label, - sig_label, dump, cov_label, int(xlen), no_count, procs) + isac(output_file,elf,trace_file, window_size, expand_cgf(cgf_file,int(xlen),int(flen)), parser_name, decoder_name, parser_path, decoder_path, detailed, test_label, + sig_label, dump, cov_label, int(xlen), int(flen), no_count, procs) @cli.command(help = "Merge given coverage files.") @click.argument( From 86f8b52977b81c4cea66c6915dbe51e7428826fe Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Mon, 13 Jun 2022 17:58:27 +0530 Subject: [PATCH 06/20] Changes to accomodate x source registers in instructions. --- riscv_isac/coverage.py | 6 +----- riscv_isac/fp_dataset.py | 24 +++++++++++++++--------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index 8ca44e0a..372ead2e 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -39,7 +39,7 @@ 'aes32esmi', 'aes32esi', 'aes32dsmi', 'aes32dsi','bclr','bext','binv',\ 'bset','zext.h','sext.h','sext.b','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'] + 'bclri','bexti','binvi','bseti','fcvt.d.wu','fcvt.s.wu','fcvt.d.lu','fcvt.s.lu'] 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',\ @@ -685,7 +685,6 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr imm_val = instr.shamt - print(instr) instr_vars = {} @@ -701,7 +700,6 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr elif rs1_type == 'x': rs1_val = struct.unpack(sgn_sz, bytes.fromhex(arch_state.x_rf[nxf_rs1]))[0] elif rs1_type == 'f': - print(bytes.fromhex(arch_state.f_rf[nxf_rs1])) rs1_val = struct.unpack(fsgn_sz, bytes.fromhex(arch_state.f_rf[nxf_rs1]))[0] define_sem(flen,iflen,rs1_val,"1",instr_vars) @@ -876,9 +874,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr op_width = 64 if instr.rs2_nregs == 2 else xlen simd_val_unpack(value['val_comb'], op_width, "rs2", rs2_val, lcls) instr_vars.update(lcls) - print(instr_vars) for coverpoints in value['val_comb']: - print(coverpoints, eval(coverpoints, globals(), instr_vars)) if eval(coverpoints, globals(), instr_vars): if cgf[cov_labels]['val_comb'][coverpoints] == 0: stats.ucovpt.append(str(coverpoints)) diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index 15135f53..ccf56a90 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -42,8 +42,12 @@ + ('' if iflen == flen else ''.join([' and rs'+str(x)+'_nan_prefix == 0x' \ + 'f'*int((flen-iflen)/4) for x in range(1,c+1)])) -get_sanitise_func = lambda opcode: sanitise_norm if any([x in opcode for x in \ - ['fsgnj','fle','flt','feq','fclass','fmv','flw','fsw','fld','fsd','fmin','fmax']]) else sanitise_cvpt +sanitise_norm_nopref = lambda rm,x,iflen,flen,c: x + ' fcsr == 0' + +get_sanitise_func = lambda opcode: sanitise_norm_nopref if any([x in opcode for x in \ + ['fsgnj','fle','flt','feq','fclass','fmv','flw','fsw','fld','fsd','fmin','fmax']]) else \ + ( sanitise_norm if any([opcode.endswith(x) for x in ['.x','.l','.w','.lu','.wu']]) \ + else sanitise_cvpt) def num_explain(flen,num): num_dict = { @@ -4293,7 +4297,7 @@ def ibm_b24(flen,iflen, opcode, ops): def ibm_b25(flen, iflen, opcode, ops, seed=10): ''' IBM Model B25 Definition: - This model creates a test-case for each of the following inputs: + This model creates a test-case for each of the following inputs(wherever applicable): 1. ±MaxInt 2. ±0 @@ -4333,16 +4337,18 @@ def ibm_b25(flen, iflen, opcode, ops, seed=10): dataset = [(0,"0"),(1,"1"),(-1,"-1")] - if iflen == 32: - maxnum = 2**31-1 - elif iflen == 64: - maxnum = 2**63-1 + is_unsigned = opcode.endswith("u") + + bitwidth = iflen if is_unsigned else iflen-1 + maxnum = 2**(bitwidth)-1 dataset.append((maxnum,"MaxInt")) - dataset.append((-1*maxnum,"-MaxInt")) + if not is_unsigned: + dataset.append((-1*maxnum,"-MaxInt")) rand_num = int(random.uniform(1,maxnum)) dataset.append((rand_num,"+ve Random Number")) - dataset.append((-1*rand_num,"-ve Random Number")) + if not is_unsigned: + dataset.append((-1*rand_num,"-ve Random Number")) b25_comb = [] From ddfe1c28ec9df9cc2e85b83b3f9fcf358e4929c0 Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Tue, 14 Jun 2022 13:12:16 +0530 Subject: [PATCH 07/20] Fixed variabbles for fcvt instructions. --- riscv_isac/fp_dataset.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index ccf56a90..b557c70f 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -43,11 +43,12 @@ + 'f'*int((flen-iflen)/4) for x in range(1,c+1)])) sanitise_norm_nopref = lambda rm,x,iflen,flen,c: x + ' fcsr == 0' +sanitise_nopref = lambda rm,x,iflen,flen,c: x + ' fcsr == 0 and rm_val == 7' -get_sanitise_func = lambda opcode: sanitise_norm_nopref if any([x in opcode for x in \ - ['fsgnj','fle','flt','feq','fclass','fmv','flw','fsw','fld','fsd','fmin','fmax']]) else \ - ( sanitise_norm if any([opcode.endswith(x) for x in ['.x','.l','.w','.lu','.wu']]) \ - else sanitise_cvpt) +get_sanitise_func = lambda opcode: sanitise_norm if any([x in opcode for x in \ + ['fsgnj','fle','flt','feq','fclass','flw','fsw','fld','fsd','fmin','fmax']]) else \ + ( sanitise_nopref if any([opcode.endswith(x) for x in ['.l','.w','.lu','.wu']]) \ + else (sanitise_norm_nopref if 'fmv' in opcode else sanitise_cvpt)) def num_explain(flen,num): num_dict = { From 07970eaa1f6489b0fd234a41ca4c0ae12e94ab8a Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Wed, 15 Jun 2022 12:46:51 +0530 Subject: [PATCH 08/20] Fixed fcsr value source. --- riscv_isac/coverage.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index 372ead2e..8a1e8b22 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -295,10 +295,8 @@ def __init__ (self, xlen, flen): if flen == 32: self.f_rf = ['00000000']*32 - self.fcsr = 0 else: self.f_rf = ['0000000000000000']*32 - self.fcsr = 0 self.pc = 0 self.flen = flen @@ -736,7 +734,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr result_count = instr.rd_nregs instr_vars["rm_val"] = instr.rm - instr_vars['fcsr'] = arch_state.fcsr + instr_vars['fcsr'] = int(csr_regfile['fcsr'],16) arch_state.pc = instr.instr_addr @@ -934,10 +932,8 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr stats.cov_pt_sig += stats.covpt if result_count <= 0: if stats.ucovpt: - stats.stat1.append((store_address, store_val, stats.ucovpt, stats.ucode_seq)) stats.last_meta = [store_address, store_val, stats.ucovpt, stats.ucode_seq] - stats.ucovpt = [] elif stats.covpt: _log = 'Op without unique coverpoint updates Signature\n' From a6b37485c802b14fdc9af809d4a6254401849bd5 Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Wed, 15 Jun 2022 13:20:00 +0530 Subject: [PATCH 09/20] Fix coverage merge function. --- riscv_isac/coverage.py | 4 +--- riscv_isac/main.py | 10 ++++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index 8a1e8b22..5574c6a5 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -481,7 +481,7 @@ def merge_fn(files, cgf, p): return files[0] -def merge_coverage(inp_files, cgf, detailed, xlen, p=1): +def merge_coverage(inp_files, cgf, detailed, p=1): ''' This function merges values of multiple CGF files and return a single cgf file. This can be treated analogous to how coverage files are merged @@ -490,13 +490,11 @@ def merge_coverage(inp_files, cgf, detailed, xlen, p=1): :param inp_files: an array of input CGF file names which need to be merged. :param cgf: a cgf against which coverpoints need to be checked for. :param detailed: a boolean value indicating if a detailed report needs to be generated - :param xlen: XLEN of the trace :param p: Number of worker processes (>=1) :type inp_files: [str] :type cgf: dict :type detailed: bool - :type xlen: int :type p: int :return: a string contain the final report of the merge. diff --git a/riscv_isac/main.py b/riscv_isac/main.py index f32ba3c4..648f661b 100644 --- a/riscv_isac/main.py +++ b/riscv_isac/main.py @@ -158,9 +158,15 @@ def coverage(elf,trace_file, window_size, cgf_file, detailed,parser_name, decode type=click.Path(writable=True,resolve_path=True), help="Coverage Group File." ) +@click.option('--flen','-f', + type=click.Choice(['32','64']), + default='32', + help="FLEN value for the ISA." +) @click.option('--xlen','-x',type=click.Choice(['32','64']),default='32',help="XLEN value for the ISA.") -def merge(files,detailed,p,cgf_file,output_file,xlen): - rpt = cov.merge_coverage(files,expand_cgf(cgf_file,int(xlen)),detailed,int(xlen),p) +def merge(files,detailed,p,cgf_file,output_file,flen,xlen): + rpt = cov.merge_coverage( + files,expand_cgf(cgf_file,int(xlen),int(flen)),detailed,p) if output_file is None: logger.info('Coverage Report:') logger.info('\n\n' + rpt) From 0ceff5522f90e4a241394d3be37897cb1b3e3b84 Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Wed, 15 Jun 2022 15:59:48 +0530 Subject: [PATCH 10/20] Fix rm for fcvt.d.s --- riscv_isac/fp_dataset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index b557c70f..b8479b67 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -46,7 +46,7 @@ sanitise_nopref = lambda rm,x,iflen,flen,c: x + ' fcsr == 0 and rm_val == 7' get_sanitise_func = lambda opcode: sanitise_norm if any([x in opcode for x in \ - ['fsgnj','fle','flt','feq','fclass','flw','fsw','fld','fsd','fmin','fmax']]) else \ + ['fsgnj','fle','flt','feq','fclass','flw','fsw','fld','fsd','fmin','fmax','fcvt.d.s']]) else \ ( sanitise_nopref if any([opcode.endswith(x) for x in ['.l','.w','.lu','.wu']]) \ else (sanitise_norm_nopref if 'fmv' in opcode else sanitise_cvpt)) From c45a185fa9fca822fb364389a9b0313c2932935c Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Wed, 15 Jun 2022 20:25:15 +0530 Subject: [PATCH 11/20] Added rm_val for fcvt.d.s --- riscv_isac/fp_dataset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index b8479b67..b557c70f 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -46,7 +46,7 @@ sanitise_nopref = lambda rm,x,iflen,flen,c: x + ' fcsr == 0 and rm_val == 7' get_sanitise_func = lambda opcode: sanitise_norm if any([x in opcode for x in \ - ['fsgnj','fle','flt','feq','fclass','flw','fsw','fld','fsd','fmin','fmax','fcvt.d.s']]) else \ + ['fsgnj','fle','flt','feq','fclass','flw','fsw','fld','fsd','fmin','fmax']]) else \ ( sanitise_nopref if any([opcode.endswith(x) for x in ['.l','.w','.lu','.wu']]) \ else (sanitise_norm_nopref if 'fmv' in opcode else sanitise_cvpt)) From 7545304bb9de50e4d6daa22a15819e00c8e75f0a Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Wed, 15 Jun 2022 23:22:52 +0530 Subject: [PATCH 12/20] Fixed b29. --- riscv_isac/fp_dataset.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index b557c70f..e882db78 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -4691,9 +4691,11 @@ def ibm_b29(flen, iflen, opcode, ops, seed=10): cvpt = sanitise(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == ' if "fmv" in opcode or "fcvt.d.s" in opcode: - cvpt += '0' + cvpt = sanitise(0,cvpt,iflen,flen,ops) + # cvpt += '0' else: - cvpt += str(rm) + cvpt = sanitise(rm,cvpt,iflen,flen,ops) + # cvpt += str(rm) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' From 1177319b8c4fb99e6986d07e5e4cd9947dbee5e7 Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Wed, 15 Jun 2022 23:25:20 +0530 Subject: [PATCH 13/20] Removed redundant sanitise in b29. --- riscv_isac/fp_dataset.py | 1 - 1 file changed, 1 deletion(-) diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index e882db78..484cbca7 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -4688,7 +4688,6 @@ def ibm_b29(flen, iflen, opcode, ops, seed=10): for x in range(1, ops+1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " - cvpt = sanitise(0,cvpt,iflen,flen,ops) # cvpt += 'rm_val == ' if "fmv" in opcode or "fcvt.d.s" in opcode: cvpt = sanitise(0,cvpt,iflen,flen,ops) From 51d27c6b10aded000a4d3dc8ea4509687768784b Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Fri, 17 Jun 2022 19:29:25 +0530 Subject: [PATCH 14/20] Fixed signedness of operations. --- riscv_isac/fp_dataset.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index 484cbca7..26357116 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -4328,17 +4328,14 @@ def ibm_b25(flen, iflen, opcode, ops, seed=10): ''' sanitise = get_sanitise_func(opcode) + is_unsigned = opcode.endswith("u") random.seed(seed) - opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] - getcontext().prec = 40 operations = ['+','-'] nums = [0,0.01,0.1,0.11] - dataset = [(0,"0"),(1,"1"),(-1,"-1")] - - is_unsigned = opcode.endswith("u") + dataset = [(0,"0"),(1,"1")] +( [(-1,"-1")] if not is_unsigned else []) bitwidth = iflen if is_unsigned else iflen-1 maxnum = 2**(bitwidth)-1 @@ -4410,8 +4407,6 @@ def ibm_b26(xlen, opcode, ops, seed=10): ''' sanitise = get_sanitise_func(opcode) random.seed(seed) - opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] - dataset = [(0," # Number in [0]"),(1," # Number in [1]")] i = 3 From d9ef1da029809f4a184a2b09d14269dc24f4c4ac Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Thu, 30 Jun 2022 12:02:02 +0530 Subject: [PATCH 15/20] fixed ordering to ensure fmv has no rm_val --- riscv_isac/fp_dataset.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index 26357116..fd3bb9ad 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -47,8 +47,8 @@ get_sanitise_func = lambda opcode: sanitise_norm if any([x in opcode for x in \ ['fsgnj','fle','flt','feq','fclass','flw','fsw','fld','fsd','fmin','fmax']]) else \ - ( sanitise_nopref if any([opcode.endswith(x) for x in ['.l','.w','.lu','.wu']]) \ - else (sanitise_norm_nopref if 'fmv' in opcode else sanitise_cvpt)) + (sanitise_norm_nopref if 'fmv' in opcode else ( sanitise_nopref if any([opcode.endswith(x) \ + for x in ['.l','.w','.lu','.wu']]) else sanitise_cvpt)) def num_explain(flen,num): num_dict = { From 058e7a1902a7b1e4bdd48cbe57884a92940d0128 Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Thu, 30 Jun 2022 13:16:45 +0530 Subject: [PATCH 16/20] Fix iflen for fmv.x.w --- riscv_isac/coverage.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index 5574c6a5..2be80fc9 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -365,6 +365,8 @@ def define_sem(flen, iflen, rsval, postfix,local_dict): e_sz = 11 m_sz = 52 bin_val = ('{:0'+str(flen)+'b}').format(rsval) + print(rsval) + print(bin_val) if flen > iflen: local_dict['rs'+postfix+'_nan_prefix'] = int(bin_val[0:flen-iflen],2) bin_val = bin_val[flen-iflen:] @@ -631,7 +633,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr iflen = flen - if instr.instr_name.endswith(".s"): + if instr.instr_name.endswith(".s") or instr.instr_name=='fmv.x.w': iflen = 32 elif instr.instr_name.endswith(".d"): iflen = 64 @@ -771,6 +773,9 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr local_dict['xlen'] = xlen local_dict['flen'] = flen + print(instr) + print(instr_vars) + if enable : for cov_labels,value in cgf.items(): if cov_labels != 'datasets': From f41277ba8e65ee3d9a87746f97bc54bdf3577b5f Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Thu, 30 Jun 2022 15:18:56 +0530 Subject: [PATCH 17/20] Fixed iflen for fmv.x.wu --- riscv_isac/coverage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index 2be80fc9..52e5eeaa 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -633,7 +633,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr iflen = flen - if instr.instr_name.endswith(".s") or instr.instr_name=='fmv.x.w': + if instr.instr_name.endswith(".s") or 'fmv.x.w' in instr.instr_name: iflen = 32 elif instr.instr_name.endswith(".d"): iflen = 64 From c82140980662e9da014d6a153b14cb9d99376385 Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Thu, 7 Jul 2022 12:00:38 +0530 Subject: [PATCH 18/20] Removed stray print statements. --- riscv_isac/coverage.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index 52e5eeaa..bfdfacd1 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -365,8 +365,6 @@ def define_sem(flen, iflen, rsval, postfix,local_dict): e_sz = 11 m_sz = 52 bin_val = ('{:0'+str(flen)+'b}').format(rsval) - print(rsval) - print(bin_val) if flen > iflen: local_dict['rs'+postfix+'_nan_prefix'] = int(bin_val[0:flen-iflen],2) bin_val = bin_val[flen-iflen:] @@ -773,9 +771,6 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr local_dict['xlen'] = xlen local_dict['flen'] = flen - print(instr) - print(instr_vars) - if enable : for cov_labels,value in cgf.items(): if cov_labels != 'datasets': From 05b91281b75edf13970071c3cbd0e69b80260e09 Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Mon, 8 Aug 2022 21:19:13 +0530 Subject: [PATCH 19/20] Fixed rs2 register for fs* instructions. --- riscv_isac/plugins/internaldecoder.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/riscv_isac/plugins/internaldecoder.py b/riscv_isac/plugins/internaldecoder.py index 557d9de7..0e9a4ea1 100644 --- a/riscv_isac/plugins/internaldecoder.py +++ b/riscv_isac/plugins/internaldecoder.py @@ -780,7 +780,7 @@ def arithi_ops(self, instrObj): return instrObj - # Put the following function in internaldecoder.py + # Put the following function in internaldecoder.py def rvp_ops(self, instrObj): instr = instrObj.instr @@ -1223,7 +1223,7 @@ def arith_ops(self, instrObj): instrObj.instr_name = 'min' instrObj.rs1 = rs1 instrObj.rs2 = rs2 - instrObj.rd = rd + instrObj.rd = rd elif funct7 == 0b0010000: instrObj.instr_name = 'sh2add' instrObj.rs1 = rs1 @@ -1234,7 +1234,7 @@ def arith_ops(self, instrObj): instrObj.rs1 = rs1 instrObj.rs2 = rs2 instrObj.rd = rd - + # elif funct7 == 0b0100100: # instrObj.instr_name = 'packu' # instrObj.rs1 = rs1 @@ -1262,7 +1262,7 @@ def arith_ops(self, instrObj): instrObj.instr_name = 'minu' instrObj.rs1 = rs1 instrObj.rs2 = rs2 - instrObj.rd = rd + instrObj.rd = rd elif funct7 == 0b0100100: instrObj.instr_name = 'bext' instrObj.rs1 = rs1 @@ -1280,12 +1280,12 @@ def arith_ops(self, instrObj): instrObj.instr_name = 'sh3add' instrObj.rs1 = rs1 instrObj.rs2 = rs2 - instrObj.rd = rd + instrObj.rd = rd elif funct7 == 0b0000101: instrObj.instr_name = 'max' instrObj.rs1 = rs1 instrObj.rs2 = rs2 - instrObj.rd = rd + instrObj.rd = rd else: instrObj.instr_name = 'or' @@ -1429,7 +1429,7 @@ def rv64i_arithi_ops(self, instrObj): instrObj.instr_name = 'sraiw' return instrObj - + def rv64m_arithm_ops(self, instrObj): instr = instrObj.instr funct3 = (instr & self.FUNCT3_MASK) >> 12 @@ -1535,8 +1535,8 @@ def rv64i_arith_ops(self, instrObj): instrObj.instr_name = 'sh3add.uw' instrObj.rs1 = rs1 instrObj.rs2 = rs2 - instrObj.rd = rd - + instrObj.rd = rd + return instrObj @@ -1629,7 +1629,7 @@ def fsw_fsd(self, instrObj): imm_4_0 = (instr & self.RD_MASK) >> 7 imm_11_5 = (instr >> 25) << 5 imm = self.twos_comp(imm_4_0 + imm_11_5, 12) - rs1 = ((instr & self.RS1_MASK) >> 15, 'd') + rs1 = ((instr & self.RS1_MASK) >> 15, 'x') rs2 = ((instr & self.RS2_MASK) >> 20, 'f') funct3 = (instr & self.FUNCT3_MASK) >> 12 @@ -1972,7 +1972,7 @@ def rv32_rv64_float_ops(self, instrObj): instrObj.rs1 = (rs1[0], 'x') instrObj.rs2 = None return instrObj - + if instrObj.instr_name != 'None': return instrObj @@ -2329,7 +2329,7 @@ def quad2(self, instrObj): instrObj.rs1 = (2 , 'x') return instrObj - + def parseCompressedInstruction(self, instrObj_temp): ''' Parse a compressed instruction From acd5220443df4e54f856dfbe5e21e2a2209cab0b Mon Sep 17 00:00:00 2001 From: S Pawan Kumar Date: Mon, 8 Aug 2022 21:29:38 +0530 Subject: [PATCH 20/20] =?UTF-8?q?Bump=20version:=200.13.1=20=E2=86=92=200.?= =?UTF-8?q?14.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 6 ++++++ riscv_isac/__init__.py | 2 +- setup.cfg | 2 +- setup.py | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e045bf9..29b8bbdc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.14.0] - 2022-08-08 +- Add fields to instruction object +- Enable generic coverage evaluation mechanisms for floating point instructions +- Fix coverpoint generation to account for nan boxing of fp instructions. +- Add fields(frm, fcsr, nan_prefix) for fp instructions + ## [0.13.2] - 2022-05-23 - Error reporting for missing coverlabel in cgf file diff --git a/riscv_isac/__init__.py b/riscv_isac/__init__.py index 4a02a1ef..b3fa5993 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.13.2' +__version__ = '0.14.0' diff --git a/setup.cfg b/setup.cfg index b5012e01..e5e72ba9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.13.2 +current_version = 0.14.0 commit = True tag = True diff --git a/setup.py b/setup.py index 00e7ce29..f2b0e324 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ def read_requires(): setup( name='riscv_isac', - version='0.13.2', + version='0.14.0', description="RISC-V ISAC", long_description=readme + '\n\n', classifiers=[