UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

AR# 23969

LogiCORE PCI-X - Using M_DATH_VLD and M_DATL_VLD, or S_DATH_VLD and S_DATL_VLD to capture data and advance an address pointer

Description

How do I use the core User Interface signals M_DATH_VLD and M_DATL_VLD (initiator), or S_DATH_VLD and S_DATL_VLD (target) to correctly capture data and advance an address pointer when the user application acts as either an Initiator or Target of a transaction?

Solution

This Answer Record explains how to increment an address pointer when the user application acts as an initiator or as a target. It also provides a detailed explanation of an example data capture scheme.

=== Incrementing the Address Pointer ===

As either an initiator or target, the user application needs to keep track of the address so that in the event of a disconnect, it knows where to restart when the next transaction occurs. Below is a suggested algorithm that can be used as a template for designs in general that implement a 64-bit user application data object, meaning that the full 64-bits of data buses on the user application interface are used rather than just 32 bits. The width of the bus used between the user application and the core does not have to match the width of the actual PCI or PCI-X bus. Please see the PCI-X User Guide for more information:

http://www.xilinx.com/support/documentation/ip_documentation/pcix_64_ug160.pdf

The same principles can be applied when the PCI-X Core is acting as both an initiator or target. When acting as an Initiator, the signals M_DATH_VLD, M_DATL_VLD, and M_DONE are used. When acting as a Target, the signals S_DATH_VLD, S_DATL_VLD, and S_DONE are used.

1. At the beginning of the transfer, load the ADDRESS_REGISTER with the starting memory address.

2. After requesting the bus from the Arbiter, provide the ADDRESS_REGISTER to the core when prompted. If acting as a Target, capture the starting address from the core using S_ADDL_VLD and/or S_ADDH_VLD. Also, take note of AD bit 2 of the address. AD[2] tells if the initial memory address is quadword aligned. AD[2] must be stored in a register so that it can be considered when adjusting the ADDRESS_REGISTER. For this example, UNALIGNED represents this register.

AD[2] = 0 => The start address is quadword aligned

AD[2] = 1 => The starting address is non-quadword aligned

3. On any cycle where M_DATH_VLD and M_DATL_VLD (S_DATH_VLD and S_DATL_VLD for targets) are both asserted, increment the ADDRESS_REGISTER by +8

ADDRESS_REGISTER <= ADDRESS_REGISTER +8;

4. On any cycle where M_DONE (S_DONE for targets) is asserted, the ADDRESS_REGISTER must be incremented or decremented based on two signals: the starting alignment of the ADDRESS_REGISTER (using register UNALIGNED) and M_DATH_VLD (S_DATH_VLD for targets). This case statement will properly adjust the ADDRESS_REGISTER based on the initial alignment and M_DATH_VLD (S_DATH_VLD).

case ({UNALIGNED, M_DATH_VLD})

2'b00 : ADDRESS_REGISTER <= ADDRESS_REGISTER + 0

2'b01 : ADDRESS_REGISTER <= ADDRESS_REGISTER + 4

2'b10 : ADDRESS_REGISTER <= ADDRESS_REGISTER - 4

2'b11 : ADDRESS_REGISTER <= ADDRESS_REGISTER + 0

endcase

Below are generic scenarios which show the proper adjustment of the ADDRESS_REGISTER where time is from Left to Right and:

H = M_DATH_VLD or S_DATH_VLD

L = M_DATL_VLD or S_DATH_VLD

D - M_DONE or S_DONE

Cases where AD[2] = 0 - UNALIGNED = 0

For 64-bit bus transactions, you must increment the ADDRESS_REGISTER by 8 every time a valid transfer on the bus occurs. A valid data phase occurs when M_DATH_VLD and M_DATL_VLD (S_DATH_VLD and S_DATL_VLD) are both asserted on the rising edge of the PCI clock. "n" phases => 8n bytes, as shown below:

64-Bit Bus Transaction
64-Bit Bus Transaction

32-bit bus transactions require more logic to correctly adjust the ADDRESS_REGISTER. Below are example scenarios showing how the case statement above is implemented. There are four examples, each one representing a different number of data phases. This concept is scalable to any number of data phases. Notice that the user application does not need to know if the bus transactions are 64-bit or 32-bits as long as the rules below are followed.

 32-Bit Bus Transactions (1 - 4 Valid Data Phases)
32-Bit Bus Transactions (1 - 4 Valid Data Phases)

PCI-X LogiCORE behavioral simulations showing the ALIGNED scenarios described above:

1 Data Phase
1 Data Phase

2 Data Phases
2 Data Phases

3 Data Phases
3 Data Phases

4 Data Phases
4 Data Phases

Cases where AD[2] = 1 - UNALIGNED = 1

Again, for 64-bit bus transactions, the user application needs to increment the address pointer by 8 every time a valid transfer on the bus occurs ( M_DATL_VLD and M_DATH_VLD or S_DATH_VLD and S_DATL_VLD are asserted). However, since the starting address is not aligned to a quadword boundary, you need to subtract 4 from the ADDRESS_REGISTER to properly adjust the pointer for the next transaction. "n" phases => 8n bytes - 4, as shown below:

