Switch, UDP và strength: đọc mô hình mô phỏng thấp hơn RTL

Khoảng 30 phútMức 2/3Bản nháp: một số khẳng định chưa đối chiếu spec

Sau bài này bạn sẽ

  • Đọc một switch tranif1 và phân biệt nó với phép gán vào biến
  • Dự đoán output của UDP combinational hai input với 0/1/X/Z
  • Phân biệt tranh chấp cùng strength với strong thắng weak trong ví dụ
  • Giới hạn kết luận ở mô hình số, không suy ra transistor hay synthesis target

Vì sao còn gặp mô hình thấp hơn RTL?

Khi đọc mô hình thư viện hoặc mô phỏng một kết nối đặc biệt, bạn có thể gặp primitive switch, user-defined primitive (UDP) và drive strength. Chúng trả lời những câu hỏi khác với một RTL mux thông thường.

Bài này tự chọn: mục tiêu là đọc được mô hình nhỏ và biết giới hạn của nó, không bắt người mới thiết kế transistor hoặc viết library đầy đủ. Hoàn thành các bài bắt buộc của A6 không cần đánh dấu xong bài này.

Icarus 4-state chạy ví dụ gốc của dự án. Các quy tắc đầy đủ về switch, UDP và strength vẫn [1]; bài giữ draft, không nâng thành đã xác minh đặc tả từ một simulator.

Tranif1 nối hai net khi enable bằng 1

tranif1 u_switch(switched, source, gate) là primitive switch có hai terminal dữ liệu và một điều khiển. Trong các vector của bài, gate bằng 1 nối hai terminal; gate bằng 0 ngắt đường nối. Ta drive source bằng một continuous assignment, còn switched không có driver riêng.

Khi gate=1 và source=1, switched bằng 1. Khi gate=0, switched quan sát là Z vì không còn đường drive từ source. Cả source và switched là net; biến source_value được gán trong TB rồi drive source qua assign.

Bản nháp đầu từng nối terminal hai chiều trực tiếp vào biến reg. Pyslang báo InOutVarPortConn và Icarus từ chối elaborate. Bản hiện tại sửa đúng loại kết nối, không tắt diagnostic hoặc đổi expected. Đây là lý do phải đọc terminal contract, không chỉ nhìn tên primitive.

Ví dụ chỉ drive từ phía source để dễ kiểm. Không suy ra tranif1 là buffer một chiều trong mọi ngữ cảnh, và chưa kiểm gate=X, kết nối nhiều switch hoặc charge storage.

Một bảng UDP AND không có clock

Primitive udp_and khai báo output y và hai input a, b, với bảng combinational:

table
  0 ? : 0;
  ? 0 : 0;
  1 1 : 1;
endtable

Hai hàng đầu nói có input 0 thì output 0; dấu ? là ký hiệu trong bảng UDP, không phải toán tử điều kiện ?: của biểu thức thông thường. Hàng cuối cho 1 khi cả hai input 1. Các trường hợp unknown chưa quyết định được AND cho output X trong ví dụ.

TB đưa đủ 16 cặp 0/1/X/Z vào UDP. Với Z, kết quả đã kiểm khớp cách unknown tham gia bảng này: 0 với Z vẫn ra 0, còn Z/Z ra X. Không biến một hàng ? thành bảo đảm mọi mô hình sequential UDP đều giống bảng combinational này.

UDP trong bài không có clock, state hoặc bảng edge transition. Đọc các model có state cần xem cú pháp và đặc tả riêng; không áp dụng ba hàng ở đây cho flip-flop library.

Không phải mọi xung đột đều ra X

Một wire có hai driver bằng 0 và 1 cùng strength strong cho X trong TB. Nhưng net khác có strong0 đối đầu weak1 lại resolve bằng 0. Vì vậy câu “hai driver khác dữ liệu luôn ra X” còn thiếu điều kiện về strength và net kind.

