SV_LAB学习01篇 LAB1

最近需要学习SystemVerilog,入门是SV_LAB。因此在EETOP搜集了一些学习资料。

相关资料 SV_LAB、SV_TestbenchGuider、SV_LABGuider,是可以在EETOP搜索。

快捷跳转如下:

(1)2016最新Synopsys 官方Lab  http://bbs.eetop.cn/thread-614054-1-1.html

(2)SystemVerilog Testbench Student Guide & Lab Guide  http://bbs.eetop.cn/forum.php?mod=viewthread&tid=357937

篇中所说的绿皮书,指的是《SystemVerilog验证  测试平台编写指南》的中文版,张春...译的那本;

这里只是学习笔记,方便自己查看,写有不周,望理解。

 

目录

一、DUT

1.1  DUT端口

1.2  DUT输入时序

1.3  DUT输出时序

1.4  DUT代码参考

1.5  Interface 代码

二、测试平台顶层代码

2.1  定义时钟

2.2  定义接口

2.3  接口连接测试平台

2.4  接口连接待测模块

2.5  产生时钟信号

三、 测试平台的驱动代码  test.sv


一、DUT

1.1  DUT端口

由于第一个LAB比较简单,这里先介绍一下DUT;

DUT是一个16进16出的路由器,你看din、frame_n、valid_n都是16位,din一位就表示一个路由的输入口,dout同理。

1.2  DUT输入时序

输入时序中,从frame_n拉低开始,在frame_n拉高结束,注意最后一个数据时frame_n是为高的。

输入时序中,din分为三个部分:(1)addr 占4个周期,(2)pad 占5个周期,(3)data 长度不定。

输入时序中,valid_n在(1)输入addr阶段时不关注,在(2)输入pad阶段为高,在(3)输入数据阶段指示数据是否有效。

其中地址4位,范围0~15,表示数据要从哪个dout转发出去。

1.3  DUT输出时序

输出时序,相对简单一些,使用frameo_n下降沿表示开始,frameo_n上升沿表示结束。

然后,转发时序中只包含data阶段,在传输过程中valid_n用来指示数据线是否有效。

1.4  DUT代码参考

位于sv_lab的rtl目录下,接口可参考1.1中图。

1.5  Interface 代码

由于6个lab,接口代码 router_io.sv都一样,所以提前介绍了;

(1)接口信号,使用logic定义;

(2)定义clocking块定义时钟域,指定信号的方向;这里方向是 相对于测试平台而言的。

(3)使用modport将信号分组。

关于这个分组的含义主要是为了方便和安全吧,关于接口的说明位于绿皮书4.2章节。然后关于使用modport后信号赋值的问题,有自己的一些疑惑和思考,10月27号之前尽快做点实验出一个篇7。

这里有个大佬讲的挺好,放出链接 https://blog.csdn.net/liubin1222/article/details/81169314 

摘抄一个重点:“大概是这个意思的:input  #1ns 指的是采样时间相对时钟上升沿提前1ns,但不在波形上显示。用来模拟真实电路中的建立时间。  output #1ns指的是驱动时间相对时钟上升沿推后1ns,会在波形上显示出来。用来模拟真实电路中的传播延时。”

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  frameo_n;
	input  busy_n;
  endclocking: cb

  modport TB(clocking cb, output reset_n);

endinterface: router_io

 

二、测试平台顶层代码

对应代码是lab中的 router_test_top.sv 。这是搭建测试平台的最重要一步,主要有五方面内容:定义时钟 --- 定义接口 --- 接口连接测试平台 --- 接口连接待测模块 --- 产生时钟信号

请务必理解和理清这5个步骤,只有只有这样才能理解测试平台呀。数字电路的测试,总归还是以时钟和时序为中心的,只不过驱动时序的表述使用了高级语言,比verilog方便而已。

2.1  定义时钟

定义了一个bit信号,这里用作时钟。bit在SV中是一个双状态数据类型,即只有0和1,用绿皮书2.1.2中说法,这“有利于提高仿真器稳定性”。

    bit SystemClock;

2.2  定义接口

以2.1定义的时钟信号作为关联输入,定义了一个接口变量;其中 router_io 就是1.5中定义的与DUT相关的interface类型,也就是在这里接口top_io中的clock信号和顶层中的SystemClock信号关联起来。然后,top_io中信号的赋值将在SystemClock作用下完成。

    router_io top_io(SystemClock);

2.3  接口连接测试平台

将接口传递个驱动模块,这里test是用来产生激励的program块,具体在第三节叙述,其作用是驱动top_io中的信号。

    test t(top_io);

2.4  接口连接待测模块

将接口与DUT连接,在该实验中test程序块驱动接口信号,那么只要将接口的信号与DUT相连接,就可以驱动DUT,或收集DUT输出了。

  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)
  );

2.5  产生时钟信号

启动平台,就是产生是时钟,然后测试平台和DUT就在时钟作用下开始工作。

  initial begin
	$timeformat(-9, 1, "ns", 10);
    SystemClock = 0;
    forever begin
      #(simulation_cycle/2)    SystemClock = ~SystemClock;
    end
  end

三、 测试平台的驱动代码  test.sv

(1)首先在顶层需要把router_io类型的变量传递进来,而且指定了modport组,明确接口中信号的类型是input还是output。

(2)在task reset()任务中,将reset_n等信号置为默认值,然后等待15个周期结束该task。

思考一点:这里驱动信号时并没有指明时钟信号、时钟触发沿,那是因为时钟在声明接口top_io时已经指明了是SystemClock,没有指明触发沿是因为在interface中定义clocking cb时已经指明了触发沿。

值得说明,这个teat并没有对dut输入太多内容,仅仅是一个复位。然后这里task中赋值,有两个疑问,待做实验探究:

(1)通过 rtr_io.reset_n = 1'b0 赋值与通过 rtr_io.cb.reset_n <= 1'b1 的区别 ?

(2)##2是等待两个时钟周期的时间,还是等待两个时钟触发沿(完全等同于repeat(2) @(rtr_io.cb)) ?

program automatic test(router_io.TB rtr_io);

  initial begin
    $vcdpluson;
	reset();
  end

task reset();
  rtr_io.reset_n = 1'b0;
  rtr_io.cb.frame_n <= '1;
  rtr_io.cb.valid_n <= '1;
  ##2 rtr_io.cb.reset_n <= 1'b1;
  repeat(15) @(rtr_io.cb);
endtask: reset

endprogram: test

 

 

 

 

 

 


版权声明:本文为ShiAokai原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。