Home > Community > Blogs > Functional Verification > using constraints to pass configuration options in the unit hierarchy top down approach
 
Login with a Cadence account.
Not a member yet?
Create a permanent login account to make interactions with Cadence more conveniennt.

Register | Membership benefits
Get email delivery of the Functional Verification blog (individual posts).
 

Email

* Required Fields

Recipients email * (separate multiple addresses with commas)

Your name *

Your email *

Message *

Contact Us

* Required Fields
First Name *

Last Name *

Email *

Company / Institution *

Comments: *

Using Constraints to Pass Configuration Options in the Unit Hierarchy (Top-Down approach)

Comments(0)Filed under: Functional Verification, Incisive Enterprise Simulator (IES), e, Specman, IEEE 1647, Aspect Oriented Programming, AOP, IntelliGen, IES-XL, team specman

To allow for increased solvability, some constraints that were previously uni-directional with the old “Pgen” generator are now treated by IntelliGen in a bi-directional manner by default.  This behavior dramatically improves solvability and gives you a lot more freedom in writing and layering very complex constraints. 

However, if you are coding with a Pgen frame of mind there is one case where the results might not be what you expected.  Specifically, the behavior of IntelliGen can differ from Pgen for the case where you want to constrain a child struct’s fields from within the parent (for example, when you want to pass configuration options down the unit hierarchy).  Fortunately, the code needed to address this situation is very simple to apply. Consider the following general example:

 

type size_t: [SMALL, MEDIUM, LARGE];

 

struct config_s {

   sz: size_t;

   valid: bool;

}; // struct config_s...

 

unit agent_u {

   cfg: config_s;

   bfm: bfm_u is instance;

   keep bfm.cfg == cfg;    // constraint [1]

}; // unit agent_u

 

unit bfm_u {

   cfg: config_s;

   keep soft cfg == NULL;        // constraint [2]

}; // unit bfm_u

 

unit env_u {

   agent: agent_u is instance;

}; // unit env_u



Specman users familiar with Pgen will know that Pgen will treat constraint [1] as unidirectional (from agent_u.cfg to agent_u.bfm.cfg), allowing agent_u.cfg to be randomly generated, and then pushing that struct down to agent_u.bfm.cfg.  Additionally, constraint [2] will not be enforced given that it is a soft constraint (and of course with Pgen the user would have to make constraint [2] a hard constraint in order for it to be enforced.)  If we run the above code we would find that agent_u.cfg and agent_u.bfm.cfg both point to the same config_s instance.  Here is the potential gotcha: since constraint [1] is unidirectional, (soft) constraint [2] will be ignored, which might not be the intended behavior – in this example it’s not clear if the user truly desired the cfg struct of the bfm_u to be NULL

Now consider the behavior of this code with IntelliGen: IntelliGen will treat constraint [1] as bi-directional by default.  As a result, constraint [2] will be applied in addition to constraint [1], Users will find that both agent_u.cfg and agent_u.bfm.cfg both point to the same instance of cfg_s which, in this case would be a NULL struct.  IntelliGen will apply all constraints in the above example, which is generally more intuitive and showcases the additional solving capabilities of IntelliGen.

But what if the intention was to pass the value of parent fields down into child structs in a purely top-to-bottom, unidirectional way?  The correct way to implement this in IntelliGen would be to wrap the right hand side of the constraint in a read_only() to enforce top-down unidirectionality (because wrapping constraint variables in read_only() causes them to be generated first), as shown in the following example:

 

type size_t: [SMALL, MEDIUM, LARGE];

 

struct config_s {

   sz: size_t;

   valid: bool;

}; // struct config_s...

 

unit agent_u {

   cfg: config_s;

   bfm: bfm_u is instance;

   keep bfm.cfg == read_only(cfg);     // constraint [1]

}; // unit agent_u

 

unit bfm_u {

   cfg: config_s;

   keep soft cfg == NULL;        // constraint [2]

}; // unit bfm_u

 

unit env_u {

   agent: agent_u is instance;

}; // unit env_u

 

In the above example, constraint [2] would not be enforced as sys.agent.bfm.cfg would point to the same cfg struct as its parent due to constraint [1].  Without the read_only(), constraint [1] would be bidirectional and IntelliGen would also consider constraint [2], hence the NULL cfg struct in bfm_u would be propagated upwards through the hierarchy resulting in sys.agent.cfg == NULL.

Bottom line:
IntelliGen has improved solvability over the previous generation engine (Pgen) given more constraints are now treated as bi-directional by default.  Thus if you would like to push parent fields down into lower level child structs, you will need to wrap the parent field value in a read_only() call.

Corey Goss

Comments(0)

Leave a Comment


Name
E-mail (will not be published)
Comment
 I have read and agree to the Terms of use and Community Guidelines.
Community Guidelines
The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.