OVP Forums - A community of assistance, help, questions, and answers.
  FAQFAQ    SearchSearch      RegisterRegister  ProfileProfile    Log in to check your private messagesLog in to check your private messages    Log inLog in
Cache

 
Post new topic   Reply to topic    Open Virtual Platforms Forum Index -> Ask a Question
View previous topic :: View next topic  
Author Message
AntonioPrioletti



Joined: 02 May 2011
Posts: 20

PostPosted: Fri Sep 16, 2011 7:13 am    Post subject: Cache Reply with quote

Hi, I would suggest a problem. I have created an architecture with two processors, and I instanced a cache full privacy for both processors, and then a cache shared by connecting it always full to the first two via a single bus for sharing. Now if I make a call before the main application where a variable x-volatile, then the processor assigns the value 0 3. When I go to read the value of the variable x with the processor 1 this is always 0 and not 3 because the processor 0 has changed. Looking at the address of the variable x that coincides for both variables, then how come I always value 0? :cry:
Back to top
View user's profile Send private message
AntonioPrioletti



Joined: 02 May 2011
Posts: 20

PostPosted: Fri Sep 16, 2011 1:32 pm    Post subject: Re: Cache Reply with quote

Sorry, but in precedent post I wrote a really poor english, because I am Italian; now think that it is better.

Hi, I would suggest a problem. I have created an architecture with two processors, and I instanced a full private cache for both processors, and then a shared cache of second level always full, by connecting it with the first via a single share bus. Now a create an example application when I define a volatile variable x, then the processor 0 assigns to it the value 3. When I go to read the value of the variable x with the processor 1 this is always 0 and not 3 though the processor 0 has changed that value in 3. Looking at the address of the variable x in both processor, that coincides, How can i solve this problem, doing so that the processor 1 read value 3 and not 0?

The code is:

Code:
volatile int x;

int proc0(int id)
{
   
    printf("Cpu 0, before change x = %d \n", x);
    x = 3;
    printf("Cpu 0, after change x = %d, with address %p\n", x, &x);
}

int proc1(int id)
{
    printf("Cpu 1, before change x = %d, with address %p\n", x, &x);
    x = 20;
    printf("Cpu 1, after change x = %d\n", x);
}



int main(int argc, char **argv) {
   
    int id = impProcessorId();
    printf("CPU %d starting...\n", id);

    switch(id) {

        case 0:
            proc0(id);
            break;

        case 1:
             proc1(id);
             break;

        case 2:
            break;
    }
   
    return 1;
}
Back to top
View user's profile Send private message
DuncGrah
OVP Technologist
OVP Technologist


Joined: 27 Feb 2008
Posts: 1646
Location: United Kingdom

PostPosted: Mon Sep 19, 2011 4:22 am    Post subject: Reply with quote

I guess the first question I have is the write back policy you have created in the cache models? Will the cache get flushed after every write?

Another issue may be that this is a very short and trivial program. It is most likely that it would complete in a single quantum execution (the default quantum is 1mS or 100M instructions). There is no checking in the program so the processor will write the data and finish so you will get no interactions.

Have you any debug code in your cache models to indicate that the transfers are working and are correct?
Back to top
View user's profile Send private message Visit poster's website
AntonioPrioletti



Joined: 02 May 2011
Posts: 20

PostPosted: Mon Sep 19, 2011 10:43 am    Post subject: Reply with quote

the code of platform is the following:

