SV知识点总结

SV知识点总结

Tags: Learn

  • program和module有什么区别?

    Program是在SystemVerilog中新添加的,它用于以下目的:

    • 分离testbench与DUT
    • 有助于确保testbench和DUT没有竞争冒险(race condition)
    • 提供了执行testbench的入口点
    • 通过(program … endprogram)指定了Reactive Region的调度。

    program内部不能包含always语句块,而module可以
    program中不能包含UDP,modules或其他program实例,而module可以
    program在调度队列的re-active region中执行,module在active region中执行
    program可以调用modules或其他program中task或function,但是module不能调用program中的task或function。

  • packages的用途是什么?

    在Verilog中,模块内变量/任务/函数的声明特定于模块(module)。SystemVerilog的package结构允许声明全局变量/任务/函数,从而在modules/classes之间使用。

    packages可以包含module/class/function/task/constraints/covergroup等声明,在使用时需要使用范围解析运算符或import来访问packages中的内容。

  • $ rose和posege有什么区别?

    posege返回一个事件(event),而$rose返回一个布尔值,因此它们是不可互换的。

  • 动态数组在new时可以不分配大小吗 ?

    不可以

  • 端口设置Ref 代表的意思 Ref的使用规则?

    Ref表示的是引用,若方法中的变量类型是ref类型,则函数里面对数据的操作对外部实时可见,若要求方法中的数据操作不影响数据变化,可用const限定,意思为只读不写

  • Class或package中声明的function/task默认时静态还是动态方法

    动态(软件中)只有task可以调用task,task可以消耗时间而function不能从最大灵活性角度考虑,所有用于调用的子程序都应该被定义成函数而非任务

  • 类里面的interface为什么要是virtual?

    需求因素:在systemverilog中的软件环境中无法实例化硬件module(interface),但是需求验证环境中的class驱动interface。

    为什么是virtual:定义一个interface,且实例化多个后,如果没有定义virtual,则在任何一个实例中修改了某个信号值,在其他实例中都会受到影响。如果定义了virtual,则每个实例独立,如果该interface只有一个实例,可用可不用virtual,有多个实例,需要virtual。更好的办法是,都加上virtual。virtual interface只是申明一个handle, 保存实际接口的句柄。就好像一个指针一样, 可以在程序进行中进行construct构造, 所以class里必须是virtual interface

    接口interface作为一个类,方便了不同的模块直接的连接(使模块直接的连接看起来更为简洁,修改也更为方便。)但是不同模块直接调用(多出实例化),可能某一个值改变而改变了所有使用此接口处的值(相当于于物理连接)。而不同模块使用virtual interface以后,就类似一个指针用来指向此接口。Virtual interface作为一个句柄,此时在该class中调用时,专属这一个接口对实际的静态interface并无影响。

    类似virtual interface还有virtual task 、virtual function 、virtual class等。其应该主要体现出OOP的思想,可以根据自己的需要快速的搭建验证环境

  • 解释数据类型logic,reg,和wire之间的区别和联系

    Wire:用于连接不同的元件,不存储值,被连续赋值(assign)或端口(port)驱动。
    Reg:并不意味实际的存储器,代表verilog/sv 中的数据存储元素,保存值,直到被下一次赋值(阻塞或非阻塞),可被综合为触发器,锁存器或组合电路。过程赋值
    Logic:不能被多驱动,改进reg数据类型,可以被连续赋值。连续赋值。过程赋值

  • SV clocking block的用处和好处?

    clocking只能在module/interface/checker/program中声明,不能在function/task/package中。clocking块里声明的inout类型相当于对具有相同名字的input和output的两个信号同时进行声明的简略写法,和port声明里的inout意义不同

    主要是为了更好解决testbench和DUT之间的timing和同步的问题,

    Interface 指定了testbench和DUT之间的通信信号,但是Interface,没有指定任何的时序规则和同步要求Clocking block指定timing规则和同步要求,以确保在正确的时间与DUT交互,避免竞争冒险问题。

  • 使用SV 避免testbench和DUT之间的竞争冒险的方法有哪些?

    • Module中的initial语句块调度在active region, Program中的initial语句快调度在reactive region。
    • 在program中使用非阻塞赋值来驱动设计信号,在re-NBA区域对其进行更新
    • 通过带有 #0 input skews的clocking blocks。
  • Timescale的理解描述

    Timeslot:中发生的行为,可以认为是实际电路中同一时刻并行完成的,而在仿真中是有先后顺序调度的。
    在这里插入图片描述

    Preponed 时间片入口,断言采样时间 断言采样到的值一定是旧值

    active/in-active/no-block module中代码执行时间

    active区域 阻塞赋值直接在本区域完成

    in-active区域: #0延时的线程会在该区域执行

    NBA域 完成非阻塞赋值的操作使赋值行为生效 环境”采样module信号是在NBA之后,那么采样到的就是“新值”;

    observed 断言检查时间

    re-active/re-inactive/re-NBA program中代码执行时间

    program中线程开始执行,program中的re-active域就相当于module中active域一样,这里的阻塞赋值立即执行,非阻塞赋值被推如re-NBA域

    postponed 时间片出口

    除了顺序执行的非阻塞赋值会立即生效外,其他线程大体都会需要一个采样-生效的过程,而这个采样点一般是preponed域、observed域。

  • fork-join_none与循环语句共同使用的行为探究

    1. fork-join_none提起线程本身不会阻塞时间片前进;
    2. fork-join_none不会立即执行,而是暂时被挂起等待延时语句阻塞时间片时,再被执行;
    eg1
    
    begin
    
    fork  
       $display("dislpay fork1"); 
    join_none
    fork  
       $display("dislpay fork2");
    join_none
    fork  
       $display("dislpay fork3"); 
    join_none
    
    #10ns;
    
    End
    
    #display fork3
    
    #display fork3
    
    #display fork3
    
    begin
     for(int i=0; i<10; i++)begin
       fork
          $display("A: i = %0d", i); 
       join_none
     end
    end
     #10ns;
    
    // A: i = 10;
    // A: i = 10;
    // A: i = 10; …..
    /*循环中的10个线程都被提起来都等待执行,for循环内没有阻碍时间进程的语句因此for循环直接执行
    完成,跳出循环时i==10,遇到#10ns语句执行所有悬挂的打印线程。对于所有打印的线程,i值均为
    10,因此打印了10次i = 10。*/
    
    begin
    for(int i=0; i<10; i++)begin
    	fork
    		automatic  int  k = i;
    		$display("B: k = %0d", k);
    	join_none
    end
    end
    
    #10ns;
    
    /*
    # B: k = 9;
    # B: k = 8;
    # B: k = 7; …..
    其中int k创建语句会立即执行不会被挂起,因此i的值通过k保留了下来。等到#10ns时候指令
    打印时,每个线程都打印了自己作用域内的k值,因此时没有问题的。*/
    
  • build_phase的执行顺序

    要分清build_phase执行和真正component的create的创立是有区别的。真正节点的建立是new函数的执行。

