• Integrated Circuit Design - Chia sẻ kiến thức về vi mạch

    Vi mạch và Ứng dụng

  • Integrated Circuit Design - Chia sẻ kiến thức về vi mạch

    Vi mạch và Ứng dụng

  • Integrated Circuit Design - Chia sẻ kiến thức về vi mạch

    Vi mạch và Ứng dụng

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.


Thứ Sáu, 21 tháng 7, 2017

[Basic Knowledge] Khái niệm cơ bản về vi mạch và phân loại


1. Vi mạch là gì?

Mạch tích hợp (Integrated circuit), viết tắt là IC, còn được gọi là vi mạch hoặc chip là những linh kiện điện tử có lõi làm bằng vật liệu bán dẫn. Vật liệu bán dẫn có rất nhiều loại nhưng phổ biến là Silicon (Si) và Germanium (Ge). Hiểu đơn giản, vi mạch là mạch điện tử rất nhỏ được đóng gói thành một linh kiện hoàn chỉnh. 

Hình 1. Vi mạch là mạch điện tử rất nhỏ được đóng gói thành một linh kiện hoàn chỉnh

Cấu tạo cơ bản của một vi mạch (chip) gồm có vỏ chip (cover), lõi (core) và chân (pin).

Hình 2. Cấu tạo cơ bản của vi mạch
Lõi (CORE hoặc DIE) vi mạch là mạch điện gồm các thành phần thụ động hoặc tích cực hoặc cả hai. Các thành phần thụ động gồm có điện trở, tụ điện, cuộn cảm. Các thành phần tích cực gồm có diodes, transistor, NMOS, PMOS,... Cụm từ "thiết kế vi mạch" được ngầm hiểu là thiết kế phần lõi vi mạch thông qua các công cụ phần mềm chuyên dụng. Việc chế tạo phần lõi và sản xuất ra chip thuộc về nhà máy chế tạo chip.

Chân chip (PIN hoặc LEAD) là vật liệu dẫn điện được kết nối đến lõi thông qua các dây dẫn điện, gọi là BOND WIRE. Các dây này thường làm bằng vàng.

Vỏ là thành phần bao bọc và cố định lõi, dây dẫn và các chân, được làm bằng vật liệu cách điện như nhựa, gốm, thủy tinh,...
Hình 3. Bên trong một vi mạch
Xem thêm các hình ảnh bên trong một số chip ở link: http://diephotos.blogspot.com/

2. Phân loại vi mạch

Vi mạch có thể được phân làm nhiều loại khác nhau dựa trên các đặc điểm về cấu trúc, chức năng hay mật độ tích hợp.

Một cách phân loại phổ biến dựa trên mật độ tích hợp là dựa vào số lượng transistor hoặc CMOS hoặc số cổng (gate) có trong vi mạch để chia thành các nhóm như sau:
  • Vi mạch mật độ tích hợp thấp SSI (Small Scale Integration) là những vi mạch chứa khoảng từ vài đến vài chục transistor.
    • Ví dụ như các chip 74151 (Multiplexer), 7404 (cổng đảo),  ...
  • Vi mạch mật độ tích hợp trung bình MSI (Medium Scale Integration) là những vi mạch chứa khoảng vài trăm transistor
    • Ví dụ như các chip 54157 (multiplexer) chứa khoảng 100 transistor
  • Vi mạch mật độ tích hợp cao LSI (Large Scale Integration) là những vi mạch chứa khoảng vài nghìn transistor
    • Ví dụ như chip Intel 4004 chưa khoảng 2300 transistor, Intel 8008 khoảng 3500 transistor
  • Vi mạch mật độ tích hợp rất cao VLSI (Very Large Scale Integration) là những vi mạch chứa khoảng vài chục nghìn transistor trở lên
    • Ví dụ như chip 8088 chưa khoảng 29000 transistor, Motorola 68000 chứa khoảng 68000 transistor, ARM 1 chứa khoảng 25000 transistor
  • Vi mạch mật độ tích siêu cao ULSI (Ultra Large Scale Integration) là những vi mạch chứa khoảng vài triệu transistor.
    • Ví dụ như chip Pentium I, II và III đời đầu khoảng vài triệu transistor, ...
  • Vi mạch mật độ tích hợp cực cao GSI (Giant Scale Integration) là những vi mạch chứa khoảng vài trăm triệu transistor hoặc hơn.
    • Ví dụ các dòng Dual-core của Intel, AND K8/K10, ... dùng cho máy tính cá nhân PC hoặc các dòng đa nhân dùng cho các điện thoại thông minh như A7 của Apple có số lượng transistor khoảng 1 tỷ với 2 nhân ARM64, ...
