Scoping
-------
In a constraint program, it is often convenient to be
able to navigate to a particular instantiation of a module
in a hierarchical design before applying constraints to objects
in that module and/or its descendents. There are a couple of
underlying reasons why this is useful:
- Hierarchy-based inheritance minimizes the number of
constraints that a designer must specify, decreases
the likelihood of unintentional inconsistencies, and
is more robust in the face of incremental changes to
the design
- Relative names can be used for design objects contained
within a portion of the hierarchy.
Some examples of hierarchy-based inheritance include
- setting wire load models to be the same for a hierarchical
portion of the design
- specifying different operating conditions for a voltage island
- indicating that cycle stealing should not be allowed for any
of the latches in a part of the design.
In a declarative language, there may be inheritance
mechanisms built into the language, and there is a
natural scoping inherent in specifying constraints
within the description of a module. In an executable
language, there may be primitives that find all of the
objects of a given type within a portion of the hierarchy.
When an expanded DCD is used as the basis for exchanging
constraints between multiple tools in a flow, we need to
make sure that the designer's original intent for the
scope of each constraint is preserved. If we interpret
the scope in one tool and expand the constraints to
explicitly refer to all of the objects within that scope,
then we won't have a basis for applying the designer's
original intent to subsequent changes to the hierarchy or
incremental additions (buffer insertion, etc).
On the other hand, we've explicitly decided to avoid
including macros like find or all_registers in DCDL.
Our expectation is that the application's constraint
programming environment (e.g., DCDL + application-specific
macros and commands + TCL) will provide these features
in the forms that designers are already comfortable
with.
Suggestions:
- Include a notion of "current scope" in DCDL
which corresponds to module boundaries in
declarative languages
- For constraints where inheritance is useful,
provide a mechanism for specifying an explicit
default value that implicitly applies to relevant
objects within the current scope. We may need
to distinguish between defaults that apply to
objects directly instantiated within the current module,
and defaults that apply to objects within the current module
and any of its descendents.
Defaults
--------
Either in combination with inheritance or without it, it is
useful to be able to specify a default value that applies to
all objects of a given type.
In constraint programming languages, there is typically a
macro that expands into a list of all of the objects of a
given type. Default values are specified using that macro,
then overridden or reset on particular objects in the list.
Although this approach works well within a single tool, it
presents a problem for constraint interchange between multiple
tools in a flow.
When the macro is expanded (which would typically occur
within the TCL interpreter so that the application never
even sees that the macro was used), the designer's intent
of distinguishing between a default value and explicitly
specified values is lost. Subsequent changes to the design
may introduce new objects of the same type, which would be
included in the list if the macro were re-expanded at that
point. The effect (potentially far downstream in the flow
from the original constraint entry point) is that objects
that should be constrained will not be.
Suggestions:
- Introduce a notion of default values in DCDL which are
explicitly maintained, rather than expanded.
- Specify these default values in one of ways
1. Through special default_xxx commands
2. Through the use of a special -default option on
each command
3. Through omitting a list of objects where a list would
normally be specified on each command
I prefer 3.
General Precedence Rules
------------------------
In a constraint program, it is possible to specify several
related constraint values using multiple commands. I think
of each constraint as having a number of value slots, where
each value slot may be filled by default, by an explicit
specification, or by precedence resolution across a default
and one or more explicit specifications.
For example, an arrival time for a given input pin and
referenced to a particular clock edge will have four value
slots:
- the minimum rise time
- the maximum rise time
- the minimum fall time
- the maximum fall time
Constraint programming languages typically allow a designer
to specify a single number that applies to all four value
slots or separate numbers for each slot. It is also typical
to allow some of the slots to remain unspecified.
When there are several commands that affect the same slot,
typically the last command has the highest precedence and
the value specified with that command overrides any previous
value in the slot. However, in some cases it is useful to
accumulate the worst case value across all of the commands
that affect the same slot. In this case, there is usually
an option on the command to indicate whether the value
specified should override previous values or be merged with
them.
With inheritance, there is the chance that a particular
value slot may be affected by default constraint commands
specified at two different levels in the design hierarchy.
In this case, whether the precedence is based on scoping
or order is important.
It is also possible that a default constraint specifies a
value for a particular value slot, but on certain design
objects the value should remain unspecified. In a constraint
programming language, there are usually commands that unset
a constraint which can be used for this purpose.
In addition to these general types of precedence rules,
there are many domain-specific precedence rules. The
domain-specific precedence rules arbitrate between similar
constraints which have the same purpose (such as driver
cell type, driver strength, and input slew), or between
constraints that overlap in their effect (such as a default
slew for all internal pins and a default slew specific to the
leaf pins in a particular clock tree).
In a declarative language, there are less likely to be issues
associated with multiple explicit specifications for the same
value slot. It seems likely that this would be result in a syntax
error. However, the precedence issues related to inheritance
and defaulting will still apply.
Suggestions:
- Treat each value slot on each design object independently
for all precedence resolution.
- Include a -merge option in each explicit constraint command.
If -merge is not specified, the constraint value(s) override
the existing values in each value slot. If it is specified,
the constraint values are merged in a worst case fashion with
the existing values.
- For default values, have the precedence be scope-based. A
default value specified at a lower level in the hierarchy
overrides a default value specified at a higher level in the
hierarchy. When multiple commands are specified at the same
level of hierarchy, have the precedence be order-based, so
that the last one specified wins.
- Have values specified explicitly on a particular design
object override default values, and have the precedence
between explict values be order-based.
- Have either an option to each command to explicitly reset a
value slot to unspecified, or a placeholder for the value that
indicates the same (such as an asterisk).
- Don't specify anything domain-specific in the general
precedence rules, but ensure that the domain-specific
precedence rules follow similar conventions.
Thanks,
Mark
-- Mark Hahn phone: (408) 428-5399 Architect, Deep Submicron Business Unit fax: (408) 428-5959 Cadence Design Systems email: mhahn@cadence.com