我需要使I2C多路复用器在现场可编程门阵列。从主机到从机的SCL信号应该通过多路复用连接,这是没有问题的。那SDA信号呢?它应该在两个方向上都有效。直接连接,无需High-Z或时钟同步。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发布于 2021-05-13 09:34:09
由于您的目标是FPGA,因此您需要检查您的主板支持什么。内部双向帐篷对FPGA的支持有限或没有支持。他们可能有特殊的宏模块。
通常,带有inout的应该有一个确定性的驱动程序assign io = drv_en ? data : 'z;。但是看起来你想让连接逻辑来决定驱动方向。这可以在模拟中完成;对于合成来说,这是有问题的。
对于SystemVerilog,您可以使用alias (假设您的工具集支持它)
alias sda_master = sda_slave0 = sda_slave1;在Veriog和SystemVerilog中,你可以使用tran原语(通常是不可合成的)
tran (sda_master,sda_slave0);
tran (sda_master,sda_slave1); 您还可以使用别名端口创建自己的模块。这与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 (通常不能合成)
tranif1 (sda_master,sda_slave0, select==2'b00);
tranif1 (sda_master,sda_slave1, select==2'b01); 同样,检查您的FPGA支持什么,因为它将是限制因素。
https://stackoverflow.com/questions/67502732
复制相似问题