Enum và typedef: tên kiểu không thay cho kiểm dữ liệu

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

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

  • Dùng enum có encoding rõ và duyệt theo declaration order
  • Phân biệt type name, biến độc lập và alias của net
  • Giữ width khi dùng typedef và nhận diện conversion cần kiểm

Đổi con số vô danh thành một miền có tên

Các số 0/5/2 có thể là encoding trạng thái, nhưng một log chỉ in 5 buộc người debug nhớ bảng mã. Enum đặt tên IDLE/BUSY/DONE cho những giá trị ấy. Typedef cho phép cùng một định nghĩa được dùng ở nhiều nơi. Cả hai cải thiện biểu đạt, nhưng không tự chứng minh mọi bit đọc từ bên ngoài đều là một member hợp lệ.

Chọn base type và encoding rõ

Ví dụ dùng enum bit[2: 0] với IDLE 0, BUSY 5, DONE 2. Ba encoding vừa ba bit và không trùng. Enum mặc định có base int nếu bỏ khai báo base, nhưng không cần lãng phí suy luận bằng việc dựa vào mặc định khi encoding là giao diện. Base 2-state ở đây cũng nghĩa là không thử unknown enum. [1]

Next không phải cộng một

Declaration order là IDLE→BUSY→DONE; next từ 0 trả 5, từ 5 trả 2 và từ 2 wrap 0. Prev từIDLE trảDONE 2. num trả 3; first/last theo vị trí khai báo. Không dùng next như bộ cộng encoding hoặc sắp xếp numeric. TB kiểm đủ chu trình và tên DONE để bắt cách hiểu sai này.

Typedef đặt tên cho kiểu, mỗi biến vẫn riêng

word_t là bit[4: 0]. word_a và word_b khai cùng kiểu nhưng mỗi biến có storage riêng; gán b=a là chép giá trị. Đổi a sau đó không đổi b. Cast từ index 8 bit xuống word_t giữ low 5, nên mọi index n trong 0..255 cho b=n modulo 32. Tên kiểu đẹp không làm vector tự rộng hơn. [2]

Raw bits cần chính sách khi đi vào enum

Một biến integer không tự được coi là cùng kiểu enum chỉ vì giá trị đang là 0. Named member assignment biểu đạt rõ kiểu; tại biên decode, cần checked conversion hoặc kiểm domain theo yêu cầu. Static cast có thể tạo encoding không thuộc member set; bài casting sẽ kiểm 7 không được liệt kê. Không thêm static cast chỉ để compiler hết phản đối rồi tin input hợp lệ.

Alias của net khác tên khác cho một kiểu

typedef đặt tên cho kiểu; alias nối các tên net vào cùng đối tượng net, không tạo hai biến độc lập như word_a/word_b. Không dùng alias như handle của một biến logic được procedural write. Ví dụ dưới chỉ được pyslang parse/elaborate, chưa được flow mô phỏng net resolution; nhãn kiểm chứng phải phản ánh giới hạn đó. [3]

Alias chỉ đổi tên cùng net, không phải typedef

Kiểm parse/elaborate alias hai net 4 bit; không claim simulation hoặc synthesis.

net_alias.sv RTL
module net_alias(input wire[3:0] pin_a,output wire[3:0] pin_b);  alias pin_a=pin_b;endmodule

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

  • Phân tích và elaborate theo LRM (pyslang 12.1.0)

Alias chỉ được kiểm parse/elaborate bởi pyslang; chưa kiểm resolution hoặc truyền hai chiều bằng simulator của flow này.

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.

Dùng chung định nghĩa thay vì chép lại nhiều enum

Hai khai báo enum viết giống nhau ở hai scope không phải lý do để mặc định mọi assignment giữa chúng tương thích. Trong dự án, chia sẻ typedef từ một nơi phù hợp như package để monitor và scoreboard thống nhất type/encoding. Package/import cụ thể sẽ được kiểm ở bài liên quan; không coi việc trùng text là proof type identity.

Chu trình 0/5/2 và 256 phép chép 5 bit

Tính trước chạy: forward 0/5/2/0, prevIDLE 2, num 3, nameDONE;256 ca width 5, cuối b31 còn a0 sau complement.

Thí nghiệm enum-typedef

Kỳ vọng tính trước chạy: Declarationorder 0/5/2, nextwrap 0/prevwrap 2,3 members;256 byte→5 bit n%32 vàcopyđộc lập.

