由於專案需要,現在編寫了一個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裡面增加一個延時就可以巧妙的解決掉這個問題了。