Vengineerの妄想(準備期間)

人生は短いけど、長いです。人生を楽しみましょう!

OVP : Dual Cortex-A9デモ、その1


今回は、Cortex-A9の2コアのデモOVPsim_multicore2_arm_Cortex-A9UP ディレクトリには、
次のようなファイルがあります。
OVPsim_single_arm_Cortex-A9UP ディレクトリと基本的には同じです。
    各種バッチファイル(RUN_xxx.bat)
  ARM Cortex-A9の実行プログラム(.elf)とソースコード(.c)

    シミュレータのソースコード&実行プログラム
    OVPsim_multicore2_arm_Cortex-A9UP.c
      OVPsim_multicore2_arm_Cortex-A9UP.Windows32.exe

バッチファイルではチェック後、
デモを実行するために必要なファイルのOVPsim_multicore2_arm_Cortex-A9UP.Windows32.exeの引数に、
対応するARM Cortex-A9の実行プログラムを引数にしているだけです。
    OVPsim_multicore2_arm_Cortex-A9UP.Windows32.exe multicore2.ARM_CORTEX_A9.elf V Cortex-A9UP
2コアなのでプロセッサのインスタンスを2つ生成します。
processor0とprocessor1の違いは、CPU name(cpu0/cpu1)とCPU cpuId(0/1)です。
プロセッサの区別をしているだけです。
    // create pointers to processors
    icmProcessorP processor0, processor1;

    // Create the processor instances
    processor0 = icmNewProcessor(
        "cpu0",             // CPU name
        "arm",              // CPU type
        0,                  // CPU cpuId
        0,                  // CPU model flags
        32,                 // address bits
        armModel,           // model file
        "modelAttrs",       // morpher attributes
        SIM_ATTRS,          // attributes
        icmAttr,            // user-defined attributes
        armSemihost,        // semi-hosting file
        "modelAttrs"        // semi-hosting attributes
    );

    processor1 = icmNewProcessor(
        "cpu1",             // CPU name
        "arm",              // CPU type
        1,                  // CPU cpuId
        0,                  // CPU model flags
        32,                 // address bits
        armModel,           // model file
        "modelAttrs",       // morpher attributes
        SIM_ATTRS,          // attributes
        icmAttr,            // user-defined attributes
        armSemihost,        // semi-hosting file
        "modelAttrs"        // semi-hosting attributes
    );
マルチコアでは、シングルコアのときには無かったバスとメモリが必要になります。
各プロセッサの毎にバスのインスタンスを生成し、プロセッサと接続します。
icmConnectProcessorBusses関数の第2引数は命令用、第3引数はデータ用です。
    // create the processor busses
    icmBusP bus1 = icmNewBus("bus1", 32);
    icmBusP bus2 = icmNewBus("bus2", 32);

    // connect the processors onto the busses
    icmConnectProcessorBusses(processor0, bus1, bus1);
    icmConnectProcessorBusses(processor1, bus2, bus2);
メモリのインスタンスは、バスに接続します。
ここでは、sharedが共有メモリで、local0がcpu1用ローカルメモリ、local2がcpu1用ローカルメモリです。
    // create memories
    icmMemoryP local1 = icmNewMemory("local1", ICM_PRIV_RWX, 0x000fffff);
    icmMemoryP local2 = icmNewMemory("local2", ICM_PRIV_RWX, 0x000fffff);
    icmMemoryP shared = icmNewMemory("shared", ICM_PRIV_RWX, 0x000fffff);

    // connect the memories onto the busses
    icmConnectMemoryToBus(bus1, "mp1", shared, 0x00000000);
    icmConnectMemoryToBus(bus2, "mp2", shared, 0x00000000);
    icmConnectMemoryToBus(bus1, "mp1", local1, 0x00100000);
    icmConnectMemoryToBus(bus2, "mp1", local2, 0x00100000);
シングルコアと同様にプログラムをCPUのメモリにロードしますが、
cpu0とcpu1のプログラム用メモリは共有メモリになっていますので、
processor0に対してだけ、icmLoadProcessorMemory関数を実行しています。
    // load the application executable file into processor memory space
    // because all memory is shared, both processors will
    // execute the same application code
    if(!icmLoadProcessorMemory(processor0, application, False, False, False)) {
        return -1;
    }
これ以降は、シングルコアと同じです。

検証、Verification、OVP