The
PCI Express®
Specifications require that the completer request
interface continue to deliver Posted transactions even when the user logic is unable to
accept Non-Posted transactions the interface. To enable this capability, the core
implements a credit-based flow control mechanism on the completer interface through
which user logic can control the flow of Non-Posted requests across the interface,
without affecting Posted requests. The user logic signals the availability of buffers to
receive Non-Posted requests to the core using the pcie_cq_np_req[1:0]
signal. The core delivers a Non-Posted request to the user logic only when the available
credit is non-zero. The core continues to deliver Posted requests while the delivery of
Non-Posted requests has been paused for lack of credit. When no backpressure is applied
by the credit mechanism for the delivery of Non-Posted requests, the core delivers
Posted and Non-Posted requests in the same order as received from the link.
The core maintains an internal credit counter to track the credit available for Non-Posted requests on the completer request interface. The following algorithm is used to keep track of the available credit:
- On reset, the counter is set to 0.
- After the interface comes out of reset, in every clock cycle:
- If
pcie_cq_np_req
is non-zero and no Non-Posted request is being delivered this cycle, the credit count is incremented by 1, unless it has already reached its saturation limit of 32. The increment amount is 1 whenpcie_cq_np_req
=2'b01
and 2 whenpcie_cq_np_req
=2'b10
or2'b11
. - If
pcie_cq_np_req
=2'b00
and a single Non-Posted request is being delivered this cycle, the credit count is decremented by 1, unless it is already 0. - If
pcie_cq_np_req
=2'b00
and two Non-Posted requests are being delivered this cycle, the credit count is decremented twice, unless it has already reached 0. - Otherwise, the credit count remains unchanged.
- If
- The core starts delivery of a Non-Posted TLP to the user logic only if the credit count is greater than 0.
The user application can either provide one or two credits on pcie_cq_np_req
each time it is ready to receive Non-Posted
requests, or can keep it permanently set to 2'b11
if it
does not need to exercise selective backpressure on Non-Posted requests. If the credit
count is always non-zero, the core delivers Posted and Non-Posted requests in the same
order as received from the link. If it remains 0 for some time, Non-Posted requests can
accumulate in the core's FIFO. When the credit count becomes non-zero later, the core
first delivers the accumulated Non-Posted requests that arrived before Posted requests
already delivered to the user application, and reverts to delivering the requests in the
order received from the link.
The setting of pcie_cq_np_req
does not need to be aligned with the
packet transfers on the completer request interface.
The user application can monitor the current value of the credit count on the output
pcie_cq_np_req_ count[5:0]
. The counter saturates at 32. Because of
internal pipeline delays, there can be several cycles of delay between the core
receiving a pulse on the pcie_cq_np_req
input and updating the
pcie_cq_np_req_count
output in response. Thus, when the user logic
has adequate buffer space available, it should provide the credit in advance so that
Non-Posted requests are not held up by the core for lack of credit.