How is scan rate / execution order determined when using "Module Blocks"

I ran into a case last week where there was a module, that contained a module block ref, that contained another module block. Besides being a major "no-no pet-peeve" of mine, I feel that it goofs up the scan rate and/or execution order of the modules a bit. Does anyone know for sure what happens in this case? Can anyone elaborate on the "shared" and "private" options when using this feature?

  • In reply to Tyler Anderson:

    Just want to clarify a couple of points.  First, module execution order is not based on Alphabetical module names.  During a total download, modules are downloaded in alphebetical order, but the controller scheduler balances modules over execution time slices, so that all modules execute at their configured scan rate.  If 20  modules with a scan rate of 1 second are downloaded, the scheduler will assign one module to each time slice, spread out over one second.  The 21st module will be assigned to the first time slice with the 1st module, etc.  If you download 20 modules with a 100 ms execution rate, each module executes 10 times per second, so you would find have the modules in one time slice and the other in the next.  As the modules arrive (in alphebetical order), the scheduler balances these time slices to get the same number of modules in each time slice.  So execution order is not something you control by naming modules in alphabetical order.

    As for Embedded Module blocks, these provide access to the referenced modules, but in now way affect the execution of those modules.  When the Embedded block "executes" within the host module, it reads data from the referenced module.  The data resides in the referenced module memory space.  

    As for writes to the embedded module block this is done in two ways:  Typically, a value is wired to an exposed parameter on the Embedded block, say "CAS_IN".   This parameter is configured in the referenced module as a "Floating Point with Status".  This is for convenience in configuration.  The Parameter is created in the module and the module is referenced with an Embedded Module block, and the parameter shows up as a connection point.  HOwever, at Run Time, DeltaV optimizes this to be a read by the referenced module.  The CAS_IN parameter becomes an External Read parameter with the path set to the source of the wired connection.  Why?  Because using a read allows this module to be in a remote controller and Unsolicited reads bring the CAS_IN value to that location.  When the modules are in the same controller, the module reads the CAS_IN Source value from the Embedded block host module at the time it needs it.

    If the Host module uses an expression to write to the Embedded Block CAS_IN connection, the parameter will not be changed to an external read and the Write will be made when the host module executes the write.  This is fine if both modules are in the same controller.  IF the destination module is moved to another controller, these write will still work, but should be done by exception, and should be avoided.  If this is a continuous write (ie a cascad Master to Slave loop) you should use the wired connection and let DeltaV perform the execption reporting between the nodes.  

    Both these methods behave very similar in runtime.  If you read the slave loop's "CAS_IN Parameter, the controller redirects you to the source parameter memory location, so you get the value you expect, except it comes from the source, not the destination.  If you write with an expression, the CAS_IN will hold the value written, and if you read this parameter, you get the same value.  In both cases, if you read the BLock/CAS_IN value in the slave loop, it will not hold the new value until that module executes and the transfer of the wired connection is made.

    The Ownership level determines whether the block can be embedded in multiple modules or whether it is deditcated to a single "Master", as in the case of a typical Cascade loop.  You can still make references to a Slave loop that is owned by a master, but you cannot embed the module as a block if it is owned by another module.  This avoids wiring up the same parameter in two or more modules.  

    The Embedded Module Block is provided to aid in visuallizing a complex strategy using the upper level module, and seeing how data is moved between the modules by the master module.  For instance, a lead/Lag controller of Fuel and Air flows controlled by the Boiler master.  The BG Station provides the SEt point for both fuel and Air, but cross limiting is applied so that Aire leads fuel on increase and lags fuel on decrease.  This lead lag logic can be done in the master BG loop, and connection to the two Flow loops done with embedded module blocks.  Alterhantively, the cross limiting could be done inside each of the two flow loops, but you would not be able to "Tune" this behavior along with the excess air curve, in the master BG module.  One might argue that doing the cross limiting in the BG module adds delay between the two flow loops, but in reality, this is inconsequential to the header pressure loop that drives the BG, and the dominant lag in that loop.  

    So, to recap, Embedded Module Blocks have no effect on module execution rates or order of exectuion.  Order of execution is not controlled by configuration, other than to use different scan rates where appropriate, such as a faster scan rate on the flow loop of a cascade Level control.  The Master will be slower due to its overall time constant.  

    Andre Dicaire