在这里插入图片描述

上图的执行build_phase和creat的创建顺序。

2的build_phase的执行(按照书写顺序创建子节点3.4.5.6),然后执行到4的build_phase(按照字母顺序排序)创建了7.8.9(按照书写顺序)然后执行789的build_phase(按照字母排序)但是一个节点的build_phase执行时如果还有子节点,就先进行子节点,在执行兄弟节点的子节点build_phase,所以7.8.9.10.的build_phase的执行顺序为7.8.10.9

build_phase是按自上而下的原则执行的,但只有直接上下级关系的节点能保证先后顺序。

对于在UVM树中具有叔侄关系的节点的创建顺序,并不能保证谁先谁后。

build_phase是按照深度优先的原则遍历的。

create操作是在父节点的build_phase里执行,同级节点的create操作是按照代码书写顺序执行的.

当该父节点的build_phase执行完,开始执行其子节点的build_phase时,则按照字母表顺序执行各子节点的build_phase.

要分清build_phase执行和真正component的create的区别。

**对一个节点来说:**

其create操作是在父节点的build_phase中完成的。

该节点的build_phase, 是在其父节点的build_phase完成后,将该父节点的所有儿子节点按字母表排序,顺序执行的。

在其build_phase中,按书写顺序create其下级子节点。

