Skip to content

Commit

Permalink
Update google_riscv-dv to chipsalliance/riscv-dv@ea8dd25
Browse files Browse the repository at this point in the history
Update code from upstream repository https://github.com/google/riscv-
dv to revision ea8dd25140178eed13c3e0f3d3a97a0c07ab44a0

* Upgrade bitmanip v.0.92 to v.0.93, enable simultaneous use with
  v.1.00 (Pirmin Vogel)
* Added v1.0.0 bitmanip support (Henrik Fegran)
* Remove the pyucis-viewer from requirements.txt (aneels3)
* Update README.md for PyFlow & add pyucis-viewer in requiremen.txt
  (aneels3)
* Fix typo with fs3_sign (aneels3)
* Add hint_cg and illegal_compressed_instr_cg covergroups (aneels3)
* override deepcopy method (aneels3)
* Fix issue with illegal_instr_testi and randselect (aneels3)
* Fixed b_extension_c() issue (shrujal20)
* Fixed get_rand_spf_dpf_value() issue (shrujal20)
* Add support for RV32C coverage (aneels3)
* Add README.md for PyFlow (aneels3)
* Add gen_timeout for PyFlow (aneels3)
* Issue chipsalliance/riscv-dv#778 fix, change mie behavior in
  setup_mmode_reg (Henrik Fegran)
* Fixed wrong length of I, S, B-type immediates causing wrong sign
  extension for certain instructions (Henrik Fegran)
* Update riscv_compressed_instr.sv (AryamanAg)
* Update var binary of function convert2bin (AryamanAg)
* Improve status reporting (Philipp Wagner)
* update ml/testlist.yaml to get better coverage (Udi Jonnalagadda)
* add m extension covgroup (ishita71)
* Update pygen_src files (aneels3)

Signed-off-by: Pirmin Vogel <[email protected]>
  • Loading branch information
vogelpi committed Dec 3, 2021
1 parent 169785d commit 6467492
Show file tree
Hide file tree
Showing 59 changed files with 3,941 additions and 1,532 deletions.
2 changes: 1 addition & 1 deletion vendor/google_riscv-dv.lock.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
upstream:
{
url: https://github.com/google/riscv-dv
rev: 59dcd8c813484eb6dcca67e7e36089fe772b9cc8
rev: ea8dd25140178eed13c3e0f3d3a97a0c07ab44a0
}
}
99 changes: 99 additions & 0 deletions vendor/google_riscv-dv/pygen/pygen_src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
## Overview

RISCV-DV-PyFlow is a purely Python based open-source instruction generator for RISC-V processor
verification. It uses [PyVSC](https://github.com/fvutils/pyvsc) as the main library for
randomization and coverage collection. It currently supports the following features:

- Supported instruction set: RV32IMAFDC
- Supported privileged modes: For now only machine mode is supported.
- Illegal instruction and HINT instruction generation
- Random forward/backward branch instructions
- Supports mixing directed instructions with random instruction stream
- Support for direct & vectored interrupt table.
- Multi-hart support
- Functional coverage framework (reports GUI as well as text, currently
supports RV32IMFDC extensions)
- Supported ISS : Spike, OVPsim

## Supported tests

- riscv_arithmetic_basic_test
- riscv_amo_test
- riscv_floating_point_arithmetic_test
- riscv_floating_point_rand_test
- riscv_floating_point_mmu_stress_test
- riscv_b_ext_test
- riscv_rand_instr_test
- riscv_jump_stress_test
- riscv_rand_jump_test
- riscv_mmu_stress_test
- riscv_illegal_instr_test
- riscv_unaligned_load_store_test
- riscv_single_hart_test
- riscv_non_compressed_instr_test
- riscv_loop_test


## Getting Started

### Prerequisites

To be able to run the generator, you need to have RISCV-GCC compiler toolchain and ISS
(Instruction Set Simulator) installed (Spike is preferred).


### Install RISCV-DV-PyFlow

Getting the source
```bash
git clone https://github.com/google/riscv-dv.git
```

```bash
pip3 install -r requirements.txt # install dependencies (only once)
python3 run.py --help
```

## Running the Generator

Command to run a single test:
```bash
python3 run.py --test=riscv_arithmetic_basic_test --simulator=pyflow
```
--simulator=pyflow will invoke the Python generator.

Run a single test 10 times
```bash
python3 run.py --test=riscv_arithmetic_basic_test --iterations=10 --simulator=pyflow
```
Run the generator only, do not compile and simluation with ISS
```bash
python3 run.py --test=riscv_arithmetic_basic_test --simulator=pyflow --steps gen
```
## Coverage Model
The coverage model of PyFlow is developed using PyVSC library.

Command to generate the coverage report.
#### Process spike simulation log and collect functional coverage
```bash
python3 cov.py --dir out/spike_sim/ --simulator=pyflow --enable_visualization
```
--enable_visualization helps enabling coverage report visualization for pyflow.
#### Get the command reference
```bash
cov --help
```
#### Run the coverage flow with predefined targets
```bash
python3 cov.py --dir out/spike_sim/ --simulator=pyflow --enable_visualization --target rv32imc
```
The coverage reports can be viewed using two ways:
1) Text format: By opening the CoverageReport.txt file.
2) GUI format: By opening the cov_db.xml using pyucis-viewer.
The GUI format could be enabled using "--enable_visualization" command option.
```bash
pyucis-viewer cov_db.xml
```
## Note
Currently, time to generate a single program with larger than 10k instructions is around
12 minutes. We are working on improving the overall performance.
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,6 @@ def conver2bin(self, prefix=""):
def get_c_opcode(self):
pass

