Menu
CoddyTech

Cheat sheet Verilog

Cập nhật lần cuối

Cấu trúc module và cổng

Module là khối xây dựng cơ bản: có tên và danh sách cổng.

Cú phápÝ nghĩa
module adder(...); ... endmoduleĐịnh nghĩa một module và phần thân của nó
input clk;Một cổng vào
output q;Một cổng ra
output reg q;Cổng ra được gán giá trị từ khối always
input [7:0] data;Bus vào 8 bit (vector)
inout sda;Cổng hai chiều
adder u1 (.a(x), .b(y), .sum(s));Tạo instance của module, nối cổng theo tên

Kiểu dữ liệu

wire mô hình hóa một đường nối; reg giữ giá trị do code thủ tục gán.

Thành phầnTác dụng
wire w;Net được điều khiển bởi assign hoặc cổng ra của module
reg r;Giữ giá trị được gán bên trong khối always/initial
wire [3:0] bus;Vector 4 bit (từ bit 3 xuống bit 0)
reg [7:0] count;Thanh ghi 8 bit
bus[2]Chọn một bit
bus[3:1]Chọn một đoạn bit (part-select)
reg mem [0:255];Bộ nhớ: một mảng các thanh ghi
parameter WIDTH = 8;Hằng số có tên dùng trong module

Hằng số dạng số

Định dạng là <size>'<base><value>: size tính bằng bit, base là b/o/d/h.

Cú phápÝ nghĩa
4'b1010Nhị phân 4 bit, giá trị 10
8'hFFThập lục phân 8 bit, giá trị 255
8'hffGiống hệt: chữ số hex không phân biệt hoa thường
16'd255Thập phân 16 bit, giá trị 255
3'o7Bát phân 3 bit, giá trị 7
8'b1010_1100Dấu gạch dưới nhóm các chữ số cho dễ đọc
1'bxGiá trị bit không xác định (x)
1'bzGiá trị bit trở kháng cao (z)

Toán tử

Toán tử bitwise, logic, so sánh và rút gọn (reduction).

