双向端口的两种写法
1 带dir控制
出
assign panel1_sda_a = (panel_iic_sel == PANEL1_IIC_A) ?( fpga_dir ? fpga_sda :1'bz):1‘bz;
入
assign fpga_sda = fpga_dir ? 1'bz :fpga_sda_r ;
always @(*)
case (panel_iic_sel)
PANEL1_IIC_A: fpga_sda_r = panel1_sda_a;
default : fpga_sda_r = fpga_sda_r ;
endcase
-------------------------------------------------------------------------------------------------------------------------------------
废弃 废弃 废弃 仅限于仿真
2 自动识别方向(废弃,仿真可行,上板后 A→B,ok, B→A,电平处于中间态且无法传送)
module sda_test
(
input rst_n,
inout A,
inout B
);
reg A_r;
reg B_r;
reg line_en;
assign A = A_r ;
assign B = B_r ;
always @(*) begin
if (!rst_n)
begin
A_r <= 1'bz;
B_r <= 1'bz;
end
else begin
if (line_en)
begin
B_r <= 1'bz;
A_r <= B;
end
else
begin
B_r <= A;
A_r <= 1'bz;
end
end
end
always @(A or B)
begin
if (!rst_n)
line_en <= 1'b0;
else if (A !== A_r)
line_en <= 1'b0;
else if (B_r !== B)
line_en <= 1'b1;
else
line_en <= line_en;
end
endmodule
测试代码
`timescale 1ns/1ps
module tb;
reg clk;
reg rst_n;
reg A_w,B_w;
wire A,B;
always #10 clk = ~clk;
initial
begin
clk = 0;
rst_n = 0;
#200
rst_n = 1;
#100
A_w = 1;
B_w = 'hz;
#200
B_w = 0;
A_w = 'hz;
#200
B_w = 1;
A_w = 'hz;
#100
A_w = 0;
B_w = 'hz;
end
//must use assign to give inout port a value
assign A = A_w;
assign B = B_w;
sda_test sda_test
(
.rst_n (rst_n),
.A (A),
.B (B)
);
endmodule
仿真波形