This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Errors Reading GPMC Bus Beaglebone Black



I apologize ahead of time for the length and formatting of this post (I tried i swear). Any help would be greatly appreciated and please excuse me for my naivete in concerns to certain topics.

I have the GPMC configured to write then read a 2048 word block from an FPGA. The data written to the device is randomly generated. When comparing the data written vs. read there occurs errors every 10,000 or so accesses. Each access being an entire read and write of the 2048 words. We have tested it under a variety of conditions(all synchronous but will be trying it asynchronously soon).

Tried:

-16 word/8 word/ 4 word

-96/48/24 Mhz

-With/Without Cycle Delay Enabled

-With/Without EDMA

Weird things about it:

-For a given data set, if an error occurs the error reoccurs at the same address.

-For a data set that has previously generated errors, the likelihood of an error occurring increases drastically.

           The rate of errors goes from tens of thousands to only a few accesses before errors reoccur.

-Between error generating datasets, the error locations seem to be unique.

-The errors are typically an offset in the words.

As seen from the logic analyzer on the fpga, it appears as if the correct data is being sent from the fpga to the beaglebone. At least verifying that

the data was correctly written in the first place to the fpga.

Configuration of FPGA:

#define GPMC_DEVICE_SIZE GPMC_16MB_SIZE

//Single Read Time Settings
#define CSONTIME (0x00)//
#define ADVRDOFFTIME (0x01)//
#define ADVONTIME (0x00)//
#define OEONTIME (0x01)//
#define RDACCESSTIME (0x04)//
#define RDCYCLETIME ((0x04) + 1)//
#define CSRDOFFTIME ((0x04) + 1)//
#define OEOFFTIME ((0x04))//


//Single Write Time Settings
#define CSWROFFTIME (0x03)//
#define ADVWROFFTIME (0x01)//
#define WEOFFTIME ((CSWROFFTIME))//
#define WEONTIME ((CSWROFFTIME-(2)))//
#define WRCYCLETIME ((CSWROFFTIME))//
#define WRACCESSTIME ((CSWROFFTIME-(1)))//


//Other
#define CYCLEDELAY 0x00//
#define CYCLEDELAYEN 0x01
#define SYNCHWREN 0x01
#define SYNCHRDEN 0x01
#define WRMULTEN 0x01
#define RDMULTEN 0x01


#define WAITMONITORMODE  GPMC_CONFIG1_0_WAITMONITORINGTIME_NOTDEFINED
#define CLKACTSTART GPMC_CONFIG1_0_CLKACTIVATIONTIME_ATSTART //GPMC_CONFIG1_0_CLKACTIVATIONTIME_TWOCLKB4
#define FCLOCKDIV GPMC_CONFIG1_0_GPMCFCLKDIVIDER_DIVBY2
#define TIMEGRANULAR GPMC_CONFIG1_0_TIMEPARAGRANULARITY_X2
#define WRAPBURSTEN 0x00u
//#define WORDPAGELEN GPMC_CONFIG1_0_ATTACHEDDEVICEPAGELENGTH_FOUR
#define WORDPAGELEN GPMC_CONFIG1_0_ATTACHEDDEVICEPAGELENGTH_SIXTEEN
#define DATAWIDTH GPMC_CONFIG1_0_DEVICESIZE_SIXTEENBITS
#define DEVICETYPE GPMC_CONFIG1_0_DEVICETYPE_NORLIKE
#define MUXADDATATYPE GPMC_CONFIG1_0_MUXADDDATA_NONMUX
//#define MUXADDATATYPE GPMC_CONFIG1_0_MUXADDDATA_MUX
#define WRDATAONADMUXBUS ADVWROFFTIME
#define CSEXTRADELAY GPMC_CONFIG2_0_CSEXTRADELAY_NOTDELAYED
#define ADVEXTRADELAY GPMC_CONFIG3_0_ADVEXTRADELAY_NOTDELAYED
#define WEEXTRADELAY GPMC_CONFIG4_0_WEEXTRADELAY_NOTDELAYED
#define OEEXTRADELAY GPMC_CONFIG4_0_OEEXTRADELAY_NOTDELAYED
#define PAGEBURSTACCTIME 0x01// //0-15
#define BUSTURNAROUND 0x00 //0-15

