HDL Primitive Best Practice
Primitive Description
A primitive is a unit of HDL processing (typically a Verilog or VHDL module); primitives are lower level modules than workers and only relevant to HDL implementations (currently). Primitives are considered finished when there is the HDL implementation. It is encouraged that each primitive be tested and accompanied by supporting documentation.
Primitives must complete generic processing functions and must not be application specific. Any primitive in OpenCPI should be used in at least one OpenCPI worker.
Primitives are created when a function is, or likely to be, used/shared among multiple workers. They are grouped together in primitive libraries. Primitives may also be based on externally supplied preexisting Verilog or VHDL modules that need to or are preferred to be used untouched.
Scope and Size
OpenCPI defines primitives as “… HDL assets that are lower level than workers and may be used as building blocks for workers”.
Primitives are created when a function is likely to be used/shared among multiple workers. They are grouped together in primitive libraries. When workers are created that could share functionality with other existing workers, primitives should be created to share that code.
Primitives should contain only a single implementation of their functionality. For example in a complex stream worker which operates on the real and imaginary inputs separately this should contain two primitives, one for the real part of the data and one for the imaginary part of the data rather than a single primitive which does both.
Primitives should include a single function, if the primitive could be used in multiple ways it should be broken up into multiple primitives that can be used in a single way. It is worker’s responsibility to group primitive functionality together.
Primitive code should be in a single file. If a primitive is split over multiple files it is encouraged that this trigger consideration as to whether the primitive should be split into multiple primitives.
Primitive libraries
Primitive libraries should group similar primitives together. It is allowable to move primitives between libraries or split libraries to keep libraries as similar collections. Since moving primitives between libraries effects the compatibility of the library and project, moving primitives between libraries should not remove the existing primitives until one release later with a deprecation notice.
If a primitive can fit into the definition of multiple primitive libraries, the primitive should be placed into the primitive library the primitive most closely matches. Historical precedence can be used as the final decider for which primitive library a primitive is placed in, if there is no other deciding factor available.
If historical precedence is becoming a major and frequent decider on which library a primitive is to be placed in, this should trigger consideration as to whether the primitive libraries need to be re-organized.
“Miscellaneous” primitive libraries should not be used. Ideally libraries will contain more than one primitive, however it is acceptable to have a library of a single primitive particularly if this prevents the need for a miscellaneous library — but libraries should not be named or designed to have a single primitive.
Primitive Library Naming
All library names should contain a short description of the library. This description should be a noun. The description should only use widely recognized acronyms. Abbreviations or shortening of words should not be used (e.g. num should not be used in place of number).
The library name should be all lower case with words separated by an underscore.
Primitive Name
Primitive names should be all lower case with underscores between words.
Primitive names should be a short description of the function the component implements. The description should start with the key functional behavior and be appended with implementation variations (e.g. fir_filter and fir_filter_scaled). This description should be a noun of the implementation, rather than a verb (e.g. cic_decimator rather than cic_decimate). The description should only use widely recognized acronyms. Abbreviations or shortening of words should not be used (e.g. “num” should not be used in place of “number”), the exception to this is for the following mathematical terms:
“sin” in place of sine
“cos” in place of cosine
“tan” in place of tangent
“log” in place of logarithm