HDL Worker Best Practice
An HDL worker implements the functionality of a component. When possible, the worker should utilize available primitives so as not to duplicate code logic. When logic is likely to be useful by one or more other workers, then development of a primitive for that logic should be considered. When writing a new worker that would like to use logic in another worker, then refactoring the worker and creating a new primitive should be considered.
For workers that implement functionality that is contained in primitive(s), the only actions the worker should do is connect primitives and handle the protocol interfacing. In cases where the protocol interface handling is complex then protocol handling primitives should be used across the whole library or project, as appropriate.
It is encouraged that even simple workers implement a similar structure to that described above, since this will enable easier updating of protocols and protocol handling primitives in the future.
HDL Worker Description XML File
For any component with stream interfaces, there should be at least one worker whose data path widths match the primary data types of the protocol. For complex types this should mean the width of the real and imaginary (I and Q) parts together (i.e. 32 bits for complex-short).
It is encouraged for workers to have parameterized data widths for smaller (e.g. 16 bits for complex short), or larger (multiple data values at a time) to accommodate systems optimized for those widths (e.g. pure 16 bit data paths) and to improve performance with parallelism (e.g. with 128 bit data paths). Such parameterized code should not make the basic implementation using the natural data path width (e.g. 32 bits for real/imaginary) slower or larger. I.e. parameterization of data width may be accomplished by additional/different workers or using parameterization of the port data path width in a single worker.
HDL worker description files should include the streaminterface width.
Where used, a specproperty should not have a default attribute set, as the property in the component specification should have a default value and there is a desire to keep this behavior the same across workers. If a property (not specproperty) is defined in the worker description, then this should have a default value.
Any properties that are defined in the worker description should follow the same guidelines as for component wide properties as set in the component specification XML file.
Input Data and Signals
Since logical checks on input properties add an overhead to the implementation, the design approach with HDL implementations should be to prevent out-of-range properties being set (i.e. if an input property is 8-bits wide due to the implementation requirements the tested and supported range of values should be 0 to 255).
When an input property or data checks are implemented if an erroneous input is detected then the ctl_out.error signal should be asserted in response to the start control operation.
The HDL implementation must support “back-pressure”. Back-pressure is the ability of a component to handle the output not being ready to receive data, so holding the next output values and flagging this backwards along the processing chain. I.e. components should only give data to their output’s when the output(s) are ready and should only take data from their input’s when their input(s) are ready and data will not be dropped due to output not being ready.
A component specification and documentation may specify behavior that involves dropping data in the face of back-pressure, but this should rare and explicit and a volatile property should indicate that it happened.
The HDL implementation should support all aspects of the protocol, which may require proper handling of start-of-message and end-of-message.
Data-only protocols (those that only support one message type which contains data to be processed) should use the “version 2” HDL worker interface and can thus avoid start and end of message handling.
The HDL implementation should support “zero-length-messages” only if specified in the protocol. Messages that are variable length sequences do not have to support the case of zero length sequences, and such messages should not be produced. In the future this may be considered a runtime error.
When the control input ctl_in.is_operating is false then the component should stop. No new data will be offered to the worker if ctl_in.is_operating is false, but any other processing unrelated to the availability of input data or output port readiness should cease.
When the control input ctl_in.reset is asserted, the component state should reset, and the reset state should be the same as the initial state. All reset inputs are synchronous and should be processed as such.
Return Conditions
Under normal operation the error signal ctl_out.error signal should be set to 0. When an error state needs to be returned by an HDL worker in response to a control operation, the error signal should be set to 1. If statically asserted, this indicates the error response to all control operations.