Synopsys system veriolog Lab学习(1)

Lab1

该实验创建一个测试平台对DUT进行复位的测试

测试平台总体框图

在这里插入图片描述

DUT

DUT为一个16输入,16输出的路由器,这个路由器的功能是把数据通过各个输入端(Input)发送到任意输出端(Output)。
代码如下:

module router(
    reset_n, clock, frame_n, valid_n, din, dout, busy_n, valido_n, frameo_n);

input reset_n, clock;

input [15:0] din, frame_n, valid_n;

output [15:0] dout, valido_n, busy_n, frameo_n;

...

endmodule

Interface

接口定义如下:

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;

  //Lab 1 - Task 2, Step 3
  //
  //Declare a clocking block driven by posedge of signal clock
  //Add all signals required to connect test program to the DUT
  //All directions must be with respect to test program
  //ToDo
  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

    //Lab 1 - Task 2, Step 4
    //
    //Add input and output skew in clocking block(optional)
    //ToDo

  //Lab 1 - Task 2, Step 5
  //
  //Create a modport to connect to test program
  //Arguments should list clocking block and all other potential asynch signals
  //ToDo
  modport TB(clocking cb, output reset_n);

endinterface: router_io

Test

Test部分实现DUT的复位,代码如下:

//Lab 1 - Task 3, Step 2
//
//Declare a program block with arguments to connect
//to modport TB declared in interface
//ToDo
program automatic test(router_io.TB rtr_io);

  //Lab 1 - Task 3, Step 3
  //
  //Declare an initial block 
  //In the initial block print a simple message to the screen
  //ToDo
  initial begin
    $vcdpluson;
	reset();
  end

  //Lab 1 - Task 6, Steps 3 and 4 -
  //
  //Replace $display() in initial block with $vcdpluson
  //Call reset() task
  //ToDo - Caution!! Do only in Task 6

//Lab 1 - Task 6, Step 2
//
//Define a task called reset() inside the program to reset DUT per spec.
//ToDo - Caution!! Do only in Task 6
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

代码中“##2”为等待两个时钟控制事件,如果当前的模块、接口或程序没有指定缺省的时钟控制的话,编译器应该发布一条错误。详见(https://www.wenjiangs.com/doc/xihjjvxc)。
在开始时刻,采用阻塞赋值,接下来的语句采用非阻塞赋值。
二者主要区别为:等号左边的变量值是否立即得到更新;赋值语句执行期间是否允许其他语句执行。

TB_TOP

该部分为顶层模块,例化上述三个部分,代码如下:

//Lab 1 - Task 4, Step 6a
//
//Add `timescale
//ToDo
`timescale 1ns/100ps

module router_test_top;
  parameter simulation_cycle = 100;

  bit SystemClock;

  //Lab 1 - Task 4, Step 3
  //
  //Add an interface instance
  //ToDo
  router_io top_io(SystemClock);

  //Lab 1 - Task 4, Step 4
  //
  //Instantiate the test program
  //Make I/O connection via interface
  //ToDo
  test t(top_io);

  router dut(
    //Lab 1 - Task 4, Step 5
    //
    //Modify DUT connection to connect via interface
    //ToDo

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

  initial begin
    //Lab 1 - Task 4, Step 6b
    //
    //Add $timeformat
    //ToDo

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

endmodule

通过Modelsim仿真:
由于modelsim跑有的在##2处会出错,这里改了一下:
在这里插入图片描述
仿真结果如下图,延时200ns后,在时钟上升沿处reset_n跳变。
在这里插入图片描述
再贴一张VCS仿真的图:
在这里插入图片描述
该图实验结果是按照指导实验指导手册的实验步骤进行所得,复位发生在两个时钟控制事件之后(即两个时钟上升沿)。图中151ns时reset_n信号拉高,两个时钟事件的时间为150ns,接口中时钟块设置输入输出skew为1ns,所以reset_n拉高的时间为151ns。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值