PCI Target Termination Examples for pci_mt32 and pci_t32 MegaCore Functions

This document describes how to generate various target terminations when using Altera’s pci_t32 and pci_mt32 MegaCore® functions, and assumes that the user is familiar with the PCI specifications as well as the functionality of the Altera® PCI MegaCore functions.

Under most conditions, the target is able to source or sink the data requested by the master until the master terminates the transaction. But when the target is unable to complete the request, it may use the stopn signal to initiate termination of the transaction. How the target combines stopn with other signals will indicate to the master information about the condition which lead to the termination.

There are three types of target initiated termination:

The following sections describe each of the target termination types in more detail.

Download the files used in this example:

The use of this design is governed by, and subject to, the terms and conditions of the Altera Hardware Reference Design License Agreement.

Target Abort

Target abort refers to an abnormal termination because either the local logic detected a fatal error, or the target will never be able to complete the request. An abnormal termination may cause a fatal error for the application that originally requested the transaction. A target abort allows the transaction to complete gracefully, thus preserving normal operation for other agents. A target device issues an abort by deasserting devseln and trdyn and asserting stopn..

The user logic can request a target abort by asserting the signal lt_abortn. If unused, the signal lt_abortn should be tied high as shown below:

Verilog

wire lt_abortn = 1’b1;

VHDL

lt_abortn <= '1';

 

 

Target Retry

The local-side device can request a retry because, for example, the device cannot meet the initial latency requirement or because the local resource cannot transfer data at this time. A target device signals a retry by asserting devseln and stopn, while deasserting trdyn before the first data phase. The local-side device can request a retry as long as it did not supply or request at least one data phase in a burst transaction. In a write transaction, the local-side device may request a retry by asserting lt_discn as long as it did not assert the lt_rdyn signal to indicate it is ready for a data transfer. If lt_rdyn is asserted, it can result in the PCI MegaCore function asserting the trdyn signal on the PCI bus. Therefore, asserting lt_discn forces a disconnect instead of a retry. In a read transaction, the local-side device can request a retry as long as data has not been transferred to the PCI MegaCore function.

The following example shows the sample logic required for generating a PCI retry

Verilog

always @ (posedge clk or negedge rstn)
if (!rstn) begin
lt_rdyn <= 1'b1;
lt_discn <= 1'b1;
end else begin
lt_rdyn <= ! USER_READY ;
lt_discn <= !(cycle_start & !USER_READY);
end

VHDL