tb_enum.sv testbench
module tb_enum;  typedef enum bit[2:0] {IDLE=0,BUSY=5,DONE=2} phase_t;  typedef bit[4:0] word_t;  phase_t phase;  word_t word_a,word_b;  int n;  initial begin    phase=IDLE;    if(phase.num()!=3||phase.first()!=IDLE||phase.last()!=DONE) $fatal(1,"enum endpoints/count");    phase=phase.next();if(phase!=BUSY||phase.name()!="BUSY") $fatal(1,"enum next follows declaration");    phase=phase.next();if(phase!=DONE) $fatal(1,"enum numeric order used");    phase=phase.next();if(phase!=IDLE) $fatal(1,"enum next wrap");    phase=phase.prev();if(phase!=DONE) $fatal(1,"enum prev wrap");    $display("ENUM ORDER forward=0/5/2/0 prev_idle=2 members=3 name=%s",phase.name());    for(n=0;n<256;n++) begin      word_a=word_t'(n);word_b=word_a;word_a=~word_a;      if(int'(word_b)!=n%32||int'(word_a)!=31-(n%32)||$bits(word_b)!=5) $fatal(1,"typedef width/copy n=%0d",n);    end    $display("TYPEDEF CHECK cases=256 bits=5 last_saved=31 last_changed=0");    $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 (Verilator 5.050, 2-state)

Output phải khớp: ENUM ORDER forward=0/5/2/0 prev_idle=2 members=3 name=DONETYPEDEF CHECK cases=256 bits=5 last_saved=31 last_changed=0

Chỉ enum 2 state/typedef/methods trong TB; không claim alias net simulation, X/Z hoặc synthesis.

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.

Verilator kiểm subset 2-state/methods/copy trong TB; không suy ra alias đã simulated hoặc synthesize enum thành encoding cụ thể. [4]

Tự kiểm tra

Tự kiểm tra: enum-typedef

  1. Enum declaration IDLE 0,BUSY 5,DONE 2: next của BUSY là gì?
  2. Prev của IDLE trong enum 0/5/2 là gì?
  3. word_t là bit[4:0], cast 255 thành giá trị nào?
  4. Sau b=a rồi complement a, b thế nào?
  5. Bằng chứng của ví dụ net alias trong bài là gì?

Đọc tên và đọc hợp đồng cùng nhau

Chốt member set, base width/sign, ownership định nghĩa và chính sách raw input. Duyệt enum bằng declaration order khi đó là điều muốn làm; dùng số học rõ khi cần số học. Typedef giữ semantics của kiểu, alias là chuyện net khác. Bài vẫn draft/LRM needs-spec-check.

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

  1. SystemVerilog Enumeration — bản chụp resources.zip, Enum declaration. Trích dẫn; nguồn đã đọc các mục liên quan.
  2. SystemVerilog typedef and alias — bản chụp resources.zip, Typedef. Trích dẫn; nguồn đã đọc các mục liên quan.
  3. SystemVerilog typedef and alias — bản chụp resources.zip, Net alias. Trích dẫn; nguồn đã đọc các mục liên quan.
  4. Thí nghiệm nguyên bản ex.b1.enum-typedef, Bằng chứng. Trích dẫn; nguồn đã đọc toàn văn.
  5. IEEE 1800-2023 SystemVerilog LRM, Net aliasing. Chưa đối chiếu với văn bản nguồn (chưa mở).
  6. IEEE 1800-2023 SystemVerilog LRM, enum-typedef types, assignment and conversion semantics. Chưa đối chiếu với văn bản nguồn (chưa mở).
  7. Thí nghiệm nguyên bản ex.b1.enum-typedef, Source, self-checks, metadata và verification.json. Trích dẫn; nguồn đã đọc toàn văn.
  8. IEEE 1800-2023 SystemVerilog LRM, enum-typedef type and conversion semantics. Chưa đối chiếu với văn bản nguồn (chưa mở).
  9. SystemVerilog Enumeration — bản chụp resources.zip, Basic Enum Declaration; Defining a Custom Enumerated Type With typedef; Enumerated-Type Methods; Type Checking. Trích dẫn; nguồn đã đọc các mục liên quan.
  10. SystemVerilog typedef and alias — bản chụp resources.zip, Typedef; Alias; Common Beginner Mistakes. Trích dẫn; nguồn đã đọc các mục liên quan.