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!

cancel
Showing results for 
Search instead for 
Did you mean: 
Adventurer
Adventurer
11,768 Views
Registered: ‎07-12-2012

Problems with large burst data transfer with PCI express

Jump to solution

Hi everyone,

 

I have implemented a PCIe EndPoint v1.7. core, x4 250 MHz, in my ML605 board. I have been modifying the PIO state machines in order to generate large burst data transfer. Now my PIO application works sends large burst data transfer in a very similar way to the way described in UG517.pdf file (I would say in the same way, but that would be too pretencious). But my RootComplex does not receive anything, and the results lead us to think that there is a problem in the FPGA protocol.

 

Below is a ChipScope picture of the signals I send to the EndPoint core in a large burst.

 

tlp2dw.png

 

where the fields of the TLP sent are:

 

1st QW :  4A000002     00000004

2nd QW:  00000100     0F101112

3rd QW:   13141516     Trash

 

However, when sending a 4-byte (1-DWORD) the RC receives the data. Below is a capture of the signals.

 

tlp1dw.png

 

where the TLP fields are:

 

1st QW :     4A000001 00000004

2nd QW:     00000100 1F202122

 

I have two hypothesis:

- There is some signal that is not working as expected.

- There is some problem when sending the TLP in non-consecutive trn_clk cycles (though I have read in the UG517 file that this is possible with just modifying the trn_tsrc_rdy_n signal, and I have modify it)

- There is some field in the PCIe Tx TLP that is not set to an appropriate value.

 

Can anyone help me with this? I would also appreciate if somebody could send and example of the TLP and the signals when sending a large burst data transfer in order to compare them with my signals.

 

Thank you very much for your attention.

 

Regards,

Alberto.

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Contributor
Contributor
19,291 Views
Registered: ‎02-13-2009

Re: Problems with large burst data transfer with PCI express

Jump to solution

I think your TLP is wrong. Fix the bytecount value. Currently you set length to two DWs, but have the bytecount field set to 4. Check the PCIe specification on how to calculate the bytecount, this depends on the byte enables and the length. Here is some example code:

 

    function [11:0] byte_count;
    input [7:0] be;
    input [9:0] len;
    begin
        casex(be)
            8'b00001xx1: byte_count = 4;
            8'b000001x1: byte_count = 3;
            8'b00001x10: byte_count = 3;
            8'b00000011: byte_count = 2;
            8'b00000110: byte_count = 2;
            8'b00001100: byte_count = 2;
            8'b00000001: byte_count = 1;
            8'b00000010: byte_count = 1;
            8'b00000100: byte_count = 1;
            8'b00001000: byte_count = 1;
            8'b00000000: byte_count = 1;
            8'b1xxxxxx1: byte_count = len << 2;
            8'b01xxxxx1: byte_count = (len << 2) - 1;
            8'b001xxxx1: byte_count = (len << 2) - 2;
            8'b0001xxx1: byte_count = (len << 2) - 3;
            8'b1xxxxx10: byte_count = (len << 2) - 1;
            8'b01xxxx10: byte_count = (len << 2) - 2;
            8'b001xxx10: byte_count = (len << 2) - 3;
            8'b0001xx10: byte_count = (len << 2) - 4;
            8'b1xxxx100: byte_count = (len << 2) - 2;
            8'b01xxx100: byte_count = (len << 2) - 3;
            8'b001xx100: byte_count = (len << 2) - 4;
            8'b0001x100: byte_count = (len << 2) - 5;
            8'b1xxx1000: byte_count = (len << 2) - 3;
            8'b01xx1000: byte_count = (len << 2) - 4;
            8'b001x1000: byte_count = (len << 2) - 5;
            8'b00011000: byte_count = (len << 2) - 6;
            default:     byte_count = 12'h000;
        endcase
    end
    endfunction

    function [1:0] lower_addr;
    input [3:0] be;
    begin
        casex(be)
            4'b0000: lower_addr = 2'b00;
            4'bxxx1: lower_addr = 2'b00;
            4'bxx10: lower_addr = 2'b01;
            4'bx100: lower_addr = 2'b10;
            4'b1000: lower_addr = 2'b11;
            default: lower_addr = 2'b00;
        endcase
    end
    endfunction

