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

如何在可综合的层级结构内实现inout信号线的交换?

可综合的SystemVerilog Inout信号线模块化交换实现

需求背景

我希望通过独立的层级结构实现inout信号线的交换,以此提升RTL设计的模块化程度。目前在SystemVerilog中实现inout线交换存在难度,我找到的唯一可行方法是使用alias命令,但该方法会导致不可综合错误,尽管其功能与非模块化实现一致。以下是最小可复现代码(当前代码通过alias实现了预期的交换功能,我希望在不使用alias命令的前提下实现相同效果):

原实现代码

mod_a.sv

module mod_a  (
    inout bit0,
    inout bit1,
    input signal_a,
    input [1:0] bus_a
);

wire mod_b_bit0;
wire mod_b_bit1;

mod_b u_mod_b (
    .bit0(mod_b_bit0),
    .bit1(mod_b_bit1),
    .signal_a(signal_a),
    .bus_a(bus_a)
);

mapper u_mapper (
    .mod_b_bit0(mod_b_bit0),
    .mod_b_bit1(mod_b_bit1),
    .bit0(bit0),
    .bit1(bit1)
);

endmodule

mod_b.sv

module mod_b  (
    inout bit0,
    inout bit1,
    input signal_a,
    input [1:0] bus_a
);

assign bit0 = signal_a ? 1'bZ : bus_a[0];
assign bit1 = signal_a ? 1'bZ : bus_a[1];

endmodule

原mapper.sv(不可综合)

module mapper  (
    inout mod_b_bit0,
    inout mod_b_bit1,
    inout bit0,
    inout bit1
);

alias bit0 = mod_b_bit1; //swap
alias bit1 = mod_b_bit0; //swap

endmodule

测试台tb.sv

module testbench_top;

   wire bit0;
   wire bit1;

   logic  signal_a;
   logic [1:0] bus_a;

   logic dq0_driver;
   logic dq1_driver;

   assign    bit0 = signal_a ? dq0_driver : 1'bZ;
   assign    bit1 = signal_a ? dq1_driver : 1'bZ;

initial begin
        signal_a = 0;
        dq0_driver = 0;
        dq1_driver = 0;
        bus_a = $random();

        #20 
        signal_a = 1;
        dq0_driver = 1;
        dq1_driver = 0;

        #20 
        signal_a = 0;
        bus_a = $random();

        #20 
        signal_a  = 1;
        dq0_driver = 0;
        dq1_driver = 1;

        #20 
        signal_a = 0;
        bus_a = $random();

        #20 
        signal_a  = 1;
        dq0_driver = 1;
        dq1_driver = 1;

        #20 
        signal_a = 0;
        bus_a = $random();

        #20 
        signal_a  = 1;
        dq0_driver = 0;
        dq1_driver = 0;

        #20 
        signal_a  = 1;
        dq0_driver = 1;
        dq1_driver = 0;

        #1000 $stop;
end

mod_a u_mod_a ( //mod A
    .bit0(bit0),
    .bit1(bit1),
    .signal_a(signal_a),
    .bus_a(bus_a)
);

endmodule

可综合的替代方案

要替换不可综合的alias命令,我们可以通过双向连续赋值实现inout信号的交叉交换,这种方式完全符合综合工具的要求,同时能实现与原代码一致的功能。修改后的mapper.sv如下:

修改后的mapper.sv(可综合)

module mapper  (
    inout mod_b_bit0,
    inout mod_b_bit1,
    inout bit0,
    inout bit1
);

// 双向交叉连接,实现信号交换,完全可综合
assign bit0 = mod_b_bit1;
assign mod_b_bit1 = bit0;

assign bit1 = mod_b_bit0;
assign mod_b_bit0 = bit1;

endmodule

方案说明

  • alias命令本质是为信号创建别名,物理上属于同一条导线,但绝大多数综合工具不支持该语法的综合。
  • 双向连续赋值通过将两组inout信号交叉连接,实现了完全等价的信号交换逻辑:当mod_b_bit1被驱动时,bit0会同步接收信号;当bit0被外部驱动时,mod_b_bit1也会同步接收信号,完美复现原alias的双向传输行为。
  • 该方案保持了原有的模块化层级结构,无需修改mod_a、mod_b或测试台代码,仅替换mapper模块即可实现可综合的信号交换。

内容的提问来源于stack exchange,提问作者Mahmoud Maarouf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 12:12:31