process(clk, rstn)
begin
if (rstn='0') then
lt_rdyn <= '1';
lt_discn <= '1';
elsif (clk'event and clk='1') then
lt_rdyn <= not(USER_READY);
lt_discn <= not(cycle_start and (not(USER_READY)));
end if;
end process;

USER_READY is an active high user signal that indicates if the user application is ready to accept a PCI access. The above example assumes that USER_READY is generated elsewhere in the user logic. USER_READY is typically a function of the signals bar_hit[5:0], l_cmdo[3:0], lt_framen and l_adro[31:0].

The signal cycle_start is a signal generated in the user logic to indicate the start of a target transaction. This signal can be generated by detecting a falling edge of the signal lt_framen.

Target Disconnect

A PCI target can signal a disconnect by asserting stopn and devseln after at least one data phase is complete. There are two types of disconnects: Disconnect with data and disconnect without data.

Disconnect with data may be signaled on any data phase by asserting trdyn and stopn together. This termination is used when the target is only willing to complete the current data phase and no more.

Disconnect without data may be signaled on any subsequent data phase (meaning data was transferred on the previous data phase) by deasserting trdyn and asserting stopn.

lt_rdyn and lt_discn control the PCI MegaCore function’s generation of a target disconnect. In addition, the state of irdyn controls whether there is a disconnect with data or disconnect without data.

Since disconnect with data or disconnect without data transactions depend upon the sate of the irdyn signal, you must design your logic to disconnect after the specified number of DWORDs are transferred on the PCI bus. You can use lt_dxfrn to check the number of DWORDS transferred on the local side and use lt_tsr[10] to check the number of DWORDS transferred on the PCI bus.

The following examples show how to generate a target disconnect for different transfer lengths. The final example is a generic example and can generate a disconnect for any transfer length.

Example 1: Disconnect after 1st data transfer

In this example, the user application is always ready and cannot accept burst transfers, so it terminates the transfer after the first data transfer.

Verilog

always @ (posedge clk or negedge rstn)
if (!rstn) begin
lt_rdyn <= 1'b1;
lt_discn <= 1'b1;
end else begin
lt_rdyn <= lt_framen;
lt_discn <= lt_rdyn;
end

VHDL

process(clk, rstn)
begin
if (rstn='0') then
lt_rdyn <= '1';
lt_discn <= '1';
elsif (clk'event and clk='1') then
lt_rdyn <= lt_framen;
lt_discn <= lt_rdyn;
end if;
end process;

Example 2: Disconnect after 2 transfers

The following example shows how to generate a target disconnect after 2 transfers. For PCI writes, the user application can detect a successful PCI transfer one cycle after it occurs. So lt_discn in this case is generated combinatorially by looking at the signal lt_dxfrn, indicating that the first transfer has taken place and the second transfer is in progress on the PCI bus. For reads, lt_discn is generated by looking at a registered version of lt_dxfrn. This signal is called assert_disc. This condition indicates that the first transfer has taken place on the local side. The combinatorial gating of lt_dxfrn with assert_disc, allows lt_discn to be asserted when the second transfer is occurring on the local side.

The signal targ_wr_rdn indicates the direction of transfer and can be generated by looking at l_cmd[0].

Verilog

reg targ_wr_rdn; // write = 1 and read = 0
always @ (posedge clk)
targ_wr_rdn <= l_cmdo[0];


// Signal indicating when lt_discn should be asserted.
reg assert_disc;
always @ (posedge clk or negedge rstn)
if (!rstn)
assert_disc <= 1’b0;
else if (!lt_framen )
assert_disc <= targ_wr_rdn | (!targ_wr_rdn & !lt_dxfrn);
else // lt_framen = >
assert_disc <= 1’b0;

wire lt_discn = ! (assert_disc & !lt_dxfrn);

VHDL

signal targ_wr_rdn: std_logic; -- write = 1 and read = 0
process(clk)
begin
if (clk'event and clk='1') then
targ_wr_rdn <= l_cmdo(0);
end if;
end process;

-- Signal indicating when lt_discn should be asserted.
signal assert_disc: std_logic;
process(clk, rstn)
begin
if (rstn='0') then
assert_disc <= ’0’
elsif (clk'event and clk='1') then
if (lt_framen =’0’)
assert_disc <= targ_wr_rdn or ((not(targ_wr_rdn)) and (not(lt_dxfrn)));
else --lt_framen = >
assert_disc <= ’0’
end if;
end if;
end process;

lt_discn = not(assert_disc and (not(lt_dxfrn)));

Example 3: Generic Disconnect Example

The following example shows lt_discn generation for different transfer lengths. The assumption here is that the user logic knows at the beginning of the transfer how many transfers it can accept and provides this information in the parameter CAN_ACCEPT. The signal assert_disc indicates when lt_discn should be asserted. This signal is generated based on the value of CAN_ACCEPT and the number of transfers that have taken place on the local side. In order to keep track of the number of words transferred on the local side, a counter is required and is implemented by the signal xfr_cnt.

Verilog

// The parameter indicates how many transfers the design can accept and must be greater than 0
parameter [7:0] CAN_ACCEPT = 4;

always @ (posedge clk or negedge rstn)
if (!rstn)
xfr_cntr <= 8'b0;
else if (cycle_start)
xfr_cntr <= 8'b0;
else if (!lt_dxfrn)
xfr_cntr <= xfr_cntr + 1'b1;

// This signal indicates that the value of CAN_ACCEPT is either 1
reg transfer_1_dword;

// This signal indicates timing for when lt_discn should be asserted and is generated
// based on the value of xfr_cntr and CAN_ACCEPT
reg assert_disc;

always @ (posedge clk or negedge rstn)
if (!rstn) begin
lt_rdyn <= 1'b1;
assert_disc <= 1'b0;
transfer_1_dword <= 1'b0;
end else begin
transfer_1_dword <= ( (CAN_ACCEPT == 8'h1) );
lt_rdyn <= lt_framen ;
if (!lt_framen) begin
if (CAN_ACCEPT == 8'h1)
assert_disc <= !lt_rdyn;
else if (CAN_ACCEPT == 8'h2)
assert_disc <= targ_wr_rdn | (!targ_wr_rdn & !lt_dxfrn);
else
assert_disc <= assert_disc | (!lt_dxfrn &
((targ_wr_rdn & (xfr_cntr == CAN_ACCEPT -3)) |
(!targ_wr_rdn & (xfr_cntr == CAN_ACCEPT -2))));
end else
assert_disc <= 1'b0;
end

wire lt_discn = !(assert_disc & (!lt_dxfrn | transfer_1_dword));

VHDL

process(clk, rstn)
begin
if (rstn='0') then
xfr_cntr <= x"00"
elsif (clk'event and clk='1') then
if (cycle_start='1') then
xfr_cntr <= x"00"
elsif (lt_dxfrn='0') then
xfr_cntr <= xfr_cntr + 1;
end if;
end if;
end process;

CAN_ACCEPT <= 4; -- set the burst length size here!

process(clk, rstn)
begin
if (rstn='0') then
lt_rdyn_tmp <= '1';
assert_disc <= '0';
transfer_1_dword <= '0';
elsif(clk'event and clk='1') then
if (CAN_ACCEPT = 1) then
transfer_1_dword <= '1';
end if;

lt_rdyn_tmp <= (not ((not(lt_framen)) and (bar0_mem_hit)));

if (lt_framen='0') then
if (CAN_ACCEPT = 1) then
assert_disc <= (not(lt_rdyn_tmp));
elsif (CAN_ACCEPT = 2) then
assert_disc <= (targ_wr_rdn or (not(targ_wr_rdn) and (not(lt_dxfrn))));
else
if (CAN_ACCEPT - 2 = xfr_cntr) then
assert_disc <= (assert_disc or ((not(lt_dxfrn)) and (not(targ_wr_rdn))));
elsif (CAN_ACCEPT - 3 = xfr_cntr) then
assert_disc <= (assert_disc or ((not(lt_dxfrn)) and targ_wr_rdn));
end if;
end if;
else
assert_disc <= '0';
end if;
end if;
end process;

 

Design Examples Disclaimer

These design examples may only be used within Altera Corporation devices and remain the property of Altera. They are being provided on an “as-is” basis and as an accommodation; therefore, all warranties, representations, or guarantees of any kind (whether express, implied, or statutory) including, without limitation, warranties of merchantability, non-infringement, or fitness for a particular purpose, are specifically disclaimed. Altera expressly does not recommend, suggest, or require that these examples be used in combination with any other product not provided by Altera.