Using existing unit test frameworks with SystemC

后端 未结 4 752
野的像风
野的像风 2021-02-05 17:28

I am working on a project in SystemC and want to incorporate unit testing. Is it possible to use existing unit test frameworks with SystemC?

I ask this because it seems

4条回答
  •  挽巷
    挽巷 (楼主)
    2021-02-05 17:56

    I was able to run 2 SystemC tests using the fork system call. I used the tutorial example on doulos.com and the Google Test framework. I was able to run the test twice, but I get an error printed out by the SystemC simulator about starting the test after calling sc_stop. However, regardless of the error, the simulator runs fine the second time around.

     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.
    

    UPDATE: Code sample as requested:

    // main_1.cxx
    
    #include "systemc.h"
    #include "stim.hxx"
    #include "exor2.hxx"
    #include "mon.hxx"
    
    
    //#include 
    #include 
    #include 
    
    
    void run_1()
    {
      sc_signal 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 
    #include 
    #include 
    
    
    void run_2()
    {
      sc_signal 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 A, B;
      sc_in 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 A, B;
      sc_out F;
    
      nand2 n1, n2, n3, n4;
    
      sc_signal 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 
    #include 
    
    
    using namespace std;
    
    SC_MODULE(mon)
    {
        sc_in A,B,F;
        sc_in 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
    

提交回复
热议问题