Skip to content
This repository was archived by the owner on Nov 4, 2024. It is now read-only.

Commit a4b25fa

Browse files
authored
Merge pull request #60 from techiepriyansh/multiple-sigs-per-covpt
Implement capturing multiple signature updates per coverpoint
2 parents 9dc9503 + 980473e commit a4b25fa

File tree

12 files changed

+741
-150
lines changed

12 files changed

+741
-150
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
44

55

6+
## [0.17.0] - 2022-10-25
7+
- Improve data propagation reports to capture multiple signature updates per coverpoint
8+
- Add a CLI flag to explicitly log the redundant coverpoints while normalizing the CGF files
9+
610
## [0.16.1] - 2022-10-20
711
- Fix length of commitval to 32 bits if flen is 32 for f registers in sail parser.
812

docs/source/cgf.rst

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,11 @@ A covergroup contains the following nodes:
334334
* **csrcomb-str**
335335
This string is interpreted as a valid python statement/expression which evaluates to a Boolean value. The variables available for use in the expression are as follows:
336336

337-
* ``csr_name`` : The value (as of the end of previous instruction) in the CSR whose name is specified by csr_name.
337+
* ``csr_name`` : The value (as of the end of current instruction) in the CSR whose name is specified by csr_name.
338+
339+
* ``old("csr_name")`` : The value (as of the end of previous instruction) in the CSR whose name is specified by csr_name.
340+
341+
* ``write("csr_name")`` : The value being written to the CSR in the current instruction whose name is specified by csr_name.
338342

339343
* ``xlen`` : The length of the regsiters in the machine.
340344

@@ -367,6 +371,12 @@ A covergroup contains the following nodes:
367371
368372
mstatus && (0x8) == 0x8
369373
374+
4. A coverpoint which checks whether the *M* bit of the value being written to *misa* register is unset and the final value that the register assumes has that bit still set.
375+
376+
.. code-block:: python
377+
378+
(write("misa") >> 12) & 1 == 0 and misa & 0x1000 == 0x1000
379+
370380
* **cross_comb**
371381
*This node is optional.*
372382

docs/source/dpr.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
***********************
2+
Data Propagation Report
3+
***********************
4+
5+
The data propagation details quality analysis on the data propagation occurring within the test/application. It reports
6+
the following statistics about coverpoint hits and related signature updates:
7+
8+
* **STAT1** : Number of instructions that hit unique coverpoints and update the signature
9+
* **STAT2** : Number of instructions that hit covepoints which are not unique but still update the signature (completely or partially)
10+
* **STAT3** : Number of instructions that hit a unique coverpoint but do not update the signature completely
11+
* **STAT4** : Number of multiple signature updates for the same coverpoint
12+
* **STAT5** : Number of times the signature was overwritten

riscv_isac/InstructionObject.py

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
import struct
22

