首先能夠看特權同窗的這篇文章http://www.eefocus.com/ilove314/blog/11-09/231507_10e01.html做個初步瞭解。html
下面咱們用三種方法去實現inout,先說明一下,第一種方法的結果與其餘兩種方法不同,估計有問題,不推薦使用。工具
第一種方法和第二種方法的區別是inout做輸入時的寫法不同。第三種方法針對Xilinx FPGA,直接使用原語IOBUF。spa
代碼以下,綜合工具Vivado 2015.3,器件選擇k7325tffg900-2。code
module inout_def( input clk, input z, inout dinout, input z2, inout dinout2, input z3, inout dinout3, output reg led_r1, output reg led_r2, output reg led_r3 ); reg dout = 0; wire din; assign dinout = z?1'bz:dout; assign din = z?dinout:1'bz; always @(posedge clk) begin if(din) led_r1 <= 1; else led_r1 <= 0; end reg dout2 = 0; wire din2; assign dinout2 = z2?1'bz:dout2; assign din2 = dinout2; always @(posedge clk) begin if(din2) led_r2 <= 1; else led_r2 <= 0; end reg dout3 = 0; wire din3; IOBUF IOBUF( .I(dout3), .O(din3), .T(z3), .IO(dinout3) ); always @(posedge clk) begin if(din3) led_r3 <= 1; else led_r3 <= 0; end endmodule
對代碼進行綜合,結果以下圖所示,能夠看到,第二種方法和第三種方法綜合出來的結果是相同的,第一種方法的結果與其餘兩種不一樣。因此inout做輸入時直接assign就好了。htm
放大IOBUF能夠看到,IOBUF實際上由一個OBUFT和一個IBUF組成。blog
IBUF是輸入緩衝器,這個很少說。OBUFT是三態輸出緩衝器,其結構和真值表以下圖所示,能夠看到,當T爲1時,輸出是高阻態。當T爲0時,輸出與輸入結果相同。get
所謂高阻態,百度百科是這樣說的:電路分析時高阻態可作開路理解。你能夠把它看做輸出(輸入)電阻很是大。它的極限狀態能夠認爲懸空(開路)。也就是說理論上高阻態不是懸空,它是對地或對電源電阻極大的狀態。而實際應用上與引腳的懸空幾乎是同樣的。input
咱們想象一下,OBUFT爲高阻態時至關於開路,那dinout3和IBUF組成的通路和通常的輸入通路豈不是徹底相同,因此此時能夠當Input來用。io
下面進行implementation,咱們看dinout3實現的結果,能夠看到IOBUF的IBUF和OBUFT以及相應的聯結關係。OBUFT的TRI對應的是z3。IBUF的OUT對應的是led_r3_reg。class
最後,考慮到代碼的通用性,在使用inout端口的時候仍是推薦用第二種方法。