OVP Forums - A community of assistance, help, questions, and answers.
|
View previous topic :: View next topic |
Author |
Message |
AntonioPrioletti
Joined: 02 May 2011 Posts: 20
|
Posted: Fri Sep 16, 2011 7:13 am Post subject: Cache |
|
|
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 |
|
 |
AntonioPrioletti
Joined: 02 May 2011 Posts: 20
|
Posted: Fri Sep 16, 2011 1:32 pm Post subject: Re: Cache |
|
|
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 |
|
 |
DuncGrah OVP Technologist

Joined: 27 Feb 2008 Posts: 1654 Location: United Kingdom
|
Posted: Mon Sep 19, 2011 4:22 am Post subject: |
|
|
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 |
|
 |
AntonioPrioletti
Joined: 02 May 2011 Posts: 20
|
Posted: Mon Sep 19, 2011 10:43 am Post subject: |
|
|
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 |
|
 |
DuncGrah OVP Technologist

Joined: 27 Feb 2008 Posts: 1654 Location: United Kingdom
|
Posted: Tue Sep 20, 2011 7:56 am Post subject: |
|
|
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 |
|
 |
AntonioPrioletti
Joined: 02 May 2011 Posts: 20
|
Posted: Tue Sep 20, 2011 7:59 am Post subject: |
|
|
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 |
|
 |
AntonioPrioletti
Joined: 02 May 2011 Posts: 20
|
Posted: Tue Sep 20, 2011 8:06 am Post subject: |
|
|
ok, if I use the application that I have posted; How do I use a WriteThrough cache? |
|
Back to top |
|
 |
DuncGrah OVP Technologist

Joined: 27 Feb 2008 Posts: 1654 Location: United Kingdom
|
Posted: Tue Sep 20, 2011 8:08 am Post subject: |
|
|
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 |
|
 |
AntonioPrioletti
Joined: 02 May 2011 Posts: 20
|
Posted: Tue Sep 20, 2011 8:13 am Post subject: |
|
|
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 |
|
 |
AntonioPrioletti
Joined: 02 May 2011 Posts: 20
|
Posted: Tue Sep 20, 2011 8:57 am Post subject: |
|
|
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 |
|
 |
DuncGrah OVP Technologist

Joined: 27 Feb 2008 Posts: 1654 Location: United Kingdom
|
Posted: Tue Sep 20, 2011 11:34 pm Post subject: |
|
|
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 |
|
 |
AntonioPrioletti
Joined: 02 May 2011 Posts: 20
|
Posted: Tue Sep 20, 2011 11:45 pm Post subject: |
|
|
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 |
|
 |
AntonioPrioletti
Joined: 02 May 2011 Posts: 20
|
Posted: Wed Sep 21, 2011 5:15 am Post subject: |
|
|
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 |
|
 |
|
|
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
|