Results when data is always randomly generate(from serial):

Pass: 46000
Pass: 47000
Error, address 316
w0: 0x5A76, expected: 0x5643
w1: 0x092D, expected: 0x5A76
w2: 0x3D24, expected: 0x092D
w3: 0x20A4, expected: 0x3D24
Pass: 47095
Average runs to fail: 29907
Error, address 317
w0: 0x3D0A, expected: 0x20A4
w1: 0x05F3, expected: 0x3D0A
w2: 0x35CA, expected: 0x05F3
w3: 0x444A, expected: 0x35CA
Pass: 0
Average runs to fail: 29907
Error, address 318
w0: 0x0338, expected: 0x444A
w1: 0x2F05, expected: 0x0338
w2: 0x08E7, expected: 0x2F05
w3: 0x42A7, expected: 0x08E7
Pass: 0
Average runs to fail: 29907
Error, address 319
w0: 0x355E, expected: 0x42A7
w1: 0x1A91, expected: 0x355E
w2: 0x5F82, expected: 0x1A91
w3: 0x121E, expected: 0x5F82
Pass: 0
Average runs to fail: 29673
Pass: 1000
Pass: 2000
Pass: 3000

Results when data is locked in after first error generation:

ass: 11000
Pass: 12000
Pass: 13000
Pass: 14000
Pass: 15000
Error, address 128
w0: 0x2033, expected: 0x2033
w1: 0x2033, expected: 0x1322
w2: 0x1322, expected: 0x1D3B
w3: 0x1D3B, expected: 0x16BB
Pass: 15458
Average runs to fail: 4294967295
Error, address 129
w0: 0x16BB, expected: 0x58BF
w1: 0x58BF, expected: 0x3396
w2: 0x3396, expected: 0x50F9
w3: 0x50F9, expected: 0x374D
Pass: 0
Average runs to fail: 4294967295
Error, address 130
w0: 0x374D, expected: 0x19D4
w1: 0x19D4, expected: 0x1716
w2: 0x1716, expected: 0x2BA7
w3: 0x2BA7, expected: 0x4271
Pass: 0
Average runs to fail: 4294967295
Error, address 131
w0: 0x4271, expected: 0x0D6E
w1: 0x0D6E, expected: 0x632F
w2: 0x632F, expected: 0x0274
w3: 0x0274, expected: 0x1F77
Pass: 0
Average runs to fail: 15458
Error, address 128
w0: 0x2033, expected: 0x2033
w1: 0x1D3B, expected: 0x1322
w2: 0x16BB, expected: 0x1D3B
w3: 0x58BF, expected: 0x16BB
Pass: 17
Average runs to fail: 15475
Error, address 129
w0: 0x3396, expected: 0x58BF
w1: 0x50F9, expected: 0x3396
w2: 0x374D, expected: 0x50F9
w3: 0x19D4, expected: 0x374D
Pass: 0
Average runs to fail: 15475
Error, address 130
w0: 0x1716, expected: 0x19D4
w1: 0x2BA7, expected: 0x1716
w2: 0x4271, expected: 0x2BA7
w3: 0x0D6E, expected: 0x4271
Pass: 0
Average runs to fail: 15475
Error, address 131
w0: 0x632F, expected: 0x0D6E
w1: 0x0274, expected: 0x632F
w2: 0x1F77, expected: 0x0274
w3: 0x502C, expected: 0x1F77
Pass: 0

As you can see the error occurs at the same place and only takes 17 passes before it occurs again. This is pretty typical of what i have been seeing.

