An interesting feature of CertSAFE is that every unit is non-atomic, even reusable components. This means that it is legal in CertSAFE to write a model where the inputs of a component are dependent upon the outputs of the same component, as long as there is no actual data dependency cycle. This is useful for modeling communicating redundant subsystems and other situations.
Suppose we have a CertSAFE project with two diagrams in it. The first diagram, named “My Component”, performs some simple conditional arithmetic depending upon its inputs:
The second diagram, named “Component User”, contains two instances of the “My Component” diagram as custom components, named “My Component 1” and “My Component 2”:
Note that the two instances of My Component are used non-atomically. In My Component 1, the logic for computing output u must be executed before the logic to compute output v can begin, because the output from u is wrapped around to input z. On the other hand, in My Component 2, the value of output v must be computed before the value of output u, because the output from v is wrapped around to input y. This is 100% legal in CertSAFE, because there is no actual data dependency cycle. Note also that the calculations performed using input x are independent of u or v and are required to compute both; wrapping u or v around to input x without a one-frame delay would be illegal, and CertSAFE would generate an error in the definition of the Component User diagram.
It is not always easy to tell when you are and are not allowed to loop a data dependency back around on a component. CertSAFE provides a feature to help you visualize these rules. Simply mouse over an input or output pin of a component in a diagram:
When mousing over an output pin of a component, for each input of the component CertSAFE will display either a blue translucent line, a gray dashed line, or no line at all. A blue translucent line indicates an instantaneous dependency on an input of that component. This means that the value of that input is used to compute the value of that output within a single frame of execution. You cannot use the value of an output to compute the value for an input on which it instantaneously depends without inserting a one-frame delay somewhere to break the logical cycle and ensure well-defined behavior.
A gray dashed line from an output to an input is similar to a blue line, but indicates only a dependency instead of an instantaneous dependency. This most commonly occurs when a component contains a one-frame delay. The complete absence of a line means that the value of the output is not in any way dependent on the input in question. When either a gray dashed line or no line is present between an output and an input, it is permissible to wrap that output around to compute the value for that input.
When you mouse over an input, the same rules all apply, just in reverse: all of the outputs are displayed that have an (instantaneous) dependency on that input.