64-Bit Bus Transactions
64-Bit Bus Transactions

Again, 32-bit bus transactions require more logic to correctly adjust the ADDRESS_REGISTER. Below are example scenarios showing how the case statement above is implemented when dealing with unaligned starting addresses. With unaligned addresses, you might need to subtract 4 from the ADDRESS_REGISTER depending on the number of data phases.

 32-Bit Bus Transactions (1 - 4 Valid Data Phases)
32-Bit Bus Transactions (1 - 4 Valid Data Phases)

PCI-X LogiCORE behavioral simulations showing the UNALIGNED scenarios described above:

1 Data Phase
1 Data Phase

2 Data Phases
2 Data Phases

3 Data Phases
3 Data Phases

4 Data Phases
4 Data Phases

In general:

H & L means +8

For AD[2] = 0, D & H means +4

For AD[2] = 1, D & !H means -4

=== Capturing the Data ===

Below is a method that can be used as a template to capture data when acting as a 64-bit data object. The same principles can be applied to both initiators and targets to correctly capture data presented on M_DATA_OUT[63:0] or S_DATA_OUT[63:0] busses.

NOTE: The PCI-X Core presents data to the user application as it would be stored in system memory. The pictures below show how data is transferred from System Memory to the PCI-X target.

Aligned transfer representation
Aligned transfer representation

Unaligned transfer representation
Unaligned transfer representation

An initiator needs to monitor M_DATH_VLD and M_DATL_VLD while a target should monitor S_DATH_VLD and S_DATL_VLD. Similar to the address counter algorithm, the alignment must also be factored in when capturing data. AD[2] dictates whether the starting address is aligned or un-aligned and must be stored.

When acting as a 64-bit data object, S_DATH_VLD (M_DATH_VLD for initiators) indicates valid data is present on S_DATA_OUT. S_DATL_VLD (M_DATL_VLD for initiators) is a qualifier signal and when asserted, the core is indicating to the user application that all 64 bits of the data bus should be captured except for the first data phase of an unaligned transfer as shown below.

NOTE: S_DATH_VLD does not indicate valid data on the upper 32 bits of S_DATA_OUT, nor does S_DATL_VLD indicate valid data on the lower 32 bits of S_DATA_OUT.

Below are generic scenarios which explain how to capture data. Again, time is from Left to Right and:

H = M_DATH_VLD or S_DATH_VLD

L = M_DATL_VLD or S_DATH_VLD

D - M_DONE or S_DONE

+64 = Capture all 64 bits of data bus

+32L = Capture lower 32 bits of data bus

+32H = Capture upper 32 bits of data bus

Cases where AD[2] = 0 - ALIGNED

For 64-bit bus transactions when the starting address is ALIGNED, the user application will capture the entire 64 bits of the data bus. S_DATH_VLD and S_DATL_VLD will be asserted on every clock when doing 64-bit transfers. S_DATH_VLD indicates valid data is present on S_DATA_OUT and S_DATL_VLD qualifies all 64 bits of the bus.

64-bit data object Capture
64-bit data object Capture

32-bit bus transactions require more logic to correctly capture data. In the 32-bit aligned case, S_DATH_VLD always indicates valid data is present on the lower 32 bits of the bus. S_DATL_VLD is a qualifier signal for the upper 32 bits of S_DATA_OUT. On the rising edge of PCI_CLK, both these signals must be evaluated. When S_DATH_VLD is asserted, the lower 32 bits are valid. The assertion of S_DATH_VLD along with S_DATL_VLD indicates that all 64 bits should be captured. Below are four examples, each one representing a different number of data phases. This concept is scalable to any number of data phases.

64-bit data object Capture
64-bit data object Capture

Cases where AD[2] = 1 - UNALIGNED

For 64-bit bus transactions, the user application needs to capture all 64 bits of the data bus when S_DATH_VLD and S_DATL_VLD (M_DATH_VLD and M_DATL_VLD for initiators) are asserted. However, since the starting address is not aligned to a quadword boundary, the lower 32 bits of the data bus will not be valid on the first cycle. Remember that the PCI-X Core presents data as it is stored in system memory.

64-bit data object Capture
64-bit data object Capture

32-bit bus transactions must monitor the alignment of the transfer. In the unaligned scenario, data will always be presented on the upper 32 bits on the first clock. On the first clock where S_DATH_VLD is asserted, the upper 32 bits must be captured regardless of the state of S_DATL_VLD. On subsequent clocks, you must capture on an S_DATH_VLD assertion. S_DATL_VLD is again a qualifier for all 64 bits. Below are example scenarios showing how to capture when dealing with unaligned starting addresses.

64-bit data object Capture
64-bit data object Capture

AR# 23969
Date Created 09/04/2007
Last Updated 12/15/2012
Status Active
Type General Article