Ordering (NOC, CMD_BUF, VC)
NoC requests/responses are usually asynchronous, but they can have an implicit ordering, or you could enforce an explicit ordering. In this section, we will go over command buffers (CMD_BUF), virtual channels (VC), and allocation of virtual channels.
There are two NoCs (NoC-0 and NoC-1) that are completely phyiscally replicated and separated. The only communication between these NoCs is through software or L1 memory. For each NoC, we have 4 command buffers: RD_CMD_BUF, WR_CMD_BUF, WR_REG_CMD_BUF, AT_CMD_BUF. We usually use the WR_CMD_BUF for all writes, except for the atomic ones where we use AT_CMD_BUF, e.g. noc_semaphore_inc uses AT_CMD_BUF.
For each NoC, we have 6 VC (numbered 0-5). Each VC is usually used for a different purpose. For example, all unicast writes go on NOC_UNICAST_WRITE_VC, which is VC 1, and all multicast writes go on NOC_MULTICAST_WRITE_VC, which is VC 4.
We can allocate VC either statically or dynamically. We can allocate VC statically using NOC_CMD_STATIC_VC, which is usually the case for noc writes. For noc reads, the read requests can use a statically allocated VC, as for read responses, we always use dynamically allocated VC. So there’s really no way to control ordering for data reads.
As for ordering of the NoC writes:
If writes are on different NoCs, there is no ordering guarantees.
If writes are on the same NoC but different VCs, there’s also no ordering guarantees. You might as well use different CMD_BUFs to avoid serialization.
If writes are on the same NoC and same VC, they will be ordered based on program order, regardless whether you use the same CMD_BUF or different ones.