Hình 4. Phân loại vi mạch theo số lượng transistor và số cổng

Hình 5. Phân loại vi mạch theo số lượng cổng


Cách phân chia trên không có một ranh giới rõ ràng và chỉ mang tính tương đối. Hiện nay, các vi mạch chứa hàng trăm triệu và hàng tỷ transistor đã ra đời như các vi xử lý core  i5, core i7, chip SnapDragon 8 nhân của Qualcomm, các vi xử lý dùng cho các máy chủ.

Thông số về số lượng transistor và cổng trong một vi mạch cũng không phải lúc nào cũng được công bố rỗng rãi nên việc xác định vi mạch đó thuộc loại LSI, VLSI, ULSI, ... chỉ là mang tính phỏng đoán nên thuật ngữ VLSI được sử dụng phổ biến để gọi các loại vi mạch có mật độ tích hợp cao nói chung.

Một cách phân loại phổ biến thứ 2 là dựa trên loại tín hiệu mà vi mạch đó có thể xử lý là tín hiệu số (digital) hay tín hiệu tương tự (analog). Theo cách phân loại này, vi mạch được chia làm 3 nhóm là:
  • Vi mạch số (Digital IC) xử lý các tín hiệu rời rạc dựa trên mức logic, 0 và 1, hoặc cạnh chuyển của tín hiệu, cạnh lên và cạnh xuống. Các vi mạch điển hình là các vi mạch cổng logic như AND, OR, đảo, các mạch đếm, MUX, ... Các thành phần chính của vi mạch này là các cổng logic, Flip-Flop, Latch, ...
  • Vi mạch tương tự (Analog IC) xử lý các tín hiệu liên tục dựa trên thuộc tính tần số, điện áp, dòng điện, của tín hiệu ... Các thành phần chính là các transistor, điện trở, tụ điện, cuộn cảm, ... Các chip điển hình là mạch khuếch đại thuật toán OP-AMP, chip ổn áp,...
  • Vi mạch tín hiệu hỗ hợp (Mixed-signal IC) là chip tích hợp cả thành phần xử lý tín hiệu số và tín hiệu tương tự ví dụ như chip vi điều khiển MCU có tích hợp các bộ chuyển đổi tín hiệu tương tự/số ADC
Hình 6. Vi mạch số 74HC245 của NXP
 
Hình 7. Vi mạch tương tự OPAMP OPA2188 của TI


Hình 8 là một vi mạch tín hiệu hỗ hợp dùng trong thẻ RFID, một loại thẻ thông minh không tiếp xúc giao tiếp không dây. Trong chip này, thành phần số là DIGITAL CONTROL UNIT, thành phần xử lý tín hiệu tương tự gồm có RF INTERFACE, FIELD DETECTION và khối bộ nhớ EEPROM.
Hình 8. Sơ đồ khối vi mạch mixed-signal NTAG213F dùng cho thẻ RFID của NXP 



Chủ Nhật, 16 tháng 7, 2017

[Asynchronous Design][Thiết kế bất đồng bộ][Bài 5] Phần tử C Muller và lý thuyết chỉ thị


1. Lý thuyết chỉ thị

