Skip to content

Commit

Permalink
Merge pull request #828 from saurabhsingh-pvips/rv32fd_coverage
Browse files Browse the repository at this point in the history
[PyFlow]: Add support for RV32FD coverage
  • Loading branch information
hodjat91 committed Dec 9, 2021
2 parents a556f0c + 8a4e2a8 commit 96c1ee6
Show file tree
Hide file tree
Showing 5 changed files with 5,902 additions and 111 deletions.
95 changes: 81 additions & 14 deletions pygen/pygen_src/isa/riscv_cov_instr.py
Expand Up @@ -13,12 +13,10 @@
limitations under the License.
"""

import os
import sys
import vsc
import logging
from importlib import import_module
from enum import Enum, IntEnum, auto
from enum import IntEnum, auto
from pygen_src.riscv_instr_pkg import *
from pygen_src.riscv_instr_gen_config import cfg
rcs = import_module("pygen_src.target." + cfg.argv.target + ".riscv_core_setting")
Expand Down Expand Up @@ -77,14 +75,14 @@ def __init__(self):
# self.operands = "None" # Instruction operands (srcss/dests)
# self.pad = None # Not used

self.rs1_value = vsc.int_t(rcs.XLEN)
self.rs2_value = vsc.int_t(rcs.XLEN)
self.rs3_value = vsc.int_t(rcs.XLEN)
self.rd_value = vsc.int_t(rcs.XLEN)
self.fs1_value = vsc.int_t(rcs.XLEN)
self.fs2_value = vsc.int_t(rcs.XLEN)
self.fs3_value = vsc.int_t(rcs.XLEN)
self.fd_value = vsc.int_t(rcs.XLEN)
self.rs1_value = vsc.bit_t(rcs.XLEN)
self.rs2_value = vsc.bit_t(rcs.XLEN)
self.rs3_value = vsc.bit_t(rcs.XLEN)
self.rd_value = vsc.bit_t(rcs.XLEN)
self.fs1_value = vsc.bit_t(rcs.XLEN)
self.fs2_value = vsc.bit_t(rcs.XLEN)
self.fs3_value = vsc.bit_t(rcs.XLEN)
self.fd_value = vsc.bit_t(rcs.XLEN)

self.mem_addr = vsc.int_t(rcs.XLEN)
self.unaligned_pc = 0
Expand Down Expand Up @@ -117,8 +115,9 @@ def __init__(self):
self.imm_type = None

self.csr = vsc.bit_t(12)
''' TODO: rs2, rs1, rd, group, format, category, imm_type will be
changed to vsc.enum_t once the issue with set/get_val is fixed '''
''' TODO: rs2, rs1, rd, group, format, category, imm_type
fs1, fs2, fs3, fd will be changed to vsc.enum_t once
the issue with set/get_val is fixed '''
self.rs2 = 0
self.rs1 = 0
self.rd = 0
Expand All @@ -128,6 +127,14 @@ def __init__(self):
self.has_rd = 1
self.has_imm = 1
self.imm_len = 0
self.has_fs1 = 1
self.has_fs2 = 1
self.has_fs3 = 0
self.has_fd = 1
self.fs1 = 0
self.fs2 = 0
self.fs3 = 0
self.fd = 0

def assign_attributes(self):
attr_list = get_attr_list(self.instr)
Expand All @@ -139,6 +146,8 @@ def assign_attributes(self):
self.imm_type = attr_list[3]
self.set_imm_len()
self.set_mode()
if self.group.name in ["RV32D", "RV32F"]:
self.set_fd_mode()

def set_imm_len(self):
if self.format.name in ["U_FORMAT", "J_FORMAT"]:
Expand Down Expand Up @@ -167,6 +176,50 @@ def set_mode(self):
if self.format.name == "I_FORMAT":
self.has_rs1 = 0

# mode setting for F and D Instruction
def set_fd_mode(self):
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 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 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 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 {}".format(self.format.name))

def pre_sample(self):
unaligned_pc = self.pc.get_val() % 4 != 0
self.rs1_sign = self.get_operand_sign(self.rs1_value)
Expand Down Expand Up @@ -326,7 +379,7 @@ def check_hazard_condition(self, pre_instr):
explicitly extract the destination register from the operands '''
if pre_instr.has_rd:
if ((self.has_rs1 and (self.rs1 == pre_instr.rd)) or
(self.has_rs2 and (self.rs1 == pre_instr.rd))):
(self.has_rs2 and (self.rs2 == pre_instr.rd))):
logging.info("pre_instr {}".format(pre_instr.instr.name))
self.gpr_hazard = hazard_e["RAW_HAZARD"]
elif self.has_rd and (self.rd == pre_instr.rd):
Expand All @@ -352,6 +405,20 @@ def check_hazard_condition(self, pre_instr):
self.lsu_hazard = hazard_e["WAR_HAZARD"]
else:
self.lsu_hazard = hazard_e["NO_HAZARD"]
# Hazard Condition check for RV32D and RV32F instructions
if pre_instr.has_fd:
if ((self.has_fs1 and (self.fs1 == pre_instr.fd)) or
(self.has_fs2 and (self.fs2 == pre_instr.fd)) or
(self.has_fs3 and (self.fs3 == pre_instr.fd))):
self.gpr_hazard = hazard_e["RAW_HAZARD"]
elif (self.has_fd and (self.fd == pre_instr.fd)):
self.gpr_hazard = hazard_e["WAW_HAZARD"]
elif (self.has_fd and ((pre_instr.has_fs1 and (pre_instr.fs1 == self.fd)) or
(pre_instr.has_fs2 and (pre_instr.fs2 == self.fd)) or
(pre_instr.has_fs3 and (pre_instr.fs3 == self.fd)))):
self.gpr_hazard = hazard_e["WAR_HAZARD"]
else:
self.gpr_hazard = hazard_e["NO_HAZARD"]
logging.debug("Pre PC/name: {}/{}, Cur PC/name: {}/{}, "
"Hazard: {}/{}".format(pre_instr.pc.get_val(),
pre_instr.instr.name,
Expand Down
91 changes: 79 additions & 12 deletions pygen/pygen_src/isa/riscv_floating_point_instr.py
Expand Up @@ -14,8 +14,9 @@
import logging
import vsc
from pygen_src.isa.riscv_instr import riscv_instr
from pygen_src.isa.riscv_cov_instr import riscv_cov_instr, operand_sign_e
from pygen_src.riscv_instr_pkg import (pkg_ins, riscv_fpr_t, riscv_instr_format_t,
riscv_instr_category_t)
riscv_instr_category_t, get_val)


@vsc.randobj
Expand All @@ -30,6 +31,7 @@ def __init__(self):
self.has_fs2 = vsc.bit_t(1, 1)
self.has_fs3 = vsc.bit_t(1)
self.has_fd = vsc.bit_t(1, 1)
self.riscv_cov_ins = None

def convert2asm(self, prefix = " "):
asm_str = pkg_ins.format_string(string = self.get_instr_name(),
Expand Down Expand Up @@ -127,20 +129,85 @@ def pre_randomize(self):
self.fd.rand_mode = bool(self.has_fd)

# coverage related functons
def update_src_regs(self, operands = []):
pass
def update_src_regs(self, instruction, operands):
if self.riscv_cov_ins is None:
self.riscv_cov_ins = riscv_cov_instr()
if instruction.category in ["LOAD", "CSR"]:
self.riscv_cov_ins.update_src_regs(operands)
if instruction.format.name == "I_FORMAT":
logging.info("instr = {}".format(instruction.__dict__))
if instruction.has_fs1:
instruction.fs1 = self.get_fpr(operands[1])
instruction.fs1_value.set_val(self.riscv_cov_ins.get_gpr_state(operands[1]))
elif instruction.has_rs1:
instruction.rs1 = self.riscv_cov_ins.get_gpr(operands[1])
instruction.rs1_value = self.riscv_cov_ins.get_gpr_state(operands[1])
elif instruction.format.name == "S_FORMAT":
assert len(operands) == 3
instruction.fs2 = self.get_fpr(operands[0])
instruction.fs2_value.set_val(self.riscv_cov_ins.get_gpr_state(operands[0]))
instruction.rs1 = self.riscv_cov_ins.get_gpr(operands[1])
instruction.rs1_value = self.riscv_cov_ins.get_gpr_state(operands[1])
instruction.imm = get_val(operands[2])
elif instruction.format.name == "R_FORMAT":
if len(operands) == 2 and instruction.instr.name in ["FSGNJ_S", "FSGNJX_S",
"FSGNJN_S", "FSGNJ_D",
"FSGNJX_D", "FSGNJN_D"]:
operands.append(operands[-1])
if instruction.has_fs2 or instruction.category.name == "CSR":
assert len(operands) == 3
else:
assert len(operands) == 2
if instruction.category.name != "CSR":
instruction.fs1 = self.get_fpr(operands[1])
instruction.fs1_value.set_val(self.riscv_cov_ins.get_gpr_state(operands[1]))
if instruction.has_fs2:
instruction.fs2 = self.get_fpr(operands[0])
instruction.fs2_value.set_val(self.riscv_cov_ins.get_gpr_state(operands[0]))
elif instruction.format.name == "R4_FORMAT":
assert len(operands) == 4
instruction.fs1 = self.get_fpr(operands[1])
instruction.fs1_value.set_val(self.riscv_cov_ins.get_gpr_state(operands[1]))
instruction.fs2 = self.get_fpr(operands[2])
instruction.fs2_value.set_val(self.riscv_cov_ins.get_gpr_state(operands[2]))
instruction.fs3 = self.get_fpr(operands[3])
instruction.fs3_value.set_val(self.riscv_cov_ins.get_gpr_state(operands[3]))
else:
logging.error("Unsupported format {}".format(instruction.format.name))

def update_dst_regs(self, reg_name, val_str):
pass
def update_dst_regs(self, instruction, reg_name, val_str):
self.riscv_cov_ins.gpr_state[reg_name] = get_val(val_str, hexa=1)
if instruction.has_fd:
instruction.fd = self.get_fpr(reg_name)
instruction.fd_value.set_val(self.riscv_cov_ins.get_gpr_state(reg_name))
elif instruction.has_rd:
instruction.rd = self.riscv_cov_ins.get_gpr(reg_name)
instruction.rd_value = self.riscv_cov_ins.get_gpr_state(reg_name)

def get_fpr(self, reg_name):
pass
result = riscv_fpr_t[reg_name.upper()]
return result

def get_pre_sample(self):
pass
def pre_sample(self, instr):
if instr.group.name in ["RV32F", "RV64F"]:
instr.fs1_sign = self.get_fp_operand_sign(instr.fs1_value, 31)
instr.fs2_sign = self.get_fp_operand_sign(instr.fs2_value, 31)
instr.fs3_sign = self.get_fp_operand_sign(instr.fs3_value, 31)
instr.fd_sign = self.get_fp_operand_sign(instr.fd_value, 31)
elif instr.instr.name == "FCVT_S_D":
instr.fs1_sign = self.get_fp_operand_sign(instr.fs1_value, 63)
instr.fd_sign = self.get_fp_operand_sign(instr.fd_value, 31)
elif instr.instr.name == "FCVT_D_S":
instr.fs1_sign = self.get_fp_operand_sign(instr.fs1_value, 31)
instr.fd_sign = self.get_fp_operand_sign(instr.fd_value, 63)
else:
instr.fs1_sign = self.get_fp_operand_sign(instr.fs1_value, 63)
instr.fs2_sign = self.get_fp_operand_sign(instr.fs2_value, 63)
instr.fs3_sign = self.get_fp_operand_sign(instr.fs3_value, 63)
instr.fd_sign = self.get_fp_operand_sign(instr.fd_value, 63)

def get_fp_operand_sign(self, value, idx):
pass

def check_hazard_condition(self, pre_instr):
pass
if value[idx]:
return operand_sign_e.NEGATIVE
else:
return operand_sign_e.POSITIVE

0 comments on commit 96c1ee6

Please sign in to comment.