Static EMC read using 2x the configured clock cycles

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by mdittrich on Tue Feb 26 11:51:05 MST 2013

I have a 32bit static EMC bus interfacing an FPGA, I am working on getting them bolted together.  I am observing that a write transaction completes in the configured amount of clock cycles, but the reads are taking twice as long.

My FPGA logic looks for CS being low and the address (bits 10 downto 2) not changing for one EMC clock before I honor the OE or WE signals.  I have test points from the FPGA passing its view of the CS signal out.  I also have outputs that assert when I am honoring the OE and WE signals.  My last test point is the result of the "current address equals last address" comparator.

My static config code for CS2:

  LPC_EMC->STATICCONFIG2 =  (2 << 0)  | /* MW[1:0] = 2 (32 bit Memory Width) */
                            (0 << 3)  | /* PM = 0 page mode disabled         */
                            (0 << 6)  | /* PC = 0 (Active LOW chip select)   */
                            (1 << 7)  | /* PB = 1 (All BLS HIGH for read)
                                         *  must be 1 for WE to be significant */
                            (0 << 8)  | /* EW = 0 (DISABLED extended wait)   */
                            (0 << 19) | /* B = 0 (DISABLED buffer)           */
                            (0 << 20);  /* P = 0 (DISABLED write protect)    */

  /* WAITWEN[3:0] = 0x0 (n+1 encoded - EMC_CLK cycle delay between
   assertion of chip select to write enable.)            */
  LPC_EMC->STATICWAITWEN2 = 0x0; // 1 clk

  /* WAITOEN[3:0] = 0x1 (n+0 encoded -  EMC_CLK cycle delay from chip
     select or address change to output enable.)            */
  LPC_EMC->STATICWAITOEN2 = 0x0; // 0 clk

  /* WAITRD[4:0]  = 0x1 (n+1 encoded - EMC_clk cycle delay from the chip
     select to the read access.)                            */
  LPC_EMC->STATICWAITRD2 = 0x3; //4 clocks

  /* WAITPAGE[4:0] = 0x0 (n+1 encoded - EMC_CLK delay for asynchronous
     page mode sequential accesses.) we have page mode disabled */
  LPC_EMC->STATICWAITPAG2 = 0x0; // should be insignificant

  /* WAITWR[4:0] = 0x0 (n+2 encoded - EMC_CLK delays from the chip select
     to the write access.)                                  */
  LPC_EMC->STATICWAITWR2 = 0x2; // 4 clocks

  /* WAITTURN[3:0] = 0x1 (n+1 encoded - Bus turn-around cycles AKA two
     EMC_CLK delays between external bus transfers.)        */
  LPC_EMC->STATICWAITTURN2 = 0x0; // 1 clocks

Static CS2 is the only static bank I am using, but I have SDRAM on dynamic CS0. I am not yet concerned about the exact wait state settings, but how the EMC behaves and how I need to write my FPGA logic.  All accesses to the FPGA map are by 32 bit words, on 32 bit boundaries.

Attached is a screen shot from my scope for a read: signal 3 is the "address has not changed" comparator, signal 2 is CS2 (unregistered by the FPGA, just a pass through), signal 1 is my "write is honored", signal 0 is "read is honored".  The EMC is running at 96MHz (divided by 2 from 192MHz core).  Here the CS is ~82ns (8 clks) and my decoded "ok to do work" signal is ~32ns (4 clks), but I get 2 of them because the address changes half way through the doubled up read cycle...

Also attached is a write, and it completes in the expected time, ~42ns (4 clks) for "write OK".

Enabling the buffers in bit 19 of the config register does not make things better.  My control code does 11 of these reads every loop, my scope shows 22 edges of the "read ok" signal with the buffers disabled.  When I enabled the buffers the CS is only ~40ns long, my 11 regular reads do not cause any bus activity ("ok to read" signal).  Single stepping, a "ldr" instruction from one of these regular reads causes no activity. And, then I get the "double transactions" on the regular writes I do every loop...

I have not yet experimented with the PB bit that affects the byte lane selects.

So is this expected read behavior with the buffers disabled (as enabling them does not seem to be workable)?  Burning 11 x 32ns per tick is not going to kill my app, but I eventually need a fifo interface... and I like to avoid "fancy" bus logic for that would suppress one of the extra transactions.