如何在可综合的层级结构内实现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
相关产品推荐
相关产品推荐

