在项目中可能需要调用c model,就要涉及到调用脚本和读写文件
cpp
cmd_str = $psprintf("cd %0s; ./run_RandomGen.sh ~/MATLAB/v99 >& csd.log",folder_name);
$system(cmd_str);
上述调用system 函数无法运行*.sh的脚本,需要用perl脚本包一下
cpp
$system("perl call_c_model.pl 1 20 ");
Call_c_model.pl
perl
#!/usr/bin/perl
use warnings;
use strict;
Use Fcntl qw(:flock);
My $matlab_use_file;
My @matlab_use_info;
My $use_cnt;
My $debug_en;
My $csd_log;
My @ignore_err;
My $log_out;
My $c_model_log;
My $sleep_time;
$csd_log = "c_model_0/csd.log";
$c_model_log = "c_model_0/c_model.log";
$log_out = 0 ;
$matlab_use_file = "$ENV{SIMENV_SIM}/matlab_use.log";
$debug_en = 1;
print "log path: $matlab_use_file\n";
@ignore_err = qw /
ERROR:.*MATLAB Runtime component cache
/;
&before_call_c_model;
system('cd c_model_0; ./run_RandomGen.sh ~/MATLAB/v99 >& csd.log');
&after_call_c_model;
sub before_call_c_model{
if(ARGV[0] == 1) {
while(1) {
My $print_wait_info;
Open INFO,'+>>', $matlab_use_file or die "could not open $matlab_use_file: $! ";
Flock INFO,LOCK_EX;
@matlab_use_info = <INFO>;
$use_cnt = 0;
Foreach(@matlab_use_info){
Chomp($_);
$use_cnt += $_;
}
if($debug_en) {
If(! defined($use_cnt_pre)) {
$print_wait_info = 1;
}
Else {
if ($use_cnt != $use_cnt_pre) {
$print_wait_info = 1;
}
}
}
if($use_cnt < $ARGV[1]){
Print INFO "1\n";
Close INFO;
$use_cnt_pre = $use_cnt;
Last;
}
else {
close INFO;
$sleep_time = 1;
sleep $sleep_time;
@matlab_use_info = ();
$use_cnt_pre = $use_cnt;
}
}
}
}
sub after_call_c_model {
if(ARGV[0] == 1) {
open INFO,'+>>', $matlab_use_file or die "could not open $matlab_use_file: $! ";
Flock INFO,LOCK_EX;
@matlab_use_info = <INFO>;
print INFO "-1 \n";
$use_cnt = 0;
foreach(@matlab_use_info){
chomp($_);
$use_cnt += $_;
}
$use_cnt--;
if($use_cnt == 0) {
system("echo 0 > $matlab_use_file");
}
print "call c model done matlab use num is : $use_cnt\n" if $debug_en;
close INFO;
}
获取环境变量
perl
package common_pkg;
Import uvm_pkg ::*;
Import "DPI-C" function string getenv (input string env_name);
....
endpackage
pwa = getenv("PWA");
sv中获取c model output
perl
Function automatic void rd_data_from_c_model(
Int id=0;
Dut_type_e dut,
String file_name,
Ref int data_q_q[$][$],
Input string info = "READ_FILE",
String folder_path = "./randbitTrue/",
Bit clr_q_en=0,
Uvm_verbosity VBST=UVM_DEBUG
);
string path;
int fp;
string line;
int get_str_code;
int scan_value;
int line_num;
int pkt_cnt;
path = {$sformatf("%0s_c_model_%0d"),folder_path,file_name};
file_exist(path);
if(clr_q_en == 1)begin
Foreach(data_q_q[j]) data_q_q[j] = {}
end
fp = $fopen(path,"r");
while(!$feof(fp))begin
get_str_code = $fgets(line,fp);
line_num++;
if(get_str_code != 0)begin
if(line.substr(0,17) == "//end of the burst")begin
`uvm_info(info,$sformatf("pkt_cnt = %0d",pkt_cnt),VBST)
pkt_cnt ++;
end
else if($sscanf(line,"%0h",scan_value) != 0)begin
data_q_q[pkt_cnt].push_back(scan_value);
end
end
end
endfunction
perl
task automatic read_input_data_from_c_model(int id =0,ref bit [3:0] tx_data_arr_4bit[]);
bit [31:0] tx_data_arr[];
integer n_tx_symbol_per_cmd[0];
integer n_tx_symbol[0];
integer n_tx_cmd[0];
string txt_path;
txt_path = $psprintf("c_model_%0d/Pattern/RandomBitTrue/Tx_n_cmd.txt",id);
$readmemh(txt_path,n_tx_cmd);
txt_path = $psprintf("c_model_%0d/Pattern/RandomBitTrue/Tx_cmd_len.txt",id);
$readmemh(txt_path,n_tx_symbol_per_cmd);
n_tx_symbol[0] = n_tx_cmd[0] * n_tx_symbol_per_cmd[0];
tx_data_arr = new[n_tx_symbol[0]];
tx_data_arr_4bit = new[n_tx_symbol[0]];
txt_path = $psprintf("c_model_%0d/Pattern/RandomBitTrue/Tx_ModData.txt",id);
$readmemh(txt_path,tx_data_arr);
foreach(tx_data_arr[ii])begin
Tx_data_arr_4bit[ii] = tx_data_arr[ii][3:0];
end
endtask
function read_data_from_c_model (string path,ref int rx_data_q[$]);
int rx_data_32bit_aa[int];
$readmemh(path,rx_data_32bit_aa);
if(rx_data_32bit_aa.size ==0)begin
`uvm_fatal(get_type_name(), $sformatf("fail read file : %0s",path))
end
foreach(rx_data_32bit_aa[ii])begin
rx_data_q.push_back(rx_data_32bit_aa[ii]);
end
endfunction