3-
3+
instrs_sig_mutable = ['auipc','jal','jalr']
4+
instrs_sig_update = ['sh','sb','sw','sd','c.sw','c.sd','c.swsp','c.sdsp','fsw','fsd',\
5+
'c.fsw','c.fsd','c.fswsp','c.fsdsp']
6+
instrs_no_reg_tracking = ['beq','bne','blt','bge','bltu','bgeu','fence','c.j','c.jal','c.jalr',\
7+
'c.jr','c.beqz','c.bnez', 'c.ebreak'] + instrs_sig_update
8+
instrs_fcsr_affected = ['fmadd.s','fmsub.s','fnmsub.s','fnmadd.s','fadd.s','fsub.s','fmul.s','fdiv.s',\
9+
'fsqrt.s','fmin.s','fmax.s','fcvt.w.s','fcvt.wu.s','feq.s','flt.s',\
10+
'fle.s','fcvt.s.w','fcvt.s.wu','fcvt.l.s','fcvt.lu.s','fcvt.s.l',\
11+
'fcvt.s.lu', 'fmadd.d','fmsub.d','fnmsub.d','fnmadd.d','fadd.d','fsub.d',\
12+
'fmul.d','fdiv.d','fsqrt.d','fmin.d','fmax.d','fcvt.s.d','fcvt.d.s',\
13+
'feq.d','flt.d','fle.d','fcvt.w.d','fcvt.wu.d','fcvt.l.d','fcvt.lu.d',\
14+
'fcvt.d.l','fcvt.d.lu']
415
unsgn_rs1 = ['sw','sd','sh','sb','ld','lw','lwu','lh','lhu','lb', 'lbu','flw','fld','fsw','fsd',\
516
'bgeu', 'bltu', 'sltiu', 'sltu','c.lw','c.ld','c.lwsp','c.ldsp',\
617
'c.sw','c.sd','c.swsp','c.sdsp','mulhu','divu','remu','divuw',\
@@ -112,6 +123,10 @@ def __init__(
112123
self.rd_nregs = 1
113124

114125

126+
def is_sig_update(self):
127+
return self.instr_name in instrs_sig_update
128+
129+
115130
def evaluate_instr_vars(self, xlen, flen, arch_state, csr_regfile, instr_vars):
116131
'''
117132
This function populates the provided instr_vars dictionary
@@ -179,6 +194,84 @@ def evaluate_instr_vars(self, xlen, flen, arch_state, csr_regfile, instr_vars):
179194
instr_vars.update(ext_specific_vars)
180195

181196

197+
def get_elements_to_track(self, xlen):
198+
'''
199+
This function returns the elements to track to aid in monitoring signature updates and related statistics.
200+
The returned value is a tuple of three elements:
201+
202+
- The first element is a list of registers to track whose values cannot be modified before storing
203+
- The second element is a list of registers to track whose value can be modified prior to storing
204+
- The third element is a list of instructions to track for signature updates other than those of tracked registers (mostly used for branch instructions)
205+
'''
206+
regs_to_track_immutable = []
207+
regs_to_track_mutable = []
208+
instrs_to_track = []
209+
210+
if self.instr_name in instrs_no_reg_tracking:
211+
store_instrs = []
212+
if self.is_sig_update():
213+
store_instrs = [self.instr_name]
214+
else:
215+
if self.instr_name.startswith("c."):
216+
store_instrs = ['sd','c.sdsp'] if xlen == 64 else ['sw','c.swsp']
217+
else:
218+
store_instrs = ['sd'] if xlen == 64 else ['sw']
219+
instrs_to_track.append(store_instrs)
220+
elif self.instr_name in instrs_sig_mutable:
221+
if self.rd is not None:
222+
reg = self.rd[1] + str(self.rd[0])
223+
regs_to_track_mutable.append(reg)
224+
else:
225+
if self.rd is not None:
226+
reg = self.rd[1] + str(self.rd[0])
227+
regs_to_track_immutable.append(reg)
228+
229+
if self.instr_name in instrs_fcsr_affected:
230+
regs_to_track_immutable.append('fcsr')
231+
232+
if self.csr_commit is not None:
233+
for commit in self.csr_commit:
234+
if commit[0] == "CSR":
235+
csr_reg = commit[1]
236+
if csr_reg not in regs_to_track_immutable:
237+
regs_to_track_immutable.append(csr_reg)
238+
239+
return (regs_to_track_immutable, regs_to_track_mutable, instrs_to_track)
240+
241+
242+
def get_changed_regs(self, arch_state, csr_regfile):
243+
'''
244+
This function returns a list of registers whose value will be changed as
245+
a result of executing this instruction.
246+
247+
:param csr_regfile: Architectural state of CSR register files
248+
:param instr_vars: Dictionary to be populated by the evaluated instruction variables
249+
'''
250+
changed_regs = []
251+
252+
if self.reg_commit is not None:
253+
reg = self.reg_commit[0] + self.reg_commit[1]
254+
255+
prev_value = None
256+
if self.reg_commit[0] == 'x':
257+
prev_value = arch_state.x_rf[int(self.reg_commit[1])]
258+
elif self.reg_commit[0] == 'f':
259+
prev_value = arch_state.f_rf[int(self.reg_commit[1])]
260+
261+
if prev_value != str(self.reg_commit[2][2:]): # this is a string check, but should we do an exact number check?
262+
changed_regs.append(reg)
263+
264+
if self.csr_commit is not None:
265+
for commit in self.csr_commit:
266+
if commit[0] == "CSR":
267+
csr_reg = commit[1]
268+
269+
if csr_regfile[csr_reg] != str(commit[2][2:]):
270+
changed_regs.append(csr_reg)
271+
272+
return changed_regs
273+
274+
182275
def update_arch_state(self, arch_state, csr_regfile):
183276
'''
184277
This function updates the arch state and csr regfiles

riscv_isac/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44

55
__author__ = """InCore Semiconductors Pvt Ltd"""
66
__email__ = 'info@incoresemi.com'
7-
__version__ = '0.16.1'
7+
__version__ = '0.17.0'
88

riscv_isac/cgf_normalize.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ def alternate(var, size, signed=True, fltr_func=None,scale_func=None):
549549
#return [(coverpoint,"Alternate") for coverpoint in coverpoints]
550550

551551

552-
def expand_cgf(cgf_files, xlen,flen):
552+
def expand_cgf(cgf_files, xlen,flen, log_redundant=False):
553553
'''
554554
This function will replace all the abstract functions with their unrolled
555555
coverpoints. It replaces node
@@ -616,6 +616,8 @@ def expand_cgf(cgf_files, xlen,flen):
616616
+" in "+labels+": "+str(e) )
617617
else:
618618
for cp,comment in exp_cp:
619+
if log_redundant and cp in cgf[labels][label]:
620+
logger.warn(f'Redundant coverpoint during normalization: {cp}')
619621
cgf[labels][label].insert(l+i,cp,coverage,comment=comment)
620622
i += 1
621623
return dict(cgf)

riscv_isac/constants.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
dpr_template = '''
1010
# Data Propagation Report
1111
12-
- **STAT1** : Number of instructions that hit unique coverpoints and update the signature.
13-
- **STAT2** : Number of instructions that hit covepoints which are not unique but still update the signature
14-
- **STAT3** : Number of instructions that hit a unique coverpoint but do not update signature
12+
- **STAT1** : Number of instructions that hit unique coverpoints and update the signature
13+
- **STAT2** : Number of instructions that hit covepoints which are not unique but still update the signature (completely or partially)
14+
- **STAT3** : Number of instructions that hit a unique coverpoint but do not update the signature completely
1515
- **STAT4** : Number of multiple signature updates for the same coverpoint
1616
- **STAT5** : Number of times the signature was overwritten
1717
@@ -57,10 +57,15 @@
5757
5858
## Details of STAT1:
5959
60-
- The first column indicates the signature address and the data at that location in hexadecimal in the following format:
60+
- The first column indicates the signature address(es) and the data at that location in hexadecimal in the following format:
6161
```
62-
[Address]
63-
Data
62+
[Address1]
63+
Data1
64+
65+
[Address2]
66+
Data2
67+
68+
...
6469
```
6570
6671
- The second column captures all the coverpoints which have been captured by that particular signature location

0 commit comments

Comments
 (0)