Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 18, 2025

The bin_array class was removing duplicate values during initialization, violating IEEE 1800-2023 §18.5.1.1 which states: "Duplicate values are retained; thus the same value can be assigned to multiple bins."

Root Cause

bin_array.__init__ called self.ranges.compact() which merges overlapping ranges and eliminates duplicates. This collapsed specifications like [1:10], 1, 4, 7 (13 values) into just [1:10] (10 values), breaking bin distribution.

Changes

  • src/vsc/coverage.py: Removed compact() call, added comment explaining IEEE requirement
  • ve/unit/test_bin_array_duplicates.py: Added 5 test cases covering duplicate value scenarios
  • .gitignore: Added cov.xml

Example

@vsc.covergroup
class my_cg:
    def __init__(self):
        self.with_sample(dict(v_a = vsc.bit_t(9)))
        self.v_a = vsc.coverpoint(self.v_a, bins = {
            "fixed": vsc.bin_array([4], [1, 10], 1, 4, 7)  # 13 values
        })

Before: 3 bins created (duplicates removed)
After: 4 bins as <1,2,3>, <4,5,6>, <7,8,9>, <10,1,4,7> with values 1, 4, 7 hitting both their range bin and bin[3] when sampled.

Testing

All existing tests pass. New test suite validates duplicate handling across range overlaps, separate values, and exact duplicates.

Original prompt

This section details on the original issue you should resolve

<issue_title>Possible issue with bin_array not retaining duplicate values as required by IEEE 1800</issue_title>
<issue_description>### Summary
I have encountered a possible issue regarding the handling of duplicate values in bin arrays. It seems that when bin arrays contain duplicate values, PyVSC does not distribute these values in accordance with the standard. As specified in IEEE 1800-2023 (page 585), "duplicate values are retained; thus the same value can be assigned to multiple bins."

Example: duplicate values in bin_array

import vsc

@vsc.covergroup
class my_covergroup:
    def __init__(self, name="my_covergroup"):
        self.with_sample(dict(
            v_a = vsc.bit_t(9)
        ))
        self.options.name = name
        self.v_a = vsc.coverpoint(self.v_a, bins = {
            # According to IEEE 1800-2023 (page 585):
            #   "Duplicate values are retained; thus the same value can be assigned to multiple bins"
            # e.g., bins fixed [4] = {[1:10], 1, 4, 7} should distribute the 13 values in <1,2,3>, <4,5,6>, <7,8,9>, <10,1,4,7>
            "fixed1": vsc.bin_array([4], [1, 10], 1, 4, 7)
        })

cg_inst = my_covergroup(name="cg_inst")

Expected:

  • fixed1[0]: 1, 2, 3
  • fixed1[1]: 4, 5, 6
  • fixed1[2]: 7, 8, 9
  • fixed1[3]: 10, 1, 4, 7 (including duplicates as required by standard)

Actual PyVSC output:

  • fixed1[0]: 1
  • fixed1[1]: 4
  • fixed1[2]: 7

Additional observation

If bin_array is used without duplicates:

"fixed2": vsc.bin_array([4], [4, 12], 1, 2, 8)

The bins are distributed as:

  • fixed2[0]: 1, 2, 3
  • fixed2[1]: 4, 5, 6
  • fixed2[2]: 7, 8, 9
  • fixed2[3]: 10, 11, 12 (which matches expectations)

However, the declaration below:

"fixed3": vsc.bin_array([4], [4, 12], 1, 2, 8)

Produces the bins:

  • fixed3[0]: 1
  • fixed3[1]: 2
  • fixed3[2]: 4
  • fixed3[3]: 5, 6, 7, 8

Which is counter-intuitive and seems related to handling of duplicate values.

Below is the code used to check the ranges of bins:

# access the backend coverage model object
cg_model = cg_inst.get_model()

# loop over all coverpoints
for cp_model in cg_model.coverpoint_l:
    # print coverpoint summary
    print(f"\nCoverpoint: {cp_model.name}, Coverage: {cp_model.get_coverage():.2f}%")

    # loop over all bins in the coverpoint 
    n_bins = cp_model.get_n_bins()
    print(f"n_bins = {n_bins}")
    for idx in range(n_bins):
        bin_name = cp_model.get_bin_name(idx)
        bin_range = cp_model.get_bin_range(idx)
        hits = cp_model.get_bin_hits(idx)

        # RangelistModel expected to have .range_l (list of [lo, hi])
        if hasattr(bin_range, "range_l"):
            print(f"  Bin: {bin_name}, Range: {bin_range.range_l}, Hits: {hits}")
        else:
            # likely a tuple e.g. (lo, hi)
            print(f"  Bin: {bin_name}, Range: {bin_range}, Hits: {hits}")

This code was used to inspect how PyVSC distributes values across bins and confirm the issue described above.</issue_description>

<agent_instructions>Propose a fix that implements proper IEEE 1800-2023 behavior. Implement tests to confirm proper behavior</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Fix bin_array handling of duplicate values Fix bin_array to retain duplicate values per IEEE 1800-2023 Nov 18, 2025
Copilot AI requested a review from mballance November 18, 2025 17:18
Copy link
Member

@mballance mballance left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

@mballance mballance marked this pull request as ready for review November 18, 2025 17:36
@mballance mballance merged commit 40aa1d6 into master Nov 18, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Possible issue with bin_array not retaining duplicate values as required by IEEE 1800

2 participants