BF707 SMC (High-Speed Asynchronous SRAM Writes)

Hello,

How to initialise the SMC controller in "FAST" mode ?

I tried to put the lowest possible values into SMC configuration registres but I it is not enough.

On this picture each write take 30 ns (I guess CLKOUT = SCLK0 = 10ns) and logically with '1' in

Write Access Time the performance can be as low as 20ns per write.

Figure 10-5: "Fast Asynchronous SRAM Writes" from the Hardware Reference manual :

But in my case I have only 80 ns per WRITE and only 160 (!) ns per READ.

What is wrong ?

Another problem - there is no accesses without additional NOPs or another dummy accesses

between the write instructions. Why ? Cross Core compiler add automatically 4 NOPs between

the read instructions but nothing between the read instructions.

There is my code :

void Test_SMC_Speed(void)
{

#ifdef FAST_SMC
//                           ┌──────────────────────────────── ARDY abort enable, ARDY disable
//                           │┌─────────────────────────────── Select Control (AMS0 ORed with ARE, AOE, AWE) - obscure ...
//                           ││┌────────────────────────────── Memory Access Mode - obscure ...
//                           │││┌───────────────────────────── Enable
    *pREG_SMC0_B0CTL = 0x00004001;                            // SMC0 Bank 0 Control Register

//                       ┌┬─────────────────────────────────── Read Access Time = RD\ width, 0 => invalid, 1 => 1 cycle etc
//                       ││┌────────────────────────────────── Read Hold Time
//                       │││┌───────────────────────────────── Read Setup Time, 1 => 1 cycle, 2 => 2 cycle etc but 0 => 8 cycles
    *pREG_SMC0_B0TIM = 0x01010101;                            // SMC0 Bank 0 Timing Register
//                           │││└───────────────────────────── Write Setup Time = CS\ before WR\, 1 => 1 cycle, 2 => 2 cycle etc but 0 => 8 cycles
//                           ││└────────────────────────────── Write Hold Time = maintain CS\ after WR\, 0 => 0 cycles, 1 => 1 cycle etc
//                           └┴─────────────────────────────── Write Access Time = WR\ width, 0 => invalid, 1 => 1 cycle etc

//                           ┌──────────────────────────────── Page Wait States - flash page protocol extension time
    *pREG_SMC0_B0ETIM = 0x00020000;                            // SMC0 Bank 0 Extended Timing Register
//                            │││└──────────────────────────── Pre Setup Time, 0 to 3 cycles
//                            ││└───────────────────────────── Pre Access Time, 0 to 3 cycles
//                            │└────────────────────────────── Transition Time, 0 to 7 cycles
//                            └─────────────────────────────── Idle Time, 0 to 7 cycles


    *pREG_PORTA_MUX = 0xFFFFFFFF;                            // PortA all => Multiplexed Function 3 = SMC
    *pREG_PORTA_FER |= 0xFF00;                                // PortA 8 à 15 => peripheral mode (A1 A2 A3 A4 OE RE WE CE)

    *pREG_PORTB_MUX = 0xFFFFFFFF;                            // PortB all => Multiplexed Function 3 = SMC
    *pREG_PORTB_FER |= 0x01FF;                                // PortB 0 à 10 => peripheral mode (D0 à D8)

    while (1)
    {
        #define pFPGA_INDEX    ((volatile unsigned short *)0x70000000)        // SMC0 Bank 0
        #define pFPGA_DATA    ((volatile unsigned short *)0x70000002)        // SMC0 Bank 0

        register unsigned short test;

// 80 ns per write with SCLK0 = 100 MHz, not 20ns, why ?

        *pFPGA_INDEX = 0x1111;
        asm(" NOP; ");                    // without 'NOP' or another dummy access there is no second FPGA write - why ?
        *pFPGA_INDEX = 0x2222;
        asm(" NOP; ");                    // without 'NOP' or another dummy access there is no third FPGA write - why ?
        *pFPGA_INDEX = 0x3333;

// the first READ is 80 ns after the last WRITE
// but the second and third READ come only 160ns after previous READ - why so long ???

        test = *pFPGA_DATA;                // compiler add 4 NOPs there - why ?
        test = *pFPGA_DATA;                // compiler add 4 NOPs there - why ?
        test = *pFPGA_DATA;                // compiler add 4 NOPs there - why ?

        My_Delay_ms(10);
    }
}

There is assembler code generated by CrossCore :

_Test_SMC_Speed:
11a00eec:   LINK 0xc;
11a00ef0:   R0=0x4001(X);
11a00ef4:   [0x2005d00c]=R0;
11a00efc:   R0=0x1010101;
11a00f04:   [0x2005d010]=R0;
11a00f0c:   R0=0x20000;
11a00f14:   [0x2005d014]=R0;
11a00f1c:   R0=-0x1(X);
11a00f1e:   [0x20040030]=R0;
11a00f26:   NOP;
11a00f28:   NOP;
11a00f2a:   R1=[0x20040000];
11a00f32:   NOP;
11a00f34:   NOP;
11a00f36:   NOP;
11a00f38:   R2=0xff00(Z);
11a00f3c:   R1=R1|R2;
11a00f3e:   [0x20040000]=R1;
11a00f46:   [0x200400b0]=R0;
11a00f4e:   NOP;
11a00f50:   NOP;
11a00f52:   R0=[0x20040080];
11a00f5a:   NOP;
11a00f5c:   NOP;
11a00f5e:   NOP;
11a00f60:   R1=0x1ff(X);
11a00f64:   R0=R0|R1;
11a00f66:   [0x20040080]=R0;
11a00f6e:   R7=0x1111(X);
11a00f72:   W[0x70000000]=R7;
11a00f7a:   NOP;
11a00f7c:   R0=0x2222(X);
11a00f80:   W[0x70000000]=R0;
11a00f88:   NOP;
11a00f8a:   R0=0x3333(X);
11a00f8e:   W[0x70000000]=R0;
11a00f96:   NOP;
11a00f98:   NOP;
11a00f9a:   R0=W[0x70000002](X);
11a00fa2:   NOP;
11a00fa4:   NOP;
11a00fa6:   NOP;
11a00fa8:   NOP;
11a00faa:   R0=W[0x70000002](X);
11a00fb2:   NOP;
11a00fb4:   NOP;
11a00fb6:   NOP;
11a00fb8:   NOP;
11a00fba:   R0=W[0x70000002](X);
11a00fc2:   NOP;
11a00fc4:   NOP;
11a00fc6:   NOP;
11a00fc8:   R0=0xa(X);
11a00fca:   CALL.L _My_Delay_ms;

3. Screenshot : (CS, WE, OE)

Regards

Eugene

Parents Reply Children