一个节点,只有其下的所有子孙节点的build_phase完成后,才开始执行其兄弟节点的build_phase.
  • Systemverilog中有哪些覆盖率的类

    代码覆盖率:又包括(行覆盖率,路径覆盖率,状态覆盖,翻转覆盖)
    功能覆盖率:是最重要的,主观的,反映设计意图实现的完备性。
    如代码覆盖率高而功能覆盖率低就代表可能代码没有实现一些功能
    如代码覆盖率低而功能覆盖率高就代表功能测试表不够完备。
    断言覆盖率:衡量在测试过程中断言的触发。
    寄存器覆盖率:寄存器时候都测试到。可读写域的检查。

  • 解释Abstract class(抽象类)和virtual meath

    • Abstract class(抽象类)是可以扩展但不能直接实例化的类。使用virtual关键字定义的。
    1. 虚方法必须有实现部分,抽象方法没有提供实现部分,抽象方法是一种强制派生类覆盖
    2. 抽象方法只能在抽象类中声明,虚方法不是。其实如果类包含抽象方法,那么该类也是抽象的,也必须声明为抽象的。
    3. 抽象方法必须在派生类中重写,这一点跟接口类似,虚方法不必。

    抽象方法和虚方法的区别 :

    ~抽象方法和虚方法的区别在于:虚拟方法有一个实现部分,并为派生类提供了覆盖该方法的选项,相反,抽象方法没有提供实现部分,强制派生类覆盖方法(否则 派生类不能成为具体类); ~abstract方法只能在抽象类中声明,虚方法则不是; ~abstract方法必须在派生类中重写,而virtual则不必; ~abstract方法不能声明方法实体,虚方法则可以。

    Abstract class是不打算实例化的基类,只用来派生子类。可将其抽象化。

    用途:有时候需要描述一组对象的属性而无需知道其实际的行为,派生的扩展子类可以通过abstract class 共享方法。

    Virtual methods是类的多态必须的,父类的句柄指向子类同名的方法,需要将父类的方法声明为虚方法。

  • 用来建立scoreboard的数据结构是什么

    Queue(队列)或mailbox

    队列像链表一样,可以在队列中的任何位置添加或删除元素,而无需单步执行前面的元素。 像数组一样,可以直接访问带有索引的任何元素,而无需分配新的数组并复制整个内容

  • 什么是$root?

    top-level scope,可用于引用任意层次中例化的模块

  • 在constraint之前“solve”是什么意思?

    如果用户要指定约束求解器求解约束的顺序,则用户可以在约束之前通过solve指定顺序

    SystemVerilog添加了专门的always_ff建模触发器
    SystemVerilog添加了专门的always_latch建模锁存器
    SystemVerilog添加了专门的always_comb建模组合逻辑

  • 在systemverilog中为function和task添加了哪些功能?

    不需要begin和end。function可以具有void返回类型,task可以具有return

  • 什么是封装(Encapsulation)?

    将数据和方法绑定在一起。

  • Associative arrays(关联数组)和dynamic arrays(动态数组)之间的区别?

    关联数组:具有字符串索引功能,在编译时分配内存。

    动态数组:在运行时分配内存,构造函数用于初始化动态数组的大小。

  • 与队列(queue)相比,链表(linked-list)的优点是什么?

    队列有固定的顺序,很难将数据插入队列中。但是链表可以轻松地将数据插入任何位置。

  • 不使用randmize或rand,生成随机循环数组

    int UniqVal[10];
    foreach(UniqVal[i])  UniqVal[i]= i;
    UniqVal.shuffle(); //打乱排序
    
  • 解释pass by ref和pass by value的区别?

    pass by value 是将参数传递给function或task的默认方法,每个子例程保留该参数的本地副本,如果在子例程中更改了参数,不会影响原来的值
    pass by ref function和task直接访问作为参数传递的指针变量,传递的是指针,指向同一对象,如果不想更改数组值,可以使用const ref。

  • 如何在program语句中实现always语句块?

    //用forever和fork join、any,none加begin end实现
    always @(posedge clk or negedge reset) begin
       if(!reset) begin
           data <= '0;
       end else begin
           data <= data_next;
       end
    end
    
    // Using forever : slightly complex but doable
    forever begin
       fork
       begin
           @ (negedge reset);
           data <= '0;
       end
       begin
           @ (posedge clk);
           if(!reset)    data <= '0;
           else           data <=data_next;
       end
       join_any
       disable fork
    end
    
  • 什么是前向引用?如何避免此问题?

    有时需要在类声明之前声明另一个类变量。例如,如果两个类各自需要对方的句柄。使用typedef可以解决此问题,为第二个类提供前向声明/引用

  • Covergroup中的option和type_option的区别,

    type_option与option的区别,type_option会影响最后总和的结果,而option影响的是每个intance内的结果。这一点对于weight, comment等其他参数也一样

  • 6
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值