将inout分配给inout(SystemVerilog)

将inout分配给inout(SystemVerilog),verilog,system-verilog,iverilog,Verilog,System Verilog,Iverilog,我需要在FPGA内部制作I2C多路复用器。 从主设备到从设备的SCL信号应该通过多路复用器连接,这没有问题。 SDA信号呢?它应该是双向的。直接连接,无需High-Z或时钟同步。 分配sda_slave0=sda_master` module i2c_mux ( inout wire sda_master, input wire scl_master, inout wire

我需要在FPGA内部制作I2C多路复用器。 从主设备到从设备的SCL信号应该通过多路复用器连接,这没有问题。 SDA信号呢?它应该是双向的。直接连接,无需High-Z或时钟同步。 分配sda_slave0=sda_master`

module i2c_mux
(
    inout       wire            sda_master,
    input       wire            scl_master,
    inout       wire            sda_slave0,
    output      bit             scl_slave0,
    inout       wire            sda_slave1,
    output      bit             scl_slave1
    inout       bit [1:0]       select
    
)

always_comb
begin
    unique case (select)
    2'b00 : { scl_slave1, scl_slave0 } = { 1, scl_master };
    2'b01 : { scl_slave1, scl_slave0 } = { scl_master, 1 };
    2'b10 : { scl_slave1, scl_slave0 } = { 1, 1 };
    2'b11 : { scl_slave1, scl_slave0 } = { 1, 1 };
end

assign sda_master = sda_slave0; // ?????????????????????
assign sda_slave0 = sda_master; // ?????????????????????


    
endmodule

由于您的目标是FPGA,因此需要检查板上支持的内容。内部双向帐篷对FPGA的支持有限或没有。它们可能有特殊的宏模块

通常,对于inout,应该有一个确定性驱动程序
assign io=drv\u en?数据:'z。但是,看起来您需要连接逻辑来确定行驶方向。这可以在模拟中完成;合成有问题

通过SystemVerilog,您可以使用
别名
(假设您的工具集支持它)

在Verilog和SystemVerilog中,您可以使用
tran
原语(通常不可合成)

您还可以使用别名端口创建自己的模块。这与Verilog-95及以上版本兼容。我不知道它有多友好

module conn3( .a(io), .b(io), .c(io) );
  inout io;
endmodule

module i2c_mux( /*your port list*/ );
// ... other code

  conn3 link_io(sda_master, sda_slave0, sda_slave1);
endmodule
如果需要有条件地连接,可以使用Verilog原语
tranif
(通常不可合成)


再次检查您的FPGA支持什么,因为这将是一个限制因素。

您的问题到底是什么?在任何情况下,yo都不能将值分配给always_梳中的网络。inout必须是网络,而不是变量。(不要在那里使用钻头)。在做任何fpga工作之前,你应该编译、模拟和验证你的模型。无论如何,我找到了一些关于这个案例的信息。使用alt_bidir_buf可以解决这个问题。我使用max10系列,但它不受支持。
tran (sda_master,sda_slave0); 
tran (sda_master,sda_slave1); 
module conn3( .a(io), .b(io), .c(io) );
  inout io;
endmodule

module i2c_mux( /*your port list*/ );
// ... other code

  conn3 link_io(sda_master, sda_slave0, sda_slave1);
endmodule
tranif1 (sda_master,sda_slave0, select==2'b00); 
tranif1 (sda_master,sda_slave1, select==2'b01);