Synopsys SV lab guide—lab1

目录

0.前言 

1.Interface代码

1.1声明接口

1.2声明clocking block 

 1.3声明modport

2.test代码

3.Test Harness 文件 

4.波形文件


0.前言 

     在上一篇文章中介绍了该router的端口说明和协议,从这篇文章中我们正式开始做lab1,该lab的目标有以下2点:

1.创建interface连接DUT和TB

2.根据协议产生复位激励,初始化DUT

    该lab搭建起来的组件及连接关系如下草图:

1.Interface代码

1.1声明接口

       使用SV中的logic类型声明端口,logic可代表reg/wire型,这样就不用管各个端口信号相对于TB是输入还是输出,即不用管是input还是output,直接logic类型声明简单粗暴。

interface router_io (input bit clock);//使用外部时钟时要在该处声明
  logic reset_n;
  logic [15:0] din ;
  logic [15:0] frame_n;
  logic [15:0] valid_n ;
  logic [15:0] dout ;
  logic [15:0] valido_n;
  logic [15:0] busy_n;
  logic [15:0] frameo_n;//所有DUT接口声明

endinterface

1.2声明clocking block 

       clocking block的主要作用是同步驱动和采样信号,同时声明信号相对于TB的方向,并声明输入/输出偏差,需要注意的是,若不声明,这里默认为: 

default input #1step output #0; 

        路桑在一篇文章中( IC验证培训——实战SV验证学习(lab1)_路科验证-CSDN博客_sv验证 )表明:input  #1ns 指的是采样时间相对时钟上升沿提前1ns,但不在波形上显示;用来模拟真实电路中的建立时间。output #1ns指的是驱动时间相对时钟上升沿推后1ns,会在波形上显示出来;用来模拟真实电路中的传播延时。

       关于clocking block的更详细的介绍我会另写一篇文章深入讲解。 

interface router_io (input bit clock);
  logic reset_n;
  logic [15:0] din ;
  logic [15:0] frame_n;
  logic [15:0] valid_n ;
  logic [15:0] dout ;
  logic [15:0] valido_n;
  logic [15:0] busy_n;
  logic [15:0] frameo_n;

  clocking cb @(posedge clock);//用来同步采样和驱动信号,相对于TB方向
    default input #1ns output #1ns ; //设置输入/出偏差

    output reset_n; 
    output din; 
    output frame_n; 

    output valid_n; 
    input dout; 
    input valido_n; 
    input busy_n; 
    input frameo_n; 
endclocking: cb


endinterface

 1.3声明modport

interface router_io (input bit clock);
  logic reset_n;
  logic [15:0] din ;
  logic [15:0] frame_n;
  logic [15:0] valid_n ;
  logic [15:0] dout ;
  logic [15:0] valido_n;
  logic [15:0] busy_n;
  logic [15:0] frameo_n;

  clocking cb @(posedge clock);
    default input #1ns output #1ns ; 

    output reset_n; 
    output din; 
    output frame_n; 

    output valid_n; 
    input dout; 
    input valido_n; 
    input busy_n; 
    input frameo_n; 
endclocking: cb

  modport TB(clocking cb,output reset_n) ;//声明clocing用来同步采样和驱动信号,另外又在modport中单独声明了reset_n,表明reset_n可同步(cb中)可异步(modport中)

endinterface

2.test代码

     该test实现的功能十分简单,即打印Hello World和按照router复位协议初始化DUT。该复位协议时序图如下,有如下几点关键点:

1.复位时,reset_n为低电平,frame_n和valid_n为高电平

2.有效复位至少保持1个clk

3.复位后至少等待15个时钟周期后才可以发送数据

       按照协议写test如下,具体讲解在代码后注释说明:

program automatic test (router__io.TB rtr__io);//使用接口连接
  initial begin
    $display("Hello World!"); //打印字符串
    $vcdpluson; 
    reset ();//调用复位函数 
  end

  task reset();
    router.reset_n=1'b0;//注意这里调用的是modport中的reset,是异步复位,用阻塞赋值即可,因此不用等待时钟沿;这里用异步复位的原因是为了在0时刻直接将reset拉低
    router.cb.frame_n.<='b1; //按照协议将frame和valid拉高
    router.cb.valid_n<='b1;
    ##2 router.cb.reset_n<=1'b1;//根据协议复位至少保持一个clk,这里等待2个时钟周期后把reset拉高
    repeat(15) @(router.cb); //按照协议,复位后至少等待15个时钟周期后复位结束
  endtask
endprogram

3.Test Harness 文件 

      顶层控制文件是为了将TB和interface和DUT连接起来,并生成全局时钟,具体讲解在代码后注释说明:

`timescale 1ns/lOOps//声明时间单位和精度

module router_test__top;
  parameter simulation_cycle = 100;//声明时钟周期

  bit SystemClock; //声明全局时钟变量

  router_io top__io (SystemClock) ;//例化接口 
  test t (top_io); //例化TB并连接到接口上
  router dut (
                .reset_n(top_io.reset__n),
                .clock(top__io.clock),
                .din(top_io.din),
                .frame_n(top_io.frame_n),
                .valid__n(top_io.valid_n),
                .dout(top__io.dout),
                .valido_n(top_io.valido_n),
                .busy_n(top__io.busy__n),
                .frameo__n(top_io.frameo_n)
              );//例化DUT并连接到接口上,由于DUT是按照verilog风格写的,所以不能像test一样直接连接接口,而是要通过信号映射的方式连接

  initial begin
    $timeformat(-9, 1, "ns", 10) ; //设置时间格式
    SystemClock = 0;//0时刻时钟变量为0
    forever begin
    #(simula.tion__cycle/2) SystemClock = -SystemClock;//生成周期为100ns的时钟
    end
  end
endmodule

4.波形文件

     由于default  input #1ns output #1ns的作用,根据前述路桑的讲解,结合如下波形文件可见,TB驱动信号valid_n和frameo_n的输出偏差可见,比时钟上升沿50ns晚1ns;而TB的采样信号在波形上在时钟上升沿50ns处变化,但实际上是提前1ns采样,但在波形上确实没有反映出来。

 

       配合代码看波形,首先是clock,以100ns为一个周期没有问题;再看reset_n,使用的是异步阻塞赋值,因此在0ns是0,##2表示在2个时钟上升沿后,采样cb中的同步reset_n非阻塞赋值,因此在150ns时拉高为1,但输出偏差延迟了1ns,所以在151ns拉高为1;再看驱动信号frame_n和valid_n,其使用cb中的信号非阻塞赋值,因此在0ns为x值,等到第一个时钟上升沿时同时变为1。

  • 12
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值