Open gauravjain14 opened 5 years ago
You do not say what size of transfer you are attempting to send. The WidthWidget preserves transfer size, only varying the subset of the transfer sent on each beat. So, the number of beats that will be taken to process the transfer on each side of the interface equals (transfer_size/beat_bytes). For example, if the transfer is a single byte, it will only take a single cycle to accept it on one side, but also only a single cycle to send on the other side, even though the width of the data paths on each side are different.
If your transfer size is larger than InputBeatBytes, and so takes multiple beats to be accepted by the adapter, then the TileLink spec prohibits changing the source ID between different beats of the message. Violating the spec will result in undefined behavior.
If you would like to add more unit tests for the WidthWidget device, you might try adding them to the WithTLWidthUnitTests
configuration in the unittest
package and observe the behavior under test there.
Thank you for your response. I have figured out the issue. The scenario I was trying to simulate should never occur which is exactly what you have mentioned by saying that the source ID between different beats will not vary.
However, I have another question. Can the transfer sizes on the receiving and transmitting ports be different? If yes, then how is the source ID violation prevented in this scenario, as in can I have a transfer size of 64-bits on the receiving side and 128-bits on the transmitting side, even when the data width is same on both the ports?
How is the source field of taken care of while upscaling (if there is any)?
The transfer size is a property of the message itself, not the underlying wire serialization. So, no matter what happens to the width of the wires, the transfer size will remain constant unless an adapter is inserted to specifically change it. One adapter that changes the transfer size is the TLFragmenter
, which takes a message of a large size and fragments it into multiple messages of a smaller size. (Again, this fragmentation is totally orthogonal to the width of the data transferred on each beat.) The Fragmenter must give each of the new smaller messages a new source id. On the return path, the Fragmenter collects responses (with matching but unique source ids) for all the fragments it sent out, before sending a response to the original source id. (Note that source ids are only required to be uniquely in flight on any one link, and can be reused on different links). I don't know that we have an example of taking a small transfer size and making it larger, but presumably you could just keep using the same source id.
I have been trying to simulate the TLWidthWidget RTL implementation.
The following the TLWidthWidget configuration - Input BeatBytes = 64, Output BeatBytes = 512 Input Source width = Output Source width = 5 bits
To simulate:
Observation:
Since the ratio of OutputBeatBytes/InputBeatBytes = 8, for every 8 transfers on the input port, one
auto_out_a_valid
is generated (corresponding to valid 512 bites).What I have observed is that the
auto_out_a_bits_source
=auto_in_a_bits_source
wheneverauto_out_a_valid
is valid, and theauto_in_a_bits_source
for the remaining transfers is discarded/not used. If my understanding and observation is right, then this should imply that given there are 32 source values possible and that the ack is issued after 32 transactions on theauto_out_d_*
port, then only 4 valid transactions can be issued by the TLWidthWidget due to no more Ids remaining for which the Ack has been received and thus unnecessarily halt the system when 32 such transactions were possible.In addition, even if the Ack is issued,
auto_in_d_bits_source = auto_out_d_bits_source
further implying that the source ids which are never latched onto the output are never Acked and thus can never be used in the subsequent transactions.Kindly let me know if what I've mentioned is an intended behaviour or if my observations are absolutely wrong, being so, kindly let me know, what would be the best to verify the functionality of the rocket-chip at the submodule level