- vừa được xem lúc

Bài 4: Các lỗi thường gặp trong thiết kế Verilog – và cách tránh chúng

0 0 4

Người đăng: Yuri

Theo Viblo Asia

"Một dòng Verilog có thể sinh ra cả một mạch sai nếu bạn không hiểu bản chất phần cứng." Trong bài viết này, ta cùng mổ xẻ những lỗi kinh điển, khó debug nhưng rất phổ biến trong thiết kế Verilog – và cách phòng tránh để tiết kiệm hàng giờ gỡ bug!

I. Gán giá trị sai trong always block – wire hay reg?

❌ Lỗi:

always @(posedge clk) begin y = a + b; // Sai: y không phải reg
end

✅ Cách đúng:

reg [7:0] y; always @(posedge clk) begin y <= a + b; // Dùng <= cho logic tuần tự
end

💡 Ghi nhớ:

  • Dùng reg khi gán trong always
  • Dùng <= (non-blocking assignment) khi mô tả logic có clock

II. Quên default assignment trong block combinational

❌ Lỗi:

always @(*) begin if (sel == 1) y = a; // Không có else -> latch
end

✅ Cách đúng:

always @(*) begin y = 0; // Default if (sel == 1) y = a;
end

🧠 Vì sao?

Nếu không gán giá trị mặc định, trình tổng hợp sẽ hiểu bạn muốn giữ lại giá trị trước đó → Latch không mong muốn → khó timing closure, không đồng bộ hóa được.

III. Gán giá trị tuần tự bằng = (blocking) thay vì <= (non-blocking)

❌ Lỗi:

always @(posedge clk) begin a = b; b = a + 1; // Cả 2 gán cùng lúc → lỗi logic
end

✅ Cách đúng:

always @(posedge clk) begin a <= b; b <= a + 1;
end

🧠 Vì sao?

  • = sẽ thực thi tuần tự như code C.
  • Nhưng phần cứng đồng bộ, mọi flip-flop cập nhật cùng lúc, nên phải dùng <= để mô tả đúng hành vi phần cứng.

IV. Clock domain crossing (CDC) mà không đồng bộ

❌ Lỗi:

// Tín hiệu từ clk_a qua clk_b
// Không xử lý gì → glitch, metastability

✅ Cách đúng:

reg sync1, sync2; always @(posedge clk_b) begin sync1 <= signal_from_clk_a; sync2 <= sync1;
end

💡 Mẹo:

  • Sử dụng 2-3 stage synchronizer để tránh metastability khi tín hiệu đi qua vùng clock khác.
  • Nếu truyền nhiều bit: dùng FIFO có CDC built-in (dual clock FIFO).

V. Quên reset hoặc reset không rõ ràng

❌ Lỗi:

always @(posedge clk) begin count <= count + 1; // Không reset → không xác định giá trị ban đầu
end

✅ Cách đúng:

always @(posedge clk or posedge rst) begin if (rst) count <= 0; else count <= count + 1;
end

🎯 Gợi ý:

  • Luôn xác định giá trị khởi tạo rõ ràng cho các thanh ghi quan trọng.
  • Với reset đồng bộ/asynchronous → tuân thủ hướng dẫn của công cụ tổng hợp.

VI. Dùng biến chưa khai báo hoặc không kết nối

❌ Lỗi:

assign y = x + z; // z chưa khai báo → silent fail hoặc gán mặc định

✅ Cách tránh:

  • Luôn bật strict compile flag của trình tổng hợp (Vivado, ModelSim)
  • Dùng lint tool như Verilator, iverilog -Wall để bắt lỗi sớm.

VII. Viết if, case không đầy đủ

❌ Lỗi:

always @(*) begin case (sel) 2'b00: y = a; 2'b01: y = b; // thiếu default → latch endcase
end

✅ Cách đúng:

always @(*) begin case (sel) 2'b00: y = a; 2'b01: y = b; default: y = 8'hxx; // Hoặc giá trị hợp lệ endcase
end

VIII. Tổng kết: Những bài học xương máu từ thực chiến Verilog

Thiết kế phần cứng số với Verilog đòi hỏi hiểu đúng bản chất phần cứng – vì chỉ một lỗi nhỏ như quên reset, thiếu default trong block tổ hợp hay dùng sai toán tử gán cũng có thể gây ra hậu quả nghiêm trọng: từ sinh latch, sai chức năng, đến lỗi metastability khó debug. Người mới thường mắc các lỗi như dùng sai kiểu reg/wire, không đồng bộ khi chuyển clock domain, hoặc bỏ sót nhánh trong case.

Cách tốt nhất để tránh các lỗi này là luyện tập mô phỏng kỹ, bật các cảnh báo tổng hợp, dùng công cụ lint như Verilator, và luôn viết code dựa trên mô hình mạch rõ ràng thay vì dịch từ tư duy phần mềm. Khi nắm được các nguyên tắc này, bạn sẽ viết Verilog chắc tay hơn và tự tin bước vào các dự án FPGA thực tế.

🎯 Bài tới: Thực chiến thiết kế FPGA – Bộ đếm, UART, và IP đơn giản

Bạn đã biết tránh sai, giờ là lúc viết những module thực tế – Bài 5 mình sẽ hướng dẫn các bạn thiết kế bộ đếm, UART truyền nhận cơ bản, và tái sử dụng IP hiệu quả.

Hẹn gặp lại!

Bình luận

Bài viết tương tự

- vừa được xem lúc

Một phím một chuột và 2 máy tính

Một phím một chuột và 2 máy tính. Khác với các công ty startup, ở các công ty lớn hơn, thì đa phần vì policy của công ty nên máy tính do công ty cấp đều cài sẵn các phần mềm theo dõi hoặc kiểm soát in

0 0 35

- vừa được xem lúc

Keyboard from Scratch: Từ A tới Z

Keyboard from Scratch: Từ A tới Z. Sau khi kết thúc hai phần trước, chúng ta đã có những kiến thức cơ bản về chiếc bàn phím cơ, không để các bạn đợi lâu, ở phần này chúng ta sẽ thực sự bắt tay vào làm

0 0 42

- vừa được xem lúc

Keyboard from Scratch: Debounce

Keyboard from Scratch: Debounce. Bạn đang xem phần hai của một sê ri nhiều phần, nhiều chừng nào, nhiều đến khi nào, thì chưa biết được. . .

0 0 45

- vừa được xem lúc

Keyboard from Scratch: Prototype

Keyboard from Scratch: Prototype. Là một lập trình viên, bàn phím là một vật dụng bạn phải sờ vào hằng ngày, thậm chí số lần bạn sờ nó còn nhiều hơn số lần bạn sờ vào vợ hoặc bạn gái.

0 0 39

- vừa được xem lúc

Chuyện biểu diễn ma trận trên máy tính

Chuyện biểu diễn ma trận trên máy tính. Cách đây mấy hôm mình có share cái screenshot trên Facebook, khoe linh tinh vụ mình đang viết lại cái CHIP-8 emulator bằng Rust.

0 0 45

- vừa được xem lúc

[Reading] Engineer's Mini-Notebook: Communications Projects

[Reading] Engineer's Mini-Notebook: Communications Projects. Đây là một quyển trong bộ sách Engineer's Mini-Notebook được phát hành năm 1987 bởi Radio Shack, một thương hiệu bán đồ linh kiện điện tử k

0 0 29