双端口是通过控制三态门来实现的,其典型结构如图。
当z=1时,上面输出管子导通,此时数据从上面的管子输出。
当z=0时,上面的管子输出高阻,数据从下面的管子输入。
inout型信号只能被定义成wire类型,不能被定义成reg型。因此,必须使用assgin赋值语句进行赋值。(这一点与VHDL不同)
在仿真文件中,inout要声明成wire类型的,当他作为输出使用时不必初始化,只需打开三态门;而当他作为输入时,在关闭三态门的同时要进行初始化。初始化要使用force,force后再次当做输出用时,要release,不然值还保持force的值,force的力量比较强嘛。
例子:
(z=1时,做输出;z=0时,做输入)
`timescale 1ns/10ps
module bidirec(clk,z,din,dout,dinout);
input clk;
input z;
input[7:0] din;
inout[7:0] dinout;
output [7:0] dout;
reg [7:0] dout;
reg [7:0] din_t;
always@(posedge clk) begin
din_t<= 0;
dout<= 0;
if(z)
din_t <= din;
else
dout<= dinout;
end
assign dinout= z ? din_t : 7'bz;
endmodule
`timescale 1ns/10ps
module tb_bidirec();
reg clk;
reg z;
reg[7:0] din;
wire [7:0] dout;
wire [7:0] dinout;
bidirec dut (
.clk (clk ),
.z (z ),
.din (din ),
.dout(dout),
.dinout(dinout)
);
initial clk=0;
always #5 clk=~clk; //100MHz
initial begin
z=0;
force dinout=8'h55;
#22
release dinout;
z=1;
#1 din = 8'haa;
#22 $finish;
end
initial begin
$fsdbDumpfile("dump.fsdb");
$fsdbDumpvars();
end
endmodule
仿真波形:
<ignore_js_op>
<ignore_js_op>