Thứ Bảy, 22 tháng 7, 2017

[Verilog] Làm thế nào để mô tả mạch tổ hợp bằng ngôn ngữ Verilog

Nội dung bài này hướng dẫn các cách mô tả mạch tổ hợp bằng ngôn ngữ mô tả phần cứng Verilog. Mạch dùng để minh họa là bộ mã hóa ưu tiên 8 bit trong chip MC14532B của hãng ON Semiconductor.

1. Phân tích cấu trúc mạch mã hóa ưu tiên 8 bit của MC14532B

Chip mã hóa ưu tiên 8 bit là một chip số có sơ đồ chân chip và bảng sự thật của chip mã hóa ưu tiên như hình 1.

Hình 1. Sơ đồ chân và bảng sự thật của chip mã hóa ưu tiên 8 bit
Trong đó:
  • Ein (Input Enable) là tín hiệu cho phép các ngõ vào D0 đến D7 hoạt động
    • Ein = 0 thì D0 đến D7 không tác động đến ngõ ra. Tất cả các ngõ ra là 0
    • Ein = 1 thì D0 đến D7 tác động đến ngõ ra với thứ tự ưu tiên từ D7 đến D0
  • GS (Group Select) là ngõ ra sẽ tích cực mức 1 khi Ein=1 và một trong các ngõ vào từ D0 đến D7 bằng 1.
  • Q0 đến Q2 thể hiện giá trị của ngõ vào đang tích cực và có mức ưu tiên cao nhất. Ví dụ: D6=1 và D3=1 thì Q2,Q1,Q0=110 vì D7 có mức ưu tiên cao hơn D3
  • Eout (Output Enable)
    • Eout=1 khi Ein=1 và không có ngõ vào nào từ D0 đến D7 tích cực
    • Eout=0 trong tất cả các trường hợp khác
Hình 2 minh họa dạng sóng khi hoạt động của bộ mã hóa ưu tiên 8 bit MC14532B. Bỏ qua các ký hiệu định thời (timing) trong hình 2, bạn đọc sẽ hình dung rõ về đáp ứng của các ngõ ra theo các giá trị ngõ vào.

Hình 2. Dạng sóng (waveform) của MC14532B
Mạch nguyên lý của bộ mã hóa ưu tiên này có thể được thể hiện bằng nhiều dạng khác nhau. Hình 3 là một dạng mạch nguyên lý cho chức năng của bộ mã hóa ưu tiên 8 bit trong chip MC14532B.

Hình 3. Mạch nguyên lý của MC14532B

Từ bảng sự thật, áp dụng phương pháp tổng các tích SOP (Sum of Product) có thể tìm được biểu thức rút gọn của từng tín hiệu (chân) ngõ ra theo các ngõ vào. SOP là lấy tổng (ký hiệu là "+") của các tổ hợp tích (ký hiệu là ".") ngõ vào. Chú ý, dấu "/" là ký hiệu "bù" hoặc "đảo".

Biểu thức GS:

GS = Ein.D7 + Ein./D7.D6 + Ein./D7./D6.D5 + Ein./D7./D6./D5.D4 + Ein./D7./D6./D5./D4.D3 + Ein./D7./D6./D5./D4./D3.D2 + Ein./D7./D6./D5./D4./D3./D2.D1 + Ein./D7./D6./D5./D4./D3./D2./D1.D0

Đặt Ein làm nhân tử chung và áp dụng quy tắc A +/A.B = A + B, biểu thức GS được rút gọn thành:

GS = Ein.(D7+D6+D5+D4+D3+D2+D1+D0)

Biểu thức Q2:

Q2 = Ein.D7 + Ein./D7.D6 + Ein./D7./D6.D5 + Ein./D7./D6./D5.D4

Rút gọn thành:

Q2 = Ein(D7+D6+D5+D4)

Biểu thức Q1:

Q1 = Ein.D7 + Ein./D7.D6 + Ein./D7./D6./D5./D4.D3 + Ein./D7./D6./D5./D4./D3.D2

Rút gọn thành:

Q1 = Ein(D7+D6+/D5./D4.D3+/D5./D4.D2)

Biểu thức Q0:

Q0 = Ein.D7 + Ein./D7./D6.D5 + Ein./D7./D6./D5./D4.D3 + Ein./D7./D6./D5./D4./D3./D2.D1

