Pattern v2 (pattern_v2)
pattern_v2 is an asset in the ocpi.assets.util_comps component library. Implementations include pattern_v2 HDL Worker (pattern_v2.hdl) and pattern_v2 RCC Worker (pattern_v2.rcc). Tested platforms include xsim, zed, Rocky9.
Design
The pattern_v2 component provides the ability to output a pattern of messages by allowing the user to create a record of messages each having a configurable number of bytes (bytes that are a multiple of 4) and associated 8 bit opcode. Through a set of properties, the component may send messages (data and opcode) up to the amount dictated by the build-time parameters.
The messages property defines the record of messages to send, as well as, defines the number of data bytes and an opcode for each message.
For example:
When messages = {4, 255}, one message will be sent having 4 bytes of data and an opcode of 255. When messages = {8, 251}, {12, 250}, two messages will be sent, the first having 8 bytes of data and an opcode of 251, and the second message having 12 bytes of data and an opcode of 250.
Data to be sent with a message is defined by the data property and is referred to as the data buffer. The number of data words in the data buffer is the number of data bytes for the messages.
The component offers an additional feature when there are multiple messages via the dataRepeat property which indicates whether the a message starts at the beginning of the data buffer, or continues from its current index within the buffer.
For example:
Given messages = {4, 251},{8, 252},{12, 253},{16, 254},{20, 255}
If dataRepeat = true, then numDataWords is 5. To calculate the numDataWords when dataRepeat is true, divide the largest message size (in bytes) by 4. Dividing by four required because the data is output as a 4 byte data word. Since the largest message size in the given messages assignment is 20, 20/4 = 5.
When numDataWords = 5, then a valid data assignment would be data = {0, 1, 2, 3, 4}, and the data within each message would look like: msg1 = {0}, msg2 = {0, 1}, msg3 = {0, 1, 2}, msg4 = {0, 1, 2, 3}, msg5 = {0, 1, 2, 3, 4}
If dataRepeat = false, then numDataWords is 15. To calculate the numDataWords when dataRepeat is false, divide the sum of all the message sizes (in bytes) by 4. Dividing by four is required because the data is output as a 4 byte data word. Since the sum of all message sizes in the given messages assignment is (4+8+12+16+20)/4 = 15.
When numDataWords = 15, then a valid data assignment would be data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, and the data within each message would look like: msg1 = {0}, msg2 = {1, 2}, msg3 = {3, 4, 5}, msg4 = {6, 7, 8, 9}, msg5 = {10, 11, 12, 13, 14}
There is also a messagesToSend property that sets the number of messages to send and decrements as the messages are sent. When dataRepeat is true, messagesToSend is greater than numMessagesMax, and at the end of the messages buffer, the buffer wraps around and starts at the beginning of the messages buffer. When dataRepeat is false, this value must be less than or equal to numMessagesMax. The HDL and RCC worker will check for this and report an error if messagesToSend is greater than numMessagesMax. The error checking for the HDL worker only happens in simulation.
When using pattern_v2.hdl, the messagesToSend, messagesSent, and dataSent properties should be checked at the end of an app run because they won’t be stable until then. The worker doesn’t use cdc crossing circuits for them because it takes advantage that they will have a stable value by the time the control plane reads those values at the end of an app run.
A block diagram representation of the implementation is given in Figure 167:
Figure 167: pattern_v2 block diagram.
Interface
<ComponentSpec>
<Port Name="out" Producer="true"/>
<Property Name="dataRepeat" Type="bool" Default="false" Initial='true' Description="
True - Multiple messages sent from the beginning of the data buffer.
False - Multiple messages sent from the current position of the data buffer."/>
<Property Name="numMessagesMax" Parameter="true" Type="uLong" Default="5" Description="Max number of messages to send."/>
<Property Name="messagesToSend" Type="uLong" Volatile="true" Initial="true" Default="5" Description="Counter of messages to send and decrements as they are sent. When dataRepeat is true,
messagesToSend greater than numMessagesMax, and at the end of the messages buffer, the buffer wraps around and starts at the beginning of the messages buffer. When dataRepeat is false,
this value must be less than or equal to numMessagesMax."/>
<Property Name="messagesSent" Type="uLong" Volatile="true" Description="Messages sent counter. Initialized to 0."/>
<Property Name="dataSent" Type="uLong" Volatile="true" Description="Words sent counter. Initialized to 0."/>
<Property Name="numDataWords" Parameter="true" Type="uLong" Default="15" Description="Max number of four byte data for the data buffer. To calculate
the numDataWords when dataRepeat is true, divide the largest message size (in bytes) by 4. To calculate the numDataWords when dataRepeat is false,
divide the sum of all the message sizes (in bytes) by 4. Dividing by four required because the data is output as a 4 byte data word."/>
<Property Name="numMessageFields" Parameter="true" Type="uLong" Default="2" Description="Due to a limitation (AV-4292), cannot use constrained elements
in unconstrained array declarations, so cannot directly set the second dimension for the messages property to 2. The numMessageFields property must
always be 2 since there are 2 message fields; the number of data bytes (bytes that are a multiple of 4) and opcode. So the default value must not be changed."/>
<Property Name="messages" Type="uLong" ArrayDimensions="numMessagesMax, numMessageFields" Initial="true" Description="Multidimensional array that defines
the record of messages to send, as well as, defines the number of data bytes (bytes that are a multiple of 4) and an 8 bit opcode for each message."/>
<Property Name="data" Type="uLong" ArrayLength="numDataWords" Initial="true" Description="Data buffer containing the data to be sent."/>
</ComponentSpec>
Properties
dataRepeat: True - Multiple messages sent from the beginning of the data buffer. False - Multiple messages sent from the current position of the data buffer.Type:
boolAccess:
Parameter:
FalseWritable:
FalseInitial:
TrueVolatile:
False
Default value:
false
numMessagesMax: Max number of messages to send.Type:
ulongAccess:
Parameter:
TrueWritable:
FalseInitial:
FalseVolatile:
False
Default value:
5
messagesToSend: Counter of messages to send and decrements as they are sent. When dataRepeat is true, messagesToSend greater than numMessagesMax, and at the end of the messages buffer, the buffer wraps around and starts at the beginning of the messages buffer. When dataRepeat is false, this value must be less than or equal to numMessagesMax.Type:
ulongAccess:
Parameter:
FalseWritable:
FalseInitial:
TrueVolatile:
True
Default value:
5
messagesSent: Messages sent counter. Initialized to 0.Type:
ulongAccess:
Parameter:
FalseWritable:
FalseInitial:
FalseVolatile:
True
Default value:
None
dataSent: Words sent counter. Initialized to 0.Type:
ulongAccess:
Parameter:
FalseWritable:
FalseInitial:
FalseVolatile:
True
Default value:
None
numDataWords: Max number of four byte data for the data buffer. To calculate the numDataWords when dataRepeat is true, divide the largest message size (in bytes) by 4. To calculate the numDataWords when dataRepeat is false, divide the sum of all the message sizes (in bytes) by 4. Dividing by four required because the data is output as a 4 byte data word.Type:
ulongAccess:
Parameter:
TrueWritable:
FalseInitial:
FalseVolatile:
False
Default value:
15
numMessageFields: Due to a limitation (AV-4292), cannot use constrained elements in unconstrained array declarations, so cannot directly set the second dimension for the messages property to 2. The numMessageFields property must always be 2 since there are 2 message fields; the number of data bytes (bytes that are a multiple of 4) and opcode. So the default value must not be changed.Type:
ulongAccess:
Parameter:
TrueWritable:
FalseInitial:
FalseVolatile:
False
Default value:
2
messages: Multidimensional array that defines the record of messages to send, as well as, defines the number of data bytes (bytes that are a multiple of 4) and an 8 bit opcode for each message.Type:
ulongArray dimensions:
['numMessagesMax', 'numMessageFields']
Access:
Parameter:
FalseWritable:
FalseInitial:
TrueVolatile:
False
Default value:
None
data: Data buffer containing the data to be sent.Type:
ulongArray dimensions:
['numDataWords']
Access:
Parameter:
FalseWritable:
FalseInitial:
TrueVolatile:
False
Default value:
None
Ports
Inputs:
None.
Outputs:
outProtocol:
NoneOptional:
False
Implementations
Dependencies
The dependencies to other elements in OpenCPI are:
assets/components/util_comps/pattern_v2.hdl/pattern_v2.vhd
core/hdl/primitives/util/BRAM2.v
core/hdl/primitives/util/util_pkg.vhd
assets/components/util_comps/pattern_v2.rcc/pattern_v2.cc
Limitations
Limitations of pattern_v2 are:
None.
Testing
The pattern_v2 worker is tested by generating data for the messages and data properties and verifying that final value of the volatile properties and the output data are correct. Since the pattern_v2 worker’s messages and data property array sizes depend on parameters, they have to be generated via scripts(gen_messages.py and gen_data.py)