1. 双向(可控)开关
目的是在顶层文件中实现对两个I2C模块的sda线进行选择,最初直接使用下述代码:
assign sda = ctrl ? sda_1 : sda_2 ;
可以发现当 sda 处于输出状态时,sda 在他们之中进行选择进行输出,是没有问题的;但 sda 如果是输入的话,明显就有问题了。
最初考虑把子模块 sda 的输入和输出都拉出来,先选择信号再写三态门,但这样很麻烦。
最后发现 verilog 原语里面有双向开关这么一个东西,即数据可以双向流动。
普通双向开关
tran 或 rtran ( tran 的高阻态版本 ) 开关实例语句的语法如下:
(r)tran [instance_name] (inout_a, inout_b) ;
端口表只有两个端口,并且无条件地双向流动,即从 signala 向 signalb ,反之亦然。
可控双向开关
tranif 或 rtranif 的实例语句的语法如下:
(r)tranif [instance_name] (inout_a, inout_b, ctrl);
前两个端口是双向端口,即数据从 signala 流向 signalb ,反之亦然。第三个端口是控制信号。对于 tranif0 和 tranif0,ctrl 为 0 时允许双向数据流动;对于 tranif1 和 rtranif1 ,ctrl 为 1 时允许双向数据流动。
对于 rtran、rtranif0 和 rtranif1 (高阻态版本),当信号通过开关传输时,信号强度减弱。
注意:vivado 综合不支持开关级源语!!!