fvutils/pyvsc

PyVSC to give exhaustive list of stimulus

Opened this issue ยท 0 comments

Hi Matt,

(Shashi here. Nice to meet you again. ๐Ÿ˜Š)

Is it possible to setup constraints in PyVSC and have it run all possible stimulus exhaustively to get 100% coverage, without duplicate stimulus? I am looking for a way to do stimulus analysis without running sim.

I created this code to capture the stimulii even if it is duplicate until coverage hits 100%. Then I will do something with the solutions created.

The coverage never goes past 3%. May be the covergroup needs to match the constraints. Can you suggest the changes? I wish constraint had builtin coverage. Or covergroup allowed constraint syntax as it is. Is that a possibility with pyvsc? This is big hole in SystemVerilog. I don't want to mimic PSS, but just aid stimulus analysis, don't care about optimized number of stimulus generation without duplication at this point..

If I remove the ab_c constraint then it runs quickly and meets 100%. Similarly, if I remove cross coverage it returns quickly. Any suggestions? Thanks.

import vsc
from vsc.coverage import *
from vsc.model.rand_state import RandState
import random

class stats(object):
    instances = []
    counts = {}

    def __init__(self, **kwargs):
        # Save all the keyword arguments
        self.kwargs = kwargs
        values = []
        for k, v in kwargs.items():
            setattr(self, k, v)
            values.append((k, v))
        key = tuple(values)
        self.instances.append(self)
        if key in self.counts:
            self.counts[key] += 1
        else:
            self.counts[key] = 1
            self.print()


    def print(self):
        # Print the attributes
        print(f"[{len(self.counts)}] Creating {self.__class__.__name__}: {self.kwargs}")
        #for attr, value in self.kwargs.items():
        #    print(f"{attr}: {value}")

    @classmethod
    def summary(cls):
        for i, (key, value) in enumerate(cls.counts.items()):
            print(f"Variation [{i}]: {key}, Count: {value}")

@vsc.randobj
class my_item_c(stats):
    def __init__(self):
        self.a = vsc.rand_bit_t(3)
        self.b = vsc.rand_bit_t(3)

    def pre_randomize(self):
        pass

    def post_randomize(self):
        # Pass all the arguments to the base class's __init__ method
        super().__init__(a=self.a, b=self.b)
        #super().print()

    @vsc.constraint
    def ab_c(self):
        self.a != 0
        self.a <= self.b
        self.b in vsc.rangelist(1,2,4)
        pass

@vsc.covergroup
class my_cg():

    def __init__(self):
        # Define the parameters accepted by the sample function
        self.with_sample(dict(
            it=my_item_c()
        ))

        #self.a_cp = vsc.coverpoint( self.it.a )
        self.a_cp = vsc.coverpoint( self.it.a, bins=dict(
           # Create 4 bins across the space 0..63
           a_bins = bin_array([], [1,3])
        ))
        #self.b_cp = vsc.coverpoint(self.it.b )
        self.b_cp = vsc.coverpoint(self.it.b, bins=dict(
           # Create one bin for each value (1,2,4)
           b_bins = bin_array([], 1, 2, 4)
        ))
        self.ab_cross = vsc.cross([self.a_cp, self.b_cp])
        #self.ab_cross = vsc.cross([self.a_cp, self.b_cp], bins=dict(
        #    ab_bins = [vsc.bin_array([],[[i, 6], [i+1, 7]]) for i in range(7)]
        #))

# Randomize and sample coverage
my_item_i = my_item_c()

# Create an instance of the covergroup
my_cg_i = my_cg()

# Create an instance of the item class
cov=0
seed=0
seed = random.randint(0, 0xFFFFFFFF)
rs = RandState.mkFromSeed(seed)
my_item_i.set_randstate(rs)
while cov<100:
  for i in range(100):
      my_item_i.randomize()
      my_cg_i.sample(my_item_i)
  #
  ## Now, randomize keeping b in the range [1,2]
  #for i in range(100):
  #    with my_item_i.randomize_with() as it:
  #        it.b in vsc.rangelist(1,2,4)
  #    my_cg_i.sample(my_item_i)
  cov = my_cg_i.get_coverage()
  vsc.report_coverage(details=True)
  print("[seed = %d]: Coverage: %f\n" % (seed, cov))
  # Print the attributes
stats.summary()