在SystemC中的测试平台模块中管理信号

时间:2016-06-10 17:54:17

标签: c++ segmentation-fault systemc test-bench

我正在尝试在SystemC中模拟一个带有CABA(Cycle Accurate / Bit Accurate)模型的模块,它增加了两个数字。它有以下信号:

模块addition_CABA

  • a:添加的输入数字。
  • b:添加的输入数字。
  • clk:时钟输入。
  • valid:当输入ab可用时,输入信号变为1。
  • result:包含a + b结果的输出信号。
  • ready:当result准备就绪时,输出信号变为1。

为了测试此模块的结果是否正确,我创建了一个testbench模块,其中包含以下信号:

模块testbench

  • result_tb:从addition_CABA模块接收结果信号的输入信号。
  • ready_tb:从addition_CABA模块接收就绪信号的输入信号。
  • clk_tb:时钟输入信号。两个模块都是一样的。
  • rst_tb:重置输入信号。两个模块都是一样的。
  • a_tb:输出信号,将数字a发送到addition_CABA模块。
  • b_tb:输出信号,将数字b发送到addition_CABA模块。
  • valid_tb:将有效信号发送到addition_CABA模块的输出信号。

我正在做的测试如下:

  • 在模块testbench中生成一对随机数,以便为ab提供值。
  • 模块在一些时钟周期后计算结果。
  • 测试平台直接执行添加操作,并将其与模块生成的操作进行比较。
  • 这些动作在一个重复五次的循环中。

我遇到的问题是,当我运行模拟时testbench会给出正确的结果,而addition_CABA会显示结果,但稍后会显示一些时钟周期,因此比较是在两个不同的数字之间。此外,当程序结束时,我有一条Segmentation fault (core dumped)消息。我想弄清楚的是如何指示testbench等待结果准备好(信号ready_tb),这样它就可以用正确的数字进行比较。我在开始测试之前尝试了while(!ready_tb.read()) wait();条件,但是当这样做时,程序结束,模拟永远不会开始。

main.cpp文件中,我只是在模块之间建立连接,生成时钟并将rst信号设置为0。以下是我的代码:

addition_CABA.h

#include <systemc.h>
//Module which adds two numbers
SC_MODULE(addition_CABA){
    sc_in< sc_uint<8> > a;
    sc_in< sc_uint<8> > b;
    sc_in<bool> clk;
    sc_in<bool> valid;
    sc_in<bool> rst;
    sc_out<bool> ready;
    sc_out< sc_uint<8> > result;

    int addcaba(int a, int b){
        int c;
        c = a+b;
        wait(3);
        return c;
    }

    void loop();

    SC_CTOR(addition_CABA){
        SC_CTHREAD(loop, clk.pos());
        async_reset_signal_is(rst, true);
    }

};

addition_CABA.cpp

void addition_CABA::loop(){

    ready.write(0);
    result.write(0);

    if(rst){
        ready.write(0);
        result.write(0);
    }   

    else{

        while(1){
            while (!valid.read()) wait();

            result.write(addcaba(a.read(),b.read()));
            ready.write(1);

            wait();
            ready.write(0);
        }

    }
}

testbench.h

#include <systemc.h>

SC_MODULE(testbench){

    sc_in< sc_uint<8> > result_tb;
    sc_in<bool> ready_tb;
    sc_in<bool> clk_tb;
    sc_in<bool> rst_tb;

    sc_out< sc_uint<8> > a_tb;
    sc_out< sc_uint<8> > b_tb;
    sc_out<bool> valid_tb;

    void test();

    SC_CTOR(testbench){
        SC_CTHREAD(test, clk_tb.pos());
        async_reset_signal_is(rst_tb, true);
    }   

};

testbench.cpp

void testbench::test(){

    uint8_t c = 0;
    int k = 0;

    if (rst_tb){
        c = 0;
        k = 0;
        cout << "\nReset on!\n" << endl;
    }

    else{
        //while(!ready_tb.read()) wait(); //when using this condition the simulation never starts
            while(k < 5){
                a_tb.write( (1 + rand() % (128-1)) );
                b_tb.write( (1 + rand() % (128-1)) );

                valid_tb.write(1);
                sc_start(10, SC_NS);

                valid_tb.write(0);
                sc_start(10, SC_NS);

                cout << "\nTest number " << k+1 << endl;
                cout << "\ta = " << a_tb.read() << " and b = " << b_tb.read() << endl;
                cout << "\tAddition of " << a_tb.read() << " and " << b_tb.read();
                cout << " = " << result_tb.read() << endl;

                c = a_tb.read() + b_tb.read();

                if ( result_tb.read() != c ){
                    cout << "Real result = " << a_tb.read() + b_tb.read();
                    cout << " and result with module = " << result_tb.read() << endl;  
                    cout << "Wrong result\n" << endl;
                    //  exit(1);
                }

                else cout << "Result OK\n" << endl;
                k++;
        }   
    }
}

1 个答案:

答案 0 :(得分:1)

问题的根本原因如下:

  1. main.cpp函数中的模拟时间太短(10 ns,我修改为500 ns)。
  2. 由于testbench模块中的测试函数是SC_CTHREAD,因此它必须在无限循环内。之前的实现完全错误,我认为这也是Segmentation fault (core dumped)消息的根本原因。
  3. 此外,由于迭代次数与模拟时间(在main.cpp函数中设置)有关,因此不需要重复测试五次的循环。以下是testbench.cpp更正的代码:

    void testbench::test(){
    
        uint8_t c = 0;
        int k = 0;
    
        if (rst_tb){
            c = 0;
            k = 0;
            cout << "\nReset on!\n" << endl;
        }
    
        else{
            while(1){   
                    a_tb.write( (1 + rand() % (128-1)) );
                    b_tb.write( (1 + rand() % (128-1)) );
    
                    valid_tb.write(1);
                    wait();
                    valid_tb.write(0);
                    wait();
    
                    while(!ready_tb.read()) wait();//This condition waits until ready_tb = true to continue the simulation
    
                    cout << "\nTest number " << k+1 << endl;
                    cout << "\ta = " << a_tb.read() << " and b = " << b_tb.read() << endl;
                    cout << "\tAddition of " << a_tb.read() << " and " << b_tb.read();
                    cout << " = " << result_tb.read() << endl;
    
                    c = a_tb.read() + b_tb.read();
    
                    if ( result_tb.read() != c ){
                        cout << "Real result = " << a_tb.read() + b_tb.read();
                        cout << " and result with module = " << result_tb.read() << endl;  
                        cout << "Wrong result\n" << endl;
                        exit(1);
                    }
    
                    else cout << "Result OK\n" << endl;
    
                    k++;
            }   
        }
    }