SV中inout与ref区别

hegangben
2025-05-27 / 0 评论 / 3 阅读 / 正在检测是否收录...

mb8rt6bp.png

一、Inout是什么?
inout百度翻译为“双向,双向总线”,顾名思义就是该类型端口既能做输入又能做输出。很多需要交互的芯片外部的有些管脚都会使用inout类型,尤其是需要与外界做双向通信的数据总线与地址总线。

在需要用到inout类型搭建仿真验证平台时,需要注意以下两个方面:

1.在例化端口时,需将顶层的inout型的信号必须变为wire型;
2.在编写assign语句时,其必须放在initial或always块外部。

想对inout型的信号进行读写操作时需使用assign语句,具体代码如下:

module TB();
    wire  data_inout;
    reg   data_reg;
    reg   db_link;
    
    initial begin
    ..........
    end
    
    assign data_inout = db_link ? data_reg : 1'hz;
  
endmodule

二、Ref是什么?
Ref为Reference的缩写,百度翻译为“参考,引用”。通过查阅资料,ref类型会使参数按照引用传递。下面为本人在验证工作时碰到的一个例子:

设计(DUT)源程序部分代码:

module DUT;
        
endmodule

验证环境 (Test_Bench—cpu_mod) 部分代码:

`timescale 1ns/1ps
module cpu_mod;
    parameter cpu_period   = 33.33;
    parameter cpu_period*2 = 66.67;
    parameter cpu_period*9 = 299.97;   
     initial begin
        write_flag = 0;
     end   
    task automatic cpu_write (input [15:0] addr , input [15:0] data , ref logic cs);
          dut.if.ebi_rd_wr = 1'b1;
        cs               = 1   ;
        #cpu_period;
          dut.if.ebi_addr  = addr ;
          dut.if.ebi_rd_wr = 1'b0 ;        
          dut.if.ebi_ts    = 1'b0 ;
        cs               = 0    ;
        #cpu_period*2;
          dut.if.ebi_ts    = 1'b1 ;
          write_flag       = 1    ;
        cpu_wdata        = data ;
          dut.if.ebi_we_be0  = 1'b0 ;        
          dut.if.ebi_we_be1  = 1'b0 ;
        #cpu_period*9;
          dut.if.ebi_rd_wr   = 1'b1 ;
          dut.if.ebi_we_be0  = 1'b1 ;        
          dut.if.ebi_we_be1  = 1'b1 ;
        #cpu_period;
          write_flag         = 0     ;
          dut.if.ebi_addr    = 16'hz ;        
        cpu_wdata          = 16'h0 ;    
        cs                 = 1     ;
  endtask
endmodule

测试用例 (Test_Case) 部分代码:

`timescale 1ns/1ps
   module testcase(interface dut_if);
        bit [15:0] cpu_addr1 = 16'h1803;
        bit [15:0] cpu_data1 = 16'h1234;
     initial begin
         #150ms;
          cpu_mod.cpu_write (cpu_addr1,cpu_data1,dut_if.ebi_cs3);   
     end
   endmodule

1)代码结构的思路
待更新

2)代码结构的说明
待更新

三、两者区别是什么?
当task和function的形式参数被声明为input类型时,input类型的形参只是进行了数值的拷贝;而当task和function的形式参数被声明为output类型时,output类型的形参会在return时刻将数值拷贝至接收方。这就不难得出 inout 类型不仅会在输入时进行数值的拷贝,而且会在输出时将数值拷贝至接收方。
Ref 类型的形参,我们做的不是拷贝,而是 引用 。对于task来讲,ref类型的参数,其外部是可见的,换句话说在外部对ref的形参数值进行的修改,task是可见且同步变化的;而inout类型的参数,task得到的仅仅是一个拷贝过来的数值,在整个task运行期间,外部的数值无论发生什么变化,对于task而言是未知的,同理task对该数值在其内部进行的修改,只有task运行结束后,外部才会获得该值。

四、两者联系/区别总结
Inout 与 Ref 均可以在task与function中传入传出数据;
Inout 在外部传递的参数改变时,其调用的task或function无法实时更新,只有当调用的task或function执行完毕后才会发生变化;
Ref 在外部传递的参数改变时,其调用的task或function能够实时更新数值;
Ref 操作不需要消耗仿真时间,而 Inout 则需要消耗仿真时间。
————————————————
版权声明:本文为CSDN博主「进击的砰砰砰」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42493102/article/details/122311686

1

评论 (0)

取消