Code:
int main(int argc, char ** argv) {

    int portNum;
    const char *appName;
   
    // check for the application program name argument
    if(argc<2) {
        icmPrintf("usage: %s <application> [<port> <processor>]\n", argv[0]);
        return -1;
    }
    if(argc<3){
        // initialize ICM - require Imperas intercepts because the
        // application uses impProcessorId() to get processor id
        icmInit(ICM_VERBOSE|ICM_ENABLE_IMPERAS_INTERCEPTS, 0, 0);
    }
    else {
         if(argc<4){
              icmPrintf("usage: %s <application> <port> <processor> \n", argv[0]);
              return -1;     
         }
         else{
                  sscanf(argv[2], "%d", &portNum);
                  // initialize ICM - require Imperas intercepts because the
                  // application uses impProcessorId() to get processor id
                  icmInit(ICM_VERBOSE|ICM_ENABLE_IMPERAS_INTERCEPTS, "rsp", portNum);
         }
    }
   
    appName = argv[1];
   
    // select library components
   const char *vlnvRoot = NULL; //When NULL use default library
    const char *model       = icmGetVlnvString(vlnvRoot, "ovpworld.org", "processor", "or1k", "1.0", "model");
    const char *semihosting = icmGetVlnvString(vlnvRoot, "ovpworld.org", "semihosting", "or1kNewlib", "1.0", "model");
    const char *mmc_model = icmGetVlnvString( vlnvRoot, "ovpworld.org", "mmc", "wb_1way_32byteline_2048tags", "1.0","model");

    // create processor cpu0
    icmProcessorP processor0 = icmNewProcessor(
        "cpu0",             // CPU name
        "or1k",             // CPU type
        0,                  // CPU cpuId
        0,                  // CPU model flags
        32,                 // address bits
        model,              // model file
        "modelAttrs",       // morpher attributes
        SIM_ATTRS,          // simulation attributes
        0,                  // user-defined attributes
        semihosting,        // semi-hosting file
        "modelAttrs"        // semi-hosting attributes
    );
   
    //create processor cpu1
    icmProcessorP processor1 = icmNewProcessor(
        "cpu1",             // CPU name
        "or1k",             // CPU type
        1,                  // CPU cpuId
        0,                  // CPU model flags
        32,                 // address bits
        model,              // model file
        "modelAttrs",       // morpher attributes
        SIM_ATTRS,          // simulation attributes
        0,                  // user-defined attributes
        semihosting,        // semi-hosting file
        "modelAttrs"        // semi-hosting attributes
    );
   
   
    // create full MMCs
    icmMmcP mmci1 = icmNewMMC("mmci1", mmc_model, "modelAttrs", 0, 0, False);
    icmMmcP mmcd1 = icmNewMMC("mmcd1", mmc_model, "modelAttrs", 0, 0, False);
   
    icmMmcP mmci2 = icmNewMMC("mmci2", mmc_model, "modelAttrs", 0, 0, False);
    icmMmcP mmcd2 = icmNewMMC("mmcd2", mmc_model, "modelAttrs", 0, 0, False);

    // memory cache L2
    icmMmcP mmcL2 = icmNewMMC("mmcL2", mmc_model, "modelAttrs", 0, 0, False);
   
    // create the processor instruction bus and data bus
    icmBusP ibus1 = icmNewBus("ibus1", 32);
    icmBusP dbus1 = icmNewBus("dbus1", 32);

    icmBusP ibus2 = icmNewBus("ibus2", 32);
    icmBusP dbus2 = icmNewBus("dbus2", 32);
   
    //bus per cache L2
    icmBusP buscache = icmNewBus("buscache", 32);
   
    // main bus
    icmBusP mbus = icmNewBus("mbus", 32);
   
    // connect processor ports to their buses
    icmConnectProcessorBusses(processor0, ibus1, dbus1);
    icmConnectProcessorBusses(processor1, ibus2, dbus2);
   
    // connect MMCs to buses
    icmConnectMMCBus(mmci1, ibus1, "sp1", False);
    icmConnectMMCBus(mmcd1, dbus1, "sp1", False);
   
    icmConnectMMCBus(mmci2, ibus2, "sp1", False);
    icmConnectMMCBus(mmcd2, dbus2, "sp1", False);
   
    // connect master ports of MMC layer 1 to buscache
    icmConnectMMCBus(mmci1, buscache, "mp1", True);
    icmConnectMMCBus(mmcd1, buscache, "mp1", True);
   
    icmConnectMMCBus(mmci2, buscache, "mp1", True);
    icmConnectMMCBus(mmcd2, buscache, "mp1", True);
   
    // connect MMC layer 2 to buscache
    icmConnectMMCBus(mmcL2, buscache, "sp1", False);
   
    // connect MMC layer 2 to main bus
    icmConnectMMCBus(mmcL2, mbus, "mp1", True);
   
    // create memories
    icmMemoryP memory1 = icmNewMemory("mem1", ICM_PRIV_RWX, 0xffffffff);
   
    // connect memory to main bus
    icmConnectMemoryToBus(mbus, "mp1", memory1, 0x00000000);
   
    // show the bus connections

    icmPrintf("\nmbus1 CONNECTIONS\n");
    icmPrintBusConnections(mbus);
    icmPrintf("\nibus1 CONNECTIONS\n");
    icmPrintBusConnections(ibus1);
    icmPrintf("\nibus2 CONNECTIONS\n");
    icmPrintBusConnections(ibus2);
    icmPrintf("\ndbus1 CONNECTIONS\n");
    icmPrintBusConnections(dbus1);
    icmPrintf("\ndbus2 CONNECTIONS\n");
    icmPrintBusConnections(dbus2);
    icmPrintf("\ncachebus CONNECTIONS\n");
    icmPrintBusConnections(buscache);
    icmPrintf("\n");
   
   
    if(argc == 4 ){
            icmProcessorP sub = icmFindProcessorByName(argv[3]);
            icmDebugThisProcessor(sub);
    }
   
   
    // load the processor object file - because all memory is shared, both
    // processors will execute the same application code
    icmLoadProcessorMemory(processor0, appName, False, False, True);
    icmLoadProcessorMemory(processor1, appName, False, False, True);

    // run simulation
    icmSimulatePlatform();

    // report the total number of instructions executed
    icmPrintf(
        "processor0 has executed " FMT_64u " instructions\n",
        icmGetProcessorICount(processor0)
    );
    icmPrintf(
        "processor1 has executed " FMT_64u " instructions\n",
        icmGetProcessorICount(processor1)
    );

    // free simulation data structures
    icmTerminate();

    return 0;
}
Back to top
View user's profile Send private message
DuncGrah
OVP Technologist
OVP Technologist


