在 SystemC 的测试台模块中管理信号
Managing signals within a testbench module in SystemC
我正在尝试在 SystemC 中模拟一个带有 CABA(周期精确/位精确)模型的模块,该模型将两个数字相加。它有以下信号:
模块addition_CABA
a
: 输入加号。
b
: 输入加号。
clk
:时钟输入。
valid
:输入信号,当输入a
和b
可用时变为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
中生成了一对随机数来为 a
和 b
赋值。
- 模块在一些时钟周期后计算结果。
- 测试平台直接进行加法运算,并将其与模块生成的结果进行比较。
- 这些动作在一个重复五次的循环中。
我遇到的问题是,当我 运行 时,模拟 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++;
}
}
}
问题的根本原因如下:
main.cpp
函数中的仿真时间太短(10ns,我修改为500ns)
- 由于testbench模块中的测试函数是一个
SC_CTHREAD
,它必须在一个无限循环中。之前的实现是完全错误的,我认为这也是 Segmentation fault (core dumped)
消息的根本原因。
另外,重复测试5次的循环是不需要的,因为迭代次数与仿真时间有关(在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++;
}
}
}
我正在尝试在 SystemC 中模拟一个带有 CABA(周期精确/位精确)模型的模块,该模型将两个数字相加。它有以下信号:
模块addition_CABA
a
: 输入加号。b
: 输入加号。clk
:时钟输入。valid
:输入信号,当输入a
和b
可用时变为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
中生成了一对随机数来为a
和b
赋值。 - 模块在一些时钟周期后计算结果。
- 测试平台直接进行加法运算,并将其与模块生成的结果进行比较。
- 这些动作在一个重复五次的循环中。
我遇到的问题是,当我 运行 时,模拟 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++;
}
}
}
问题的根本原因如下:
main.cpp
函数中的仿真时间太短(10ns,我修改为500ns)- 由于testbench模块中的测试函数是一个
SC_CTHREAD
,它必须在一个无限循环中。之前的实现是完全错误的,我认为这也是Segmentation fault (core dumped)
消息的根本原因。
另外,重复测试5次的循环是不需要的,因为迭代次数与仿真时间有关(在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++;
}
}
}