Toán tửTác dụng
& | ^ ~AND, OR, XOR, NOT theo bit
&& || !AND, OR, NOT logic (trả về 1 bit)
== != < > <= >=Toán tử so sánh
<< >>Dịch trái và dịch phải
+ - * / %Toán tử số học
&busAND rút gọn (AND của tất cả các bit)
|busOR rút gọn (OR của tất cả các bit)
^busXOR rút gọn (bit chẵn lẻ của tất cả các bit)
{a, b}Ghép bit; {4{1'b1}} nhân bản thành 4'b1111

Gán liên tục

assign điều khiển một wire liên tục: dùng cho logic tổ hợp.

Cú phápÝ nghĩa
assign y = a & b;Gán cho y kết quả AND của a và b
assign sum = a + b;Tính tổng một cách liên tục
assign y = sel ? a : b;Toán tử ba ngôi: bộ dồn kênh 2 sang 1
assign {c, s} = a + b;Lấy cả bit nhớ (carry) và tổng cùng lúc
assign y = ~en;Điều khiển một wire bằng tín hiệu đảo

Khối thủ tục

always và initial chạy các câu lệnh; danh sách nhạy (sensitivity list) quyết định khi nào chạy.

Cú phápÝ nghĩa
always @(*) begin ... endLogic tổ hợp (chạy khi bất kỳ đầu vào nào thay đổi)
always @(posedge clk)Chạy ở mỗi sườn lên của xung clock (tuần tự)
always @(negedge clk)Chạy ở mỗi sườn xuống của xung clock
always @(posedge clk or posedge rst)Khối theo clock có reset bất đồng bộ
initial begin ... endChạy một lần tại thời điểm 0 (testbench, chỉ khi mô phỏng)
begin ... endGom nhiều câu lệnh thành một khối
#10Trễ 10 đơn vị thời gian (chỉ khi mô phỏng)

Blocking và non-blocking

Dùng = cho logic tổ hợp, <= cho logic tuần tự theo clock.

Cú phápÝ nghĩa
a = b;Blocking: thực thi ngay, theo thứ tự
a <= b;Non-blocking: đọc hết vế phải trước, rồi mới gán
always @(*) y = a & b;Tổ hợp: dùng blocking =
always @(posedge clk) q <= d;Flip-flop: dùng non-blocking <=
Trộn = và <= trong cùng một khốiNên tránh: nguồn gây bug rất phổ biến

Luồng điều khiển

Câu lệnh điều kiện và rẽ nhánh nhiều hướng bên trong khối thủ tục.

Cú phápÝ nghĩa
if (cond) ... else ...Câu lệnh điều kiện
if (a) x = 1; else x = 0;If/else trên một dòng
case (sel) ... endcaseRẽ nhánh nhiều hướng theo một giá trị
2'b00: y = a;Một nhánh case
default: y = 0;Nhánh case mặc định
for (i = 0; i < 8; i = i + 1)Vòng lặp (thường nằm trong generate hoặc khi mô phỏng)
repeat (4) @(posedge clk);Lặp lại một câu lệnh N lần

Mẫu thường gặp

Những khối bạn viết đi viết lại, cùng các task dùng trong testbench.

MẫuCú pháp
D flip-flopalways @(posedge clk) q <= d;
Thanh ghi có resetalways @(posedge clk) if (rst) q <= 0; else q <= d;
Bộ đếmalways @(posedge clk) count <= count + 1;
Thanh ghi trạng thái FSMalways @(posedge clk) state <= next_state;
Logic trạng thái kế tiếp của FSMalways @(*) case (state) ... endcase
In ra một giá trị$display("q = %b", q);
In ra khi giá trị thay đổi$monitor("t=%0t q=%b", $time, q);
Kết thúc mô phỏng$finish;

Mọi cú pháp Verilog bạn hay dùng, gói gọn trong một trang. Cheat sheet Verilog này là bảng tra cứu nhanh cho ngôn ngữ mô tả phần cứng (HDL): khai báo module và cổng, chọn kiểu dữ liệu, viết logic tổ hợp và logic tuần tự, cùng các mẫu khối always dùng để mô tả mạch thật.

Cú pháp ở đây là Verilog chuẩn (IEEE 1364) và chạy được trên các trình mô phỏng phổ biến như Icarus Verilog và Verilator. Sao chép phần bạn cần, hoặc thử ngay trong Playground Verilog: viết một module, mô phỏng và xem đầu ra ngay trên trình duyệt.

Câu hỏi thường gặp về cheat sheet Verilog

Cheat sheet Verilog này có miễn phí không?

Có. Cheat sheet Verilog này hoàn toàn miễn phí, không cần đăng ký. Lưu lại trang này và quay lại bất cứ khi nào bạn cần tra cú pháp, toán tử hay một mẫu khối always.

wire và reg khác nhau thế nào?
wire mô hình hóa một đường nối vật lý và phải được điều khiển liên tục, bởi câu lệnh assign hoặc cổng ra của một module, nên bạn dùng nó cho các net tổ hợp. reg giữ giá trị cho đến khi code thủ tục thay đổi nó, nên bạn dùng nó cho mọi thứ được gán bên trong khối always hoặc initial. Dù tên là vậy, reg không phải lúc nào cũng trở thành một thanh ghi phần cứng; nó chỉ có nghĩa là giá trị được gán theo kiểu thủ tục.
Gán blocking và gán non-blocking khác nhau thế nào?
Phép gán blocking (=) thực thi ngay và theo thứ tự, giống một câu lệnh lập trình bình thường, nên hãy dùng nó cho logic tổ hợp trong khối always @(*). Phép gán non-blocking (<=) tính tất cả vế phải trước rồi mới cập nhật đồng thời các vế trái, nhờ vậy mô hình hóa flip-flop chính xác. Vì thế hãy dùng nó trong khối theo clock always @(posedge clk). Trộn hai kiểu gán trong cùng một khối là nguồn gây bug mô phỏng kinh điển.
Có thể luyện tập Verilog online không?

Có. Mở Playground Verilog để viết một module, mô phỏng và xem đầu ra ngay trên trình duyệt, không cần cài đặt gì. Khi muốn học có lộ trình, khóa học Verilog tương tác miễn phí của Coddy đưa bạn đi từng bước, từ module và kiểu dữ liệu đến khối always và máy trạng thái hữu hạn (FSM).

Cheat sheet này có phù hợp cho người mới bắt đầu không?

Có. Nội dung được sắp xếp từ phần nền tảng (module, cổng và kiểu dữ liệu) đến logic tuần tự và các mẫu FSM, nên bạn có thể bắt đầu từ các phần đầu rồi dần dần mô tả được những mạch thật.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học Verilog cùng Coddy

Bắt đầu