Menu
CoddyTech

Thiết kế bộ phát

Thuộc phần Kiến thức nền tảng trong hành trình Verilog của Coddy. Bài học 89 trên 90.

challenge icon

Thử thách

Trong bài học này, bạn sẽ hoàn thiện bộ phát UART bằng cách thêm thanh ghi dịch để gửi bất kỳ byte nào, không chỉ chữ cái cố định 'A'.

Thanh ghi dịch nạp toàn bộ khung (bit dừng + 8 bit dữ liệu + bit bắt đầu), rồi dịch từng bit ra ngoài.

Định dạng khung

Dừng (1)Dữ liệu (8 bit)Bắt đầu (0)
1data_in0

Ví dụ, nếu data_in = 8'b01000001 (chữ cái 'A'), thanh ghi dịch sẽ có giá trị: 1 01000001 0

Nhiệm vụ của bạn

Bạn được cung cấp máy trạng thái từ bài học trước (truyền byte cố định). Bạn cần sửa đổi máy trạng thái để gửi bất kỳ byte nào từ đầu vào data_in.

Cần làm:

  1. Thêm một input [7:0] có tên data_in vào danh sách cổng (bên trong dấu ngoặc đơn)
  2. Thêm một reg 10 bit có tên shift_reg bên ngoài dấu ngoặc đơn (bên trong thân module, vì đây là tín hiệu nội bộ)
  3. Khi cnt == 0 và start == 1:
    1. Nạp shift_reg với {1'b1, data_in, 1'b0}
  4. Khi cnt nằm trong khoảng từ 1 đến 8:
    1. Gửi tx <= shift_reg[0]
    2. Dịch phải: shift_reg <= shift_reg >> 1
  5. Khi cnt == 9:
    1. Gửi tx <= shift_reg[0]
    2. Dịch phải: shift_reg <= shift_reg >> 1

Tự làm thử

module uart_tx (
  input clk,
  input start,           // NEW: tín hiệu start để bắt đầu truyền
  output reg tx,         // NEW: đường truyền đầu ra nối tiếp
  output reg [3:0] cnt   // Giữ làm output để kiểm thử
);

  initial begin
    cnt = 0;
    tx = 1;              // NEW: đặt tx ở mức cao (trạng thái chờ)
  end

  always @(posedge clk) begin
    // NEW: logic bộ đếm với điều kiện start
    if (cnt == 0 && start) begin   // NEW: bắt đầu truyền
      cnt <= 1;
    end
    else if (cnt > 0 && cnt < 9) begin   // NEW: đếm trong khi truyền
      cnt <= cnt + 1;
    end
    else if (cnt == 9) begin      // NEW: đặt lại bộ đếm sau bit cuối
      cnt <= 0;
    end
  end

endmodule

Tất cả bài học trong Kiến thức nền tảng

Tự luyện tập: Trình biên dịch Verilog online