You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Interface中实现inout端口并正确连接至DUT?

问题:Interface中inout端口与DUT连接的多驱动冲突解决

问题背景

在将inout端口集成到SystemVerilog Interface并连接DUT时,出现了编译错误,提示intf.a_data和intf.b_data存在多驱动冲突。冲突来源于DUT和测试台同时对Interface中的信号进行连续赋值,即使两者都包含高阻分支,工具仍识别为非法多驱动。

错误原因分析

  1. 信号类型问题:原Interface中a_data/b_data声明为logic类型,logic属于变量型,不允许多个驱动源(哪怕是带高阻的分支);而inout端口本质是双向线网,需要用wire类型支持多驱动场景。
  2. 驱动逻辑互斥性:虽然DUT和测试台的赋值都有高阻分支,但工具在编译阶段无法提前判断运行时的互斥性,因此直接报错。

解决方案

核心修改点

  • 将Interface中的双向数据信号改为wire类型,适配inout端口的线网特性。
  • 确保DUT与测试台的驱动逻辑通过控制信号严格互斥,同一时刻只有一个非高阻驱动源。

修改后的完整代码示例

1. 修正后的Interface

interface mem_intf(input clk);
    logic   cs     ;
    logic   a_we   ;
    logic   a_oe   ;
    logic   [16:0] a_addr ;
    wire    [7:0]  a_data ; // 改为wire类型适配inout
    logic   b_we   ;
    logic   b_oe   ;
    logic   [16:0] b_addr ;
    wire    [7:0]  b_data ; // 改为wire类型适配inout
endinterface

2. 修正后的DUT(mem.sv)

module mem_ram (
    mem_intf intf
);
    // 补全缺失的参数声明
    parameter DATA_WIDTH = 8;
    parameter ADDR_WIDTH = 17;
    parameter RAM_DEPTH  = 1 << ADDR_WIDTH;

    reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1]; 
    reg [DATA_WIDTH-1:0] r_data;                
    reg r_a_oe;                                                  
    reg r_b_oe;                                                                             
    
    always@ (posedge intf.clk) begin                                     
        if (intf.cs) begin                                               
            if (intf.a_we)                                               
                mem[intf.a_addr] <= intf.a_data;                         
            if (intf.b_we)                                               
                mem[intf.b_addr] <= intf.b_data;                         
            r_data <= mem[intf.a_addr];                                  
        end
        r_a_oe <= intf.a_oe;
        r_b_oe <= intf.b_oe;
    end

    // 保持原有驱动逻辑,确保仅在输出使能有效时驱动,否则置高阻
    assign intf.a_data = (intf.a_oe && intf.cs && !intf.a_we) ? r_data : 'bz;
    assign intf.b_data = (intf.b_oe && intf.cs && !intf.b_we) ? r_data : 'bz;
endmodule

3. 修正后的测试台(tb_top.sv)

module tb_mem_ram;
    bit clk;
    always #5 clk = ~clk;

    mem_intf intf(clk);
    reg  [7:0] a_data_value; 
    reg  [7:0] b_data_value; 
    
    mem_ram dut (
        .intf(intf)
    );

    // 测试台驱动逻辑:仅在输出使能无效时(写操作)驱动,否则置高阻
    assign intf.a_data = !intf.a_oe ? a_data_value : 'bz;
    assign intf.b_data = !intf.b_oe ? b_data_value : 'bz;

    initial begin
        // 示例测试流程:先写后读
        intf.cs = 1;
        // 写操作:a_oe=0(禁止DUT输出),a_we=1(允许写入)
        intf.a_oe = 0;
        intf.a_we = 1;
        intf.a_addr = 10'h000;
        a_data_value = 8'hAA;
        #10;
        // 读操作:a_oe=1(允许DUT输出),a_we=0(禁止写入)
        intf.a_oe = 1;
        intf.a_we = 0;
        #10;
        $display("Read data from A port: %h", intf.a_data);
        $finish;
    end
endmodule

原理说明

  • wire类型支持多驱动源,只要运行时同一时刻只有一个非高阻驱动,就不会产生冲突。
  • 通过a_oe/b_oe信号实现驱动互斥:当DUT需要输出数据时,测试台的驱动自动置为高阻;当测试台需要写入数据时,DUT的驱动自动置为高阻,从根本上避免了多驱动冲突。

内容的提问来源于stack exchange,提问作者bu-ral

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 05:15:40