Joined: 27 Feb 2008
Posts: 1646
Location: United Kingdom

PostPosted: Tue Sep 20, 2011 7:56 am    Post subject: Reply with quote

Added a bit of formatting to the postings to make easier to read.

Your problem is the choice of using WriteBack caches and the small example application. If you add some debug into the cache.h (common code used for all MMC cache models) you will see that the cache line containing your variable is never flushed!

If you change to using a WriteThrough cache the simulation runs as you would expect.

Because of the short run length of the application this does lead to a scheduling problem that one processor finishes before the other has started ...


Last edited by DuncGrah on Tue Sep 20, 2011 8:00 am; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website
AntonioPrioletti



Joined: 02 May 2011
Posts: 20

PostPosted: Tue Sep 20, 2011 7:59 am    Post subject: Reply with quote

If I use the following code, which is in the multiprocessor Example:
Code:

#include <stdio>
#include <stdlib>
#include <string>
#include "simulatorIntercepts.h"

#define NUM_VALUES 35

static volatile int flag;
static volatile int fibres;

int fib(int i) {
    return (i>1) ? fib(i-1) + fib(i-2) : i;
}

int munge(int mungeIn) {

    int result = 0;
    int i;

    for(i=0; i<mungeIn; i++) {
        result += i;
    }
    return result;
}

int writer(int id) {

    int i;

    for(i=0; i<NUM_VALUES; i++) {
        int result = fib(i);
        while(flag) {
                    printf("cpu0, flag 1 = %d, indirizzo %p\n", flag, &flag);
                    }
        printf("CPU %d: fib(%d) = %d\n", id, i, result);
        fibres = result;
        flag = (i==(NUM_VALUES-1)) ? 2 : 1;
    }

    while(flag) {}

    return 1;
}

int reader(int id) {

    int done = 0;

    do {
        int mungeIn;
        while(!flag) {
                     printf("cpu1, flag2 = %d, indirizzo %p\n", flag, &flag);
                     }
        mungeIn = fibres;
        done    = (flag==2);
        printf("CPU %d: munge(%d) = %d\n", id, mungeIn, munge(mungeIn));
        flag    = 0;
    } while(!done);

    return 1;
}

