Note that downsample domains are implemented. Upsample domains are not yet.
This has several subtasks
Simulink and Import
[x] Add rate change blocks to Simulink export script
[x] Modify import script to detect VITIS_CLOCK_DOMAIN subsystems
[x] Implement Generic Rate Change Blocks. These will later be converted to specialized rate change blocks by a pass.
[x] Restrict rate change blocks to have phase 0 (later on, we can add automatic delay insertion to handle other phases)
[x] Write pass to locate rate change nodes and associate them with VITIS_CLOCK_DOMAINS
[x] Write pass to discovery I/O ports associated to clock domains.
[x] Write pass to attach intermediate node for Downsample ClockDomain I/O outputs
Input Validation
[x] Write validation pass for VITIS_CLOCK_DOMAINS and check that all rate change nodes are associated with a clock domain (need to be directly under one). It is allowed for rate change nodes to be within subsystems, just not enabled subsystems or other clock domains.
[x] Create a pass to check that all clock domains are either an integer upsample from the base rate (input rate) or an integer downsample from the base rate. This allows the block sizes for I/O and FIFOs to be statically determined and easy to provide. This requirement may be relaxed later.
[ ] Create a pass to check that the block size works with the clock domains in the design
Multirate Code Emit (Downsample Clock Domain)
[x] Stop Context Expansion (Mux and Enabled Subsystem) at rate change blocks (and I/O blocks if it isn't already)
[ ] Update I/O controller to expand/contract block size for inputs at different rates. Practically, do this by supporting vector I/O (pointer passing is already supported). Create nodes to serve as the select operation for these vectors. These will only be needed in upsampled clock domains. Let these be different from the canonical select nodes as they will take an inner loop index variable as an argument. Downsample domains should have width 1 and the index variable should increment slower.
[x] Implement Specialized Rate Change Blocks (ie Input and Output versions of generic rate change blocks): Use context update nodes for output rate change blocks to update externally facing variables, similarly to how enable outputs are handled. Upsample should create 2 state update nodes, one for when the downsample domain is run and another for when the downsample domain is not run. Since stateUpdateNodeInsertion occurs after encapsulation, should be able to insert into "else" container. Insert a runtime check for this.
[x] Make sure StateVariableUpdateNodes are in the same partition as the block they are modifying. Possibly update partitioning? Inherited partition when created may come to the rescue here. EDIT: Looks like stateUpdateNode insertion happens after partitioning and encapsulation and context is included so this should be a non-issue.
[x] Implement clock domain context logic (including for loop for upsample). Downsample may be more than just an enabled subsystem as an else context is required for upsample output blocks (unless they are implemented with redundant if/else statements). Also, if these clock domains are split, there is no reason to communicate the counter value - it should be replicated. Note that both types of clock domains should be ContextRoots like EnabledSubsystems or Muxes.
[x] Modify encapsulate function to check if ContextRoot needs to replicate conditional logic. Add this as a method to ContextRoot as well as a method to declare if the ContextDriver is replicated for each partition or not. If not, use the old approach of adding new driver arcs.
[ ] Update block size of inter-partition FIFOs based on rate changes
[x] Expand encapsulation to support clock domain subsystems
High Priority Stretch tasks
[ ] Implement a pass to detect partitions that are all in one clock domain and promote that clock domain to be the base rate for that partition. This results in the control for those clock domains being omitted. Possibly add a check of some state variable during context emit to determine if the conditional should be emitted. Also modify I/O and FIFO handling for that partition to account for the change.
[ ] Implement Upsample Clock Domains
[ ] Write pass to insert ClockDomain I/O Select Nodes For I/O (after partitioning) - for upsample domains
Stretch Tasks:
[ ] Allow clock domains to reference another clock domain for merging. Allows a clock domain to be defined inside of a subsystem for code portability reasons but to be re-organized into another clock domain after import. Similar to how subsystems are split when parts are in different partitions. The way we currently do partitions, different separate subsystems can be placed in the same partition just by setting the same partition number. Can discover mergability if all lines not to a rate change block or an I/O line are to another clock domain at the same rate. Merging needs to be done before passes which check constraints on boundary of clock domain (would see lines going between clock domains without rate change blocks).
Direct FIFO I/O (Stretch Tasks for now)
[ ] Update I/O so that input/output FIFOs are directly accessed. Note that this requires that all fanout occur in a single clock domain. Perhaps put this as a TODO to investigate.
Implement Support for Rate Changes in a design
Note that downsample domains are implemented. Upsample domains are not yet.
This has several subtasks
Simulink and Import
Input Validation
Multirate Code Emit (Downsample Clock Domain)
High Priority Stretch tasks
Stretch Tasks:
Direct FIFO I/O (Stretch Tasks for now)
For General Support (postponing for now)