View solution in original post

0 Kudos
4 Replies
Voyager
Voyager
11,670 Views
Registered: ‎05-21-2008

Re: Problems with large burst data transfer with PCI express

Jump to solution
did you simulate the code?
0 Kudos
Highlighted
Contributor
Contributor
19,292 Views
Registered: ‎02-13-2009

Re: Problems with large burst data transfer with PCI express

Jump to solution

I think your TLP is wrong. Fix the bytecount value. Currently you set length to two DWs, but have the bytecount field set to 4. Check the PCIe specification on how to calculate the bytecount, this depends on the byte enables and the length. Here is some example code:

 

    function [11:0] byte_count;
    input [7:0] be;
    input [9:0] len;
    begin
        casex(be)
            8'b00001xx1: byte_count = 4;
            8'b000001x1: byte_count = 3;
            8'b00001x10: byte_count = 3;
            8'b00000011: byte_count = 2;
            8'b00000110: byte_count = 2;
            8'b00001100: byte_count = 2;
            8'b00000001: byte_count = 1;
            8'b00000010: byte_count = 1;
            8'b00000100: byte_count = 1;
            8'b00001000: byte_count = 1;
            8'b00000000: byte_count = 1;
            8'b1xxxxxx1: byte_count = len << 2;
            8'b01xxxxx1: byte_count = (len << 2) - 1;
            8'b001xxxx1: byte_count = (len << 2) - 2;
            8'b0001xxx1: byte_count = (len << 2) - 3;
            8'b1xxxxx10: byte_count = (len << 2) - 1;
            8'b01xxxx10: byte_count = (len << 2) - 2;
            8'b001xxx10: byte_count = (len << 2) - 3;
            8'b0001xx10: byte_count = (len << 2) - 4;
            8'b1xxxx100: byte_count = (len << 2) - 2;
            8'b01xxx100: byte_count = (len << 2) - 3;
            8'b001xx100: byte_count = (len << 2) - 4;
            8'b0001x100: byte_count = (len << 2) - 5;
            8'b1xxx1000: byte_count = (len << 2) - 3;
            8'b01xx1000: byte_count = (len << 2) - 4;
            8'b001x1000: byte_count = (len << 2) - 5;
            8'b00011000: byte_count = (len << 2) - 6;
            default:     byte_count = 12'h000;
        endcase
    end
    endfunction

    function [1:0] lower_addr;
    input [3:0] be;
    begin
        casex(be)
            4'b0000: lower_addr = 2'b00;
            4'bxxx1: lower_addr = 2'b00;
            4'bxx10: lower_addr = 2'b01;
            4'bx100: lower_addr = 2'b10;
            4'b1000: lower_addr = 2'b11;
            default: lower_addr = 2'b00;
        endcase
    end
    endfunction

View solution in original post

0 Kudos
Observer danbo.liang
Observer
11,630 Views
Registered: ‎03-20-2012

Re: Problems with large burst data transfer with PCI express

Jump to solution

why your completer_id is 0? but the request_id in your TLP is 4A00?

the best way is simulating your design.

 

1) request_id is from IP's configuration space, when sending TLP, using it.

2) implement tag using a counter, then using it in TLP

3) the size you want to send should meet the length of TLP

4) enable bus master bit(this is done by root)

 

 

0 Kudos
Adventurer
Adventurer
11,618 Views
Registered: ‎07-12-2012

Re: Problems with large burst data transfer with PCI express

Jump to solution

Thank you everybody,

 

Finally, my byte-count field had much to do with my problem (apart from other little details I have fixed too). I didn't realize that a read completion had different fields than a write command.

 

Regards,

Alberto.

0 Kudos