int main(int argc, char **argv) {

    int id = impProcessorId();

    printf("CPU %d starting...\n", id);

    switch(id) {

        case 0:
            writer(id);
            break;

        case 1:
            reader(id);
            break;

        case 2:
            break;
    }

    return 1;
}


I have the following output:

Code:

CPU1 starting
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
CPU0 starting
CPU0: fib(0) = 0
cpu0, flag1 = 1, indirizzo 0xe460
cpu0, flag1 = 1, indirizzo 0xe460
cpu0, flag1 = 1, indirizzo 0xe460
cpu0, flag1 = 1, indirizzo 0xe460
cpu0, flag1 = 1, indirizzo 0xe460
cpu0, flag1 = 1, indirizzo 0xe460
cpu0, flag1 = 1, indirizzo 0xe460
cpu0, flag1 = 1, indirizzo 0xe460
cpu0, flag1 = 1, indirizzo 0xe460
cpu0, flag1 = 1, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460
cpu1, flag2 = 0, indirizzo 0xe460


where is the problem? Because in this case both the processor are blocked in the while cycle. It seems that processor0 dont't see the variable flag that is modified by processor 1.
Back to top
View user's profile Send private message
AntonioPrioletti



Joined: 02 May 2011
Posts: 20

PostPosted: Tue Sep 20, 2011 8:06 am    Post subject: Reply with quote

ok, if I use the application that I have posted; How do I use a WriteThrough cache?
Back to top
View user's profile Send private message
DuncGrah
OVP Technologist
OVP Technologist


Joined: 27 Feb 2008
Posts: 1646
Location: United Kingdom

PostPosted: Tue Sep 20, 2011 8:08 am    Post subject: Reply with quote

I see your problem ... You have two processors running the same program and both using the same memory for stack. They, therefore, corrupt each others stack!!

You need to have separate memories for the stacks of the processors.
Back to top
View user's profile Send private message Visit poster's website
AntonioPrioletti



Joined: 02 May 2011
Posts: 20

PostPosted: Tue Sep 20, 2011 8:13 am    Post subject: Reply with quote

But If I want to have a second level cache shared, How I can have a separate memory? If I load the application in only one processor, then the second processor don't start.
Back to top
View user's profile Send private message
AntonioPrioletti



Joined: 02 May 2011
Posts: 20

PostPosted: Tue Sep 20, 2011 8:57 am    Post subject: Reply with quote

In this case I have the same problem:

Code:

#include <stdio>
#include <stdlib>

#include "icm/icmCpuManager.h"

#define SIM_ATTRS (ICM_ATTR_RELAXED_SCHED)

