1. 子类和父类的方法调用问题:(参考绿皮书P227)

B extend A;A和B都有方法 fun,且fun前面都有virtual修饰:此时根据句柄指向的对象类型来决定调度谁的fun;

如果fun前面没有virtual修饰:则会根据句柄类来决定调用谁的fun,而不是对象类型;

多个具有继承关系的类的方法,共用同一个名字的现象即为:“多态”


  1. vcs 只支持   bit   [10:0] XXX;
  2. 不支持:byte    [10:0] XXX;   这种编译会报错

  1. vcs编译某一个filelist文件:vcs  -sverilog  -f  xxx.f  -l xxx.log

上述编译完成后会生成:simv文件;再输入./ simv进行仿真


1)GVIM:
   1、:iab lw liu wei  编辑简写;.vimrc配置
   2、gvim窗口:命令模式:vsp  说明:左右分屏
   3、:E   打开目录页
   4、:bd    :w回退窗口

2)linux:
    ssh 主机名   //切换主机 or 服务器

3)verdi波形中需要下载数组信号时:在仿真中加入 $fsdbDumpMDA()或者按下图加上“”“+all” 

system verilog function output队列_sed

4)根据用例名字和随机种子生成波形文件名: 

在top_tb里面加入:

reg [1000:0] casename;
    initial begin //  12 27
        if($value$plusargs("TESTNAME_FSDB=%s",casename)) begin
            $display("TESTNAME_FSDB = %s ",casename);
            $fsdbAutoSwitchDumpfile(1024,casename,10);
        end
        $fsdbDumpvars(0,top_tb,"+all"); // +all for strunct
        $fsdbDumpMDA();
        $fsdbDumpon();
    end

在run/Makefile加入:

RUN_OPTS += +TESTNAME_FSDB=$(tc)_$(seed).fsdb #3-14

根据用例名字和随机种子生成波形文件名: 

makefile里面:(export 把fsdb_name导出)

system verilog function output队列_sed_02

  • -ucli 是启动UCLI命令行模式,-i 吃进去 tcl 脚本文件;
  • +fsdb+autofulsh,一边仿真,一边dump 波形;()

 tcl部分:(set env()获得变量fsdb_name(由makefile导出的))

system verilog function output队列_学习_03


取int数据中的某一些比特

system verilog function output队列_学习_04


资料来源:公众号-芯片学堂

1.initialize RNG

(1)初始化RNG是产生随机数的开始,用来给RNG初始化随机种子。

(2)每一个模块实例(module instance)、接口实例(interface instance)、程序块(program)和包(package)实例都有属于自己的初始化RNG,在不指定随机种子的情况下,默认的随机种子根据不同编译器的实现决定的。

2.hierarchy seeding

(1)分层分配随机种子是随机稳定性的重要机制。

(2)在创建新的线程或者实例化对象的时候,父线程使用的RNG的下一个随机值会作为这个新线程或者新对象的RNG的随机状态,即作为新的种子传递下去。

3.thread & object stability

(1)SV中将程序(program)、模块(module)、接口(interface)、函数(function)、任务(task)等这些独立的块叫Process。

(2)每个Process都有自己的RNG。每个RNG都有自己的随机状态(random state)。

(3)可以通过process::self()这个静态方法获取当前Process的RNG句柄,再通过句柄调用get_randstate()方法来获得随机状态。不同的仿真工具返回来的随机状态的值的表现方式可能会不一样,但基本都是一段看起来没有规律的字符串,这个字符串表示下一个要产生的随机数的值。

注:在复现一个执行失败的测试用例的时候,不要改动之前布下的种子,也不要改变程序中线程和对象创建的顺序,避免更改了分层随机种子的顺序。


在sv/verilog中,我们常用的是整数(int, longint),小数可以用(real),对小数的处理大致分为三种:

1. 四舍五入(如果除数和被除数均为整数,可以通过乘以1.0来实现)

2. 向上取整:系统函数$ceil(164*8/28) = 47

3. 向下取整:通过系统函数$floor实现;$floor(164*8/28) = 46

$ceil和$floor只參數接受int 和real類型,不接受bit類型或int unsigned;


随机一个数组

int    ai_port[] ;
int    port_tmp[8] = '{0,1,2,3,4,5,6,7,8};


ai_port = new[7]; //初始化
ai_port_tmp.shuffle(); //打乱数组顺序,再去取前面的一部分;
foreach (ai_port[i])   ai_port[i] = ai_port_tmp[i] ;
ai_port[$] = 9 ; //对数组的最后一个元素给特定值

