Clocking Block

module multiplier(mult_if.RTL inf);
  
  always@(posedge inf.clk or posedge inf.reset) begin 
    if(inf.reset) begin 
      inf.out <= 0;
      inf.ack <= 0;
    end
    else begin
      if(inf.en) begin
        inf.out <= inf.a * inf.b;
        inf.ack <= 1;
      end
      else begin
        inf.out <= inf.out;
        inf.ack <= 0;
	  end
    end
  end
endmodule

interface mult_if (input logic clk, reset);
  logic [7:0] a, b;
  logic [15:0] out;
  logic en;
  logic ack;
  
  clocking cb @(posedge clk);
    default input #7 output #6;
    input out, ack;  // 这里数据宽度不是必要的
    output a,b, en;
  endclocking

  // 这里的default input #7 output #6指的是对于@(posedge clk)的偏移,而非对于信号的延迟

  modport TB (clocking cb, input clk, reset);
  modport RTL (input clk, reset, a,b, en, output out, ack);
  
endinterface

module tb_top;
  bit clk;
  bit reset;
  
  always #2 clk = ~clk;
  
  initial begin
    clk = 0;
    reset = 1;
    #2;
    reset = 0;
  end 
  
  mult_if inf(clk, reset);
  multiplier DUT(inf);
  
  `define TB_IF inf.cb
   
  initial begin
    
    $monitor("postponed time = %0t:\ta=%d\tb=%d\tout=%d\ten=%d\tack=%d\tTB_IF.out=%d\tTB_IF.ack=%d", \
        $time, inf.a,inf.b,inf.out,inf.en,inf.ack,`TB_IF.out,`TB_IF.ack);
    
    #1;
    
    `TB_IF.a <= 'd20; 
    `TB_IF.b <= 'd7;
    
    #5;
    
    `TB_IF.en <= 1; 
    
    wait(`TB_IF.ack);
    $display("time = %0t: finish", $time);

    #10;
    $finish;
  end
  initial begin 
    $dumpfile("dump.vcd"); $dumpvars;
  end
endmodule

Output:

time = 0:	a=  x	b=  x	out=    0	en=x	ack=0	TB_IF.out=    x	TB_IF.ack=x
time = 8:	a= 20	b=  7	out=    0	en=x	ack=0	TB_IF.out=    x	TB_IF.ack=x
time = 10:	a= 20	b=  7	out=    0	en=x	ack=0	TB_IF.out=    0	TB_IF.ack=0
time = 12:	a= 20	b=  7	out=    0	en=1	ack=0	TB_IF.out=    0	TB_IF.ack=0
time = 14:	a= 20	b=  7	out=  140	en=1	ack=1	TB_IF.out=    0	TB_IF.ack=0
time = 22: finish
time = 22:	a= 20	b=  7	out=  140	en=1	ack=1	TB_IF.out=  140	TB_IF.ack=1

Clocking Block 的作用及输出解释

Clocking Block 的作用

这段代码中的 clocking block (cb) 在接口 mult_if 中定义,主要作用有:

  1. 同步信号采样和驱动:为测试平台(TB)提供与时钟同步的信号访问方式
  2. 时序控制
  3. 接口简化:通过 modport 为不同模块提供不同的信号访问权限

时间线分析:

  1. time=0:

  2. time=1:

  3. time=2:

  4. time=6:

  5. time=8:

  6. time=12:

  7. time=14:

  8. time=22:

关键点:

这种机制确保了测试平台与设计之间的同步,避免了竞争条件,是SystemVerilog中验证环境常用的同步技术。

default input #7 output #8; 下面是结果:

time = 0:	a=  x	b=  x	out=    0	en=x	ack=0	TB_IF.out=    x	TB_IF.ack=x
time = 10:	a= 20	b=  7	out=    0	en=x	ack=0	TB_IF.out=    0	TB_IF.ack=0
time = 14:	a= 20	b=  7	out=    0	en=1	ack=0	TB_IF.out=    0	TB_IF.ack=0
time = 18:	a= 20	b=  7	out=  140	en=1	ack=1	TB_IF.out=    0	TB_IF.ack=0
time = 26: finish
time = 26:	a= 20	b=  7	out=  140	en=1	ack=1	TB_IF.out=  140	TB_IF.ack=1