1.需要设置CPU最大运行周期数max_cycle,以防止case死掉
1 always@(posedge clkcpu) begin
2 cycle_count=cycle_count+1;
3 if(cycle_count>test.max_cycle) fail_finish;
4 end
2.需要有统一的功能错误err和断言错误assert_err统计,以便于self-check
1 property p_etimer;
2 @(posedge clk)
3 disable iff(!rst_n)
4 $fell(etimer_cfgok) |-> (cnt==0);
5 endproperty
6 etimer_assert: assert property(p_etimer)
7 else begin
8 test.assert_err++;
9 end
1 task compare;
2 input[255:0] str;
3 input[7:0] expected, measured;
4 begin
5 if(expected===measured);
6 else begin
7 $display("%tns, %s, FAIL: expect=%h, measured output=%h
", $time, str, expected, measured);
8 test.err++;
9 end
10 end
3.需要有随机种子seed实现CRT,在perl中产生,在testbench中调用
perl:
1 sub anay_cmd_line{
2 my @para = @_;
3 my $i;
4 for($i=0; $i<@para; $i++){
5 if($para[$i] =~ /-s(d+)/){
6 $set_seed = $1;
7 }
8 elsif($para[$i] =~ /-seed/){
9 $i++;
10 $set_seed=$para[$i];
11 if($set_seed =~ /0x/) {$set_seed=hex($set_seed);}
12 }
13 }
14 }
1 if($set_seed==0) {$seed=int(rand(2**10));}
2 else{$seed=$set_seed;}
3 $cfg_set_name="seed";
4 $cfg_set_val=$seed;
5 $script_set{$cfg_set_name}=$cfg_set_val;
verilog:
1 initial begin
2 $readmemh("cfg.set", cfg_set);
3 seed=cfg_set[0];
4 $display("seed: %d", seed);
5 end
4.需要有统一的PASS/FAIL函数,便于regression
其中需要征用一部分SRAM地址作为driver地址,使用下面两个模块分别作为driver的控制位和状态位。
PASS/FAIL函数则对应上述其中一个地址。
1 module Mdrv_ctrl_reg(
2 input[15:0] addr,
3 output reg[7:0] data,
4 output reg updata
5 );
6
7 always@(negedge `RAM.cen) begin
8 if(~`RAM.wen && ~`RAM.cen && (`RAM.A==(addr-16'h4800))) begin
9 data=`RAM.D;
10 update=1;
11 #1;
12 update=0;
13 end
14 end
15 endmodule
1 module Mdrv_status_reg(
2 input[15:0] addr,
3 input[7:0] reg_data,
4 );
5 endmodule
5.show函数实现打印功能,以便于debug
打印字符使用如下类似代码:
1 always@(posedge act_show_str) begin
2 show_pointer = show_addr;
3 show_byte = `ROM[show_pointer];
4 while(show_byte !=0) begin
5 $write("%c", show_byte);
6 show_pointer = show_pointer+1;
7 show_byte=`ROM.[show_pointer];
8 end
9 $write("
");
10 end
6.使用DPI将reference model与testbench连接
C函数sndr_eval在systemverilog中如下定义:
1 module dsp_connect;
2 import "DPI-C" function void sndr_eval(
3 input int data_i[],
4 input int data_q[],
5 input real fs,
6 output real sndr,
7 );
8 always@(posedge clk) begin
9 sndr_eval(data_i, data_q, fs, sndr);
10 end
11 endmodule
编译C的gcc命令如下:
gcc -m64 -fPIC -shared -o libdpi.so sndr_eval.c -I /appl/tools/cadence/INCISIV1410/tools.lnx86/inca/include/
testbench中还需要将编译C后的LIB在脚本perl中声明一下:
$ENV{'LD_LIBRARY_PATH'}="/proj/laoshan/.../sndr/c";
7.RAM必须初始化后才能使用,不然后仿真会出现很多不定态x