//
// Main simulation routine
//
int main(int argc, char ** argv) {

    int portNum;
    const char *appName;
   
    // check for the application program name argument
    if(argc<2) {
        icmPrintf("usage: %s <application> [<port> <processor>]\n", argv[0]);
        return -1;
    }
    if(argc<3){
        // initialize ICM - require Imperas intercepts because the
        // application uses impProcessorId() to get processor id
        icmInit(ICM_VERBOSE|ICM_ENABLE_IMPERAS_INTERCEPTS, 0, 0);
    }
    else {
         if(argc<4){
              icmPrintf("usage: %s <application> <port> <processor> \n", argv[0]);
              return -1;     
         }
         else{
                  sscanf(argv[2], "%d", &portNum);
                  // initialize ICM - require Imperas intercepts because the
                  // application uses impProcessorId() to get processor id
                  icmInit(ICM_VERBOSE|ICM_ENABLE_IMPERAS_INTERCEPTS, "rsp", portNum);
         }
    }
   
    appName = argv[1];
   
    // select library components
   const char *vlnvRoot = NULL; //When NULL use default library
    const char *model       = icmGetVlnvString(vlnvRoot, "ovpworld.org", "processor", "or1k", "1.0", "model");
    const char *semihosting = icmGetVlnvString(vlnvRoot, "ovpworld.org", "semihosting", "or1kNewlib", "1.0", "model");
    const char *mmc_model = icmGetVlnvString( vlnvRoot, "ovpworld.org", "mmc", "wb_1way_32byteline_2048tags", "1.0","model");

    // create processor cpu0
    icmProcessorP processor0 = icmNewProcessor(
        "cpu0",             // CPU name
        "or1k",             // CPU type
        0,                  // CPU cpuId
        0,                  // CPU model flags
        32,                 // address bits
        model,              // model file
        "modelAttrs",       // morpher attributes
        SIM_ATTRS,          // simulation attributes
        0,                  // user-defined attributes
        semihosting,        // semi-hosting file
        "modelAttrs"        // semi-hosting attributes
    );
   
    //create processor cpu1
    icmProcessorP processor1 = icmNewProcessor(
        "cpu1",             // CPU name
        "or1k",             // CPU type
        1,                  // CPU cpuId
        0,                  // CPU model flags
        32,                 // address bits
        model,              // model file
        "modelAttrs",       // morpher attributes
        SIM_ATTRS,          // simulation attributes
        0,                  // user-defined attributes
        semihosting,        // semi-hosting file
        "modelAttrs"        // semi-hosting attributes
    );
   
   
    // create full MMCs
    icmMmcP mmci1 = icmNewMMC("mmci1", mmc_model, "modelAttrs", 0, 0, False);
    icmMmcP mmcd1 = icmNewMMC("mmcd1", mmc_model, "modelAttrs", 0, 0, False);
   
    icmMmcP mmci2 = icmNewMMC("mmci2", mmc_model, "modelAttrs", 0, 0, False);
    icmMmcP mmcd2 = icmNewMMC("mmcd2", mmc_model, "modelAttrs", 0, 0, False);
   
    icmMemoryP local1 = icmNewMemory("local1", ICM_PRIV_RWX, 0x0fffffff);
    icmMemoryP local2 = icmNewMemory("local2", ICM_PRIV_RWX, 0x0fffffff);
   
    // create memories
    icmMemoryP memory1 = icmNewMemory("mem1", ICM_PRIV_RWX, 0xefffffff);

   
    // create the processor instruction bus and data bus
    icmBusP ibus1 = icmNewBus("ibus1", 32);
    icmBusP dbus1 = icmNewBus("dbus1", 32);

    icmBusP ibus2 = icmNewBus("ibus2", 32);
    icmBusP dbus2 = icmNewBus("dbus2", 32);
   
     icmBusP bus1 = icmNewBus("bus1", 32);
    icmBusP bus2 = icmNewBus("bus2", 32);

   
    // main bus
    icmBusP mbus = icmNewBus("mbus", 32);
   
    // connect processor ports to their buses
    icmConnectProcessorBusses(processor0, ibus1, dbus1);
    icmConnectProcessorBusses(processor1, ibus2, dbus2);
   
    // connect MMCs to buses
    icmConnectMMCBus(mmci1, ibus1, "sp1", False);
    icmConnectMMCBus(mmcd1, dbus1, "sp1", False);
   
    icmConnectMMCBus(mmci2, ibus2, "sp1", False);
    icmConnectMMCBus(mmcd2, dbus2, "sp1", False);
   
    // connect master ports of MMC layer 1 to buscache
    icmConnectMMCBus(mmci1, bus1, "mp1", True);
    icmConnectMMCBus(mmcd1, bus1, "mp1", True);
   
    icmConnectMMCBus(mmci2, bus2, "mp1", True);
    icmConnectMMCBus(mmcd2, bus2, "mp1", True);
   
    icmConnectMemoryToBus(bus1, "mp1", memory1, 0x00000000);
    icmConnectMemoryToBus(bus2, "mp2", memory1, 0x00000000);
    icmConnectMemoryToBus(bus1, "mp1", local1, 0xf0000000);
    icmConnectMemoryToBus(bus2, "mp1", local2, 0xf0000000);
   
   
   
    // show the bus connections

    icmPrintf("\nmbus1 CONNECTIONS\n");
    icmPrintBusConnections(mbus);
    icmPrintf("\nibus1 CONNECTIONS\n");
    icmPrintBusConnections(ibus1);
    icmPrintf("\nibus2 CONNECTIONS\n");
    icmPrintBusConnections(ibus2);
    icmPrintf("\ndbus1 CONNECTIONS\n");
    icmPrintBusConnections(dbus1);
    icmPrintf("\ndbus2 CONNECTIONS\n");
    icmPrintBusConnections(dbus2);
    icmPrintf("\n");
   
   
    if(argc == 4 ){
            icmProcessorP sub = icmFindProcessorByName(argv[3]);
            icmDebugThisProcessor(sub);
    }
   
   
    // load the processor object file - because all memory is shared, both
    // processors will execute the same application code
    icmLoadProcessorMemory(processor0, appName, False, False, True);
    //icmLoadProcessorMemory(processor1, appName, False, False, True);

    // run simulation
    icmSimulatePlatform();

    // report the total number of instructions executed
    icmPrintf(
        "processor0 has executed " FMT_64u " instructions\n",
        icmGetProcessorICount(processor0)
    );
    icmPrintf(
        "processor1 has executed " FMT_64u " instructions\n",
        icmGetProcessorICount(processor1)
    );

    // free simulation data structures
    icmTerminate();

    return 0;
}
Back to top
View user's profile Send private message
DuncGrah
OVP Technologist
OVP Technologist


