Module là một cấu trúc cơ bản của ngôn ngữ verilog. Mọi thành phần trong verilog đều chứa trong module. Một module có khả năng giao tiếp với các module khác thông qua các port. Cấu trúc bên trong của module này không thể truy suất từ các module khác, đây là một tính chất rất linh hoạt của verilog giúp người thiết kế có thể thay đổi cấu trúc bên trong của module mà không làm ảnh hưởng đến các thiết kế khác.
Cấu trúc của một module trong verilog như hình 6.3.
Hình 6.3 – Cấu trúc module trong verilog
Định nghĩa một module bắt đầu bằng từ khóa module và phải kết thúc bằng từ khóaendmodule. Mỗi module phải có tên riêng đại diện cho module
đó, khai báo các port (nếu có), tùy chọn khai báo các thông số (parameter) phải đặt ở đầu module. Port list và port chỉ có khi module có bất kì cổng giao tiếp với môi trường bên ngoài. Có năm thành phần bên trong module là: khai
báo biến, các câu lệnh mức dataflow, tạo các module thấp hơn, khối lệnh hành vi, và nhiệm vụ - chức năng của module. Các thành phần có thể đặt bất kỳ đâu, bất kỳ vị trì nào bên trong module. Verilog cho phép ghép nhiều module được định nghĩa trong cùng một file. Các module có thể được định nghĩa tại bất kì vị trí nào của file.
b.Port :
Port cung cấp giao diện, qua đó module có thể truyền thông với môi trường bên ngoài. Các thành phần bên trong module không nhìn thấy được từ môi trường bên ngoài. Sự thay đổi các thành phần bên trong không ảnh hưởng đến môi trường bên ngoài, miễn là giao diện không bị thay đổi. Điều này cung cấp tính linh hoạt mạnh cho người thiết kế.
Danh sách các port là tùy chọn, và được khai báo khi định nghĩa module. Nếu module không trao đổi bất kỳ tín hiệu nào với bên ngoài, thì ta không cần danh sách các port.
Tất cả các port trong danh sách port đều phải được khai báo trong module, mỗi port trong khai báo có thể thuộc một trong ba dạng sau:
Từ khóa Loại port
input Port ngõ vào output Port ngõ ra
inout Port hai chiều (vào/ra)
Lưu ý là các port input và inout thường được khai báo dưới dạng wire, nếu portoutput lưu trữ giá trị của port thì phải được khai báo dưới dạng reg.
Có nhiều quy luật chi phối các kết nối port khi các module được thể hiện bên trong module khác, Trình mô phỏng sẽ báo lỗi nếu ta vi phạm các quy luật kết nối port. Các quy luật được tóm tắt như sau:
v Input: ở bên trong thì port input luôn luôn có kiểu net, còn bên ngoài port input có thể được kết nối đến một biến kiểu reg hoặc kiểu net.
v Ouput: ở bên trong port output có kiểu reg hoặc kiểu net, còn bên noài port output phải luôn luôn được nối với biến kiểu net và không được nối với biến kiểu reg.
v Inout: ở bên trong port inout phải luôn luôn có kiểu net, còn ở bên ngoài port inout phải luôn luôn được nối với kiểu net.
v Tương thích độ rộng: việc nối các mục bên trong và bên ngoài có kích thước khác nhau là hợp lệ khi thực hiện nối port giữa các module, và lúc này sẽ có kèm theo cảnh báo (warning).
v Port không kết nói: verilog cho phép port duy trì không kết nối. Một vài port ngõ ra có thể chỉ đơn thuần dùng để gỡ rối.
Để kết nối đến tín hiệu bên ngoài, thì verilog hỗ trợ hai phương pháp thực hiện kết nối giữa các tín hiệu được chỉ rõ trong thể hiện module và các port trong định nghĩa module. Hai phương pháp này không được trộn lẫn với nhau.
v Kết nối theo danh sách thứ tự: kết kết nối này cho thấy sự tương tác 1–1 rất trực quan. Cụ thể, tín hiệu trong module chính phải truyền vào module con theo đúng thứ tự các port đã được module con định nghĩa sẵn.
Ví dụ:
module Top;
//Declare connection variables reg [3:0]A,B;
reg C_IN;
wire [3:0] SUM; wire C_OUT;
//Instantiate fulladd4, call it fa_ordered.
//Signals are connected to ports in order (by position) fulladd4 fa_ordered(SUM, C_OUT, A, B, C_IN);
... <stimulus>
... Endmodule
v Kết nối theo tên: các tín hiệu của module chính truyền vào module con không cần đúng thứ tự, mà phải phù hợp với tên. Đây là ưu điểm
của verilog, bởi vì danh sách các port có thể rất dài, khi đó việc kết nối theo vị trí rất dễ bị lỗi.
Ví dụ:
// kết nối đến module con theo tên
fulladd4 fa_byname(.c_out(C_OUT), .sum(SUM), .b(B), .c_in(C_IN), .a(A),);
// Các port không sử dụng có thể bỏ qua, không cần viết tên vào
fulladd4 fa_byname(.sum(SUM), .b(B), .c_in(C_IN), .a(A),);
4.3.5. Điều khiển động cơ thuận nghịchLoại cổng AND/OR: