diff --git a/CHANGELOG.md b/CHANGELOG.md index ff10111..be2e810 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.7.0] - 2021-08-11 +- Adding support for floating point extension coverpoints +- Bug fixes for instruction decoder and improved pretty printing. +- fix for uninitialized total_categories variable in coverage. +- fixed CONTRIBUTING.rst file + ## [0.6.6] - 2021-08-03 - Bug fix for error while decoding instruction name diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index acfc08c..97af244 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -6,85 +6,92 @@ Contributing ============ -Contributions are welcome, and they are greatly appreciated and credit will always be given. +Your inputs are welcome and greatly appreciated! We want to make contributing to this project as easy and transparent as possible, whether it's: -You can contribute in many ways: +- Reporting a bug +- Discussing the current state of the code +- Submitting a fix +- Proposing new features +- Becoming a maintainer -Types of Contributions +We develop with Github ---------------------- -Report Bugs -~~~~~~~~~~~ +We use github to host code, to track issues and feature requests, as well as accept pull requests. -Report bugs at https://gitlab.com/incoresemi/riscv-compliance/riscv_isac/issues. +All changes happen through Pull Requests +---------------------------------------- -Submit Feedback -~~~~~~~~~~~~~~~ +Pull requests are the best way to propose changes to the codebase. We actively welcome your pull requests: -The best way to send feedback is to file an issue at https://gitlab.com/incoresemi/riscv-compliance/riscv_isac/issues. +1. Fork the repo and create your branch from `master`. +2. If you have updated the docs, ensure that they render correctly in the respective format. +3. Make sure to create an entry in the CHANGELOG.md. Please refer to the section on versioning below + to choose an appropriate version number. +4. Ensure the existing framework is not broken and still passes the basic checks. +5. Please include a comment with the SPDX license identifier in all source files, for example: + ``` + // SPDX-License-Identifier: BSD-3-Clause + ``` +6. Bump the version of the tool to patch/minor/major as per the entry made in the CHANGELOG.md +7. Issue that pull request! -If you are proposing a feature: +Checks for a PR +--------------- -* Explain in detail how it would work. -* Keep the scope as narrow as possible, to make it easier to implement. -* Remember that this is a volunteer-driven project, and that contributions - are welcome :) +Make sure your PR meets all the following requirements: -Get Started! ------------- +1. You have made an entry in the CHANGELOG.md. +2. You have bumped the version of the tool using bumpversion utility described below. +3. The commit messages are verbose. +4. You PR doesn't break existing framework. -Ready to contribute? Here's how to set up `riscv_isac` for local development. +Versioning +---------- -1. Fork the `riscv_isac` repo on GitLab. -2. Clone your fork locally:: +When issuing pull requests, an entry in the CHANGELOG.md is mandatory. The arch-test-repo adheres to +the [`Semantic Versioning`](https://semver.org/spec/v2.0.0.html) scheme. Following guidelines must +be followed while assigning a new version number : - $ git clone https://gitlab.com/incoresemi/riscv-compliance/riscv_isac.git +- Patch-updates: all doc updates (like typos, more clarification,etc) will be patches. Beautification enhancements will also be treated as patch updates. Certain bug fixes to existing code may be treated as patches as well. +- Minor-updates: Updates to code with new extensions, features, run time optimizations can be + treated as minor updates. +- Major-updates: Changes to the framework flow (backward compatible or incompatible) will be treated + as major updates. -3. Create an issue and WIP merge request that creates a working branch for you +Note: You can have either a patch or minor or major update. +Note: In case of a conflict, the maintainers will decide the final version to be assigned. - $ git checkout -b name-of-your-bugfix-or-feature +All contributions will be under the permissive open-source License +------------------------------------------------------------------ - Now you can make your changes locally. +In short, when you submit code changes, your submissions are understood to be under a permissive open source license like BSD-3, Apache-2.0 and CC, etc that covers the project. Feel free to contact the maintainers if that's a concern. -4. When you're done making changes, check that your changes pass pytest - tests, including testing other Python versions with tox:: +Report bugs using Github's `issues `_ +------------------------------------------------------------------------------------ - $ cd tests - $ pytest test_riscv_isac.py -v +We use GitHub issues to track public bugs. Report a bug by `opening a new issue `_ it's that easy! -5. Commit your changes and push your branch to GitLab:: +Write bug reports with detail, background, and sample code +---------------------------------------------------------- - $ git add . - $ git commit -m "Your detailed description of your changes." - $ git push origin name-of-your-bugfix-or-feature +**Great Bug Reports** tend to have: -6. Submit a merge request through the GitLab website. +- A quick summary and/or background +- Steps to reproduce + - Be specific! + - Give sample code if you can. +- What you expected would happen +- What actually happens +- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) -Merge Request Guidelines ----------------------------- -Before you submit a merge request, check that it meets these guidelines: +Version Bumping made simple +--------------------------- -1. The merge request should include tests. -2. If the merge request adds functionality, the docs should be updated. -3. The merge request should work for Python 3.6, 3.7 and 3.8, and for PyPy. - and make sure that the tests pass for all supported Python versions. +Each PR will require the tools version to be bumped. This can be achieved using the following +commands:: -Tips ----- + $ bumpversion --allow-dirty --no-tag --config-file setup.cfg patch #options: major / minor / patch -To run a subset of tests:: - - $ pytest tests.test_riscv_isac - - -Deploying ---------- - -A reminder for the maintainers on how to deploy. -Make sure all your changes are committed. -Then run:: - -$ bumpversion --no-tag --config-file setup.cfg patch # possible: major / minor / patch -$ git push origin name-of-your-branch diff --git a/riscv_isac/__init__.py b/riscv_isac/__init__.py index b8b7724..7afc1a7 100644 --- a/riscv_isac/__init__.py +++ b/riscv_isac/__init__.py @@ -4,4 +4,4 @@ __author__ = """InCore Semiconductors Pvt Ltd""" __email__ = 'info@incoresemi.com' -__version__ = '0.6.6' +__version__ = '0.7.0' diff --git a/riscv_isac/coverage.py b/riscv_isac/coverage.py index b17d5a9..01b2c5a 100644 --- a/riscv_isac/coverage.py +++ b/riscv_isac/coverage.py @@ -39,7 +39,15 @@ 'aes64esm','aes64ks2','sm4ed','sm4ks','ror','rol','rorw','rolw','clmul',\ 'clmulh','andn','orn','xnor','pack','packh','packu','packuw','packw',\ 'xperm.n','xperm.b', 'aes32esmi', 'aes32esi', 'aes32dsmi', 'aes32dsi',\ - 'sha512sum1r','sha512sum0r','sha512sig1l','sha512sig1h','sha512sig0l','sha512sig0h'] + 'sha512sum1r','sha512sum0r','sha512sig1l','sha512sig1h','sha512sig0l','sha512sig0h','fsw'] + +one_operand_finstructions = ["fsqrt.s","fmv.x.w","fcvt.wu.s","fcvt.w.s","fclass.s","fcvt.l.s","fcvt.lu.s","fcvt.s.l","fcvt.s.lu","fcvt.s.w","fcvt.s.wu","fmv.w.x"] +two_operand_finstructions = ["fadd.s","fsub.s","fmul.s","fdiv.s","fmax.s","fmin.s","feq.s","flt.s","fle.s","fsgnj.s","fsgnjn.s","fsgnjx.s"] +three_operand_finstructions = ["fmadd.s","fmsub.s","fnmadd.s","fnmsub.s"] + +one_operand_dinstructions = ["fsqrt.d","fclass.d","fcvt.w.d","fcvt.wu.d","fcvt.d.w","fcvt.d.wu","fcvt.l.d","fcvt.lu.d","fcvt.d.l","fcvt.d.lu","fmv.x.d","fmv.d.x","fcvt.s.d","fcvt.d.s"] +two_operand_dinstructions = ["fadd.d","fsub.d","fmul.d","fdiv.d","fmax.d","fmin.d","feq.d","flt.d","fle.d","fsgnj.d","fsgnjn.d","fsgnjx.d"] +three_operand_dinstructions = ["fmadd.d","fmsub.d","fnmadd.d","fnmsub.d"] class csr_registers(MutableMapping): ''' @@ -61,6 +69,8 @@ def __init__ (self, xlen): ''' + global arch_state + if(xlen==32): self.csr = ['00000000']*4096 self.csr[int('301',16)] = '40000000' # misa @@ -85,6 +95,9 @@ def __init__ (self, xlen): # S-Mode CSRs self.csr[int('106',16)] = '00000000' # scounteren + # F-Mode CSRs + self.csr[int('003',16)] = '00000000' # fcsr + self.csr_regs={ "mvendorid":int('F11',16), "marchid":int('F12',16), @@ -130,7 +143,8 @@ def __init__ (self, xlen): "scause": int('142',16), "stval": int('143',16), "sip": int('144',16), - "satp": int('180',16) + "satp": int('180',16), + "fcsr": int('003',16) } for i in range(16): self.csr_regs["pmpaddr"+str(i)] = int('3B0',16)+i @@ -141,10 +155,15 @@ def __init__ (self, xlen): def __setitem__ (self,key,value): - if(isinstance(key, str)): - self.csr[self.csr_regs[key]] = value + if(key == 'frm'): + value = value[-1:] + arch_state.fcsr = value + self.csr[self.csr_regs["fcsr"]] = "00000000" else: - self.csr[key] = value + if(isinstance(key, str)): + self.csr[self.csr_regs[key]] = value + else: + self.csr[key] = value def __iter__(self): for entry in self.csr_regs.keys(): @@ -229,10 +248,14 @@ def __init__(self, xlen, flen): self.cov_pt_sig = [] self.last_meta = [] -def pretty_print_yaml(yaml): +def pretty_print_yaml(myyaml): res = '''''' - for line in ruamel.yaml.round_trip_dump(yaml, indent=5, block_seq_indent=3).splitlines(True): - res += line + + from io import StringIO + string_stream = StringIO() + yaml.dump(myyaml,string_stream) + res = string_stream.getvalue() + string_stream.close() return res def pretty_print_regfile(regfile): @@ -461,11 +484,10 @@ def compute_per_line(instr, cgf, xlen, addr_pairs, sig_addrs): rs1_val = struct.unpack(unsgn_sz, bytes.fromhex(arch_state.x_rf[rs1]))[0] elif rs1_type == 'x': rs1_val = struct.unpack(sgn_sz, bytes.fromhex(arch_state.x_rf[rs1]))[0] - if instr.instr_name in ["fmv.w.x"]: - rs1_val = '0x' + (arch_state.x_rf[rs1]).lower() elif rs1_type == 'f': rs1_val = struct.unpack(sgn_sz, bytes.fromhex(arch_state.f_rf[rs1]))[0] - if instr.instr_name in ["fadd.s","fsub.s","fmul.s","fdiv.s","fsqrt.s","fmadd.s","fmsub.s","fnmadd.s","fnmsub.s","fmax.s","fmin.s","feq.s","flt.s","fle.s","fmv.x.w","fmv.w.x","fcvt.wu.s","fcvt.s.wu","fcvt.w.s","fcvt.s.w","fsgnj.s","fsgnjn.s","fsgnjx.s","fclass.s"]: + if instr.instr_name in one_operand_finstructions + two_operand_finstructions + three_operand_finstructions\ + + one_operand_dinstructions + two_operand_dinstructions + three_operand_dinstructions: rs1_val = '0x' + (arch_state.f_rf[rs1]).lower() if instr.instr_name in unsgn_rs2: @@ -474,16 +496,18 @@ def compute_per_line(instr, cgf, xlen, addr_pairs, sig_addrs): rs2_val = struct.unpack(sgn_sz, bytes.fromhex(arch_state.x_rf[rs2]))[0] elif rs2_type == 'f': rs2_val = struct.unpack(sgn_sz, bytes.fromhex(arch_state.f_rf[rs2]))[0] - if instr.instr_name in ["fadd.s","fsub.s","fmul.s","fdiv.s","fmadd.s","fmsub.s","fnmadd.s","fnmsub.s","fmax.s","fmin.s","feq.s","flt.s","fle.s","fsgnj.s","fsgnjn.s","fsgnjx.s"]: + if instr.instr_name in two_operand_finstructions + two_operand_dinstructions + three_operand_finstructions\ + + three_operand_dinstructions: rs2_val = '0x' + (arch_state.f_rf[rs2]).lower() - if instr.instr_name in ["fmadd.s","fmsub.s","fnmadd.s","fnmsub.s"]: + if instr.instr_name in three_operand_finstructions + three_operand_dinstructions: rs3_val = '0x' + (arch_state.f_rf[rs3]).lower() if instr.instr_name in ['csrrwi']: arch_state.fcsr = instr.zimm - if instr.instr_name in ["fadd.s","fsub.s","fmul.s","fdiv.s","fsqrt.s","fmadd.s","fmsub.s","fnmadd.s","fnmsub.s","fmax.s","fmin.s","feq.s","flt.s","fle.s","fmv.x.w","fmv.w.x","fcvt.wu.s","fcvt.s.wu","fcvt.w.s","fcvt.s.w","fsgnj.s","fsgnjn.s","fsgnjx.s","fclass.s"]: + if instr.instr_name in one_operand_finstructions + two_operand_finstructions + three_operand_finstructions\ + + one_operand_dinstructions + two_operand_dinstructions + three_operand_dinstructions: rm = instr.rm if(rm==7 or rm==None): rm_val = arch_state.fcsr @@ -502,7 +526,7 @@ def compute_per_line(instr, cgf, xlen, addr_pairs, sig_addrs): if instr.instr_name in ['sw','sh','sb','lw','lhu','lh','lb','lbu','lwu','flw','fsw']: ea_align = (rs1_val + imm_val) % 4 - if instr.instr_name in ['ld','sd']: + if instr.instr_name in ['ld','sd','fld','fsd']: ea_align = (rs1_val + imm_val) % 8 local_dict={} @@ -573,24 +597,71 @@ def compute_per_line(instr, cgf, xlen, addr_pairs, sig_addrs): stats.covpt.append(str(coverpoints)) cgf[cov_labels]['op_comb'][coverpoints] += 1 if 'val_comb' in value and len(value['val_comb']) != 0: - if instr.instr_name in ['fadd.s',"fsub.s","fmul.s","fdiv.s","fmax.s","fmin.s","feq.s","flt.s","fle.s","fsgnj.s","fsgnjn.s","fsgnjx.s"]: + if instr.instr_name in two_operand_finstructions: + if xlen == 64: + rs1_val = rs1_val[8:] + rs2_val = rs2_val[8:] + val_key = fmt.extract_fields(32, rs1_val, str(1)) + val_key+= " and " + val_key+= fmt.extract_fields(32, rs2_val, str(2)) + val_key+= " and " + val_key+= 'rm_val == '+ str(rm_val) + val_key+= ' #nosat' + l=[0] + l[0] = val_key + val_key = l + if(val_key[0] in cgf[cov_labels]['val_comb']): + if cgf[cov_labels]['val_comb'][val_key[0]] == 0: + stats.ucovpt.append(str(val_key[0])) + stats.covpt.append(str(val_key[0])) + cgf[cov_labels]['val_comb'][val_key[0]] += 1 + elif instr.instr_name in one_operand_finstructions: + if xlen == 64 and instr.instr_name not in ["fcvt.s.l", "fcvt.s.lu"]: + rs1_val = rs1_val[8:] + if instr.instr_name not in ["fcvt.s.l","fcvt.s.lu","fcvt.s.w","fcvt.s.wu","fmv.w.x"]: + val_key = fmt.extract_fields(32, rs1_val, str(1)) + else: + val_key = "rs1_val == "+ str(rs1_val) + val_key+= " and " + val_key+= 'rm_val == '+ str(rm_val) + val_key+= ' #nosat' + l=[0] + l[0] = val_key + val_key = l + if(val_key[0] in cgf[cov_labels]['val_comb']): + if cgf[cov_labels]['val_comb'][val_key[0]] == 0: + stats.ucovpt.append(str(val_key[0])) + stats.covpt.append(str(val_key[0])) + cgf[cov_labels]['val_comb'][val_key[0]] += 1 + elif instr.instr_name in three_operand_finstructions: + if xlen == 64: + rs1_val = rs1_val[8:] + rs2_val = rs2_val[8:] + rs3_val = rs3_val[8:] val_key = fmt.extract_fields(32, rs1_val, str(1)) val_key+= " and " val_key+= fmt.extract_fields(32, rs2_val, str(2)) val_key+= " and " - val_key+= 'rm == '+ str(rm_val) + val_key+= fmt.extract_fields(32, rs3_val, str(3)) + val_key+= " and " + val_key+= 'rm_val == '+ str(rm_val) + val_key+= ' #nosat' l=[0] l[0] = val_key val_key = l + print(val_key) if(val_key[0] in cgf[cov_labels]['val_comb']): if cgf[cov_labels]['val_comb'][val_key[0]] == 0: stats.ucovpt.append(str(val_key[0])) stats.covpt.append(str(val_key[0])) cgf[cov_labels]['val_comb'][val_key[0]] += 1 - elif instr.instr_name in ["fsqrt.s","fmv.x.w","fmv.w.x","fcvt.wu.s","fcvt.s.wu","fcvt.w.s","fcvt.s.w","fclass.s"]: - val_key = fmt.extract_fields(32, rs1_val, str(1)) + elif instr.instr_name in two_operand_dinstructions: + val_key = fmt.extract_fields(64, rs1_val, str(1)) + val_key+= " and " + val_key+= fmt.extract_fields(64, rs2_val, str(2)) val_key+= " and " - val_key+= 'rm == '+ str(rm_val) + val_key+= 'rm_val == '+ str(rm_val) + val_key+= ' #nosat' l=[0] l[0] = val_key val_key = l @@ -599,14 +670,31 @@ def compute_per_line(instr, cgf, xlen, addr_pairs, sig_addrs): stats.ucovpt.append(str(val_key[0])) stats.covpt.append(str(val_key[0])) cgf[cov_labels]['val_comb'][val_key[0]] += 1 - elif instr.instr_name in ["fmadd.s","fmsub.s","fnmadd.s","fnmsub.s"]: - val_key = fmt.extract_fields(32, rs1_val, str(1)) + elif instr.instr_name in one_operand_dinstructions: + if instr.instr_name not in ["fcvt.d.l","fcvt.d.lu","fcvt.d.w","fcvt.d.wu","fmv.d.x"]: + val_key = fmt.extract_fields(64, rs1_val, str(1)) + else: + val_key = "rs1_val == "+ str(rs1_val) val_key+= " and " - val_key+= fmt.extract_fields(32, rs2_val, str(2)) + val_key+= 'rm_val == '+ str(rm_val) + val_key+= ' #nosat' + l=[0] + l[0] = val_key + val_key = l + if(val_key[0] in cgf[cov_labels]['val_comb']): + if cgf[cov_labels]['val_comb'][val_key[0]] == 0: + stats.ucovpt.append(str(val_key[0])) + stats.covpt.append(str(val_key[0])) + cgf[cov_labels]['val_comb'][val_key[0]] += 1 + elif instr.instr_name in three_operand_dinstructions: + val_key = fmt.extract_fields(64, rs1_val, str(1)) val_key+= " and " - val_key+= fmt.extract_fields(32, rs3_val, str(3)) + val_key+= fmt.extract_fields(64, rs2_val, str(2)) + val_key+= " and " + val_key+= fmt.extract_fields(64, rs3_val, str(3)) val_key+= " and " - val_key+= 'rm == '+ str(rm_val) + val_key+= 'rm_val == '+ str(rm_val) + val_key+= ' #nosat' l=[0] l[0] = val_key val_key = l @@ -617,6 +705,11 @@ def compute_per_line(instr, cgf, xlen, addr_pairs, sig_addrs): cgf[cov_labels]['val_comb'][val_key[0]] += 1 else: for coverpoints in value['val_comb']: + if type(rs1_val) is str: + if '0x' in rs1_val: + rs1_val = int(rs1_val,16) + else: + rs1_val = int(rs1_val) if eval(coverpoints): if cgf[cov_labels]['val_comb'][coverpoints] == 0: stats.ucovpt.append(str(coverpoints)) @@ -784,6 +877,7 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle logger.info('Creating Data Propagation Report : ' + test_name + '.md') writer = pytablewriter.MarkdownTableWriter() writer.headers = ["s.no","signature", "coverpoints", "code"] + total_categories = 0 for cov_labels, value in cgf.items(): if cov_labels != 'datasets': # rpt_str += cov_labels + ':\n' diff --git a/riscv_isac/fp_dataset.py b/riscv_isac/fp_dataset.py index 436f4c1..13b108f 100644 --- a/riscv_isac/fp_dataset.py +++ b/riscv_isac/fp_dataset.py @@ -65,7 +65,7 @@ def num_explain(flen,num): for i in range(len(num_list)): if(('0x'+num[2:].upper()) in num_list[i][0]): return(num_list[i][1]) - + if flen == 32: e_sz = 8 m_sz = 23 @@ -76,7 +76,7 @@ def num_explain(flen,num): sgn = bin_val[0] exp = bin_val[1:e_sz+1] man = bin_val[e_sz+1:] - + if(int(exp,2)!=0): return('fnorm' if flen==32 else 'dnorm') else: @@ -105,7 +105,7 @@ def extract_fields(flen, hexstr, postfix): return string def fields_dec_converter(flen, hexstr): # IEEE-754 Hex -> Decimal Converter - + if flen == 32: e_sz = 8 m_sz = 23 @@ -116,15 +116,15 @@ def fields_dec_converter(flen, hexstr): # IEEE-754 Hex -> Decimal Converte sgn = bin_val[0] exp = bin_val[1:e_sz+1] man = bin_val[e_sz+1:] - + num='' if(int(sgn)==1): sign = '-' elif(int(sgn)==0): sign = '+' - + exp_str = '*pow(2,' - + if(flen == 32): if((int(exp,2)-127)<-126): conv_num = 0.0 @@ -141,7 +141,7 @@ def fields_dec_converter(flen, hexstr): # IEEE-754 Hex -> Decimal Converte exp_str+= str(int(exp,2)-1023)+')' for i in range(len(man)): conv_num+= (1/(pow(2,i+1)))*int(man[i]) - + num = sign + str(conv_num) + exp_str if(flen == 32): if(eval(num) > 1e-45 or eval(num)<-1e-45): @@ -152,7 +152,7 @@ def fields_dec_converter(flen, hexstr): # IEEE-754 Hex -> Decimal Converte return(eval(num)) def floatingPoint_tohex(flen,float_no): # Decimal -> IEEE-754 Hex Converter - + if(flen==32): if(str(float_no)=='-inf'): return(finfinity[1]) @@ -163,17 +163,17 @@ def floatingPoint_tohex(flen,float_no): # Decimal -> IEEE-754 Hex Converte return(dinfinity[1]) elif(str(float_no)=='inf'): return(dinfinity[0]) - + float_no=float.hex(float_no) num="N" - + a=float.fromhex(float_no) - + sign=0 if(a<0 or str(a)[0]=='-'): sign=1 nor=float.hex(a) # Normalized Number - + if(flen==32): if(int(nor.split("p")[1])<-126): # Checking Underflow of Exponent exp_bin=('0'*8) # Exponent of Subnormal numbers @@ -201,7 +201,7 @@ def floatingPoint_tohex(flen,float_no): # Decimal -> IEEE-754 Hex Converte else: # Converting Exponent to 8-Bit Binary exp=int(nor.split("p")[1])+1023 exp_bin=('0'*(11-(len(bin(exp))-2)))+bin(exp)[2:] - + if(num=="SN"): if(sign==0): mant="0x"+float_no.split("p")[0][4:] @@ -212,7 +212,7 @@ def floatingPoint_tohex(flen,float_no): # Decimal -> IEEE-754 Hex Converte mant="0x"+nor.split("p")[0][4:] else: mant="0x"+nor.split("p")[0][5:] - + if(flen==32): mant_bin=bin(int('1'+mant[2:],16))[3:] if(num == "SN"): @@ -232,9 +232,9 @@ def floatingPoint_tohex(flen,float_no): # Decimal -> IEEE-754 Hex Converte binary=binary+str(sign)+exp_bin+mant_bin[0:52] hex_tp=hex(int(binary,2)) hex_tp=hex_tp.replace('0x','0x'+'0'*(16-(len(hex_tp)-2))) - + return(hex_tp) - + def unique_cpts(x): d = {} for i in range(len(x)): # Returning a List Of Unique Coverpoints @@ -249,7 +249,7 @@ def comments_parser(coverpoints): for coverpoint in coverpoints: cvpt = coverpoint.split("#")[0] comment = coverpoint.split("#")[1] - cvpts.append((cvpt+ " #nosat_f",comment)) + cvpts.append((cvpt+ " #nosat",comment)) return cvpts def ibm_b1(flen, opcode, ops): @@ -259,19 +259,19 @@ def ibm_b1(flen, opcode, ops): each of the inputs. The basic types are Zero, One, MinSubNorm, SubNorm, MaxSubNorm, MinNorm, Norm, MaxNorm, Infinity, DefaultNaN, QNaN, and SNaN. - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode - + :type flen: int :type opcode: str :type ops: int - + Abstract Dataset Description: Operands => [Zero, One, MinSubNorm, SubNorm, MaxSubNorm, MinNorm, Norm, MaxNorm, Infinity, DefaultNaN, QNaN, SNaN] - + Implementation: - Dependent on the value of flen, a predefined dataset of floating point values are added. - Using the itertools package, an iterative multiplication is performed with two lists to create an exhaustive combination of all the operand values. @@ -292,7 +292,7 @@ def ibm_b1(flen, opcode, ops): else: logger.error('Invalid flen value!') sys.exit(1) - + # the following creates a cross product for ops number of variables b1_comb = list(itertools.product(*ops*[basic_types])) coverpoints = [] @@ -315,7 +315,7 @@ def ibm_b1(flen, opcode, ops): if(y != ops): cvpt += " and " coverpoints.append(cvpt) - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B1 for '+opcode+' !' logger.info(mess) @@ -332,22 +332,22 @@ def ibm_b2(flen, opcode, ops, int_val = 100, seed = -1): flipping one bit of the significand. - :param flen: Size of the floating point registers + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param int_val: Number to define the range in which the random value is to be generated. (Predefined to 100) :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :type int_val: int :param seed: int - + Abstract Dataset Description: Final Results = [Zero, One, MinSubNorm, MaxSubNorm, MinNorm, MaxNorm] Operand1 {operation} Operand2 = Final Results - + Implementation: - Hamming distance is calculated using an xor operation between a number in the dataset and a number generated using walking ones operation. - A random operand value for one of the operands is assigned and based on the result and operation under consideration, the next operand is calculated. @@ -366,11 +366,11 @@ def ibm_b2(flen, opcode, ops, int_val = 100, seed = -1): b = '0x0000000000000010' e_sz=11 m_sz = 52 - + result = [] b2_comb = [] opcode = opcode.split('.')[0] - + if seed == -1: if opcode in 'fadd': random.seed(0) @@ -392,14 +392,14 @@ def ibm_b2(flen, opcode, ops, int_val = 100, seed = -1): random.seed(8) else: random.seed(seed) - + for i in range(len(flip_types)): k=1 for j in range (1,24): #print('{:010b}'.format(k)) result.append(['0x'+hex(eval(bin(int('1'+flip_types[i][2:], 16))) ^ eval('0b'+'{:023b}'.format(k)))[3:],' | Result = '+num_explain(flen, '0x'+str(hex(eval(bin(int('1'+flip_types[i][2:], 16))))[3:]))+'(0x'+str(hex(eval(bin(int('1'+flip_types[i][2:], 16))))[3:])+')^'+str('0x'+hex(eval('0b'+'1'+'{:024b}'.format(k)))[3:])]) k=k*2 - + for i in range(len(result)): bin_val = bin(int('1'+result[i][0][2:],16))[3:] rsgn = bin_val[0] @@ -431,12 +431,12 @@ def ibm_b2(flen, opcode, ops, int_val = 100, seed = -1): rs2 = (fields_dec_converter(flen,result[i][0]) + rs3)/rs1 elif opcode in 'fnmsub': rs2 = -1*(rs3 + fields_dec_converter(flen,result[i][0]))/rs1 - + if(flen==32): m = struct.unpack('f', struct.pack('f', rs2))[0] elif(flen==64): m = rs2 - + if opcode in ['fadd','fsub','fmul','fdiv']: b2_comb.append((floatingPoint_tohex(flen,rs1),floatingPoint_tohex(flen,m))) elif opcode in 'fsqrt': @@ -462,37 +462,37 @@ def ibm_b2(flen, opcode, ops, int_val = 100, seed = -1): cvpt += result[k][1] coverpoints.append(cvpt) k=k+1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B2 for '+opcode+' !' logger.info(mess) coverpoints = comments_parser(coverpoints) return coverpoints - + def ibm_b3(flen, opcode, ops, seed=-1): ''' IBM Model B3 Definition: This model tests all combinations of the sign, significand’s LSB, guard bit & sticky bit of the intermediate result. - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Intermediate Result is chosen at random Intermediate Result = [All possible combinations of Sign, LSB, Guard and Sticky are taken] Operand1 {operation} Operand2 = Intermediate Results - + Implementation: - The Sticky bit is 1 if there were non-zero digits to the right of the guard digit, hence the lsb list is subjected to that condition. - - Float_val [ a list of numbers ] extracted from the fields_dec_converter is checked for the LSB. If it is a negative number, then the list ieee754_num is appended with splitting the p character and first 10 characters in the 0th split + ‘p’ + other part of the split. “p” specifies the maximum available number in python and used in 64 bit architecture. If we require a digit more than thea number, then we represent it using a string because an int + - Float_val [ a list of numbers ] extracted from the fields_dec_converter is checked for the LSB. If it is a negative number, then the list ieee754_num is appended with splitting the p character and first 10 characters in the 0th split + ‘p’ + other part of the split. “p” specifies the maximum available number in python and used in 64 bit architecture. If we require a digit more than thea number, then we represent it using a string because an int - Now the ir_dataset is initialized and since the ieee754_num list has the same element twice [ first is just the number and second is with sign ], hence we loop that array, considering only multiples of 2 elements from it. If the sign is ‘-’, then then the index is updated with 1 else if it is ‘+’, then it is updated with 0 complying with the IEEE standards. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. @@ -500,7 +500,7 @@ def ibm_b3(flen, opcode, ops, seed=-1): ''' opcode = opcode.split('.')[0] getcontext().prec = 40 - + if seed == -1: if opcode in 'fadd': random.seed(0) @@ -522,14 +522,14 @@ def ibm_b3(flen, opcode, ops, seed=-1): random.seed(8) else: random.seed(seed) - + if flen == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) ieee754_num = [] lsb = [] for i in fsubnorm+fnorm: - if int(i[-1],16)%2 == 1: + if int(i[-1],16)%2 == 1: lsb.append('1') lsb.append('1') else: @@ -542,7 +542,7 @@ def ibm_b3(flen, opcode, ops, seed=-1): else: ieee754_num.append(float_val.split('p')[0][0:11]+'p'+float_val.split('p')[1]) ieee754_num.append(float_val.split('p')[0][1:11]+'p'+float_val.split('p')[1]) - + ir_dataset = [] for k in range(len(ieee754_num)): for i in range(2,16,2): @@ -550,10 +550,10 @@ def ibm_b3(flen, opcode, ops, seed=-1): if ieee754_num[k][0] == '-': sign = '1' else: sign = '0' ir_dataset.append([ieee754_num[k].split('p')[0]+str(i)+'p'+ieee754_num[k].split('p')[1],' | Guard = '+grs[0]+' Sticky = '+grs[2]+' Sign = '+sign+' LSB = '+lsb[k]]) - + for i in range(len(ir_dataset)): ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) - + elif flen == 64: maxdec = '1.7976931348623157e+308' maxnum = float.fromhex('0x1.fffffffffffffp+1023') @@ -573,7 +573,7 @@ def ibm_b3(flen, opcode, ops, seed=-1): 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): @@ -581,9 +581,9 @@ def ibm_b3(flen, opcode, ops, seed=-1): if ieee754_num[k][0] == '-': sign = '1' else: sign = '0' ir_dataset.append([str(Decimal(ieee754_num[k].split('e')[0])+Decimal(pow(i*16,-14)))+'e'+ieee754_num[k].split('e')[1],' | Guard = '+grs[0]+' Sticky = '+grs[2]+' Sign = '+sign+' LSB = '+lsb[k]]) - + b4_comb = [] - + for i in range(len(ir_dataset)): rs1 = random.uniform(1,maxnum) rs3 = random.uniform(1,maxnum) @@ -632,7 +632,7 @@ def ibm_b3(flen, opcode, ops, seed=-1): rs2 = -1*(rs3 + ir_dataset[i][0])/rs1 elif flen == 64: rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) - + if(flen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] @@ -641,16 +641,16 @@ def ibm_b3(flen, opcode, ops, seed=-1): x1 = rs1 x2 = rs2 x3 = rs3 - + if opcode in ['fadd','fsub','fmul','fdiv']: b4_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) elif opcode in 'fsqrt': b4_comb.append((floatingPoint_tohex(flen,float(rs2)),)) elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: b4_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - + coverpoints = [] - k = 0 + k = 0 for c in b4_comb: for rm in range(5): cvpt = "" @@ -668,14 +668,14 @@ def ibm_b3(flen, opcode, ops, seed=-1): cvpt += ir_dataset[k][1] coverpoints.append(cvpt) k=k+1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B3 for '+opcode+' !' logger.info(mess) coverpoints = comments_parser(coverpoints) return coverpoints - + def ibm_b4(flen, opcode, ops, seed=-1): ''' IBM Model B4 Definition: @@ -687,21 +687,21 @@ def ibm_b4(flen, opcode, ops, seed=-1): 3. A random number that is larger than +MaxNorm + 3 ulp 4. A random number that is smaller than -MaxNorm – 3 ulp 5. One number for every exponent in the range [MaxNorm.exp - 3, MaxNorm.exp + 3] for positive and negative numbers - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Intermediate Results = [[MaxNorm-3 ulp, MaxNorm+3 ulp], [-MaxNorm-3 ulp, -MaxNorm+3 ulp], Random Num > MaxNorm+3 ulp, Random Num < -MaxNorm-3 ulp, [MaxNorm.exp-3, MaxNorm.exp+3]] Operand1 {operation} Operand2 = Intermediate Results - + Implementation: - The intermediate results dataset is populated in accordance with the abstract dataset defined above. - Intermediate results can be out of the range of what is representable in the specified format; they should only be viewed numerically. Inorder to represent numbers that went out of range of the maximum representable number in python, the “Decimal” module was utilized. @@ -710,7 +710,7 @@ def ibm_b4(flen, opcode, ops, seed=-1): ''' opcode = opcode.split('.')[0] getcontext().prec = 40 - + if seed == -1: if opcode in 'fadd': random.seed(0) @@ -732,7 +732,7 @@ def ibm_b4(flen, opcode, ops, seed=-1): random.seed(8) else: random.seed(seed) - + if flen == 32: ieee754_maxnorm_p = '0x1.7fffffp+127' ieee754_maxnorm_n = '0x1.7ffffep+127' @@ -759,9 +759,9 @@ def ibm_b4(flen, opcode, ops, seed=-1): for i in range(-3,4): ir_dataset.append([str(random.uniform(1,maxnum)).split('e')[0]+'e'+str(int(math.log(pow(2,1023+i),10))),' | Exponent = '+str(1023+i)+' Number = +ve']) ir_dataset.append([str(-1*random.uniform(1,maxnum)).split('e')[0]+'e'+str(int(math.log(pow(2,1023+i),10))),' | Exponent = '+str(1023+i)+' Number = -ve']) - + b4_comb = [] - + for i in range(len(ir_dataset)): rs1 = random.uniform(1,maxnum) rs3 = random.uniform(1,maxnum) @@ -810,7 +810,7 @@ def ibm_b4(flen, opcode, ops, seed=-1): rs2 = -1*(rs3 + ir_dataset[i][0])/rs1 elif flen == 64: rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) - + if(flen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] @@ -819,16 +819,16 @@ def ibm_b4(flen, opcode, ops, seed=-1): x1 = rs1 x2 = rs2 x3 = rs3 - + if opcode in ['fadd','fsub','fmul','fdiv']: b4_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) elif opcode in 'fsqrt': b4_comb.append((floatingPoint_tohex(flen,float(rs2)),)) elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: b4_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - + coverpoints = [] - k = 0 + k = 0 for c in b4_comb: for rm in range(5): cvpt = "" @@ -846,52 +846,50 @@ def ibm_b4(flen, opcode, ops, seed=-1): cvpt += ir_dataset[k][1] coverpoints.append(cvpt) k=k+1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B4 for '+opcode+' !' logger.info(mess) coverpoints = comments_parser(coverpoints) return coverpoints - + def ibm_b5(flen, opcode, ops, seed=-1): ''' IBM Model B5 Definition: This model creates a test-case for each of the following constraints on the intermediate results: - 1. All the numbers in the range [+MinSubNorm – 3 ulp, +MinSubNorm + 3 ulp] - 2. All the numbers in the range [-MinSubNorm - 3 ulp, -MinSubNorm + 3 ulp] - 3. All the numbers in the range [MinNorm – 3 ulp, MinNorm + 3 ulp] + 2. All the numbers in the range [-MinSubNorm - 3 ulp, -MinSubNorm + 3 ulp] + 3. All the numbers in the range [MinNorm – 3 ulp, MinNorm + 3 ulp] 4. All the numbers in the range [-MinSubNorm - 3 ulp, -MinSubNorm + 3 ulp] 5. All the numbers in the range [MinNorm – 3 ulp, MinNorm + 3 ulp] - 6. All the numbers in the range [-MinNorm - 3 ulp, -MinNorm + 3 ulp] - 7. A random number in the range (0, MinSubNorm) - 8. A random number in the range (-MinSubNorm, -0) + 6. All the numbers in the range [-MinNorm - 3 ulp, -MinNorm + 3 ulp] + 7. A random number in the range (0, MinSubNorm) + 8. A random number in the range (-MinSubNorm, -0) 9. One number for every exponent in the range [MinNorm.exp, MinNorm.exp + 5] - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Intermediate Results = [+MinSubNorm – 3 ulp, +MinSubNorm + 3 ulp], [-MinSubNorm - 3 ulp, -MinSubNorm + 3 ulp] , [MinNorm – 3 ulp, MinNorm + 3 ulp] , [-MinNorm - 3 ulp, -MinNorm + 3 ulp] , Random Num in (0, MinSubNorm), Random Num in (-MinSubNorm, -0), One Num for every exp in [MinNorm.exp, MinNorm.exp + 5]] Operand1 {operation} Operand2 = Intermediate Results - + Implementation: - - The intermediate results dataset is populated in accordance with the abstract dataset defined above. - Intermediate results can be out of the range of what is representable in the specified format; they should only be viewed numerically. Inorder to represent numbers that went out of range of the maximum representable number in python, the “Decimal” module was utilized. - These operand values are treated as decimal numbers until their derivation after which they are converted into their respective IEEE754 hexadecimal floating point formats using the “floatingPoint_tohex” function. - Coverpoints are then appended with all rounding modes for that particular opcode. - + ''' - + opcode = opcode.split('.')[0] getcontext().prec = 40 if flen == 32: @@ -913,7 +911,7 @@ def ibm_b5(flen, opcode, ops, seed=-1): for i in range(n): ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) ir_dataset.append([-1*ir_dataset[i][0],ir_dataset[i][1]]) - + elif flen == 64: maxdec = '1.7976931348623157e+308' maxnum = float.fromhex('0x1.fffffffffffffp+1023') @@ -929,7 +927,7 @@ def ibm_b5(flen, opcode, ops, seed=-1): grs = '{:04b}'.format(i) ir_dataset.append([str(Decimal(minnormdec.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+minnormdec.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Minnorm + '+str(int(grs[0:3],2))+' ulp']) minnorm_Exp = ['4.450147717014403e-308','8.900295434028806e-308','1.780059086805761e-307','3.560118173611522e-307','7.120236347223044e-307'] - + k = 1 for i in minnorm_Exp: ir_dataset.append([i,' | Exponent = MinNorm.exp + '+str(k)]) @@ -937,7 +935,7 @@ def ibm_b5(flen, opcode, ops, seed=-1): n = len(ir_dataset) for i in range(n): ir_dataset.append(['-'+ir_dataset[i][0],ir_dataset[i][1]]) - + if seed == -1: if opcode in 'fadd': random.seed(0) @@ -959,9 +957,9 @@ def ibm_b5(flen, opcode, ops, seed=-1): random.seed(8) else: random.seed(seed) - + b5_comb = [] - + for i in range(len(ir_dataset)): rs1 = random.uniform(1,maxnum) rs3 = random.uniform(1,maxnum) @@ -1010,7 +1008,7 @@ def ibm_b5(flen, opcode, ops, seed=-1): rs2 = -1*(rs3 + ir_dataset[i][0])/rs1 elif flen == 64: rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) - + if(flen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] @@ -1019,16 +1017,16 @@ def ibm_b5(flen, opcode, ops, seed=-1): x1 = rs1 x2 = rs2 x3 = rs3 - + if opcode in ['fadd','fsub','fmul','fdiv']: b5_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) elif opcode in 'fsqrt': b5_comb.append((floatingPoint_tohex(flen,float(rs2)),)) elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: b5_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - + coverpoints = [] - k = 0 + k = 0 for c in b5_comb: for rm in range(5): cvpt = "" @@ -1046,7 +1044,7 @@ def ibm_b5(flen, opcode, ops, seed=-1): cvpt += ir_dataset[k][1] coverpoints.append(cvpt) k=k+1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B5 for '+opcode+' !' logger.info(mess) @@ -1065,22 +1063,22 @@ def ibm_b6(flen, opcode, ops, seed=-1): 2. -MinSubNorm / 2 <= intermediate < 0 3. 0 < intermediate <= +MinSubNorm / 2 4. +MinSubNorm / 2 < intermediate < +MinSubNorm - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: - Intermediate Results = [Random number ∈ (-MinSubNorm, -MinSubNorm/2), Random number ∈ (-MinSubNorm/2, 0), Random number ∈ (0, +MinSubNorm/2), Random number ∈ (+MinSubNorm/2, +MinSubNorm)] + Intermediate Results = [Random number ∈ (-MinSubNorm, -MinSubNorm/2), Random number ∈ (-MinSubNorm/2, 0), Random number ∈ (0, +MinSubNorm/2), Random number ∈ (+MinSubNorm/2, +MinSubNorm)] {All 8 combinations of guard, round and sticky bit are tested for every number} Operand1 {operation} Operand2 = Intermediate Results - + Implementation: - The intermediate results dataset is populated in accordance with the abstract dataset defined above. - Intermediate results can be out of the range of what is representable in the specified format; they should only be viewed numerically. Inorder to represent numbers that went out of range of the maximum representable number in python, the “Decimal” module was utilized. @@ -1091,7 +1089,7 @@ def ibm_b6(flen, opcode, ops, seed=-1): ''' opcode = opcode.split('.')[0] getcontext().prec = 40 - + if seed == -1: if opcode in 'fmul': random.seed(0) @@ -1107,7 +1105,7 @@ def ibm_b6(flen, opcode, ops, seed=-1): random.seed(5) else: random.seed(seed) - + if flen == 32: ir_dataset = [] ieee754_minsubnorm_n = '-0x0.000001p-127' @@ -1148,13 +1146,13 @@ def ibm_b6(flen, opcode, ops, seed=-1): for i in range(2,16,2): grs = '{:04b}'.format(i) ir_dataset.append([str(Decimal(r.split('e')[0])+Decimal(pow(i*16,-14))),' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> IR ∈ (+MinSubNorm / 2, +MinSubNorm)']) - + b6_comb = [] - + for i in range(len(ir_dataset)): rs1 = random.uniform(0,1e-30) rs3 = random.uniform(0,1e-30) - + if opcode in 'fmul': rs2 = Decimal(ir_dataset[i][0])/Decimal(rs1) elif opcode in 'fdiv': @@ -1167,7 +1165,7 @@ def ibm_b6(flen, opcode, ops, seed=-1): rs2 = (Decimal(ir_dataset[i][0]) + Decimal(rs3))/Decimal(rs1) elif opcode in 'fnmsub': rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) - + if(flen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] @@ -1176,16 +1174,16 @@ def ibm_b6(flen, opcode, ops, seed=-1): x1 = rs1 x2 = rs2 x3 = rs3 - + if opcode in ['fmul','fdiv']: b6_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: b6_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - - #print(*b6_comb,sep='\n') - coverpoints = [] + + #print(*b6_comb,sep='\n') + coverpoints = [] k=0 - + for c in b6_comb: for rm in range(5): cvpt = "" @@ -1203,14 +1201,14 @@ def ibm_b6(flen, opcode, ops, seed=-1): cvpt += ir_dataset[k][1] coverpoints.append(cvpt) k=k+1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B6 for '+opcode+' !' logger.info(mess) coverpoints = comments_parser(coverpoints) return coverpoints - + def ibm_b7(flen, opcode, ops, seed=-1): ''' IBM Model B7 Definition: @@ -1225,25 +1223,25 @@ def ibm_b7(flen, opcode, ops, seed=-1): 0000...010 0000...001 0000000000 - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: - Intermediate Results = [ieee754_maxnorm, maxnum, maxdec, maxnum] + Intermediate Results = [ieee754_maxnorm, maxnum, maxdec, maxnum] {It assures the calculation of sticky bit for every possible combination in the table} Operand1 {operation} Operand2 = Intermediate Results - + Implementation: - The Sticky bit is calculated in each case. The guard bit here is always assumed to be zero and the sign is positive, so that miscalculation of the sticky bit will alter the final result. - - In the intermediate result dataset, the elements are appended as elements before the character ‘p’ and then the binary equivalent of ‘010’ + pow(2,i). + - In the intermediate result dataset, the elements are appended as elements before the character ‘p’ and then the binary equivalent of ‘010’ + pow(2,i). - Finally on the extra bits, it is masked with the comment created in the previous point. All the first character of each element is converted to its floating point equivalent in a loop - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. @@ -1267,7 +1265,7 @@ def ibm_b7(flen, opcode, ops, seed=-1): n = len(ir_dataset) for i in range(n): ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) - + elif flen == 64: maxdec = '1.7976931348623157e+308' maxnum = float.fromhex('0x1.fffffffffffffp+1023') @@ -1276,14 +1274,14 @@ def ibm_b7(flen, opcode, ops, seed=-1): float_val = fields_dec_converter(64,i) if float_val > 0: ieee754_num.append(str(float_val)) - + ir_dataset = [] for l in range(len(ieee754_num)): for k in range(1,13): for i in range(4): comment = (k*(i+1))*'0' + '1' + (51-(k*(i+1)))*'0' ir_dataset.append([str(Decimal(ieee754_num[l].split('e')[0])+Decimal(pow(16,-14))+Decimal(pow(pow(2,3-i)*16,-14-k)))+'e'+ieee754_num[l].split('e')[1],' | Mask on extra bits ---> ' + comment]) - + if seed == -1: if opcode in 'fadd': random.seed(0) @@ -1305,9 +1303,9 @@ def ibm_b7(flen, opcode, ops, seed=-1): random.seed(8) else: random.seed(seed) - + b7_comb = [] - + for i in range(len(ir_dataset)): rs1 = random.uniform(1,maxnum) rs3 = random.uniform(1,maxnum) @@ -1356,7 +1354,7 @@ def ibm_b7(flen, opcode, ops, seed=-1): rs2 = -1*(rs3 + ir_dataset[i][0])/rs1 elif flen == 64: rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) - + if(flen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] @@ -1365,16 +1363,16 @@ def ibm_b7(flen, opcode, ops, seed=-1): x1 = rs1 x2 = rs2 x3 = rs3 - + if opcode in ['fadd','fsub','fmul','fdiv']: b7_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) elif opcode in 'fsqrt': b7_comb.append((floatingPoint_tohex(flen,float(rs2)),)) elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: b7_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - + coverpoints = [] - k = 0 + k = 0 for c in b7_comb: cvpt = "" for x in range(1, ops+1): @@ -1391,14 +1389,14 @@ def ibm_b7(flen, opcode, ops, seed=-1): cvpt += ir_dataset[k][1] coverpoints.append(cvpt) k=k+1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B7 for '+opcode+' !' logger.info(mess) coverpoints = comments_parser(coverpoints) return coverpoints - + def ibm_b8(flen, opcode, ops, seed=-1): ''' IBM Model B8 Definition: @@ -1408,21 +1406,21 @@ def ibm_b8(flen, opcode, ops, seed=-1): 2. All values of extra-bits in the range [111...11100, 111...11111] For each value selected above, test all the combinations on the LSB of the significand, the guard bit, and the sticky bit (if the number of extra bits is not finite). - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Intermediate Results = [For every Subnormal and Normal number, 8 combinations of guard, round and sticky bit are appended, along with 6 combinations(3 positive, 3 negative) of the mask on extra bits] Operand1 {operation} Operand2 = Intermediate Results - + Implementation: - The intermediate results dataset is populated in accordance with the abstract dataset defined above. The coverpoints can be increased by increasing the dataset of normal and subnormal numbers. - Intermediate results can be out of the range of what is representable in the specified format; they should only be viewed numerically. Inorder to represent numbers that went out of range of the maximum representable number in python, the “Decimal” module was utilized. @@ -1452,7 +1450,7 @@ def ibm_b8(flen, opcode, ops, seed=-1): n = len(ir_dataset) for i in range(n): ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) - + elif flen == 64: maxdec = '1.7976931348623157e+308' maxnum = float.fromhex('0x1.fffffffffffffp+1023') @@ -1493,9 +1491,9 @@ def ibm_b8(flen, opcode, ops, seed=-1): random.seed(8) else: random.seed(seed) - + b8_comb = [] - + for i in range(len(ir_dataset)): rs1 = random.uniform(1,ir_dataset[i][0]) rs3 = random.uniform(1,ir_dataset[i][0]) @@ -1544,7 +1542,7 @@ def ibm_b8(flen, opcode, ops, seed=-1): rs2 = -1*(rs3 + ir_dataset[i][0])/rs1 elif flen == 64: rs2 = -1*(Decimal(rs3) + Decimal(ir_dataset[i][0]))/Decimal(rs1) - + if(flen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] @@ -1553,14 +1551,14 @@ def ibm_b8(flen, opcode, ops, seed=-1): x1 = rs1 x2 = rs2 x3 = rs3 - + if opcode in ['fadd','fsub','fmul','fdiv']: b8_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) elif opcode in 'fsqrt': b8_comb.append((floatingPoint_tohex(flen,float(rs2)),)) elif opcode in ['fmadd','fnmadd','fmsub','fnmsub']: b8_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - + coverpoints = [] k=0 for c in b8_comb: @@ -1580,7 +1578,7 @@ def ibm_b8(flen, opcode, ops, seed=-1): cvpt += ir_dataset[k][1] coverpoints.append(cvpt) k=k+1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B8 for '+opcode+' !' logger.info(mess) @@ -1605,18 +1603,18 @@ def ibm_b9(flen, opcode, ops): 7. A "checkerboard" pattern (for example 00110011... or 011011011...) 8. Long sequences of 1s 9. Long sequences of 0s - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode - + :type flen: int :type opcode: str :type ops: int - + Abstract Dataset Description: Operand1, Operand2 ∈ [A sequence of leading zeroes, A sequence of leading ones, A sequence of trailing zeroes, A sequence of trailing ones, A small number of 1s as compared to 0s, A small number of 0s as compared to 1s, A "checkerboard" pattern (for example 00110011... or 011011011...), Long sequences of 1s, Long sequences of 0s] - + Implementation: - The rs1 array is appended with the elements of flip types and then for each iteration, the respective sign, mantissa and exponent is computed. - A nested loop is initialized, assuming the rs1 mantissa as the base number and rs2 sign and rs2 exponent is obtained directly from the rs1 sign and rs1 exponent. Rs2 mantissa is calculated by adding the iteration number in the beginning of rs1 mantissa. This is done respectively for each repeating pattern. @@ -1625,14 +1623,14 @@ def ibm_b9(flen, opcode, ops): ''' opcode = opcode.split('.')[0] - + if flen == 32: flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm e_sz=8 elif flen == 64: flip_types = dzero + done + dminsubnorm + dmaxsubnorm + dminnorm + dmaxnorm e_sz=11 - + rs1 = [] b9_comb = [] comment = [] @@ -1644,9 +1642,9 @@ def ibm_b9(flen, opcode, ops): rs1_sgn = bin_val[0] rs1_exp = bin_val[1:e_sz+1] rs1_man = bin_val[e_sz+1:] - + for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn + rs2_sgn = rs1_sgn rs2_exp = rs1_exp rs2_man = '0'*j + rs1_man[j:] # Leading 0s rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) @@ -1654,28 +1652,28 @@ def ibm_b9(flen, opcode, ops): comment.append(' | Leading zeroes ---> rs2_man = '+rs2_man) b9_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(' | Leading zeroes ---> rs1_man = '+rs2_man) - + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b9_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(' | Leading ones ---> rs2_man = '+rs2_man) b9_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(' | Leading ones ---> rs1_man = '+rs2_man) - + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b9_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(' | Trailing zeroes ---> rs2_man = '+rs2_man) b9_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(' | Trailing zeroes ---> rs1_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b9_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(' | Trailing ones ---> rs2_man = '+rs2_man) b9_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(' | Trailing ones ---> rs1_man = '+rs2_man) - + for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): rs2_sgn = rs1_sgn rs2_exp = rs1_exp @@ -1685,14 +1683,14 @@ def ibm_b9(flen, opcode, ops): comment.append(' | Long sequence of ones ---> rs2_man = '+rs2_man) b9_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(' | Long sequence of ones ---> rs1_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b9_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(' | Long sequence of zeroes ---> rs2_man = '+rs2_man) b9_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(' | Long sequence of zeroes ---> rs1_man = '+rs2_man) - + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] for j in chkrbrd: rs2_sgn = rs1_sgn @@ -1706,7 +1704,7 @@ def ibm_b9(flen, opcode, ops): comment.append(' | Checkerboard pattern ---> rs2_man = '+rs2_man) b9_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(' | Checkerboard pattern ---> rs1_man = '+rs2_man) - + else: for i in range(len(flip_types)): rs1.append(flip_types[i]) @@ -1715,31 +1713,31 @@ def ibm_b9(flen, opcode, ops): rs1_sgn = bin_val[0] rs1_exp = bin_val[1:e_sz+1] rs1_man = bin_val[e_sz+1:] - + if rs1_sgn != '1': for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn + rs2_sgn = rs1_sgn rs2_exp = rs1_exp rs2_man = '0'*j + rs1_man[j:] # Leading 0s rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b9_comb.append((floatingPoint_tohex(flen,rs2),)) comment.append(' | Leading zeroes ---> rs1_man = '+rs2_man) - + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b9_comb.append((floatingPoint_tohex(flen,rs2),)) comment.append(' | Leading ones ---> rs1_man = '+rs2_man) - + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b9_comb.append((floatingPoint_tohex(flen,rs2),)) comment.append(' | Trailing zeroes ---> rs1_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b9_comb.append((floatingPoint_tohex(flen,rs2),)) comment.append(' | Trailing ones ---> rs1_man = '+rs2_man) - rs1_sgn = '0' + rs1_sgn = '0' for j in range(flen-e_sz-1-math.ceil(0.1*(flen-e_sz-1)), flen-e_sz-1): rs2_sgn = rs1_sgn rs2_exp = rs1_exp @@ -1747,12 +1745,12 @@ def ibm_b9(flen, opcode, ops): rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b9_comb.append((floatingPoint_tohex(flen,rs2),)) comment.append(' | Long sequence of ones ---> rs1_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b9_comb.append((floatingPoint_tohex(flen,rs2),)) comment.append(' | Long sequence of zeroes ---> rs1_man = '+rs2_man) - + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] for j in chkrbrd: rs2_sgn = rs1_sgn @@ -1764,7 +1762,7 @@ def ibm_b9(flen, opcode, ops): rs2 = fields_dec_converter(32,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b9_comb.append((floatingPoint_tohex(flen,rs2),)) comment.append(' | Checkerboard pattern ---> rs1_man = '+rs2_man) - + coverpoints = [] k = 0 for c in b9_comb: @@ -1783,14 +1781,14 @@ def ibm_b9(flen, opcode, ops): cvpt += comment[k] coverpoints.append(cvpt) k += 1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B9 for '+opcode+' !' logger.info(mess) coverpoints = comments_parser(coverpoints) return coverpoints - + def ibm_b10(flen, opcode, ops, N=-1, seed=-1): ''' IBM Model B10 Definition: @@ -1798,23 +1796,23 @@ def ibm_b10(flen, opcode, ops, N=-1, seed=-1): 1. A value smaller than -(p + 4) 2. All the values in the range [-(p + 4) , (p + 4)] 3. A value larger than (p + 4) - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param N: No. of sets of coverpoints to be generated. (Predefined to -1. Set to 2) :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :type N: int :param seed: int - + Abstract Dataset Description: Operand1 = [Random Number] Operand2 = [A value smaller than -(op1.exp+4), All values in the range [-(op1.exp+4), (op1.exp+4)], A value larger than +(op1.exp+4)] - + Implementation: - The exponent values of operand 1 and operand 2 obey the shift defined above. The mantissa value is randomly chosen and appended with the exponent derived. - Simultaneously, we convert these numbers into their corresponding IEEE754 floating point formats. @@ -1823,7 +1821,7 @@ def ibm_b10(flen, opcode, ops, N=-1, seed=-1): ''' opcode = opcode.split('.')[0] - + if flen == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) @@ -1832,10 +1830,10 @@ def ibm_b10(flen, opcode, ops, N=-1, seed=-1): maxdec = '1.7976931348623157e+308' maxnum = float.fromhex('0x1.fffffffffffffp+1023') exp_max = 1023 - + if N == -1: N = 2 - + if seed == -1: if opcode in 'fadd': random.seed(0) @@ -1843,30 +1841,30 @@ def ibm_b10(flen, opcode, ops, N=-1, seed=-1): random.seed(1) else: random.seed(seed) - + b10_comb = [] comment = [] for i in range(1,N): rs1 = random.uniform(1,maxnum/1000) rs2 = random.uniform(1,maxnum/1000) rs1_exp = str(rs1).split('e')[1] - + rs2_exp = -1*random.randrange(int(math.log(pow(10,int(rs1_exp)),2))+4, exp_max) rs2_num = str(rs2).split('e')[0] + 'e' + str(int(math.log(pow(2,int(rs2_exp)),10))) b10_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2_num)))) comment.append(' | Exponent = '+ str(rs2_exp) + ' --> A value smaller than -(p + 4)') - + for j in range(-(int(math.log(pow(10,int(rs1_exp)),2))+4),+(int(math.log(pow(10,int(rs1_exp)),2))+4)): rs2_num = str(rs2).split('e')[0] + 'e' + str(int(math.log(pow(2,int(j)),10))) b10_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2_num)))) comment.append(' | Exponent = '+ str(j) + ' --> Values in the range [-(p + 4) , (p + 4)]') - + rs2_exp = random.randrange(int(math.log(pow(10,int(rs1_exp)),2))+4, exp_max) rs2_num = str(rs2).split('e')[0] + 'e' + str(int(math.log(pow(2,int(rs2_exp)),10))) b10_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2_num)))) comment.append(' | Exponent = '+ str(rs2_exp) + ' --> A value larger than (p + 4)') - - coverpoints = [] + + coverpoints = [] k = 0 for c in b10_comb: cvpt = "" @@ -1884,14 +1882,14 @@ def ibm_b10(flen, opcode, ops, N=-1, seed=-1): cvpt += comment[k] coverpoints.append(cvpt) k += 1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B10 for '+opcode+' !' logger.info(mess) coverpoints = comments_parser(coverpoints) return coverpoints - + def ibm_b11(flen, opcode, ops, N=-1, seed=-1): ''' IBM Model B11 Definition: @@ -1902,20 +1900,20 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): Shift: as in model (B10) "Shift - Add" We test both effective operations: addition and subtraction. - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Operand1, Operand2 ∈ Abstract Dataset in B9 + Abstract Dataset in B10 - + Implementation: - A culmination of the techniques used in the implementations of Model B9 and Model B10 are used to form the dataset. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). @@ -1923,7 +1921,7 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): ''' opcode = opcode.split('.')[0] - + if flen == 32: flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm e_sz=8 @@ -1932,7 +1930,7 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): flip_types = dzero + done + dminsubnorm + dmaxsubnorm + dminnorm + dmaxnorm e_sz=11 exp_max = 1023 - + if seed == -1: if opcode in 'fadd': random.seed(0) @@ -1940,7 +1938,7 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): random.seed(1) else: random.seed(seed) - + rs1 = [] b11_comb = [] comment = [] @@ -1952,7 +1950,7 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): rs1_sgn = bin_val[0] rs1_exp = bin_val[1:e_sz+1] rs1_man = bin_val[e_sz+1:] - + if int(rs1_exp,2) < 4: rs2_exp = -127 else : rs2_exp = random.randrange(-127,int(rs1_exp,2)-131) comment_str = ' | Exponent = '+ str(rs2_exp) + ' --> A value smaller than (p - 4)' @@ -1960,35 +1958,35 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): if flen == 32: rs2_exp = '{:08b}'.format(rs2_exp) elif flen == 64: rs2_exp = '{:011b}'.format(rs2_exp) for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn + rs2_sgn = rs1_sgn rs2_man = '0'*j + rs1_man[j:] # Leading 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(comment_str + ' | Leading zeroes ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Leading zeroes ---> rs1_man = '+rs2_man) - + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(comment_str + ' | Leading ones ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Leading ones ---> rs1_man = '+rs2_man) - + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(comment_str + ' | Trailing zeroes ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Trailing zeroes ---> rs1_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(comment_str + ' | Trailing ones ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Trailing ones ---> rs1_man = '+rs2_man) - + for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): rs2_sgn = rs1_sgn rs2_exp = rs1_exp @@ -1998,14 +1996,14 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): comment.append(comment_str + ' | Long sequence of ones ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Long sequence of ones ---> rs1_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(comment_str + ' | Long sequence of zeroes ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Long sequence of zeroes ---> rs1_man = '+rs2_man) - + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] for j in chkrbrd: rs2_sgn = rs1_sgn @@ -2019,7 +2017,7 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): comment.append(comment_str + ' | Checkerboard pattern ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Checkerboard pattern ---> rs1_man = '+rs2_man) - + if int(rs1_exp,2) >= 250: rs2_exp = 127 else : rs2_exp = random.randrange(int(rs1_exp,2)-123,127) comment_str = ' | Exponent = '+ str(rs2_exp) + ' --> A value greater than (p + 4)' @@ -2027,35 +2025,35 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): if flen == 32: rs2_exp = '{:08b}'.format(rs2_exp) elif flen == 64: rs2_exp = '{:011b}'.format(rs2_exp) for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn + rs2_sgn = rs1_sgn rs2_man = '0'*j + rs1_man[j:] # Leading 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(comment_str + ' | Leading zeroes ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Leading zeroes ---> rs1_man = '+rs2_man) - + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(comment_str + ' | Leading ones ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Leading ones ---> rs1_man = '+rs2_man) - + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(comment_str + ' | Trailing zeroes ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Trailing zeroes ---> rs1_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(comment_str + ' | Trailing ones ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Trailing ones ---> rs1_man = '+rs2_man) - + for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): rs2_sgn = rs1_sgn rs2_exp = rs1_exp @@ -2065,14 +2063,14 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): comment.append(comment_str + ' | Long sequence of ones ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Long sequence of ones ---> rs1_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(comment_str + ' | Long sequence of zeroes ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Long sequence of zeroes ---> rs1_man = '+rs2_man) - + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] for j in chkrbrd: rs2_sgn = rs1_sgn @@ -2086,7 +2084,7 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): comment.append(comment_str + ' | Checkerboard pattern ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Checkerboard pattern ---> rs1_man = '+rs2_man) - + ul = int(rs1_exp,2)-123 ll = int(rs1_exp,2)-131 if int(rs1_exp,2) >= 250: ul = 127 @@ -2098,35 +2096,35 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): if flen == 32: rs2_exp = '{:08b}'.format(rs2_exp) elif flen == 64: rs2_exp = '{:011b}'.format(rs2_exp) for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn + rs2_sgn = rs1_sgn rs2_man = '0'*j + rs1_man[j:] # Leading 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(comment_str + ' | Leading zeroes ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Leading zeroes ---> rs1_man = '+rs2_man) - + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(comment_str + ' | Leading ones ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Leading ones ---> rs1_man = '+rs2_man) - + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(comment_str + ' | Trailing zeroes ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Trailing zeroes ---> rs1_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(comment_str + ' | Trailing ones ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Trailing ones ---> rs1_man = '+rs2_man) - + for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): rs2_sgn = rs1_sgn rs2_exp = rs1_exp @@ -2136,14 +2134,14 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): comment.append(comment_str + ' | Long sequence of ones ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Long sequence of ones ---> rs1_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b11_comb.append((rs1[i],floatingPoint_tohex(flen,rs2))) comment.append(comment_str + ' | Long sequence of zeroes ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Long sequence of zeroes ---> rs1_man = '+rs2_man) - + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] for j in chkrbrd: rs2_sgn = rs1_sgn @@ -2157,8 +2155,8 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): comment.append(comment_str + ' | Checkerboard pattern ---> rs2_man = '+rs2_man) b11_comb.append((floatingPoint_tohex(flen,rs2),rs1[i])) comment.append(comment_str + ' | Checkerboard pattern ---> rs1_man = '+rs2_man) - - coverpoints = [] + + coverpoints = [] k = 0 for c in b11_comb: cvpt = "" @@ -2176,7 +2174,7 @@ def ibm_b11(flen, opcode, ops, N=-1, seed=-1): cvpt += comment[k] coverpoints.append(cvpt) k += 1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B11 for '+opcode+' !' logger.info(mess) @@ -2191,21 +2189,21 @@ def ibm_b12(flen, opcode, ops, seed=-1): For the difference between the exponent of the intermediate result and the maximum between the exponents of the inputs, test all values in the range: [-p, +1]. - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Intermediate Result - Operand.Exp ∈ [-p, +1] Operand1 {operation} Operand2 = Intermediate Results - + Implementation: - The exponent values of operand 1 and operand 2 obey the shift defined above. The mantissa value is randomly chosen and appended with the exponent derived. - Simultaneously, we convert these numbers into their corresponding IEEE754 floating point formats. @@ -2213,7 +2211,7 @@ def ibm_b12(flen, opcode, ops, seed=-1): - Coverpoints are then appended with rounding mode ‘0’ for that particular opcode. ''' - + opcode = opcode.split('.')[0] getcontext().prec = 40 if flen == 32: @@ -2223,7 +2221,7 @@ def ibm_b12(flen, opcode, ops, seed=-1): minsubnorm = float.fromhex(ieee754_minsubnorm) ieee754_maxsubnorm = '0x0.7fffffp-126' maxsubnorm = float.fromhex(ieee754_maxsubnorm) - + elif flen == 64: ieee754_maxnorm = '0x1.fffffffffffffp+1023' maxnum = float.fromhex(ieee754_maxnorm) @@ -2231,7 +2229,7 @@ def ibm_b12(flen, opcode, ops, seed=-1): minsubnorm = float.fromhex(ieee754_minsubnorm) ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' maxsubnorm = float.fromhex(ieee754_maxsubnorm) - + if seed == -1: if opcode in 'fadd': random.seed(0) @@ -2239,9 +2237,9 @@ def ibm_b12(flen, opcode, ops, seed=-1): random.seed(1) else: random.seed(seed) - + b12_comb = [] - + for i in range(50): if opcode in 'fadd': rs1 = -1*random.uniform(minsubnorm,maxnum) elif opcode in 'fsub': rs1 = random.uniform(minsubnorm,maxnum) @@ -2256,19 +2254,19 @@ def ibm_b12(flen, opcode, ops, seed=-1): rs2 = rs1 - ir elif flen == 64: rs2 = Decimal(rs1) - Decimal(ir) - + if(flen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] elif(flen==64): x1 = rs1 x2 = rs2 - + if opcode in ['fadd','fsub']: b12_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - - coverpoints = [] - comment = ' | Add: Cancellation' + + coverpoints = [] + comment = ' | Add: Cancellation' for c in b12_comb: cvpt = "" for x in range(1, ops+1): @@ -2284,7 +2282,7 @@ def ibm_b12(flen, opcode, ops, seed=-1): cvpt += " and " cvpt += comment coverpoints.append(cvpt) - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B12 for '+opcode+' !' logger.info(mess) @@ -2297,28 +2295,28 @@ def ibm_b13(flen, opcode, ops, seed=-1): IBM Model B13 Definition: This model tests all combinations of cancellation values as in model (B12), with all possible unbiased exponent values of subnormal results. - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Intermediate Result - Operand.Exp ∈ [-p, +1] (The exponent for the intermediate result is chosen such that it is a subnormal number) Operand1 {operation} Operand2 = Intermediate Results - + Implementation: - The implementation procedure for Model B12 is repeated with a revised exponent range as defined above. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. ''' - + opcode = opcode.split('.')[0] getcontext().prec = 40 if flen == 32: @@ -2328,7 +2326,7 @@ def ibm_b13(flen, opcode, ops, seed=-1): minsubnorm = float.fromhex(ieee754_minsubnorm) ieee754_maxsubnorm = '0x0.7fffffp-126' maxsubnorm = float.fromhex(ieee754_maxsubnorm) - + elif flen == 64: ieee754_maxnorm = '0x1.fffffffffffffp+1023' maxnum = float.fromhex(ieee754_maxnorm) @@ -2336,7 +2334,7 @@ def ibm_b13(flen, opcode, ops, seed=-1): minsubnorm = float.fromhex(ieee754_minsubnorm) ieee754_maxsubnorm = '0x0.fffffffffffffp-1022' maxsubnorm = float.fromhex(ieee754_maxsubnorm) - + if seed == -1: if opcode in 'fadd': random.seed(0) @@ -2344,9 +2342,9 @@ def ibm_b13(flen, opcode, ops, seed=-1): random.seed(1) else: random.seed(seed) - + b13_comb = [] - + for i in range(200): rs1 = random.uniform(minsubnorm,maxnum) ir = random.uniform(minsubnorm,maxsubnorm) @@ -2360,19 +2358,19 @@ def ibm_b13(flen, opcode, ops, seed=-1): rs2 = rs1 - ir elif flen == 64: rs2 = Decimal(rs1) - Decimal(ir) - + if(flen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] elif(flen==64): x1 = rs1 x2 = rs2 - + if opcode in ['fadd','fsub']: b13_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) - - coverpoints = [] - comment = ' | Add: Cancellation ---> Subnormal result' + + coverpoints = [] + comment = ' | Add: Cancellation ---> Subnormal result' for c in b13_comb: cvpt = "" for x in range(1, 3): @@ -2388,7 +2386,7 @@ def ibm_b13(flen, opcode, ops, seed=-1): cvpt += " and " cvpt += comment coverpoints.append(cvpt) - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B13 for '+opcode+' !' logger.info(mess) @@ -2406,27 +2404,27 @@ def ibm_b14(flen, opcode, ops, N=-1, seed=-1): 1. A value smaller than -(2* p + 1) 2. All the values in the range [-(2*p +1), (p +1) ] 3. A value larger than (p + 1) - + We test both effective operations: addition and subtraction. The end values tested are selected to be greater by one than the largest possible shift in which the smaller addend may affect the result. - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param N: No. of sets of coverpoints to be generated. (Predefined to -1. Set to 2) :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :type N: int :param seed: int - + Abstract Dataset Description: Shift between the addends of the multiply-add operation = [ A value smaller than -(2* p + 1), All the values in the range [-(2*p +1), (p +1), A value larger than (p + 1) ] → Condition 1 Operand 1, 2 = Random Operand 3 = Condition 1 - + Implementation: - The shift between the two addends are constrained by the conditions mentioned in the dataset above. - Operands 1 and 2 are randomly obtained. But Operand 3 is obtained by ensuring the shift conditions. @@ -2435,14 +2433,14 @@ def ibm_b14(flen, opcode, ops, N=-1, seed=-1): ''' opcode = opcode.split('.')[0] - + if flen == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) exp_max = 127 mant_bits = 23 limnum = maxnum - + elif flen == 64: maxdec = '1.7976931348623157e+308' maxnum = float.fromhex('0x1.fffffffffffffp+1023') @@ -2450,10 +2448,10 @@ def ibm_b14(flen, opcode, ops, N=-1, seed=-1): ieee754_limnum = '0x1.fffffffffffffp+507' mant_bits = 52 limnum = float.fromhex(ieee754_limnum) - + if N == -1: N = 2 - + if seed == -1: if opcode in 'fmadd': random.seed(0) @@ -2465,7 +2463,7 @@ def ibm_b14(flen, opcode, ops, N=-1, seed=-1): random.seed(3) else: random.seed(seed) - + b14_comb = [] comment = [] for i in range(1,N): @@ -2474,14 +2472,14 @@ def ibm_b14(flen, opcode, ops, N=-1, seed=-1): rs3 = random.uniform(1,limnum) mul_exp = int(str(rs1*rs2).split('e')[1]) mul_exp = int(math.log(pow(2,int(mul_exp)),10)) - + if mul_exp-((2*mant_bits)+1) > -1*exp_max: rs3_exp = random.randrange(-1*exp_max,mul_exp-((2*mant_bits)+1)) rs3_num = float.hex(float(str(rs3).split('e')[0])).split('p')[0]+'p'+str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+rs3_exp) rs3_num = float.fromhex(rs3_num) b14_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3_num)))) comment.append(' | Multiplicand Exponent = '+str(mul_exp)+', Addend exponent = '+ str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+rs3_exp) + ' --> Difference smaller than -(2*p + 1)') - + if mul_exp-((2*mant_bits)+1) < -1*exp_max: exp1 = -1*exp_max else: exp1 = mul_exp-((2*mant_bits)+1) if mul_exp+mant_bits+1 > exp_max: exp2 = exp_max @@ -2491,14 +2489,14 @@ def ibm_b14(flen, opcode, ops, N=-1, seed=-1): rs3_num = float.fromhex(rs3_num) b14_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3_num)))) comment.append(' | Multiplicand Exponent = '+str(mul_exp)+', Addend exponent = '+ str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+j) + ' --> Values in the range [-(2*p + 1) , (p + 1)]') - + rs3_exp = random.randrange(exp2, exp_max) rs3_num = float.hex(float(str(rs3).split('e')[0])).split('p')[0]+'p'+str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+rs3_exp) rs3_num = float.fromhex(rs3_num) b14_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3_num)))) comment.append(' | Multiplicand Exponent = '+str(mul_exp)+', Addend exponent = '+ str(int(float.hex(float(str(rs3).split('e')[0])).split('p')[1])+rs3_exp) + ' --> A value larger than (p + 1)') - - coverpoints = [] + + coverpoints = [] k = 0 for c in b14_comb: cvpt = "" @@ -2516,7 +2514,7 @@ def ibm_b14(flen, opcode, ops, N=-1, seed=-1): cvpt += comment[k] coverpoints.append(cvpt) k += 1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B14 for '+opcode+' !' logger.info(mess) @@ -2532,31 +2530,31 @@ def ibm_b15(flen, opcode, ops, N=-1, seed=-1): For the significand of the addend and for the multiplication result we take the cases defined in model (B9) "Special Significands on Inputs" For the shift we take the cases defined in model (B14) "Shift – multiply-add". - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Operand 1, 2 = Random Operand 3 ∈ Abstract Dataset in B9 + Abstract Dataset in B14 - + Implementation: - Here the condition is imposed that if the value of the ops variable is 3, then each of the elements in the flip types is iterated and split into their respective sign, mantissa and exponent part. - A mul variable is initialized and parsed to the field_dec_converter for each rs1 value in the list. Next the loop is run for the mantissa parts generated for rs1 values, where it is checked for certain patterns like the leading 0’s, leading 1’s, trailing 0’s and trailing 1’s. - - The checkerboard list is declared with the probable sequences for rs2. Here the sign and exponent are extracted from the rs1 values. Mantissa part is derived from the checkerboard list. Consecutively, if the flen value differs, then the range available varies. + - The checkerboard list is declared with the probable sequences for rs2. Here the sign and exponent are extracted from the rs1 values. Mantissa part is derived from the checkerboard list. Consecutively, if the flen value differs, then the range available varies. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with rounding mode “0” for that particular opcode. ''' opcode = opcode.split('.')[0] - + if flen == 32: flip_types = fzero + fone + fminsubnorm + fmaxsubnorm + fminnorm + fmaxnorm e_sz=8 @@ -2576,7 +2574,7 @@ def ibm_b15(flen, opcode, ops, N=-1, seed=-1): ieee754_limnum = '0x1.fffffffffffffp+507' mant_bits = 52 limnum = float.fromhex(ieee754_limnum) - + if seed == -1: if opcode in 'fmadd': random.seed(0) @@ -2585,10 +2583,10 @@ def ibm_b15(flen, opcode, ops, N=-1, seed=-1): elif opcode in 'fmsub': random.seed(2) elif opcode in 'fnmsub': - random.seed(3) + random.seed(3) else: random.seed(seed) - + rs1 = [] b15_comb = [] comment = [] @@ -2600,42 +2598,42 @@ def ibm_b15(flen, opcode, ops, N=-1, seed=-1): rs1_sgn = bin_val[0] rs1_exp = bin_val[1:e_sz+1] rs1_man = bin_val[e_sz+1:] - + if flen == 32: if int(rs1_exp,2) < 65: rs2_exp = 0 - else : rs2_exp = random.randrange(0,int(rs1_exp,2)-65) + else : rs2_exp = random.randrange(0,int(rs1_exp,2)-65) comment_str = ' | Exponent = '+ str(rs2_exp-127) + ' --> Difference smaller than -(2p + 1)' rs2_exp = '{:08b}'.format(rs2_exp) - elif flen == 64: + elif flen == 64: if int(rs1_exp,2) < 129: rs2_exp = 0 - else : rs2_exp = random.randrange(0,int(rs1_exp,2)-129) + else : rs2_exp = random.randrange(0,int(rs1_exp,2)-129) comment_str = ' | Exponent = '+ str(rs2_exp-1023) + ' --> Difference smaller than -(2p + 1)' rs2_exp = '{:011b}'.format(rs2_exp) mul = fields_dec_converter(flen,rs1[i]) rs1_act = random.uniform(1,limnum) rs2_act = mul/rs1_act for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn + rs2_sgn = rs1_sgn rs2_man = '0'*j + rs1_man[j:] # Leading 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Leading zeroes ---> rs3_man = '+rs2_man) - + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Leading ones ---> rs3_man = '+rs2_man) - + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Trailing zeroes ---> rs3_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Trailing ones ---> rs3_man = '+rs2_man) - + for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): rs2_sgn = rs1_sgn rs2_exp = rs1_exp @@ -2643,12 +2641,12 @@ def ibm_b15(flen, opcode, ops, N=-1, seed=-1): rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Long sequence of ones ---> rs3_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Long sequence of zeroes ---> rs3_man = '+rs2_man) - + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] for j in chkrbrd: rs2_sgn = rs1_sgn @@ -2660,42 +2658,42 @@ def ibm_b15(flen, opcode, ops, N=-1, seed=-1): rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Checkerboard pattern ---> rs3_man = '+rs2_man) - + if flen == 32: if int(rs1_exp,2) > 222: rs2_exp = 255 - else : rs2_exp = random.randrange(int(rs1_exp,2)+33, 255) + else : rs2_exp = random.randrange(int(rs1_exp,2)+33, 255) comment_str = ' | Exponent = '+ str(rs2_exp-127) + ' --> Difference greater than (p + 1)' rs2_exp = '{:08b}'.format(rs2_exp) - elif flen == 64: + elif flen == 64: if int(rs1_exp,2) > 958: rs2_exp = 1023 - else : rs2_exp = random.randrange(int(rs1_exp,2)+65, 1023) + else : rs2_exp = random.randrange(int(rs1_exp,2)+65, 1023) comment_str = ' | Exponent = '+ str(rs2_exp-1023) + ' --> Difference greater than (p + 1)' rs2_exp = '{:011b}'.format(rs2_exp) mul = fields_dec_converter(flen,rs1[i]) rs1_act = random.uniform(1,limnum) rs2_act = mul/rs1_act for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn + rs2_sgn = rs1_sgn rs2_man = '0'*j + rs1_man[j:] # Leading 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Leading zeroes ---> rs3_man = '+rs2_man) - + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Leading ones ---> rs3_man = '+rs2_man) - + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Trailing zeroes ---> rs3_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Trailing ones ---> rs3_man = '+rs2_man) - + for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): rs2_sgn = rs1_sgn rs2_exp = rs1_exp @@ -2703,12 +2701,12 @@ def ibm_b15(flen, opcode, ops, N=-1, seed=-1): rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Long sequence of ones ---> rs3_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Long sequence of zeroes ---> rs3_man = '+rs2_man) - + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] for j in chkrbrd: rs2_sgn = rs1_sgn @@ -2720,13 +2718,13 @@ def ibm_b15(flen, opcode, ops, N=-1, seed=-1): rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Checkerboard pattern ---> rs3_man = '+rs2_man) - + if flen == 32: ul = int(rs1_exp,2)+33 ll = int(rs1_exp,2)-65 if int(rs1_exp,2) >= 222: ul = 255 if int(rs1_exp,2) < 65: ll = 0 - elif flen == 64: + elif flen == 64: ul = int(rs1_exp,2)+65 ll = int(rs1_exp,2)-129 if int(rs1_exp,2) >= 958: ul = 1023 @@ -2736,35 +2734,35 @@ def ibm_b15(flen, opcode, ops, N=-1, seed=-1): if flen == 32: comment_str = ' | Exponent = '+ str(rs2_exp-127) + ' --> Difference between -(2p+1) and (p+1)' rs2_exp = '{:08b}'.format(rs2_exp) - elif flen == 64: + elif flen == 64: comment_str = ' | Exponent = '+ str(rs2_exp-1023) + ' --> Difference between -(2p+1) and (p+1)' rs2_exp = '{:011b}'.format(rs2_exp) mul = fields_dec_converter(flen,rs1[i]) rs1_act = random.uniform(1,limnum) rs2_act = mul/rs1_act - + for j in range(len(rs1_man)): - rs2_sgn = rs1_sgn + rs2_sgn = rs1_sgn rs2_man = '0'*j + rs1_man[j:] # Leading 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Leading zeroes ---> rs3_man = '+rs2_man) - + rs2_man = '1'*j + '0'*(len(rs1_man)-j) # Leading 1s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Leading ones ---> rs3_man = '+rs2_man) - + rs2_man = rs1_man[0:j] + '0'*(len(rs1_man)-j) # Trailing 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Trailing zeroes ---> rs3_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Trailing 1s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Trailing ones ---> rs3_man = '+rs2_man) - + for j in range(len(rs1_man)-math.ceil(0.1*len(rs1_man)),len(rs1_man)): rs2_sgn = rs1_sgn rs2_exp = rs1_exp @@ -2772,12 +2770,12 @@ def ibm_b15(flen, opcode, ops, N=-1, seed=-1): rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Long sequence of ones ---> rs3_man = '+rs2_man) - + rs2_man = '0'*j + '1'*(len(rs1_man)-j) # Long sequence of 0s rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Long sequence of zeroes ---> rs3_man = '+rs2_man) - + chkrbrd = ['011','110','0011','1100','0111','1000','010','101','0110','1001'] for j in chkrbrd: rs2_sgn = rs1_sgn @@ -2789,8 +2787,8 @@ def ibm_b15(flen, opcode, ops, N=-1, seed=-1): rs2 = fields_dec_converter(flen,'0x'+hex(int('1'+rs2_sgn+rs2_exp+rs2_man,2))[3:]) b15_comb.append((floatingPoint_tohex(flen,float(rs1_act)),floatingPoint_tohex(flen,float(rs2_act)),floatingPoint_tohex(flen,float(rs2)))) comment.append(comment_str + ' | Checkerboard pattern ---> rs3_man = '+rs2_man) - - coverpoints = [] + + coverpoints = [] k = 0 for c in b15_comb: cvpt = "" @@ -2808,7 +2806,7 @@ def ibm_b15(flen, opcode, ops, N=-1, seed=-1): cvpt += comment[k] coverpoints.append(cvpt) k += 1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B15 for '+opcode+' !' logger.info(mess) @@ -2824,21 +2822,21 @@ def ibm_b16(flen, opcode, ops, seed=-1): maximum between the exponents of the addend and the multiplication result, test all values in the range: [-(2 * p + 1), 1]. - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Intermediate Result.exp - max(addend.exp, multiplication result.exp) ∈ [-(2 * p + 1), 1] → Condition 1 Operand 1 {operation 1} Operand 2 {operation 2} Operand 3 = Condition 1 - + Implementation: - Random values of operands 1 and 2 are obtained from the random library. - Since the objective of the test is to cancel the operands among each other constrained by the above condition, the intermediate result is calculated by the multiplication of operand 1 and 2. @@ -2846,7 +2844,7 @@ def ibm_b16(flen, opcode, ops, seed=-1): - Coverpoints are then appended with rounding mode “0” for that particular opcode. ''' - + opcode = opcode.split('.')[0] getcontext().prec = 40 if flen == 32: @@ -2857,7 +2855,7 @@ def ibm_b16(flen, opcode, ops, seed=-1): ieee754_maxsubnorm = '0x0.7fffffp-126' maxsubnorm = float.fromhex(ieee754_maxsubnorm) limnum = maxnum - + elif flen == 64: ieee754_maxnorm = '0x1.fffffffffffffp+1023' maxnum = float.fromhex(ieee754_maxnorm) @@ -2867,7 +2865,7 @@ def ibm_b16(flen, opcode, ops, seed=-1): maxsubnorm = float.fromhex(ieee754_maxsubnorm) ieee754_limnum = '0x1.fffffffffffffp+507' limnum = float.fromhex(ieee754_limnum) - + if seed == -1: if opcode in 'fmadd': random.seed(0) @@ -2879,9 +2877,9 @@ def ibm_b16(flen, opcode, ops, seed=-1): random.seed(3) else: random.seed(seed) - + b17_comb = [] - + for i in range(200): rs1 = random.uniform(minsubnorm,limnum) rs2 = random.uniform(minsubnorm,limnum) @@ -2907,20 +2905,20 @@ def ibm_b16(flen, opcode, ops, seed=-1): rs3 = ir + rs1*rs2 elif flen == 64: rs3 = Decimal(ir) + Decimal(rs1)*Decimal(rs2) - + if(flen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] elif(flen==64): x1 = rs1 x2 = rs2 - + result = [] if opcode in ['fmadd','fmsub','fnmadd','fnmsub']: b17_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - - coverpoints = [] - comment = ' | Multiply-Add: Cancellation' + + coverpoints = [] + comment = ' | Multiply-Add: Cancellation' for c in b17_comb: cvpt = "" for x in range(1, 4): @@ -2936,7 +2934,7 @@ def ibm_b16(flen, opcode, ops, seed=-1): cvpt += " and " cvpt += comment coverpoints.append(cvpt) - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B16 for '+opcode+' !' logger.info(mess) @@ -2949,29 +2947,29 @@ def ibm_b17(flen, opcode, ops, seed=-1): IBM Model B17 Definition: This model tests all combinations of cancellation values as in model (B16), with all possible unbiased exponent values of subnormal results. - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Intermediate Result.exp - max(addend.exp, multiplication result.exp) ∈ [-(2 * p + 1), 1] → Condition 1 (Exponents are subnormal) Operand 1 {operation 1} Operand 2 {operation 2} Operand 3 = Condition 1 - + Implementation: - It functions the same as model B16 with calculating the additional unbiased exponent values of subnormal results. - - Operands 1 and 2 are randomly initialized in the range and the subsequent operator value is found. + - Operands 1 and 2 are randomly initialized in the range and the subsequent operator value is found. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with rounding mode “0” for that particular opcode. ''' - + opcode = opcode.split('.')[0] getcontext().prec = 40 if flen == 32: @@ -2982,7 +2980,7 @@ def ibm_b17(flen, opcode, ops, seed=-1): ieee754_maxsubnorm = '0x0.7fffffp-126' maxsubnorm = float.fromhex(ieee754_maxsubnorm) limnum = maxnum - + elif flen == 64: ieee754_maxnorm = '0x1.fffffffffffffp+1023' maxnum = float.fromhex(ieee754_maxnorm) @@ -2992,7 +2990,7 @@ def ibm_b17(flen, opcode, ops, seed=-1): maxsubnorm = float.fromhex(ieee754_maxsubnorm) ieee754_limnum = '0x1.fffffffffffffp+507' limnum = float.fromhex(ieee754_limnum) - + if seed == -1: if opcode in 'fmadd': random.seed(0) @@ -3004,9 +3002,9 @@ def ibm_b17(flen, opcode, ops, seed=-1): random.seed(3) else: random.seed(seed) - + b17_comb = [] - + for i in range(200): rs1 = random.uniform(minsubnorm,limnum) rs2 = random.uniform(minsubnorm,limnum) @@ -3033,20 +3031,20 @@ def ibm_b17(flen, opcode, ops, seed=-1): rs3 = ir + rs1*rs2 elif flen == 64: rs3 = Decimal(ir) + Decimal(rs1)*Decimal(rs2) - + if(flen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] elif(flen==64): x1 = rs1 x2 = rs2 - + result = [] if opcode in ['fmadd','fmsub','fnmadd','fnmsub']: b17_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) - - coverpoints = [] - comment = ' | Multiply-Add: Cancellation ---> Subnormal result ' + + coverpoints = [] + comment = ' | Multiply-Add: Cancellation ---> Subnormal result ' for c in b17_comb: cvpt = "" for x in range(1, 4): @@ -3062,7 +3060,7 @@ def ibm_b17(flen, opcode, ops, seed=-1): cvpt += " and " cvpt += comment coverpoints.append(cvpt) - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B17 for '+opcode+' !' logger.info(mess) @@ -3079,17 +3077,17 @@ def ibm_b18(flen, opcode, ops, seed=-1): 1. Product: Enumerate all options for LSB, Guard and Sticky bit. Intermediate Result: Exact (Guard and Sticky are zero). 2. Product: Take overflow values from (B4) "Overflow". Intermediate Result: No overflow 3. Product: Take underflow values from model (B5) "Underflow". Intermediate Result: No underflow - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Implementation: - Firstly, cancellation using the B3 model as base is performed. - Next model is the replica of the B4 model which takes into account the overflow of value for guard, round and sticky bits @@ -3100,7 +3098,7 @@ def ibm_b18(flen, opcode, ops, seed=-1): ''' opcode = opcode.split('.')[0] getcontext().prec = 40 - + if seed == -1: if opcode in 'fmadd': random.seed(0) @@ -3112,7 +3110,7 @@ def ibm_b18(flen, opcode, ops, seed=-1): random.seed(3) else: random.seed(seed) - + # Cancellation of B3 if flen == 32: ieee754_maxnorm = '0x1.7fffffp+127' @@ -3120,7 +3118,7 @@ def ibm_b18(flen, opcode, ops, seed=-1): ieee754_num = [] lsb = [] for i in fsubnorm+fnorm: - if int(i[-1],16)%2 == 1: + if int(i[-1],16)%2 == 1: lsb.append('1') lsb.append('1') else: @@ -3133,7 +3131,7 @@ def ibm_b18(flen, opcode, ops, seed=-1): else: ieee754_num.append(float_val.split('p')[0][0:11]+'p'+float_val.split('p')[1]) ieee754_num.append(float_val.split('p')[0][1:11]+'p'+float_val.split('p')[1]) - + ir_dataset = [] for k in range(len(ieee754_num)): for i in range(2,16,2): @@ -3141,10 +3139,10 @@ def ibm_b18(flen, opcode, ops, seed=-1): if ieee754_num[k][0] == '-': sign = '1' else: sign = '0' ir_dataset.append([ieee754_num[k].split('p')[0]+str(i)+'p'+ieee754_num[k].split('p')[1],' | Guard = '+grs[0]+' Sticky = '+grs[2]+' Sign = '+sign+' LSB = '+lsb[k] + ': Multiply add - Guard & Sticky Cancellation']) - + for i in range(len(ir_dataset)): ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) - + elif flen == 64: maxdec = '1.7976931348623157e+308' maxnum = float.fromhex('0x1.fffffffffffffp+1023') @@ -3164,7 +3162,7 @@ def ibm_b18(flen, opcode, ops, seed=-1): 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): @@ -3172,9 +3170,9 @@ def ibm_b18(flen, opcode, ops, seed=-1): if ieee754_num[k][0] == '-': sign = '1' else: sign = '0' ir_dataset.append([str(Decimal(ieee754_num[k].split('e')[0])+Decimal(pow(i*16,-14)))+'e'+ieee754_num[k].split('e')[1],' | Guard = '+grs[0]+' Sticky = '+grs[2]+' Sign = '+sign+' LSB = '+lsb[k] + ': Multiply add - Guard & Sticky Cancellation']) - + b18_comb = [] - + for i in range(len(ir_dataset)): rs1 = random.uniform(1,maxnum) res = '0x1.7ffff0p+100' @@ -3207,7 +3205,7 @@ def ibm_b18(flen, opcode, ops, seed=-1): elif flen == 64: rs2 = -1*Decimal(ir_dataset[i][0])/Decimal(rs1) rs3 = Decimal(res) - Decimal(ir_dataset[i][0]) - + if(flen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] @@ -3216,11 +3214,11 @@ def ibm_b18(flen, opcode, ops, seed=-1): x1 = rs1 x2 = rs2 x3 = rs3 - + if opcode in ['fmadd','fnmadd','fmsub','fnmsub']: b18_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) ir_dataset1 = ir_dataset - + # Cancellation of B4 if flen == 32: ieee754_maxnorm_p = '0x1.7fffffp+127' @@ -3242,7 +3240,7 @@ def ibm_b18(flen, opcode, ops, seed=-1): grs = '{:04b}'.format(i) ir_dataset.append([str(Decimal(maxdec_p.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+maxdec_p.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm + '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Overflow Cancellation']) ir_dataset.append([str(Decimal(maxdec_n.split('e')[0])+Decimal(pow(i*16,-14)))+'e'+maxdec_n.split('e')[1],' | Guard = '+grs[0]+' Round = '+grs[1]+' Sticky = '+grs[2]+' --> Maxnorm - '+str(int(grs[0:3],2))+' ulp' + ': Multiply add - Overflow Cancellation']) - + for i in range(len(ir_dataset)): rs1 = random.uniform(1,maxnum) res = '0x1.7ffff0p+100' @@ -3275,7 +3273,7 @@ def ibm_b18(flen, opcode, ops, seed=-1): elif flen == 64: rs2 = -1*Decimal(ir_dataset[i][0])/Decimal(rs1) rs3 = Decimal(res) - Decimal(ir_dataset[i][0]) - + if(flen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] @@ -3284,11 +3282,11 @@ def ibm_b18(flen, opcode, ops, seed=-1): x1 = rs1 x2 = rs2 x3 = rs3 - + if opcode in ['fmadd','fnmadd','fmsub','fnmsub']: b18_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) ir_dataset2 = ir_dataset - + # Cancellation of B5 if flen == 32: ieee754_maxnorm = '0x1.7fffffp+127' @@ -3306,7 +3304,7 @@ def ibm_b18(flen, opcode, ops, seed=-1): for i in range(n): ir_dataset[i][0] = float.fromhex(ir_dataset[i][0]) ir_dataset.append([-1*ir_dataset[i][0],ir_dataset[i][1]]) - + elif flen == 64: maxdec = '1.7976931348623157e+308' maxnum = float.fromhex('0x1.fffffffffffffp+1023') @@ -3324,7 +3322,7 @@ def ibm_b18(flen, opcode, ops, seed=-1): n = len(ir_dataset) for i in range(n): ir_dataset.append(['-'+ir_dataset[i][0],ir_dataset[i][1]]) - + for i in range(len(ir_dataset)): rs1 = random.uniform(1,maxnum) res = '0x1.7ffff0p+100' @@ -3357,7 +3355,7 @@ def ibm_b18(flen, opcode, ops, seed=-1): elif flen == 64: rs2 = -1*Decimal(ir_dataset[i][0])/Decimal(rs1) rs3 = Decimal(res) - Decimal(ir_dataset[i][0]) - + if(flen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] @@ -3366,14 +3364,14 @@ def ibm_b18(flen, opcode, ops, seed=-1): x1 = rs1 x2 = rs2 x3 = rs3 - + if opcode in ['fmadd','fnmadd','fmsub','fnmsub']: b18_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)),floatingPoint_tohex(flen,float(rs3)))) ir_dataset3 = ir_dataset - - ir_dataset = ir_dataset1 + ir_dataset2 + ir_dataset3 + + ir_dataset = ir_dataset1 + ir_dataset2 + ir_dataset3 coverpoints = [] - k = 0 + k = 0 for c in b18_comb: cvpt = "" for x in range(1, ops+1): @@ -3390,7 +3388,7 @@ def ibm_b18(flen, opcode, ops, seed=-1): cvpt += ir_dataset[k][1] coverpoints.append(cvpt) k=k+1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B18 for '+opcode+' !' logger.info(mess) @@ -3409,30 +3407,30 @@ def ibm_b19(flen, opcode, ops, seed=-1): -Normal -Normal =0 =0 +SubNormal +SubNormal <0 <0 -SubNormal -SubNormal - 0 0 - - :param flen: Size of the floating point registers + 0 0 + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Operand1 {operation} Operand2 = Derived from the table above - + Implementation: - - Normal (positive and negative), subnormal (positive and negative) arrays are randomly initialized within their respectively declared ranges. + - Normal (positive and negative), subnormal (positive and negative) arrays are randomly initialized within their respectively declared ranges. - The difference between exponents and significands are formed as per the conditions in the table. - All possible combinations of the table are used in creating the test-cases. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. ''' - + opcode = opcode.split('.')[0] getcontext().prec = 40 if flen == 32: @@ -3443,7 +3441,7 @@ def ibm_b19(flen, opcode, ops, seed=-1): ieee754_maxsubnorm = '0x0.7fffffp-126' maxsubnorm = float.fromhex(ieee754_maxsubnorm) limnum = maxnum - + elif flen == 64: ieee754_maxnorm = '0x1.fffffffffffffp+1023' maxnum = float.fromhex(ieee754_maxnorm) @@ -3453,7 +3451,7 @@ def ibm_b19(flen, opcode, ops, seed=-1): maxsubnorm = float.fromhex(ieee754_maxsubnorm) ieee754_limnum = '0x1.fffffffffffffp+507' limnum = float.fromhex(ieee754_limnum) - + if seed == -1: if opcode in 'fmin': random.seed(0) @@ -3467,7 +3465,7 @@ def ibm_b19(flen, opcode, ops, seed=-1): random.seed(3) else: random.seed(seed) - + b19_comb = [] comment = [] normal = [] @@ -3480,10 +3478,10 @@ def ibm_b19(flen, opcode, ops, seed=-1): normal_neg.append([random.uniform(-1*maxnum,-1),'-Normal']) sub_normal.append([random.uniform(minsubnorm,maxsubnorm),'Subnormal']) sub_normal_neg.append([random.uniform(-1*maxsubnorm,-1*minsubnorm),'-Subnormal']) - - all_num = normal + normal_neg + sub_normal + sub_normal_neg + zero + + all_num = normal + normal_neg + sub_normal + sub_normal_neg + zero for i in all_num: - for j in all_num: + for j in all_num: if i[0] != 0: i_sig = str(i[0]).split('e')[0] i_exp = str(i[0]).split('e')[1] @@ -3497,9 +3495,9 @@ def ibm_b19(flen, opcode, ops, seed=-1): j_sig = '0' j_exp = '0' if float(i_sig) >= float(j_sig): sig_sign = '>=' - else: sig_sign = '<' + else: sig_sign = '<' if float(i_exp) >= float(j_exp): exp_sign = '>=' - else: exp_sign = '<' + else: exp_sign = '<' rs1 = float(i_sig+'e'+i_exp) rs2 = float(j_sig+'e'+j_exp) b19_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) @@ -3524,16 +3522,21 @@ def ibm_b19(flen, opcode, ops, seed=-1): rs2 = float(i_sig+'e'+i_exp) b19_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) comment.append(' | rs1 --> ' + i[1] + ', rs2 --> ' + i[1] + ', rs1_sigificand = rs2_significand, rs1_exp = rs2_exp') - - coverpoints = [] - k = 0 + + coverpoints = [] + k = 0 for c in b19_comb: cvpt = "" for x in range(1, 3): # cvpt += 'rs'+str(x)+'_val=='+str(c[x-1]) # uncomment this if you want rs1_val instead of individual fields cvpt += (extract_fields(flen,c[x-1],str(x))) cvpt += " and " - cvpt += 'rm_val == 0' + if opcode in ["fadd","fsub","fmul","fdiv","fsqrt","fmadd","fnmadd","fmsub","fnmsub","fcvt","fmv","fle","fmv","fmin","fsgnj"]: + cvpt += 'rm_val == 0' + elif opcode in ["fclass","flt","fmax","fsgnjn"]: + cvpt += 'rm_val == 1' + elif opcode in ["feq","flw","fsw","fsgnjx"]: + cvpt += 'rm_val == 2' cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -3543,7 +3546,7 @@ def ibm_b19(flen, opcode, ops, seed=-1): cvpt += comment[k] coverpoints.append(cvpt) k += 1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B19 for '+opcode+' !' logger.info(mess) @@ -3555,47 +3558,47 @@ def ibm_b20(flen, opcode, ops, seed=-1): ''' IBM Model B20 Definition: This model will create test-cases such that the significand of the intermediate results will cover each of the following patterns: - + Mask on the intermediate result significand (excluding the leading “1” ) .. code-block:: xxx...xxx10 xxx...xx100 - xxx...x1000 + xxx...x1000 … - xx1...00000 - x10...00000 + xx1...00000 + x10...00000 100...00000 000...00000 - - The sticky bit of the intermediate result should always be 0. In case of the remainder operation, we will look at the result of the division in order to find the interesting test-cases. + + The sticky bit of the intermediate result should always be 0. In case of the remainder operation, we will look at the result of the division in order to find the interesting test-cases. Operation: Divide, Square-root. - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Intermediate Results = [Random bits are taken initially to form xxx...xxx10. The pattern described above is then formed] Operand1 {operation} Operand2 = Intermediate Results - + Implementation: - A loop is initiated where random bits are obtained for which the subsequent sign, exponent is calculated for the intermediate value and stored in the ir_dataset. - - Operand 1 (rs1) is randomly initialized in the range (1, limnum) and the subsequent operator value is found. + - Operand 1 (rs1) is randomly initialized in the range (1, limnum) and the subsequent operator value is found. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. ''' opcode = opcode.split('.')[0] getcontext().prec = 60 - + if seed == -1: if opcode in 'fdiv': random.seed(1) @@ -3603,7 +3606,7 @@ def ibm_b20(flen, opcode, ops, seed=-1): random.seed(2) else: random.seed(seed) - + if flen == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) @@ -3621,17 +3624,17 @@ def ibm_b20(flen, opcode, ops, seed=-1): bits = '0'*front_zero + bits trailing_zero = 22-i sig = bits+'1'+'0'*trailing_zero - + exp = random.getrandbits(8) exp = '{:08b}'.format(exp) - + sgn = random.getrandbits(1) sgn = '{:01b}'.format(sgn) - + ir_bin = ('0b'+sgn+exp+sig) ir = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) ir_dataset.append([ir, ' | Intermediate result significand: ' + sig + ' Pattern: ' + 'X'*i + '1' + '0'*trailing_zero]) - + sig = '1'+'0'*22 exp = random.getrandbits(8) exp = '{:08b}'.format(exp) @@ -3640,7 +3643,7 @@ def ibm_b20(flen, opcode, ops, seed=-1): ir_bin = ('0b'+sgn+exp+sig) ir = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) ir_dataset.append([ir, 'Intermediate result significand: '+ sig + ' Pattern: ' + '1' + '0'*22]) - + sig = '0'*23 exp = random.getrandbits(8) exp = '{:08b}'.format(exp) @@ -3649,7 +3652,7 @@ def ibm_b20(flen, opcode, ops, seed=-1): ir_bin = ('0b'+sgn+exp+sig) ir = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) ir_dataset.append([ir, 'Intermediate result significand: '+ sig + ' Pattern: ' + '0' + '0'*22]) - + elif flen == 64: ieee754_maxnorm = '0x1.fffffffffffffp+1023' maxnum = float.fromhex(ieee754_maxnorm) @@ -3669,17 +3672,17 @@ def ibm_b20(flen, opcode, ops, seed=-1): bits = '0'*front_zero + bits trailing_zero = 51-i sig = bits+'1'+'0'*trailing_zero - + exp = random.getrandbits(11) exp = '{:011b}'.format(exp) - + sgn = random.getrandbits(1) sgn = '{:01b}'.format(sgn) - + ir_bin = ('0b'+sgn+exp+sig) ir = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) ir_dataset.append([ir, ' | Intermediate result significand: ' + sig + ' Pattern: ' + 'X'*i + '1' + '0'*trailing_zero]) - + sig = '1'+'0'*51 exp = random.getrandbits(8) exp = '{:08b}'.format(exp) @@ -3688,7 +3691,7 @@ def ibm_b20(flen, opcode, ops, seed=-1): ir_bin = ('0b'+sgn+exp+sig) ir = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) ir_dataset.append([ir, 'Intermediate result significand: '+ sig + ' Pattern: ' + '1' + '0'*51]) - + sig = '0'*52 exp = random.getrandbits(8) exp = '{:08b}'.format(exp) @@ -3697,8 +3700,8 @@ def ibm_b20(flen, opcode, ops, seed=-1): ir_bin = ('0b'+sgn+exp+sig) ir = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) ir_dataset.append([ir, 'Intermediate result significand: ' + sig + ' Pattern: ' + '0' + '0'*52]) - - b8_comb = [] + + b8_comb = [] for i in range(len(ir_dataset)): rs1 = random.uniform(1, limnum) if opcode in 'fdiv': @@ -3711,19 +3714,19 @@ def ibm_b20(flen, opcode, ops, seed=-1): rs2 = ir_dataset[i][0]*ir_dataset[i][0] elif flen == 64: rs2 = Decimal(ir_dataset[i][0])*Decimal(ir_dataset[i][0]) - + if(flen==32): x1 = struct.unpack('f', struct.pack('f', rs1))[0] x2 = struct.unpack('f', struct.pack('f', rs2))[0] elif(flen==64): x1 = rs1 x2 = rs2 - + if opcode in ['fdiv']: b8_comb.append((floatingPoint_tohex(flen,float(rs1)),floatingPoint_tohex(flen,float(rs2)))) elif opcode in 'fsqrt': b8_comb.append((floatingPoint_tohex(flen,float(rs2)),)) - + coverpoints = [] k=0 for c in b8_comb: @@ -3742,7 +3745,7 @@ def ibm_b20(flen, opcode, ops, seed=-1): cvpt += ir_dataset[k][1] coverpoints.append(cvpt) k=k+1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B20 for '+opcode+' !' logger.info(mess) @@ -3754,26 +3757,26 @@ def ibm_b21(flen, opcode, ops): ''' IBM Model B21 Definition: This model will test the Divide By Zero exception flag. For the operations divide and remainder, a test case will be created for each of the possible combinations from the following table: - + First Operand : 0, Random non-zero number, Infinity, NaN Second Operand : 0, Random non-zero number, Infinity, NaN - + Operation: Divide, Remainder - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode - + :type flen: int :type opcode: str :type ops: int - + Abstract Dataset Description: Final Results = [ Zero, Subnorm, Norm, Infinity, DefaultNaN, QNaN, SNaN ] - + Implementation: - The basic_types dataset is accumulated with the combinations of the abstract dataset description. - - Using python’s package itertools, a permutation of all possible combinations as a pair is computed for basic_types dataset.. + - Using python’s package itertools, a permutation of all possible combinations as a pair is computed for basic_types dataset.. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. ''' @@ -3787,7 +3790,7 @@ def ibm_b21(flen, opcode, ops): else: logger.error('Invalid flen value!') sys.exit(1) - + # the following creates a cross product for ops number of variables b21_comb = list(itertools.product(*ops*[basic_types])) coverpoints = [] @@ -3806,38 +3809,38 @@ def ibm_b21(flen, opcode, ops): if(y != ops): cvpt += " and " coverpoints.append(cvpt) - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B21 for '+opcode+' !' logger.info(mess) coverpoints = comments_parser(coverpoints) return coverpoints - -def ibm_b22(flen, opcode, ops, seed=-1): + +def ibm_b22(flen, opcode, ops, seed=10): ''' IBM Model B22 Definition: This model creates test cases for each of the following exponents (unbiased): - 1. Smaller than -3 - 2. All the values in the range [-3, integer width+3] - 3. Larger than integer width + 3 + 1. Smaller than -3 + 2. All the values in the range [-3, integer width+3] + 3. Larger than integer width + 3 For each exponent two cases will be randomly chosen, positive and negative. - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to -1. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Operand1 = [Smaller than -3, All the values in the range [-3, integer width+3], Larger than integer width + 3] - + Implementation: - Random bits are calculated and appended to obtain the exponent ranges defined in case 2. - To satisfy case 1 and case 3, similar steps are performed outside the loop and hence updated in the loop. @@ -3845,13 +3848,13 @@ def ibm_b22(flen, opcode, ops, seed=-1): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' - + opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] if opcode[2] == 's': flen = 32 elif opcode[2] == 'd': flen = 64 getcontext().prec = 40 xlen = 0 - + if opcode in 'fcvt.w': xlen = 32 elif opcode in 'fcvt.l': @@ -3860,7 +3863,7 @@ def ibm_b22(flen, opcode, ops, seed=-1): xlen = 32 elif opcode in 'fcvt.lu': xlen = 64 - + if seed == -1: if opcode in 'fcvt.w': random.seed(0) @@ -3872,9 +3875,9 @@ def ibm_b22(flen, opcode, ops, seed=-1): random.seed(3) else: random.seed(seed) - + b22_comb = [] - + if flen == 32: ieee754_maxnorm = '0x1.7fffffp+127' maxnum = float.fromhex(ieee754_maxnorm) @@ -3889,10 +3892,10 @@ def ibm_b22(flen, opcode, ops, seed=-1): bits = bin(bits)[2:] front_zero = 23-len(bits) sig = '0'*front_zero + bits - + exp = i exp = '{:08b}'.format(exp) - + sgn = random.getrandbits(1) sgn = '{:01b}'.format(sgn) @@ -3900,33 +3903,33 @@ def ibm_b22(flen, opcode, ops, seed=-1): op = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-127) + ', Exponent in the range [-3, integer width+3]']) b22_comb.append((floatingPoint_tohex(flen,float(op)),)) - + bits = random.getrandbits(23) bits = bin(bits)[2:] front_zero = 23-len(bits) sig = '0'*front_zero + bits exp = random.randint(0,124) - exp = '{:08b}'.format(exp) + exp = '{:08b}'.format(exp) sgn = random.getrandbits(1) sgn = '{:01b}'.format(sgn) ir_bin = ('0b'+sgn+exp+sig) op = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-127) + ', Exponent less than -3']) b22_comb.append((floatingPoint_tohex(flen,float(op)),)) - + bits = random.getrandbits(23) bits = bin(bits)[2:] front_zero = 23-len(bits) sig = '0'*front_zero + bits exp = random.randint(xlen+130,255) - exp = '{:08b}'.format(exp) + exp = '{:08b}'.format(exp) sgn = random.getrandbits(1) sgn = '{:01b}'.format(sgn) ir_bin = ('0b'+sgn+exp+sig) op = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-127) + ', Exponent greater than (integer width+3)']) b22_comb.append((floatingPoint_tohex(flen,float(op)),)) - + elif flen == 64: ieee754_maxnorm = '0x1.fffffffffffffp+1023' maxnum = float.fromhex(ieee754_maxnorm) @@ -3942,10 +3945,10 @@ def ibm_b22(flen, opcode, ops, seed=-1): bits = bin(bits)[2:] front_zero = 52-len(bits) sig = '0'*front_zero + bits - + exp = i exp = '{:011b}'.format(exp) - + sgn = random.getrandbits(1) sgn = '{:01b}'.format(sgn) @@ -3953,33 +3956,33 @@ def ibm_b22(flen, opcode, ops, seed=-1): op = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-1023) + ', Exponent in the range [-3, integer width+3]']) b22_comb.append((floatingPoint_tohex(flen,float(op)),)) - + bits = random.getrandbits(52) bits = bin(bits)[2:] front_zero = 52-len(bits) sig = '0'*front_zero + bits exp = random.randint(0,1020) - exp = '{:011b}'.format(exp) + exp = '{:011b}'.format(exp) sgn = random.getrandbits(1) sgn = '{:01b}'.format(sgn) ir_bin = ('0b'+sgn+exp+sig) op = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-1023) + ', Exponent less than -3']) b22_comb.append((floatingPoint_tohex(flen,float(op)),)) - + bits = random.getrandbits(52) bits = bin(bits)[2:] front_zero = 52-len(bits) sig = '0'*front_zero + bits exp = random.randint(xlen+1026,2047) - exp = '{:011b}'.format(exp) + exp = '{:011b}'.format(exp) sgn = random.getrandbits(1) sgn = '{:01b}'.format(sgn) ir_bin = ('0b'+sgn+exp+sig) op = fields_dec_converter(flen,'0x'+hex(int('1'+ir_bin[2:],2))[3:]) op_dataset.append([op, ' | Exponent: ' + str(int(exp,2)-1023) + ', Exponent greater than (integer width+3)']) b22_comb.append((floatingPoint_tohex(flen,float(op)),)) - + coverpoints = [] k=0 for c in b22_comb: @@ -3998,7 +4001,7 @@ def ibm_b22(flen, opcode, ops, seed=-1): cvpt += op_dataset[k][1] coverpoints.append(cvpt) k=k+1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+ \ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B22 for '+opcode+' !' logger.info(mess) @@ -4010,27 +4013,27 @@ def ibm_b23(flen, opcode, ops): ''' IBM Model B23 Definition: This model creates boundary cases for the rounding to integers that might cause Overflow. - A test case will be created with inputs equal to the maximum integer number in the destination's format (MaxInt), or close to it. In particular, the following FP numbers will be used: - - 1. ±MaxInt - 2. ±MaxInt ± 0.01 (¼) - 3. ±MaxInt ± 0.1 (½) - 4. ±MaxInt ± 0.11 (¾) - 5. ±MaxInt ± 1 - - Rounding Mode: All - - :param flen: Size of the floating point registers + A test case will be created with inputs equal to the maximum integer number in the destination's format (MaxInt), or close to it. In particular, the following FP numbers will be used: + + 1. ±MaxInt + 2. ±MaxInt ± 0.01 (¼) + 3. ±MaxInt ± 0.1 (½) + 4. ±MaxInt ± 0.11 (¾) + 5. ±MaxInt ± 1 + + Rounding Mode: All + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode - + :type flen: int :type opcode: str :type ops: int - + Abstract Dataset Description: Operand 1 = [ MaxInt-4, MaxInt+5 ] - + Implementation: - In the range of (-4,5), the dataset array is appended with the hexadecimal equivalent of maxnum plus the iteration number in a string format. The next highest encoding of the hexadecimal value is calculated. - This is done with different values of maxnum for flen=32 or flen=64. @@ -4039,11 +4042,11 @@ def ibm_b23(flen, opcode, ops): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' - + opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] getcontext().prec = 40 - + operations = ['+','-'] nums = [0,100,200,800,1600] dataset = [] @@ -4055,7 +4058,7 @@ def ibm_b23(flen, opcode, ops): dataset.append((hex(int(maxnum)+i),"| MaxInt + ({})".format(str(i)))) elif flen == 64: maxnum = 0x43e0000000000000 - + for i in range(-4,5): dataset.append((hex(int(maxnum)+i),"| MaxInt + ({})".format(str(i)))) @@ -4068,7 +4071,10 @@ def ibm_b23(flen, opcode, ops): cvpt += (extract_fields(flen,c[x-1],str(x))) cvpt += " and " cvpt += 'rm_val == ' - cvpt += str(rm) + if "fmv" in opcode or opcode in "fcvt.d.s": + cvpt += '0' + else: + cvpt += str(rm) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4078,7 +4084,7 @@ def ibm_b23(flen, opcode, ops): cvpt += " "+c[1] coverpoints.append(cvpt) k=k+1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B23 for '+opcode+' !' logger.info(mess) @@ -4090,44 +4096,43 @@ def ibm_b24(flen, opcode, ops): ''' IBM Model B24 Definition: This model creates boundary cases for rounding to integer that might cause major loss of accuracy. - - A test-case will be created for each of the following inputs: + + A test-case will be created for each of the following inputs: 1. ±0 - 2. ±0 ± 0.01 (¼) - 3. ±0 ± 0.1 (½) - 4. ±0 ± 0.11 (¾) - 5. ±1 - 6. ±1 + 0.01 (¼) - 7. ±1 + 0.1 (½) - 8. ±1 + 0.11 (¾) - - Rounding Mode: All - - :param flen: Size of the floating point registers + 2. ±0 ± 0.01 (¼) + 3. ±0 ± 0.1 (½) + 4. ±0 ± 0.11 (¾) + 5. ±1 + 6. ±1 + 0.01 (¼) + 7. ±1 + 0.1 (½) + 8. ±1 + 0.11 (¾) + + Rounding Mode: All + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode - + :type flen: int :type opcode: str :type ops: int - + Abstract Dataset Description: Operand 1 = [±0, ±0 ± 0.01, ±0 ± 0.1, ±0 ± 0.11, ±1, ±1 + 0.01, ±1 + 0.1, ±1 + 0.11] - + Implementation: - - A nested loop with 4 stages is initiated to iterate each element in minimums, nums, operations1 and operations2 for the two operands. This is done to form the dataset defined above. - Depending on the value of flen, these values are then converted into their respective IEEE 754 hexadecimal values. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). - Coverpoints are then appended with all rounding modes for that particular opcode. ''' - + opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] getcontext().prec = 40 - + operations = ['+','-'] nums = [0,0.01,0.1,0.11] minnums = [0,1] @@ -4138,7 +4143,7 @@ def ibm_b24(flen, opcode, ops): for op1 in operations: for op2 in operations: dataset.append((eval(op1+str(minnum)+op2+str(num)),op1+str(minnum)+op2+str(num))) - + b24_comb = [] for data in dataset: @@ -4156,7 +4161,10 @@ def ibm_b24(flen, opcode, ops): cvpt += (extract_fields(flen,c[x-1],str(x))) cvpt += " and " cvpt += 'rm_val == ' - cvpt += str(rm) + if "fmv" in opcode or opcode in "fcvt.d.s": + cvpt += '0' + else: + cvpt += str(rm) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4166,7 +4174,7 @@ def ibm_b24(flen, opcode, ops): cvpt += " | "+c[1] coverpoints.append(cvpt) k=k+1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B24 for '+opcode+' !' logger.info(mess) @@ -4177,28 +4185,27 @@ def ibm_b24(flen, opcode, ops): def ibm_b25(flen, opcode, ops, seed=10): ''' IBM Model B25 Definition: - This model creates a test-case for each of the following inputs: - - 1. ±MaxInt - 2. ±0 - 3. ±1 + This model creates a test-case for each of the following inputs: + + 1. ±MaxInt + 2. ±0 + 3. ±1 4. Random number - - :param xlen: Size of the integer registers + + :param xlen: Size of the integer registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to 10) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Operand 1 = [±MaxInt, ±0, ±1, Random number] - + Implementation: - - The dataset is formed as per the dataset description. - rand_num is initialized to a random number in the range (1, maxnum). - Since this model is for an integer to floating point conversion instruction, the operands are presented in decimal format. @@ -4209,17 +4216,17 @@ def ibm_b25(flen, opcode, ops, seed=10): opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] getcontext().prec = 40 - + operations = ['+','-'] nums = [0,0.01,0.1,0.11] - + dataset = [(0,"0"),(1,"1"),(-1,"-1")] if flen == 32: maxnum = 2**31-1 elif flen == 64: maxnum = 2**63-1 - + dataset.append((maxnum,"MaxInt")) dataset.append((-1*maxnum,"-MaxInt")) rand_num = int(random.uniform(1,maxnum)) @@ -4229,7 +4236,7 @@ def ibm_b25(flen, opcode, ops, seed=10): b25_comb = [] for data in dataset: - b25_comb.append((hex(data[0]),data[1])) + b25_comb.append((int(data[0]),data[1])) coverpoints = [] k=0 @@ -4237,20 +4244,23 @@ def ibm_b25(flen, opcode, ops, seed=10): for rm in range(0,5): cvpt = "" for x in range(1, ops+1): - cvpt += "rs1 == "+str(c[x-1]) + cvpt += "rs1_val == "+str(c[x-1]) cvpt += " and " cvpt += 'rm_val == ' - cvpt += str(rm) + if "fmv" in opcode or opcode in "fcvt.d.wu": + cvpt += str(0) + else: + cvpt += str(rm) cvpt += ' # Number = ' cvpt += c[1] coverpoints.append(cvpt) k=k+1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B25 for '+opcode+' !' logger.info(mess) coverpoints = comments_parser(coverpoints) - + return (coverpoints) def ibm_b26(xlen, opcode, ops, seed=10): @@ -4258,20 +4268,20 @@ def ibm_b26(xlen, opcode, ops, 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 ranges: [0], [1], [2,3], [4,7], [8,15], …, [(MaxInt+1)/2, MaxInt] - + :param xlen: Size of the integer registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to 10) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Operand 1 = Random number in [0], [1], [2,3], [4,7], [8,15], …, [(MaxInt+1)/2, MaxInt] - + Implementation: - A random number is chosen in the ranges defined above. - Since this model is for an integer to floating point conversion instruction, the operands are presented in decimal format. @@ -4280,7 +4290,7 @@ def ibm_b26(xlen, opcode, ops, seed=10): ''' random.seed(seed) opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] - + dataset = [(0," # Number in [0]"),(1," # Number in [1]")] i = 3 @@ -4288,21 +4298,24 @@ def ibm_b26(xlen, opcode, ops, seed=10): rand_num = random.randint(int((i+1)/2),i) dataset.append((rand_num," # Random number chosen in the range: ["+str(int((i+1)/2))+", "+str(i)+"]")) i = i*2+1 - + coverpoints = [] k=0 for c in dataset: for rm in range(0,5): cvpt = "" for x in range(1, ops+1): - cvpt += "rs1 == "+str(c[x-1]) + cvpt += "rs1_val == "+str(c[x-1]) cvpt += " and " cvpt += 'rm_val == ' - cvpt += str(rm) + if "fmv" in opcode or opcode in "fcvt.d.wu": + cvpt += str(0) + else: + cvpt += str(rm) cvpt += c[1] coverpoints.append(cvpt) k=k+1 - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ (str(32) if xlen == 32 else str(64)) + '-bit coverpoints using Model B26 for '+opcode+' !' logger.info(mess) @@ -4313,31 +4326,30 @@ def ibm_b26(xlen, opcode, ops, seed=10): def ibm_b27(flen, opcode, ops, seed=10): ''' IBM Model B27 Definition: - This model tests the conversion of NaNs from a wider format to a narrow one. Each combination from the following table will create one test case (N represents the number of bits in the significand of the destination's format): + This model tests the conversion of NaNs from a wider format to a narrow one. Each combination from the following table will create one test case (N represents the number of bits in the significand of the destination's format): [SNaN, QNaN] ==================== ========================================================= ===================== - Value of the operand The N-1 MSB bits of the significand (excluding the first) The rest of the bits + Value of the operand The N-1 MSB bits of the significand (excluding the first) The rest of the bits ==================== ========================================================= ===================== QNaN All 0 All 0 SNan Not all 0 Not all 0 ==================== ========================================================= ===================== - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to 10) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Operand 1 = [ SNaN, QNaN ] - + Implementation: - - Dataset is the combination of snan and qnan values predefined at random initially. - Depending on the value of flen, these values are then converted into their respective IEEE 754 hexadecimal values. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). @@ -4345,12 +4357,12 @@ def ibm_b27(flen, opcode, ops, seed=10): ''' opcode = opcode.split('.')[0] + '.' + opcode.split('.')[1] - + if flen == 32: dataset = fsnan + fqnan elif flen == 64: dataset = dsnan + dqnan - + coverpoints = [] for c in dataset: cvpt = "" @@ -4376,39 +4388,38 @@ def ibm_b27(flen, opcode, ops, seed=10): def ibm_b28(flen, opcode, ops, seed=10): ''' IBM Model B28 Definition: - This model tests the conversion of a floating point number to an integral value, represented in floating-point format. A test case will be created for each of the following inputs: - - 1. +0 - 2. A random number in the range (+0, +1) - 3. +1 - 4. Every value in the range (1.00, 10.11] (1 to 2.75 in jumps of 0.25) - 5. A random number in the range (+1, +1.11..11*2^precision) - 6. +1.11..11*2^precision - 7. +Infinity - 8. NaN - 9. -0 - 10. A random number in the range (-1, -0) - 11. -1 - 12. Every value in the range [-10.11, -1.00) - 13. A random number in the range (-1.11..11*2^precision , -1) - 14. -1.11..11*2^precision + This model tests the conversion of a floating point number to an integral value, represented in floating-point format. A test case will be created for each of the following inputs: + + 1. +0 + 2. A random number in the range (+0, +1) + 3. +1 + 4. Every value in the range (1.00, 10.11] (1 to 2.75 in jumps of 0.25) + 5. A random number in the range (+1, +1.11..11*2^precision) + 6. +1.11..11*2^precision + 7. +Infinity + 8. NaN + 9. -0 + 10. A random number in the range (-1, -0) + 11. -1 + 12. Every value in the range [-10.11, -1.00) + 13. A random number in the range (-1.11..11*2^precision , -1) + 14.-1.11..11*2^precision 15. –Infinity - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to 10. Actual value is set with respect to the opcode calling the function) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Operand 1 = [ ±0, ±1, ±Infinity, Default NaN, A random number in the range (+0, +1), Every value in the range (1.00, 10.11] (1 to 2.75 in jumps of 0.25), A random number in the range (+1, +1.11..11*2^precision), ±1.11..11*2^precision, A random number in the range (-1, -0), Every value in the range [-10.11, -1.00), A random number in the range (-1.11..11*2^precision , -1) ] - + Implementation: - - According to the given inputs, all cases are declared and appended to the dataset for flen=32 and flen=64. - Random numbers are obtained in the respective ranges and for absolute values, it is inherited from the dataset definition. - The operand values are then passed into the extract_fields function to get individual fields in a floating point number (sign, exponent and mantissa). @@ -4478,7 +4489,7 @@ def ibm_b28(flen, opcode, ops, seed=10): cvpt += " and " cvpt += " | "+c[1] coverpoints.append(cvpt) - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B28 for '+opcode+' !' logger.info(mess) @@ -4489,23 +4500,23 @@ def ibm_b28(flen, opcode, ops, seed=10): def ibm_b29(flen, opcode, ops, seed=10): ''' IBM Model B29 Definition: - This model checks different cases of rounding of the floating point number. A test will be created for each possible combination of the Sign, LSB, Guard bit and the Sticky bit (16 cases for each operation). - + This model checks different cases of rounding of the floating point number. A test will be created for each possible combination of the Sign, LSB, Guard bit and the Sticky bit (16 cases for each operation). + Rounding Mode: All - - :param flen: Size of the floating point registers + + :param flen: Size of the floating point registers :param opcode: Opcode for which the coverpoints are to be generated :param ops: No. of Operands taken by the opcode :param seed: Initial seed value of the random library. (Predefined to 10) - + :type flen: int :type opcode: str :type ops: int :param seed: int - + Abstract Dataset Description: Operand 1 = [All possible combinations of Sign, LSB, Guard and Sticky are taken] - + Implementation: - A random mantissa is obtained and is iterated for each sign in each digit in the binary number. - The exponent is always maintained at -3, in order to facilitate the shift process that occurs during the actual conversion. @@ -4514,7 +4525,7 @@ def ibm_b29(flen, opcode, ops, seed=10): - Coverpoints are then appended with all rounding modes for that particular opcode. ''' - random.seed(seed) + random.seed(seed) sgns = ["0","1"] dataset = [] if flen == 32: @@ -4544,7 +4555,10 @@ def ibm_b29(flen, opcode, ops, seed=10): cvpt += (extract_fields(flen,c[x-1],str(x))) cvpt += " and " cvpt += 'rm_val == ' - cvpt += str(rm) + if "fmv" in opcode or "fcvt.d.s" in opcode: + cvpt += '0' + else: + cvpt += str(rm) cvpt += ' # ' for y in range(1, ops+1): cvpt += 'rs'+str(y)+'_val==' @@ -4553,7 +4567,7 @@ def ibm_b29(flen, opcode, ops, seed=10): cvpt += " and " cvpt += " | "+c[1] coverpoints.append(cvpt) - + mess='Generated'+ (' '*(5-len(str(len(coverpoints)))))+ str(len(coverpoints)) +' '+\ (str(32) if flen == 32 else str(64)) + '-bit coverpoints using Model B29 for '+opcode+' !' logger.info(mess) diff --git a/riscv_isac/plugins/internaldecoder.py b/riscv_isac/plugins/internaldecoder.py index 47f821e..1114ef5 100644 --- a/riscv_isac/plugins/internaldecoder.py +++ b/riscv_isac/plugins/internaldecoder.py @@ -332,10 +332,10 @@ def priviledged_ops(self, instrObj): if funct3 == 0b000: etype = (instr >> 20) & 0x01 if etype == 0b0: - instrObj.name = 'ecall' + instrObj.instr_name = 'ecall' return instrObj if etype == 0b1: - instrObj.name = 'ebreak' + instrObj.instr_name = 'ebreak' return instrObj # Test for csr ops @@ -380,7 +380,7 @@ def rv64i_arithi_ops(self, instrObj): if funct3 == 0b000: imm = self.twos_comp((instr >> 20) & 0x00000FFF, 12) instrObj.imm = imm - instrObj.name = 'addiw' + instrObj.instr_name = 'addiw' return instrObj shamt = (instr >> 20) & 0x0000001f @@ -552,7 +552,7 @@ def fsw_fsd(self, instrObj): funct3 = (instr & self.FUNCT3_MASK) >> 12 instrObj.rs1 = rs1 - instrObj.rs2 = rs1 + instrObj.rs2 = rs2 instrObj.imm = imm if funct3 == 0b010: @@ -572,13 +572,14 @@ def fmadd(self, instrObj): size_bit = (instr >> 25) & 0x00000001 instrObj.rs1 = rs1 - instrObj.rs2 = rs1 + instrObj.rs2 = rs2 instrObj.rd = rd instrObj.rm = rm instrObj.rs3 = rs3 if size_bit == 0b0: + print(rs1, rs2, rs3) instrObj.instr_name = 'fmadd.s' elif size_bit == 0b1: instrObj.instr_name = 'fmadd.d' @@ -595,7 +596,7 @@ def fmsub(self, instrObj): size_bit = (instr >> 25) & 0x00000001 instrObj.rs1 = rs1 - instrObj.rs2 = rs1 + instrObj.rs2 = rs2 instrObj.rd = rd instrObj.rm = rm @@ -618,7 +619,7 @@ def fnmsub(self, instrObj): size_bit = (instr >> 25) & 0x00000001 instrObj.rs1 = rs1 - instrObj.rs2 = rs1 + instrObj.rs2 = rs2 instrObj.rd = rd instrObj.rm = rm @@ -641,7 +642,7 @@ def fnmadd(self, instrObj): size_bit = (instr >> 25) & 0x00000001 instrObj.rs1 = rs1 - instrObj.rs2 = rs1 + instrObj.rs2 = rs2 instrObj.rd = rd instrObj.rm = rm instrObj.rs3 = rs3 @@ -662,7 +663,7 @@ def rv32_rv64_float_ops(self, instrObj): funct7 = (instr >> 25) instrObj.rs1 = rs1 - instrObj.rs2 = rs1 + instrObj.rs2 = rs2 instrObj.rd = rd instrObj.rm = rm @@ -684,7 +685,7 @@ def rv32_rv64_float_ops(self, instrObj): elif funct7 == 0b0001101: instrObj.instr_name = 'fdiv.d' - if instrObj.instr_name is not None: + if instrObj.instr_name != "None": return instrObj # fsqrt @@ -807,7 +808,7 @@ def rv32_rv64_float_ops(self, instrObj): return instrObj # fcvt.s.w, fcvt.s.wu, fcvt.s.l, fcvt.s.lu - if funct7 == 0b1100100: + if funct7 == 0b1101000: mode = rs2[0] instrObj.rs1 = (rs1[0], 'x') instrObj.rs2 = None @@ -1246,7 +1247,7 @@ def quad2(self, instrObj): instrObj.rs1 = (2 , 'x') return instrObj - + def parseCompressedInstruction(self, instrObj_temp): ''' Parse a compressed instruction diff --git a/setup.cfg b/setup.cfg index 902b2bf..a2bc896 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.6.6 +current_version = 0.7.0 commit = True tag = True diff --git a/setup.py b/setup.py index 4b10fef..e8f6a73 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ def read_requires(): setup( name='riscv_isac', - version='0.6.6', + version='0.7.0', description="RISC-V ISAC", long_description=readme + '\n\n', classifiers=[