Menu
CoddyTech

Cổng vào ra hai chiều

Thuộc phần Kiến thức nền tảng trong hành trình Verilog của Coddy. Bài học 32 trên 90.

Cổng inout là cổng hai chiều có thể vừa gửi vừa nhận tín hiệu. Cổng này có thể đóng vai trò đầu vào hoặc đầu ra vào những thời điểm khác nhau. Hầu hết các cổng đều là input (dữ liệu đi vào) hoặc output (dữ liệu đi ra). Cổng inout có thể làm cả hai. Cổng này có thể xuất dữ liệu hoặc nhận dữ liệu, tùy tình huống.

Hãy nghĩ về nó như một con đường hai chiều thay vì đường một chiều.

Các cổng vào/ra được dùng cho:

  • Các bus dùng chung: nhiều thiết bị kết nối với cùng một nhóm dây
  • Các bus dữ liệu bộ nhớ: dữ liệu có thể được đọc hoặc ghi
  • Giao tiếp hai chiều: I2C, SPI, v.v.

Mỗi lần chỉ có một thiết bị điều khiển bus. Các thiết bị khác phải ở trạng thái trở kháng cao (Z).

Khai báo cổng vào ra hai chiều

inout [7:0] data_bus;   // Bus hai chiều 8 bit
inout ready;             // Tín hiệu hai chiều 1 bit

Cách Inout hoạt động

Một cổng inout cần tín hiệu điều khiển (control signal) để xác định nó đang hoạt động như đầu vào hay đầu ra:

module bidir (
  inout [7:0] bus,
  input [7:0] data_out,
  input enable,
  output [7:0] data_in
);
  
  assign bus = (enable) ? data_out : 8'bZ;  // Drive bus when enabled, else Z
  assign data_in = bus;                     // Always read the bus
  
endmodule
  • Khi enable = 1, module điều khiển bus (chế độ đầu ra)
  • Khi enable = 0, module nhả bus (chế độ đầu vào, high-Z)

Các quy tắc quan trọng về Inout

Quy tắcLý do
Phải khai báo là wireKhông thể là reg
Không được để nhiều thiết bị điều khiển bus cùng lúcCác tín hiệu điều khiển xung đột sẽ tạo ra X
Dùng Z để nhả busCho phép thiết bị khác điều khiển bus
Mỗi lần chỉ một thiết bị điều khiển busNgăn bus bị tranh chấp

Inout so với input và output

Loại cổngHướngCó thể điều khiểnCó thể đọc
inputMột chiều (chỉ vào)KhôngCó
outputMột chiều (chỉ ra)CóCó (giá trị mà nó điều khiển)
inoutHai chiều (cả hai)Có (khi được bật)Có (luôn luôn)

Lỗi thường gặp

// SAI: Không thể gán giá trị cho inout trong khối always
always @(posedge clk) begin
  data_bus <= something;   // Lỗi! Dùng assign với điều kiện
end

// ĐÚNG: Dùng assign với điều kiện enable
assign data_bus = (enable) ? something : 8'bZ;
challenge icon

Thử thách

Thêm cổng inout còn thiếu và các câu lệnh assign để bộ đệm hai chiều này hoạt động.

Cần làm:

  1. Thêm cổng inout 8 bit có tên io_bus
  2. Thêm câu lệnh assign để đưa send_value vào io_bus khi send_enable là 1, nếu không thì đưa Z
  3. Thêm câu lệnh assign để đọc io_bus vào receive_value

Tự làm thử

module bidir_buffer (
  // Nhiệm vụ 1: Thêm cổng inout 8 bit tên io_bus vào đây
  
  
  input [7:0] send_value,
  input send_enable,
  output [7:0] receive_value
);

  // Nhiệm vụ 2: Thêm câu lệnh assign để đưa send_value lên io_bus khi send_enable bằng 1, nếu không thì đưa Z
  
  
  // Nhiệm vụ 3: Thêm câu lệnh assign để đọc io_bus vào receive_value
  

endmodule
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Kiến thức nền tảng

Tự luyện tập: Trình biên dịch Verilog online