cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
ximoose
Observer
Observer
10,012 Views
Registered: ‎09-25-2014

Bus Master Design on SP605

Jump to solution

I am trying to implement the XAPP1052 (PCIe BMD) on a Linux system, but I am facing some difficulty and was hoping somebody out there can help. 

 

Here is a summary of the steps taken so far:  

- The xbmd driver is loading ok (judged by the kernel messages in the system log).

- The Xilinx PCIe end-point is recognized by running lspci.

- xbmd_app application runs and the GUI opens (I get some warning messages from Gtk, but that should be no big deal I suppose)

- The Read_CFG and Read_BMD winsows are populated which hints to the correct communication between SP605 and OS having been established.

- However, when I choose either Read or Write transfer with any TLP size and TLPs To Transfer, I get a fragmentation error and the program exits.

 

I have traced this down to trn_clk variable being zero and causing a divide by zero error in file bmd.cpp. When I assign a non-zero value to trn_clk (for example trn_clk = 1) then the fragmentation error dispappears, but now the status bar in the GUI says there was an error.

 

I hope the above explanation is enough to get some help as at this point I don't know how to proceed. I am new to FPGA programming and it will take me some time to deeply understand the PCIe end-point design. In the meantime it will be a great relief if I can get a working BMD case to be able to proceed with my research.

 

 

 

 

 

0 Kudos
1 Solution

Accepted Solutions
ximoose
Observer
Observer
17,099 Views
Registered: ‎09-25-2014

Solved!

 

I was using the wrong bitstream. Instead of routed.bit I was programming the FPGA with the bitstream for the PIO design. I feel stupid but also relieved now! :-)

View solution in original post

0 Kudos
4 Replies
kotir
Scholar
Scholar
9,960 Views
Registered: ‎02-03-2010

Hi

 

there is trn_clks variable used to count the performance numbers of read and write.

This variable gets its value by a ioctl command from xbmd descriptors as below.

 

 

  if (xbmd_descriptors.wr_enable == 0x00000001)  {
    if (ioctl(xbmd_descriptors.g_devFile, RDWDMAPERF, &trn_clks) < 0) {
    
      // If error is found when reading RD performance register, update the fatal text and return with CRIT_ERR
      file << "RDMATLPP Read Failed\n";
      this->bmd_fatal_text = "RDMATLPP Read Failed: BMD.cpp";
      file.close();
      return CRIT_ERR;
    }

 

 

 

  // Only update performance if Read DMA is enabled.  Won't be calculated on error condition
  if (xbmd_descriptors.rd_enable == 0x00010000)  {
    // Reads WR_DMA PERFORMANCE REGISTER
    if (ioctl(xbmd_descriptors.g_devFile, RDRDMAPERF, &trn_clks) < 0) {

      // If error is found when reading RD performance register, update the fatal text and return with CRIT_ERR
      file << "RDMATLPP Read Failed\n";
      this->bmd_fatal_text = "RDMATLPP Read Failed: BMD.cpp";
      file.close();
      return CRIT_ERR;
    }

 

Can you check if there are any error ?

 

 

Regards,

KR

--------------------------------------------------​--------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful.
--------------------------------------------------​-------------------------------------------
0 Kudos
ximoose
Observer
Observer
9,947 Views
Registered: ‎09-25-2014

Hello kotir,

 

The ioctl command that you mentioned returns successfully with trn_clks = 0, therefore the program proceeds and does a divide by 0 a few lines later.

 

When I force trn_clks to be non-zero by adding trn_clks = 1; right before the division, and run the "Write" from GUI, I get the error message: "ERROR: WR DMA did not complete successfully". I looked into the code and could see that it is produced from the following code:

 

    // if no mismatch is found, lets do a final check of DMACR_REG to make sure WR_DMA completed successfully   
    if (this->wr_success != false) {
      if (dmacr_reg_wr!= 0x00000101) {
        // if an error is found, output the control register contents to the log
        file << "DMACR register contents = 32'h" << hex << dmacr_reg<< "\n";

        // Update the WR result text
        this->wr_result_text = "ERROR: WR DMA did not complete successfully";

        // set the WR success variable to false
        this->wr_success=false;
      } else {
        //if both checks fall through- consider a success  
        file << "WRITE DMA SUCCESS!"<<endl;
        this->wr_result_text = "WRITE DMA SUCCESS!";
        this->wr_success=true;
      }
    }

 

By the way, I get the following line in the log:

DMACR register contents = 32'h1

 

0 Kudos
ximoose
Observer
Observer
9,908 Views
Registered: ‎09-25-2014

I am still trying to pinpoint the problem.

 

Q1) In bmd.cpp in the "//  CHECK KERNEL BUFFER AND XBMD STATUS REGISTERS FOR ERRORS", there is a code for masking the lower or upper 16 bits of DDMACR register value read by ioctl that I have pasted below:

 

  // Read the XBMD control register which will state whether XBMD encountered an error condition during transfer.
  // If error occurs on read, update fatal_text and return to GUI which will show error in main status bar
  if (ioctl(xbmd_descriptors.g_devFile, RDDDMACR, &reg_value) < 0) {
    file << "DMACR Read Failed\n";
    this->bmd_fatal_text = "DMACR Read Failed: BMD.cpp";
    file.close();
    return CRIT_ERR;
  } else {
    dmacr_reg = reg_value;
    // mask off the write bits (lower 16) to check write DMA seperately
    dmacr_reg_wr = dmacr_reg & 0x00001111;
    // mask off the read bits (upper 16) to check read DMA seperately
    dmacr_reg_rd = dmacr_reg & 0x11110000;
  }

 

Are these masks correct?! Shouldn't we use 0x0000ffff and 0xffff0000 instead?

 

Q2) In xbmd_app GUI under Read_BMD window, the values of Device Link Width Status (DLWSTAT) Register and Device Link Transaction Size Status (DLTRSSTAT) Regiser are both reported as 0x0. What does that mean? Since these are read-only registers, I believe they are set by the end-point design when the bitstream is downloaded to SP605 board. If they are 0, does that mean there was a problem with generating the core?

 

 

0 Kudos
ximoose
Observer
Observer
17,100 Views
Registered: ‎09-25-2014

Solved!

 

I was using the wrong bitstream. Instead of routed.bit I was programming the FPGA with the bitstream for the PIO design. I feel stupid but also relieved now! :-)

View solution in original post

0 Kudos