In this note, I have proposed overview of one alternative solution which may be considered to address this mantis issue (1). I have also described some generic points that the committee can consider before finalizing the syntax/semantics (2). Finally, I have captured some comments regarding the existing proposal (3). I would request the committee members to provide their valuable comments/feedback on these items so that we can finalize the syntax/semantics. 1. Overview of alternative Solution: --------------------------------- This approach is suggested based on two considerations, namely, usability and backward compatibility. Allow refering coverpoints from different covergroups using scope resolution operator "::" as shown below. covergroup cg; A: coverpoint a; B: coverpoint b; endgroup covergroup cg1; cross cg::A, cg::B; endgroup When user declares such coverpoints, an implicit coverpoint matching "A" can be created within the scope of "cg1". For embedded covergroups, since we cannot access the anonymous type of covergroup, we may allow users to specify the covergroup instance as shown below: class c1; covergroup cg; A: coverpoint a; B: coverpoint b; endgroup covergroup cg1; cross cg.A, cg.B;// "cg" is basically instance name endgroup endclass This approach will prevent instantiating "cg" inside "cg1". As "cg" is not constructed, the sampling of "cg" will also not happen. "cg1" will have an implicit coverpoint "A" matching it's declaration in "cg" and that will be sampled with every sample of "cg1" instances. 2. Other Points to Ponder: -------------------------- In this section I have captured some possible approaches which are radically different but may be aligned with long term syntax of covergroups. The committee needs to decide if such approaches will be viable or not. 2.1 Support extending covergroups just like a class. Then declare the coverpoints in base class and declare the cross in derived class. In this way, the derived class cross is able to reference the base class coverpoints. Also this approach has the limitation that cross can only be formed using coverpoints of the parent class. 2.2 Support multiple inheritence for covergroups. This will address the limitation of the previous approach. Cross can be declared using the coverpoints from different covergroups not necessarily within the same covergroup hierarchy. But again this is a major modification given that multiple inheritence is not supported even for classes. 2.3 AOP extension of classes and how that can impact this feature (?) 3. Points to be clarified w.r.t. the suggested approach in the mantis: ---------------------------------------------------------------------- These are already emailed to sv-ec. I am capturing some of them for reference. Some comments below are based on the example already provided with the mantis. ====================================== Queries on mantis 2993 ====================================== Q1. In case of embedded covergroups, LRM says that anonymous type is defined. So, the proposed syntax is not clear on how user can do this for embedded cgs? Consider the following example. How does the user declare an instance "cg1_inst" inside "cg2" declaration? class c1; int a,b; covergroup cg1; A: coverpoint a; B: coverpoint b; endgroup covergroup cg2; cg1 cg1_inst = new; <<------- This will not be allowed as "cg1" is the instance name and not the type X: cross cg1_inst.A, cg1_inst.B; <<----- So, in order to make this work, we need to think about some modification endgroup function new; cg2 = new; endfunction endclass Q2. Please consider the following example. covergroup cg1 @ clk; A: coverpoint a; B: coverpoint b; endgroup covergroup cg2; cg1 cg1_inst = new; X: cross cg1_inst.A, cg1_inst.B; endgroup cg2 cg2_inst = new; cg2_inst.sample(); In this case, how many items will be considered to belong to "cg2"? Should we consider only cross X as part of "cg2"? As per my understanding, we should consider only the cross X as part of "cg2". This makes sense because "cg2" does not inherit the items from "cg1" and just uses them using hierarchical references. Q3. In the example given with Q2, when user does the instantiation of "cg1_inst" inside "cg2", will it start the sampling of this covergroup instance such that sampling of a, b happens at every event on "clk"? OR the sampling of "cg1_inst" will only happen when sampling of "cg2_inst" happens using sample() method as shown? This will determine the coverage numbers for covergroup type "cg1". Q4. In the example given with Q2, if option.per_instance for "cg1" is set to 1, then will the instance-based coverage of "cg1_inst" be tracked and reported? Please note "cg1_inst" is declared inside "cg2" just to enable "cg2" to access its coverpoints. This instantiation does not intend to create a separate independent instance of "cg1". Is this the expected behavior? Q5. Please look at the following example. This is similar to example shown in Q1 with the addition of one more instance of "cg1" outside the scope of "cg2". covergroup cg1 @ clk; A: coverpoint a; B: coverpoint b; endgroup covergroup cg2; cg1 cg1_inst = new; X: cross cg1_inst.A, cg1_inst.B; endgroup cg2 cg2_inst = new; cg2_inst.sample(); cg1 cg1_inst_out = new; <<----------- Instance of "cg1" outside the scope of "cg2" In this case, we need to understand the sampling semantics clearly. One interpretation of the sampling semantics may be: - "cg1_inst_out" samples at every "clk" event independent of "cg2_inst". - In addition, when "cg2_inst" samples using the sample() method, the coverpoints A, B in "cg1_inst" should also sample. Please let me know your views on this. Q6. Should we allow following ways of cyclic specifications? covergroup cg1 @ clk; A: coverpoint a; B: coverpoint b; cg2 cg2_in_1_inst = new; <<------- cg2 used in cg1 cross cg2_in_1_inst.cg1_inst A, A; <<---- accessing same item A endgroup covergroup cg2; cg1 cg1_inst = new; <<----- cg1 used in cg2 X: cross cg1_inst.A, cg1_inst.B; endgroup cg2 cg2_inst = new; cg2_inst.sample(); Q7. The syntax given in example is probably incorrect, The first item mentioned in the cross refers to the covergroup instance "pe" and not any coverpoint inside "pe". Also the second item in the cross declaration i.e. "op.op.prec" is incorrect. If we assume it is "op.op_prec" then also it is wrong because LRM doesn't allow cross of cross. This needs to be clarified. covergroup stage_corners(ref bit ovr_bit, ref bit udr_bit, ref bit err ..., ref bit [71:0] op, ref bit[1:0] precision); pipe_events pe = new(ovr_bit, udr_bit, err,...; opcodes op = new(op, precision); cross pe op.op.prec; <<-------- Issues here as noted above. endgroup