一个SystemC线程与SystemVerilog线程通信的例子
由于项目需要,现在编写了一个systemc的reference model要加入到一个systemverilog的uvm框架里面去。
现在碰到的问题是systemc这边的model是以线程的模式持续运行的,而不是发一个input package给一个output package的模式,因此需要实现:
-
整体框架运行在sv中,使用vcs仿真器
-
同时拉起一个sc线程和一个sv线程
-
sv的线程可以控制sc线程中的一个锁的上锁和解锁
经过一番实验后完成的demo如下:
sc代码:
#include "systemc.h"
#include "svdpi.h"
#include "svdpi_src.h"
#include <unistd.h>
#include <iostream>
using namespace std;
extern "C" {
void wait_for_time(int delay_time);
bool get_lock();
}
SC_MODULE(ThreadExample) {
SC_CTOR(ThreadExample) {
SC_THREAD(thread_func);
}
void thread_func() {
while (true) {
cout << "systemc thread running" << endl;
wait_for_time(5);
while(get_lock())
wait_for_time(1);
}
}
};
extern "C" {
void echo(char* str) {
printf("%s\n",str);
}
int sc_main(int argc, char* argv[]) {
ThreadExample thread_example("ThreadExample");
cout << "thread crearted" << endl;
sc_start();
return 0;
}
void sc_main_wrapper(int argc, svOpenArrayHandle argv) {
char* argv_main[argc];
for (int i = 0; i < argc; i++)
{
char ** p = (char **) svGetArrElemPtr(argv, i);
argv_main[i] = *p;
}
sc_main(argc, argv_main);
}
}
sv代码:
// tb.sv
module tb;
import "DPI-C" context task sc_main_wrapper(int argc, string argv[]);
import "DPI-C" function void echo(string str);
export "DPI-C" task wait_for_time;
export "DPI-C" function get_lock;
task wait_for_time(input int delay_time);
//$display("sc time is",$time);
repeat(delay_time) begin
#1;
end
endtask
bit lock = 1;
function bit get_lock();
return lock;
endfunction
string argv[5];
initial begin
argv[0] = "./uvm";
argv[1] = "-f";
argv[2] = "../../../sw/project/build/rvcim.hex";
argv[3] = "-R";
argv[4] = "32";
fork
begin
while (1) begin
$display("sv thread1 running");
$display("sv time is",$time);
lock = ~lock;
$display("lock is ",lock);
#10;
end
end
begin
sc_main_wrapper(5, argv);
end
join_none
end
endmodule
执行结果(截取部分):
sv thread1 running
sv time is 378240
lock is 0
systemc thread running
systemc thread running
sv thread1 running
sv time is 378250
lock is 1
sv thread1 running
sv time is 378260
lock is 0
systemc thread running
systemc thread running
sv thread1 running
sv time is 378270
lock is 1
sv thread1 running
sv time is 378280
lock is 0
systemc thread running
systemc thread running
sv thread1 running
sv time is 378290
lock is 1
sv thread1 running
sv time is 378300
lock is 0
systemc thread running
systemc thread running
sv thread1 running
sv time is 378310
lock is 1
sv thread1 running
sv time is 378320
lock is 0
systemc thread running
systemc thread running
sv thread1 running
sv time is 378330
可以看到运行状态符合预期。
之前碰到的一个问题是,如果在sc线程上锁后等待的while里面不加延时的话,那么整个仿真时间无法再前进,从而sv线程也无法执行到解锁,因此sc线程无法解锁也会一直卡死,最后两个线程一起进入死锁这样一个状态。所以通过给while里面增加一个延时就可以巧妙的解决掉这个问题了。