Thank you for your time if you have read this far, I have tried quite a few things but the errors seem to persist and I think I have run out of theories at this point. Any input is greatly appreciated, and while it is strange that the numbers written seem to play a role in this I have not ruled out other possibilities(e.g. bad timing, bad trace layouts to FPGA, etc.). It still is strange though that it can do sometimes 100's of thousands of writes with no errors, but with data sets it seems to have difficulties even doing a hundreds cycles prior to getting an error.

Thanks again,

Rodney

  • Hi Rodney,

    would you please indicates the hw connection: bus width, other...

    FYI, with CCS, you may also access to the fpga as if it were a memory chip:

    configure mapping in GEL file: GEL_MapAddStr in OnTargetConnect function. for example:

    GEL_MapAddStr(0x10000000, 0, 0x00080000, "R|W|AS1", 0);  // SRAM

    add a function to configure GPMC, for example, mine is like this

    //******************************************************************
    //GPMC parameters
    //******************************************************************
    menuitem "AM335x SRAM Configuration";
    
    #define  SRAM_RD_ACCESSTIME      0x5
    #define  SRAM_RD_CYCLETIME       0x7
    #define  SRAM_CS_ONTIME          0x0
    #define  SRAM_CS_RD_OFFTIME      0x6
    #define  SRAM_ADV_ONTIME         0x0
    #define  SRAM_ADV_RD_OFFTIME     0x0
    #define  SRAM_OE_ONTIME          0x3
    #define  SRAM_OE_OFFTIME         0x6
    #define  SRAM_WR_ACCESSTIME      0x5
    #define  SRAM_WR_CYCLETIME       0x7
    #define  SRAM_CS_WR_OFFTIME      0x6
    #define  SRAM_ADV_WR_OFFTIME     0x0
    #define  SRAM_WE_ONTIME          0x3
    #define  SRAM_WE_OFFTIME         0x6
    
    #define SRAM_GPMC_CONFIG1        0x00000000u
    #define SRAM_GPMC_CONFIG2        ((SRAM_CS_WR_OFFTIME<<16) | (SRAM_CS_RD_OFFTIME<<8) | (SRAM_CS_ONTIME<<0))
    #define SRAM_GPMC_CONFIG3        ((SRAM_ADV_WR_OFFTIME<<16)| (SRAM_ADV_RD_OFFTIME<<8)| (SRAM_ADV_ONTIME<<0))
    #define SRAM_GPMC_CONFIG4        ((SRAM_WE_OFFTIME<<24)    | (SRAM_WE_ONTIME<<16)    | (SRAM_OE_OFFTIME<<8) | (SRAM_OE_ONTIME<<0))
    #define SRAM_GPMC_CONFIG5        ((SRAM_RD_ACCESSTIME<<16) | (SRAM_WR_CYCLETIME<<8)  | (SRAM_RD_CYCLETIME<<0))
    #define SRAM_GPMC_CONFIG6        (SRAM_WR_ACCESSTIME<<24)
    #define SRAM_GPMC_CONFIG7        0x00000000
    
    
    #define GPMC_SIZE_16M            0xF
    #define CONFIG_SYS_SRAM_BASE     (0x10000000)
    
    #define CM_PER_GPMC_CLKCTRL      (PRCM_BASE_ADDR + 0x0030)
    #define SOC_GPMC_0_REGS          (0x50000000)
    #define GPMC_SYSCONFIG           (SOC_GPMC_0_REGS + 0x0010)
    #define GPMC_SYSSTATUS           (SOC_GPMC_0_REGS + 0x0014)
    #define GPMC_IRQENABLE           (SOC_GPMC_0_REGS + 0x001C)
    #define GPMC_TIMEOUT_CONTROL     (SOC_GPMC_0_REGS + 0x0040)
    #define GPMC_CONFIG              (SOC_GPMC_0_REGS + 0x0050)
    #define GPMC_CONFIG1             (SOC_GPMC_0_REGS + 0x0060)
    #define GPMC_CONFIG2             (SOC_GPMC_0_REGS + 0x0064)
    #define GPMC_CONFIG3             (SOC_GPMC_0_REGS + 0x0068)
    #define GPMC_CONFIG4             (SOC_GPMC_0_REGS + 0x006C)
    #define GPMC_CONFIG5             (SOC_GPMC_0_REGS + 0x0070)
    #define GPMC_CONFIG6             (SOC_GPMC_0_REGS + 0x0074)
    #define GPMC_CONFIG7             (SOC_GPMC_0_REGS + 0x0078)
    
    hotmenu SRAM_GPMC_Config()
    {
        unsigned int temp;
    
        GEL_TextOut("****  AM335x SRAM GPMCconfiguration is in progress......... \n","Output",1,1,1);
    
        GEL_TextOut("GPMC PRCM is in progress ....... \n","Output",1,1,1);
        WR_MEM_32(CM_PER_GPMC_CLKCTRL,0x02);
        while(RD_MEM_32(CM_PER_GPMC_CLKCTRL) & 0x00030000u != 0x0);
        GEL_TextOut("GPMC PRCM Done \n","Output",1,1,1);
    
        GEL_TextOut("Resetting GPMC module....... \n","Output",1,1,1,0);
        WR_MEM_32(GPMC_SYSCONFIG,0x02);
        while(RD_MEM_32(GPMC_SYSSTATUS) & 0x1u == 0x0);
        GEL_TextOut("GPMC module reset Done \n","Output",1,1,1);
    
    
        GEL_TextOut("Configuring GPMC module for SRAM access....... \n","Output",1,1,1,0);
    
        // Configure to no idle
        temp = RD_MEM_32(GPMC_SYSCONFIG);
        temp = temp & ~0x18u;
        temp = temp | 0x8u;
        WR_MEM_32(GPMC_SYSCONFIG,temp);
    
        // Disable IRQ
        WR_MEM_32(GPMC_IRQENABLE,0x0u);
    
        // Disable timeout
        WR_MEM_32(GPMC_TIMEOUT_CONTROL,0x0u);
    
        // GPMC controls all addresses
        WR_MEM_32(GPMC_CONFIG,0x0u);
    
        // Chip-select configuration
        // Mask address : chip-select size of 16MB
        // start address = 0x10000000
        temp = SRAM_GPMC_CONFIG7;
        temp |= (GPMC_SIZE_16M<<8)|((CONFIG_SYS_SRAM_BASE>>24)<<0);    
       
        // Configure timings
        WR_MEM_32(GPMC_CONFIG1, SRAM_GPMC_CONFIG1);
        WR_MEM_32(GPMC_CONFIG2, SRAM_GPMC_CONFIG2);
        WR_MEM_32(GPMC_CONFIG3, SRAM_GPMC_CONFIG3);
        WR_MEM_32(GPMC_CONFIG4, SRAM_GPMC_CONFIG4);
        WR_MEM_32(GPMC_CONFIG5, SRAM_GPMC_CONFIG5);
        WR_MEM_32(GPMC_CONFIG6, SRAM_GPMC_CONFIG6);
        WR_MEM_32(GPMC_CONFIG7, temp);
    
    
        // Enable chip select
        temp = RD_MEM_32(GPMC_CONFIG7);
        temp |= (0x1u<<6);
        WR_MEM_32(GPMC_CONFIG7, temp);
    
        GEL_TextOut("Configuration of GPMC module for SRAM access is done ....... \n","Output",1,1,1);
    
    }
    

    and call it after DDR3_EMIF_Config() call for example.

    With this gel file, I was able to access to SRAM in memory window (physical access) and verify write and read timings on my logic analyzer vs datasheet.

    Regards.

  • Hello A2G,
    I really appreciate the input, we were having continuous problems with it and have yet to come up with a solution. We are moving forward with asynchronous access of the FPGA. That has at least allowed us to do about 48Mbyte/s up and down with our timings. Your information has helped in regards to my understanding of the GEL files though(I'm pretty new to this). If/when we have a chance to come back to this I'll definitely come back to post what we find out. For you/community in case it helps anyone else. Thank you so much for taking the time to respond though.
    Best Regards,
    Rodney Miller