Tiếp nội dung phần 1 , Giáo trình Ngôn ngữ mô tả phần cứng Verilog: Phần 2 cung cấp cho người học những kiến thức như: Cấu trúc phân cấp và module; Mô hình thiết kế cấu trúc (Structural model); Mô hình thiết kế hành vi (Behavioral model); Tác vụ (task) và hàm (function). Mời các bạn cùng tham khảo!
Chương Cấu trúc phân cấp module Chương Cấu trúc phân cấp module 5.1 Cấu trúc phân cấp Ngôn ngữ mô tả phần cứng Verilog hỗ trợ cấu trúc phân cấp cách cho phép modules nhúng modules khác Modules cấp độ cao tạo thể module cấp độ thấp giao tiếp với chúng thông qua đầu vào, đầu đầu vào chiều Các cổng vào vơ hướng vector Cấu trúc phân cấp giúp người thiết kế chia hệ thống thiết kế thành module nhỏ để dễ thiết kế kiểm soát luồng liệu trình thiết kế Như ví dụ cho hệ thống module phân cấp, xem xét hệ thống bao gồm bảng mạch in (PCBs) 5.2 Module 5.2.1 Khai báo module Trong mục cung cấp cú pháp thông thường cho định nghĩa module cú pháp cho việc cài đặt module, với ví dụ định nghĩa module cài đặt module Một định nghĩa module bao hai từ khóa module endmodule Các định danh kèm theo sau từ khóa module tên định nghĩa module Danh sách tùy chọn tham số định nghĩa rõ danh sách theo thứ tự tham số module Danh sách tùy chọn cổng khai báo cổng định nghĩa rõ danh sách theo thứ tự cổng module Thứ tự sử dụng định nghĩa danh sách tham số module-parameter-port-list 112 Chương Cấu trúc phân cấp module danh sách cổng có ý nghĩa việc cài đặt module Các định danh danh sách khai báo lại câu lệnh input, output, inout định nghĩa module Khai báo cổng danh sách khai báo cổng không khai báo lại thân module Các mục module định nghĩa tạo thành module, chúng bao gồm nhiều loại khai báo định nghĩa khác nhau, nhiều số giới thiệu Từ khóa macromodule dùng để thay từ khóa module để định nghĩa module Một q trình thực thi chọn để giải module định nghĩa bắt đầu với thừ khóa macromodule khác Cú pháp 5-1 module_declaration ::= {attribute_instance} module_keyword module_identifier [ module_parameter_port_list ] list_of_ports ; { module_item } endmodule |{ attribute_instance } module_keyword module_identifier [ module_parameter_port_list ] [ list_of_port_declarations ] ; { non_port_module_item } endmodule module_keyword ::= module | macromodule module_parameter_port_list ::= (From A.1.3 # ( parameter_declaration { , parameter_declaration } ) list_of_ports ::= ( port { , port } ) list_of_port_declarations ::= ( port_declaration { , port_declaration } ) | ( ) port ::= [ port_expression ] | port_identifier ( [ port_expression ] ) port_expression ::= port_reference | { port_reference { , port_reference } } port_reference ::= port_identifier [ [ constant_range_expression ] ] port_declaration ::= {attribute_instance} inout_declaration | {attribute_instance} input_declaration | {attribute_instance} output_declaration module_item ::= (From A.1.4) port_declaration ; | non_port_module_item module_or_generate_item ::= { attribute_instance } module_or_generate_item_declaration | { attribute_instance } local_parameter_declaration ; 113 Chương Cấu trúc phân cấp module | { attribute_instance } parameter_override | { attribute_instance } continuous_assign | { attribute_instance } gate_instantiation | { attribute_instance } udp_instantiation | { attribute_instance } module_instantiation | { attribute_instance } initial_construct | { attribute_instance } always_construct | { attribute_instance } loop_generate_construct | { attribute_instance } conditional_generate_construct module_or_generate_item_declaration ::= net_declaration | reg_declaration | integer_declaration | real_declaration | time_declaration | realtime_declaration | event_declaration | genvar_declaration | task_declaration | function_declaration non_port_module_item ::= module_or_generate_item |generate_region | specify_block | { attribute_instance } parameter_declaration ; | { attribute_instance } specparam_declaration parameter_override ::= defparam list_of_defparam_assignments ; Ví dụ 5.1 Định dạng module chuẩn module tên_module (danh sách cổng, có); Khai báo port input, output, inout; Khai báo tham số Khai báo loại liệu (dữ liệu net, liệu biến, ví dụ: wire, reg, integer) Gọi gán đặc tính (instantiate) module (sub-module) Phát biểu gán sử dụng mơ hình RTL (assign) Phát biểu gán qui trình (always, initial) 114 Chương Cấu trúc phân cấp module Khai báo hàm tác vụ Khai báo kết thúc module (endmodule) 5.2.2 Module mức cao Module mức cao (top-module) module mà bao gồm văn gốc, khơng có câu lệnh cài đặt module khác Điều áp dụng module cài đặt tạo khối tạo mà khơng phải tự cài đặt Một mơ hình phải có module mức cao 5.2.3 Gọi gán đặc tính module (instantiate) Việc gọi gán đặc tính module cho phép module gọi gán đặc tính module khác để sử dụng Các module không định nghĩa lồng Nói cách khác, module định nghĩa không chứa mô tả thiết kế module khác cặp từ khóa module endmodule Một module định nghĩa lồng module khác cách gọi gán đặc tính module để sử dụng Một câu lệnh gọi gán đặc tính module tạo nhiều module định nghĩa Ví dụ, module đếm phải cài đặt module D flip-flop để tạo nhiều thể flip-flop Cú pháp 5-2 đưa cú pháp chi tiếc cho việc gọi gán đặc tính module Cú pháp 5-2 module_instantiation ::= (From A.4.1) module_identifier [ parameter_value_assignment ] module_instance { , module_instance } ; parameter_value_assignment ::= # ( list_of_parameter_assignments ) 115 Chương Cấu trúc phân cấp module list_of_parameter_assignments ::= ordered_parameter_assignment { , ordered_parameter_assignment } | named_parameter_assignment { , named_parameter_assignment } ordered_parameter_assignment ::= expression named_parameter_assignment ::= parameter_identifier ( [ mintypmax_expression ] ) module_instance ::= name_of_module_instance ( [ list_of_port_connections ] ) name_of_module_instance ::= module_instance_identifier [ range ] list_of_port_connections ::= ordered_port_connection { , ordered_port_connection } | named_port_connection { , named_port_connection } ordered_port_connection ::= { attribute_instance } [ expression ] named_port_connection ::= { attribute_instance } port_identifier ( [ expression ] ) Việc gọi gán đặc tính module chứa loạt đặc điểm kỹ thuật Nó cho phép mảng thể tạo Cú pháp ngữ nghĩa mảng thể định nghĩa cho cổng cổng áp dụng tốt cho module Một nhiều thể module (bản nguyên module) đưa câu lệnh gọi gán đặc tính module riêng lẻ Danh sách cổng kết nối cung cấp cho module định nghĩa với cổng Các dấu ngoặc đơn luôn cần thiết Khi danh sách cổng kết nối đưa để sử dụng theo thức tự phương thức cổng kết nối, phần tử danh sách kết nối với cổng khai báo cổng module, phần tử thứ kết nối với cổng thứ Phần 5.2.4.9 thảo luận rõ luật kết nối cổng với cổng Một kết nối tham khảo đơn giản tới biến định danh net, biểu thức, khoản trống Một biểu thức sử 116 Chương Cấu trúc phân cấp module dụng để cung cấp giá trị tới cổng vào module Một cổng kết nối trống trình bày tình nơi mà cổng không kết nối Khi kết nối cổng tên, cổng chưa kết nối cách bỏ danh sách khơng cung cấp biểu thức bên đấu ngoặc (ví dụ portname()) Ví dụ 5.2 Ví dụ 1: Ví dụ minh họa mạch ( module cấp độ thấp) điều khiển dạng sóng đơn giản (module cấp độ cao hơn) nơi mà mạch cài đặt bên module dạng sóng: //module cấp độ thấp: module mơ tả mạch flip-flop nand module ffnand (q, qbar, preset, clear); output q, qbar;//khai báo net đầu cho mạch input preset, clear;// khai báo net đầu vào cho mạch // khai báo cổng nand đầu vào kết nối với chúng nand g1 (q, qbar, preset), g2 (qbar, q, clear); endmodule // module cấp độ cao: // dạng sóng mơ tả cho flip-flop nand module ffnand_wave; wire out1, out2;//đầu từ mạch reg in1, in2;//biến để điều khiển mạch parameter d = 10; // thể mạch ffnand, tên "ff", // đặc tả đầu kết nối IO bên ffnand ff(out1, out2, in1, in2); // định nghĩ dạng sóng để mô mạch 117 Chương Cấu trúc phân cấp module initial begin #d in1 = 0; in2 = 1; #d in1 = 1; #d in2 = 0; #d in2 = 1; end endmodule Ví dụ 2: Ví dụ tạo thể module flip-flop ffnand định nghĩa ví dụ Nó kết nối với đầu q vào thể đầu qbar vào thể khác // dạng sóng mơ tả để kiểm tra // nand flip-flop, khơng có cổng đầu module ffnand_wave; reg in1,in2;//biến để điều khiển mạch parameter d=10; // tạo hai mạch ff nand // ff1 có qbar khơng kết nối, ff2 có q khơng kết nối ffnand ff1(out1,,in1,in2), ff2(.qbar(out2), clear(in2), preset(in1), q()); // ff3(.q(out3),.clear(in1),,,); is illegal // định nghĩ dạng sóng để mơ mạch initial begin #din1=0;in2=1; #din1=1; #din2=0; #din2=1; end 118 Chương Cấu trúc phân cấp module endmodule 5.2.4 Khai báo port Cổng cung cấp phương tiện kết nối mô tả phần cứng bao gồm module phần cứng nguyên thủy Ví dụ, module A khởi tạo module B, sử dụng cổng kết nối phù hợp tới module A Tên cổng khác với tên dây nối nội biến định nghĩa module B 5.2.4.1 Định nghĩa port Cú pháp cho cổng danh sách cổng đưa Cú pháp 5-3 Cú pháp 5-3 list_of_ports ::= (From A.1.3) ( port { , port } ) list_of_port_declarations ::= ( port_declaration { , port_declaration } ) |() port ::= [ port_expression ] | port_identifier ( [ port_expression ] ) port_expression ::= port_reference | { port_reference { , port_reference } } port_reference ::= port_identifier [ [ constant_range_expression ] ] port_declaration ::= {attribute_instance} inout_declaration | {attribute_instance} input_declaration | {attribute_instance} output_declaration 119 Chương Cấu trúc phân cấp module 5.2.4.2 Liệt kê port Cổng tham khảo cho cổng danh sách cổng bên khai báo module số: Một định danh đơn giản định danh bị bỏ qua Một bit-select vector khai báo module Một part- select vector khai báo module Một toán tử kết nối phần phần Biểu thức cổng tùy chọn cổng định nghĩa mà khơng cần kết nối module Khi cổng định nghĩa, khơng có cổng khác định nghĩa tên Có hai loại cổng module, loại cổng biểu thức, loại cổng ngầm Loại thứ hai loại cổng trực tiếp Điều rõ ràng chi tiết cổng định danh sử dụng kết nối với cổng module thể tên cổng biểu thức bao gồm khai báo định danh bên module miêu tả phần 5.2.4.3 Tên cổng kết nối không sử dụng cho cổng ngầm định cổng biểu thức không định danh đơn giản định danh bị bỏ qua, mà sử dụng tên cổng 5.2.4.3 Khai báo port Mỗi cổng định danh cổng biểu thức danh sách cổng khai báo module khai báo thân module khai báo: input, output inout (cổng hai chiều).Ở thêm vào khai báo loại liệu khác cho cổng đặt thù – ví dụ reg wire.Cú pháp cho việc khai báo cổng đưa 120 Chương Cấu trúc phân cấp module Cú pháp 5-4: Cú pháp 5-4 inout_declaration ::= inout [ net_type ] [ signed ] [ range ] list_of_port_identifiers input_declaration ::= input [ net_type ] [ signed ] [ range ] list_of_port_identifiers output_declaration ::= output [ net_type ] [ signed ] [ range ] list_of_port_identifiers | output reg [ signed ] [ range ] list_of_variable_port_identifiers | output output_variable_type list_of_variable_port_identifiers list_of_port_identifiers ::= (From A.2.3) port_identifier { , port_identifier } Nếu khai báo cổng bao gồm net loại biến khác, cổng khai báo lại khai báo net biến Nếu net biến khai báo vector, đặc tả phạm vi hai khai báo công phải giống hệt 121 Chương Kiểm tra thiết kế assert_always #( severity_level, property_type, msg, coverage_level ) instance_name ( clk, reset_n, test_expr ) Lệnh liên tục chèn kiểm tra test_expr để chắn ln ln cạnh clock Nếu biểu thức kiểm tra sai, thông điệp tương ứng hiển thị Ví dụ 9.13 module BCD_Counter (input rst, clk, outputreg [3:0] cnt); always @(posedge clk) begin if (rst || cnt >= 10) cnt = 0; else cnt = cnt + 1; end assert_always #(1, 0, “Err: Non BCD Count”, 0) AA1 (clk, 1’b1, (cnt >= 0) && (cnt