I need make I2C mux inside FPGA. SCL signal from master to slaves should be connected through mux and it's no problem. What about SDA signal? It should work in both directions. Directly connection without High-Z or clock synchronization. assign 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
Since you are targeting FPGA, you need to check what is supported on your board. Internal bidirectional tents have limited or no support on FPGAs. They might have special macro modules.
Normally with inouts should have a deterministic driver
assign io = drv_en ? data : 'z;
. But it looks you want the connecting logic to determine the driving direction. This can be done in simulation; questionable for synthesis.With SystemVerilog you can use
alias
(assuming your tool-set supports it)In Veriog and SystemVerilog you can use
tran
primitive (typically not synthesizable)You can also create your own module with aliased ports. This is compatible with Verilog-95 and above. I'm not sure how synthesis friendly it is.
If you need to conditionally connect, you can use the Verilog primitive
tranif
(typically not synthesizable)Again, check what your FPGA supports as it will be the limiting factor.