TB viết rõ (strong0, strong1) và (weak0, weak1) ở continuous assignments. Chỉ hai cặp này được kiểm; không tuyên bố đã phủ toàn bộ thứ tự strength hoặc mọi net type.

Strength là khái niệm của mô hình số. Nó không cung cấp dòng điện, điện trở hay điện áp đo được của thiết bị. Cũng không dùng cách tăng strength trong mô hình để che lỗi hai master đang drive sai giao thức.

Bốn ca switch và mười sáu cặp UDP

Tính trước: hai enable × hai source 0/1 là bốn ca switch. Hai input UDP, mỗi input có bốn trạng thái, tạo 16 cặp. Strong0 thắng weak1 cho 0, hai strong ngược nhau cho X, switch tắt cho Z.

Switch, UDP và strength trong mô hình số

Kiểm tranif1, bảng UDP AND và resolution strong/weak bằng Icarus, không suy ra transistor vật lý.

tb_switch.sv testbench
primitive udp_and (y, a, b);  output y;  input a, b;  table    0 ? : 0;    ? 0 : 0;    1 1 : 1;  endtableendprimitivemodule tb_switch;  timeunit 1ns;  timeprecision 1ps;  reg source_value, gate, a, b;  wire source;  assign source = source_value;  tri switched;  wire udp_y;  wire strength_winner, same_strength;  reg expected_switch, expected_udp;  int switch_cases = 0, udp_cases = 0;  tranif1 u_switch(switched, source, gate);  udp_and u_udp(udp_y, a, b);  assign (strong0, strong1) strength_winner = 1'b0;  assign (weak0, weak1) strength_winner = 1'b1;  assign (strong0, strong1) same_strength = 1'b0;  assign (strong0, strong1) same_strength = 1'b1;  function automatic reg state(input integer i);    case(i)      0: state = 1'b0;      1: state = 1'b1;      2: state = 1'bx;      3: state = 1'bz;    endcase  endfunction  initial begin    for (int en = 0; en < 2; en++)      for (int v = 0; v < 2; v++) begin        gate = 1'(en); source_value = 1'(v);        expected_switch = en ? 1'(v) : 1'bz;        #1;        if (switched !== expected_switch) $fatal(1, "switch mismatch");        switch_cases++;      end    $display("SWITCH RESULT enabled=%b", switched);    gate = 0;    #1;    if (switched !== 1'bz || strength_winner !== 0 || same_strength !== 1'bx)      $fatal(1, "strength or disabled switch mismatch");    $display("STRENGTH RESULT strong0_weak1=%b equal_conflict=%b disabled=%b",             strength_winner, same_strength, switched);    for (int i = 0; i < 4; i++)      for (int j = 0; j < 4; j++) begin        a = state(i); b = state(j);        expected_udp = (i == 0 || j == 0) ? 1'b0 :                       (i == 1 && j == 1) ? 1'b1 : 1'bx;        #1;        if (udp_y !== expected_udp) $fatal(1, "UDP mismatch i=%0d j=%0d", i, j);        udp_cases++;      end    $display("UDP RESULT zero_x=%b z_z=%b cases=%0d switch_cases=%0d",             1'b0 & 1'bx, udp_y, udp_cases, switch_cases);    $finish;  endendmodule

Đã kiểm chứng thế nào

  • Phân tích và elaborate theo LRM (pyslang 12.1.0)
  • Mô phỏng, exit 0 và output khớp kỳ vọng tính tay (Icarus Verilog 11.0, 4-state)

Output phải khớp: SWITCH RESULT enabled=1STRENGTH RESULT strong0_weak1=0 equal_conflict=x disabled=zUDP RESULT zero_x=0 z_z=x cases=16 switch_cases=4

Chỉ kiểm switch enable/source 0/1, UDP combinational hai input và hai cặp strength nêu rõ; không phủ switch X, charge storage, sequential UDP hoặc MOS analog.

Không claim lint/synthesis: mô hình testbench cho mô phỏng, không bảo đảm map lên transistor/FPGA.

