SystemVerilog验证 测试平台编写指南 第四章学习笔记(一)

4.2 接口

例4.4 仲裁器的简单接口

interface arb_if(input bit clk);
    logic [1:0] grant,request;
    logic rst;
endinterface

例4.5 使用了简单接口的仲裁器

module arb (arb_if arbif);
    ...
    always@(posedge arbif.clk or posedge arbif.rst)
        begin
        if(arbif.rst)
            arbif.grant<=2'b00;
        else
            arbif.grant<=next_grant;
        ...
        end
endmodule

接口信号必须使用非阻塞赋值来驱动。

例4.6 使用简单仲裁器接口的测试平台

module test (arb_if arbif)
...
    initial begin

        ...
        @(posedge arbif.clk);
        arbif.request<=2'b01;
        $display("@%0t:Drove req=01",$time);
        repeat(2)@(posedge arbif.clk);
        if (arbif.grant!=2'b01)
            $display("@%0t: a1: grant!=2'b01",$time);
        $finish
    end
endmodule:test

例4.7 使用简单仲裁器接口的top模块

module top;
    bit clk;
    always #5 clk=~clk;

    arb_if arbif(clk);
    arb a1(arbif);
    test t1(arbif);
endmodule:top

4.2.3 使用modport将接口中的信号分组

例4.10 带有modport的接口

interface arb_if(input bit clk);
    logic[1:0] grant,request;
    logic rst;
    
    modport TEST(output request, rst, input grant, clk);

    modport DUT(input request,rst,clk,output grant);
    
    modport MONITOR(input request,grant,rst,clk);

endinterface

例4.11 接口中使用modport的仲裁器模型

module arb(arb_if.DUT arbif);
    ...
endmodule

例4.12 接口中使用modport的测试平台

module test(arb_if.TEST arb_if);
    ...
endmodule

例4.13 接口使用modport的仲裁器监视模型

module monitor (arb_if.MONITOR arbif)
    
    always@(posedge arbif.request[0]) begin
        $display("@%0t:request[0] asserted",$time);
        @(posedge arbif.grant[0]);
        $display("@%0t:grant[0] asserted",$time);
    end

    always@(posedge arbif.request[1]) begin
        $display("@%0t:request[1] asserted",$time);
        @(posedge arbif.grant[1]);
        $display("@%0t:grant[1] asserted",$time);
    end
endmodule

4.3 激励时序

4.3.1 使用时钟块控制同步信号的时序

例4.14 带时钟块的接口

interface arb_if(input bit clk);
    logic[1:0] grant,request;
    logic rst;

    clocking cb@(posedge clk);  //声明cb
        output request;
        input grant;
    endclocking

    modport TEST(clocking cb,output rst);
    
    modport DUT(input request,rst,output grant);

endinterface

module test(arb_if.TEST arbif)
    initial begin
        arbif.cb.request<=0;
        @arbif.cb;
        $display("@%0t:Grant=%b",$time,arbif.cb.grant);
endmodule:test

4.3.2 接口中的logic和wire对比

VMM注重代码的可重用性,其规则指明将接口中的信号定义为wire

但本书注重logic的易用性,建议在接口中将信号定义为logic

若要在接口中使用过程赋值语句驱动一个异步信号,则该信号必须定义为logic。

而wire变量只能被连续赋值语句驱动。

时钟块中的信号始终是同步的,可以定义为logic或者wire。

例4.15 如何驱动接口中的logic和wire信号:logic信号可以直接被驱动,wire需要使用额外的代码。

interface asynch_if();
    logic l;
    wire w;
    
endinterface

module test(asynch_if ifc);
    logic local_wire;
    assign ifc.w=logic_wire;
    
    initial begin
        ifc.l<=0;   //直接驱动异步logic信号
        local_wire<=1;// 只能用assign驱动wire信号
        ...
    end
endmodule

4.3.4 测试平台—设计间的竞争状态

例4.14 设计和测试平台之间的竞争状态

module memory(input wire start, write, 
              input wire [7:0] daar,
              inout wire [7:0] data);
    logic [7:0] men[256];
    always @(posedge start) begin
        if(write)
            mem[addr]<=data;
        ...
    end
endmodule

module test(output logic start,write,
            output logic [7:0] addr,data);
    initial begin
        start=0;
        write=0;
        #10;
        addr=8'h42;
        data=8'h5a;
        start=1;
        write=1;
        ...
    end
endmodule
 

4.3.5 程序块(Program Block)和时序区域(Timing Region)

测试平台和设计的竞争问题的根源在于设计和测试平台的事件(event)混合在同一个时间片(time slot)内,即使在纯RTL程序中也会发生同样的问题。

在SV中,测试平台的代码在一个 程序块中。

模块中含有代码和变量,可以在其他模块中例化。

程序块不能有任何的层次级别,如模块的实例、接口或者其他程序。

SV引入了新的时间片的划分方式:

  1. Active(design)区域:仿真模块中的设计代码。在这个区域中运行设计事件,包括RTL、门级代码和始终发生器(clock generator)。
  2. Observed(assertions)区域:执行断言。
  3. Reactive(testbench)区域:执行程序中的测试平台部分。
  4. Postponed(sample)区域:为测试平台的输入采样信号。

Observed(assertions)和Reactive(testbench)区域可以触发本时钟周期内Active区域中进一步的设计事件。

例4.17 带有时钟块接口的测试平台

program automatic test(arb_if.TEST arbif);
...
    initial begin
        arbif.cb.request<=2'b01;
        $display("@%0t:Drove req=01",$time);
        repeat(2) @arbif.cb;
        if(arbif.cb.grant!=2'b01)
        $display("@%0t:a1:grant!=2'b01",$time);
    end
endprogram:test

4.4 接口的驱动和采样

在时钟块中应当使用同步驱动,即“<=”操作符来驱动信号。

在SV中的program块中,可以使用initial块,但不可以使用always块。

不应该把时钟发生器放在程序块中,这回引起信号的竞争。应该把它放到模块中。

4.6 顶层作用域

Verilog:宏定义

SV:编译单元

任何module,macromodule,interface,program,package或者primitive边界之外的作用域被称为编译单元作用域,也称为$unit。

这个作用域内的任何成员,比如parameter,都类似于全局成员,可以被所有低一级的块访问。

$root

4.7 模块交互

4.8 SystemVerilog断言

4.8.1 立即断言

例4.33 使用if语句检查一个信号

bus.cb.request<=1;
repeat(2) @bus.cb;
if(bus.cb.grant!=2'b01)
    $display("Error,grant!=1");

例4.34 简单的立即断言

bus.cb.request<=1;
repeat(2)@bus.cb;
a1:assert(bus.cb.grant==2'b01);

4.8.2 定制断言行为

立即断言有可选的then和else分句。

例4.36 在立即断言中创建一个定制的错误消息

a1:assert(bus.cb.grant==2'b01)
else $error("Grant not asserted");

SV有四个输出消息的函数:$info,$warning,$error,$fatal,仅允许在断言内部使用,而不允许在过程代码中使用。

例4.38 创建一个定制的错误消息

a1:assert(bus.cb.grant==2'b01)
   grants_received++;
else
    $error("Grant not asserted");

4.8.3 并发断言

例4.39 检查X/Z的并发断言

interface arb_if(input bit clk);
    logic [1:0] grant,request;
    logic rst;
    
    property request_2state;
        @(posedge clk) disable iff (rst);
        $isunknown(request)==0;
    endproperty
    assert_request_2state:assert property(request_2state);
endinterface

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值