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.

How do I set up then access L1 memory as SRAM

Guru 10685 points

Other Parts Discussed in Thread: SYSBIOS

Hi, I have a DM8168 and I want to DMA data from main memory (DDR) into L1 memory in my IUNIVERSAL codec..

1) How do I configure L1 as SRAM? Can I configure all of L1P and L1D for my algorithm or will this cause problems if some of it needs to be used as normal cache for the C674x? Presumably I need to modify my codec server config.bld file?

2) How do I allocate/access memory from the L1 SRAM area in my codec? At present my codec can happily DMA (using ECPY) to and from main memory. I just need to work out how to do this between main memory and L1.

Here's some of my codec server config.bld in case it's useful:

var mem_ext = [
["DDR3_HOST", {
    comment:    "DDR3 Memory reserved for use by the A8",
    name:       "DDR3_HOST",
    base:       0x80000000,
    len:        0x16C00000,
    }
],
["DDR3", {
    comment:    "DDR3 Memory reserved for use by the C674",
    name:       "DDR3",
    base:       0x99500000,
    len:        0x00C00000,
    }
],
["DDRALGHEAP", {
    comment:    "DDRALGHEAP: off-chip memory for dynamic allocation",
    name:       "DDRALGHEAP",
    base:       0x98000000,
    len:        0x01400000,
    }
],
["DDR3_SR2", {
    comment:    "DDR3 Memory reserved for use by SharedRegion 2",
    name:       "DDR3_SR2",
    base:       0xB3D00000,
    len:        0x0BC00000,
    }
],
["DDR3_SR1", {
    comment:    "DDR3 Memory reserved for use by SharedRegion 1",
    name:       "DDR3_SR1",
    base:       0x9A100000,
    len:        0x00100000,
    }
],
["DDR3_SR0", {
    comment: "DDR3 Memory reserved for use by SharedRegion 0",
    name: "DDR3_SR0",
    base: 0x9F700000,
    len:  0x00200000
    }
],
];


/* platform instances used by this package */
Build.platformTable["ti.platforms.evmTI816X"] = {
    externalMemoryMap: mem_ext,
    l1DMode:"32k",
    l1PMode:"32k",
    l2Mode:"128k",
    codeMemory: "DDR3",
    dataMemory: "DDR3",
    stackMemory: "DDR3"
};

Thanks,

Ralph

P.S.

