Tool/software:
We use GPMC bus to interface with an FPGA in asynchronous mode and with use of WAIT signal.
The strange thing that happens is that when reading we notice a time between one cycle and the next that is much longer than when writing (about 120 ns more).
To perform the tests we inserted a cycle of 100 readings and a cycle of 100 writings:
static volatile unsigned short n,a,b,c,d,e,f,g,h,i,l;
for (n=0;n<10;n++)
{
a=(* (unsigned short *) 0xA01E000);
b=(* (unsigned short *) 0xA01E002);
c=(* (unsigned short *) 0xA01E004);
d=(* (unsigned short *) 0xA01E006);
e=(* (unsigned short *) 0xA01E008);
f=(* (unsigned short *) 0xA01E00A);
g=(* (unsigned short *) 0xA01E00C);
h=(* (unsigned short *) 0xA01E00E);
i=(* (unsigned short *) 0xA01E010);
l=(* (unsigned short *) 0xA01E012);
}
for (n=0;n<10;n++)
{
(* (unsigned short *) 0xA01C00E)=a;
(* (unsigned short *) 0xA01C010)=b;
(* (unsigned short *) 0xA01C012)=c;
(* (unsigned short *) 0xA01C00E)=d;
(* (unsigned short *) 0xA01C010)=e;
(* (unsigned short *) 0xA01C012)=f;
(* (unsigned short *) 0xA01C00E)=g;
(* (unsigned short *) 0xA01C010)=h;
(* (unsigned short *) 0xA01C012)=i;
(* (unsigned short *) 0xA01C00E)=l;
}
These are the writing times:
These are the reading times:
You can notice that the time between when the CS goes high and when it goes back low is much longer in reading access (the red arrow indicate the difference).
Obviously, when reading, the CPU must save the variables in DDR, but it is an operation which however should take much shorter times than 120 ns.
We set the GPMC bus timing values to almost minimum but with no improvement. If we decrease them further the bus starts to give errors or lock the CPU.
These are the minimum possible settings we used:
WAIT0=high active
BUS=16 bit
WRACCESSTIME= 2 (15ns)
RDACCESSTIME= 2 (15ns)
WRCYCLETIME= 4 (30ns)
RDCYCLETIME= 4 (30ns)
CSONTIME=1 (7,5ns)
CSRDOFFTIME= 3 (22ns)
CSEXTRADELAY=0
WEONTIME=0
OEONTIME=0
WEOFFTIME=4 (30ns)
OEOFFTIME= 4 (30ns)
CYCLE2CYCLEDELAY=6(45ns)
BASEADDRESS=0x10
The code:
//******* GPMC INITIALIZATION (FPGA interface)********************
// note: GPMC_FCLK = 133Mhz (1 period = 7.5nsec).
SOC_moduleClockEnable(TISCI_DEV_GPMC0, 1);
// wait for reset (RESETDONE)
while((*((volatile uint32_t*)GPMC_SYSSTATUS) & TESTBIT_0)==0)
{}
//WAIT0 active high, WAIT1 active high
*((volatile uint32_t*)GPMC_CONFIG) = SETBIT_9 | SETBIT_8;
//GPMC IRQ disabled
*((volatile uint32_t*)GPMC_IRQENABLE) = 0;
//TIMEOUTSTARTVALUE=511 GPMC_FCLK cycles, TIMEOUTENABLE=0
*((volatile uint32_t*)GPMC_TIMEOUT_CONTROL) = (511<<4);
//WAIT MONITORING ENABLED (su read e write), uso WAIT0, 16 BIT BUS
*((volatile uint32_t*)GPMC_CONFIG1_0) = SETBIT_22 | SETBIT_21 | SETBIT_12;
//CSWROFFTIME=3 (22ns), CSRDOFFTIME=3 (22ns), CSEXTRADELAY=0, CSONTIME=1
*((volatile uint32_t*)GPMC_CONFIG2_0) = (3<<16) | (3<<8) | 1;
//WEOFFTIME=4 (30ns), WEONTIME=0, OEOFFTIME=4 (30ns), OEONTIME=0
*((volatile uint32_t*)GPMC_CONFIG4_0) = (4<<24) | (4<<8);
//PAGEBURSTACCESSTIME=1(default), RDACCESSTIME=2 (15ns), WRCYCLETIME=4 (30ns) , RDCYCLETIME=4 (30ns)
*((volatile uint32_t*)GPMC_CONFIG5_0) = (1<<24) | (2<<16) | (4<<8) | 4;
//WRACCESSTIME=2 (15ns), WRDATAONADMUXBUS=7(default), CYCLE2CYCLEDELAY=6 (45ns), CYCLE2CYCLESAMECSEN=1
*((volatile uint32_t*)GPMC_CONFIG6_0) = (2<<24) | (7<<16) | (6<<8) | SETBIT_7;
//MASKADDRESS=0xF(16MB), CSVALID=1, BASEADDRESS=0x10 (0x50000000)
*((volatile uint32_t*)GPMC_CONFIG7_0) = (0xF<<8) | SETBIT_6 | 0x10;
//*********************************************************************
So in conclusion, the final question is: is it possible to decrease the time between one read cycle and the next so as to make it as fast as writing or is it a limitation of the GPMC bus architecture and therefore cannot be improved?
Thanks in advance
Best regards
Francesco Parolini