# TOD0
# TODO
def get_func3(self):
pass
22 changes: 14 additions & 8 deletions vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_cov_instr.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
import logging
from importlib import import_module
from enum import Enum, IntEnum, auto
from bitstring import BitArray
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")


class operand_sign_e(IntEnum):
POSITIVE = 0
NEGATIVE = auto()
Expand All @@ -35,6 +35,11 @@ class div_result_e(IntEnum):
DIV_OVERFLOW = auto()


class div_result_ex_overflow_e(IntEnum):
DIV_NORMAL = 0
DIV_BY_ZERO = auto()


class compare_result_e(IntEnum):
EQUAL = 0
LARGER = auto()
Expand Down Expand Up @@ -142,7 +147,7 @@ def set_imm_len(self):
if self.imm_type.name == "UIMM":
self.imm_len = 5
else:
self.imm_len = 11
self.imm_len = 12

def set_mode(self):
# mode setting for Instruction Format
Expand Down Expand Up @@ -320,10 +325,11 @@ def check_hazard_condition(self, pre_instr):
the result of the check_hazard_condition won't be accurate. Need to
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)):
if ((self.has_rs1 and (self.rs1 == pre_instr.rd)) or
(self.has_rs2 and (self.rs1 == 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:
elif self.has_rd and (self.rd == pre_instr.rd):
self.gpr_hazard = hazard_e["WAW_HAZARD"]
elif (self.has_rd and
((pre_instr.has_rs1 and (pre_instr.rs1 == self.rd)) or
Expand All @@ -333,16 +339,16 @@ def check_hazard_condition(self, pre_instr):
self.gpr_hazard = hazard_e["NO_HAZARD"]
if self.category == riscv_instr_category_t.LOAD:
if (pre_instr.category == riscv_instr_category_t.STORE and
pre_instr.mem_addr.get_val() == self.mem_addr.get_val()):
(pre_instr.mem_addr.get_val() == self.mem_addr.get_val())):
self.lsu_hazard = hazard_e["RAW_HAZARD"]
else:
self.lsu_hazard = hazard_e["NO_HAZARD"]
if self.category == riscv_instr_category_t.STORE:
if (pre_instr.category == riscv_instr_category_t.STORE and
pre_instr.mem_addr.get_val() == self.mem_addr.get_val()):
(pre_instr.mem_addr.get_val() == self.mem_addr.get_val())):
self.lsu_hazard = hazard_e["WAW_HAZARD"]
elif (pre_instr.category == riscv_instr_category_t.LOAD and
pre_instr.mem_addr.get_val() == self.mem_addr.get_val()):
(pre_instr.mem_addr.get_val() == self.mem_addr.get_val())):
self.lsu_hazard = hazard_e["WAR_HAZARD"]
else:
self.lsu_hazard = hazard_e["NO_HAZARD"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def set_rand_mode(self):
self.has_fs1 = 0
self.has_fd = 0
else:
logging.info("Unsupported format %0s", self.format.name)
logging.info("Unsupported format {}".format(self.format.name))

def pre_randomize(self):
super().pre_randomize()
Expand Down
25 changes: 22 additions & 3 deletions vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_instr.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
"""
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
Expand Down Expand Up @@ -110,12 +108,32 @@ def imm_c(self):
with vsc.if_then(self.XLEN != 32):
self.imm[11:6] == 0

@vsc.constraint
def csr_c(self):
# TODO
pass

@classmethod
def register(cls, instr_name, instr_group):
logging.info("Registering {}".format(instr_name.name))
cls.instr_registry[instr_name] = instr_group
return 1

def __deepcopy__(self, memo):
cls = self.__class__ # Extract the class of the object.
# Create a new instance of the object based on extracted class.
result = cls.__new__(cls)
memo[id(self)] = result
for k, v in self.__dict__.items():
if k in ["_ro_int", "tname", "__field_info"]:
continue # Skip the fields which are not required.
else:
# Copy over attributes by copying directly.
setattr(result, k, copy.deepcopy(v, memo))
return result

# Create the list of instructions based on the supported ISA extensions and configuration
# of the generator
@classmethod
def create_instr_list(cls, cfg):
cls.instr_names.clear()
Expand All @@ -129,6 +147,7 @@ def create_instr_list(cls, cfg):

if not instr_inst.is_supported(cfg):
continue
# C_JAL is RV32C only instruction
if ((rcs.XLEN != 32) and (instr_name == riscv_instr_name_t.C_JAL)):
continue
if ((riscv_reg_t.SP in cfg.reserved_regs) and
Expand Down Expand Up @@ -310,7 +329,7 @@ def set_imm_len(self):
if self.imm_type.name == "UIMM":
self.imm_len = 5
else:
self.imm_len = 11
self.imm_len = 12
self.imm_mask = (self.imm_mask << self.imm_len) & self.shift_t

def extend_imm(self):
Expand Down
11 changes: 5 additions & 6 deletions vendor/google_riscv-dv/pygen/pygen_src/riscv_amo_instr_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
import vsc
import random
from importlib import import_module
from pygen_src.riscv_instr_gen_config import cfg
from pygen_src.isa.riscv_instr import riscv_instr
from pygen_src.riscv_pseudo_instr import riscv_pseudo_instr
from pygen_src.riscv_directed_instr_lib import riscv_mem_access_stream
from pygen_src.riscv_instr_pkg import (riscv_reg_t, riscv_pseudo_instr_name_t,
riscv_instr_name_t, riscv_instr_category_t,
riscv_instr_group_t)
from pygen_src.riscv_instr_gen_config import cfg
from pygen_src.riscv_pseudo_instr import riscv_pseudo_instr
from pygen_src.isa.riscv_instr import riscv_instr
rcs = import_module("pygen_src.target." + cfg.argv.target + ".riscv_core_setting")


Expand Down Expand Up @@ -62,7 +62,6 @@ def addr_range_c(self):

@vsc.constraint
def aligned_amo_c(self):

with vsc.foreach(self.offset, idx = True) as i:
with vsc.if_then(self.XLEN == 32):
self.offset[i] % 4 == 0
Expand All @@ -73,15 +72,15 @@ def pre_randomize(self):
self.data_page = cfg.amo_region
max_data_page_id = len(self.data_page)
self.data_page_id = random.randrange(0, max_data_page_id - 1)
self.max_offset = self.data_page[self.data_page_id]['size_in_bytes']
self.max_offset = self.data_page[self.data_page_id].size_in_bytes

# Use "la" instruction to initialize the offset regiseter
def init_offset_reg(self):
for i in range(len(self.rs1_reg)):
la_instr = riscv_pseudo_instr()
la_instr.pseudo_instr_name = riscv_pseudo_instr_name_t.LA
la_instr.rd = self.rs1_reg[i]
la_instr.imm_str = "{}+{}".format(cfg.amo_region[self.data_page_id]['name'],
la_instr.imm_str = "{}+{}".format(cfg.amo_region[self.data_page_id].name,
self.offset[i])
self.instr_list.insert(0, la_instr)

Expand Down
Loading

0 comments on commit 6467492

Please sign in to comment.