diff --git a/vendor/google_riscv-dv.lock.hjson b/vendor/google_riscv-dv.lock.hjson index 8ac5b859..4346c5a7 100644 --- a/vendor/google_riscv-dv.lock.hjson +++ b/vendor/google_riscv-dv.lock.hjson @@ -9,6 +9,6 @@ upstream: { url: https://github.com/google/riscv-dv - rev: 39797b2f07784e775149a4f05c90fee2427124e5 + rev: 3467c3777cb428b2e30b30b7f895a8fd73873d4f } } diff --git a/vendor/google_riscv-dv/docs/source/appendix.rst b/vendor/google_riscv-dv/docs/source/appendix.rst index 6d6028e6..84a54f94 100644 --- a/vendor/google_riscv-dv/docs/source/appendix.rst +++ b/vendor/google_riscv-dv/docs/source/appendix.rst @@ -21,7 +21,7 @@ A standard CSV format is defined for the instruction execution trace. It's used - The same format as the GPR field - binary: Instruction binary -- instr_str: Instruction in assmebly format +- instr_str: Instruction in assembly format - operand: Instruction operands - pad: Unused diff --git a/vendor/google_riscv-dv/docs/source/end_to_end_simulation.rst b/vendor/google_riscv-dv/docs/source/end_to_end_simulation.rst index 4d7fe79f..b3aea2b5 100644 --- a/vendor/google_riscv-dv/docs/source/end_to_end_simulation.rst +++ b/vendor/google_riscv-dv/docs/source/end_to_end_simulation.rst @@ -1,7 +1,7 @@ End to End Simulation Flow ========================== -We have collaborated with LowRISC to apply this flow for `IBEX RISC-V core verification`_. +We have collaborated with lowRISC to apply this flow for `Ibex RISC-V core verification`_. You can use it as a reference to setup end-to-end co-simulation flow. This repo is still under active development, this is the recommended approach to customize the instruction generator while keeping the effort of merging @@ -27,13 +27,13 @@ upstream changes to a minimum. ``--sim_opts="+uvm_set_inst_override=riscv_asm_program_gen,,'uvm_test_top.asm_gen'"`` -You can refer to `riscv-dv extension for ibex`_ for a working example. +You can refer to `riscv-dv extension for Ibex`_ for a working example. We have plan to open-source the end-to-end environments of other advanced RISC-V processors. Stay tuned! -.. _IBEX RISC-V core verification: https://github.com/lowRISC/ibex/blob/master/doc/verification.rst -.. _riscv-dv extension for ibex: https://github.com/lowRISC/ibex/blob/master/dv/uvm/Makefile#L68 +.. _Ibex RISC-V core verification: https://github.com/lowRISC/ibex/blob/master/doc/03_reference/verification.rst +.. _riscv-dv extension for Ibex: https://github.com/lowRISC/ibex/blob/master/dv/uvm/core_ibex/Makefile#L110 diff --git a/vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_floating_point_instr.py b/vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_floating_point_instr.py new file mode 100644 index 00000000..4d4dcba5 --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_floating_point_instr.py @@ -0,0 +1,146 @@ +""" +Copyright 2020 Google LLC +Copyright 2020 PerfectVIPs Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + +import logging +import vsc +from pygen_src.isa.riscv_instr import riscv_instr +from pygen_src.riscv_instr_pkg import (pkg_ins, riscv_fpr_t, riscv_instr_format_t, + riscv_instr_category_t) + + +@vsc.randobj +class riscv_floating_point_instr(riscv_instr): + def __init__(self): + super().__init__() + self.fs1 = vsc.rand_enum_t(riscv_fpr_t) + self.fs2 = vsc.rand_enum_t(riscv_fpr_t) + self.fs3 = vsc.rand_enum_t(riscv_fpr_t) + self.fd = vsc.rand_enum_t(riscv_fpr_t) + self.has_fs1 = vsc.bit_t(1, 1) + self.has_fs2 = vsc.bit_t(1, 1) + self.has_fs3 = vsc.bit_t(1) + self.has_fd = vsc.bit_t(1, 1) + + def convert2asm(self, prefix = " "): + asm_str = pkg_ins.format_string(string = self.get_instr_name(), + length = pkg_ins.MAX_INSTR_STR_LEN) + if self.format == riscv_instr_format_t.I_FORMAT: + if self.category == riscv_instr_category_t.LOAD: + asm_str = "{}{}, {}({})".format(asm_str, self.fd.name, + self.get_imm(), self.rs1.name) + elif self.instr_name.name in ['FMV_X_W', 'FMV_X_D', 'FCVT_W_S', 'FCVT_WU_S', + 'FCVT_L_S', 'FCVT_LU_S', 'FCVT_L_D', 'FCVT_LU_D', + 'FCVT_W_D', 'FCVT_WU_D']: + asm_str = "{}{}, {}".format(asm_str, self.rd.name, self.fs1.name) + elif self.instr_name.name in ['FMV_W_X', 'FMV_D_X', 'FCVT_S_W', 'FCVT_S_WU', + 'FCVT_S_L', 'FCVT_D_L', 'FCVT_S_LU', 'FCVT_D_W', + 'FCVT_D_LU', 'FCVT_D_WU']: + asm_str = "{}{}, {}".format(asm_str, self.fd.name, self.rs1.name) + else: + asm_str = "{}{}, {}".format(asm_str, self.fd.name, self.fs1.name) + elif self.format == riscv_instr_format_t.S_FORMAT: + asm_str = "{}{}, {}({})".format(asm_str, self.fs2.name, self.get_imm(), self.rs1.name) + elif self.format == riscv_instr_format_t.R_FORMAT: + if self.category == riscv_instr_category_t.COMPARE: + asm_str = "{}{}, {}, {}".format(asm_str, self.rd.name, self.fs1.name, self.fs2.name) + elif self.instr_name.name in ['FCLASS_S', 'FCLASS_D']: + asm_str = "{}{}, {}".format(asm_str, self.rd.name, self.fs1.name) + else: + asm_str = "{}{}, {}, {}".format(asm_str, self.fd.name, self.fs1.name, self.fs2.name) + elif self.format == riscv_instr_format_t.R4_FORMAT: + asm_str = "{}{}, {}, {}, {}".format( + asm_str, self.fd.name, self.fs1.name, self.fs2.name, self.fs3.name) + elif self.format == riscv_instr_format_t.CL_FORMAT: + asm_str = "{}{}, {}({})".format(asm_str, self.fd.name, self.get_imm(), self.rs1.name) + elif self.format == riscv_instr_format_t.CS_FORMAT: + asm_str = "{}{}, {}({})".format(asm_str, self.fs2.name, + self.get_imm(), self.rs1.name) + else: + logging.error("Unsupported floating point format: %0s", self.format.name) + if self.comment != "": + asm_str = asm_str + " #" + self.comment + return asm_str.lower() + + def set_rand_mode(self): + self.has_rs1 = 0 + self.has_rs2 = 0 + self.rd = 0 + self.has_imm = 0 + if self.format == riscv_instr_format_t.I_FORMAT: + self.has_fs2 = 0 + if self.category == riscv_instr_category_t.LOAD: + self.has_imm = 1 + elif self.instr_name.name in ['FMV_X_W', 'FMV_X_D', 'FCVT_W_S', 'FCVT_WU_S', + 'FCVT_L_S', 'FCVT_LU_S', 'FCVT_L_D', 'FCVT_LU_D', + 'FCVT_LU_S', 'FCVT_W_D', 'FCVT_WU_D']: + self.has_fd = 0 + self.has_rd = 1 + elif self.instr_name.name in ['FMV_W_X', 'FMV_D_X', 'FCVT_S_W', 'FCVT_S_WU', + 'FCVT_S_L', 'FCVT_D_L', 'FCVT_S_LU', 'FCVT_D_W', + 'FCVT_D_LU', 'FCVT_D_WU']: + self.has_rs1 = 1 + self.has_fs1 = 0 + elif self.format == riscv_instr_format_t.S_FORMAT: + self.has_imm = 1 + self.has_rs1 = 1 + self.has_fs1 = 0 + self.has_fs3 = 0 + elif self.format == riscv_instr_format_t.R_FORMAT: + if self.category == riscv_instr_category_t.COMPARE: + self.has_rd = 1 + self.has_fd = 0 + elif self.instr_name.name in ['FCLASS_S', 'FCLASS_D']: + self.has_rd = 1 + self.has_fd = 0 + self.has_fs2 = 0 + elif self.format == riscv_instr_format_t.R4_FORMAT: + self.has_fs3 = 1 + elif self.format == riscv_instr_format_t.CL_FORMAT: + self.has_imm = 1 + self.has_rs1 = 1 + self.has_fs1 = 0 + self.has_fs2 = 0 + elif self.format == riscv_instr_format_t.CS_FORMAT: + self.has_imm = 1 + self.has_rs1 = 1 + self.has_fs1 = 0 + self.has_fd = 0 + else: + logging.info("Unsupported format %0s", self.format.name) + + def pre_randomize(self): + super().pre_randomize() + with vsc.raw_mode(): + self.fs1.rand_mode = bool(self.has_fs1) + self.fs2.rand_mode = bool(self.has_fs2) + self.fs3.rand_mode = bool(self.has_fs3) + self.fd.rand_mode = bool(self.has_fd) + + # coverage related functons + def update_src_regs(self, operands = []): + pass + + def update_dst_regs(self, reg_name, val_str): + pass + + def get_fpr(self, reg_name): + pass + + def get_pre_sample(self): + pass + + def get_fp_operand_sign(self, value, idx): + pass + + def check_hazard_condition(self, pre_instr): + pass diff --git a/vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_instr.py b/vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_instr.py index 75098137..0140cf62 100644 --- a/vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_instr.py +++ b/vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_instr.py @@ -111,11 +111,9 @@ class riscv_instr: self.imm[11:6] == 0 @classmethod - def register(cls, instr_name): - logging.info("Registering %s", instr_name.name) - cls.instr_registry[instr_name] = 1 - if instr_name is None: - print("\n") + def register(cls, instr_name, instr_group): + logging.info("Registering {}".format(instr_name.name)) + cls.instr_registry[instr_name] = instr_group return 1 @classmethod @@ -123,10 +121,10 @@ class riscv_instr: cls.instr_names.clear() cls.instr_group.clear() cls.instr_category.clear() - for instr_name, values in cls.instr_registry.items(): + for instr_name, instr_group in cls.instr_registry.items(): if instr_name in rcs.unsupported_instr: continue - instr_inst = cls.create_instr(instr_name) + instr_inst = cls.create_instr(instr_name, instr_group) cls.instr_template[instr_name] = instr_inst if not instr_inst.is_supported(cfg): @@ -153,10 +151,13 @@ class riscv_instr: cls.create_csr_filter(cfg) @classmethod - def create_instr(cls, instr_name): - # Importing get_object here to eliminate the Cyclic dependency for DEFINE_INSTR - from pygen_src.riscv_utils import get_object - instr_inst = get_object(instr_name) + def create_instr(cls, instr_name, instr_group): + try: + module_name = import_module("pygen_src.isa." + instr_group.name.lower() + "_instr") + instr_inst = eval("module_name.riscv_" + instr_name.name + "_instr()") + except Exception: + logging.critical("Failed to create instr: {}".format(instr_name.name)) + sys.exit(1) return instr_inst def is_supported(self, cfg): diff --git a/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32d_instr.py b/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32d_instr.py new file mode 100644 index 00000000..f072604f --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32d_instr.py @@ -0,0 +1,71 @@ +""" +Copyright 2020 Google LLC +Copyright 2020 PerfectVIPs Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +""" + +from pygen_src.riscv_defines import DEFINE_FP_INSTR +from pygen_src.riscv_instr_pkg import (riscv_instr_name_t, riscv_instr_format_t, + riscv_instr_category_t, riscv_instr_group_t) + + +DEFINE_FP_INSTR(riscv_instr_name_t.FLD, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FSD, riscv_instr_format_t.S_FORMAT, + riscv_instr_category_t.STORE, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FMADD_D, riscv_instr_format_t.R4_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FMSUB_D, riscv_instr_format_t.R4_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FNMSUB_D, riscv_instr_format_t.R4_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FNMADD_D, riscv_instr_format_t.R4_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FADD_D, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FSUB_D, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FMUL_D, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FDIV_D, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FSQRT_D, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FSGNJ_D, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FSGNJN_D, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FSGNJX_D, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FMIN_D, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FMAX_D, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FCVT_S_D, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FCVT_D_S, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FEQ_D, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.COMPARE, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FLT_D, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.COMPARE, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FLE_D, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.COMPARE, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FCLASS_D, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FCVT_W_D, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FCVT_WU_D, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FCVT_D_W, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FCVT_D_WU, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32D, g=globals()) diff --git a/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32dc_instr.py b/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32dc_instr.py new file mode 100644 index 00000000..cc4d56c5 --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32dc_instr.py @@ -0,0 +1,27 @@ +""" +Copyright 2020 Google LLC +Copyright 2020 PerfectVIPs Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +""" + +from pygen_src.riscv_defines import DEFINE_FC_INSTR +from pygen_src.riscv_instr_pkg import (riscv_instr_name_t, riscv_instr_format_t, + riscv_instr_category_t, riscv_instr_group_t, imm_t) + + +DEFINE_FC_INSTR(riscv_instr_name_t.C_FLD, riscv_instr_format_t.CL_FORMAT, + riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32DC, imm_t.UIMM, g=globals()) +DEFINE_FC_INSTR(riscv_instr_name_t.C_FSD, riscv_instr_format_t.CS_FORMAT, + riscv_instr_category_t.STORE, riscv_instr_group_t.RV32DC, imm_t.UIMM, g=globals()) +DEFINE_FC_INSTR(riscv_instr_name_t.C_FLDSP, riscv_instr_format_t.CI_FORMAT, + riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32DC, imm_t.UIMM, g=globals()) +DEFINE_FC_INSTR(riscv_instr_name_t.C_FSDSP, riscv_instr_format_t.CSS_FORMAT, + riscv_instr_category_t.STORE, riscv_instr_group_t.RV32DC, imm_t.UIMM, g=globals()) diff --git a/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32f_instr.py b/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32f_instr.py new file mode 100644 index 00000000..45c75ebe --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32f_instr.py @@ -0,0 +1,71 @@ +""" +Copyright 2020 Google LLC +Copyright 2020 PerfectVIPs Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +""" + +from pygen_src.riscv_defines import DEFINE_FP_INSTR +from pygen_src.riscv_instr_pkg import (riscv_instr_name_t, riscv_instr_format_t, + riscv_instr_category_t, riscv_instr_group_t) + + +DEFINE_FP_INSTR(riscv_instr_name_t.FLW, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FSW, riscv_instr_format_t.S_FORMAT, + riscv_instr_category_t.STORE, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FMADD_S, riscv_instr_format_t.R4_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FMSUB_S, riscv_instr_format_t.R4_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FNMSUB_S, riscv_instr_format_t.R4_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FNMADD_S, riscv_instr_format_t.R4_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FADD_S, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FSUB_S, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FMUL_S, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FDIV_S, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FSQRT_S, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FSGNJ_S, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FSGNJN_S, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FSGNJX_S, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FMIN_S, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FMAX_S, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FCVT_W_S, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FCVT_WU_S, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FMV_X_W, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FEQ_S, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.COMPARE, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FLT_S, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.COMPARE, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FLE_S, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.COMPARE, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FCLASS_S, riscv_instr_format_t.R_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FCVT_S_W, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FCVT_S_WU, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) +DEFINE_FP_INSTR(riscv_instr_name_t.FMV_W_X, riscv_instr_format_t.I_FORMAT, + riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32F, g=globals()) diff --git a/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32fc_instr.py b/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32fc_instr.py new file mode 100644 index 00000000..a343bc79 --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32fc_instr.py @@ -0,0 +1,27 @@ +""" +Copyright 2020 Google LLC +Copyright 2020 PerfectVIPs Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +""" + +from pygen_src.riscv_defines import DEFINE_FC_INSTR +from pygen_src.riscv_instr_pkg import (riscv_instr_name_t, riscv_instr_format_t, + riscv_instr_category_t, riscv_instr_group_t, imm_t) + + +DEFINE_FC_INSTR(riscv_instr_name_t.C_FLW, riscv_instr_format_t.CL_FORMAT, + riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32FC, imm_t.UIMM, g=globals()) +DEFINE_FC_INSTR(riscv_instr_name_t.C_FSW, riscv_instr_format_t.CS_FORMAT, + riscv_instr_category_t.STORE, riscv_instr_group_t.RV32FC, imm_t.UIMM, g=globals()) +DEFINE_FC_INSTR(riscv_instr_name_t.C_FLWSP, riscv_instr_format_t.CI_FORMAT, + riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32FC, imm_t.UIMM, g=globals()) +DEFINE_FC_INSTR(riscv_instr_name_t.C_FSWSP, riscv_instr_format_t.CSS_FORMAT, + riscv_instr_category_t.STORE, riscv_instr_group_t.RV32FC, imm_t.UIMM, g=globals()) diff --git a/vendor/google_riscv-dv/pygen/pygen_src/riscv_asm_program_gen.py b/vendor/google_riscv-dv/pygen/pygen_src/riscv_asm_program_gen.py index 9a3ccba2..5ef606f0 100644 --- a/vendor/google_riscv-dv/pygen/pygen_src/riscv_asm_program_gen.py +++ b/vendor/google_riscv-dv/pygen/pygen_src/riscv_asm_program_gen.py @@ -25,6 +25,7 @@ from pygen_src.riscv_instr_pkg import (pkg_ins, privileged_reg_t, misa_ext_t, riscv_instr_group_t) from pygen_src.riscv_instr_gen_config import cfg from pygen_src.riscv_data_page_gen import riscv_data_page_gen +from pygen_src.riscv_privileged_common_seq import riscv_privileged_common_seq from pygen_src.riscv_utils import factory rcs = import_module("pygen_src.target." + cfg.argv.target + ".riscv_core_setting") @@ -241,18 +242,17 @@ class riscv_asm_program_gen: def gen_init_section(self, hart): string = pkg_ins.format_string("init:", pkg_ins.LABEL_STR_LEN) self.instr_stream.append(string) + if (cfg.enable_floating_point): + self.init_floating_point_gpr() self.init_gpr() # Init stack pointer to point to the end of the user stack string = "{}la x{}, {}user_stack_end".format( pkg_ins.indent, cfg.sp.value, pkg_ins.hart_prefix(hart)) self.instr_stream.append(string) - if (cfg.enable_floating_point): - self.init_floating_point_gpr() if (cfg.enable_vector_extension): self.init_vector_engine() self.core_is_initialized() self.gen_dummy_csr_write() - if (rcs.support_pmp): string = pkg_ins.indent + "j main" self.instr_stream.append(string) @@ -338,7 +338,50 @@ class riscv_asm_program_gen: self.instr_stream.append(init_string) def init_floating_point_gpr(self): - pass + for i in range(rcs.NUM_FLOAT_GPR): + # TODO randselect + ''' + vsc.randselect([(1, lambda:self.init_floating_point_gpr_with_spf(i)), + ('RV64D' in rcs.supported_isa, lambda:self.init_floating_point_gpr_with_dpf(i))]) + ''' + self.init_floating_point_gpr_with_spf(i) + # Initialize rounding mode of FCSR + fsrmi_instr = "{}fsrmi {}".format(pkg_ins.indent, cfg.fcsr_rm) + self.instr_stream.append(fsrmi_instr) + + def init_floating_point_gpr_with_spf(self, int_floating_gpr): + imm = self.get_rand_spf_value() + li_instr = "{}li x{}, {}".format(pkg_ins.indent, cfg.gpr[0].value, hex(imm)) + fmv_instr = "{}fmv.w.x f{}, x{}".format(pkg_ins.indent, int_floating_gpr, + cfg.gpr[0].value) + self.instr_stream.extend((li_instr, fmv_instr)) + + def init_floating_point_gpr_with_dpf(self, int_floating_gpr): + imm = vsc.bit_t(64) + imm = self.get_rand_dpf_value() + int_gpr1 = cfg.gpr[0].value + int_gpr2 = cfg.gpr[1].value + + li_instr0 = "{}li x{}, {}".format(pkg_ins.indent, int_gpr1, imm[63:32]) + # shift to upper 32bits + for _ in range(2): + slli_instr = "{}slli x{}, x{}, 16".format(pkg_ins.indent, int_gpr1, int_gpr1) + li_instr1 = "{}li x{}, {}".format(pkg_ins.indent, int_gpr2, imm[31:0]) + or_instr = "{}or x{}, x{}, x{}".format(pkg_ins.indent, int_gpr2, int_gpr2, int_gpr1) + fmv_instr = "{}fmv.d.x f{}, x{}".format(pkg_ins.indent, int_floating_gpr, int_gpr2) + self.instr_stream.extend((li_instr0, slli_instr, li_instr1, or_instr, fmv_instr)) + + # Get a random single precision floating value + def get_rand_spf_value(self): + # TODO randcase + value = random.randrange(0, 2**32 - 1) + return value + + # Get a random double precision floating value + def get_rand_dpf_value(self): + value = vsc.bit_t(64) + # TODO randcase + return value def init_vector_engine(self): pass @@ -384,26 +427,42 @@ class riscv_asm_program_gen: if(cfg.virtual_addr_translation_on): self.page_table_list.process_page_table(instr) self.gen_section(pkg_ins.get_label("process_pt", hart), instr) - # Commenting for now - # self.setup_epc(hart) - - if(rcs.support_pmp): - self.gen_privileged_mode_switch_routine(hart) + self.setup_epc(hart) + self.gen_privileged_mode_switch_routine(hart) def gen_privileged_mode_switch_routine(self, hart): - pass + privil_seq = riscv_privileged_common_seq() + for i in range(len(rcs.supported_privileged_mode)): + instr = [] + csr_handshake = [] + if(rcs.supported_privileged_mode[i] != cfg.init_privileged_mode.name): + continue + logging.info("Generating privileged mode routing for {}" + .format(rcs.supported_privileged_mode[i])) + # Enter Privileged mode + privil_seq.hart = hart + privil_seq.randomize() + privil_seq.enter_privileged_mode(rcs.supported_privileged_mode[i], instr) + # TODO + if cfg.require_signature_addr: + pass + self.instr_stream.extend(instr) def setup_epc(self, hart): instr = [] instr.append("la x{}, {}init".format(cfg.gpr[0].value, pkg_ins.hart_prefix(hart))) - # if(cfg.virtual_addr_translation_on): - # instr.append("slli x{}, x{}") - # TODO - mode_name = cfg.init_privileged_mode - instr.append("csrw mepc, x{}".format(cfg.gpr[0].value)) - if(not rcs.support_pmp): # TODO - instr.append("j {}init_{}".format(pkg_ins.hart_prefix(hart), mode_name.name.lower())) - + if(cfg.virtual_addr_translation_on): + # For supervisor and user mode, use virtual address instead of physical address. + # Virtual address starts from address 0x0, here only the lower 12 bits are kept + # as virtual address offset. + instr.append("slli x{}, x{}, {}".format(cfg.gpr[0].value, + cfg.gpr[0].value, rcs.XLEN - 12) + + "srli x{}, x{}, {}".format(cfg.gpr[0].value, + cfg.gpr[0].value, rcs.XLEN - 12)) + mode_name = cfg.init_privileged_mode.name + instr.append("csrw {}, x{}".format(hex(privileged_reg_t.MEPC), cfg.gpr[0].value)) + if not rcs.support_pmp: + instr.append("j {}init_{}".format(pkg_ins.hart_prefix(hart), mode_name.lower())) self.gen_section(pkg_ins.get_label("mepc_setup", hart), instr) def setup_pmp(self, hart): diff --git a/vendor/google_riscv-dv/pygen/pygen_src/riscv_defines.py b/vendor/google_riscv-dv/pygen/pygen_src/riscv_defines.py index 0dc97530..af074679 100644 --- a/vendor/google_riscv-dv/pygen/pygen_src/riscv_defines.py +++ b/vendor/google_riscv-dv/pygen/pygen_src/riscv_defines.py @@ -15,9 +15,12 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. from pygen_src.riscv_instr_pkg import imm_t from pygen_src.isa.riscv_instr import riscv_instr from pygen_src.isa.riscv_compressed_instr import riscv_compressed_instr +from pygen_src.isa.riscv_floating_point_instr import riscv_floating_point_instr -def DEFINE_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp=imm_t.IMM, g=globals()): +# Regular integer instruction +def DEFINE_INSTR(instr_n, instr_format, instr_category, + instr_group, imm_tp=imm_t.IMM, g=globals()): class_name = "riscv_{}_instr".format(instr_n.name) def __init__(self): @@ -32,12 +35,14 @@ def DEFINE_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp=imm_ self.set_rand_mode() NewClass = type(class_name, (riscv_instr,), { "__init__": __init__, - "valid": riscv_instr.register(instr_n) + "valid": riscv_instr.register(instr_n, instr_group) }) g[class_name] = NewClass -def DEFINE_C_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp=imm_t.IMM, g=globals()): +# Compressed instruction +def DEFINE_C_INSTR(instr_n, instr_format, instr_category, + instr_group, imm_tp=imm_t.IMM, g=globals()): class_name = "riscv_{}_instr".format(instr_n.name) def __init__(self): @@ -51,7 +56,49 @@ def DEFINE_C_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp=im self.set_rand_mode() NewClass = type(class_name, (riscv_compressed_instr,), { "__init__": __init__, - "valid": riscv_compressed_instr.register(instr_n) + "valid": riscv_compressed_instr.register(instr_n, instr_group) + }) + g[class_name] = NewClass + + +# Floating point instruction +def DEFINE_FP_INSTR(instr_n, instr_format, instr_category, + instr_group, imm_tp=imm_t.IMM, g=globals()): + class_name = "riscv_{}_instr".format(instr_n.name) + + def __init__(self): + riscv_floating_point_instr.__init__(self) + self.instr_name = instr_n + self.format = instr_format + self.category = instr_category + self.group = instr_group + self.imm_type = imm_tp + self.set_imm_len() + self.set_rand_mode() + NewClass = type(class_name, (riscv_floating_point_instr,), { + "__init__": __init__, + "valid": riscv_floating_point_instr.register(instr_n, instr_group) + }) + g[class_name] = NewClass + + +# Floating point compressed instruction +def DEFINE_FC_INSTR(instr_n, instr_format, instr_category, + instr_group, imm_tp=imm_t.IMM, g=globals()): + class_name = "riscv_{}_instr".format(instr_n.name) + + def __init__(self): + riscv_compressed_instr.__init__(self) + self.instr_name = instr_n + self.format = instr_format + self.category = instr_category + self.group = instr_group + self.imm_type = imm_tp + self.set_imm_len() + self.set_rand_mode() + NewClass = type(class_name, (riscv_compressed_instr,), { + "__init__": __init__, + "valid": riscv_compressed_instr.register(instr_n, instr_group) }) g[class_name] = NewClass diff --git a/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_gen_config.py b/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_gen_config.py index 8c958195..aaf95f13 100644 --- a/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_gen_config.py +++ b/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_gen_config.py @@ -16,7 +16,6 @@ import argparse import logging import sys import vsc -from bitstring import BitArray from importlib import import_module from pygen_src.riscv_instr_pkg import (mtvec_mode_t, f_rounding_mode_t, riscv_reg_t, privileged_mode_t, @@ -47,25 +46,25 @@ class riscv_instr_gen_config: # init_privileged_mode default to MACHINE_MODE self.init_privileged_mode = privileged_mode_t.MACHINE_MODE - self.mstatus = BitArray(bin(0b0), length=rcs.XLEN - 1) - self.mie = BitArray(bin(0b0), length=rcs.XLEN - 1) - self.sstatus = BitArray(bin(0b0), length=rcs.XLEN - 1) - self.sie = BitArray(bin(0b0), length=rcs.XLEN - 1) - self.ustatus = BitArray(bin(0b0), length=rcs.XLEN - 1) - self.uie = BitArray(bin(0b0), length=rcs.XLEN - 1) + self.mstatus = vsc.rand_bit_t(rcs.XLEN - 1) + self.mie = vsc.rand_bit_t(rcs.XLEN - 1) + self.sstatus = vsc.rand_bit_t(rcs.XLEN - 1) + self.sie = vsc.rand_bit_t(rcs.XLEN - 1) + self.ustatus = vsc.rand_bit_t(rcs.XLEN - 1) + self.uie = vsc.rand_bit_t(rcs.XLEN - 1) - self.mstatus_mprv = 0 - self.mstatus_mxr = 0 - self.mstatus_sum = 0 - self.mstatus_tvm = 0 - self.mstatus_fs = BitArray(bin(0b0), length=2) - self.mstatus_vs = BitArray(bin(0b0), length=2) + self.mstatus_mprv = vsc.rand_bit_t(1) + self.mstatus_mxr = vsc.rand_bit_t(1) + self.mstatus_sum = vsc.rand_bit_t(1) + self.mstatus_tvm = vsc.rand_bit_t(1) + self.mstatus_fs = vsc.rand_bit_t(2) + self.mstatus_vs = vsc.rand_bit_t(2) self.mtvec_mode = vsc.rand_enum_t(mtvec_mode_t) self.tvec_alignment = vsc.rand_uint8_t(self.argv.tvec_alignment) - self.fcsr_rm = list(map(lambda csr_rm: csr_rm.name, f_rounding_mode_t)) - self.enable_sfence = 0 + self.fcsr_rm = vsc.rand_enum_t(f_rounding_mode_t) + self.enable_sfence = vsc.rand_bit_t(1) self.gpr = [] # Helper fields for gpr @@ -225,51 +224,59 @@ class riscv_instr_gen_config: else: vsc.soft(self.tvec_alignment == (rcs.XLEN * 4) / 8) + @vsc.constraint + def floating_point_c(self): + if self.enable_floating_point: + self.mstatus_fs == 1 + else: + self.mstatus_fs == 0 + + @vsc.constraint + def mstatus_c(self): + if self.set_mstatus_mprv: + self.mstatus_mprv == 1 + else: + self.mstatus_mprv == 0 + if rcs.SATP_MODE == "BARE": + self.mstatus_mxr == 0 + self.mstatus_sum == 0 + self.mstatus_tvm == 0 + def check_setting(self): support_64b = 0 support_128b = 0 - # list of satp_mode_t from riscv_core_setting.py - stp_md_lst = rcs.SATP_MODE - - # list of riscv_instr_group_t with names of riscv_instr_name_t in it. - supported_isa_lst = list(map(lambda z: z.name, riscv_instr_group_t)) - # check the valid isa support for x in rcs.supported_isa: - if x == (supported_isa_lst[1] or supported_isa_lst[3] or supported_isa_lst[5] or - supported_isa_lst[8] or supported_isa_lst[11] or supported_isa_lst[13] or - supported_isa_lst[19]): + if x in ["RV64I", "RV64M", "RV64A", "RV64F", "RV64D", "RV64C", "RV64B"]: support_64b = 1 - logging.info("support_64b=%d" % support_64b) - logging.debug("Supported ISA=%s" % x) - elif x == (supported_isa_lst[14] or supported_isa_lst[15]): + logging.info("support_64b = {}".format(support_64b)) + logging.debug("Supported ISA = {}".format(x)) + elif x in ["RV128I", "RV128C"]: support_128b = 1 - logging.info("support_128b=%d" % support_128b) - logging.debug("Supported ISA=%s" % x) + logging.info("support_128b = {}".format(support_128b)) + logging.debug("Supported ISA = {}".format(x)) - if (support_128b == 1) and (rcs.XLEN != 128): + if support_128b and rcs.XLEN != 128: logging.critical("XLEN should be set to 128 based on \ riscv_core_setting.supported_isa setting") - logging.info("XLEN Value=%d" % rcs.XLEN) + logging.info("XLEN Value = {}".format(rcs.XLEN)) sys.exit("XLEN is not equal to 128, set it Accordingly!") - if (support_128b == 0) and (support_64b == 1) and (rcs.XLEN != 64): + if not(support_128b) and support_64b and rcs.XLEN != 64: logging.critical("XLEN should be set to 64 based on \ riscv_core_setting.supported_isa setting") - logging.info("XLEN Value=%d" % rcs.XLEN) + logging.info("XLEN Value = {}".format(rcs.XLEN)) sys.exit("XLEN is not equal to 64, set it Accordingly!") - if not(support_128b or support_64b) and (rcs.XLEN != 32): + if not(support_128b or support_64b) and rcs.XLEN != 32: logging.critical("XLEN should be set to 32 based on \ riscv_core_setting.supported_isa setting") - logging.info("XLEN Value=%d" % rcs.XLEN) + logging.info("XLEN Value = {}".format(rcs.XLEN)) sys.exit("XLEN is not equal to 32, set it Accordingly!") - if not(support_128b or support_64b) and not(('SV32' in stp_md_lst) or - ('BARE' in stp_md_lst)): - logging.critical("SATP mode is not supported for RV32G ISA") - logging.info(stp_md_lst) + if not(support_128b or support_64b) and not(rcs.SATP_MODE in ['SV32', "BARE"]): + logging.critical("SATP mode {} is not supported for RV32G ISA".format(rcs.SATP_MODE)) sys.exit("Supported SATP mode is not provided") # TODO @@ -309,12 +316,12 @@ class riscv_instr_gen_config: self.reserved_regs.append(self.sp) self.reserved_regs.append(self.scratch_reg) self.min_stack_len_per_program = 2 * (rcs.XLEN / 8) - logging.info("min_stack_len_per_program value = %d" - % self.min_stack_len_per_program) + logging.info("min_stack_len_per_program value = {}" + .format(self.min_stack_len_per_program)) self.check_setting() # check if the setting is legal if self.init_privileged_mode == privileged_mode_t.USER_MODE: - logging.info("mode=%s" % "USER_MODE") + logging.info("mode = USER_MODE") self.no_wfi = 1 def get_invalid_priv_lvl_csr(self): diff --git a/vendor/google_riscv-dv/pygen/pygen_src/riscv_privil_reg.py b/vendor/google_riscv-dv/pygen/pygen_src/riscv_privil_reg.py new file mode 100644 index 00000000..4631a2a2 --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/riscv_privil_reg.py @@ -0,0 +1,79 @@ +""" +Copyright 2020 Google LLC +Copyright 2020 PerfectVIPs Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + +import logging +import vsc +from importlib import import_module +from pygen_src.riscv_instr_pkg import privileged_level_t, reg_field_access_t, privileged_reg_t +from pygen_src.riscv_reg import riscv_reg +from pygen_src.riscv_instr_gen_config import cfg +rcs = import_module("pygen_src.target." + cfg.argv.target + ".riscv_core_setting") + + +# RISC-V privileged register class +@vsc.randobj +class riscv_privil_reg(riscv_reg): + def __init__(self): + super().__init__() + + def init_reg(self, reg_name): + super().init_reg(reg_name) + # ---------------Machine mode register ---------------- + # Machine status Register + if(reg_name == privileged_reg_t.MSTATUS): + self.privil_level = privileged_level_t.M_LEVEL + self.add_field("UIE", 1, reg_field_access_t.WARL) + self.add_field("SIE", 1, reg_field_access_t.WARL) + self.add_field("WPRI0", 1, reg_field_access_t.WPRI) + self.add_field("MIE", 1, reg_field_access_t.WARL) + self.add_field("UPIE", 1, reg_field_access_t.WARL) + self.add_field("SPIE", 1, reg_field_access_t.WARL) + self.add_field("WPRI1", 1, reg_field_access_t.WPRI) + self.add_field("MPIE", 1, reg_field_access_t.WARL) + self.add_field("SPP", 1, reg_field_access_t.WLRL) + self.add_field("VS", 2, reg_field_access_t.WARL) + self.add_field("MPP", 2, reg_field_access_t.WLRL) + self.add_field("FS", 2, reg_field_access_t.WARL) + self.add_field("XS", 2, reg_field_access_t.WARL) + self.add_field("MPRV", 1, reg_field_access_t.WARL) + self.add_field("SUM", 1, reg_field_access_t.WARL) + self.add_field("MXR", 1, reg_field_access_t.WARL) + self.add_field("TVM", 1, reg_field_access_t.WARL) + self.add_field("TW", 1, reg_field_access_t.WARL) + self.add_field("TSR", 1, reg_field_access_t.WARL) + if(rcs.XLEN == 32): + self.add_field("WPRI3", 8, reg_field_access_t.WPRI) + else: + self.add_field("WPRI3", 9, reg_field_access_t.WPRI) + self.add_field("UXL", 2, reg_field_access_t.WARL) + self.add_field("SXL", 2, reg_field_access_t.WARL) + self.add_field("WPRI4", rcs.XLEN - 37, reg_field_access_t.WPRI) + self.add_field("SD", 1, reg_field_access_t.WARL) + # Machine interrupt-enable register + elif(reg_name == privileged_reg_t.MIE): + self.privil_level = privileged_level_t.M_LEVEL + self.add_field("USIE", 1, reg_field_access_t.WARL) + self.add_field("SSIE", 1, reg_field_access_t.WARL) + self.add_field("WPRI0", 1, reg_field_access_t.WPRI) + self.add_field("MSIE", 1, reg_field_access_t.WARL) + self.add_field("UTIE", 1, reg_field_access_t.WARL) + self.add_field("STIE", 1, reg_field_access_t.WARL) + self.add_field("WPRI1", 1, reg_field_access_t.WPRI) + self.add_field("MTIE", 1, reg_field_access_t.WARL) + self.add_field("UEIE", 1, reg_field_access_t.WARL) + self.add_field("SEIE", 1, reg_field_access_t.WARL) + self.add_field("WPEI2", 1, reg_field_access_t.WPRI) + self.add_field("MEIE", 1, reg_field_access_t.WARL) + self.add_field("WPRI3", rcs.XLEN - 12, reg_field_access_t.WPRI) + else: + logging.error("reg %0s is not supported yet", reg_name.name) diff --git a/vendor/google_riscv-dv/pygen/pygen_src/riscv_privileged_common_seq.py b/vendor/google_riscv-dv/pygen/pygen_src/riscv_privileged_common_seq.py new file mode 100644 index 00000000..8915deaa --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/riscv_privileged_common_seq.py @@ -0,0 +1,121 @@ +""" +Copyright 2020 Google LLC +Copyright 2020 PerfectVIPs Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +""" + +import logging +import vsc +from importlib import import_module +from pygen_src.riscv_instr_pkg import pkg_ins, privileged_reg_t +from pygen_src.riscv_instr_gen_config import cfg +from pygen_src.riscv_privil_reg import riscv_privil_reg +rcs = import_module("pygen_src.target." + cfg.argv.target + ".riscv_core_setting") + + +@vsc.randobj +class riscv_privileged_common_seq(): + def __init___(self): + self.hart = 0 + self.mstatus = vsc.attr(riscv_privil_reg) + self.mie = vsc.attr(riscv_privil_reg) + + def enter_privileged_mode(self, mode, instrs): + label = pkg_ins.format_string("{}init_{}:" + .format(pkg_ins.hart_prefix(self.hart), mode), + pkg_ins.LABEL_STR_LEN) + ret_instr = ["mret"] + regs = vsc.list_t(vsc.attr(riscv_privil_reg())) + label = label.lower() + self.setup_mmode_reg(mode, regs) + if mode == "SUPERVISOR_MODE": + self.setup_smode_reg(mode, regs) + if mode == "USER_MODE": + self.setup_umode_reg(mode, regs) + if cfg.virtual_addr_translation_on: + self.setup_satp(instrs) + self.gen_csr_instr(regs, instrs) + # Use mret/sret to switch to the target privileged mode + instrs.append(ret_instr[0]) + for i in range(len(instrs)): + instrs[i] = pkg_ins.indent + instrs[i] + instrs.insert(0, label) + + # TODO + def setup_mmode_reg(self, mode, regs): + self.mstatus = riscv_privil_reg() + self.mstatus.init_reg(privileged_reg_t.MSTATUS) + if cfg.randomize_csr: + self.mstatus.set_val(cfg.mstatus) + self.mstatus.set_field("MPRV", cfg.mstatus_mprv) + self.mstatus.set_field("MXR", cfg.mstatus_mxr) + self.mstatus.set_field("SUM", cfg.mstatus_sum) + self.mstatus.set_field("TVM", cfg.mstatus_tvm) + self.mstatus.set_field("TW", cfg.set_mstatus_tw) + self.mstatus.set_field("FS", cfg.mstatus_fs) + self.mstatus.set_field("VS", cfg.mstatus_vs) + if (not("SUPERVISOR_MODE" in rcs.supported_privileged_mode) and (rcs.XLEN != 32)): + self.mstatus.set_field("SXL", 0) + elif rcs.XLEN == 64: + self.mstatus.set_field("SXL", 2) + if (not("USER_MODE" in rcs.supported_privileged_mode) and (rcs.XLEN != 32)): + self.mstatus.set_field("UXL", 0) + elif rcs.XLEN == 64: + self.mstatus.set_field("UXL", 2) + self.mstatus.set_field("XS", 0) + self.mstatus.set_field("SD", 0) + self.mstatus.set_field("UIE", 0) + # Set the previous privileged mode as the target mode + self.mstatus.set_field("MPP", 3) # TODO pass mode value as parameter + self.mstatus.set_field("SPP", 0) + # Enable Interrupt + self.mstatus.set_field("MPIE", cfg.enable_interrupt) + self.mstatus.set_field("MIE", cfg.enable_interrupt) + self.mstatus.set_field("SPIE", cfg.enable_interrupt) + self.mstatus.set_field("SIE", cfg.enable_interrupt) + self.mstatus.set_field("UPIE", cfg.enable_interrupt) + self.mstatus.set_field("UIE", rcs.support_umode_trap) + logging.info("self.mstatus_val: {}".format(hex(self.mstatus.get_val()))) + regs.append(self.mstatus) + # Enable external and timer interrupt + if "MIE" in rcs.implemented_csr: + self.mie = riscv_privil_reg() + self.mie.init_reg(privileged_reg_t.MIE) + if cfg.randomize_csr: + self.mie.set_val(cfg.mie) + self.mie.set_field("UEIE", cfg.enable_interrupt) + self.mie.set_field("SEIE", cfg.enable_interrupt) + self.mie.set_field("MEIE", cfg.enable_interrupt) + self.mie.set_field("USIE", cfg.enable_interrupt) + self.mie.set_field("SSIE", cfg.enable_interrupt) + self.mie.set_field("MSIE", cfg.enable_interrupt) + self.mie.set_field("MTIE", cfg.enable_interrupt & cfg.enable_timer_irq) + self.mie.set_field("STIE", cfg.enable_interrupt & cfg.enable_timer_irq) + self.mie.set_field("UTIE", cfg.enable_interrupt & cfg.enable_timer_irq) + regs.append(self.mie) + + # TODO + def setup_smode_reg(self, mode, regs): + pass + + # TODO + def setup_umode_reg(self, mode, regs): + pass + + # TODO + def setup_satp(self, instrs): + pass + + def gen_csr_instr(self, regs, instrs): + for i in range(len(regs)): + instrs.append("li x{}, {}".format(cfg.gpr[0].value, hex(regs[i].get_val()))) + instrs.append("csrw {}, x{} # {}".format(hex(regs[i].reg_name.value), + cfg.gpr[0], regs[i].reg_name.name)) diff --git a/vendor/google_riscv-dv/pygen/pygen_src/riscv_reg.py b/vendor/google_riscv-dv/pygen/pygen_src/riscv_reg.py new file mode 100644 index 00000000..f542924b --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/riscv_reg.py @@ -0,0 +1,129 @@ +""" +Copyright 2020 Google LLC +Copyright 2020 PerfectVIPs Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + +import sys +import logging +import vsc +from importlib import import_module +from pygen_src.riscv_instr_gen_config import cfg +from pygen_src.riscv_instr_pkg import ( + pkg_ins, privileged_reg_t, reg_field_access_t, privileged_level_t) +rcs = import_module("pygen_src.target." + cfg.argv.target + ".riscv_core_setting") + + +# Light weight RISC-V register class library +# Base class for RISC-V register field +@vsc.randobj +class riscv_reg_field: + def __init__(self): + self.bit_width = 0 + self.reset_val = vsc.bit_t(rcs.XLEN) + self.val = vsc.rand_bit_t(rcs.XLEN) + self.access_type = vsc.enum_t(reg_field_access_t) + self.hard_wired = vsc.bit_t(1) + self.name = "" + + @vsc.constraint + def zero_reserved_field_c(self): + with vsc.implies(self.access_type == reg_field_access_t.WPRI): + self.val == 0 + + @vsc.constraint + def hardwired_fld_c(self): + with vsc.implies(self.hard_wired == 1): + self.val == self.reset_val + + def convert2string(self): + return pkg_ins.format_string("{} bit_width:{} val:{} type:{}".format( + self, self.bit_width, hex(self.val), self.access_type)) + + def post_randomize(self): + mask = vsc.bit_t(rcs.XLEN, 2**rcs.XLEN - 1) + mask = mask >> (rcs.XLEN - self.bit_width) + self.val = mask & self.val + + +# Base class for RISC-V register +@vsc.randobj +class riscv_reg: + def __init__(self): + self.reg_name = vsc.enum_t(privileged_reg_t) + self.offset = vsc.bit_t(12) + self.privil_level = vsc.enum_t(privileged_level_t) + self.val = vsc.bit_t(rcs.XLEN) + self.fld = vsc.rand_list_t(vsc.attr(riscv_reg_field())) + + def init_reg(self, reg_name): + self.reg_name = reg_name + self.offset = reg_name.value + + def get_val(self): + total_len = 0 + for i in range((len(self.fld) - 1), -1, -1): + total_len += self.fld[i].bit_width + if total_len != rcs.XLEN: + for i in range((len(self.fld) - 1), -1, -1): + logging.info(self.fld[i].convert2string()) + logging.critical("Total field length {} != XLEN {}".format(total_len, rcs.XLEN)) + sys.exit(1) + self.val = 0 + for i in range((len(self.fld) - 1), -1, -1): + self.val = (self.val << self.fld[i].bit_width) | self.fld[i].val + return self.val + + def add_field(self, fld_name, bit_width, access_type, reset_val = 0): + new_fld = riscv_reg_field() + new_fld.bit_width = bit_width + new_fld.access_type = access_type + new_fld.reset_val = reset_val + new_fld.name = fld_name + self.fld.append(new_fld) # insert(index, value) is not supported in PyVSC + + def set_field(self, fld_name, val, hard_wired = 0): + for i in range((len(self.fld) - 1), -1, -1): + if fld_name == self.fld[i].name: + self.fld[i].val = val + self.fld[i].hard_wired = hard_wired + if hard_wired: + self.fld[i].reset_val = val + return + logging.critical("Cannot match found field {}".format(fld_name)) + sys.exit(1) + + def get_field_by_name(self, fld_name): + for i in range((len(self.fld) - 1), -1, -1): + if fld_name == self.fld[i].name: + return self.fld[i] + logging.critical("Cannot match found field {}".format(fld_name)) + sys.exit(1) + + # TODO + def rand_field(self, fld_name): + pass + + # TODO + def set_field_rand_mode(self, fld_name, rand_on): + pass + + def reset(self): + for i in range((len(self.fld) - 1), -1, -1): + self.fld[i].val = self.fld[i].reset_val + + def set_val(self, val): + for i in range((len(self.fld) - 1), -1, -1): + if not self.fld[i].hard_wired: + # Assign the valid msb to the field + self.fld[i].val = (val >> (rcs.XLEN - self.fld[i].bit_width)) + logging.info("Assign field {}, bit_width:{}, reg_val 0x{}, fld_val:0x{}", + self.fld[i].name, self.fld[i].bit_width, val, self.fld[i].val) + self.val = val << self.fld[i].bit_width diff --git a/vendor/google_riscv-dv/pygen/pygen_src/riscv_utils.py b/vendor/google_riscv-dv/pygen/pygen_src/riscv_utils.py index c6adcd95..87e21e29 100644 --- a/vendor/google_riscv-dv/pygen/pygen_src/riscv_utils.py +++ b/vendor/google_riscv-dv/pygen/pygen_src/riscv_utils.py @@ -15,9 +15,6 @@ import sys import logging import pandas as pd from tabulate import tabulate -from pygen_src.isa import rv32i_instr -from pygen_src.isa import rv32m_instr -from pygen_src.isa import rv32c_instr from pygen_src.riscv_instr_gen_config import cfg from pygen_src.riscv_directed_instr_lib import (riscv_directed_instr_stream, riscv_int_numeric_corner_stream, @@ -38,155 +35,18 @@ def factory(obj_of): sys.exit(1) -def get_object(instr): - try: - instr_inst = eval("rv32i_instr.riscv_" + instr.name + "_instr()") - except Exception: - try: - instr_inst = eval("rv32m_instr.riscv_" + instr.name + "_instr()") - except Exception: - try: - instr_inst = eval("rv32c_instr.riscv_" + instr.name + "_instr()") - except Exception: - logging.critical("Failed to create instr: %0s", instr.name) - sys.exit(1) - return instr_inst - - def gen_config_table(): data = [] - data.append(['main_program_instr_cnt', type(cfg.main_program_instr_cnt), - sys.getsizeof(cfg.main_program_instr_cnt), cfg.main_program_instr_cnt]) - data.append(['sub_program_instr_cnt', type(cfg.sub_program_instr_cnt), - sys.getsizeof(cfg.sub_program_instr_cnt), cfg.sub_program_instr_cnt]) - data.append(['debug_program_instr_cnt', type(cfg.debug_program_instr_cnt), - sys.getsizeof(cfg.debug_program_instr_cnt), cfg.debug_program_instr_cnt]) - data.append(['debug_sub_program_instr_cnt', type(cfg.debug_sub_program_instr_cnt), - sys.getsizeof(cfg.debug_sub_program_instr_cnt), - cfg.debug_sub_program_instr_cnt]) - data.append(['max_directed_instr_stream_seq', type(cfg.max_directed_instr_stream_seq), - sys.getsizeof(cfg.max_directed_instr_stream_seq), - cfg.max_directed_instr_stream_seq]) - data.append(['data_page_pattern', type(cfg.data_page_pattern), - sys.getsizeof(cfg.data_page_pattern), cfg.data_page_pattern]) - data.append(['init_privileged_mode', type(cfg.init_privileged_mode), - sys.getsizeof(cfg.init_privileged_mode), cfg.init_privileged_mode]) - data.append(['scratch_reg', type(cfg.scratch_reg), - sys.getsizeof(cfg.scratch_reg), cfg.scratch_reg]) - data.append(['pmp_reg', type(cfg.pmp_reg), sys.getsizeof(cfg.pmp_reg), cfg.pmp_reg]) - data.append(['reserved_regs', type(cfg.reserved_regs), - sys.getsizeof(cfg.reserved_regs), cfg.reserved_regs]) - data.append(['sp', type(cfg.sp), sys.getsizeof(cfg.sp), cfg.sp]) - data.append(['tp', type(cfg.tp), sys.getsizeof(cfg.tp), cfg.tp]) - data.append(['ra', type(cfg.ra), sys.getsizeof(cfg.ra), cfg.ra]) - data.append(['check_misa_init_val', type(cfg.check_misa_init_val), - sys.getsizeof(cfg.check_misa_init_val), cfg.check_misa_init_val]) - data.append(['check_xstatus', type(cfg.check_xstatus), - sys.getsizeof(cfg.check_xstatus), cfg.check_xstatus]) - data.append(['virtual_addr_translation_on', type(cfg.virtual_addr_translation_on), - sys.getsizeof(cfg.virtual_addr_translation_on), - cfg.virtual_addr_translation_on]) - data.append(['kernel_stack_len', type(cfg.kernel_stack_len), - sys.getsizeof(cfg.kernel_stack_len), cfg.kernel_stack_len]) - data.append(['kernel_program_instr_cnt', type(cfg.kernel_program_instr_cnt), - sys.getsizeof(cfg.kernel_program_instr_cnt), cfg.kernel_program_instr_cnt]) - data.append(['num_of_sub_program', type(cfg.num_of_sub_program), - sys.getsizeof(cfg.num_of_sub_program), cfg.num_of_sub_program]) - data.append(['instr_cnt', type(cfg.instr_cnt), sys.getsizeof(cfg.instr_cnt), cfg.instr_cnt]) - data.append(['num_of_tests', type(cfg.num_of_tests), - sys.getsizeof(cfg.num_of_tests), cfg.num_of_tests]) - data.append(['no_data_page', type(cfg.no_data_page), - sys.getsizeof(cfg.no_data_page), cfg.no_data_page]) - data.append(['no_branch_jump', type(cfg.no_branch_jump), - sys.getsizeof(cfg.no_branch_jump), cfg.no_branch_jump]) - data.append(['no_load_store', type(cfg.no_load_store), - sys.getsizeof(cfg.no_load_store), cfg.no_load_store]) - data.append(['no_csr_instr', type(cfg.no_csr_instr), - sys.getsizeof(cfg.no_csr_instr), cfg.no_csr_instr]) - data.append(['no_ebreak', type(cfg.no_ebreak), sys.getsizeof(cfg.no_ebreak), cfg.no_ebreak]) - data.append(['no_dret', type(cfg.no_dret), sys.getsizeof(cfg.no_dret), cfg.no_dret]) - data.append(['no_fence', type(cfg.no_fence), sys.getsizeof(cfg.no_fence), cfg.no_fence]) - data.append(['no_wfi', type(cfg.no_wfi), sys.getsizeof(cfg.no_wfi), cfg.no_wfi]) - data.append(['enable_unaligned_load_store', type(cfg.enable_unaligned_load_store), - sys.getsizeof(cfg.enable_unaligned_load_store), - cfg.enable_unaligned_load_store]) - data.append(['illegal_instr_ratio', type(cfg.illegal_instr_ratio), - sys.getsizeof(cfg.illegal_instr_ratio), cfg.illegal_instr_ratio]) - data.append(['hint_instr_ratio', type(cfg.hint_instr_ratio), - sys.getsizeof(cfg.hint_instr_ratio), cfg.hint_instr_ratio]) - data.append(['num_of_harts', type(cfg.num_of_harts), - sys.getsizeof(cfg.num_of_harts), cfg.num_of_harts]) - data.append(['fix_sp', type(cfg.fix_sp), sys.getsizeof(cfg.fix_sp), cfg.fix_sp]) - data.append(['use_push_data_section', type(cfg.use_push_data_section), - sys.getsizeof(cfg.use_push_data_section), cfg.use_push_data_section]) - data.append(['boot_mode_opts', type(cfg.boot_mode_opts), - sys.getsizeof(cfg.boot_mode_opts), cfg.boot_mode_opts]) - data.append(['enable_page_table_exception', type(cfg.enable_page_table_exception), - sys.getsizeof(cfg.enable_page_table_exception), - cfg.enable_page_table_exception]) - data.append(['no_directed_instr', type(cfg.no_directed_instr), - sys.getsizeof(cfg.no_directed_instr), cfg.no_directed_instr]) - data.append(['asm_test_suffix', type(cfg.asm_test_suffix), - sys.getsizeof(cfg.asm_test_suffix), cfg.asm_test_suffix]) - data.append(['enable_interrupt', type(cfg.enable_interrupt), - sys.getsizeof(cfg.enable_interrupt), cfg.enable_interrupt]) - data.append(['enable_nested_interrupt', type(cfg.enable_nested_interrupt), - sys.getsizeof(cfg.enable_nested_interrupt), cfg.enable_nested_interrupt]) - data.append(['enable_timer_irq', type(cfg.enable_timer_irq), - sys.getsizeof(cfg.enable_timer_irq), cfg.enable_timer_irq]) - data.append(['bare_program_mode', type(cfg.bare_program_mode), - sys.getsizeof(cfg.bare_program_mode), cfg.bare_program_mode]) - data.append(['enable_illegal_csr_instruction', type(cfg.enable_illegal_csr_instruction), - sys.getsizeof(cfg.enable_illegal_csr_instruction), - cfg.enable_illegal_csr_instruction]) - data.append(['enable_access_invalid_csr_level', type(cfg.enable_access_invalid_csr_level), - sys.getsizeof(cfg.enable_access_invalid_csr_level), - cfg.enable_access_invalid_csr_level]) - data.append(['enable_misaligned_instr', type(cfg.enable_misaligned_instr), - sys.getsizeof(cfg.enable_misaligned_instr), cfg.enable_misaligned_instr]) - data.append(['enable_dummy_csr_write', type(cfg.enable_dummy_csr_write), - sys.getsizeof(cfg.enable_dummy_csr_write), cfg.enable_dummy_csr_write]) - data.append(['randomize_csr', type(cfg.randomize_csr), - sys.getsizeof(cfg.randomize_csr), cfg.randomize_csr]) - data.append(['allow_sfence_exception', type(cfg.allow_sfence_exception), - sys.getsizeof(cfg.allow_sfence_exception), cfg.allow_sfence_exception]) - data.append(['no_delegation', type(cfg.no_delegation), - sys.getsizeof(cfg.no_delegation), cfg.no_delegation]) - data.append(['force_m_delegation', type(cfg.force_m_delegation), - sys.getsizeof(cfg.force_m_delegation), cfg.force_m_delegation]) - data.append(['force_s_delegation', type(cfg.force_s_delegation), - sys.getsizeof(cfg.force_s_delegation), cfg.force_s_delegation]) - data.append(['support_supervisor_mode', type(cfg.support_supervisor_mode), - sys.getsizeof(cfg.support_supervisor_mode), cfg.support_supervisor_mode]) - data.append(['disable_compressed_instr', type(cfg.disable_compressed_instr), - sys.getsizeof(cfg.disable_compressed_instr), cfg.disable_compressed_instr]) - data.append(['require_signature_addr', type(cfg.require_signature_addr), - sys.getsizeof(cfg.require_signature_addr), cfg.require_signature_addr]) - data.append(['signature_addr', type(cfg.signature_addr), - sys.getsizeof(cfg.signature_addr), cfg.signature_addr]) - data.append(['gen_debug_section', type(cfg.gen_debug_section), - sys.getsizeof(cfg.gen_debug_section), cfg.force_s_delegation]) - data.append(['enable_ebreak_in_debug_rom', type(cfg.enable_ebreak_in_debug_rom), - sys.getsizeof(cfg.enable_ebreak_in_debug_rom), cfg.enable_ebreak_in_debug_rom]) - data.append(['set_dcsr_ebreak', type(cfg.set_dcsr_ebreak), - sys.getsizeof(cfg.set_dcsr_ebreak), cfg.set_dcsr_ebreak]) - data.append(['num_debug_sub_program', type(cfg.num_debug_sub_program), - sys.getsizeof(cfg.num_debug_sub_program), cfg.num_debug_sub_program]) - data.append(['enable_debug_single_step', type(cfg.enable_debug_single_step), - sys.getsizeof(cfg.enable_debug_single_step), cfg.enable_debug_single_step]) - data.append(['single_step_iterations', type(cfg.single_step_iterations), - sys.getsizeof(cfg.single_step_iterations), cfg.single_step_iterations]) - data.append(['set_mstatus_tw', type(cfg.set_mstatus_tw), - sys.getsizeof(cfg.set_mstatus_tw), cfg.set_mstatus_tw]) - data.append(['set_mstatus_mprv', type(cfg.set_mstatus_mprv), - sys.getsizeof(cfg.set_mstatus_mprv), cfg.set_mstatus_mprv]) - data.append(['enable_floating_point', type(cfg.enable_floating_point), - sys.getsizeof(cfg.enable_floating_point), cfg.enable_floating_point]) - data.append(['enable_vector_extension', type(cfg.enable_vector_extension), - sys.getsizeof(cfg.enable_vector_extension), cfg.enable_vector_extension]) - data.append(['enable_b_extension', type(cfg.enable_b_extension), - sys.getsizeof(cfg.enable_b_extension), cfg.enable_b_extension]) - + for key, value in cfg.__dict__.items(): + # Ignoring the unneccesary attributes + if key in ["_ro_int", "_int_field_info", "argv", "mem_region", + "amo_region", "s_mem_region", "args_dict"]: + continue + else: + try: # Fields values for the pyvsc data types + data.append([key, type(key), sys.getsizeof(key), value.get_val()]) + except Exception: + data.append([key, type(key), sys.getsizeof(key), value]) df = pd.DataFrame(data, columns=['Name', 'Type', 'Size', 'Value']) df['Value'] = df['Value'].apply(str) logging.info('\n' + tabulate(df, headers='keys', tablefmt='psql')) diff --git a/vendor/google_riscv-dv/pygen/pygen_src/target/rv32imfdc/riscvOVPsim.ic b/vendor/google_riscv-dv/pygen/pygen_src/target/rv32imfdc/riscvOVPsim.ic new file mode 100644 index 00000000..fdf74487 --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/target/rv32imfdc/riscvOVPsim.ic @@ -0,0 +1,21 @@ +# riscOVPsim configuration file converted from YAML +--variant RV64GC +--override riscvOVPsim/cpu/misa_MXL=2 +--override riscvOVPsim/cpu/misa_MXL_mask=0x0 # 0 +--override riscvOVPsim/cpu/misa_Extensions_mask=0x0 # 0 +--override riscvOVPsim/cpu/unaligned=T +--override riscvOVPsim/cpu/mtvec_mask=0x0 # 0 +--override riscvOVPsim/cpu/user_version=2.3 +--override riscvOVPsim/cpu/priv_version=1.11 +--override riscvOVPsim/cpu/mvendorid=0 +--override riscvOVPsim/cpu/marchid=0 +--override riscvOVPsim/cpu/mimpid=0 +--override riscvOVPsim/cpu/mhartid=0 +--override riscvOVPsim/cpu/cycle_undefined=F +--override riscvOVPsim/cpu/instret_undefined=F +--override riscvOVPsim/cpu/time_undefined=T +--override riscvOVPsim/cpu/reset_address=0x80000000 +--override riscvOVPsim/cpu/simulateexceptions=T +--override riscvOVPsim/cpu/defaultsemihost=F +--override riscvOVPsim/cpu/wfi_is_nop=T +--exitonsymbol _exit diff --git a/vendor/google_riscv-dv/pygen/pygen_src/target/rv32imfdc/riscv_core_setting.py b/vendor/google_riscv-dv/pygen/pygen_src/target/rv32imfdc/riscv_core_setting.py new file mode 100644 index 00000000..d1a19597 --- /dev/null +++ b/vendor/google_riscv-dv/pygen/pygen_src/target/rv32imfdc/riscv_core_setting.py @@ -0,0 +1,63 @@ +""" +Copyright 2020 Google LLC +Copyright 2020 PerfectVIPs Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + +XLEN = 32 + +implemented_csr = ['MVENDORID', 'MARCHID', 'MIMPID', 'MHARTID', 'MSTATUS', 'MISA', 'MIE', + 'MTVEC', 'MCOUNTEREN', 'MSCRATCH', 'MEPC', 'MCAUSE', 'MTVAL', 'MIP'] + +SATP_MODE = 'BARE' + +supported_isa = ['RV32I', 'RV32M', 'RV32C', 'RV32F', 'RV32FC', 'RV32D', 'RV32DC'] + +supported_privileged_mode = ['MACHINE_MODE'] + +supported_interrupt_mode = ['DIRECT', 'VECTORED'] + +max_interrupt_vector_num = 16 + +support_debug_mode = 0 + +NUM_HARTS = 1 + +support_pmp = 0 + +unsupported_instr = [] + +support_umode_trap = 0 + +support_sfence = 0 + +support_unaligned_load_store = 1 + +NUM_FLOAT_GPR = 32 + +NUM_GPR = 32 + +NUM_VEC_GPR = 32 + +VECTOR_EXTENSION_ENABLE = 0 + +VLEN = 512 + +ELEN = 32 + +SELEN = 0 + +MAX_MUL = 8 + +implemented_interrupt = ['M_SOFTWARE_INTR', 'M_TIMER_INTR', 'M_EXTERNAL_INTR'] + +implemented_exception = ['INSTRUCTION_ACCESS_FAULT', 'ILLEGAL_INSTRUCTION', + 'BREAKPOINT', 'LOAD_ADDRESS_MISALIGNED', + 'LOAD_ACCESS_FAULT', 'ECALL_MMODE'] diff --git a/vendor/google_riscv-dv/pygen/pygen_src/test/riscv_instr_base_test.py b/vendor/google_riscv-dv/pygen/pygen_src/test/riscv_instr_base_test.py index ee61c848..94428a36 100644 --- a/vendor/google_riscv-dv/pygen/pygen_src/test/riscv_instr_base_test.py +++ b/vendor/google_riscv-dv/pygen/pygen_src/test/riscv_instr_base_test.py @@ -15,12 +15,8 @@ import sys sys.path.append("pygen/") from pygen_src.riscv_instr_pkg import * from pygen_src.riscv_instr_gen_config import cfg # NOQA -if cfg.argv.target == "rv32i": - from pygen_src.isa.rv32i_instr import * # NOQA -if cfg.argv.target == "rv32imc": - from pygen_src.isa.rv32i_instr import * # NOQA - from pygen_src.isa.rv32m_instr import * # NOQA - from pygen_src.isa.rv32c_instr import * # NOQA +for isa in rcs.supported_isa: + import_module("pygen_src.isa." + isa.lower() + "_instr") from pygen_src.isa.riscv_instr import riscv_instr # NOQA from pygen_src.riscv_asm_program_gen import riscv_asm_program_gen # NOQA from pygen_src.riscv_utils import gen_config_table diff --git a/vendor/google_riscv-dv/run.py b/vendor/google_riscv-dv/run.py index 81980c40..b26772d2 100644 --- a/vendor/google_riscv-dv/run.py +++ b/vendor/google_riscv-dv/run.py @@ -756,7 +756,7 @@ def parse_args(cwd): parser.add_argument("--target", type=str, default="rv32imc", help="Run the generator with pre-defined targets: \ - rv32imc, rv32i, rv64imc, rv64gc") + rv32imc, rv32i, rv32imfdc, rv64imc, rv64gc") parser.add_argument("-o", "--output", type=str, help="Output directory name", dest="o") parser.add_argument("-tl", "--testlist", type=str, default="", @@ -918,6 +918,9 @@ def load_config(args, cwd): if args.target == "rv32imc": args.mabi = "ilp32" args.isa = "rv32imc" + elif args.target == "rv32imfdc": + args.mabi = "ilp32" + args.isa = "rv32imfdc" elif args.target == "rv32imc_sv32": args.mabi = "ilp32" args.isa = "rv32imc" diff --git a/vendor/google_riscv-dv/src/isa/riscv_compressed_instr.sv b/vendor/google_riscv-dv/src/isa/riscv_compressed_instr.sv index 760649df..385af7b0 100644 --- a/vendor/google_riscv-dv/src/isa/riscv_compressed_instr.sv +++ b/vendor/google_riscv-dv/src/isa/riscv_compressed_instr.sv @@ -142,10 +142,6 @@ class riscv_compressed_instr extends riscv_instr; end has_imm = 1'b0; end - CI_FORMAT : begin - has_rs2 = 1'b0; - has_rs1 = 1'b0; - end CSS_FORMAT : begin has_rs1 = 1'b0; has_rd = 1'b0; @@ -160,7 +156,7 @@ class riscv_compressed_instr extends riscv_instr; has_rs1 = 1'b0; has_imm = 1'b0; end - CIW_FORMAT: begin + CI_FORMAT, CIW_FORMAT: begin has_rs1 = 1'b0; has_rs2 = 1'b0; end diff --git a/vendor/google_riscv-dv/src/riscv_pseudo_instr.sv b/vendor/google_riscv-dv/src/riscv_pseudo_instr.sv index 181b2fdd..34664356 100644 --- a/vendor/google_riscv-dv/src/riscv_pseudo_instr.sv +++ b/vendor/google_riscv-dv/src/riscv_pseudo_instr.sv @@ -1,3 +1,19 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + // Psuedo instructions are used to simplify assembly program writing class riscv_pseudo_instr extends riscv_instr; diff --git a/vendor/google_riscv-dv/target/rv32imfdc/riscv_core_setting.sv b/vendor/google_riscv-dv/target/rv32imfdc/riscv_core_setting.sv new file mode 100644 index 00000000..2ac5da2c --- /dev/null +++ b/vendor/google_riscv-dv/target/rv32imfdc/riscv_core_setting.sv @@ -0,0 +1,146 @@ +/* + * Copyright 2019 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//----------------------------------------------------------------------------- +// Processor feature configuration +//----------------------------------------------------------------------------- +// XLEN +parameter int XLEN = 32; + +// Parameter for SATP mode, set to BARE if address translation is not supported +parameter satp_mode_t SATP_MODE = BARE; + +// Supported Privileged mode +privileged_mode_t supported_privileged_mode[] = {MACHINE_MODE}; + +// Unsupported instructions +riscv_instr_name_t unsupported_instr[]; + +// ISA supported by the processor +riscv_instr_group_t supported_isa[$] = {RV32I, RV32M, RV32C, RV32F, RV32FC}; + +// Interrupt mode support +mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED}; + +// The number of interrupt vectors to be generated, only used if VECTORED interrupt mode is +// supported +int max_interrupt_vector_num = 16; + +// Physical memory protection support +bit support_pmp = 0; + +// Debug mode support +bit support_debug_mode = 0; + +// Support delegate trap to user mode +bit support_umode_trap = 0; + +// Support sfence.vma instruction +bit support_sfence = 0; + +// Support unaligned load / store +bit support_unaligned_load_store = 1'b1; + +// GPR setting +parameter int NUM_FLOAT_GPR = 32; +parameter int NUM_GPR = 32; +parameter int NUM_VEC_GPR = 32; + +// ---------------------------------------------------------------------------- +// Vector extension configuration +// ---------------------------------------------------------------------------- + +// Parameter for vector extension +parameter int VECTOR_EXTENSION_ENABLE = 0; + +parameter int VLEN = 512; + +// Maximum size of a single vector element +parameter int ELEN = 32; + +// Minimum size of a sub - element, which must be at most 8 - bits. +parameter int SELEN = 8; + +// Maximum size of a single vector element(encoded in vsew format) +parameter int VELEN = int'($ln(ELEN) /$ln(2)) - 3; + +// Maxium LMUL supported by the core +parameter int MAX_LMUL = 8; + +// ---------------------------------------------------------------------------- +// Multi - harts configuration +// ---------------------------------------------------------------------------- + +// Number of harts +parameter int NUM_HARTS = 1; + +// ---------------------------------------------------------------------------- +// Previleged CSR implementation +// ---------------------------------------------------------------------------- + +// Implemented previlieged CSR list +`ifdef DSIM +privileged_reg_t implemented_csr[] = { +`else +const privileged_reg_t implemented_csr[] = { +`endif // + Machine mode mode CSR + MVENDORID, // Vendor ID + MARCHID, // Architecture ID + MIMPID, // Implementation ID + MHARTID, // Hardware thread ID + MSTATUS, // Machine status + MISA, // ISA and extensions + MIE, // Machine interrupt - enable register + MTVEC, // Machine trap - handler base address + MCOUNTEREN, // Machine counter enable + MSCRATCH, // Scratch register for machine trap handlers + MEPC, // Machine exception program counter + MCAUSE, // Machine trap cause + MTVAL, // Machine bad address or instruction + MIP // Machine interrupt pending +}; + +// Implementation - specific custom CSRs +bit[11:0] custom_csr[] = { +}; + +// ---------------------------------------------------------------------------- +// Supported interrupt / exception setting, used for functional coverage // +---------------------------------------------------------------------------- + +`ifdef DSIM +interrupt_cause_t implemented_interrupt[] = { +`else +const interrupt_cause_t implemented_interrupt[] = { +`endif + M_SOFTWARE_INTR, + M_TIMER_INTR, + M_EXTERNAL_INTR +}; + +`ifdef DSIM +exception_cause_t implemented_exception[] = { +`else +const exception_cause_t implemented_exception[] = { +`endif + INSTRUCTION_ACCESS_FAULT, + ILLEGAL_INSTRUCTION, + BREAKPOINT, + LOAD_ADDRESS_MISALIGNED, + LOAD_ACCESS_FAULT, + ECALL_MMODE +}; diff --git a/vendor/google_riscv-dv/target/rv32imfdc/testlist.yaml b/vendor/google_riscv-dv/target/rv32imfdc/testlist.yaml new file mode 100644 index 00000000..bc562f64 --- /dev/null +++ b/vendor/google_riscv-dv/target/rv32imfdc/testlist.yaml @@ -0,0 +1,81 @@ +# Copyright Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ================================================================================ +# Regression test list format +# -------------------------------------------------------------------------------- +# test : Assembly test name +# description : Description of this test +# gen_opts : Instruction generator options +# iterations : Number of iterations of this test +# no_iss : Enable/disable ISS simulator (Optional) +# gen_test : Test name used by the instruction generator +# asm_tests : Path to directed, hand-coded assembly test file or directory +# rtl_test : RTL simulation test name +# cmp_opts : Compile options passed to the instruction generator +# sim_opts : Simulation options passed to the instruction generator +# no_post_compare : Enable/disable comparison of trace log and ISS log (Optional) +# compare_opts : Options for the RTL & ISS trace comparison +# gcc_opts : gcc compile options +# -------------------------------------------------------------------------------- + +- import: /target/rv32imc/testlist.yaml + + +- test: riscv_floating_point_arithmetic_test + description: > + Enable floating point instructions + gen_opts: > + +instr_cnt=10000 + +num_of_sub_program=0 + +no_fence=1 + +no_data_page=1 + +no_branch_jump=1 + +enable_floating_point=1 + +boot_mode=m + iterations: 1 + gen_test: riscv_instr_base_test + rtl_test: core_base_test + +- test: riscv_floating_point_rand_test + description: > + Enable floating point instructions + gen_opts: > + +enable_floating_point=1 + +instr_cnt=10000 + +num_of_sub_program=5 + +directed_instr_0=riscv_load_store_rand_instr_stream,4 + +directed_instr_1=riscv_loop_instr,4 + +directed_instr_2=riscv_multi_page_load_store_instr_stream,4 + +directed_instr_3=riscv_mem_region_stress_test,4 + +directed_instr_4=riscv_jal_instr,4 + iterations: 1 + gen_test: riscv_instr_base_test + rtl_test: core_base_test + +- test: riscv_floating_point_mmu_stress_test + description: > + Test with different patterns of load/store instructions, stress test MMU + operations. + iterations: 2 + gen_test: riscv_instr_base_test + gen_opts: > + +instr_cnt=5000 + +num_of_sub_program=5 + +enable_floating_point=1 + +directed_instr_0=riscv_load_store_rand_instr_stream,40 + +directed_instr_1=riscv_load_store_hazard_instr_stream,40 + +directed_instr_2=riscv_multi_page_load_store_instr_stream,10 + +directed_instr_3=riscv_mem_region_stress_test,10 + rtl_test: core_base_test diff --git a/vendor/google_riscv-dv/yaml/simulator.yaml b/vendor/google_riscv-dv/yaml/simulator.yaml index 47eacb8b..be025433 100644 --- a/vendor/google_riscv-dv/yaml/simulator.yaml +++ b/vendor/google_riscv-dv/yaml/simulator.yaml @@ -12,6 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +# The -CFLAGS option is required as some VCS DPI code contains smart quotes +# around some preprocessor macros, making G++ throw errors during compilation. +# As a result, passing -fno-extended-identifiers tells G++ to pretend that +# everything is ASCII, preventing strange compilation errors. - tool: vcs compile: cmd: @@ -21,6 +25,7 @@ -f /files.f -full64 -l /compile.log -LDFLAGS '-Wl,--no-as-needed' + -CFLAGS '--std=c99 -fno-extended-identifiers' -Mdir=/vcs_simv.csrc -o /vcs_simv " cov_opts: >