void'(std::randomize(qid_port) with {qid_port inside {ai_port}); //qid_port将在ai_port里面的几个值平均随机;即使里面重复多次的数,也会是均匀随机,参考绿皮书P142 例子6.14
//上面数组ai_port,也可以是队列的形式

$display的打印选项


system verilog function output队列_学习_05

语句

含义

\n

换行符

\t

制表符

\v

垂直制表符

\f

换页符

\\

\字符

\"

" 字符

\a

%字符

%d

十进制输出

%b

二进制输出

%o

八进制输出

%h

十六进制输出

%e

指数形式输出

%f

十进制表示方法输出实数

%g

十进制或者指数表示方法输出实数

%s

字符串输出

%l or %L 

Display library binding information,显示库关联关系

%c

ASCII码输出

%m

输出层次名

%v

输出网线类型变量的强度

%t

输出当前时间

%p

可以打印数组(还有unpacked structures, arrays, and  unions.)

IEEE Std 1800™-2012 :The %p format specifier may be used to print aggregate expressions such as unpacked structures, arrays, and  unions.

常用形式: 

system verilog function output队列_systemverilog_06


小数计算场景

int   i_tmp=3;
real  r_real_ab;
real  r_real_a = 1;
real  r_real_b = 2;

i_tmp = real'(1/3); // 结果为0
r_real_ab = real'(2)/real'(3); // 结果为:0.6667
i_tmp = 4/3;// 结果为: 1
r_real_ab = 1/3; // 结果为0
r_real_ab = r_real_a/r_real_b; // 结果为:0.5
int          ai_test_array[10];
          int          a = 4;
          int          b = 9;

          ai_test_array [1]    =  $ceil(real'(9)/real'(4));// result is 3
          ai_test_array [2]    =  $ceil(real'(9)/4)       ;// result is 3
          ai_test_array [3]    =  $ceil(9.0/4.0);  // result is 3 
          ai_test_array [4]    =  $ceil(9/4.0)  ;  // result is 3
          ai_test_array [5]    =  $ceil(9/4*1.0);  // result is 2
          ai_test_array [6]    =  $ceil(1.0*9/4);  // result is 3
          ai_test_array [7]    =  $ceil(9/real'(4));  // result is 3 
          ai_test_array [8]    =  $ceil(9/real'(a));  // result is 3
          ai_test_array [9]    =  $ceil(real'(b)/4);  // result is 3

字符串类型

SystemVerilog引入了一个字符串类型(string),它是一个大小可变、动态分配的字节数组。

字符串类型变量的声明语法如下:

     string variable_name [=initial_value];

如果在声明中没有指定初始值,变量会被初始化成空字符串(“”)。字符串文本由引号(“”)包围并且拥有自己的数据类型。对字符串文本的长度没有预定义的限制,一个字符串文本必须存在一个单行中,除非新的行紧跟着一个反斜杠(\)。


system verilog function output队列_学习_05



SV文件写入:()

integer   fit_dut,fid_refm;// 声明文件的句柄

fid_refm = $fopen("data_refm.txt","w");
fid_dut  = $fopen("data_dut.txt","w");
$fwrite(fid_refm,"%0h",exp_tr_0);
$fwrite(fid_dut,"%0h",act_tr_0);

//......
$fclose(fid_refm); //已验证 可行
$fclose(fid_dut);

有时候,一个类的里面定义了一套写入txt的debug代码,但是这个类会被例化成多个,所以要确保文件名不能一样;在UVM中,可以利用不能同名的实例名来作为文件的句柄; 
 

class  base_scb  extends uvm_scoreboard;

string       ms_rep_id;
integer      mi_file_name;

function   new(string   name="base_scb",uvm_component  parent);
super.new(name,parent);
ms_rep_id = name;//获取这个类被实例化时注册的名字,以便作为句柄名;
endfunction

function  void   build_phase(uvm_phase  phase);
super.build_phase(phase);
mi_file_name = $fopen({ms_rep_id,"xx_debug.txt"},"w");
endfunction

endclass

静态变量和动态变量:

静态变量只初始化一次;动态变量每次调用都会初始化;

静态变量的初始化时不可综合的;动态变量的初始化是可综合的,前提是这些动态变量只是函数内部使用,不会传递到函数外面;

变量在声明时,可以直接初始化;(int   mi_abc = 99;)(在SV中内嵌初始化在仿真时刻0之前执行)(initial块则是在仿真时刻0执行)

静态task/function内的变量,缺省时也是静态的;

模块一级的变量都是都是静态的,不能显示的声明为static或automatic;(参考黄皮书P44)

在verilog中:module、begin......end块、fork.......join块以及非自动的task和function中,缺省时都为静态存储;

SV向后兼容verilog:所以上述:module、begin......end块、fork.......join块以及非自动的task和function中,缺省时都为静态存储;(这就是为什么fork.....join_none开启多个线程时,需要用到动态变量来辅助的原因吧TBD)


函数调用自身:递归函数;

一般系统函数和系统任务是不可以综合的;


@(posedge  bus.clk);(这个好像会多花一拍时间)(10368ns)
@bus.monitor_cb;(这个会少花一拍时间)(10367ns)

实际场景中:如果没有统一,采用混用的话,可能会出现输出数据的顺序不一致
这两种触发有什么区别吗?

第一:@(posedge  bus.clk)采的信号仿真器认为是上升沿前的数据,@bus.monitor_cb仿真器认为是触发沿后的数据;(如果所有的采样信号都已加入clocking block,那么采样的数据均为时钟沿前的数据)

第二:后一种方式在时钟信号名发生改变后只需要修改interface文件即可


 执行顺序顺序问题:

fork

    begin // thred1:
        repeat(1)  @(posedge   v_glb_intf.clk);
        $display("it is not #0ns");
    end

    begin // thred2: #0ns
        repeat(1)  @(posedge   v_glb_intf.clk);
        #0ns;
        $display("it is #0ns");
    end

    begin // thred3:
        repeat(1)  @(posedge   v_glb_intf.clk);
        repeat(2) #0ns;
        $display("it is 2 #0ns");
    end

join_none

//#0ns 可以用来调整代码块的执行顺序;上述伪代码:会先执行线程1,再执行线程2,最后再执行线程3

task和function的区别:

1、function不能执行耗时语句,可以用return返回值;

2、task能执行耗时语句,不可以用return返回值;

常见的耗时语句@event 、wait event 、 #delay

function和task的区别——SV,SystemVerilog_小小verifier的博客

system verilog function output队列_学习_05

system verilog function output队列_字符串_09


对某一个信号打拍(就是refm的信号延迟多少拍后再与DUT的信号比对) 

//beat_num 要打的拍数
int        pipe_mem_bp[]; //pipe refm_bp //solve refe_mode syn DUT signal;
pipe_mem_bp = new[beat_num];
foreach(pipe_mem_bp[i])  pipe_mem_bp[i] = 0;// initial array[]

while(1) begin
        @(posedge v_glb_intf.clk); // 
        for(int i = 0; i < (beat_num -1); i++)    pipe_mem_bp[i+1] = pipe_mem_bp[i]; // to achieve pipe beat_num clk
        pipe_mem_bp[0] = refm_bp;

        if (pipe_mem_bp[beat_num-1] != dut_bp) begin
            //do somethng
        end
end

pre_randomize()和post_randomize;

当调用 obj . randomize () 的时候,它首先调用 obj 的 pre_randomize () 方法以及它的所有被使能的随机对象成员。接下 来 pre_randomize () 会调用 super . pre_randomize () 。在新的随机值被计算并赋值后, randomize () 会调用 obj 的 post_randomize () 方法以及它的所有被使能的随机对象成员。接下来 post_randomize () 会调用 super . post_randomize ();

用户可以在任何类中过载 pre_randomize () 方法以便执行对象被随机化之前的初始化和预处理

用户可以在任何类中过载 post_randomize () 方法以便执行对象被随机化之后的清除、打印诊断、以及后处理。

如果这些方法被过载,那么它们必须调用对应的父类方法,否则它们在随机化之前和之后的处理步骤会被忽略。

pre_randomize()和 post_randomize()方法不是虚拟的。然而,因为它们会被虚拟的 randomize()方法自动调用,所 以它们看上去像是虚拟的。

system verilog function output队列_sed_10


给所有bit赋值:data = 'b1;  data = {32{1'b1}}; 


1、在使用ref修饰函数参数时(在module/program中),需要将function/task修饰为automatic,否则xrun编译不通过,VCS可以。严谨起见,还是记得加automatic。
通过ref传递参数是一个唯一的参数传递限定符,将ref与任何其他方向限定符(input/output/inout)组合应该是非法的。
对于具有静态生命的子程序,通过引用的方式传递参数是非法的。
原文链接:


关联数组:可以通过foreach遍历里面的每一个有效存在的成员;

int      mi_array[string];