Trong mạch đồng bộ, vai trò của xung clock là xác định các điểm trong từng khoảng thời gian mà tại đó các tín hiệu ổn định và hợp lệ để có thể lấy giá trị và sử dụng. Điểm này là tại cạnh tích cực của xung clock (cạnh lên hoặc cạnh xuống. Trước và sau cạnh tích cực này các tín hiệu buộc phải ổn định. Thời gian ổn định trước cạnh tích cực là setup time. Thời gian sau cạnh tích cực là hold time. Hai khoảng thời gian này tạo nên một cửa sổ định thời (timing window). Ngoài cửa sổ định thời tín hiệu có thể thay đổi giá trị nhiều lần hoặc không ổn định.

Hình 1. Timing trong mạch đồng bộ
Trong mạch bất đồng bộ, việc không sử dụng xung clock làm cho các tín hiệu có thể phải giữ ổn định (stable) trong toàn bộ thời gian.  Mỗi lần tín hiệu thay đổi đều phải có ý nghĩa. Tức là giá trị tín hiệu trước và sau khi thay đổi đều là những giá trị hợp lệ. Vì vậy, các nguy hiểm (hazard) và chạy đua (race) cần phải tránh. Nguy hiểm ở đây có thể là xung nháy (glitch). Glitch là trạng thái tín hiệu không mong muốn và thường thể hiện dưới dạng 1 xung có độ rộng rất nhỏ trên tín hiệu. Chạy đua có thể sinh ra các trạng thái không mong muốn của tín hiệu khi độ trễ trên các tín hiệu không giống nhau.

Các mạch bất đồng bộ là tổ hợp của các cổng logic thường có một hoặc nhiều đường hồi tiếp (feedback loop). Khi ngõ ra một cổng thay đổi nó có thể làm ngõ ra các cổng khác thay đổi theo đến một giá tị phù hợp. Hình 2 là một ví dụ về mạch nguyên lý cho khối CTL trong mô hình mạch bất đồng bộ từng trình bày ở bài 1 - đồng bộ theo xung clock và giao thức bắt tay. Hoạt động của mạch hình 2 như sau:


  1. Khởi động các tín hiệu đều bằng 0 và ck = 0
  2. Khi req_i = 1, ngõ ra cổng AND 1 bằng 1:
    1. req_o = 1 để yêu cầu tầng tiếp theo
    2. ack_o = 1 để xác nhận với tầng đã phát req_i
    3. ck = 1 để yêu cầu thanh ghi chốt dữ liệu từ tầng trước
  3. Khi ack_i = 1, ngõ ra cổng AND 1 bằng 0, ngõ ra ck = req_o = ack_o chỉ bằng 0 khi req_i đã kéo xuống 1.
Nhưng ở đây, việc giải thích chức năng của mạch (b) không phải là mục đích chính mà chỉ nhằm minh họa một cách trực quan về những nguy hiểm có thể xảy ra trên các ngõ ra req_o, ack_o và ck khi áp dụng vào mô hình pipeline (a).

Hình 2. Một sơ độ nguyên lý (b) của mạch điều khiển bất đồng bộ CTL cho mô hình pipeline (a)
Xem xét một cổng OR đơn thuần sử dụng trong mạch hình 2, nếu ngõ ra y chuyển trạng thái từ 1 sang 0 thì chắc chắn cả 2 ngõ vào đều bằng 0, nếu ngõ ra y chuyển trạng thái từ 0 sang 1 thì không thể kết luận giá trị của 2 ngõ vào là bao nhiêu. Chúng ta nói rằng cổng OR chỉ thị (indicate) hoặc xác nhận (acknowledge)  khi cả hai ngõ vào bằng 0. Tương tự, cổng AND chỉ thị khi cả hai ngõ vào bằng 1.

Hình 3. Cổng OR chỉ thị hoặc xác nhận khi 2 ngõ vào bằng 0
Khi các tín hiệu ngõ vào thay đổi trạng thái mà không được chỉ thị hoặc xác nhận bởi sự chuyển đổi ở ngõ ra thì  đó là nguồn hazard cần phải tránh. Mạch càng phức tạp thì việc kiểm soát các nguy hiểm và chạy đua càng khó. Vì vậy, cần có những lý thuyết và phương pháp để kiểm soát các thiết kế như trên một cách hiệu quả.

Khái niệm chỉ thị (indication) hoặc xác nhận (acknowledgement) có vai trò quan trọng trong thiết kế các mạch bất đồng bộ.

Một mạch tốt hơn dùng cho việc chỉ thị này là phần tử C muller.

2. Phần tử C Muller

Phần tử C Muller (Muller C-element) còn được gọi bằng nhiều tên khác như cổng C (C gate), Flip-flop trễ (Hysteresis Flip-flop), hoặc Flip-flop trùng nhau (coincident Flip-flop), mạch an toàn 2 tay (two-hand safety circuit) là một phần tử số được sử dụng rộng rãi trong thiết kế mạch bất đồng bộ. Phần tử này được mô tả bởi nhà toán học và khoa học máy tính người Mỹ David E. Muller.

Hình 3. Ký hiệu, mạch mức MOS và các cách biểu diễn phần tử C
Phần tử C là một thành phần giữ trạng thái có:
  • Ngõ ra bằng 0 khi cả hai ngõ vào là 0
  • Ngõ ra bằng 1 khi cả hai ngõ vào là 1
  • Ngõ ra không thay đổi giá trị khi ngõ vào là 01 hoặc 10
Như vậy, phần tử C chỉ thị khi cả 2 ngõ vào bằng 1 hoặc cả 2 ngõ vào bằng 0.

3. Đường ống Muller (Muller Pipeline) 

Hình 4 là một mạch được xây dựng bằng phần tử C và cổng đảo thay thế cho mạch nguyên lý hình 2.


Hình 4. Mạch CTL sử dụng phần tử C và cổng đảo

Hình 5 là mạch pipeline của CTL sử dụng mạch hình 4. Mô hình này là Muller pipeline hoặc phân bố Muller (Muller distributor). Sự mở rộng hoặc biến đổi mạch này được sử dụng trong phần lớn các mạch đồng bộ khác. Hoạt động của pipeline này như sau:
  1. Sau khi tất cả các phần tử C được khởi động về 0 thì quá trình bắt tay req/ack bắt đầu từ phía ngoài cùng bên trái (Left).
  2. Xét phần tử C thứ i, nó chỉ lấy giá trị 1 từ Req = C[i-1] của tầng trước nó khi Ack = C[i+1] tầng sau nó là 0. Tương tự, nó chỉ lấy giá trị 0 từ Req (đồng thời là C[i-1]) của tầng trước nó khi Ack (đồng thời là C[i+1]) tầng sau nó là 1. Điều này có được là nhờ thuộc tính chỉ thị khi cả 2 ngõ vào cùng bằng 1 hoặc cùng bằng 0 của phần tử C.

Hình 4. Muller Pipeline hoặc Muller Distributor
Xem dạng sóng bên dưới hình 4, các bắt tay trên mỗi giao tiếp Req/Ack sẽ lan truyền trong đường ống Muller từ bên trái (Left) qua bên phải (Right). Định thời tại mỗi giao tiếp bắt tay có thể khác nhau nhưng phần tử C đảm bảo việc chỉ thị khi C[i] chuyển trạng thái từ 1 qua 0 hoặc từ 0 qua 1. Điều này đảm bảo tính toàn vẹn của các hoạt động bắt tay được lan truyền. Nếu Req được phát từ bên trái đã lan truyền đến cuối pipeline, tức bên phải, mà không nhận được đáp ứng Ack từ bên phải thì pipeline lúc này sẽ bị đầy. Hành vi này giống như hoạt động của một FIFO.

Tốc độ lan truyền trong đường ống Muller phụ thuộc vào đỗ trễ thực tế của mạch.

Một số điểm đáng chú ý của mạch này như sau:
  1. Đơn giản và có thể ứng dụng được cho cả giao thức bắt tay 2 pha hoặc 4 pha tùy vào việc biến đổi các tín hiệu giao tiếp cho phù hợp
  2. Có thể đảo định nghĩa cực của các tín hiệu, thay vì sử dụng tích cực mức cao (logic 1) thì có thể sử dụng tích cực mức thấp (logic 0) như hình 5
  3. Mạch hoạt động chính mà không phụ thuộc vào độ trễ các cổng và dây dẫn. Đường ống Muller được được nói là "không nhạy trễ" (delay-insensitive)
Hình 5. Có thể đảo cực tín hiệu ở mạch Muller pipeline
 
Note: Tôi dịch chủ yếu từ tài liệu "Asynchronous Circuit Design A Tutorial" của tác giả Jens Sparsø nhưng có thể thêm các nhận xét hoặc minh họa theo cách hiểu của riêng mình. Mong các bạn chia sẻ và góp ý và thảo luận dưới bài viết.