Các kiểm tra chạy lúc xây dựng nội dung (2026-11-06), không chạy trong trình duyệt. Kỳ vọng được tính tay trước khi chạy.

TB so switch và UDP bằng !==, nên unknown không lọt qua một điều kiện so sánh không xác định. Oracle UDP phân loại bằng index số nguyên, không lấy output primitive làm chuẩn. Các dòng in nằm sau assertions tương ứng; chỉ exit 0 và đủ output mới đạt simulated.

Parse bằng pyslang và simulation Icarus đều đạt. Không claim lint/synthesis cho file mô hình TB này. [2]

Mô hình số khác transistor vật lý

Primitive switch không phải SPICE. Thử gate 0/1 không đo threshold, nhiễu, leakage hoặc chuyển tiếp analog. Output Z của mô hình không chứng minh một chân I/O thật đang đáp ứng mọi giới hạn điện.

Tương tự, UDP có thể hữu ích khi mô tả hành vi một cell, nhưng việc UDP chạy trong simulator không bảo đảm tool synthesis của target sẽ nhận hoặc map nó thành cell mong muốn. Flow hiện tại chưa tổng hợp switch/UDP và chưa có netlist/timing library của một chip cụ thể.

Trong công việc, trước tiên xác định mình đang đọc RTL synthesizable, functional model hay timing model thư viện. Cách dùng và tiêu chí kiểm của ba thứ đó khác nhau.

Lỗi khi đọc library model

  • Nối terminal hai chiều vào biến rồi tìm cách tắt lỗi parser.
  • Nhầm ? trong bảng UDP với một biểu thức ternary.
  • Quên các hàng chưa quyết định output, đặc biệt khi có X/Z.
  • Dùng kết quả strong/weak để suy ra điện áp hoặc dòng điện.
  • Gọi việc mô phỏng một primitive là bằng chứng synthesis của primitive đó.
  • Biến bài tự chọn thành prerequisite của bài bắt buộc; curriculum/validator không cho phép quan hệ này.

Tự kiểm tra

Tự kiểm tra: switch-udp-strength

  1. Trong bài, tranif1 tắt và switched không có driver riêng. Quan sát là gì?
  2. Terminal dữ liệu hai chiều của tranif1 trong bản đã sửa nối vào đâu?
  3. UDP AND trong bài nhận 0 và X. Output là gì?
  4. Strong0 đối đầu weak1 trong wire của bài resolve thành gì?
  5. Parse/simulate primitive này có xác nhận mapping transistor/FPGA không?

Quan sát đúng mức trừu tượng

Đọc hướng/loại terminal, bảng primitive và strength trước khi đoán giá trị net. Tính một trường hợp biết rõ và một trường hợp unknown, rồi kiểm bằng simulator giữ đúng X/Z.

Bài kiểm bốn ca switch, 16 cặp UDP và hai cặp strength cụ thể. Chưa phủ sequential UDP, MOS network, charge decay, gate unknown hay timing vật lý. Giới hạn này là một phần của kết quả kỹ thuật, không phải lý do để gắn nhãn verified cho phần chưa đọc.

Nguồn và mức độ đối chiếu

  1. IEEE 1800-2023 SystemVerilog LRM, cần đối chiếu LRM. Chưa đối chiếu với văn bản nguồn (chưa mở).
  2. Thử nghiệm A6.switch-udp-strength: source và verification.json, Bằng chứng switch/UDP/strength. Trích dẫn; nguồn đã đọc toàn văn.
  3. IEEE 1800-2023 SystemVerilog LRM, Switch primitives, user-defined primitives, net strengths. Chưa đối chiếu với văn bản nguồn (chưa mở).
  4. Thử nghiệm A6.switch-udp-strength: source và verification.json, Ví dụ đã chạy: source và verification.json. Trích dẫn; nguồn đã đọc toàn văn.
  5. Thử nghiệm A6.switch-udp-strength: source và verification.json, tb_switch.sv và verification.json. Trích dẫn; nguồn đã đọc toàn văn.