0

Bài 3: Verilog cho người mới – Học bằng ví dụ, không chỉ lý thuyết

"Muốn hiểu Verilog – hãy code nó." Không giống các ngôn ngữ lập trình thông thường, Verilog mô tả phần cứng, không phải thuật toán. Vì vậy, cách học hiệu quả nhất là học thông qua ví dụ trực quan và phân tích tư duy phần cứng đằng sau từng dòng code.

image.png

I. Verilog là gì? Khác gì với C, Python?

So sánh Verilog C/Python
Mục tiêu Mô tả phần cứng Mô tả thuật toán
Kiểu hoạt động Song song (concurrent) Tuần tự (sequential)
Output là gì? Mạch điện (logic gate) Mã máy chạy trên CPU
Debug thế nào? Mô phỏng/tín hiệu Print log, IDE

Khi bạn viết if trong Verilog, bạn đang mô tả mạch so sánh và bộ chọn – chứ không phải lệnh điều kiện tuần tự.

II. Cấu trúc một module Verilog cơ bản

module my_module (
  input clk,
  input rst,
  input [7:0] a,
  output wire [7:0] b
);
  // logic here
endmodule

Giải thích:

  • module: giống như class hoặc hàm – đơn vị thiết kế cơ bản.
  • input, output: chân kết nối (port) với các khối khác.
  • wire, reg: kiểu dữ liệu – có vai trò quan trọng (xem phần dưới).

III. Wire vs Reg – Lỗi kinh điển của người mới

Đặc điểm wire reg
Gán giá trị qua assign (liên tục) trong always block
Dùng cho kết nối combinational lưu trạng thái (flip-flop)

Ví dụ:

assign y = a + b;  // wire

always @(posedge clk) begin
  y <= a + b;      // reg
end

Nếu bạn gán giá trị trong always, thì biến đó phải là kiểu reg.

IV. Các khối cơ bản: combinational và sequential

1. Combinational logic (không có clock):

always @(*) begin
  if (sel == 0)
    y = a;
  else
    y = b;
end

2. Sequential logic (có clock):

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

Ghi nhớ:

  • @(*) → mọi tín hiệu thay đổi sẽ kích hoạt lại block.
  • @(posedge clk) → chỉ khi cạnh lên của clock xảy ra.

V. Viết testbench đơn giản để mô phỏng

module tb_my_module;
  reg clk, rst;
  reg [7:0] a;
  wire [7:0] y;

  my_module uut (
    .clk(clk), .rst(rst), .a(a), .y(y)
  );

  initial begin
    clk = 0;
    forever #5 clk = ~clk;  // Tạo clock 10ns
  end

  initial begin
    rst = 1; a = 0;
    #12 rst = 0;
    #10 a = 5;
    #10 a = 10;
    #50 $finish;
  end
endmodule

Chạy bằng Vivado hoặc ModelSim để kiểm tra dạng sóng.

Đừng bao giờ nạp code chưa mô phỏng lên FPGA!

VI. Một số ví dụ nhỏ để luyện tập

1. Mạch dồn kênh 2:1 (Multiplexer)

assign y = sel ? b : a;

2. Bộ đếm tăng

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

VII. Mẹo học Verilog hiệu quả

  • Luôn viết module nhỏ, dễ test.
  • Tách rõ combinational và sequential.
  • Mô phỏng nhiều – xem waveform thường xuyên.
  • So sánh đầu ra mô phỏng với kỳ vọng.
  • Viết code rõ ràng – đừng tối ưu sớm.

VIII. Tổng kết

Verilog là một ngôn ngữ tuyệt vời – nhưng cần tư duy phần cứng để dùng đúng. Thay vì học lý thuyết khô khan, hãy:

  • Học qua ví dụ cụ thể.
  • Viết testbench để hiểu luồng tín hiệu.
  • Tư duy "mạch điện", không phải "code tuần tự".

Chúc các bạn sớm làm quen với ngôn ngữ này 😄


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí