13

私は SystemC のプロジェクトに取り組んでおり、単体テストを組み込みたいと考えています。SystemC で既存の単体テスト フレームワークを使用することは可能ですか?

SystemC モジュールはシミュレーション カーネルでのみ実行されるようで、モジュール自体で単体テストを使用したいので、これを尋ねます。

4

4 に答える 4

2

fork システム コールを使用して、2 つの SystemC テストを実行できました。doulos.comのチュートリアルの例とGoogle Testフレームワークを使用しました。テストを 2 回実行できましたが、SystemC シミュレーターによって、sc_stop を呼び出した後にテストを開始することに関するエラーが出力されます。ただし、エラーに関係なく、シミュレーターは 2 回目は問題なく動作します。

 SystemC 2.2.0 --- Feb 24 2011 15:01:50
        Copyright (c) 1996-2006 by all Contributors
                    ALL RIGHTS RESERVED
Running main() from gtest_main.cc
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from systemc_test
[ RUN      ] systemc_test.test1
      Time A B F
       0 s 0 0 0
       0 s 0 0 1
     10 ns 0 1 1
     20 ns 1 0 1
     30 ns 1 1 0
SystemC: simulation stopped by user.
[       OK ] systemc_test.test1 (1 ms)
[ RUN      ] systemc_test.test2