Rút gọn thành:
Q0 = Ein.(D7 + /D6.D5 + /D6./D4.D3 + /D6./D4./D2.D1)

Biểu thức Eout:

Eout = Ein./D7./D6./D5./D4./D3./D2./D1./D0

Trong datasheet của MC14532B cũng đưa ra mạch thực tế của chip này như hình 4.
Hình 4. Sơ đồ mạch thực tế của MC14532B
2. Mô tả mạch mã hóa ưu tiên 8 bit bằng Verilog

2.1 Mô tả một module

Tất cả các chức năng của MC14532B như đã trình bày sẽ được mô tả trong một module, hoặc gọi là một block, như sau:

module MC14532B (Ein, D, GS, Q, Eout);
//Input
input   Ein;
input   [7:0] D;
//Output
output       GS;
output [2:0] Q;
output       Eout;
      //Output Type
//Module body

endmodule

Việc dùng ngôn ngữ Verilog mô tả chức năng của MC14532B và đặt ở phần thân module (module body) sẽ được thực hiện thông qua mạch nguyên lý, biểu thức các ngõ ra và sơ đồ mạch thực tế đã trình bày ở phần trên.

Lưu ý, phần mô tả kiểu dữ liệu ngõ ra (output type) sẽ tùy vào việc sử dụng phát biểu nào để mô tả tín hiệu mà khai báo thích hợp.

2.2 Mô tả thân module theo hình 3

//Output type
wire       GS;
wire [2:0] Q;
wire       Eout;
//Module body
assign GS   = Ein? (|D[7:0]): 0;
assign Eout = Ein & ~|D[7:0];
assign Q[2:0] = Ein? (D[7]? 3'b111
                : (D[6]? 3'b110
: (D[5]? 3'b101
: (D[4]? 3'b100
: (D[3]? 3'b011
: (D[2]? 3'b010
: (D[1]? 3'b001
: 3'b000)))))))
                : 3'b000;
Hoặc như sau (chú ý kiểu dữ liệu của Q[2:0] có thay đổi):

//Output type
wire GS;
reg [2:0] Q;
wire Eout;
//Module body
assign GS = Ein? (|D[7:0]): 0;
assign Eout = Ein & ~|D[7:0];
always @ (*) begin
if (Ein) begin
casez (D[7:0])
8'b1???????: Q[2:0] = 3'b111;
8'b01??????: Q[2:0] = 3'b110;
8'b001?????: Q[2:0] = 3'b101;
8'b0001????: Q[2:0] = 3'b100;
8'b00001???: Q[2:0] = 3'b011;
8'b000001??: Q[2:0] = 3'b010;
8'b0000001?: Q[2:0] = 3'b001;
default: Q[2:0] = 3'b000;
endcase
end
else begin
Q[2:0] = 3'b000;
end 
end
2.2 Mô tả thân module theo các biểu thức ngõ ra

//Output type
wire       GS;
wire [2:0] Q;
wire       Eout;
//Module body
assign GS   = Ein & (|D[7:0]);
assign Q[2] = Ein & (|D[7:4]);
assign Q[1] = Ein & (|D[7:6] | (~D[5] & ~D[4] & D[3]) | (~D[5] & ~D[4] & D[2]));
assign Q[0] = Ein & (D[7] | (~D[6] & D[5]) | (~D[6] & ~D[4] & D[3]) | (~D[6] & ~D[4] & ~D[2] & D[1]));
assign Eout = Ein & ~D[7] & ~D[6] & ~D[5] & ~D[4] & ~D[3] & ~D[2] & ~D[1] & ~D[0];
2.3 Mô tả thân module như mạch hình 4

(Phần này dành cho bạn đọc tự thực hiện)

2.4 Sự tương ứng giữa RTL code và mạch nguyên lý

Các hình sau đây minh họa sự tương ứng giữa RTL code và mạch nguyên lý. Nó sẽ giúp bạn hình dung ra mỗi dòng RTL code sẽ tương đương việc mô tả phần mạch nào. Mục này tôi chỉ minh họa cho hình 3.







2.5 Nhận xét

Tất cả các cách mô tả theo mạch nguyên lý hình 3, biểu thức các ngõ ra hay mạch hình 4 đều thực hiện được đúng chức năng của bộ mã hóa ưu tiên 8 bit như mong muốn. Việc lựa chọn cách mô tả nào cho đơn giản và dễ thực hiện là tùy bạn quyết định.


0 bình luận:

Đăng nhận xét