Gunjan said in this post that he'd managed to get DMA into L1 going using ECPY for the DM8168 (which is exactly what I want to do) but didn't describe how.

  • Ralph,

    You can change the size of the l1DMode.  I think the options are "0k", "4k", "8k", "16k", and "32k".  "0k" would mean it is all RAM and "32k" means it is all cache.

    Judah

  • Hi Judah,

    Okay, but how will this affect performance if there's less cache for the DSP?

    How do I work out the safe maximum SRAM I can have and thus the safe minimum cache?

    Most importantly, should I call malloc to access this memory, or is the memory management of this cache entirely up to me?

    I tried using memcpy to copy data from main memory to the address of L1D as it is in the DM8168 datasheet (0x00F00000) but nothing happened. :'-(

    Thanks Ralph

  • One more question: why does this thread not show up on the TI-RTOS main forum page?

  • I can see this thread on the forum page...

  • Okay thanks. I just realised I had for some strange reason it set to "only display unread threads".

    Just need some answers now.... :-)

  • Ralph,

    Okay, but how will this affect performance if there's less cache for the DSP?

    Don't know, it depends on your app.  If your app is doing lots of external DDR accesses, a larger cache would be better.

    How do I work out the safe maximum SRAM I can have and thus the safe minimum cache?

    Any amount of cache should be safe.  It comes down to which is the best performance.  You might have to try different sizes and see what works for you.

    Most importantly, should I call malloc to access this memory, or is the memory management of this cache entirely up to me?

    Its entirely up to you.

    Judah

  • Ralph,

    You can try doing an internal->external, or external->internal transfer in that same same universal_dma example. See \framework_components_3_24_02_15\examples\archive\TI816X_bios_elf\ex22_universal_ecpy_dsp\app.c. It places the "SRCBUFF" and "DSTBUFF" in ".EXT_HEAP". In the same folder, local.cfg also creates an internal memory heap called ".INT_HEAP". 

    Just use the pragma to place one of these buffers in internal memory and see if the examples builds/runs okay.

    Thanks,

    Gunjan.

  • judahvang said:

    Most importantly, should I call malloc to access this memory, or is the memory management of this cache entirely up to me?

    Its entirely up to you.

    But how do I access this memory and what address should I be using? I've tried literally memcpying to 0x00F00000 where L1D is meant to be according to the datasheet but when I try to memcpy the same data out again nothing happens.

  • Hi Gunjan, thanks for your helpful reply. I'm going to have a look at the example you mentioned and report back.

    Ralph

  • Actually Gunjan, on second thoughts I'm not sure how applicable that example is since it doesn't use codec engine I don't think, or at least it runs entirely on the DSP rather than the setup I have whereby the codec and codec server run on the DSP and the application runs on the ARM.

    What I have at the moment is in my codec server "config.bld" file:

    Build.platformTable["ti.platforms.evmTI816X"] = {
        externalMemoryMap: mem_ext,
        l1DMode:"4k",
        l1PMode:"32k",
        l2Mode:"128k",            
        codeMemory: "DDR3",
        dataMemory: "DDR3",
        stackMemory: "DDR3"
    };

    Then in my "server.cfg" I have:

    /* heap config */
    var internalMemoryName = 'IRAM';
    var internalHeapSize = 0xc000;     //  48 kB

    /* Configure internal and external heaps */
    Program.global.INT_HEAP =
        createHeapMem(internalHeapSize, ".INT_HEAP", internalMemoryName);

    var DSKT2 = xdc.useModule('ti.sdo.fc.dskt2.DSKT2');
    DSKT2.DARAM0     = "INT_HEAP";
    DSKT2.DARAM1     = "INT_HEAP";
    DSKT2.DARAM2     = "INT_HEAP";
    DSKT2.SARAM0     = "INT_HEAP";
    DSKT2.SARAM1     = "INT_HEAP";
    DSKT2.SARAM2     = "INT_HEAP";
    DSKT2.ESDATA     = "EXTALG_HEAP";
    DSKT2.IPROG      = "INT_HEAP";
    DSKT2.EPROG      = "EXTALG_HEAP"
    DSKT2.DSKT2_HEAP = "EXT_HEAP";

    DSKT2.ALLOW_EXTERNAL_SCRATCH = false;
    DSKT2.SARAM_SCRATCH_SIZES[GROUP_2] = 0x0000;
    DSKT2.DARAM_SCRATCH_SIZES[GROUP_2] = 0x0000;

    Obviously I'm only posting the part of these two files that I think is relevant.

    The internal heap size is larger than the entire L1D section!!! What do I need to get this working so I can then use

    #pragma DATA_SECTION(L1SRAM, ".INT_HEAP")

    to ensure the array "L1SRAM" is allocated from L1D?

    Thanks,
    Ralph

  • Ralph,

    There isn't that much memory in L1DSRAM.  Max is 32KB assuming none of it is used for Cache.  If you need a 48KB heap then you cannot use L1DSRAM.  You would need to decrease your internal heap size.

    Judah

  • Hi Judah,

    I didn't make myself clear; I didn't enter the 48kB, this is just what was in there by default. I created this codec server using the gencodecserver wizard and it just seems to be set up this way.

    Should I decrease this 48kB to 20kB so that it matches my .cfg?

    I only need 20kB heap (in S1D) and 4kB cache (in S1D as well).

    Ralph

  • Well, I tried decreasing it to 20kB and nothing happened. :'-(

    Also, I'd like to add that it's great that examples are being added to Framework Components however what is really needed is examples using Codec Engine that have the application part running on the ARM and the codec server and codec running on the DSP.

    It's easy to get stuff running *JUST* on the DSP with XDAIS/XDM but when you add in the ARM and Codec Engine, things get more complicated. The latter examples are obvious in their absence from the Framework Components.

    Ralph

  • Ralph,

    Here's some information about the default platform files that may be relevant for you:-

    IRAM is actually memory from the L2. By default it is set to be all RAM. It can be configured  in the same way as L1, to be distributed as cache/RAM (as Judah mentioned earlier). You may change the setting l2Mode to increase/decrease RAM/cache. Name of the L2 RAM memory section is "IRAM". L1D memory has the setting l1DMode to do the same, and the RAM section created (if l1DMode is set to 0,4,8,16k) will be called L1DSRAM.

    If you would like to use L1DSRAM section for your internal heap needs, you will need to set l1DMode to something under 32K and add something equivalent to this line:-

    Program.global.L1D_HEAP =
        createHeapMem(newSize, ".L1D_HEAP", "L1DSRAM");

    You can choose to use either L1DSRAM or IRAM for your DSKT2 sections, DMA memory buffers.

    I am hoping the above is sufficient information to let you accomplish what you are trying to do.

    FYI, the file I am referring to get all the platform information is:-

    xdctools_3_25_00_48/packages/ti/catalog/c6000/

    TMS320TI816X.xdc and ITI8168.xdc

  • Thanks Gunjan, I wasn't using those configuration lines before. I've added them in but am still not seeing any success. I'll summarise my setup to you in the hope that you can spot a flaw.

    Please bear in mind that I have the algorithm already working fine using a direct memcpy between source and destination buffers (allocated in shared memory 2). When I insert an intermediate step of copying data to L1D first, and then onto the destination I don't see any data copied. I've only listed the code I think is relevant to allocation and use of L1D SRAM so there is more that I am copying and pasting here obviously.

    So, here is the relevant code.

    In my codec "main.c":

    <<TOP OF FILE>>

    #pragma DATA_SECTION(L1SRAM, ".L1DSRAM")
    unsigned int L1SRAM[28*1024];

    #define L1SIZE  (1024*28)

    <<My IUNIVERSAL process function>>

    memcpy((unsigned int *)inBufs->descs[0].buf, L1SRAM, L1SIZE);
    memcpy(L1SRAM, (unsigned int *)outBufs->descs[0].buf, L1SIZE);

    XDM_CLEARACCESSMODE_WRITE(inBufs->descs[0].accessMask);
    XDM_CLEARACCESSMODE_READ(inBufs->descs[0].accessMask);

    // report how we accessed the output buffer
    XDM_CLEARACCESSMODE_READ(outBufs->descs[0].accessMask);
    XDM_CLEARACCESSMODE_WRITE(outBufs->descs[0].accessMask);

    In my codec server main.c:

    extern xdc_runtime_IHeap_Handle L1D_HEAP;

    In my codec server "server.cfg":

    var sramMemoryName = 'L1DSRAM';
    var sramHeapSize = 0x7000;    // 28 kB
    var internalMemoryName = 'IRAM';
    var internalHeapSize = 0xc000;     //  48 kB
    var externalMemoryName = 'DDR3';
    var externalHeapSize = 0x20000;    // 128 kB

    ...

    /* Configure internal and external heaps */
    Program.global.EXT_HEAP =
        createHeapMem(externalHeapSize, ".EXT_HEAP", externalMemoryName);
    Program.global.INT_HEAP =
        createHeapMem(internalHeapSize, ".INT_HEAP", internalMemoryName);
    Program.global.L1D_HEAP =
        createHeapMem(sramHeapSize, ".L1D_HEAP", sramMemoryName);

    ...

    var DSKT2 = xdc.useModule('ti.sdo.fc.dskt2.DSKT2');
    DSKT2.DARAM0     = "INT_HEAP";
    DSKT2.DARAM1     = "INT_HEAP";
    DSKT2.DARAM2     = "INT_HEAP";
    DSKT2.SARAM0     = "INT_HEAP";
    DSKT2.SARAM1     = "INT_HEAP";
    DSKT2.SARAM2     = "INT_HEAP";
    DSKT2.ESDATA     = "EXTALG_HEAP";
    DSKT2.IPROG      = "INT_HEAP";
    DSKT2.EPROG      = "EXTALG_HEAP"
    DSKT2.DSKT2_HEAP = "EXT_HEAP";

    DSKT2.ALLOW_EXTERNAL_SCRATCH = false;
    DSKT2.SARAM_SCRATCH_SIZES[GROUP_2] = 0x0000;
    DSKT2.DARAM_SCRATCH_SIZES[GROUP_2] = 0x0000;

    <<Should I be changing something in this section above???>>

    Codec server config.bld:

    Build.platformTable["ti.platforms.evmTI816X"] = {
        externalMemoryMap: mem_ext,
        l1DMode:"4k",
        l1PMode:"32k",
        l2Mode:"128k",            
        codeMemory: "DDR3",
        dataMemory: "DDR3",
        stackMemory: "DDR3"
    };

    Thanks,

    Ralph

  • Also, I'm not sure if I should have any setup code for the L1D in my codec server main.c. Here is my entire codec server main.c:

    /*
     *  ======== main.c ========
     */
    #include <xdc/std.h>
    #include <ti/sdo/ce/CERuntime.h>
    #include <xdc/runtime/Log.h>
    #include <xdc/runtime/Diags.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/ipc/Ipc.h>


    /* Need to configure all the FC modules before their "inits" are called */
    #include <ti/sdo/fc/rman/rman.h>
    #include <ti/sdo/fc/dskt2/dskt2.h>
    #include <ti/sdo/fc/edma3/edma3_config.h>

    #include <ti/sdo/fc/ecpy/ecpy.h>

    #include <xdc/runtime/IHeap.h>

    extern xdc_runtime_IHeap_Handle L1D_HEAP;


    /*
     *  ======== main ========
     */
    Void main(Int argc, Char* argv [])
    {
        Int     status;

        do {
            status = Ipc_start();
        } while (status < 0);

        /* alloc and free functions need to be assigned to appropriate delegates */
        EDMA3_PARAMS.allocFxn = &DSKT2_allocPersistent;
        EDMA3_PARAMS.freeFxn = &DSKT2_freePersistent;

        /*
         *  Since only 1 scratch group is  being used (2) by the servers algorithms,
         *  configure the number of Params, tccs, edma/qdma channels required for that
         *  group.
         */
        EDMA3_paRamScratchSizes[2] = 15;    /* Maximum number of PaRams in group */
        EDMA3_tccScratchSizes[2] = 3;       /* Number of tcc's in this group */
        EDMA3_edmaChanScratchSizes[2] = 3;  /* Number of edma3 channels in this group */
        EDMA3_qdmaChanScratchSizes[2] = 0;  /* Number of qdma channels in this group */

        /* Configure ECPY */
        ECPY_CFG_PARAMS.allocFxn = &DSKT2_allocPersistent;
        ECPY_CFG_PARAMS.freeFxn = &DSKT2_freePersistent;

        /* init Codec Engine */
        CERuntime_init();   // Calls RMAN_init

        BIOS_start();
    }

    Ralph

  • I'm still not getting this to work. Any chance of some help? Thanks.

  • Hi, it's weird how this build fine but won't run as it should.

    Should I put a new post on the forum about this issue? It is all related to the same thing so it seems a waste to do that. :-S

    Ralph

  • Solved it here:

    http://e2e.ti.com/support/embedded/bios/f/355/p/304114/1061771.aspx#1061771