Menu
CoddyTech

Cổng đầu vào và đầu ra

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 31 trên 90.

Các cổng đầu vào và đầu ra là những kết nối giúp một module giao tiếp với thế giới bên ngoài. Chúng giống như các chân trên một chip. Các cổng là giao diện giữa một module và phần còn lại của thiết kế.

Mỗi module có:

  • Cổng đầu vào: tín hiệu đi vào module
  • Cổng đầu ra: tín hiệu đi ra khỏi module

Cổng đầu vào

Cổng đầu vào nhận dữ liệu từ bên ngoài. Bạn không thể thay đổi chúng bên trong module, chỉ có thể đọc.

input clk;        // Đầu vào 1 bit
input [7:0] data; // Vectơ đầu vào 8 bit
input a, b;       // Nhiều đầu vào trên cùng một dòng

Quy tắc cho đầu vào:

  • Không thể gán giá trị bên trong module
  • Không thể khai báo là reg
  • Luôn là wire (theo mặc định)

Cổng đầu ra

Cổng đầu ra gửi dữ liệu ra bên ngoài. Bạn có thể điều khiển chúng bằng khối assign hoặc always.

output out;           // Đầu ra 1 bit
output [3:0] result;  // Đầu ra 4 bit
output reg busy;      // Đầu ra có thể là reg
output wire ready;    // Đầu ra có thể là wire

Quy tắc cho đầu ra:

  • Có thể là wire (với assign) hoặc reg (với always)
  • Phải được điều khiển bởi thứ gì đó bên trong module

Cú pháp khai báo cổng

Cú pháp khai báo cổng là cách cụ thể để viết các cổng đầu vào và đầu ra trong một module. Cú pháp này cho Verilog biết ba điều về mỗi cổng:

  1. Hướng: đây là đầu vào, đầu ra hay cả hai?
  2. Kích thước: nó rộng bao nhiêu bit?
  3. Tên: nó có tên là gì?
module example (
  input [7:0] data_in,    // Vectơ đầu vào
  input clk,              // Đầu vào đơn
  input enable,           // Đầu vào đơn
  output reg [7:0] out,   // Đầu ra kiểu reg
  output busy             // Đầu ra kiểu wire
);

Tại sao hướng của cổng lại quan trọng

Hướng cho Verilog biết:

  • Những tín hiệu nào mà mô-đun có thể đọc (đầu vào)
  • Những tín hiệu nào mà mô-đun có thể ghi (đầu ra)
  • Những kiểu kết nối nào được phép

Dùng sai hướng sẽ gây lỗi biên dịch.

Ví dụ về code

module port_demo (
  input [3:0] a,        // Chỉ có thể đọc
  input [3:0] b,        // Chỉ có thể đọc
  output reg [3:0] sum, // Có thể ghi (reg)
  output [3:0] diff     // Có thể ghi (wire)
);
  always @(*) begin
    sum = a + b;        // Ghi vào đầu ra reg
  end
  
  assign diff = a - b;   // Ghi vào đầu ra wire
endmodule
challenge icon

Thử thách

Hoàn thành khai báo cổng

Cần làm:

  1. Thêm một đầu vào 8 bit có tên data_in
  2. Thêm một đầu vào 1 bit có tên clk
  3. Thêm một đầu ra 4 bit có tên result (dùng reg: sẽ được gán trong khối always)
  4. Thêm một đầu ra 1 bit có tên valid (dùng wire: sẽ được gán bằng assign)

Tự làm thử

module port_challenge (
  // Nhiệm vụ 1: Thêm đầu vào 8 bit tên là data_in
  
  
  // Nhiệm vụ 2: Thêm đầu vào 1 bit tên là clk
  
  
  // Nhiệm vụ 3: Thêm đầu ra 4 bit tên là result (dùng reg)
  
  
  // Nhiệm vụ 4: Thêm đầu ra 1 bit tên là valid (dùng wire)
  
  
);

  reg [3:0] counter;
  
  always @(posedge clk) begin
    counter <= counter + 1;
    result <= counter;
  end
  
  assign valid = (counter > 8);
  
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