From 6a1dfdaea3ecf205193696c8285f672b2cb5dc42 Mon Sep 17 00:00:00 2001 From: Anusha Date: Mon, 5 Jun 2023 16:07:57 +0530 Subject: [PATCH 01/11] Updated Zfinx sign extension --- riscv_isac/InstructionObject.py | 105 ++- riscv_isac/coverage.py | 24 +- riscv_isac/data/constants.py | 2 +- riscv_isac/fp_dataset.py | 1158 +++++++++++++++++++++------ riscv_isac/isac.py | 6 +- riscv_isac/plugins/specification.py | 4 +- 6 files changed, 1004 insertions(+), 295 deletions(-) diff --git a/riscv_isac/InstructionObject.py b/riscv_isac/InstructionObject.py index 7dd585c8..b41f4b6e 100644 --- a/riscv_isac/InstructionObject.py +++ b/riscv_isac/InstructionObject.py @@ -1,8 +1,8 @@ import struct instrs_sig_mutable = ['auipc','jal','jalr'] -instrs_sig_update = ['sh','sb','sw','sd','c.sw','c.sd','c.swsp','c.sdsp','fsw','fsd',\ - 'c.fsw','c.fsd','c.fswsp','c.fsdsp'] +instrs_sig_update = ['sh','sb','sw','sd','c.fsw','c.sw','c.sd','c.swsp','c.sdsp','fsw','fsd',\ + 'c.fsw','c.fsd','c.fswsp','c.fsdsp''c.lbu','c.lhu','c.lh','c.sb','c.sh'] instrs_no_reg_tracking = ['beq','bne','blt','bge','bltu','bgeu','fence','c.j','c.jal','c.jalr',\ 'c.jr','c.beqz','c.bnez', 'c.ebreak'] + instrs_sig_update instrs_fcsr_affected = ['fmadd.s','fmsub.s','fnmsub.s','fnmadd.s','fadd.s','fsub.s','fmul.s','fdiv.s',\ @@ -12,9 +12,9 @@ 'fmul.d','fdiv.d','fsqrt.d','fmin.d','fmax.d','fcvt.s.d','fcvt.d.s',\ 'feq.d','flt.d','fle.d','fcvt.w.d','fcvt.wu.d','fcvt.l.d','fcvt.lu.d',\ 'fcvt.d.l','fcvt.d.lu'] -unsgn_rs1 = ['sw','sd','sh','sb','ld','lw','lwu','lh','lhu','lb', 'lbu','flw','fld','fsw','fsd',\ - 'bgeu', 'bltu', 'sltiu', 'sltu','c.lw','c.ld','c.lwsp','c.ldsp',\ - 'c.sw','c.sd','c.swsp','c.sdsp','mulhu','divu','remu','divuw',\ +unsgn_rs1 = ['sw','sd','sh','sb','ld','lw','lwu','lh','lhu','lb', 'lbu','flw','fld','fsw','fsd','flh','fsh',\ + 'bgeu', 'bltu', 'sltiu', 'sltu','c.lw','c.lh','c.ld','c.lwsp','c.ldsp',\ + 'c.sw','c.sd','c.swsp','c.sdsp','c.fsw','mulhu','divu','remu','divuw',\ 'remuw','aes64ds','aes64dsm','aes64es','aes64esm','aes64ks2',\ 'sha256sum0','sha256sum1','sha256sig0','sha256sig1','sha512sig0',\ 'sha512sum1r','sha512sum0r','sha512sig1l','sha512sig0l','sha512sig1h','sha512sig0h',\ @@ -82,7 +82,9 @@ def __init__( rm = None, reg_commit = None, csr_commit = None, - mnemonic = None + mnemonic = None, + inxFlag = None, + is_sgn_extd = None ): ''' @@ -117,6 +119,7 @@ def __init__( self.csr_commit = csr_commit self.mnemonic = mnemonic self.is_rvp = False + self.inxFlg = inxFlag self.rs1_nregs = 1 self.rs2_nregs = 1 self.rs3_nregs = 1 @@ -146,6 +149,8 @@ def evaluate_instr_vars(self, xlen, flen, arch_state, csr_regfile, instr_vars): instr_vars['iflen'] = 32 elif self.instr_name.endswith(".d"): instr_vars['iflen'] = 64 + #elif self.instr_name.endswith(".h"): + # instr_vars['iflen'] = 16 # capture the operands if self.rs1 is not None: @@ -175,6 +180,8 @@ def evaluate_instr_vars(self, xlen, flen, arch_state, csr_regfile, instr_vars): ea_align = (self.instr_addr+(imm_val<<1)) % 4 if self.instr_name == "jalr": ea_align = (rs1_val + imm_val) % 4 + if self.instr_name in ['fsh','flh']: + ea_align = (rs1_val + imm_val) % 2 if self.instr_name in ['sw','sh','sb','lw','lhu','lh','lb','lbu','lwu','flw','fsw']: ea_align = (rs1_val + imm_val) % 4 if self.instr_name in ['ld','sd','fld','fsd']: @@ -286,7 +293,11 @@ def update_arch_state(self, arch_state, csr_regfile): if commitvalue is not None: if self.rd[1] == 'x': arch_state.x_rf[int(commitvalue[1])] = str(commitvalue[2][2:]) + print(arch_state.x_rf[int(commitvalue[1])]) + elif self.rd[1] == 'f': + #offset = len(commitvalue[2])-len(arch_state.f_rf[int(commitvalue[1])]) + #arch_state.f_rf[int(commitvalue[1])] = str(commitvalue[2][offset:]) arch_state.f_rf[int(commitvalue[1])] = str(commitvalue[2][2:]) csr_commit = self.csr_commit @@ -310,7 +321,8 @@ def evaluate_instr_var(self, instr_var_name, *args): rs1 = self.rs1, rs2 = self.rs2, rs3 = self.rs3, - is_rvp = self.is_rvp + is_rvp = self.is_rvp, + inxFlag = self.inxFlg ): # could just instr_name suffice? return func(self, *args) @@ -333,14 +345,14 @@ def evaluate_rs1_val_p_ext(self, instr_vars, arch_state): return self.evaluate_reg_val_p_ext(self.rs1[0], self.rs1_nregs, arch_state) - @evaluator_func("rs1_val", lambda **params: not params['instr_name'] in unsgn_rs1 and not params['is_rvp'] and params['rs1'] is not None and params['rs1'][1] == 'x') + @evaluator_func("rs1_val", lambda **params: not params['instr_name'] in unsgn_rs1 and not params['is_rvp'] and params['rs1'] is not None and params['rs1'][1] == 'x' and not params['inxFlag']) def evaluate_rs1_val_sgn(self, instr_vars, arch_state): return self.evaluate_reg_val_sgn(self.rs1[0], instr_vars['xlen'], arch_state) - @evaluator_func("rs1_val", lambda **params: not params['instr_name'] in unsgn_rs1 and not params['is_rvp'] and params['rs1'] is not None and params['rs1'][1] == 'f') + @evaluator_func("rs1_val", lambda **params: not params['instr_name'] in unsgn_rs1 and not params['is_rvp'] and params['rs1'] is not None and (params['rs1'][1] == 'f' or params['inxFlag'])) def evaluate_rs1_val_fsgn(self, instr_vars, arch_state): - return self.evaluate_reg_val_fsgn(self.rs1[0], instr_vars['flen'], arch_state) + return self.evaluate_reg_val_fsgn(self.rs1[0], instr_vars['flen'], instr_vars['xlen'],arch_state) ''' @@ -359,14 +371,14 @@ def evaluate_rs2_val_p_ext(self, instr_vars, arch_state): return self.evaluate_reg_val_p_ext(self.rs2[0], self.rs2_nregs, arch_state) - @evaluator_func("rs2_val", lambda **params: not params['instr_name'] in unsgn_rs2 and not params['is_rvp'] and params['rs2'] is not None and params['rs2'][1] == 'x') + @evaluator_func("rs2_val", lambda **params: not params['instr_name'] in unsgn_rs2 and not params['is_rvp'] and params['rs2'] is not None and params['rs2'][1] == 'x' and not params['inxFlag']) def evaluate_rs2_val_sgn(self, instr_vars, arch_state): return self.evaluate_reg_val_sgn(self.rs2[0], instr_vars['xlen'], arch_state) - @evaluator_func("rs2_val", lambda **params: not params['instr_name'] in unsgn_rs2 and not params['is_rvp'] and params['rs2'] is not None and params['rs2'][1] == 'f') + @evaluator_func("rs2_val", lambda **params: not params['instr_name'] in unsgn_rs2 and not params['is_rvp'] and params['rs2'] is not None and (params['rs2'][1] == 'f' or params['inxFlag'])) def evaluate_rs2_val_fsgn(self, instr_vars, arch_state): - return self.evaluate_reg_val_fsgn(self.rs2[0], instr_vars['flen'], arch_state) + return self.evaluate_reg_val_fsgn(self.rs2[0], instr_vars['flen'], instr_vars['xlen'], arch_state) ''' @@ -375,9 +387,9 @@ def evaluate_rs2_val_fsgn(self, instr_vars, arch_state): :param arch_state: Architectural state :param instr_vars: Dictionary of instruction variables already evaluated ''' - @evaluator_func("rs3_val", lambda **params: params['rs3'] is not None and params['rs3'][1] == 'f') + @evaluator_func("rs3_val", lambda **params: params['rs3'] is not None and (params['rs3'][1] == 'f' or params['inxFlag'])) def evaluate_rs3_val_fsgn(self, instr_vars, arch_state): - return self.evaluate_reg_val_fsgn(self.rs3[0], instr_vars['flen'], arch_state) + return self.evaluate_reg_val_fsgn(self.rs3[0], instr_vars['flen'], instr_vars['xlen'], arch_state) ''' @@ -393,12 +405,12 @@ def evaluate_f_ext_sem(self, instr_vars, arch_state, csr_regfile): f_ext_vars['fcsr'] = int(csr_regfile['fcsr'], 16) - if 'rs1' in instr_vars and instr_vars['rs1'] is not None and instr_vars['rs1'].startswith('f'): - self.evaluate_reg_sem_f_ext(instr_vars['rs1_val'], instr_vars['flen'], instr_vars['iflen'], "1", f_ext_vars) - if 'rs2' in instr_vars and instr_vars['rs2'] is not None and instr_vars['rs2'].startswith('f'): - self.evaluate_reg_sem_f_ext(instr_vars['rs2_val'], instr_vars['flen'], instr_vars['iflen'], "2", f_ext_vars) - if 'rs3' in instr_vars and instr_vars['rs3'] is not None and instr_vars['rs3'].startswith('f'): - self.evaluate_reg_sem_f_ext(instr_vars['rs3_val'], instr_vars['flen'], instr_vars['iflen'], "3", f_ext_vars) + if 'rs1' in instr_vars and instr_vars['rs1'] is not None and (instr_vars['rs1'].startswith('f') or instr_vars['inxFlag']): + self.evaluate_reg_sem_f_ext(instr_vars['rs1_val'], instr_vars['flen'], instr_vars['iflen'], "1", f_ext_vars, instr_vars['inxFlag'], instr_vars['xlen']) + if 'rs2' in instr_vars and instr_vars['rs2'] is not None and (instr_vars['rs2'].startswith('f') or instr_vars['inxFlag']): + self.evaluate_reg_sem_f_ext(instr_vars['rs2_val'], instr_vars['flen'], instr_vars['iflen'], "2", f_ext_vars, instr_vars['inxFlag'], instr_vars['xlen']) + if 'rs3' in instr_vars and instr_vars['rs3'] is not None and (instr_vars['rs3'].startswith('f') or instr_vars['inxFlag']): + self.evaluate_reg_sem_f_ext(instr_vars['rs3_val'], instr_vars['flen'], instr_vars['iflen'], "3", f_ext_vars, instr_vars['inxFlag'], instr_vars['xlen']) return f_ext_vars @@ -416,9 +428,12 @@ def evaluate_reg_val_sgn(self, reg_idx, xlen, arch_state): return struct.unpack(sgn_sz, bytes.fromhex(arch_state.x_rf[reg_idx]))[0] - def evaluate_reg_val_fsgn(self, reg_idx, flen, arch_state): - fsgn_sz = '>Q' if flen == 64 else '>I' - return struct.unpack(fsgn_sz, bytes.fromhex(arch_state.f_rf[reg_idx]))[0] + def evaluate_reg_val_fsgn(self, reg_idx, flen, xlen, arch_state): + fsgn_sz = '>Q' if xlen == 64 else '>I' + if self.inxFlg: + return struct.unpack(fsgn_sz, bytes.fromhex(arch_state.x_rf[reg_idx]))[0] + else: + return struct.unpack(fsgn_sz, bytes.fromhex(arch_state.f_rf[reg_idx]))[0] def evaluate_reg_val_p_ext(self, reg_idx, nregs, arch_state): @@ -427,27 +442,51 @@ def evaluate_reg_val_p_ext(self, reg_idx, nregs, arch_state): reg_hi_val = evaluate_reg_val_unsgn(reg_idx+1, arch_state) reg_val = (reg_hi_val << 32) | reg_val return reg_val - - - def evaluate_reg_sem_f_ext(self, reg_val, flen, iflen, postfix, f_ext_vars): + + def sign_extend(self, value, e_bits, v_bits ): + return bin(value | ((1< iflen: - f_ext_vars['rs'+postfix+'_nan_prefix'] = int(bin_val[0:flen-iflen],2) - bin_val = bin_val[flen-iflen:] + bin_val = ('{:0'+str(xlen)+'b}').format(reg_val) + if xlen > iflen: + if inxFlag: + if bin_val[32] == '1' : + sgnd_bin_val = bin(reg_val &((1<..= patterns in instruction fixed_ranges = re.compile( diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index fd3bb9ad..90b559b5 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -6,6 +6,20 @@ import math from decimal import * +# Prasanna +hzero = ['0x0000', '0x8000'] +hminsubnorm = ['0x0001', '0x8001'] +hsubnorm = ['0x0002', '0x8002', '0x03FE', '0x83FE', '0x02AA', '0x82AA'] +hmaxsubnorm = ['0x03FF', '0x83FF'] +hminnorm = ['0x0400', '0x8400'] +hnorm = ['0x0401', '0x8401', '0x0455', '0x8455', '0x04AA', '0x84AA', '0x5400', '0xD400', '0x2800', '0xA800'] +hmaxnorm = ['0x7BFF', '0xFBFF'] +hinfinity = ['0x7C00', '0xFC00'] +hdefaultnan = ['0x7E00', '0xFE00'] +hqnan = ['0x7E01', '0xFE01', '0x7E55', '0xFE55'] +hsnan = ['0x7C01', '0xFC01', '0x7D55', '0xFD55'] +hone = ['0x3C00', '0xBC00'] + fzero = ['0x00000000', '0x80000000'] fminsubnorm = ['0x00000001', '0x80000001'] fsubnorm = ['0x00000002', '0x80000002', '0x007FFFFE', '0x807FFFFE', '0x00555555', '0x80555555'] @@ -34,16 +48,16 @@ rounding_modes = ['0','1','2','3','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' \ +sanitise_cvpt = lambda rm,x,iflen,flen,c,inxFlg: x + ' fcsr == '+hex(rm<<5) + ' and rm_val == 7 ' \ + + ('' if iflen == flen and inxFlg else ''.join([' and rs'+str(x)+'_nan_prefix == 0x' \ + 'f'*int((flen-iflen)/4) for x in range(1,c+1)])) -sanitise_norm = lambda rm,x,iflen,flen,c: x + ' fcsr == 0'\ - + ('' if iflen == flen else ''.join([' and rs'+str(x)+'_nan_prefix == 0x' \ +sanitise_norm = lambda rm,x,iflen,flen,c,inxFlg: x + ' fcsr == 0'\ + + ('' if iflen == flen or inxFlg else ''.join([' and rs'+str(x)+'_nan_prefix == 0x' \ + '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' +sanitise_norm_nopref = lambda rm,x,iflen,flen,c,inxFlg: x + ' fcsr == 0' +sanitise_nopref = lambda rm,x,iflen,flen,c,inxFlg: 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 \ @@ -52,6 +66,18 @@ def num_explain(flen,num): num_dict = { + tuple(hzero) : 'hzero', + tuple(hminsubnorm) : 'hminsubnorm', + tuple(hsubnorm) : 'hsubnorm', + tuple(hmaxsubnorm) : 'hmaxsubnorm', + tuple(hminnorm) : 'hminnorm', + tuple(hnorm) : 'hnorm', + tuple(hmaxnorm) : 'hmaxnorm', + tuple(hinfinity) : 'hinfinity', + tuple(hdefaultnan) : 'hdefaultnan', + tuple(hqnan) : 'hqnan', + tuple(hsnan) : 'hsnan', + tuple(hone) : 'hone', tuple(fzero) : 'fzero', tuple(fminsubnorm) : 'fminsubnorm', tuple(fsubnorm) : 'fsubnorm', @@ -82,7 +108,10 @@ def num_explain(flen,num): if(('0x'+num[2:].upper()) in num_list[i][0]): return(num_list[i][1]) - if flen == 32: + if flen == 16: + e_sz = 5 # exponent size + m_sz = 10 # mantissa size + elif flen == 32: e_sz = 8 m_sz = 23 else: @@ -94,12 +123,17 @@ def num_explain(flen,num): man = bin_val[e_sz+1:] if(int(exp,2)!=0): - return('fnorm' if flen==32 else 'dnorm') + #return('fnorm' if flen==32 else 'dnorm') + return('hnorm' if flen == 16 else 'fnorm' if flen==32 else 'dnorm') else: - return('fsubnorm' if flen==32 else 'dsubnorm') + return('hsubnorm' if flen == 16 else 'fsubnorm' if flen==32 else 'dsubnorm') + #return('fsubnorm' if flen==32 else 'dsubnorm') def extract_fields(flen, hexstr, postfix): - if flen == 32: + if flen == 16: + e_sz = 5 # exponent size + m_sz = 10 # mantissa size + elif flen == 32: e_sz = 8 m_sz = 23 else: @@ -109,7 +143,11 @@ def extract_fields(flen, hexstr, postfix): sgn = bin_val[0] exp = bin_val[1:e_sz+1] man = bin_val[e_sz+1:] - if flen == 32: + if flen == 16: + string = 'fs'+postfix+' == '+str(sgn) +\ + ' and fe'+postfix+' == '+'0x'+str(hex(int('1000'+exp,2))[3:]) +\ + ' and fm'+postfix+' == '+'0x'+str(hex(int('100'+man,2))[3:]) #Adds buffer bits to convert to hex + elif flen == 32: string = 'fs'+postfix+' == '+str(sgn) +\ ' and fe'+postfix+' == '+'0x'+str(hex(int('1'+exp,2))[3:]) +\ ' and fm'+postfix+' == '+'0x'+str(hex(int('10'+man,2))[3:]) @@ -121,8 +159,10 @@ def extract_fields(flen, hexstr, postfix): return string def fields_dec_converter(flen, hexstr): # IEEE-754 Hex -> Decimal Converter - - if flen == 32: + if flen == 16: + e_sz = 5 # exponent size + m_sz = 10 + elif flen == 32: e_sz = 8 m_sz = 23 elif flen == 64: @@ -141,7 +181,14 @@ def fields_dec_converter(flen, hexstr): # IEEE-754 He exp_str = '*pow(2,' - if(flen == 32): + if(flen == 16): + if((int(exp,2)-15)<-14): + conv_num = 0.0 + exp_str+= str(-14)+')' + elif((int(exp,2)-15)>=-14): + conv_num = 1.0 + exp_str+= str(int(exp,2)-15)+')' + elif(flen == 32): if((int(exp,2)-127)<-126): conv_num = 0.0 exp_str+= str(-126)+')' @@ -159,7 +206,12 @@ def fields_dec_converter(flen, hexstr): # IEEE-754 He conv_num+= (1/(pow(2,i+1)))*int(man[i]) num = sign + str(conv_num) + exp_str - if(flen == 32): + if(flen == 16): + if(eval(num) > 6e-8 or eval(num) < -6e-8): + return eval(num) + else: + return eval(sign+'6e-8') + elif(flen == 32): if(eval(num) > 1e-45 or eval(num)<-1e-45): return(eval(num)) else: @@ -169,7 +221,12 @@ def fields_dec_converter(flen, hexstr): # IEEE-754 He def floatingPoint_tohex(flen,float_no): # Decimal -> IEEE-754 Hex Converter - if(flen==32): + if (flen==16): + if(str(float_no)=='-inf'): + return(hinfinity[1]) + elif(str(float_no)=='inf'): + return(hinfinity[0]) + elif(flen==32): if(str(float_no)=='-inf'): return(finfinity[1]) elif(str(float_no)=='inf'): @@ -190,7 +247,20 @@ def floatingPoint_tohex(flen,float_no): # Decimal -> sign=1 nor=float.hex(a) # Normalized Number - if(flen==32): + if(flen==16): + if(int(nor.split("p")[1])<-14): # Checking Underflow of Exponent + exp_bin=('0'*5) # Exponent of Subnormal numbers + exp_sn=int(nor.split("p")[1]) + num="SN" + elif(int(nor.split("p")[1])>15): # Checking Overflow of Exponent + if(sign==0): + return "0x7BFF" # Most Positive Value + else: + return "0xFBFF" # Most Negative Value + else: # Converting Exponent to 8-Bit Binary + exp=int(nor.split("p")[1])+15 + exp_bin=('0'*(5-(len(bin(exp))-2)))+bin(exp)[2:] + elif(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]) @@ -213,7 +283,7 @@ def floatingPoint_tohex(flen,float_no): # Decimal -> if(sign==0): return "0x7FEFFFFFFFFFFFFF" # Most Positive Value else: - return "0x0xFFEFFFFFFFFFFFFF" # Most Negative Value + return "0xFFEFFFFFFFFFFFFF" # 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:] @@ -229,7 +299,19 @@ def floatingPoint_tohex(flen,float_no): # Decimal -> else: mant="0x"+nor.split("p")[0][5:] - if(flen==32): + if(flen==16): + 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!=-15): + exp_sn+=1 + mant_bin = '0'+mant_bin + binary="0b" + binary=binary+str(sign)+exp_bin+mant_bin[0:10] + hex_tp=hex(int(binary,2)) + hex_tp=hex_tp.replace('0x','0x'+'0'*(4-(len(hex_tp)-2))) + + elif(flen==32): mant_bin=bin(int('1'+mant[2:],16))[3:] if(num == "SN"): mant_bin='1'+bin(int('1'+mant[2:],16))[3:] @@ -268,7 +350,18 @@ def comments_parser(coverpoints): cvpts.append((cvpt+ " #nosat",comment)) return cvpts -def ibm_b1(flen, iflen, opcode, ops): +def sgn_prefix(iflen,flen,inxFlag,c,cvpt): + sp='' + xlen = 64 + if(xlen >iflen and inxFlag): + for x in range(1,c+1): + if 'fs'+str(x)+' == 1' in cvpt: + sp += ' and rs'+str(x)+'_sgn_prefix == 0x'+'f'*int((xlen-iflen)/4) + else: + sp += ' and rs'+str(x)+'_sgn_prefix == 0x'+'0'*int((xlen-iflen)/4) + return sp + +def ibm_b1(flen, iflen, opcode, ops, inxFlg=False): ''' IBM Model B1 Definition: Test all combinations of floating-point basic types, positive and negative, for @@ -298,7 +391,13 @@ def ibm_b1(flen, iflen, opcode, ops): ''' sanitise = get_sanitise_func(opcode) - if iflen == 32: + if iflen == 16: + basic_types = hzero + hminsubnorm + [hsubnorm[0], hsubnorm[3]] +\ + hmaxsubnorm + hminnorm + [hnorm[0], hnorm[3]] + hmaxnorm + \ + hinfinity + hdefaultnan + [hqnan[0], hqnan[3]] + \ + [hsnan[0], hsnan[3]] + hone + + elif iflen == 32: basic_types = fzero + fminsubnorm + [fsubnorm[0], fsubnorm[3]] +\ fmaxsubnorm + fminnorm + [fnorm[0], fnorm[3]] + fmaxnorm + \ finfinity + fdefaultnan + [fqnan[0], fqnan[3]] + \ @@ -321,11 +420,11 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) elif opcode.split('.')[0] in \ ["fclass","flt","fmax","fsgnjn","fmin","fsgnj","feq","flw","fsw","fsgnjx","fld","fle"]: - cvpt = sanitise(0,cvpt,iflen,flen,ops) - + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -333,15 +432,16 @@ def ibm_b1(flen, iflen, opcode, ops): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b2(flen, iflen, opcode, ops, inxFlg=False, int_val = 100, seed = -1): ''' IBM Model B2 Definition: This model tests final results that are very close, measured in Hamming @@ -377,7 +477,12 @@ def ibm_b2(flen, iflen, opcode, ops, int_val = 100, seed = -1): ''' sanitise = get_sanitise_func(opcode) - if iflen == 32: + if iflen == 16: + flip_types = hzero + hone + hminsubnorm + hmaxsubnorm + hminnorm + hmaxnorm + b = '0x0010' + e_sz= 5 + m_sz = 10 + elif iflen == 32: flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm b = '0x00000010' e_sz=8 @@ -416,10 +521,15 @@ def ibm_b2(flen, iflen, opcode, ops, int_val = 100, seed = -1): 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 + if iflen == 16: + for j in range(1, 11): + result.append(['0x'+hex(eval(bin(int('1'+flip_types[i][2:], 16))) ^ eval('0b'+'{:015b}'.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 + else: + 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:] @@ -453,7 +563,11 @@ def ibm_b2(flen, iflen, opcode, ops, int_val = 100, seed = -1): elif opcode in 'fnmsub': rs2 = -1*(rs3 + fields_dec_converter(iflen,result[i][0]))/rs1 - if(iflen==32): + if(iflen==16): # Checks for inf values + m = float('inf') if rs2 > fields_dec_converter(16, hmaxnorm[0]) \ + else float('-inf') if rs2 < fields_dec_converter(16, hmaxnorm[1]) \ + else rs2 + elif(iflen==32): m = struct.unpack('f', struct.pack('f', rs2))[0] elif(iflen==64): m = rs2 @@ -464,7 +578,7 @@ def ibm_b2(flen, iflen, opcode, ops, int_val = 100, seed = -1): 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: @@ -473,7 +587,8 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -485,13 +600,13 @@ def ibm_b2(flen, iflen, opcode, ops, int_val = 100, seed = -1): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b3(flen,iflen, opcode, ops, inxFlg=False, 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. @@ -547,7 +662,35 @@ def ibm_b3(flen,iflen, opcode, ops, seed=-1): else: random.seed(seed) - if iflen == 32: + if iflen == 16: + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_num = [] + lsb = [] + for i in hsubnorm+hnorm: + 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(16,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([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 == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) ieee754_num = [] @@ -606,58 +749,65 @@ def ibm_b3(flen,iflen, opcode, ops, seed=-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 = [] + b3_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: + if iflen == 32 or iflen == 16: rs2 = ir_dataset[i][0] - rs1 elif iflen == 64: rs2 = Decimal(ir_dataset[i][0]) - Decimal(rs1) elif opcode in 'fsub': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = rs1 - ir_dataset[i][0] elif iflen == 64: rs2 = Decimal(rs1) - Decimal(ir_dataset[i][0]) elif opcode in 'fmul': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = ir_dataset[i][0]/rs1 elif iflen == 64: rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) elif opcode in 'fdiv': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = rs1/ir_dataset[i][0] elif iflen == 64: rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) elif opcode in 'fsqrt': - if iflen == 32: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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): + if(iflen==16): + m = lambda rsx: float('inf') if rsx > fields_dec_converter(16, hmaxnorm[0]) \ + else float('-inf') if rsx < fields_dec_converter(16, hmaxnorm[1]) \ + else rsx + x1 = m(rs1) + x2 = m(rs2) + x3 = m(rs3) + elif(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] @@ -667,15 +817,15 @@ def ibm_b3(flen,iflen, opcode, ops, seed=-1): x3 = rs3 if opcode in ['fadd','fsub','fmul','fdiv']: - b4_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) + b3_comb.append((floatingPoint_tohex(iflen,float(rs1)),floatingPoint_tohex(iflen,float(rs2)))) elif opcode in 'fsqrt': - b4_comb.append((floatingPoint_tohex(iflen,float(rs2)),)) + b3_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)))) + b3_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 c in b3_comb: for rm in range(5): cvpt = "" for x in range(1, ops+1): @@ -683,7 +833,8 @@ 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(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -695,13 +846,13 @@ def ibm_b3(flen,iflen, opcode, ops, seed=-1): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b4(flen, iflen, opcode, ops, inxFlg=False, seed=-1): ''' IBM Model B4 Definition: This model creates a test-case for each of the following constraints on the @@ -761,7 +912,21 @@ def ibm_b4(flen, iflen, opcode, ops, seed=-1): else: random.seed(seed) - if iflen == 32: + if iflen == 16: + ieee754_maxnorm_p = float.hex(fields_dec_converter(16, hmaxnorm[0])) + ieee754_maxnorm_n = float.hex(fields_dec_converter(16, hmaxnorm[1])) + 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(15+i),' | Exponent = '+str(15+i)+' Number = +ve']) + ir_dataset.append([ieee754_maxnorm_n.split('p')[0]+'p'+str(15+i),' | Exponent = '+str(15+i)+' Number = -ve']) + for i in range(len(ir_dataset)): + ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) + elif iflen == 32: ieee754_maxnorm_p = '0x1.7fffffp+127' ieee754_maxnorm_n = '0x1.7ffffep+127' maxnum = float.fromhex(ieee754_maxnorm_p) @@ -794,52 +959,59 @@ def ibm_b4(flen, iflen, opcode, ops, seed=-1): rs1 = random.uniform(1,maxnum) rs3 = random.uniform(1,maxnum) if opcode in 'fadd': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = ir_dataset[i][0] - rs1 elif iflen == 64: rs2 = Decimal(ir_dataset[i][0]) - Decimal(rs1) elif opcode in 'fsub': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = rs1 - ir_dataset[i][0] elif iflen == 64: rs2 = Decimal(rs1) - Decimal(ir_dataset[i][0]) elif opcode in 'fmul': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = ir_dataset[i][0]/rs1 elif iflen == 64: rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) elif opcode in 'fdiv': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = rs1/ir_dataset[i][0] elif iflen == 64: rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) elif opcode in 'fsqrt': - if iflen == 32: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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): + if(iflen==16): + m = lambda rsx: float('inf') if rsx > fields_dec_converter(16, hmaxnorm[0]) \ + else float('-inf') if rsx < fields_dec_converter(16, hmaxnorm[1]) \ + else rsx + x1 = m(rs1) + x2 = m(rs2) + x3 = m(rs3) + elif(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] @@ -865,7 +1037,8 @@ 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(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -877,13 +1050,13 @@ def ibm_b4(flen, iflen, opcode, ops, seed=-1): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b5(flen, iflen, opcode, ops, inxFlg=False, seed=-1): ''' IBM Model B5 Definition: This model creates a test-case for each of the following constraints on the intermediate results: @@ -924,7 +1097,26 @@ def ibm_b5(flen, iflen, opcode, ops, seed=-1): opcode = opcode.split('.')[0] getcontext().prec = 40 - if iflen == 32: + if iflen == 16: + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = float.hex(fields_dec_converter(16, hminsubnorm[0])) + 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-14' + 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-14','0x1.000000p-13','0x1.000000p-12','0x1.000000p-11','0x1.000000p-10','0x1.000000p-9'] + for i in minnorm_Exp: + ir_dataset.append([i,' | Exponent = MinNorm.exp + '+str(14+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 == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) ieee754_minsubnorm = '0x0.000001p-126' @@ -996,52 +1188,59 @@ def ibm_b5(flen, iflen, opcode, ops, seed=-1): rs1 = random.uniform(1,maxnum) rs3 = random.uniform(1,maxnum) if opcode in 'fadd': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = ir_dataset[i][0] - rs1 elif iflen == 64: rs2 = Decimal(ir_dataset[i][0]) - Decimal(rs1) elif opcode in 'fsub': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = rs1 - ir_dataset[i][0] elif iflen == 64: rs2 = Decimal(rs1) - Decimal(ir_dataset[i][0]) elif opcode in 'fmul': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = ir_dataset[i][0]/rs1 elif iflen == 64: rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) elif opcode in 'fdiv': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = rs1/ir_dataset[i][0] elif iflen == 64: rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) elif opcode in 'fsqrt': - if iflen == 32: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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): + if(iflen==16): + m = lambda rsx: float('inf') if rsx > fields_dec_converter(16, hmaxnorm[0]) \ + else float('-inf') if rsx < fields_dec_converter(16, hmaxnorm[1]) \ + else rsx + x1 = m(rs1) + x2 = m(rs2) + x3 = m(rs3) + elif(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] @@ -1067,7 +1266,8 @@ 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(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1079,13 +1279,13 @@ def ibm_b5(flen, iflen, opcode, ops, seed=-1): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b6(flen, iflen, opcode, ops, inxFlg=False, seed=-1): ''' IBM Model B6 Definition: This model tests intermediate results in the space between –MinSubNorm and @@ -1142,7 +1342,39 @@ def ibm_b6(flen, iflen, opcode, ops, seed=-1): else: random.seed(seed) - if iflen == 32: + if iflen == 16: + ir_dataset = [] + ieee754_minsubnorm_n = float.hex(fields_dec_converter(16, hminsubnorm[1])) + minnum = float.fromhex(ieee754_minsubnorm_n) + r=str(random.uniform(minnum,minnum/2)) + for i in range(2,16,2): + grs = '{:04b}'.format(i) + print("+"*20) + print(str(Decimal(r.split('e')[0]))) + print(i) + print(i*16,-7) + print(pow(i*16, -7)) + print("="*20) + for p in range(8): + print(Decimal(pow(i*16,-1*p))) + print("="*20) + print(Decimal(pow(i*16,-2))) + print(r.split('e')[1]) + print(str(Decimal(r.split('e')[0])+Decimal(pow(i*4,-2)))) + ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*4,-4)))+'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*4,-4)))+'e'+r.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (-MinSubNorm / 2, 0)']) + r=str(random.uniform(0, (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*4,-4)))+'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,-14))),' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (+MinSubNorm / 2, +MinSubNorm)']) + elif iflen == 32: ir_dataset = [] ieee754_minsubnorm_n = '-0x0.000001p-127' minnum = float.fromhex(ieee754_minsubnorm_n) @@ -1202,7 +1434,14 @@ def ibm_b6(flen, iflen, opcode, ops, seed=-1): elif opcode in 'fnmsub': rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) - if(iflen==32): + if(iflen==16): + m = lambda rsx: float('inf') if rsx > fields_dec_converter(16, hmaxnorm[0]) \ + else float('-inf') if rsx < fields_dec_converter(16, hmaxnorm[1]) \ + else rsx + x1 = m(rs1) + x2 = m(rs2) + x3 = m(rs3) + elif(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] @@ -1227,8 +1466,9 @@ 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(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) # cvpt += 'rm_val == '+str(rm) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1240,13 +1480,13 @@ def ibm_b6(flen, iflen, opcode, ops, seed=-1): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b7(flen, iflen, opcode, ops, inxFlg=False, 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. @@ -1286,10 +1526,27 @@ 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: + if iflen == 16: + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_num = [] + for i in hsubnorm+hnorm: + float_val = float.hex(fields_dec_converter(16,i)) + if float_val[0] != '-': + ieee754_num.append(float_val.split('p')[0][0:7]+'p'+float_val.split('p')[1]) + ir_dataset = [] + for k in range(len(ieee754_num)): + for i in range(0,7): + comment = (7-i)*'0' + '1' + i*'0' + ir_dataset.append([ieee754_num[k].split('p')[0]+hex(int('010'+'{:08b}'.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 == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) ieee754_num = [] @@ -1350,52 +1607,59 @@ def ibm_b7(flen, iflen, opcode, ops, seed=-1): rs1 = random.uniform(1,maxnum) rs3 = random.uniform(1,maxnum) if opcode in 'fadd': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = ir_dataset[i][0] - rs1 elif iflen == 64: rs2 = Decimal(ir_dataset[i][0]) - Decimal(rs1) elif opcode in 'fsub': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = rs1 - ir_dataset[i][0] elif iflen == 64: rs2 = Decimal(rs1) - Decimal(ir_dataset[i][0]) elif opcode in 'fmul': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = ir_dataset[i][0]/rs1 elif iflen == 64: rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) elif opcode in 'fdiv': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = rs1/ir_dataset[i][0] elif iflen == 64: rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) elif opcode in 'fsqrt': - if iflen == 32: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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): + if(iflen==16): + m = lambda rsx: float('inf') if rsx > fields_dec_converter(16, hmaxnorm[0]) \ + else float('-inf') if rsx < fields_dec_converter(16, hmaxnorm[1]) \ + else rsx + x1 = m(rs1) + x2 = m(rs2) + x3 = m(rs3) + elif(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] @@ -1420,7 +1684,8 @@ 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(3,cvpt,iflen,flen,ops) + cvpt = sanitise(3,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1432,13 +1697,13 @@ def ibm_b7(flen, iflen, opcode, ops, seed=-1): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b8(flen, iflen, opcode, ops, inxFlg=False, 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: @@ -1475,7 +1740,28 @@ def ibm_b8(flen, iflen, opcode, ops, seed=-1): sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] getcontext().prec = 60 - if iflen == 32: + if iflen == 16: + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_num = [] + for i in hsubnorm+hnorm: + float_val = float.hex(fields_dec_converter(16,i)) + if float_val[0] != '-': + ieee754_num.append(float_val.split('p')[0][0:7]+'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)]) + print(ir_dataset[-2]) + print(ir_dataset[-1]) + n = len(ir_dataset) + for i in range(n): + ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) + elif iflen == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) ieee754_num = [] @@ -1542,52 +1828,59 @@ def ibm_b8(flen, iflen, opcode, ops, seed=-1): rs1 = random.uniform(1,ir_dataset[i][0]) rs3 = random.uniform(1,ir_dataset[i][0]) if opcode in 'fadd': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = ir_dataset[i][0] - rs1 elif iflen == 64: rs2 = Decimal(ir_dataset[i][0]) - Decimal(rs1) elif opcode in 'fsub': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = rs1 - ir_dataset[i][0] elif iflen == 64: rs2 = Decimal(rs1) - Decimal(ir_dataset[i][0]) elif opcode in 'fmul': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = ir_dataset[i][0]/rs1 elif iflen == 64: rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) elif opcode in 'fdiv': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = rs1/ir_dataset[i][0] elif iflen == 64: rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) elif opcode in 'fsqrt': - if iflen == 32: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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): + if(iflen==16): + m = lambda rsx: float('inf') if rsx > fields_dec_converter(16, hmaxnorm[0]) \ + else float('-inf') if rsx < fields_dec_converter(16, hmaxnorm[1]) \ + else rsx + x1 = m(rs1) + x2 = m(rs2) + x3 = m(rs3) + elif(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] @@ -1612,8 +1905,9 @@ 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(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) # cvpt += 'rm_val == '+str(rm) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1625,13 +1919,13 @@ def ibm_b8(flen, iflen, opcode, ops, seed=-1): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b9(flen, iflen, opcode, ops, inxFlg=False): ''' IBM Model B9 Definition: This model tests special patterns in the significands of the input operands. Each @@ -1671,8 +1965,10 @@ def ibm_b9(flen, iflen, opcode, ops): ''' sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] - - if iflen == 32: + if iflen == 16: + flip_types = hzero + hone + hminsubnorm + hmaxsubnorm + hminnorm + hmaxnorm + e_sz=5 + elif iflen == 32: flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm e_sz=8 elif iflen == 64: @@ -1820,7 +2116,8 @@ def ibm_b9(flen, iflen, opcode, ops): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1832,13 +2129,13 @@ def ibm_b9(flen, iflen, opcode, ops): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b10(flen, iflen, opcode, ops, inxFlg=False, N=-1, seed=-1): ''' IBM Model B10 Definition: This model tests every possible value for a shift between the input operands. @@ -1874,7 +2171,11 @@ def ibm_b10(flen, iflen, opcode, ops, N=-1, seed=-1): sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] - if iflen == 32: + if iflen == 16: + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + maxnum = float.fromhex(ieee754_maxnorm) + exp_max = 31 + elif iflen == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) exp_max = 255 @@ -1897,6 +2198,8 @@ def ibm_b10(flen, iflen, opcode, ops, N=-1, seed=-1): b10_comb = [] comment = [] for i in range(1,N): + # rs1 = ("{:e}".format(random.uniform(1,maxnum/1000))) + # rs2 = ("{:e}".format(random.uniform(1,maxnum/1000))) rs1 = random.uniform(1,maxnum/1000) rs2 = random.uniform(1,maxnum/1000) rs1_exp = str(rs1).split('e')[1] @@ -1924,8 +2227,9 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) # cvpt += 'rm_val == 0' + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1937,13 +2241,13 @@ def ibm_b10(flen, iflen, opcode, ops, N=-1, seed=-1): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b11(flen, iflen, opcode, ops, inxFlg=False, N=-1, seed=-1): ''' IBM Model B11 Definition: In this model we test the combination of different shift values between the @@ -1978,7 +2282,11 @@ def ibm_b11(flen, iflen, opcode, ops, N=-1, seed=-1): sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] - if iflen == 32: + if iflen == 16: + flip_types = hzero + hone + hminsubnorm + hmaxsubnorm + hminnorm + hmaxnorm + e_sz=5 + exp_max = 255 + elif iflen == 32: flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm e_sz=8 exp_max = 255 @@ -2011,7 +2319,8 @@ def ibm_b11(flen, iflen, opcode, ops, N=-1, seed=-1): 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) + if iflen == 16: rs2_exp = '{:05b}'.format(rs2_exp) + elif 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 @@ -2078,7 +2387,8 @@ def ibm_b11(flen, iflen, opcode, ops, N=-1, seed=-1): 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) + if iflen == 16: rs2_exp = '{:05b}'.format(rs2_exp) + elif 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 @@ -2149,7 +2459,8 @@ def ibm_b11(flen, iflen, opcode, ops, N=-1, seed=-1): 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) + if iflen == 16: rs2_exp = '{:05b}'.format(rs2_exp) + elif 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 @@ -2221,7 +2532,8 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -2233,13 +2545,13 @@ def ibm_b11(flen, iflen, opcode, ops, N=-1, seed=-1): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b12(flen, iflen, opcode, ops, inxFlg=False, seed=-1): ''' IBM Model B12 Definition: This model tests every possible value for cancellation. @@ -2274,7 +2586,14 @@ def ibm_b12(flen, iflen, opcode, ops, seed=-1): opcode = opcode.split('.')[0] getcontext().prec = 40 - if iflen == 32: + if iflen == 16: + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = float.hex(fields_dec_converter(16, hminsubnorm[0])) + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = float.hex(fields_dec_converter(16, hmaxsubnorm[0])) + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + elif iflen == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) ieee754_minsubnorm = '0x0.000001p-126' @@ -2305,17 +2624,23 @@ def ibm_b12(flen, iflen, opcode, ops, seed=-1): elif opcode in 'fsub': rs1 = random.uniform(minsubnorm,maxnum) ir = random.uniform(1,maxnum) if opcode in 'fadd': - if iflen == 32: + if iflen == 16 or iflen == 32: rs2 = ir - rs1 elif iflen == 64: rs2 = Decimal(ir) - Decimal(rs1) elif opcode in 'fsub': - if iflen == 32: + if iflen == 16 or iflen == 32: rs2 = rs1 - ir elif iflen == 64: rs2 = Decimal(rs1) - Decimal(ir) - if(iflen==32): + if(iflen==16): + m = lambda rsx: float('inf') if rsx > fields_dec_converter(16, hmaxnorm[0]) \ + else float('-inf') if rsx < fields_dec_converter(16, hmaxnorm[1]) \ + else rsx + x1 = m(rs1) + x2 = m(rs2) + elif(iflen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] elif(iflen==64): @@ -2333,8 +2658,9 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) # cvpt += 'rm_val == 0' + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, 3): cvpt += 'rs'+str(y)+'_val==' @@ -2345,13 +2671,13 @@ def ibm_b12(flen, iflen, opcode, ops, seed=-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 B12 for '+opcode+' !' + (str(16) if iflen == 16 else 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): +def ibm_b13(flen, iflen, opcode, ops, inxFlg=False, seed=-1): ''' IBM Model B13 Definition: This model tests all combinations of cancellation values as in model (B12), with @@ -2383,7 +2709,14 @@ def ibm_b13(flen, iflen, opcode, ops, seed=-1): opcode = opcode.split('.')[0] getcontext().prec = 40 - if iflen == 32: + if iflen == 16: + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = float.hex(fields_dec_converter(16, hminsubnorm[0])) + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = float.hex(fields_dec_converter(16, hmaxsubnorm[0])) + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + elif iflen == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) ieee754_minsubnorm = '0x0.000001p-126' @@ -2413,17 +2746,23 @@ def ibm_b13(flen, iflen, opcode, ops, seed=-1): rs1 = random.uniform(minsubnorm,maxnum) ir = random.uniform(minsubnorm,maxsubnorm) if opcode in 'fadd': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = ir - rs1 elif iflen == 64: rs2 = Decimal(ir) - Decimal(rs1) elif opcode in 'fsub': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = rs1 - ir elif iflen == 64: rs2 = Decimal(rs1) - Decimal(ir) - if(iflen==32): + if(iflen==16): + m = lambda rsx: float('inf') if rsx > fields_dec_converter(16, hmaxnorm[0]) \ + else float('-inf') if rsx < fields_dec_converter(16, hmaxnorm[1]) \ + else rsx + x1 = m(rs1) + x2 = m(rs2) + elif(iflen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] elif(iflen==64): @@ -2441,8 +2780,9 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) # cvpt += 'rm_val == 0' + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -2453,13 +2793,13 @@ def ibm_b13(flen, iflen, opcode, ops, seed=-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 B13 for '+opcode+' !' + (str(16) if iflen == 16 else 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): +def ibm_b14(flen, iflen, opcode, ops, inxFlg=False, 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. @@ -2502,7 +2842,13 @@ def ibm_b14(flen, iflen, opcode, ops, N=-1, seed=-1): sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] - if iflen == 32: + if iflen == 16: + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + maxnum = float.fromhex(ieee754_maxnorm) + exp_max = 15 + mant_bits = 10 + limnum = maxnum + elif iflen == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) exp_max = 127 @@ -2535,9 +2881,10 @@ def ibm_b14(flen, iflen, opcode, ops, N=-1, seed=-1): b14_comb = [] comment = [] for i in range(1,N): - rs1 = random.uniform(1,limnum) - rs2 = random.uniform(1,limnum) - rs3 = random.uniform(1,limnum) + rs1 =random.uniform(1,limnum) + rs2 =random.uniform(1,limnum) + rs3 =random.uniform(1,limnum) + # mul_exp = int(str("{:e}".format(rs1*rs2)).split('e')[1]) #uncomment it if iflen =16 mul_exp = int(str(rs1*rs2).split('e')[1]) mul_exp = int(math.log(pow(2,int(mul_exp)),10)) @@ -2573,7 +2920,8 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, 4): cvpt += 'rs'+str(y)+'_val==' @@ -2585,13 +2933,13 @@ def ibm_b14(flen, iflen, opcode, ops, N=-1, seed=-1): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b15(flen, iflen, opcode, ops, inxFlg=False, N=-1, seed=-1): ''' IBM Model B15 Definition: In this model we test the combination of different shift values between the @@ -2627,7 +2975,15 @@ def ibm_b15(flen, iflen, opcode, ops, N=-1, seed=-1): sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] - if iflen == 32: + if iflen == 16: + flip_types = hzero + hone + hminsubnorm + hmaxsubnorm + hminnorm + hmaxnorm + e_sz = 5 + exp_max = 15 + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + maxnum = float.fromhex(ieee754_maxnorm) + mant_bits = 10 + limnum = maxnum + elif iflen == 32: flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm e_sz=8 exp_max = 255 @@ -2671,7 +3027,12 @@ def ibm_b15(flen, iflen, opcode, ops, N=-1, seed=-1): rs1_exp = bin_val[1:e_sz+1] rs1_man = bin_val[e_sz+1:] - if iflen == 32: + if iflen == 16: + if int(rs1_exp,2) < 33: rs2_exp = 0 + else : rs2_exp = random.randrange(0,int(rs1_exp,2)-33) + comment_str = ' | Exponent = '+ str(rs2_exp-15) + ' --> Difference smaller than -(2p + 1)' + rs2_exp = '{:05b}'.format(rs2_exp) + elif 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)' @@ -2731,7 +3092,13 @@ def ibm_b15(flen, iflen, opcode, ops, N=-1, seed=-1): 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 iflen == 16: + if int(rs1_exp,2) > 46: rs2_exp = 63 + else : rs2_exp = random.randrange(int(rs1_exp,2)+17, 63) + comment_str = ' | Exponent = '+ str(rs2_exp-15) + ' --> Difference greater than (p + 1)' + rs2_exp = '{:05b}'.format(rs2_exp) + elif 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)' @@ -2791,7 +3158,12 @@ def ibm_b15(flen, iflen, opcode, ops, N=-1, seed=-1): 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 iflen == 16: + ul = int(rs1_exp,2)+17 + ll = int(rs1_exp,2)-33 + if int(rs1_exp,2) >= 46: ul = 63 + if int(rs1_exp,2) < 33: ll = 0 + elif iflen == 32: ul = int(rs1_exp,2)+33 ll = int(rs1_exp,2)-65 if int(rs1_exp,2) >= 222: ul = 255 @@ -2803,7 +3175,11 @@ def ibm_b15(flen, iflen, opcode, ops, N=-1, seed=-1): if int(rs1_exp,2) < 129: ll = 0 for expval in range (ll, ul): rs2_exp = expval - if iflen == 32: + + if iflen == 16: + comment_str = ' | Exponent = '+ str(rs2_exp-15) + ' --> Difference between -(2p+1) and (p+1)' + rs2_exp = '{:05b}'.format(rs2_exp) + elif 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: @@ -2869,7 +3245,8 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -2881,13 +3258,13 @@ def ibm_b15(flen, iflen, opcode, ops, N=-1, seed=-1): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b16(flen, iflen, opcode, ops, inxFlg=False, seed=-1): ''' IBM Model B16 Definition: This model tests every possible value for cancellation. @@ -2923,7 +3300,15 @@ def ibm_b16(flen, iflen, opcode, ops, seed=-1): opcode = opcode.split('.')[0] getcontext().prec = 40 - if iflen == 32: + if iflen == 16: + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = float.hex(fields_dec_converter(16, hminsubnorm[0])) + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = float.hex(fields_dec_converter(16, hmaxsubnorm[0])) + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + limnum = maxnum + elif iflen == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) ieee754_minsubnorm = '0x0.000001p-126' @@ -2962,27 +3347,34 @@ def ibm_b16(flen, iflen, opcode, ops, seed=-1): ir = random.uniform(minsubnorm,rs1*rs2) if opcode in 'fmadd': - if iflen == 32: + if iflen == 32 or iflen == 16: rs3 = ir - rs1*rs2 elif iflen == 64: rs3 = Decimal(ir) - Decimal(rs1)*Decimal(rs2) elif opcode in 'fnmadd': - if iflen == 32: + if iflen == 32 or iflen == 16: rs3 = -1*rs1*rs2 - ir elif iflen == 64: rs3 = -1*Decimal(rs1)*Decimal(rs2) - Decimal(ir) elif opcode in 'fmsub': - if iflen == 32: + if iflen == 32 or iflen == 16: rs3 = rs1*rs2 - ir elif iflen == 64: rs3 = Decimal(rs1)*Decimal(rs2) - Decimal(ir) elif opcode in 'fnmsub': - if iflen == 32: + if iflen == 32 or iflen == 16: rs3 = ir + rs1*rs2 elif iflen == 64: rs3 = Decimal(ir) + Decimal(rs1)*Decimal(rs2) - if(iflen==32): + if(iflen==16): + m = lambda rsx: float('inf') if rsx > fields_dec_converter(16, hmaxnorm[0]) \ + else float('-inf') if rsx < fields_dec_converter(16, hmaxnorm[1]) \ + else rsx + x1 = m(rs1) + x2 = m(rs2) + x3 = m(rs3) + elif(iflen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] elif(iflen==64): @@ -3002,7 +3394,8 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3013,13 +3406,13 @@ def ibm_b16(flen, iflen, opcode, ops, seed=-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 B16 for '+opcode+' !' + (str(16) if iflen == 16 else 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): +def ibm_b17(flen, iflen, opcode, ops, inxFlg=False, seed=-1): ''' IBM Model B17 Definition: This model tests all combinations of cancellation values as in model (B16), with @@ -3052,7 +3445,15 @@ def ibm_b17(flen, iflen, opcode, ops, seed=-1): opcode = opcode.split('.')[0] getcontext().prec = 40 - if iflen == 32: + if iflen == 16: + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = float.hex(fields_dec_converter(16, hminsubnorm[0])) + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = float.hex(fields_dec_converter(16, hmaxsubnorm[0])) + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + limnum = maxnum + elif iflen == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) ieee754_minsubnorm = '0x0.000001p-126' @@ -3092,27 +3493,34 @@ def ibm_b17(flen, iflen, opcode, ops, seed=-1): if ir > rs1*rs2: ir = random.uniform(minsubnorm,rs1*rs2) if opcode in 'fmadd': - if iflen == 32: + if iflen == 32 or iflen == 16: rs3 = ir - rs1*rs2 elif iflen == 64: rs3 = Decimal(ir) - Decimal(rs1)*Decimal(rs2) elif opcode in 'fnmadd': - if iflen == 32: + if iflen == 32 or iflen == 16: rs3 = -1*rs1*rs2 - ir elif iflen == 64: rs3 = -1*Decimal(rs1)*Decimal(rs2) - Decimal(ir) elif opcode in 'fmsub': - if iflen == 32: + if iflen == 32 or iflen == 16: rs3 = rs1*rs2 - ir elif iflen == 64: rs3 = Decimal(rs1)*Decimal(rs2) - Decimal(ir) elif opcode in 'fnmsub': - if iflen == 32: + if iflen == 32 or iflen == 16: rs3 = ir + rs1*rs2 elif iflen == 64: rs3 = Decimal(ir) + Decimal(rs1)*Decimal(rs2) - if(iflen==32): + if(iflen==16): + m = lambda rsx: float('inf') if rsx > fields_dec_converter(16, hmaxnorm[0]) \ + else float('-inf') if rsx < fields_dec_converter(16, hmaxnorm[1]) \ + else rsx + x1 = m(rs1) + x2 = m(rs2) + x3 = m(rs3) + elif(iflen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] elif(iflen==64): @@ -3131,8 +3539,9 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) # cvpt += 'rm_val == 0' + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3143,13 +3552,13 @@ def ibm_b17(flen, iflen, opcode, ops, seed=-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 B17 for '+opcode+' !' + (str(16) if iflen == 16 else 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): +def ibm_b18(flen, iflen, opcode, ops, inxFlg=False, seed=-1): ''' IBM Model B18 Definition: This model checks different cases where the multiplication causes some event @@ -3196,7 +3605,35 @@ def ibm_b18(flen, iflen, opcode, ops, seed=-1): random.seed(seed) # Cancellation of B3 - if iflen == 32: + if iflen == 16: + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + 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(16,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([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 == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) ieee754_num = [] @@ -3262,35 +3699,42 @@ def ibm_b18(flen, iflen, opcode, ops, seed=-1): res = '0x1.7ffff0p+100' res = float.fromhex(res) if opcode in 'fmadd': - if iflen == 32: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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): + if(iflen==16): + m = lambda rsx: float('inf') if rsx > fields_dec_converter(16, hmaxnorm[0]) \ + else float('-inf') if rsx < fields_dec_converter(16, hmaxnorm[1]) \ + else rsx + x1 = m(rs1) + x2 = m(rs2) + x3 = m(rs3) + elif(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] @@ -3304,7 +3748,21 @@ def ibm_b18(flen, iflen, opcode, ops, seed=-1): ir_dataset1 = ir_dataset # Cancellation of B4 - if iflen == 32: + if iflen == 16: + ieee754_maxnorm_p = float.hex(fields_dec_converter(16, hmaxnorm[0])) + ieee754_maxnorm_n = float.hex(fields_dec_converter(16, hmaxnorm[1])) + 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(15+i),' | Exponent = '+str(15+i)+' Number = +ve']) + ir_dataset.append([ieee754_maxnorm_n.split('p')[0]+'p'+str(15+i),' | Exponent = '+str(15+i)+' Number = -ve']) + for i in range(len(ir_dataset)): + ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) + elif iflen == 32: ieee754_maxnorm_p = '0x1.7fffffp+127' ieee754_maxnorm_n = '0x1.7ffffep+127' maxnum = float.fromhex(ieee754_maxnorm_p) @@ -3330,35 +3788,42 @@ def ibm_b18(flen, iflen, opcode, ops, seed=-1): res = '0x1.7ffff0p+100' res = float.fromhex(res) if opcode in 'fmadd': - if iflen == 32: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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): + if(iflen==16): + m = lambda rsx: float('inf') if rsx > fields_dec_converter(16, hmaxnorm[0]) \ + else float('-inf') if rsx < fields_dec_converter(16, hmaxnorm[1]) \ + else rsx + x1 = m(rs1) + x2 = m(rs2) + x3 = m(rs3) + elif(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] @@ -3372,7 +3837,23 @@ def ibm_b18(flen, iflen, opcode, ops, seed=-1): ir_dataset2 = ir_dataset # Cancellation of B5 - if iflen == 32: + if iflen == 16: + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = float.hex(fields_dec_converter(16, hminsubnorm[0])) + 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-14' + 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']) + 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 == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) ieee754_minsubnorm = '0x0.000001p-126' @@ -3412,35 +3893,42 @@ def ibm_b18(flen, iflen, opcode, ops, seed=-1): res = '0x1.7ffff0p+100' res = float.fromhex(res) if opcode in 'fmadd': - if iflen == 32: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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: + if iflen == 32 or iflen == 16: 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): + if(iflen==16): + m = lambda rsx: float('inf') if rsx > fields_dec_converter(16, hmaxnorm[0]) \ + else float('-inf') if rsx < fields_dec_converter(16, hmaxnorm[1]) \ + else rsx + x1 = m(rs1) + x2 = m(rs2) + x3 = m(rs3) + elif(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] @@ -3463,7 +3951,8 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3475,13 +3964,13 @@ def ibm_b18(flen, iflen, opcode, ops, seed=-1): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b19(flen, iflen, opcode, ops, inxFlg=False, seed=-1): ''' IBM Model B19 Definition: This model checks various possible differences between the two inputs. @@ -3521,7 +4010,16 @@ def ibm_b19(flen, iflen, opcode, ops, seed=-1): opcode = opcode.split('.')[0] getcontext().prec = 40 - if iflen == 32: + if iflen == 16: + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = float.hex(fields_dec_converter(16, hminsubnorm[0])) + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = float.hex(fields_dec_converter(16, hmaxsubnorm[0])) + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + limnum = maxnum + + elif iflen == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) ieee754_minsubnorm = '0x0.000001p-126' @@ -3562,6 +4060,8 @@ def ibm_b19(flen, iflen, opcode, ops, seed=-1): sub_normal_neg = [] zero = [[0e0,'Zero']] for i in range(5): + #normal.append(["{:e}".format(random.uniform(1,maxnum)),'Normal']) + #normal_neg.append(["{:e}".format(random.uniform(-1*maxnum,-1)),'-Normal']) normal.append([random.uniform(1,maxnum),'Normal']) normal_neg.append([random.uniform(-1*maxnum,-1),'-Normal']) sub_normal.append([random.uniform(minsubnorm,maxsubnorm),'Subnormal']) @@ -3620,15 +4120,16 @@ 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(0,cvpt,iflen,flen,ops) - # cvpt += 'rm_val == 0' + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) + # cvpt += 'rm_val == 0' elif opcode in ["fclass","flt","fmax","fsgnjn","fle","fmin","fsgnj","feq", "flw","fsw","fsgnjx","fld","fsd"]: - cvpt = sanitise(0,cvpt,iflen,flen,ops) - # cvpt += 'rm_val == 1' + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) + #cvpt += 'rm_val == 1' # elif opcode in []: # cvpt = sanitise(2,cvpt,iflen,flen) # cvpt += 'rm_val == 2' + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3640,13 +4141,13 @@ def ibm_b19(flen, iflen, opcode, ops, seed=-1): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b20(flen, iflen, opcode, ops, inxFlg=False, 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: @@ -3702,7 +4203,51 @@ def ibm_b20(flen, iflen, opcode, ops, seed=-1): else: random.seed(seed) - if iflen == 32: + if iflen == 16: + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = float.hex(fields_dec_converter(16, hminsubnorm[0])) + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = float.hex(fields_dec_converter(16, hmaxsubnorm[0])) + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + limnum = maxnum + ir_dataset = [] + for i in range(1,8,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 = 9-i + sig = bits+'1'+'0'*trailing_zero + exp = random.getrandbits(5) + exp = '{:05b}'.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'*9 + exp = random.getrandbits(5) + exp = '{:05b}'.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'*10 + exp = random.getrandbits(5) + exp = '{:05b}'.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 iflen == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) ieee754_minsubnorm = '0x0.000001p-126' @@ -3800,17 +4345,23 @@ def ibm_b20(flen, iflen, opcode, ops, seed=-1): for i in range(len(ir_dataset)): rs1 = random.uniform(1, limnum) if opcode in 'fdiv': - if iflen == 32: + if iflen == 32 or iflen == 16: rs2 = rs1/ir_dataset[i][0] elif iflen == 64: rs2 = Decimal(rs1)/Decimal(ir_dataset[i][0]) elif opcode in 'fsqrt': - if iflen == 32: + if iflen == 32 or iflen == 16: 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): + if(iflen==16): + m = lambda rsx: float('inf') if rsx > fields_dec_converter(16, hmaxnorm[0]) \ + else float('-inf') if rsx < fields_dec_converter(16, hmaxnorm[1]) \ + else rsx + x1 = m(rs1) + x2 = m(rs2) + elif(iflen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] elif(iflen==64): @@ -3830,8 +4381,9 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) # cvpt += 'rm_val == 0' + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3843,13 +4395,13 @@ def ibm_b20(flen, iflen, opcode, ops, seed=-1): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b21(flen, iflen, opcode, ops, inxFlg=False): ''' 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: @@ -3879,7 +4431,11 @@ def ibm_b21(flen, iflen, opcode, ops): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' sanitise = get_sanitise_func(opcode) - if iflen == 32: + if iflen == 16: + basic_types = hzero + hsubnorm + hnorm +\ + hinfinity + hdefaultnan + [hqnan[0], hqnan[-1]] + \ + [hsnan[0], hsnan[-1]] + elif iflen == 32: basic_types = fzero + fsubnorm + fnorm + finfinity + fdefaultnan + [fqnan[0], fqnan[3]] + \ [fsnan[0], fsnan[3]] elif iflen == 64: @@ -3900,7 +4456,8 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3910,13 +4467,13 @@ def ibm_b21(flen, iflen, opcode, ops): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b22(flen, iflen, opcode, ops, inxFlg=False, seed=10): ''' IBM Model B22 Definition: This model creates test cases for each of the following exponents (unbiased): @@ -3952,7 +4509,8 @@ def ibm_b22(flen, iflen, opcode, ops, seed=10): sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] - if opcode[2] == 's': iflen = 32 + if opcode[2] == 'h': iflen = 16 + elif opcode[2] == 's': iflen = 32 elif opcode[2] == 'd': iflen = 64 getcontext().prec = 40 xlen = 0 @@ -3980,7 +4538,58 @@ def ibm_b22(flen, iflen, opcode, ops, seed=10): b22_comb = [] - if iflen == 32: + if iflen == 16: + ieee754_maxnorm = float.hex(fields_dec_converter(16, hmaxnorm[0])) + maxnum = float.fromhex(ieee754_maxnorm) + ieee754_minsubnorm = float.hex(fields_dec_converter(16, hminsubnorm[0])) + minsubnorm = float.fromhex(ieee754_minsubnorm) + ieee754_maxsubnorm = float.hex(fields_dec_converter(16, hmaxsubnorm[0])) + maxsubnorm = float.fromhex(ieee754_maxsubnorm) + limnum = maxnum + op_dataset = [] + for i in range(12,xlen+18,1): + bits = random.getrandbits(10) + bits = bin(bits)[2:] + front_zero = 10-len(bits) + sig = '0'*front_zero + bits + + exp = i + exp = '{:05b}'.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)-15) + ', Exponent in the range [-3, integer width+3]']) + b22_comb.append((floatingPoint_tohex(iflen,float(op)),)) + + bits = random.getrandbits(10) + bits = bin(bits)[2:] + front_zero = 10-len(bits) + sig = '0'*front_zero + bits + exp = random.randint(0,124) + exp = '{:05b}'.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)-15) + ', Exponent less than -3']) + b22_comb.append((floatingPoint_tohex(iflen,float(op)),)) + + bits = random.getrandbits(10) + bits = bin(bits)[2:] + front_zero = 10-len(bits) + sig = '0'*front_zero + bits + exp = random.randint(xlen+130,255) + exp = '{:05b}'.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)-15) + ', Exponent greater than (integer width+3)']) + b22_comb.append((floatingPoint_tohex(iflen,float(op)),)) + elif iflen == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) ieee754_minsubnorm = '0x0.000001p-126' @@ -4094,7 +4703,8 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4106,13 +4716,13 @@ def ibm_b22(flen, iflen, opcode, ops, seed=10): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b23(flen, iflen, opcode, ops, inxFlg=False): ''' IBM Model B23 Definition: This model creates boundary cases for the rounding to integers that might cause Overflow. @@ -4157,7 +4767,13 @@ def ibm_b23(flen, iflen, opcode, ops): nums = [0,100,200,800,1600] dataset = [] - if iflen == 32: + if iflen == 16: + maxnum = 0x7800 + + for i in range(-4,5): + dataset.append((hex(int(maxnum)+i),"| MaxInt + ({})".format(str(i)))) + + elif iflen == 32: maxnum = 0x4f000000 # MaxInt (2**31-1) in IEEE 754 Floating Point Representation for i in range(-4,5): @@ -4178,11 +4794,12 @@ def ibm_b23(flen, iflen, opcode, ops): cvpt += " and " # cvpt += 'rm_val == ' if "fmv" in opcode or opcode in "fcvt.d.s": - cvpt = sanitise(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) # cvpt += '0' else: - cvpt = sanitise(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) # cvpt += str(rm) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4194,13 +4811,13 @@ def ibm_b23(flen, iflen, opcode, ops): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b24(flen, iflen, opcode, ops, inxFlg=False): ''' IBM Model B24 Definition: This model creates boundary cases for rounding to integer that might cause major loss of accuracy. @@ -4273,11 +4890,12 @@ def ibm_b24(flen,iflen, opcode, ops): cvpt += " and " # cvpt += 'rm_val == ' if "fmv" in opcode or opcode in "fcvt.d.s": - cvpt = sanitise(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) # cvpt += '0' else: - cvpt = sanitise(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) # cvpt += str(rm) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4289,13 +4907,13 @@ def ibm_b24(flen,iflen, opcode, ops): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b25(flen, iflen, opcode, ops, inxFlg=False, seed=10): ''' IBM Model B25 Definition: This model creates a test-case for each of the following inputs(wherever applicable): @@ -4363,10 +4981,13 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) # cvpt += str(0) else: - cvpt = sanitise(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + # cvpt += str(rm) cvpt += ' # Number = ' cvpt += c[1] @@ -4380,7 +5001,7 @@ def ibm_b25(flen, iflen, opcode, ops, seed=10): return (coverpoints) -def ibm_b26(xlen, opcode, ops, seed=10): +def ibm_b26(xlen, opcode, ops, inxFlg=False, seed=10): ''' 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 @@ -4425,10 +5046,12 @@ 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(0,cvpt,xlen,xlen,ops) + cvpt = sanitise(0,cvpt,xlen,xlen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) # cvpt += str(0) else: - cvpt = sanitise(rm,cvpt,xlen,xlen,ops) + cvpt = sanitise(rm,cvpt,xlen,xlen,ops,inxFlg) + cvpt += sgn_prefix(xlen,inxFlg,ops,cvpt) # cvpt += str(rm) cvpt += c[1] coverpoints.append(cvpt) @@ -4441,7 +5064,7 @@ def ibm_b26(xlen, opcode, ops, seed=10): return coverpoints -def ibm_b27(flen, iflen, opcode, ops, seed=10): +def ibm_b27(flen, iflen, opcode, ops, inxFlg=False, 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): @@ -4479,7 +5102,9 @@ def ibm_b27(flen, iflen, opcode, ops, seed=10): sanitise = get_sanitise_func(opcode) opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] - if iflen == 32: + if iflen == 16: + dataset = hsnan + hqnan + elif iflen == 32: dataset = fsnan + fqnan elif iflen == 64: dataset = dsnan + dqnan @@ -4491,7 +5116,8 @@ def ibm_b27(flen, iflen, opcode, ops, seed=10): cvpt += (extract_fields(iflen,c,str(x))) cvpt += " and " # cvpt += 'rm_val == 0' - cvpt = sanitise(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4501,13 +5127,13 @@ def ibm_b27(flen, iflen, opcode, ops, seed=10): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b28(flen, iflen, opcode, ops, inxFlg=False, 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: @@ -4555,7 +5181,28 @@ def ibm_b28(flen, iflen, opcode, ops, seed=10): opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] dataset = [] - if iflen == 32: + if iflen == 16: + dataset.append((hzero[0],"+0")) + dataset.append((floatingPoint_tohex(16,float(random.uniform(0,1))),"A random number in the range (+0, +1)")) + dataset.append((hone[0],"+1")) + for i in range(125,300,25): + dataset.append((floatingPoint_tohex(16, i/100),"Number = "+str(i/100)+" => Number ∈ (1,2.75]")) + dataset.append((floatingPoint_tohex(16,float(random.uniform(1,2**15-1))),"A random number in the range (+1, +1.11..11*2^precision)")) + dataset.append((floatingPoint_tohex(16,float(2**15-1)),"MaxInt")) + dataset.append((hinfinity[0],"+Infinity")) + + dataset.append((hsnan[0],"Signaling NaN")) + dataset.append((hqnan[0],"Quiet NaN")) + + dataset.append((hzero[1],"-0")) + dataset.append((floatingPoint_tohex(16,float(random.uniform(-1,0))),"A random number in the range (-1, -0)")) + dataset.append((hone[1],"-1")) + for i in range(-275,-100,25): + dataset.append((floatingPoint_tohex(16, i/100),"Number = "+str(i/100)+" => Number ∈ [-2.75,-1)")) + dataset.append((floatingPoint_tohex(16,float(random.uniform(-2**15-1,-1))),"A random number in the range (-1.11..11*2^precision, -1)")) + dataset.append((floatingPoint_tohex(16,float(-2**15-1)),"-MaxInt")) + dataset.append((hinfinity[1],"-Infinity")) + elif 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")) @@ -4606,7 +5253,8 @@ 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(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4617,13 +5265,13 @@ def ibm_b28(flen, iflen, opcode, ops, seed=10): 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+' !' + (str(16) if iflen == 16 else 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): +def ibm_b29(flen, iflen, opcode, ops, inxFlg=False, 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). @@ -4657,7 +5305,16 @@ def ibm_b29(flen, iflen, opcode, ops, seed=10): random.seed(seed) sgns = ["0","1"] dataset = [] - if iflen == 32: + if iflen == 16: + mant = random.getrandbits(7) + mant = '{:07b}'.format(mant) + for sgn in sgns: + for i in range(8): + LeastGuardSticky = '{:03b}'.format(i) + hexnum = "0x" + hex(int("1"+sgn + "01100" + mant + LeastGuardSticky,2))[3:] + dataset.append((hexnum,"Exp = -3; Sign = {}; LSB = {}; Guard = {}; Sticky = {}"\ + .format(sgn,LeastGuardSticky[0],LeastGuardSticky[1],LeastGuardSticky[2]))) + elif iflen == 32: mant = random.getrandbits(20) mant = '{:020b}'.format(mant) for sgn in sgns: @@ -4685,11 +5342,12 @@ def ibm_b29(flen, iflen, opcode, ops, seed=10): cvpt += " and " # cvpt += 'rm_val == ' if "fmv" in opcode or "fcvt.d.s" in opcode: - cvpt = sanitise(0,cvpt,iflen,flen,ops) + cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) # cvpt += '0' else: - cvpt = sanitise(rm,cvpt,iflen,flen,ops) + cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) # cvpt += str(rm) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4700,7 +5358,7 @@ def ibm_b29(flen, iflen, opcode, ops, seed=10): 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+' !' + (str(16) if iflen == 16 else str(32) if iflen == 32 else str(64)) + '-bit coverpoints using Model B29 for '+opcode+' !' logger.debug(mess) coverpoints = comments_parser(coverpoints) diff --git a/riscv_isac/isac.py b/riscv_isac/isac.py index c766681b..ba2b068c 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, flen, no_count, procs, logging=False): + sig_labels, dump, cov_labels, xlen, flen, inxFlg, no_count, procs, logging=False): test_addr = [] sig_addr = [] if parser_path: @@ -37,10 +37,10 @@ def isac(output_file,elf ,trace_file, window_size, cgf, parser_name, decoder_nam sig_addr.append((start_address,end_address)) else: test_name = trace_file.rsplit(',',1)[0] - rpt = cov.compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xlen, flen, test_addr, dump, cov_labels, sig_addr, window_size, no_count, procs) + rpt = cov.compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xlen, flen, test_addr, dump, cov_labels, sig_addr, window_size, inxFlg, no_count, procs) if output_file is not None and logging: logger.info('Coverage Report:') - logger.info('\n\n' + rpt) + #logger.info('\n\n' + rpt) else: rpt_file = open(output_file,'w') utils.dump_yaml(rpt, rpt_file) diff --git a/riscv_isac/plugins/specification.py b/riscv_isac/plugins/specification.py index 2dcd7659..51a7271a 100644 --- a/riscv_isac/plugins/specification.py +++ b/riscv_isac/plugins/specification.py @@ -5,7 +5,7 @@ class DecoderSpec(object): @decoderHookSpec - def setup(self,arch): + def setup(self,inxFlag,arch): pass @decoderHookSpec @@ -19,4 +19,4 @@ def setup(self,trace,arch): @parserHookSpec def __iter__(self): - pass \ No newline at end of file + pass From e57597083fa63ea1b1012627d796b56c4e43b152 Mon Sep 17 00:00:00 2001 From: Anusha Date: Mon, 26 Jun 2023 13:30:23 +0530 Subject: [PATCH 02/11] Updated Zfinx sign extension --- riscv_isac/InstructionObject.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/riscv_isac/InstructionObject.py b/riscv_isac/InstructionObject.py index b41f4b6e..93f541a1 100644 --- a/riscv_isac/InstructionObject.py +++ b/riscv_isac/InstructionObject.py @@ -2,7 +2,7 @@ instrs_sig_mutable = ['auipc','jal','jalr'] instrs_sig_update = ['sh','sb','sw','sd','c.fsw','c.sw','c.sd','c.swsp','c.sdsp','fsw','fsd',\ - 'c.fsw','c.fsd','c.fswsp','c.fsdsp''c.lbu','c.lhu','c.lh','c.sb','c.sh'] + 'c.fsw','c.fsd','c.fswsp','c.fsdsp''c.lbu','c.sb','c.sh'] instrs_no_reg_tracking = ['beq','bne','blt','bge','bltu','bgeu','fence','c.j','c.jal','c.jalr',\ 'c.jr','c.beqz','c.bnez', 'c.ebreak'] + instrs_sig_update instrs_fcsr_affected = ['fmadd.s','fmsub.s','fnmsub.s','fnmadd.s','fadd.s','fsub.s','fmul.s','fdiv.s',\ @@ -13,7 +13,7 @@ 'feq.d','flt.d','fle.d','fcvt.w.d','fcvt.wu.d','fcvt.l.d','fcvt.lu.d',\ 'fcvt.d.l','fcvt.d.lu'] unsgn_rs1 = ['sw','sd','sh','sb','ld','lw','lwu','lh','lhu','lb', 'lbu','flw','fld','fsw','fsd','flh','fsh',\ - 'bgeu', 'bltu', 'sltiu', 'sltu','c.lw','c.lh','c.ld','c.lwsp','c.ldsp',\ + 'bgeu', 'bltu', 'sltiu', 'sltu','c.lw','c.lhu','c.lh','c.ld','c.lwsp','c.ldsp',\ 'c.sw','c.sd','c.swsp','c.sdsp','c.fsw','mulhu','divu','remu','divuw',\ 'remuw','aes64ds','aes64dsm','aes64es','aes64esm','aes64ks2',\ 'sha256sum0','sha256sum1','sha256sig0','sha256sig1','sha512sig0',\ @@ -23,16 +23,16 @@ 'andn','orn','xnor','pack','packh','packu','packuw','packw',\ 'xperm.n','xperm.b','grevi','aes64ks1i', 'shfli', 'unshfli', \ 'aes32esmi', 'aes32esi', 'aes32dsmi', 'aes32dsi','bclr','bext','binv',\ - 'bset','zext.h','sext.h','sext.b','minu','maxu','orc.b','add.uw','sh1add.uw',\ + 'bset','zext.h','sext.h','sext.b','zext.b','zext.w','minu','maxu','orc.b','add.uw','sh1add.uw',\ 'sh2add.uw','sh3add.uw','slli.uw','clz','clzw','ctz','ctzw','cpop','cpopw','rev8',\ - 'bclri','bexti','binvi','bseti','fcvt.d.wu','fcvt.s.wu','fcvt.d.lu','fcvt.s.lu'] + 'bclri','bexti','binvi','bseti','fcvt.d.wu','fcvt.s.wu','fcvt.d.lu','fcvt.s.lu','c.zext.b','c.zext.h','c.sext.h','c.sext.b','c.not'] unsgn_rs2 = ['bgeu', 'bltu', 'sltiu', 'sltu', 'sll', 'srl', 'sra','mulhu',\ 'mulhsu','divu','remu','divuw','remuw','aes64ds','aes64dsm','aes64es',\ 'aes64esm','aes64ks2','sm4ed','sm4ks','ror','rol','rorw','rolw','clmul',\ 'clmulh','clmulr','andn','orn','xnor','pack','packh','packu','packuw','packw',\ 'xperm.n','xperm.b', 'aes32esmi', 'aes32esi', 'aes32dsmi', 'aes32dsi',\ 'sha512sum1r','sha512sum0r','sha512sig1l','sha512sig1h','sha512sig0l','sha512sig0h','fsw',\ - 'bclr','bext','binv','bset','minu','maxu','add.uw','sh1add.uw','sh2add.uw','sh3add.uw'] + 'bclr','bext','binv','bset','minu','maxu','add.uw','sh1add.uw','sh2add.uw','sh3add.uw','c.mul'] f_instrs_pref = ['fadd', 'fclass', 'fcvt', 'fdiv', 'feq', 'fld', 'fle', 'flt', 'flw', 'fmadd',\ 'fmax', 'fmin', 'fmsub', 'fmul', 'fmv', 'fnmadd', 'fnmsub', 'fsd', 'fsgnj', 'fsqrt',\ 'fsub', 'fsw'] @@ -429,7 +429,7 @@ def evaluate_reg_val_sgn(self, reg_idx, xlen, arch_state): def evaluate_reg_val_fsgn(self, reg_idx, flen, xlen, arch_state): - fsgn_sz = '>Q' if xlen == 64 else '>I' + fsgn_sz = '>Q' if flen == 64 and xlen > 32 else '>I' if self.inxFlg: return struct.unpack(fsgn_sz, bytes.fromhex(arch_state.x_rf[reg_idx]))[0] else: @@ -474,19 +474,19 @@ def evaluate_reg_sem_f_ext(self, reg_val, flen, iflen, postfix, f_ext_vars, inxF else: e_sz = 11 m_sz = 52 - bin_val = ('{:0'+str(xlen)+'b}').format(reg_val) - - if xlen > iflen: + bin_val = ('{:0'+str(flen)+'b}').format(reg_val) + #widthTemp = xlen if inxFlag else flen + if flen > iflen: if inxFlag: if bin_val[32] == '1' : - sgnd_bin_val = bin(reg_val &((1< Date: Mon, 26 Jun 2023 13:39:41 +0530 Subject: [PATCH 03/11] updated dataset --- riscv_isac/data/rvopcodesdecoder.py | 2 +- riscv_isac/fp_dataset.py | 164 +++++++++++++++++++++------- 2 files changed, 126 insertions(+), 40 deletions(-) diff --git a/riscv_isac/data/rvopcodesdecoder.py b/riscv_isac/data/rvopcodesdecoder.py index 22bf061a..1645a75b 100644 --- a/riscv_isac/data/rvopcodesdecoder.py +++ b/riscv_isac/data/rvopcodesdecoder.py @@ -364,7 +364,7 @@ def decode(self, instrObj_temp): if arg == 'rs1': treg = reg_type if any([instr_name.startswith(x) for x in [ - 'fsw','fsd','fcvt.s','fcvt.d','fmv.w','fmv.l']]): + 'fsh', 'fsw','fsd','fcvt.s','fcvt.d','fmv.w','fmv.l']]): treg = 'x' temp_instrobj.rs1 = (int(get_arg_val(arg)(mcode), 2), treg) if arg == 'rs2': diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index 90b559b5..082a52cd 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -49,7 +49,7 @@ rounding_modes = ['0','1','2','3','4'] sanitise_cvpt = lambda rm,x,iflen,flen,c,inxFlg: x + ' fcsr == '+hex(rm<<5) + ' and rm_val == 7 ' \ - + ('' if iflen == flen and inxFlg else ''.join([' and rs'+str(x)+'_nan_prefix == 0x' \ + + ('' if iflen == flen or inxFlg else ''.join([' and rs'+str(x)+'_nan_prefix == 0x' \ + 'f'*int((flen-iflen)/4) for x in range(1,c+1)])) sanitise_norm = lambda rm,x,iflen,flen,c,inxFlg: x + ' fcsr == 0'\ @@ -219,7 +219,8 @@ def fields_dec_converter(flen, hexstr): # IEEE-754 He elif(flen == 64): return(eval(num)) -def floatingPoint_tohex(flen,float_no): # Decimal -> IEEE-754 Hex Converter +def floatingPoint_tohex(flen,float_no): + # Decimal -> IEEE-754 Hex Converter if (flen==16): if(str(float_no)=='-inf'): @@ -352,13 +353,13 @@ def comments_parser(coverpoints): def sgn_prefix(iflen,flen,inxFlag,c,cvpt): sp='' - xlen = 64 - if(xlen >iflen and inxFlag): + xlen = 64 + if(flen >iflen and inxFlag): for x in range(1,c+1): if 'fs'+str(x)+' == 1' in cvpt: - sp += ' and rs'+str(x)+'_sgn_prefix == 0x'+'f'*int((xlen-iflen)/4) + sp += ' and rs'+str(x)+'_sgn_prefix == 0x'+'f'*int((flen-iflen)/4) else: - sp += ' and rs'+str(x)+'_sgn_prefix == 0x'+'0'*int((xlen-iflen)/4) + sp += ' and rs'+str(x)+'_sgn_prefix == 0x'+'0'*int((flen-iflen)/4) return sp def ibm_b1(flen, iflen, opcode, ops, inxFlg=False): @@ -422,7 +423,7 @@ def ibm_b1(flen, iflen, opcode, ops, inxFlg=False): if opcode.split('.')[0] in ["fadd","fsub","fmul","fdiv","fsqrt","fmadd","fnmadd","fmsub","fnmsub","fcvt","fmv"]: cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) elif opcode.split('.')[0] in \ - ["fclass","flt","fmax","fsgnjn","fmin","fsgnj","feq","flw","fsw","fsgnjx","fld","fle"]: + ["fclass","flt","fmax","fsgnjn","fmin","fsgnj","feq","flw","fsw","fsgnjx","fld","fle"]: cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) cvpt += ' # ' @@ -588,7 +589,10 @@ def ibm_b2(flen, iflen, opcode, ops, inxFlg=False, int_val = 100, seed = -1): cvpt += (extract_fields(iflen,c[x-1],str(x))) cvpt += " and " cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -834,7 +838,10 @@ def ibm_b3(flen,iflen, opcode, ops, inxFlg=False, seed=-1): cvpt += " and " # cvpt += 'rm_val == '+str(rm) cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1038,7 +1045,10 @@ def ibm_b4(flen, iflen, opcode, ops, inxFlg=False, seed=-1): cvpt += " and " # cvpt += 'rm_val == '+str(rm) cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1267,7 +1277,10 @@ def ibm_b5(flen, iflen, opcode, ops, inxFlg=False, seed=-1): cvpt += " and " # cvpt += 'rm_val == '+str(rm) cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1468,7 +1481,10 @@ def ibm_b6(flen, iflen, opcode, ops, inxFlg=False, seed=-1): cvpt += " and " cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) # cvpt += 'rm_val == '+str(rm) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1685,7 +1701,10 @@ def ibm_b7(flen, iflen, opcode, ops, inxFlg=False, seed=-1): cvpt += " and " # cvpt += 'rm_val == 3' cvpt = sanitise(3,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -1907,7 +1926,10 @@ def ibm_b8(flen, iflen, opcode, ops, inxFlg=False, seed=-1): cvpt += " and " cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) # cvpt += 'rm_val == '+str(rm) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -2117,7 +2139,10 @@ def ibm_b9(flen, iflen, opcode, ops, inxFlg=False): cvpt += " and " # cvpt += 'rm_val == 0' cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -2198,8 +2223,6 @@ def ibm_b10(flen, iflen, opcode, ops, inxFlg=False, N=-1, seed=-1): b10_comb = [] comment = [] for i in range(1,N): - # rs1 = ("{:e}".format(random.uniform(1,maxnum/1000))) - # rs2 = ("{:e}".format(random.uniform(1,maxnum/1000))) rs1 = random.uniform(1,maxnum/1000) rs2 = random.uniform(1,maxnum/1000) rs1_exp = str(rs1).split('e')[1] @@ -2229,7 +2252,10 @@ def ibm_b10(flen, iflen, opcode, ops, inxFlg=False, N=-1, seed=-1): cvpt += " and " cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) # cvpt += 'rm_val == 0' - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -2533,7 +2559,10 @@ def ibm_b11(flen, iflen, opcode, ops, inxFlg=False, N=-1, seed=-1): cvpt += " and " # cvpt += 'rm_val == 0' cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -2660,7 +2689,10 @@ def ibm_b12(flen, iflen, opcode, ops, inxFlg=False, seed=-1): cvpt += " and " cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) # cvpt += 'rm_val == 0' - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, 3): cvpt += 'rs'+str(y)+'_val==' @@ -2782,7 +2814,10 @@ def ibm_b13(flen, iflen, opcode, ops, inxFlg=False, seed=-1): cvpt += " and " cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) # cvpt += 'rm_val == 0' - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -2921,7 +2956,10 @@ def ibm_b14(flen, iflen, opcode, ops, inxFlg=False, N=-1, seed=-1): cvpt += " and " # cvpt += 'rm_val == 0' cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, 4): cvpt += 'rs'+str(y)+'_val==' @@ -3246,7 +3284,10 @@ def ibm_b15(flen, iflen, opcode, ops, inxFlg=False, N=-1, seed=-1): cvpt += " and " # cvpt += 'rm_val == 0' cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3395,7 +3436,10 @@ def ibm_b16(flen, iflen, opcode, ops, inxFlg=False, seed=-1): cvpt += " and " # cvpt += 'rm_val == 0' cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3541,7 +3585,10 @@ def ibm_b17(flen, iflen, opcode, ops, inxFlg=False, seed=-1): cvpt += " and " cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) # cvpt += 'rm_val == 0' - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3952,7 +3999,10 @@ def ibm_b18(flen, iflen, opcode, ops, inxFlg=False, seed=-1): cvpt += " and " # cvpt += 'rm_val == 0' cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4129,7 +4179,10 @@ def ibm_b19(flen, iflen, opcode, ops, inxFlg=False, seed=-1): # elif opcode in []: # cvpt = sanitise(2,cvpt,iflen,flen) # cvpt += 'rm_val == 2' - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4383,7 +4436,10 @@ def ibm_b20(flen, iflen, opcode, ops, inxFlg=False, seed=-1): cvpt += " and " cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) # cvpt += 'rm_val == 0' - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4457,7 +4513,10 @@ def ibm_b21(flen, iflen, opcode, ops, inxFlg=False): cvpt += " and " if opcode.split('.')[0] in ["fdiv"]: cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4704,7 +4763,10 @@ def ibm_b22(flen, iflen, opcode, ops, inxFlg=False, seed=10): cvpt += " and " # cvpt += 'rm_val == 0' cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4799,7 +4861,10 @@ def ibm_b23(flen, iflen, opcode, ops, inxFlg=False): else: cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) # cvpt += str(rm) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4895,7 +4960,10 @@ def ibm_b24(flen, iflen, opcode, ops, inxFlg=False): else: cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) # cvpt += str(rm) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4982,11 +5050,17 @@ def ibm_b25(flen, iflen, opcode, ops, inxFlg=False, seed=10): # cvpt += 'rm_val == ' if "fmv" in opcode or opcode in "fcvt.d.wu": cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' # cvpt += str(0) else: cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' # cvpt += str(rm) cvpt += ' # Number = ' @@ -5047,11 +5121,14 @@ def ibm_b26(xlen, opcode, ops, inxFlg=False, seed=10): # cvpt += 'rm_val == ' if "fmv" in opcode or opcode in "fcvt.d.wu": cvpt = sanitise(0,cvpt,xlen,xlen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + # cvpt += str(0) else: cvpt = sanitise(rm,cvpt,xlen,xlen,ops,inxFlg) - cvpt += sgn_prefix(xlen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(xlen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' # cvpt += str(rm) cvpt += c[1] coverpoints.append(cvpt) @@ -5117,7 +5194,10 @@ def ibm_b27(flen, iflen, opcode, ops, inxFlg=False, seed=10): cvpt += " and " # cvpt += 'rm_val == 0' cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -5254,7 +5334,10 @@ def ibm_b28(flen, iflen, opcode, ops, inxFlg=False, seed=10): cvpt += " and " # cvpt += 'rm_val == 0' cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -5347,7 +5430,10 @@ def ibm_b29(flen, iflen, opcode, ops, inxFlg=False, seed=10): else: cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) # cvpt += str(rm) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + if inxFlg == True: + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + else: + cvpt += ' # ' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' From 9b190359c34d35ecdce46356f41a477dbca8e8e3 Mon Sep 17 00:00:00 2001 From: Anusha Date: Mon, 26 Jun 2023 13:42:11 +0530 Subject: [PATCH 04/11] updated dataset --- 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 082a52cd..616abb49 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -353,7 +353,6 @@ def comments_parser(coverpoints): def sgn_prefix(iflen,flen,inxFlag,c,cvpt): sp='' - xlen = 64 if(flen >iflen and inxFlag): for x in range(1,c+1): if 'fs'+str(x)+' == 1' in cvpt: From 6f690e74e0423092ec1af148c3463c6189aa953f Mon Sep 17 00:00:00 2001 From: Anusha Date: Mon, 26 Jun 2023 15:49:14 +0530 Subject: [PATCH 05/11] updated Zfinx code --- riscv_isac/InstructionObject.py | 2 +- riscv_isac/plugins/internaldecoder.py | 309 +++++++++++++++++++++----- 2 files changed, 256 insertions(+), 55 deletions(-) diff --git a/riscv_isac/InstructionObject.py b/riscv_isac/InstructionObject.py index 93f541a1..3907e403 100644 --- a/riscv_isac/InstructionObject.py +++ b/riscv_isac/InstructionObject.py @@ -475,7 +475,7 @@ def evaluate_reg_sem_f_ext(self, reg_val, flen, iflen, postfix, f_ext_vars, inxF e_sz = 11 m_sz = 52 bin_val = ('{:0'+str(flen)+'b}').format(reg_val) - #widthTemp = xlen if inxFlag else flen + if flen > iflen: if inxFlag: if bin_val[32] == '1' : diff --git a/riscv_isac/plugins/internaldecoder.py b/riscv_isac/plugins/internaldecoder.py index 0e9a4ea1..5d65d385 100644 --- a/riscv_isac/plugins/internaldecoder.py +++ b/riscv_isac/plugins/internaldecoder.py @@ -18,8 +18,8 @@ def __init__(self): 0b0011011: self.rv64i_arithi_ops, 0b0111011: self.rv64i_arith_ops, 0b0101111: self.rv64_rv32_atomic_ops, - 0b0000111: self.flw_fld, - 0b0100111: self.fsw_fsd, + 0b0000111: self.flw_fld_flh, + 0b0100111: self.fsw_fsd_fsh, 0b1000011: self.fmadd, 0b1000111: self.fmsub, 0b1001011: self.fnmsub, @@ -406,8 +406,9 @@ def init_rvp_dictionary(self): self.rvp_dict_11[0x00003077] = 'bpick' @plugins.decoderHookImpl - def setup(self, arch): + def setup(self, inxFlag, arch): self.arch = arch + self.inxFlag = inxFlag FIRST2_MASK = 0x00000003 OPCODE_MASK = 0x0000007f @@ -529,7 +530,7 @@ def load_ops(self, instrObj): instrObj.instr_name = 'lwu' if funct3 == 0b011: instrObj.instr_name = 'ld' - + return instrObj def store_ops(self, instrObj): @@ -765,6 +766,8 @@ def arithi_ops(self, instrObj): instrObj.rs1 = rs1 instrObj.rd = rd instrObj.imm = imm + + else: instrObj.imm = None if self.arch == 'rv32': @@ -1606,7 +1609,7 @@ def rv64_rv32_atomic_ops(self, instrObj): return instrObj - def flw_fld(self, instrObj): + def flw_fld_flh(self, instrObj): instr = instrObj.instr rd = ((instr & self.RD_MASK) >> 7, 'f') rs1 = ((instr & self.RS1_MASK) >> 15, 'x') @@ -1621,10 +1624,11 @@ def flw_fld(self, instrObj): instrObj.instr_name = 'flw' elif funct3 == 0b011: instrObj.instr_name = 'fld' - + elif funct3 == 0b001: + instrObj.instr_name = 'flh' return instrObj - def fsw_fsd(self, instrObj): + def fsw_fsd_fsh(self, instrObj): instr = instrObj.instr imm_4_0 = (instr & self.RD_MASK) >> 7 imm_11_5 = (instr >> 25) << 5 @@ -1642,17 +1646,18 @@ def fsw_fsd(self, instrObj): instrObj.instr_name = 'fsw' elif funct3 == 0b011: instrObj.instr_name = 'fsd' - + elif funct3 == 0b001: + instrObj.instr_name = 'fsh' return instrObj def fmadd(self, instrObj): instr = instrObj.instr - rd = ((instr & self.RD_MASK) >> 7, 'f') + rd = ((instr & self.RD_MASK) >> 7, 'f' if not self.inxFlag else 'x') rm = (instr >> 12) & 0x00000007 - rs1 = ((instr & self.RS1_MASK) >> 15, 'f') - rs2 = ((instr & self.RS2_MASK) >> 20, 'f') + rs1 = ((instr & self.RS1_MASK) >> 15, 'f' if not self.inxFlag else 'x') + rs2 = ((instr & self.RS2_MASK) >> 20, 'f' if not self.inxFlag else 'x') rs3 = ((instr >> 27), 'f') - size_bit = (instr >> 25) & 0x00000001 + size_bit = (instr >> 25) & 0x00000003 instrObj.rs1 = rs1 instrObj.rs2 = rs2 @@ -1661,22 +1666,22 @@ def fmadd(self, instrObj): instrObj.rm = rm instrObj.rs3 = rs3 - if size_bit == 0b0: + if size_bit == 0b00: instrObj.instr_name = 'fmadd.s' - elif size_bit == 0b1: + elif size_bit == 0b01: instrObj.instr_name = 'fmadd.d' - + elif size_bit == 0b10: + instrObj.instr_name = 'fmadd.h' return instrObj def fmsub(self, instrObj): instr = instrObj.instr - rd = ((instr & self.RD_MASK) >> 7, 'f') + rd = ((instr & self.RD_MASK) >> 7, 'f' if not self.inxFlag else 'x') rm = (instr >> 12) & 0x00000007 - rs1 = ((instr & self.RS1_MASK) >> 15, 'f') - rs2 = ((instr & self.RS2_MASK) >> 20, 'f') - rs3 = ((instr >> 27), 'f') - size_bit = (instr >> 25) & 0x00000001 - + rs1 = ((instr & self.RS1_MASK) >> 15, 'f' if not self.inxFlag else 'x') + rs2 = ((instr & self.RS2_MASK) >> 20, 'f' if not self.inxFlag else 'x') + rs3 = ((instr >> 27), 'f' if not self.inxFlag else 'x') + size_bit = (instr >> 25) & 0x00000003 instrObj.rs1 = rs1 instrObj.rs2 = rs2 instrObj.rd = rd @@ -1684,21 +1689,23 @@ def fmsub(self, instrObj): instrObj.rm = rm instrObj.rs3 = rs3 - if size_bit == 0b0: + if size_bit == 0b00: instrObj.instr_name = 'fmsub.s' - elif size_bit == 0b1: + elif size_bit == 0b01: instrObj.instr_name = 'fmsub.d' + elif size_bit == 0b10: + instrObj.instr_name = 'fmsub.h' return instrObj def fnmsub(self, instrObj): instr = instrObj.instr - rd = ((instr & self.RD_MASK) >> 7, 'f') + rd = ((instr & self.RD_MASK) >> 7, 'f' if not self.inxFlag else 'x') rm = (instr >> 12) & 0x00000007 - rs1 = ((instr & self.RS1_MASK) >> 15, 'f') - rs2 = ((instr & self.RS2_MASK) >> 20, 'f') - rs3 = ((instr >> 27), 'f') - size_bit = (instr >> 25) & 0x00000001 + rs1 = ((instr & self.RS1_MASK) >> 15, 'f' if not self.inxFlag else 'x') + rs2 = ((instr & self.RS2_MASK) >> 20, 'f' if not self.inxFlag else 'x') + rs3 = ((instr >> 27), 'f' if not self.inxFlag else 'x') + size_bit = (instr >> 25) & 0x00000003 instrObj.rs1 = rs1 instrObj.rs2 = rs2 @@ -1707,21 +1714,22 @@ def fnmsub(self, instrObj): instrObj.rm = rm instrObj.rs3 = rs3 - if size_bit == 0b0: + if size_bit == 0b00: instrObj.instr_name = 'fnmsub.s' - elif size_bit == 0b1: + elif size_bit == 0b01: instrObj.instr_name = 'fnmsub.d' - + elif size_bit == 0b10: + instrObj.instr_name = 'fnmsub.h' return instrObj def fnmadd(self, instrObj): instr = instrObj.instr - rd = ((instr & self.RD_MASK) >> 7, 'f') + rd = ((instr & self.RD_MASK) >> 7, 'f' if not self.inxFlag else 'x') rm = (instr >> 12) & 0x00000007 - rs1 = ((instr & self.RS1_MASK) >> 15, 'f') - rs2 = ((instr & self.RS2_MASK) >> 20, 'f') + rs1 = ((instr & self.RS1_MASK) >> 15, 'f' if not self.inxFlag else 'x') + rs2 = ((instr & self.RS2_MASK) >> 20, 'f' if not self.inxFlag else 'x') rs3 = ((instr >> 27), 'f') - size_bit = (instr >> 25) & 0x00000001 + size_bit = (instr >> 25) & 0x00000003 # fmt bits instrObj.rs1 = rs1 instrObj.rs2 = rs2 @@ -1729,19 +1737,20 @@ def fnmadd(self, instrObj): instrObj.rm = rm instrObj.rs3 = rs3 - if size_bit == 0b0: + if size_bit == 0b00: instrObj.instr_name = 'fnmadd.s' - elif size_bit == 0b1: + elif size_bit == 0b01: instrObj.instr_name = 'fnmadd.d' - + elif size_bit == 0b10: + instrObj.instr_name = 'fnmadd.h' return instrObj def rv32_rv64_float_ops(self, instrObj): instr = instrObj.instr - rd = ((instr & self.RD_MASK) >> 7, 'f') + rd = ((instr & self.RD_MASK) >> 7, 'x' if self.inxFlag else 'f') rm = (instr >> 12) & 0x00000007 - rs1 = ((instr & self.RS1_MASK) >> 15, 'f') - rs2 = ((instr & self.RS2_MASK) >> 20, 'f') + rs1 = ((instr & self.RS1_MASK) >> 15, 'x' if self.inxFlag else 'f') + rs2 = ((instr & self.RS2_MASK) >> 20, 'x' if self.inxFlag else 'f') funct7 = (instr >> 25) instrObj.rs1 = rs1 @@ -1766,7 +1775,17 @@ def rv32_rv64_float_ops(self, instrObj): instrObj.instr_name = 'fmul.d' elif funct7 == 0b0001101: instrObj.instr_name = 'fdiv.d' - + elif funct7 == 0b0000010: + instrObj.instr_name = 'fadd.h' + elif funct7 == 0b0000110: + instrObj.instr_name = 'fsub.h' + elif funct7 == 0b0001010: + instrObj.instr_name = 'fmul.h' + elif funct7 == 0b0001110: + instrObj.instr_name = 'fdiv.h' + + #if instrObj.instr_name is not None and instrObj.instr_name is not "None": + # return instrObj # fsqrt if funct7 == 0b0101100: instrObj.instr_name = 'fsqrt.s' @@ -1776,7 +1795,10 @@ def rv32_rv64_float_ops(self, instrObj): instrObj.instr_name = 'fsqrt.d' instrObj.rs2 = None return instrObj - + elif funct7 == 0b0101110: + instrObj.instr_name = 'fsqrt.h' + instrObj.rs2 = None + return instrObj # fsgnj, fsgnjn, fsgnjx if funct7 == 0b0010000: if rm == 0b000: @@ -1798,7 +1820,16 @@ def rv32_rv64_float_ops(self, instrObj): elif rm == 0b010: instrObj.instr_name = 'fsgnjx.d' return instrObj - + elif funct7 == 0b0010010: + if rm == 0b000: + instrObj.instr_name = 'fsgnj.h' + return instrObj + elif rm == 0b001: + instrObj.instr_name = 'fsgnjn.h' + return instrObj + elif rm == 0b010: + instrObj.instr_name = 'fsgnjx.h' + return instrObj # fmin, fmax if funct7 == 0b0010100: if rm == 0b000: @@ -1814,7 +1845,13 @@ def rv32_rv64_float_ops(self, instrObj): elif rm == 0b001: instrObj.instr_name = 'fmax.d' return instrObj - + elif funct7 == 0b0010110: + if rm == 0b000: + instrObj.instr_name = 'fmin.h' + return instrObj + elif rm == 0b001: + instrObj.instr_name = 'fmax.h' + return instrObj # fcvt.w, fcvt.wu, fcvt.l, fcvt.lu if funct7 == 0b1100000: mode = rs2[0] @@ -1885,7 +1922,17 @@ def rv32_rv64_float_ops(self, instrObj): elif rm == 0b000: instrObj.instr_name = 'fle.d' return instrObj - + if funct7 == 0b1010010: + instrObj.rd = (rd[0], 'x') + if rm == 0b010: + instrObj.instr_name = 'feq.h' + return instrObj + elif rm == 0b001: + instrObj.instr_name = 'flt.h' + return instrObj + elif rm == 0b000: + instrObj.instr_name = 'fle.h' + return instrObj # fcvt.s.w, fcvt.s.wu, fcvt.s.l, fcvt.s.lu if funct7 == 0b1101000: mode = rs2[0] @@ -1973,11 +2020,107 @@ def rv32_rv64_float_ops(self, instrObj): instrObj.rs2 = None return instrObj + + if funct7 == 0b1100010: + mode = rs2[0] + instrObj.rs2 = None + instrObj.rd = (rd[0], 'x') + if mode == 0b00000: + instrObj.instr_name = 'fcvt.w.h' + instrObj.rs2 = None + return instrObj + elif mode == 0b00001: + instrObj.instr_name = 'fcvt.wu.h' + instrObj.rs2 = None + return instrObj + elif mode == 0b00010: + instrObj.instr_name = 'fcvt.l.h' + instrObj.rs2 = None + return instrObj + elif mode == 0b00011: + instrObj.instr_name = 'fcvt.lu.h' + instrObj.rs2 = None + return instrObj + + # fcvt.h.w, fcvt.h.wu, fcvt.h.l, fcvt.h.lu + if funct7 == 0b1101010: + mode = rs2[0] + instrObj.rs2 = None + instrObj.rs1 = (rs1[0], 'x') + if mode == 0b00000: + instrObj.instr_name = 'fcvt.h.w' + instrObj.rs2 = None + return instrObj + elif mode == 0b00001: + instrObj.instr_name = 'fcvt.h.wu' + instrObj.rs2 = None + return instrObj + elif mode == 0b00010: + instrObj.instr_name = 'fcvt.h.l' + instrObj.rs2 = None + return instrObj + elif mode == 0b00011: + instrObj.instr_name = 'fcvt.h.lu' + instrObj.rs2 = None + return instrObj + + # fcvt.s.h, fcvt.h.s, fcvt.d.h, fcvt.h.d + if funct7 == 0b0100000: + if rs2[0] == 0b00010: + instrObj.instr_name = 'fcvt.s.h' + instrObj.rs2 = None + return instrObj + if funct7 == 0b0100010: + if rs2[0] == 0b00000: + instrObj.instr_name = 'fcvt.h.s' + instrObj.rs2 = None + return instrObj + if funct7 == 0b0100001: + if rs2[0] == 0b00010: + instrObj.instr_name = 'fcvt.d.h' + instrObj.rs2 = None + return instrObj + if funct7 == 0b0100010: + if rs2[0] == 0b00001: + instrObj.instr_name = 'fcvt.h.d' + instrObj.rs2 = None + return instrObj + # fcvt.h.q, fcvt.q.h (Zfh, after Q extension is introducted) + if funct7 == 0b0100011: + if rs2[0] == 0b00010: + instrObj.instr_name = 'fcvt.q.h' + instrObj.rs2 = None + return instrObj + if funct7 == 0b0100010: + if rs2[0] == 0b00011: + instrObj.instr_name = 'fcvt.h.q' + instrObj.rs2 = None + return instrObj + + if funct7 == 0b1111010: + instrObj.instr_name = 'fmv.h.x' + instrObj.rs1 = (rs1[0], 'x') + instrObj.rs2 = None + return instrObj + + + if funct7 == 0b1110010: + if rm == 0b001: + instrObj.instr_name = 'fclass.h' + instrObj.rd = (rd[0], 'x') + instrObj.rs2 = None + return instrObj + elif rm == 0b000: + instrObj.instr_name = 'fmv.x.h' + instrObj.rd = (rd[0], 'x') + instrObj.rs2 = None + return instrObj if instrObj.instr_name != 'None': return instrObj ''' Compressed Instruction Parsing Functions ''' C_FUNCT3_MASK = 0xe000 + C0_OP2_MASK = 0x0003 C0_RDPRIME_MASK = 0x001C C0_RS2PRIME_MASK = 0x001C @@ -2005,7 +2148,8 @@ def quad0(self, instrObj): '''Parse instructions from Quad0 of the Compressed extension in the RISCV-ISA-Standard''' instr = instrObj.instr funct3 = (self.C_FUNCT3_MASK & instr) >> 13 - + funct6 = (instr >> 10) + # UIMM 7:6:5:3 uimm_5_3 = (self.C0_UIMM_5_3_MASK & instr) >> 7 uimm_7_6 = (self.C0_UIMM_7_6_MASK & instr) << 1 @@ -2020,6 +2164,13 @@ def quad0(self, instrObj): rdprime = (self.C0_RDPRIME_MASK & instr) >> 2 rs1prime = (self.C0_RS1PRIME_MASK & instr) >> 7 rs2prime = (self.C0_RS2PRIME_MASK & instr) >> 2 + uimm_6 = (self.C0_UIMM_6_MASK & instr) >> 6 + op = (self.C1_MINOR_OP_MASK & instr) >> 10 + op2 = (self.C1_MINOR_OP2_MASK & instr) >> 5 + rs1 = ((instr & self.C0_RS1PRIME_MASK) >> 7, 'x') + funct_0 = self.get_bit(instr,5) + funct_1 = self.get_bit(instr,6) + if funct3 == 0b000: nzuimm_3 = self.get_bit(instr, 5) @@ -2035,7 +2186,43 @@ def quad0(self, instrObj): instrObj.rd = (8 + rdprime, 'x') instrObj.imm = nzuimm return instrObj - + elif funct6 == 0b100000: + instrObj.instr_name = 'c.lbu' + instrObj.rd = (8 + rdprime, 'x') + instrObj.rs1 = (8 + rs1prime, 'x') + instrObj.imm = uimm_7_6 + + elif funct6 == 0b100001: + funct1 = self.get_bit(instr,6) + imm_6 = self.get_bit(instr,5) + imm_7_6 = (funct1 + imm_6) + if funct1 == 0: + instrObj.instr_name = 'c.lhu' + instrObj.rd = (8 + rdprime, 'x') + instrObj.rs1 = (8 + rs1prime, 'x') + instrObj.imm = uimm_6 + else: + instrObj.instr_name = 'c.lh' + instrObj.rd = (8 + rdprime, 'x') + instrObj.rs1 = (8 + rs1prime, 'x') + instrObj.imm = uimm_6 + + elif funct6 == 0b100010: + instrObj.instr_name = 'c.sb' + instrObj.rs2 = (8 + rs2prime, 'x') + instrObj.rs1 = (8 + rs1prime, 'x') + instrObj.imm = uimm_7_6 + + elif funct6 == 0b100011: + funct1 = self.get_bit(instr,6) + imm_6 = self.get_bit(instr,5) + imm_7_6 = (funct1 + imm_6) + if funct1 == 0: + instrObj.instr_name = 'c.sh' + instrObj.rs2 = (8 + rs2prime, 'x') + instrObj.rs1 = (8 + rs1prime, 'x') + instrObj.imm = uimm_7_6 + elif funct3 == 0b001: instrObj.instr_name = 'c.fld' instrObj.rd = (8 + rdprime, 'f') @@ -2048,7 +2235,7 @@ def quad0(self, instrObj): instrObj.rs1 = (8 + rs1prime, 'x') instrObj.imm = uimm_6_5_3_2 - elif funct3 == 0b011: + elif funct3 == 0b011: if self.arch == 'rv32': instrObj.instr_name = 'c.flw' instrObj.rd = (8 + rdprime, 'f') @@ -2084,12 +2271,15 @@ def quad0(self, instrObj): instrObj.rs2 = (8 + rs2prime, 'x') instrObj.imm = uimm_7_6_5_3 + return instrObj def quad1(self, instrObj): '''Parse instructions from Quad1 of the Compressed extension in the RISCV-ISA-Standard''' instr = instrObj.instr - funct3 = (self.C_FUNCT3_MASK & instr) >> 13 + funct3 = (self.C_FUNCT3_MASK & instr) >> 12 + + # Registers rdprime = (self.C1_RDPRIME_MASK & instr) >> 7 @@ -2097,6 +2287,8 @@ def quad1(self, instrObj): rs2prime = (self.C1_RS2PRIME_MASK & instr) >> 2 rd = (self.C1_RD_MASK & instr) >> 7 rs1 = (self.C1_RD_MASK & instr) >> 7 + + imm_5 = (self.C1_IMM_5_MASK & instr) >> 7 imm_4_0 = (self.C1_IMM_4_0_MASK & instr) >> 2 @@ -2209,6 +2401,11 @@ def quad1(self, instrObj): instrObj.rs1 = (8 + rs1prime, 'x') instrObj.rd = (8 + rdprime, 'x') instrObj.rs2 = (8 + rs2prime, 'x') + elif op == 3 and op2 == 2 and imm_5 !=0 and self.arch == 'rv32': + instrObj.instr_name = 'c.mul' + instrObj.rs1 = (8 + rs1prime, 'x') + instrObj.rd = (8 + rdprime, 'x') + instrObj.rs2 = (8 + rs2prime, 'x') elif funct3 == 5: instrObj.instr_name = 'c.j' instrObj.rd = (0, 'x') @@ -2223,19 +2420,19 @@ def quad1(self, instrObj): instrObj.rs1 = (8 + rs1prime, 'x') instrObj.rs2 = (0, 'x') instrObj.imm = self.twos_comp(imm_b, 9) - - - + return instrObj C2_RS2_MASK = 0x007C C2_RD_MASK = 0x0F80 + def quad2(self, instrObj): '''Parse instructions from Quad2 of the Compressed extension in the RISCV-ISA-Standard''' instr = instrObj.instr - funct3 = (self.C_FUNCT3_MASK & instr) >> 13 + funct3 = (self.C_FUNCT3_MASK & instr) >> 12 + imm_5 = self.get_bit(instr, 12) << 5 imm_4_0 = (instr & 0x007c) >> 2 @@ -2263,6 +2460,8 @@ def quad2(self, instrObj): imm_fsdsp = imm_5_3 + imm_s_8_6 imm_swsp = imm_5_2 + imm_s_7_6 + + if funct3 == 0 and imm_slli !=0 and rd !=0: instrObj.instr_name = 'c.slli' instrObj.rd = (rd, 'x') @@ -2327,6 +2526,7 @@ def quad2(self, instrObj): instrObj.rs2 = (rs2, 'x') instrObj.imm = imm_fsdsp instrObj.rs1 = (2 , 'x') + return instrObj @@ -2370,6 +2570,7 @@ def decode(self, instrObj_temp): first_two_bits = self.FIRST2_MASK & instr if first_two_bits == 0b11: instrObj = self.parseStandardInstruction(instrObj_temp) + instrObj.inxFlg = self.inxFlag return instrObj else: From f3702bb9d857539c3916ffec80fd542d8d744f6e Mon Sep 17 00:00:00 2001 From: Anusha Date: Mon, 3 Jul 2023 11:55:08 +0530 Subject: [PATCH 06/11] Amending the changes with respect to Zfh and Zfinx --- riscv_isac/InstructionObject.py | 4 ++-- riscv_isac/fp_dataset.py | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/riscv_isac/InstructionObject.py b/riscv_isac/InstructionObject.py index 3907e403..a5babad6 100644 --- a/riscv_isac/InstructionObject.py +++ b/riscv_isac/InstructionObject.py @@ -149,8 +149,8 @@ def evaluate_instr_vars(self, xlen, flen, arch_state, csr_regfile, instr_vars): instr_vars['iflen'] = 32 elif self.instr_name.endswith(".d"): instr_vars['iflen'] = 64 - #elif self.instr_name.endswith(".h"): - # instr_vars['iflen'] = 16 + elif self.instr_name.endswith(".h"): + instr_vars['iflen'] = 16 # capture the operands if self.rs1 is not None: diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index 616abb49..6a4a63fe 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -123,11 +123,10 @@ def num_explain(flen,num): man = bin_val[e_sz+1:] if(int(exp,2)!=0): - #return('fnorm' if flen==32 else 'dnorm') return('hnorm' if flen == 16 else 'fnorm' if flen==32 else 'dnorm') else: return('hsubnorm' if flen == 16 else 'fsubnorm' if flen==32 else 'dsubnorm') - #return('fsubnorm' if flen==32 else 'dsubnorm') + def extract_fields(flen, hexstr, postfix): if flen == 16: From 12285bf5dd6987d7f325bb887d996be646971e9c Mon Sep 17 00:00:00 2001 From: Anusha Date: Mon, 3 Jul 2023 13:04:02 +0530 Subject: [PATCH 07/11] Updated instruction object and constants with respect to Zfh and Zfinx --- riscv_isac/InstructionObject.py | 6 +++--- riscv_isac/data/constants.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/riscv_isac/InstructionObject.py b/riscv_isac/InstructionObject.py index a5babad6..574bdc3a 100644 --- a/riscv_isac/InstructionObject.py +++ b/riscv_isac/InstructionObject.py @@ -2,7 +2,7 @@ instrs_sig_mutable = ['auipc','jal','jalr'] instrs_sig_update = ['sh','sb','sw','sd','c.fsw','c.sw','c.sd','c.swsp','c.sdsp','fsw','fsd',\ - 'c.fsw','c.fsd','c.fswsp','c.fsdsp''c.lbu','c.sb','c.sh'] + 'c.fsw','c.fsd','c.fswsp','c.fsdsp'] instrs_no_reg_tracking = ['beq','bne','blt','bge','bltu','bgeu','fence','c.j','c.jal','c.jalr',\ 'c.jr','c.beqz','c.bnez', 'c.ebreak'] + instrs_sig_update instrs_fcsr_affected = ['fmadd.s','fmsub.s','fnmsub.s','fnmadd.s','fadd.s','fsub.s','fmul.s','fdiv.s',\ @@ -25,14 +25,14 @@ 'aes32esmi', 'aes32esi', 'aes32dsmi', 'aes32dsi','bclr','bext','binv',\ 'bset','zext.h','sext.h','sext.b','zext.b','zext.w','minu','maxu','orc.b','add.uw','sh1add.uw',\ 'sh2add.uw','sh3add.uw','slli.uw','clz','clzw','ctz','ctzw','cpop','cpopw','rev8',\ - 'bclri','bexti','binvi','bseti','fcvt.d.wu','fcvt.s.wu','fcvt.d.lu','fcvt.s.lu','c.zext.b','c.zext.h','c.sext.h','c.sext.b','c.not'] + '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',\ 'clmulh','clmulr','andn','orn','xnor','pack','packh','packu','packuw','packw',\ 'xperm.n','xperm.b', 'aes32esmi', 'aes32esi', 'aes32dsmi', 'aes32dsi',\ 'sha512sum1r','sha512sum0r','sha512sig1l','sha512sig1h','sha512sig0l','sha512sig0h','fsw',\ - 'bclr','bext','binv','bset','minu','maxu','add.uw','sh1add.uw','sh2add.uw','sh3add.uw','c.mul'] + 'bclr','bext','binv','bset','minu','maxu','add.uw','sh1add.uw','sh2add.uw','sh3add.uw'] f_instrs_pref = ['fadd', 'fclass', 'fcvt', 'fdiv', 'feq', 'fld', 'fle', 'flt', 'flw', 'fmadd',\ 'fmax', 'fmin', 'fmsub', 'fmul', 'fmv', 'fnmadd', 'fnmsub', 'fsd', 'fsgnj', 'fsqrt',\ 'fsub', 'fsw'] diff --git a/riscv_isac/data/constants.py b/riscv_isac/data/constants.py index 8bb5725e..87093b20 100644 --- a/riscv_isac/data/constants.py +++ b/riscv_isac/data/constants.py @@ -2,7 +2,7 @@ isa_regex = \ -re.compile("^RV(32|64|128)[IE]+[ABCDEFGHJKLMNPQSTUVX]*(Zfinx|Zfh|Zicsr|Zifencei|Zihintpause|Zam|Ztso|Zkne|Zknd|Zknh|Zkse|Zksh|Zkg|Zkb|Zkr|Zks|Zkn|Zba|Zbc|Zbb|Zbp|Zbr|Zbm|Zbs|Zbe|Zbf|Zbt|Zmmul|Zbpbo|Zca|Zcb|Zcf|Zcd|Zcmp|Zce){,1}(_Zicsr){,1}(_Zifencei){,1}(_Zihintpause){,1}(_Zfinx){,1}(_Zfh){,1}(_Zmmul){,1}(_Zam){,1}(_Zba){,1}(_Zbb){,1}(_Zbc){,1}(_Zbe){,1}(_Zbf){,1}(_Zbm){,1}(_Zbp){,1}(_Zbpbo){,1}(_Zbr){,1}(_Zbs){,1}(_Zbt){,1}(_Zkb){,1}(_Zkg){,1}(_Zkr){,1}(_Zks){,1}(_Zkn){,1}(_Zknd){,1}(_Zkne){,1}(_Zknh){,1}(_Zkse){,1}(_Zksh){,1}(_Ztso){,1}(_Zca){,1}(_Zcb){,1}(_Zcf){,1}(_Zcd){,1}(_Zcmp){,1}(_Zce){,1}$") +re.compile("^RV(32|64|128)[IE]+[ABCDEFGHJKLMNPQSTUVX]*(Zfinx|Zfh|Zicsr|Zifencei|Zihintpause|Zam|Ztso|Zkne|Zknd|Zknh|Zkse|Zksh|Zkg|Zkb|Zkr|Zks|Zkn|Zba|Zbc|Zbb|Zbp|Zbr|Zbm|Zbs|Zbe|Zbf|Zbt|Zmmul|Zbpbo){,1}(_Zicsr){,1}(_Zifencei){,1}(_Zihintpause){,1}(_Zfinx){,1}(_Zfh){,1}(_Zmmul){,1}(_Zam){,1}(_Zba){,1}(_Zbb){,1}(_Zbc){,1}(_Zbe){,1}(_Zbf){,1}(_Zbm){,1}(_Zbp){,1}(_Zbpbo){,1}(_Zbr){,1}(_Zbs){,1}(_Zbt){,1}(_Zkb){,1}(_Zkg){,1}(_Zkr){,1}(_Zks){,1}(_Zkn){,1}(_Zknd){,1}(_Zkne){,1}(_Zknh){,1}(_Zkse){,1}(_Zksh){,1}(_Ztso){,1}$") # regex to find ..= patterns in instruction fixed_ranges = re.compile( From bc28cfa51284019abb8233bab30fc43bcbf3420b Mon Sep 17 00:00:00 2001 From: Anusha Date: Tue, 5 Sep 2023 09:44:47 +0530 Subject: [PATCH 08/11] updated internaldecoder --- riscv_isac/plugins/internaldecoder.py | 306 +++++--------------------- 1 file changed, 51 insertions(+), 255 deletions(-) diff --git a/riscv_isac/plugins/internaldecoder.py b/riscv_isac/plugins/internaldecoder.py index 5d65d385..bff9ed8a 100644 --- a/riscv_isac/plugins/internaldecoder.py +++ b/riscv_isac/plugins/internaldecoder.py @@ -18,8 +18,8 @@ def __init__(self): 0b0011011: self.rv64i_arithi_ops, 0b0111011: self.rv64i_arith_ops, 0b0101111: self.rv64_rv32_atomic_ops, - 0b0000111: self.flw_fld_flh, - 0b0100111: self.fsw_fsd_fsh, + 0b0000111: self.flw_fld, + 0b0100111: self.fsw_fsd, 0b1000011: self.fmadd, 0b1000111: self.fmsub, 0b1001011: self.fnmsub, @@ -406,9 +406,8 @@ def init_rvp_dictionary(self): self.rvp_dict_11[0x00003077] = 'bpick' @plugins.decoderHookImpl - def setup(self, inxFlag, arch): + def setup(self, arch): self.arch = arch - self.inxFlag = inxFlag FIRST2_MASK = 0x00000003 OPCODE_MASK = 0x0000007f @@ -530,7 +529,7 @@ def load_ops(self, instrObj): instrObj.instr_name = 'lwu' if funct3 == 0b011: instrObj.instr_name = 'ld' - + return instrObj def store_ops(self, instrObj): @@ -766,8 +765,6 @@ def arithi_ops(self, instrObj): instrObj.rs1 = rs1 instrObj.rd = rd instrObj.imm = imm - - else: instrObj.imm = None if self.arch == 'rv32': @@ -1609,7 +1606,7 @@ def rv64_rv32_atomic_ops(self, instrObj): return instrObj - def flw_fld_flh(self, instrObj): + def flw_fld(self, instrObj): instr = instrObj.instr rd = ((instr & self.RD_MASK) >> 7, 'f') rs1 = ((instr & self.RS1_MASK) >> 15, 'x') @@ -1624,11 +1621,10 @@ def flw_fld_flh(self, instrObj): instrObj.instr_name = 'flw' elif funct3 == 0b011: instrObj.instr_name = 'fld' - elif funct3 == 0b001: - instrObj.instr_name = 'flh' + return instrObj - def fsw_fsd_fsh(self, instrObj): + def fsw_fsd(self, instrObj): instr = instrObj.instr imm_4_0 = (instr & self.RD_MASK) >> 7 imm_11_5 = (instr >> 25) << 5 @@ -1646,18 +1642,17 @@ def fsw_fsd_fsh(self, instrObj): instrObj.instr_name = 'fsw' elif funct3 == 0b011: instrObj.instr_name = 'fsd' - elif funct3 == 0b001: - instrObj.instr_name = 'fsh' + return instrObj def fmadd(self, instrObj): instr = instrObj.instr - rd = ((instr & self.RD_MASK) >> 7, 'f' if not self.inxFlag else 'x') + rd = ((instr & self.RD_MASK) >> 7, 'f') rm = (instr >> 12) & 0x00000007 - rs1 = ((instr & self.RS1_MASK) >> 15, 'f' if not self.inxFlag else 'x') - rs2 = ((instr & self.RS2_MASK) >> 20, 'f' if not self.inxFlag else 'x') + rs1 = ((instr & self.RS1_MASK) >> 15, 'f') + rs2 = ((instr & self.RS2_MASK) >> 20, 'f') rs3 = ((instr >> 27), 'f') - size_bit = (instr >> 25) & 0x00000003 + size_bit = (instr >> 25) & 0x00000001 instrObj.rs1 = rs1 instrObj.rs2 = rs2 @@ -1666,22 +1661,22 @@ def fmadd(self, instrObj): instrObj.rm = rm instrObj.rs3 = rs3 - if size_bit == 0b00: + if size_bit == 0b0: instrObj.instr_name = 'fmadd.s' - elif size_bit == 0b01: + elif size_bit == 0b1: instrObj.instr_name = 'fmadd.d' - elif size_bit == 0b10: - instrObj.instr_name = 'fmadd.h' + return instrObj def fmsub(self, instrObj): instr = instrObj.instr - rd = ((instr & self.RD_MASK) >> 7, 'f' if not self.inxFlag else 'x') + rd = ((instr & self.RD_MASK) >> 7, 'f') rm = (instr >> 12) & 0x00000007 - rs1 = ((instr & self.RS1_MASK) >> 15, 'f' if not self.inxFlag else 'x') - rs2 = ((instr & self.RS2_MASK) >> 20, 'f' if not self.inxFlag else 'x') - rs3 = ((instr >> 27), 'f' if not self.inxFlag else 'x') - size_bit = (instr >> 25) & 0x00000003 + rs1 = ((instr & self.RS1_MASK) >> 15, 'f') + rs2 = ((instr & self.RS2_MASK) >> 20, 'f') + rs3 = ((instr >> 27), 'f') + size_bit = (instr >> 25) & 0x00000001 + instrObj.rs1 = rs1 instrObj.rs2 = rs2 instrObj.rd = rd @@ -1689,23 +1684,21 @@ def fmsub(self, instrObj): instrObj.rm = rm instrObj.rs3 = rs3 - if size_bit == 0b00: + if size_bit == 0b0: instrObj.instr_name = 'fmsub.s' - elif size_bit == 0b01: + elif size_bit == 0b1: instrObj.instr_name = 'fmsub.d' - elif size_bit == 0b10: - instrObj.instr_name = 'fmsub.h' return instrObj def fnmsub(self, instrObj): instr = instrObj.instr - rd = ((instr & self.RD_MASK) >> 7, 'f' if not self.inxFlag else 'x') + rd = ((instr & self.RD_MASK) >> 7, 'f') rm = (instr >> 12) & 0x00000007 - rs1 = ((instr & self.RS1_MASK) >> 15, 'f' if not self.inxFlag else 'x') - rs2 = ((instr & self.RS2_MASK) >> 20, 'f' if not self.inxFlag else 'x') - rs3 = ((instr >> 27), 'f' if not self.inxFlag else 'x') - size_bit = (instr >> 25) & 0x00000003 + rs1 = ((instr & self.RS1_MASK) >> 15, 'f') + rs2 = ((instr & self.RS2_MASK) >> 20, 'f') + rs3 = ((instr >> 27), 'f') + size_bit = (instr >> 25) & 0x00000001 instrObj.rs1 = rs1 instrObj.rs2 = rs2 @@ -1714,22 +1707,21 @@ def fnmsub(self, instrObj): instrObj.rm = rm instrObj.rs3 = rs3 - if size_bit == 0b00: + if size_bit == 0b0: instrObj.instr_name = 'fnmsub.s' - elif size_bit == 0b01: + elif size_bit == 0b1: instrObj.instr_name = 'fnmsub.d' - elif size_bit == 0b10: - instrObj.instr_name = 'fnmsub.h' + return instrObj def fnmadd(self, instrObj): instr = instrObj.instr - rd = ((instr & self.RD_MASK) >> 7, 'f' if not self.inxFlag else 'x') + rd = ((instr & self.RD_MASK) >> 7, 'f') rm = (instr >> 12) & 0x00000007 - rs1 = ((instr & self.RS1_MASK) >> 15, 'f' if not self.inxFlag else 'x') - rs2 = ((instr & self.RS2_MASK) >> 20, 'f' if not self.inxFlag else 'x') + rs1 = ((instr & self.RS1_MASK) >> 15, 'f') + rs2 = ((instr & self.RS2_MASK) >> 20, 'f') rs3 = ((instr >> 27), 'f') - size_bit = (instr >> 25) & 0x00000003 # fmt bits + size_bit = (instr >> 25) & 0x00000001 instrObj.rs1 = rs1 instrObj.rs2 = rs2 @@ -1737,20 +1729,19 @@ def fnmadd(self, instrObj): instrObj.rm = rm instrObj.rs3 = rs3 - if size_bit == 0b00: + if size_bit == 0b0: instrObj.instr_name = 'fnmadd.s' - elif size_bit == 0b01: + elif size_bit == 0b1: instrObj.instr_name = 'fnmadd.d' - elif size_bit == 0b10: - instrObj.instr_name = 'fnmadd.h' + return instrObj def rv32_rv64_float_ops(self, instrObj): instr = instrObj.instr - rd = ((instr & self.RD_MASK) >> 7, 'x' if self.inxFlag else 'f') + rd = ((instr & self.RD_MASK) >> 7, 'f') rm = (instr >> 12) & 0x00000007 - rs1 = ((instr & self.RS1_MASK) >> 15, 'x' if self.inxFlag else 'f') - rs2 = ((instr & self.RS2_MASK) >> 20, 'x' if self.inxFlag else 'f') + rs1 = ((instr & self.RS1_MASK) >> 15, 'f') + rs2 = ((instr & self.RS2_MASK) >> 20, 'f') funct7 = (instr >> 25) instrObj.rs1 = rs1 @@ -1775,17 +1766,7 @@ def rv32_rv64_float_ops(self, instrObj): instrObj.instr_name = 'fmul.d' elif funct7 == 0b0001101: instrObj.instr_name = 'fdiv.d' - elif funct7 == 0b0000010: - instrObj.instr_name = 'fadd.h' - elif funct7 == 0b0000110: - instrObj.instr_name = 'fsub.h' - elif funct7 == 0b0001010: - instrObj.instr_name = 'fmul.h' - elif funct7 == 0b0001110: - instrObj.instr_name = 'fdiv.h' - - #if instrObj.instr_name is not None and instrObj.instr_name is not "None": - # return instrObj + # fsqrt if funct7 == 0b0101100: instrObj.instr_name = 'fsqrt.s' @@ -1795,10 +1776,7 @@ def rv32_rv64_float_ops(self, instrObj): instrObj.instr_name = 'fsqrt.d' instrObj.rs2 = None return instrObj - elif funct7 == 0b0101110: - instrObj.instr_name = 'fsqrt.h' - instrObj.rs2 = None - return instrObj + # fsgnj, fsgnjn, fsgnjx if funct7 == 0b0010000: if rm == 0b000: @@ -1820,16 +1798,7 @@ def rv32_rv64_float_ops(self, instrObj): elif rm == 0b010: instrObj.instr_name = 'fsgnjx.d' return instrObj - elif funct7 == 0b0010010: - if rm == 0b000: - instrObj.instr_name = 'fsgnj.h' - return instrObj - elif rm == 0b001: - instrObj.instr_name = 'fsgnjn.h' - return instrObj - elif rm == 0b010: - instrObj.instr_name = 'fsgnjx.h' - return instrObj + # fmin, fmax if funct7 == 0b0010100: if rm == 0b000: @@ -1845,13 +1814,7 @@ def rv32_rv64_float_ops(self, instrObj): elif rm == 0b001: instrObj.instr_name = 'fmax.d' return instrObj - elif funct7 == 0b0010110: - if rm == 0b000: - instrObj.instr_name = 'fmin.h' - return instrObj - elif rm == 0b001: - instrObj.instr_name = 'fmax.h' - return instrObj + # fcvt.w, fcvt.wu, fcvt.l, fcvt.lu if funct7 == 0b1100000: mode = rs2[0] @@ -1922,17 +1885,7 @@ def rv32_rv64_float_ops(self, instrObj): elif rm == 0b000: instrObj.instr_name = 'fle.d' return instrObj - if funct7 == 0b1010010: - instrObj.rd = (rd[0], 'x') - if rm == 0b010: - instrObj.instr_name = 'feq.h' - return instrObj - elif rm == 0b001: - instrObj.instr_name = 'flt.h' - return instrObj - elif rm == 0b000: - instrObj.instr_name = 'fle.h' - return instrObj + # fcvt.s.w, fcvt.s.wu, fcvt.s.l, fcvt.s.lu if funct7 == 0b1101000: mode = rs2[0] @@ -2020,107 +1973,11 @@ def rv32_rv64_float_ops(self, instrObj): instrObj.rs2 = None return instrObj - - if funct7 == 0b1100010: - mode = rs2[0] - instrObj.rs2 = None - instrObj.rd = (rd[0], 'x') - if mode == 0b00000: - instrObj.instr_name = 'fcvt.w.h' - instrObj.rs2 = None - return instrObj - elif mode == 0b00001: - instrObj.instr_name = 'fcvt.wu.h' - instrObj.rs2 = None - return instrObj - elif mode == 0b00010: - instrObj.instr_name = 'fcvt.l.h' - instrObj.rs2 = None - return instrObj - elif mode == 0b00011: - instrObj.instr_name = 'fcvt.lu.h' - instrObj.rs2 = None - return instrObj - - # fcvt.h.w, fcvt.h.wu, fcvt.h.l, fcvt.h.lu - if funct7 == 0b1101010: - mode = rs2[0] - instrObj.rs2 = None - instrObj.rs1 = (rs1[0], 'x') - if mode == 0b00000: - instrObj.instr_name = 'fcvt.h.w' - instrObj.rs2 = None - return instrObj - elif mode == 0b00001: - instrObj.instr_name = 'fcvt.h.wu' - instrObj.rs2 = None - return instrObj - elif mode == 0b00010: - instrObj.instr_name = 'fcvt.h.l' - instrObj.rs2 = None - return instrObj - elif mode == 0b00011: - instrObj.instr_name = 'fcvt.h.lu' - instrObj.rs2 = None - return instrObj - - # fcvt.s.h, fcvt.h.s, fcvt.d.h, fcvt.h.d - if funct7 == 0b0100000: - if rs2[0] == 0b00010: - instrObj.instr_name = 'fcvt.s.h' - instrObj.rs2 = None - return instrObj - if funct7 == 0b0100010: - if rs2[0] == 0b00000: - instrObj.instr_name = 'fcvt.h.s' - instrObj.rs2 = None - return instrObj - if funct7 == 0b0100001: - if rs2[0] == 0b00010: - instrObj.instr_name = 'fcvt.d.h' - instrObj.rs2 = None - return instrObj - if funct7 == 0b0100010: - if rs2[0] == 0b00001: - instrObj.instr_name = 'fcvt.h.d' - instrObj.rs2 = None - return instrObj - # fcvt.h.q, fcvt.q.h (Zfh, after Q extension is introducted) - if funct7 == 0b0100011: - if rs2[0] == 0b00010: - instrObj.instr_name = 'fcvt.q.h' - instrObj.rs2 = None - return instrObj - if funct7 == 0b0100010: - if rs2[0] == 0b00011: - instrObj.instr_name = 'fcvt.h.q' - instrObj.rs2 = None - return instrObj - - if funct7 == 0b1111010: - instrObj.instr_name = 'fmv.h.x' - instrObj.rs1 = (rs1[0], 'x') - instrObj.rs2 = None - return instrObj - - - if funct7 == 0b1110010: - if rm == 0b001: - instrObj.instr_name = 'fclass.h' - instrObj.rd = (rd[0], 'x') - instrObj.rs2 = None - return instrObj - elif rm == 0b000: - instrObj.instr_name = 'fmv.x.h' - instrObj.rd = (rd[0], 'x') - instrObj.rs2 = None - return instrObj if instrObj.instr_name != 'None': return instrObj ''' Compressed Instruction Parsing Functions ''' C_FUNCT3_MASK = 0xe000 - C0_OP2_MASK = 0x0003 C0_RDPRIME_MASK = 0x001C C0_RS2PRIME_MASK = 0x001C @@ -2148,8 +2005,7 @@ def quad0(self, instrObj): '''Parse instructions from Quad0 of the Compressed extension in the RISCV-ISA-Standard''' instr = instrObj.instr funct3 = (self.C_FUNCT3_MASK & instr) >> 13 - funct6 = (instr >> 10) - + # UIMM 7:6:5:3 uimm_5_3 = (self.C0_UIMM_5_3_MASK & instr) >> 7 uimm_7_6 = (self.C0_UIMM_7_6_MASK & instr) << 1 @@ -2164,13 +2020,6 @@ def quad0(self, instrObj): rdprime = (self.C0_RDPRIME_MASK & instr) >> 2 rs1prime = (self.C0_RS1PRIME_MASK & instr) >> 7 rs2prime = (self.C0_RS2PRIME_MASK & instr) >> 2 - uimm_6 = (self.C0_UIMM_6_MASK & instr) >> 6 - op = (self.C1_MINOR_OP_MASK & instr) >> 10 - op2 = (self.C1_MINOR_OP2_MASK & instr) >> 5 - rs1 = ((instr & self.C0_RS1PRIME_MASK) >> 7, 'x') - funct_0 = self.get_bit(instr,5) - funct_1 = self.get_bit(instr,6) - if funct3 == 0b000: nzuimm_3 = self.get_bit(instr, 5) @@ -2186,43 +2035,7 @@ def quad0(self, instrObj): instrObj.rd = (8 + rdprime, 'x') instrObj.imm = nzuimm return instrObj - elif funct6 == 0b100000: - instrObj.instr_name = 'c.lbu' - instrObj.rd = (8 + rdprime, 'x') - instrObj.rs1 = (8 + rs1prime, 'x') - instrObj.imm = uimm_7_6 - - elif funct6 == 0b100001: - funct1 = self.get_bit(instr,6) - imm_6 = self.get_bit(instr,5) - imm_7_6 = (funct1 + imm_6) - if funct1 == 0: - instrObj.instr_name = 'c.lhu' - instrObj.rd = (8 + rdprime, 'x') - instrObj.rs1 = (8 + rs1prime, 'x') - instrObj.imm = uimm_6 - else: - instrObj.instr_name = 'c.lh' - instrObj.rd = (8 + rdprime, 'x') - instrObj.rs1 = (8 + rs1prime, 'x') - instrObj.imm = uimm_6 - - elif funct6 == 0b100010: - instrObj.instr_name = 'c.sb' - instrObj.rs2 = (8 + rs2prime, 'x') - instrObj.rs1 = (8 + rs1prime, 'x') - instrObj.imm = uimm_7_6 - - elif funct6 == 0b100011: - funct1 = self.get_bit(instr,6) - imm_6 = self.get_bit(instr,5) - imm_7_6 = (funct1 + imm_6) - if funct1 == 0: - instrObj.instr_name = 'c.sh' - instrObj.rs2 = (8 + rs2prime, 'x') - instrObj.rs1 = (8 + rs1prime, 'x') - instrObj.imm = uimm_7_6 - + elif funct3 == 0b001: instrObj.instr_name = 'c.fld' instrObj.rd = (8 + rdprime, 'f') @@ -2235,7 +2048,7 @@ def quad0(self, instrObj): instrObj.rs1 = (8 + rs1prime, 'x') instrObj.imm = uimm_6_5_3_2 - elif funct3 == 0b011: + elif funct3 == 0b011: if self.arch == 'rv32': instrObj.instr_name = 'c.flw' instrObj.rd = (8 + rdprime, 'f') @@ -2271,15 +2084,12 @@ def quad0(self, instrObj): instrObj.rs2 = (8 + rs2prime, 'x') instrObj.imm = uimm_7_6_5_3 - return instrObj def quad1(self, instrObj): '''Parse instructions from Quad1 of the Compressed extension in the RISCV-ISA-Standard''' instr = instrObj.instr - funct3 = (self.C_FUNCT3_MASK & instr) >> 12 - - + funct3 = (self.C_FUNCT3_MASK & instr) >> 13 # Registers rdprime = (self.C1_RDPRIME_MASK & instr) >> 7 @@ -2287,8 +2097,6 @@ def quad1(self, instrObj): rs2prime = (self.C1_RS2PRIME_MASK & instr) >> 2 rd = (self.C1_RD_MASK & instr) >> 7 rs1 = (self.C1_RD_MASK & instr) >> 7 - - imm_5 = (self.C1_IMM_5_MASK & instr) >> 7 imm_4_0 = (self.C1_IMM_4_0_MASK & instr) >> 2 @@ -2401,11 +2209,6 @@ def quad1(self, instrObj): instrObj.rs1 = (8 + rs1prime, 'x') instrObj.rd = (8 + rdprime, 'x') instrObj.rs2 = (8 + rs2prime, 'x') - elif op == 3 and op2 == 2 and imm_5 !=0 and self.arch == 'rv32': - instrObj.instr_name = 'c.mul' - instrObj.rs1 = (8 + rs1prime, 'x') - instrObj.rd = (8 + rdprime, 'x') - instrObj.rs2 = (8 + rs2prime, 'x') elif funct3 == 5: instrObj.instr_name = 'c.j' instrObj.rd = (0, 'x') @@ -2420,19 +2223,16 @@ def quad1(self, instrObj): instrObj.rs1 = (8 + rs1prime, 'x') instrObj.rs2 = (0, 'x') instrObj.imm = self.twos_comp(imm_b, 9) - return instrObj C2_RS2_MASK = 0x007C C2_RD_MASK = 0x0F80 - def quad2(self, instrObj): '''Parse instructions from Quad2 of the Compressed extension in the RISCV-ISA-Standard''' instr = instrObj.instr - funct3 = (self.C_FUNCT3_MASK & instr) >> 12 - + funct3 = (self.C_FUNCT3_MASK & instr) >> 13 imm_5 = self.get_bit(instr, 12) << 5 imm_4_0 = (instr & 0x007c) >> 2 @@ -2460,8 +2260,6 @@ def quad2(self, instrObj): imm_fsdsp = imm_5_3 + imm_s_8_6 imm_swsp = imm_5_2 + imm_s_7_6 - - if funct3 == 0 and imm_slli !=0 and rd !=0: instrObj.instr_name = 'c.slli' instrObj.rd = (rd, 'x') @@ -2526,7 +2324,6 @@ def quad2(self, instrObj): instrObj.rs2 = (rs2, 'x') instrObj.imm = imm_fsdsp instrObj.rs1 = (2 , 'x') - return instrObj @@ -2570,7 +2367,6 @@ def decode(self, instrObj_temp): first_two_bits = self.FIRST2_MASK & instr if first_two_bits == 0b11: instrObj = self.parseStandardInstruction(instrObj_temp) - instrObj.inxFlg = self.inxFlag return instrObj else: From 0946f8e0a4f2faf062cdbf1606b44361417e1858 Mon Sep 17 00:00:00 2001 From: Anusha Date: Tue, 5 Sep 2023 09:58:54 +0530 Subject: [PATCH 09/11] Amending the changes with respect to zfh and zfinx instructions in rvopcodesdecoder --- riscv_isac/data/rvopcodesdecoder.py | 240 ++++++++++++++++++++++++++-- 1 file changed, 229 insertions(+), 11 deletions(-) diff --git a/riscv_isac/data/rvopcodesdecoder.py b/riscv_isac/data/rvopcodesdecoder.py index 1645a75b..2f5782d7 100644 --- a/riscv_isac/data/rvopcodesdecoder.py +++ b/riscv_isac/data/rvopcodesdecoder.py @@ -5,6 +5,7 @@ import os from constants import * +#from riscv_isac.data.constants import * import riscv_isac.plugins as plugins from riscv_isac.log import logger @@ -37,8 +38,9 @@ class disassembler(): INST_LIST = [] @plugins.decoderHookImpl - def setup(self, arch: str): + def setup(self, inxFlag,arch: str): self.arch = arch + self.inxFlag = inxFlag # Create nested dictionary nested_dict = lambda: defaultdict(nested_dict) @@ -329,9 +331,7 @@ def decode(self, instrObj_temp): instr = None temp_instrobj = instrObj_temp - mcode = temp_instrobj.instr - name_args = disassembler.get_instr(disassembler.INST_DICT, mcode) if not name_args: name_args = instr @@ -339,9 +339,10 @@ def decode(self, instrObj_temp): # Fill out the partially filled instructionObject if name_args: instr_name = name_args[0] - # Fill instruction name temp_instrobj.instr_name = instr_name + temp_instrobj.inxFlg = self.inxFlag + # Fill arguments args = name_args[1] imm = '' @@ -354,26 +355,54 @@ def decode(self, instrObj_temp): reg_type = 'x' if file_name in ['rv_f', 'rv64_f', 'rv_d','rv64_d']: reg_type = 'f' + if file_name in ['rv_f','rv64_f'] and temp_instrobj.inxFlg == True: + reg_type = 'x' + if file_name in ['rv_zfh','rv_d_zfh','rv64_zfh']: + reg_type = 'f' + if file_name in ['rv_zfh','rv_d_zfh','rv64_zfh'] and temp_instrobj.inxFlg == True: + reg_type = 'x' for arg in args[:-1]: - if arg == 'rd': + if 'rd' in arg: treg = reg_type if any([instr_name.startswith(x) for x in [ - 'fcvt.w','fcvt.l','fmv.s','fmv.d','flt','feq','fle','fclass']]): + 'fcvt.w','fcvt.l','fmv.s','fmv.d','flt','feq','fle','fclass','fmv.x']]): treg = 'x' temp_instrobj.rd = (int(get_arg_val(arg)(mcode), 2), treg) - if arg == 'rs1': + if 'rd' in arg and self.inxFlag == True: + treg = reg_type + if any([instr_name.startswith(x) for x in [ + 'fcvt.w','fcvt.l','fmv.s','fmv.d','flt','feq','fle','fclass','fmv.x','fsqrt','fmax','fmin','fadd','fsub','feq','flt','fle','fmul','fdiv','fsgnj','fsgnjn','fsgnjx','fcvt.lu','fcvt.wu']]): + treg = 'x' + temp_instrobj.rd = (int(get_arg_val(arg)(mcode), 2), treg) + + if 'rs1' in arg: treg = reg_type if any([instr_name.startswith(x) for x in [ - 'fsh', 'fsw','fsd','fcvt.s','fcvt.d','fmv.w','fmv.l']]): + 'fsh', 'fsw','fsd','fcvt.s','fcvt.d','fmv.w','fmv.l','fcvt.h','fmv.h','flh']]): treg = 'x' temp_instrobj.rs1 = (int(get_arg_val(arg)(mcode), 2), treg) - if arg == 'rs2': + if 'rs1' in arg and self.inxFlag == True: + print(reg_type) treg = reg_type + if any([instr_name.startswith(x) for x in [ + 'fsh', 'fsw','fsd','fcvt.s','fcvt.d','fmv.w','fmv.l','fcvt.h','fmv.h','flh','fclass','fsqrt','fmax','fmin','fadd','fsub','feq','fle','flt','fmul','fdiv','fsgnj','fsgnjn','fsgnjx','fcvt.lu','fcvt.w','fcvt.wu']]): + treg = 'x' + temp_instrobj.rs1 = (int(get_arg_val(arg)(mcode), 2), treg) + + if 'rs2' in arg: + treg = reg_type + temp_instrobj.rs2 = (int(get_arg_val(arg)(mcode), 2), treg) + if 'rs2' in arg and self.inxFlag == True: + print(reg_type) + treg = reg_type + if any([instr_name.startswith(x) for x in [ + 'fsh', 'fsw','fsd','fcvt.s','fcvt.d','fmv.w','fmv.l','fcvt.h','fmv.h','flh','fclass','fsqrt','fmax','fmin','fadd','fsub','feq','fle','flt','fmul','fdiv','fsgnj','fsgnjn','fsgnjx']]): + treg = 'x' temp_instrobj.rs2 = (int(get_arg_val(arg)(mcode), 2), treg) - if arg == 'rs3': + if 'rs3' in arg: treg = reg_type temp_instrobj.rs3 = (int(get_arg_val(arg)(mcode), 2), treg) - if arg == 'csr': + if 'csr' in arg: temp_instrobj.csr = int(get_arg_val(arg)(mcode), 2) if arg == 'shamt': temp_instrobj.shamt = int(get_arg_val(arg)(mcode), 2) @@ -420,9 +449,198 @@ def decode(self, instrObj_temp): imm = imm[0] + imm_temp[-1] + imm[1:] + imm_temp[0:4] + '0' else: imm = imm + imm_temp + if arg == 'c_uimm7hi': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm[-1] + imm_temp + imm[0] + '00' + else: + imm = imm_temp + imm + if arg == 'c_uimm7lo': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm_temp[-1] + imm + imm_temp[0] + '00' + else: + imm = imm + imm_temp + + if arg == 'c_uimm8lo': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm_temp[-1] + imm + imm_temp[0] + '00' + else: + imm = imm + imm_temp + if arg == 'c_uimm8hi': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm[-1] + imm_temp + imm[0] + '00' + else: + imm = imm_temp + imm + + if arg == 'c_uimm9lo': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm_temp[-1] + imm + imm_temp[0] + '00' + else: + imm = imm + imm_temp + elif arg == 'c_uimm9hi': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm[-1] + imm_temp + imm[0] + '00' + else: + imm = imm_temp + imm + + elif arg == 'c_nzimm6lo': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm_temp[-1] + imm + imm_temp[0] + '00' + else: + imm = imm + imm_temp + elif arg == 'c_nzimm6hi': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm[-1] + imm_temp + imm[0] + '00' + else: + imm = imm_temp + imm + + elif arg == 'c_imm6lo': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm_temp[-1] + imm + imm_temp[0] + '00' + else: + imm = imm + imm_temp + elif arg == 'c_imm6hi': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm[-1] + imm_temp + imm[0] + '00' + else: + imm = imm_temp + imm + + elif arg == 'c_nzimm10hi': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm[-1] + imm_temp + imm[0] + '00' + else: + imm = imm_temp + imm + elif arg == 'c_nzimm10lo': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm_temp[-1] + imm + imm_temp[0] + '00' + else: + imm = imm + imm_temp + + elif arg == 'c_nzimm18hi': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm[-1] + imm_temp + imm[0] + '00' + else: + imm = imm_temp + imm + elif arg == 'c_nzimm18lo': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm_temp[-1] + imm + imm_temp[0] + '00' + else: + imm = imm + imm_temp + + elif arg == 'c_imm12': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm[-1] + imm_temp + imm[0] + '00' + else: + imm = imm_temp + imm + + elif arg == 'c_bimm9lo': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm_temp[-1] + imm + imm_temp[0] + '00' + else: + imm = imm + imm_temp + elif arg == 'c_bimm9hi': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm[-1] + imm_temp + imm[0] + '00' + else: + imm = imm_temp + imm + + elif arg == 'c_nzuimm5': + imm_temp = get_arg_val(arg)(mcode) + imm = imm_temp + imm + + elif arg == 'c_nzuimm6lo': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm_temp[-1] + imm + imm_temp[0] + '00' + else: + imm = imm + imm_temp + + + elif arg == 'c_nzuimm6hi': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm[-1] + imm_temp + imm[0] + '00' + else: + imm = imm_temp + imm + + elif arg == 'c_uimm8splo': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm_temp[-1] + imm + imm_temp[0] + '00' + else: + imm = imm + imm_temp + + elif arg == 'c_uimm8sphi': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm[-1] + imm_temp + imm[0] + '00' + else: + imm = imm_temp + imm + + elif arg == 'c_uimm8sp_s': + imm_temp = get_arg_val(arg)(mcode) + imm = imm[-1] + imm_temp + imm[0] + '00' + + elif arg == 'c_uimm10splo': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm_temp[-1] + imm + imm_temp[0] + '00' + else: + imm = imm + imm_temp + + elif arg == 'c_uimm10sphi': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm[-1] + imm_temp + imm[0] + '00' + else: + imm = imm_temp + imm + + elif arg == 'c_uimm9splo': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm_temp[-1] + imm + imm_temp[0] + '00' + else: + imm = imm + imm_temp + + elif arg == 'c_uimm9sphi': + imm_temp = get_arg_val(arg)(mcode) + if imm: + imm = imm[-1] + imm_temp + imm[0] + '00' + else: + imm = imm_temp + imm + + elif arg == 'c_uimm10sp_s': + imm_temp = get_arg_val(arg)(mcode) + imm = imm_temp + imm + + elif arg == 'c_uimm9sp_s': + imm_temp = get_arg_val(arg)(mcode) + imm = imm_temp + imm + + elif arg == 'c_nzuimm10': + imm_temp = get_arg_val(arg)(mcode) + imm = imm_temp + imm + if imm: numbits = len(imm) temp_instrobj.imm = disassembler.twos_comp(int(imm, 2), numbits) + temp_instrobj.inxFlg = self.inxFlag return temp_instrobj else: return None From f29082ed1ca9f11c85b1ea3ac2c4c2fe53a1b822 Mon Sep 17 00:00:00 2001 From: Anusha Date: Tue, 5 Sep 2023 11:09:48 +0530 Subject: [PATCH 10/11] updated rvopcodesdecoder --- riscv_isac/data/rvopcodesdecoder.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/riscv_isac/data/rvopcodesdecoder.py b/riscv_isac/data/rvopcodesdecoder.py index 2f5782d7..73f0dc60 100644 --- a/riscv_isac/data/rvopcodesdecoder.py +++ b/riscv_isac/data/rvopcodesdecoder.py @@ -382,7 +382,6 @@ def decode(self, instrObj_temp): treg = 'x' temp_instrobj.rs1 = (int(get_arg_val(arg)(mcode), 2), treg) if 'rs1' in arg and self.inxFlag == True: - print(reg_type) treg = reg_type if any([instr_name.startswith(x) for x in [ 'fsh', 'fsw','fsd','fcvt.s','fcvt.d','fmv.w','fmv.l','fcvt.h','fmv.h','flh','fclass','fsqrt','fmax','fmin','fadd','fsub','feq','fle','flt','fmul','fdiv','fsgnj','fsgnjn','fsgnjx','fcvt.lu','fcvt.w','fcvt.wu']]): @@ -393,7 +392,6 @@ def decode(self, instrObj_temp): treg = reg_type temp_instrobj.rs2 = (int(get_arg_val(arg)(mcode), 2), treg) if 'rs2' in arg and self.inxFlag == True: - print(reg_type) treg = reg_type if any([instr_name.startswith(x) for x in [ 'fsh', 'fsw','fsd','fcvt.s','fcvt.d','fmv.w','fmv.l','fcvt.h','fmv.h','flh','fclass','fsqrt','fmax','fmin','fadd','fsub','feq','fle','flt','fmul','fdiv','fsgnj','fsgnjn','fsgnjx']]): From f35b22c1fb3a2042e6acfe68094952903d074fa5 Mon Sep 17 00:00:00 2001 From: Andrew de los Reyes Date: Wed, 6 Sep 2023 15:03:31 -0700 Subject: [PATCH 11/11] Modify ibm_b1 to support BF16 Specifically: - Generate BF16 literals for test from BF16 - Generate more FP32 literals to cover requested cases for FP32 to BF16 conversion - Cover all rounding modes in ibm_b1 --- riscv_isac/InstructionObject.py | 25 ++++++--- riscv_isac/coverage.py | 1 + riscv_isac/fp_dataset.py | 93 +++++++++++++++++++++++---------- 3 files changed, 85 insertions(+), 34 deletions(-) diff --git a/riscv_isac/InstructionObject.py b/riscv_isac/InstructionObject.py index 574bdc3a..8321df85 100644 --- a/riscv_isac/InstructionObject.py +++ b/riscv_isac/InstructionObject.py @@ -84,7 +84,8 @@ def __init__( csr_commit = None, mnemonic = None, inxFlag = None, - is_sgn_extd = None + is_sgn_extd = None, + bf16 = None ): ''' @@ -124,6 +125,7 @@ def __init__( self.rs2_nregs = 1 self.rs3_nregs = 1 self.rd_nregs = 1 + self.bf16 = bf16 def is_sig_update(self): @@ -151,6 +153,9 @@ def evaluate_instr_vars(self, xlen, flen, arch_state, csr_regfile, instr_vars): instr_vars['iflen'] = 64 elif self.instr_name.endswith(".h"): instr_vars['iflen'] = 16 + elif self.instr_name.endswith(".bf16"): + instr_vars['iflen'] = -16 + instr_vars['bf16'] = True # capture the operands if self.rs1 is not None: @@ -322,7 +327,8 @@ def evaluate_instr_var(self, instr_var_name, *args): rs2 = self.rs2, rs3 = self.rs3, is_rvp = self.is_rvp, - inxFlag = self.inxFlg + inxFlag = self.inxFlg, + bf16 = self.bf16 ): # could just instr_name suffice? return func(self, *args) @@ -406,11 +412,11 @@ def evaluate_f_ext_sem(self, instr_vars, arch_state, csr_regfile): f_ext_vars['fcsr'] = int(csr_regfile['fcsr'], 16) if 'rs1' in instr_vars and instr_vars['rs1'] is not None and (instr_vars['rs1'].startswith('f') or instr_vars['inxFlag']): - self.evaluate_reg_sem_f_ext(instr_vars['rs1_val'], instr_vars['flen'], instr_vars['iflen'], "1", f_ext_vars, instr_vars['inxFlag'], instr_vars['xlen']) + self.evaluate_reg_sem_f_ext(instr_vars['rs1_val'], instr_vars['flen'], instr_vars['iflen'], instr_vars['bf16'], "1", f_ext_vars, instr_vars['inxFlag'], instr_vars['xlen']) if 'rs2' in instr_vars and instr_vars['rs2'] is not None and (instr_vars['rs2'].startswith('f') or instr_vars['inxFlag']): - self.evaluate_reg_sem_f_ext(instr_vars['rs2_val'], instr_vars['flen'], instr_vars['iflen'], "2", f_ext_vars, instr_vars['inxFlag'], instr_vars['xlen']) + self.evaluate_reg_sem_f_ext(instr_vars['rs2_val'], instr_vars['flen'], instr_vars['iflen'], instr_vars['bf16'], "2", f_ext_vars, instr_vars['inxFlag'], instr_vars['xlen']) if 'rs3' in instr_vars and instr_vars['rs3'] is not None and (instr_vars['rs3'].startswith('f') or instr_vars['inxFlag']): - self.evaluate_reg_sem_f_ext(instr_vars['rs3_val'], instr_vars['flen'], instr_vars['iflen'], "3", f_ext_vars, instr_vars['inxFlag'], instr_vars['xlen']) + self.evaluate_reg_sem_f_ext(instr_vars['rs3_val'], instr_vars['flen'], instr_vars['iflen'], instr_vars['bf16'], "3", f_ext_vars, instr_vars['inxFlag'], instr_vars['xlen']) return f_ext_vars @@ -458,16 +464,19 @@ def apndSgnBit(bin_val,sgn_bit): final_bin = ''.join(new_bin) return final_bin - def evaluate_reg_sem_f_ext(self, reg_val, flen, iflen, postfix, f_ext_vars, inxFlag, xlen): + def evaluate_reg_sem_f_ext(self, reg_val, flen, iflen, bf16, postfix, f_ext_vars, inxFlag, xlen): ''' This function expands reg_val and defines the respective sign, exponent and mantissa components ''' if reg_val is None: return - if iflen == 16: + if iflen == 16 and not bf16: e_sz = 5 m_sz = 10 + elif iflen == 16: + e_sz = 8 + m_sz = 7 elif iflen == 32: e_sz = 8 m_sz = 23 @@ -526,4 +535,6 @@ def __str__(self): line+= ' csr_commit: '+ str(self.csr_commit) if self.mnemonic: line+= ' mnemonic: '+ str(self.mnemonic) + if self.bf16: + line+= ' bf16: '+ str(self.bf16) return line diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index 0cd87781..6a6d01f8 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -849,6 +849,7 @@ def compute_per_line(queue, event, cgf_queue, stats_queue, cgf, xlen, flen, addr instr_vars = {} instr_vars['inxFlag'] = instr.inxFlg + instr_vars['bf16'] = instr.bf16 instr.evaluate_instr_vars(xlen, flen, arch_state, csr_regfile, instr_vars) old_csr_regfile = {} diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index 6a4a63fe..80f77acc 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -20,12 +20,27 @@ hsnan = ['0x7C01', '0xFC01', '0x7D55', '0xFD55'] hone = ['0x3C00', '0xBC00'] +#TODO: verify these bf16 numbers +bf16zero = ['0x0000', '0x8000'] +bf16minsubnorm = ['0x0001', '0x8001'] +bf16subnorm = ['0x0002', '0x8002', '0x007E', '0x807E', '0x0055', '0x8055'] +bf16maxsubnorm = ['0x007F', '0x807F'] +bf16minnorm = ['0x0080', '0x8080'] +bf16norm = ['0x0081', '0x8081', '0x0085', '0x8085', '0x008A', '0x808A', '0x5500', '0xD500', '0x2A00', '0xAA00'] +bf16maxnorm = ['0x7F7F', '0xFF7F'] +bf16infinity = ['0x7F80', '0xFF80'] +bf16defaultnan = ['0x7FC0', '0xFFC0'] +bf16qnan = ['0x7FC1', '0xFFC1', '0x7FC5', '0xFFC5'] +bf16snan = ['0x7F81', '0xFF81', '0x7FAA', '0xFFAA'] +bf16one = ['0x3F80', '0xBF80'] + fzero = ['0x00000000', '0x80000000'] fminsubnorm = ['0x00000001', '0x80000001'] fsubnorm = ['0x00000002', '0x80000002', '0x007FFFFE', '0x807FFFFE', '0x00555555', '0x80555555'] fmaxsubnorm = ['0x007FFFFF', '0x807FFFFF'] fminnorm = ['0x00800000', '0x80800000'] fnorm = ['0x00800001', '0x80800001', '0x00855555', '0x80855555', '0x008AAAAA', '0x808AAAAA', '0x55000000', '0xD5000000', '0x2A000000', '0xAA000000'] +fnorm2 = ['0x7F7F8001', '0x7F7F0001', '0x00550000', '0x00550001', '0x007F8000'] fmaxnorm = ['0x7F7FFFFF', '0xFF7FFFFF'] finfinity = ['0x7F800000', '0xFF800000'] fdefaultnan = ['0x7FC00000', '0xFFC00000'] @@ -64,7 +79,7 @@ (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): +def num_explain(flen,num,bf16=False): num_dict = { tuple(hzero) : 'hzero', tuple(hminsubnorm) : 'hminsubnorm', @@ -78,6 +93,18 @@ def num_explain(flen,num): tuple(hqnan) : 'hqnan', tuple(hsnan) : 'hsnan', tuple(hone) : 'hone', + tuple(bf16zero) : 'bf16zero', + tuple(bf16minsubnorm) : 'bf16minsubnorm', + tuple(bf16subnorm) : 'bf16subnorm', + tuple(bf16maxsubnorm) : 'bf16maxsubnorm', + tuple(bf16minnorm) : 'bf16minnorm', + tuple(bf16norm) : 'bf16norm', + tuple(bf16maxnorm) : 'bf16maxnorm', + tuple(bf16infinity) : 'bf16infinity', + tuple(bf16defaultnan) : 'bf16defaultnan', + tuple(bf16qnan) : 'bf16qnan', + tuple(bf16snan) : 'bf16snan', + tuple(bf16one) : 'bf16one', tuple(fzero) : 'fzero', tuple(fminsubnorm) : 'fminsubnorm', tuple(fsubnorm) : 'fsubnorm', @@ -108,9 +135,12 @@ def num_explain(flen,num): if(('0x'+num[2:].upper()) in num_list[i][0]): return(num_list[i][1]) - if flen == 16: + if flen == 16 and not bf16: e_sz = 5 # exponent size m_sz = 10 # mantissa size + elif flen == 16: + e_sz = 8 + m_sz = 7 elif flen == 32: e_sz = 8 m_sz = 23 @@ -123,15 +153,18 @@ def num_explain(flen,num): man = bin_val[e_sz+1:] if(int(exp,2)!=0): - return('hnorm' if flen == 16 else 'fnorm' if flen==32 else 'dnorm') + return('bf16norm' if flen == 16 and bf16 else 'hnorm' if flen == 16 else 'fnorm' if flen==32 else 'dnorm') else: - return('hsubnorm' if flen == 16 else 'fsubnorm' if flen==32 else 'dsubnorm') + return('bf16subnorm' if flen == 16 and bf16 else 'hsubnorm' if flen == 16 else 'fsubnorm' if flen==32 else 'dsubnorm') -def extract_fields(flen, hexstr, postfix): - if flen == 16: +def extract_fields(flen, hexstr, postfix, bf16=False): + if flen == 16 and not bf16: e_sz = 5 # exponent size m_sz = 10 # mantissa size + elif flen == 16: + e_sz = 8 + m_sz = 7 elif flen == 32: e_sz = 8 m_sz = 23 @@ -360,7 +393,7 @@ def sgn_prefix(iflen,flen,inxFlag,c,cvpt): sp += ' and rs'+str(x)+'_sgn_prefix == 0x'+'0'*int((flen-iflen)/4) return sp -def ibm_b1(flen, iflen, opcode, ops, inxFlg=False): +def ibm_b1(flen, iflen, opcode, ops, inxFlg=False, bf16=False): ''' IBM Model B1 Definition: Test all combinations of floating-point basic types, positive and negative, for @@ -390,15 +423,20 @@ def ibm_b1(flen, iflen, opcode, ops, inxFlg=False): ''' sanitise = get_sanitise_func(opcode) - if iflen == 16: + if iflen == 16 and bf16: + basic_types = bf16zero + bf16minsubnorm + [bf16subnorm[0], bf16subnorm[3]] +\ + bf16maxsubnorm + bf16minnorm + [bf16norm[0], bf16norm[3]] + bf16maxnorm + \ + bf16infinity + bf16defaultnan + [bf16qnan[0], bf16qnan[3]] + \ + [bf16snan[0], bf16snan[3]] + bf16one + + elif iflen == 16: basic_types = hzero + hminsubnorm + [hsubnorm[0], hsubnorm[3]] +\ hmaxsubnorm + hminnorm + [hnorm[0], hnorm[3]] + hmaxnorm + \ hinfinity + hdefaultnan + [hqnan[0], hqnan[3]] + \ [hsnan[0], hsnan[3]] + hone - elif iflen == 32: basic_types = fzero + fminsubnorm + [fsubnorm[0], fsubnorm[3]] +\ - fmaxsubnorm + fminnorm + [fnorm[0], fnorm[3]] + fmaxnorm + \ + fmaxsubnorm + fminnorm + [fnorm[0], fnorm[3]] + fnorm2 + fmaxnorm + \ finfinity + fdefaultnan + [fqnan[0], fqnan[3]] + \ [fsnan[0], fsnan[3]] + fone elif iflen == 64: @@ -414,23 +452,24 @@ def ibm_b1(flen, iflen, opcode, ops, inxFlg=False): 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(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(0,cvpt,iflen,flen,ops,inxFlg) - elif opcode.split('.')[0] in \ - ["fclass","flt","fmax","fsgnjn","fmin","fsgnj","feq","flw","fsw","fsgnjx","fld","fle"]: - cvpt = sanitise(0,cvpt,iflen,flen,ops,inxFlg) - cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) - 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) + 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),bf16)) + " and " + if opcode.split('.')[0] in ["fadd","fsub","fmul","fdiv","fsqrt","fmadd","fnmadd","fmsub","fnmsub","fcvt","fmv"]: + cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) + elif opcode.split('.')[0] in \ + ["fclass","flt","fmax","fsgnjn","fmin","fsgnj","feq","flw","fsw","fsgnjx","fld","fle"]: + cvpt = sanitise(rm,cvpt,iflen,flen,ops,inxFlg) + cvpt += sgn_prefix(iflen,flen,inxFlg,ops,cvpt) + cvpt += ' # ' + for y in range(1, ops+1): + cvpt += 'rs'+str(y)+'_val==' + cvpt += num_explain(iflen, c[y-1], bf16) + '(' + str(c[y-1]) + ')' + if(y != ops): + cvpt += " and " + coverpoints.append(cvpt) mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \