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
  • 0
    •  Analog Employees 
    on Oct 12, 2018 1:03 PM over 2 years ago

    Hi Eugene,

     

    Regarding the "Nop" between read and write, please go through the following threads and you would get better understanding.

    https://ez.analog.com/dsp/blackfin-processors/f/q-a/59056/writing-to-asynchrone-memory

    https://ez.analog.com/dsp/blackfin-processors/f/q-a/59075/delay-between-asynchronous-memory-writes-reads

     

    Also if your project enables the I/D Cache in Cache configuration setting under the system.svc tab, kindly disable the cache and check whether you are able get going?  


    Regards,
    Jithul

  • Hello Jithul

    1. How to enable/disable I/D Cache in Cache configuration setting under the system.svc tab ? In my system.svc tab I have 3 installed plugins but none relative to cache memory configuration.

    1. There is no answers in your links, only questions - how to reduce the delay between two asynchronous memory writes or reads. There are no answer in 10 years and it is very disturbing.

    2. In fact after many tests, I found that using of NOPs is not very reliable. The single safe way is to use ssync() calls. But is  very slow. I can do better by by simulating the asynchronous bus by driving CS, WR and others pins individually in GPIO mode. I am very sad to be forced to do that and I am very disappointed by Blackfin SMC controller.

  • 0
    •  Analog Employees 
    on Nov 30, 2018 4:01 PM over 2 years ago in reply to neky

    Hello,

    1) How to enable/disable I/D Cache in Cache configuration setting under the system.svc tab ? In my system.svc tab I have 3 installed plugins but none relative to cache memory configuration.

    >> Please see below image for the reference and follow the path as given below to enable the Cache
    Project Explorer >> Project >> System.svc >> Startup LDF >> Cache configuration

    Further, cache can be configured by the control registers and brief about working with cache can be found in the "Memory" section of ADSP-BF70x Programming reference manual.

    Can you please enable the Cache and check whether read and write latency get reduced ?

    Note : When Cache is Enabled, you need to ensure that the valid CPLB's are covered for the external memory regions which you want to access in the file "app_cplbtab"(project folder>>system/startup LDF/cplbtab.c) , otherwise you would get an Exceptions.


    2) There is no answers in your links, only questions - how to reduce the delay between two asynchronous memory writes or reads. There are no answer in 10 years and it is very disturbing.
    >> Regarding your question, "Another problem - there is no accesses without additional NOPs or another dummy accesses between the write instructions. Why ?"
    In the write operations, the store instruction is considered complete as soon as it executes, even though many cycles may execute before the data is actually written to an external memory or I/O location. Typically, the "Nop" instruction allows previous instructions time to complete before continuing with subsequent instructions.

    3) Regarding "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 ???"
    >> we are working on this.

    Regards,
    Jithul

Reply
  • 0
    •  Analog Employees 
    on Nov 30, 2018 4:01 PM over 2 years ago in reply to neky

    Hello,

    1) How to enable/disable I/D Cache in Cache configuration setting under the system.svc tab ? In my system.svc tab I have 3 installed plugins but none relative to cache memory configuration.

    >> Please see below image for the reference and follow the path as given below to enable the Cache
    Project Explorer >> Project >> System.svc >> Startup LDF >> Cache configuration

    Further, cache can be configured by the control registers and brief about working with cache can be found in the "Memory" section of ADSP-BF70x Programming reference manual.

    Can you please enable the Cache and check whether read and write latency get reduced ?

    Note : When Cache is Enabled, you need to ensure that the valid CPLB's are covered for the external memory regions which you want to access in the file "app_cplbtab"(project folder>>system/startup LDF/cplbtab.c) , otherwise you would get an Exceptions.


    2) There is no answers in your links, only questions - how to reduce the delay between two asynchronous memory writes or reads. There are no answer in 10 years and it is very disturbing.
    >> Regarding your question, "Another problem - there is no accesses without additional NOPs or another dummy accesses between the write instructions. Why ?"
    In the write operations, the store instruction is considered complete as soon as it executes, even though many cycles may execute before the data is actually written to an external memory or I/O location. Typically, the "Nop" instruction allows previous instructions time to complete before continuing with subsequent instructions.

    3) Regarding "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 ???"
    >> we are working on this.

    Regards,
    Jithul

Children
No Data