Error: (E546) sc_start called after sc_stop has been called
In file: ../../../../src/sysc/kernel/sc_simcontext.cpp:1315
[       OK ] systemc_test.test2 (2 ms)
[----------] 2 tests from systemc_test (3 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (3 ms total)
[  PASSED  ] 2 tests.
[       OK ] systemc_test.test1 (3 ms)
[ RUN      ] systemc_test.test2
      Time A B F
       0 s 0 0 0
       0 s 0 0 1
     10 ns 0 1 1
     20 ns 1 0 1
     30 ns 1 1 0
SystemC: simulation stopped by user.
[       OK ] systemc_test.test2 (1 ms)
[----------] 2 tests from systemc_test (4 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (4 ms total)
[  PASSED  ] 2 tests.
[       OK ] systemc_test.test2 (1 ms)
[----------] 2 tests from systemc_test (4 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (4 ms total)
[  PASSED  ] 2 tests.

更新:要求されたコード サンプル:

// main_1.cxx

#include "systemc.h"
#include "stim.hxx"
#include "exor2.hxx"
#include "mon.hxx"


//#include <pthread.h>
#include <sys/types.h>
#include <sys/wait.h>


void run_1()
{
  sc_signal<bool> ASig, BSig, FSig;
  sc_clock TestClk("TestClock", 10, SC_NS,0.5);

  stim* Stim1 = new stim("Stimulus1_1");
  Stim1->A(ASig);
  Stim1->B(BSig);
  Stim1->Clk(TestClk);

  exor2* DUT = new exor2("exor2_1");
  DUT->A(ASig);
  DUT->B(BSig);
  DUT->F(FSig);

  mon* Monitor1 = new mon("Monitor_1");
  Monitor1->A(ASig);
  Monitor1->B(BSig);
  Monitor1->F(FSig);
  Monitor1->Clk(TestClk);


  Stim1->run();
  delete Stim1;
  delete DUT;
  delete Monitor1;
}

bool sc_main_1()
{
        //int rc;
        //pthread_t thread;
        //if( (rc = pthread_create( &thread, NULL, &run_1, NULL)) )
        //{
        //      printf("Thread creation failed: %d\n", rc);
        //};

        //pthread_join(thread, NULL);

        int pid = fork();
        if(pid == 0)
        {
                run_1();
        };
        waitpid(pid, NULL, 0);
        return true;
};


// main_2.cxx    

#include "systemc.h"
#include "stim.hxx"
#include "exor2.hxx"
#include "mon.hxx"


//#include <pthread.h>
#include <sys/types.h>
#include <sys/wait.h>


void run_2()
{
  sc_signal<bool> ASig, BSig, FSig;
  sc_clock TestClk("TestClock", 10, SC_NS,0.5);

  stim* Stim1 = new stim("Stimulus1_2");
  Stim1->A(ASig);
  Stim1->B(BSig);
  Stim1->Clk(TestClk);

  exor2* DUT = new exor2("exor2_2");
  DUT->A(ASig);
  DUT->B(BSig);
  DUT->F(FSig);

  mon* Monitor1 = new mon("Monitor_2");
  Monitor1->A(ASig);
  Monitor1->B(BSig);
  Monitor1->F(FSig);
  Monitor1->Clk(TestClk);


  Stim1->run();
  delete Stim1;
  delete DUT;
  delete Monitor1;
}

bool sc_main_2()
{
        //int rc;
        //pthread_t thread;
        //if( (rc = pthread_create( &thread, NULL, &run_1, NULL)) )
        //{
        //      printf("Thread creation failed: %d\n", rc);
        //};

        //pthread_join(thread, NULL);

        int pid = fork();
        if(pid == 0)
        {
                run_2();
        };
        waitpid(pid, NULL, 0);
        return true;
};


// main.cxx

#include "systemc.h"

#include "gtest/gtest.h"


extern bool sc_main_1();
extern bool sc_main_2();

TEST(systemc_test, test1)
{
        EXPECT_TRUE(sc_main_1());
};

TEST(systemc_test, test2)
{
        EXPECT_TRUE(sc_main_2());
};

int sc_main(int argc, char* argv[])
{
  std::cout << "Running main() from gtest_main.cc\n";
  testing::InitGoogleTest(&argc, argv);
  RUN_ALL_TESTS();
  return 0;

}

// stim.hxx

#ifndef stim_hxx
#define stim_hxx

#include "systemc.h"
SC_MODULE(stim)
{
  sc_out<bool> A, B;
  sc_in<bool> Clk;

  void StimGen()
  {
    A.write(false);
    B.write(false);
    wait();
    A.write(false);
    B.write(true);
    wait();
    A.write(true);
    B.write(false);
    wait();
    A.write(true);
    B.write(true);
        wait();
    sc_stop();
  }

  SC_CTOR(stim)
  {
    SC_THREAD(StimGen);
    sensitive << Clk.pos();
  }

  bool run()
  {
                sc_start();  // run forever
                return true;
  };

};

#endif


// exor2.hxx

#ifndef exor_hxx
#define exor_hxx

#include "systemc.h"
#include "nand2.hxx"
SC_MODULE(exor2)
{
  sc_in<bool> A, B;
  sc_out<bool> F;

  nand2 n1, n2, n3, n4;

  sc_signal<bool> S1, S2, S3;

  SC_CTOR(exor2) : n1("N1"), n2("N2"), n3("N3"), n4("N4")
  {
    n1.A(A);
    n1.B(B);
    n1.F(S1);

    n2.A(A);
    n2.B(S1);
    n2.F(S2);

    n3.A(S1);
    n3.B(B);
    n3.F(S3);

    n4.A(S2);
    n4.B(S3);
    n4.F(F);
  }
};

#endif


// mon.hxx

#ifndef mon_hxx
#define mon_hxx

#include "systemc.h"
#include <iomanip>
#include <iostream>


using namespace std;

SC_MODULE(mon)
{
    sc_in<bool> A,B,F;
    sc_in<bool> Clk;

  void monitor()
  {
    cout << setw(10) << "Time";
    cout << setw(2) << "A" ;
    cout << setw(2) << "B";
    cout << setw(2) << "F" << endl;
    while (true)
    {
      cout << setw(10) << sc_time_stamp();
      cout << setw(2) << A.read();
      cout << setw(2) << B.read();
      cout << setw(2) << F.read() << endl;
      wait();    // wait for 1 clock cycle
    }
  }

  SC_CTOR(mon)
  {
    SC_THREAD(monitor);
    sensitive << Clk.pos();
  }
};

#endif
于 2011-02-28T17:36:50.087 に答える
2

この質問には、CMkae と CTest ( http://cmake.org/ ) を使用する 2 つ目の解決策があります。私が使用したセットアップでは、テストごとにバイナリが作成されます。使用したCMakeLists.txtファイルは次のとおりです。

project(sc_unit_test)
include_directories(/home/stephan/local/include)
find_library(systemc systemc /home/stephan/local/lib-linux64)
link_directories(/home/stephan/local/lib-linux64)

add_executable(test_1 test_1.cxx)
target_link_libraries(test_1 systemc)

add_executable(test_2 test_2.cxx)
target_link_libraries(test_2 systemc)

enable_testing()
add_test(test_1 test_1)
add_test(test_2 test_2)

test_*.cxxファイルにはsc_mainテストを実行するメソッドがあり、戻り値はテストが成功したか失敗したかを示します。テストを実行するには、次のようにします。

$ cmake .
$ make
$ ctest
Test project
  1/  2 Testing test_1                           Passed
  2/  2 Testing test_2                           Passed

100% tests passed, 0 tests failed out of 2

シミュレーターを実行したくない場合はsc_start、特定のモジュールで必要な特定のテストを実行した後、呼び出しをスキップしてアプリケーションを終了するだけです。

于 2012-05-29T21:23:50.403 に答える