Joined: 27 Feb 2008
Posts: 1646
Location: United Kingdom

PostPosted: Tue Sep 20, 2011 11:34 pm    Post subject: Reply with quote

You must either:
1. Have separate memory for the stacks of the two processors, or
2. Run different programs on the two processors that are linked to use different memory locations.
Back to top
View user's profile Send private message Visit poster's website
AntonioPrioletti



Joined: 02 May 2011
Posts: 20

PostPosted: Tue Sep 20, 2011 11:45 pm    Post subject: Reply with quote

DuncGrah wrote:
You must either:
1. Have separate memory for the stacks of the two processors, or
2. Run different programs on the two processors that are linked to use different memory locations.


I understand this, but how I can have separate memory for the stacks of the two processor having a shared cache?
Back to top
View user's profile Send private message
AntonioPrioletti



Joined: 02 May 2011
Posts: 20

PostPosted: Wed Sep 21, 2011 5:15 am    Post subject: Reply with quote

Even if I use the following structure of platform, and use the example application in the folder Example/Platform/multiprocessor, that is Fibonacci, tha application stopped at first iteration.

Code:

int main(int argc, char ** argv) {

    // check for the application program name argument
    int portNum;
    const char *appName;
   
    // check for the application program name argument
    if(argc<2) {
        icmPrintf("usage: %s <application> [<port> <processor>]\n", argv[0]);
        return -1;
    }
    if(argc<3){
        // initialize ICM - require Imperas intercepts because the
        // application uses impProcessorId() to get processor id
        icmInit(ICM_VERBOSE|ICM_ENABLE_IMPERAS_INTERCEPTS, 0, 0);
    }
    else {
         if(argc<4){
              icmPrintf("usage: %s <application> <port> <processor> \n", argv[0]);
              return -1;     
         }
         else{
                  sscanf(argv[2], "%d", &portNum);
                  // initialize ICM - require Imperas intercepts because the
                  // application uses impProcessorId() to get processor id
                  icmInit(ICM_VERBOSE|ICM_ENABLE_IMPERAS_INTERCEPTS, "rsp", portNum);
         }
    }
   
    appName = argv[1];

    // select library components
   const char *vlnvRoot = NULL; //When NULL use default library
    const char *model       = icmGetVlnvString(vlnvRoot, "ovpworld.org", "processor", "or1k", "1.0", "model");
    const char *semihosting = icmGetVlnvString(vlnvRoot, "ovpworld.org", "semihosting", "or1kNewlib", "1.0", "model");

    // create processor cpu0
    icmProcessorP processor0 = icmNewProcessor(
        "cpu0",             // CPU name
        "or1k",             // CPU type
        0,                  // CPU cpuId
        0,                  // CPU model flags
        32,                 // address bits
        model,              // model file
        "modelAttrs",       // morpher attributes
        SIM_ATTRS,          // simulation attributes
        0,                  // user-defined attributes
        semihosting,        // semi-hosting file
        "modelAttrs"        // semi-hosting attributes
    );

    // create processor cpu1
    icmProcessorP processor1 = icmNewProcessor(
        "cpu1",             // CPU name
        "or1k",             // CPU type
        1,                  // CPU cpuId
        0,                  // CPU model flags
        32,                 // address bits
        model,              // model file
        "modelAttrs",       // morpher attributes
        SIM_ATTRS,          // simulation attributes
        0,                  // user-defined attributes
        semihosting,        // semi-hosting file
        "modelAttrs"        // semi-hosting attributes
    );
   
    const char *mmc_model = icmGetVlnvString( vlnvRoot, "ovpworld.org", "mmc", "wb_1way_32byteline_2048tags", "1.0","model");
   
    icmMmcP mmci1 = icmNewMMC("mmci1", mmc_model, "modelAttrs", 0, 0, False);
   
    icmMmcP mmci2= icmNewMMC("mmci2", mmc_model, "modelAttrs", 0, 0, False);

    // create the processor busses
    icmBusP bus1 = icmNewBus("bus1", 32);
    icmBusP bus2 = icmNewBus("bus2", 32);
   
    icmBusP ibus1 = icmNewBus("ibus1", 32);

    icmBusP ibus2 = icmNewBus("ibus2", 32);

    // connect the processor busses
    icmConnectProcessorBusses(processor0, ibus1, ibus1);
    icmConnectProcessorBusses(processor1, ibus2, ibus2);
   
    // connect MMCs to buses
    icmConnectMMCBus(mmci1, ibus1, "sp1", False);
    icmConnectMMCBus(mmci2, ibus2, "sp1", False);
   
    // connect master ports of MMC layer 1 to buscache
    icmConnectMMCBus(mmci1, bus1, "mp1", True);
   
    icmConnectMMCBus(mmci2, bus2, "mp1", True);

    // create memories
    icmMemoryP local1 = icmNewMemory("local1", ICM_PRIV_RWX, 0x0fffffff);
    icmMemoryP local2 = icmNewMemory("local2", ICM_PRIV_RWX, 0x0fffffff);
    icmMemoryP shared = icmNewMemory("shared", ICM_PRIV_RWX, 0xefffffff);

    // connect memories
    icmConnectMemoryToBus(bus1, "mp1", shared, 0x00000000);
    icmConnectMemoryToBus(bus2, "mp2", shared, 0x00000000);
    icmConnectMemoryToBus(bus1, "mp1", local1, 0xf0000000);
    icmConnectMemoryToBus(bus2, "mp1", local2, 0xf0000000);

    // show the bus connections
    icmPrintf("\nbus1 CONNECTIONS\n");
    icmPrintBusConnections(bus1);
    icmPrintf("\nbus2 CONNECTIONS\n");
    icmPrintBusConnections(bus2);
    icmPrintf("\n");
 
    // load the processor object file - because all memory is shared, both
    // processors will execute the same application code
    icmLoadProcessorMemory(processor0, argv[1], False, False, True);
   
    if(argc == 4 ){
            icmProcessorP sub = icmFindProcessorByName(argv[3]);
            icmDebugThisProcessor(sub);
    }

    // run simulation
    icmSimulatePlatform();

    // report the total number of instructions executed
    icmPrintf(
        "processor0 has executed " FMT_64u " instructions\n",
        icmGetProcessorICount(processor0)
    );
    icmPrintf(
        "processor1 has executed " FMT_64u " instructions\n",
        icmGetProcessorICount(processor1)
    );

    // free simulation data structures
    icmTerminate();

    return 0;
}

How i can run this application with platform that have a cache??????
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Open Virtual Platforms Forum Index -> Ask a Question All times are GMT - 8 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Information regarding OVP © 2008-2022 Imperas Software