在很多情況下,需要使用雙向IO。不過最好謹慎使用,在top層使用。網上很多描述的代碼甚至是不可以綜合並且有語法錯誤的,還是老實自己寫個模塊吧。
新版本如下:
使用inout口,直接定義個inout口。
然后用使能控制就好了,如果是作為輸入,則直接把inout賦值給reg型變量就行。
如果作為輸出,則使用使能控制,輸出則把寄存器的值賦給inout,不輸出則賦值z。表示輸出高阻態,處於輸入模式中。
inout io_sdio;//定義一個inout r_sdi_shift<={r_sdi_shift[6:0],io_sdio}; //采集數據 assign io_sdio = r_oe_n ? 1'bz : r_sdo_shift[23] & (~o_csn); //輸出
三行代碼解決一切問題。
老版本不再使用,如下:
如果你需要一個口既做輸入端口也做輸出端口,那么你就需要去描述一個雙向的IO。
1.電路框圖:
2.數據流向:
當en=0的時候,三態門選通,dinout當輸出口使用,數據從din到dinout。
當en=1的時候,三態門關閉,dinout當輸入口使用,輸出呈現高阻態,數據從dinout到dout。
3.代碼:
//************************************************ // Filename : dual_io.v // Author : kingstacker // Company : School // Email : kingstacker_work@163.com // Device : Altera cyclone4 ep4ce6f17c8 // Description : dual io,wwidth can be change; //************************************************ module dual_io #(parameter WIDTH = 8)( /*i*/ input wire clk , input wire rst_n , input wire en , input wire [WIDTH-1:0] din , inout wire [WIDTH-1:0] dinout , /*o*/ output wire [WIDTH-1:0] dout ); reg [WIDTH-1:0] din_reg; reg [WIDTH-1:0] dout_reg; always @(posedge clk or negedge rst_n) begin if (~rst_n) begin din_reg <= 0; dout_reg <= 0; end //if else begin if (~en) begin din_reg <= din; end else begin dout_reg <= dinout; end end //else end //always assign dinout = (~en) ? din_reg : 8'hzz; assign dout = dout_reg; endmodule
4.綜合一下看看:三態門實現雙端口。
以上。