怎么使用雙向IO口


在很多情況下,需要使用雙向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.綜合一下看看:三態門實現雙端口。

以上。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM