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ần | Tá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'b1010 | Nhị phân 4 bit, giá trị 10 |
8'hFF | Thập lục phân 8 bit, giá trị 255 |
8'hff | Giống hệt: chữ số hex không phân biệt hoa thường |
16'd255 | Thập phân 16 bit, giá trị 255 |
3'o7 | Bát phân 3 bit, giá trị 7 |
8'b1010_1100 | Dấu gạch dưới nhóm các chữ số cho dễ đọc |
1'bx | Giá trị bit không xác định (x) |
1'bz | Giá 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 |
&bus | AND rút gọn (AND của tất cả các bit) |
|bus | OR rút gọn (OR của tất cả các bit) |
^bus | XOR 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 ... end | Logic 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 ... end | Chạy một lần tại thời điểm 0 (testbench, chỉ khi mô phỏng) |
begin ... end | Gom nhiều câu lệnh thành một khối |
#10 | Trễ 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ối | Nê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) ... endcase | Rẽ 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ẫu | Cú pháp |
|---|---|
| D flip-flop | always @(posedge clk) q <= d; |
| Thanh ghi có reset | always @(posedge clk) if (rst) q <= 0; else q <= d; |
| Bộ đếm | always @(posedge clk) count <= count + 1; |
| Thanh ghi trạng thái FSM | always @(posedge clk) state <= next_state; |
| Logic trạng thái kế tiếp của FSM | always @(*) 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?
=) 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.