UVM 1.2'den IEEE 1800.2-2020'ye: Kaynak Kod Üzerinden Sürüm Karşılaştırması

Blog · Derinlemesine Analiz | UVM 1.2, 1800.2-2017 (0.9, 1.0) ve 1800.2-2020 (2.0, 3.0, 3.1, 3.2) kütüphanelerini dosya, sınıf, metot ve makro seviyesinde yan yana koyduk. Kaldırılanlar, yeniden tasarlananlar, geri gelenler ve bir geçiş rehberi.

Çoğu doğrulama mühendisi UVM'i 1.2 sürümüyle öğrenir; EDA Playground'daki varsayılan seçenek de budur. Oysa Accellera 2014'ten bu yana yedi yeni kütüphane kiti yayımladı, UVM bir IEEE standardı oldu ve kütüphanenin iç mimarisi birkaç yerde köklü biçimde değişti. Bu yazıda bu kitlerin kaynak kodlarını indirip birbirleriyle karşılaştırdık: hangi sınıflar silindi, hangi makrolar eklendi, hangi davranışlar sessizce değişti ve 2026 itibarıyla hangi sürümü seçmek gerekir.

Neden Böyle Bir Karşılaştırma?

UVM dünyasında iki farklı şey aynı adla anılır:

Kavram Ne demek? Kim üretir?
Standart Sınıfların, metotların ve davranışların normatif tanımı (bir PDF) 2011–2014: Accellera; 2017'den itibaren IEEE (1800.2)
Kütüphane (BCL, base class library) O standardı gerçekleyen SystemVerilog kaynak kodu (uvm_pkg) Accellera UVM Çalışma Grubu; simülatör üreticileri kendi kopyalarını paketler

UVM 1.2'de ikisi aynı pakette geliyordu: standart dokümanı da kütüphaneyi de Accellera yazıyordu. IEEE 1800.2 ile birlikte roller ayrıldı: IEEE standardı tanımlar, Accellera ise standardın bir referans gerçeklemesini (reference implementation) sunar. Bu ayrım sürüm numaralandırmasından dosya düzenine, "deprecated" politikasından uyumluluk paketlerine kadar her şeyi etkiledi.

Kurumsal projelerde çalışan birinin karşılaşacağı tipik durum şudur: ekip 1.2 ile yazılmış bir VIP'yi 1800.2-2020 kütüphanesiyle derlemeye çalışır ve set_config_int bulunamadı, uvm_sequence_base soyut sınıf olduğu için new() edilemez, printer.knobs.depth erişilemez gibi hatalar alır. Bu yazı o hataların nereden geldiğini ve nasıl çözüleceğini kaynak kodla gösteriyor.

Yöntem: Neyi, Nasıl Karşılaştırdık?

İncelenen kitler ve geldikleri yerler:

Kit Kaynak Not
UVM 1.2 accellera.org tarball (uvm-1.2.tar.gz) Son Accellera numaralı sürüm
1800.2-2017 0.9 accellera.org tarball İlk IEEE uyumlu kit
1800.2-2017 1.0 accellera.org tarball
1800.2-2020 2.0 GitHub accellera-official/uvm-core, etiket 2020-2.0 Kütüphanenin halka açık ilk git sürümü
1800.2-2020 3.0 GitHub etiketi 2020.3.0 + accellera.org tarball
1800.2-2020 3.1 GitHub etiketi 2020.3.1 + accellera.org tarball
1800.2-2020 3.2 accellera.org arşivi (Ağustos 2026) Yazı tarihindeki en yeni kit

Üç ara sürüm, 2017-1.1, 2020-1.0 ve 2020-1.1, bugün ne Accellera'nın indirme sayfasında ne de GitHub deposunda bulunuyor. Varlıklarını yalnızca sonraki kitlerin uvm_version_defines.svh dosyasındaki sürüm merdiveninden (UVM_VERSION_POST_2017_1_1, UVM_VERSION_POST_2020_1_0, UVM_VERSION_POST_2020_1_1) biliyoruz. Bu yazıda onlar hakkında yalnızca tarih bilgisi var.

Karşılaştırma için şunları yaptık:

  • src/ ağaçlarını dosya bazında diff ile eşleştirdik (eklenen, silinen, değişen dosyalar).
  • Her kitten class tanımlarını, sınıf içindeki function/task prototiplerini ve `define makrolarını basit bir ayrıştırıcıyla çıkardık ve kümeler arası farkları aldık. Ayrıştırıcı kasıtlı olarak sade; m_ önekli iç metotları ve new yapıcılarını saymıyor. Sayılar bu yüzden yaklaşık ama eğilimleri doğru gösteriyor.
  • Kitlerin README, release-notes, DEVIATIONS.md ve compat/README.md dosyalarını okuyup kod bulgularıyla çapraz kontrol ettik.
  • Tarihleri Accellera indirme sayfasındaki tablodan, arşiv içindeki dosya zaman damgalarından ve git etiket tarihlerinden aldık.

Zaman Çizelgesi

Tarih Olay Sürüm dizesi (uvm_revision_string())
Haziran 2014 UVM 1.2 yayımlandı; Accellera ardından standardı IEEE'ye devretti UVM-1.2
Şubat 2017 IEEE 1800.2-2017 onaylandı —
Haziran 2018 1800.2-2017 0.9 (dokümantasyonu eksik, "kullanırken dikkat" uyarılı ilk kit) Accellera:1800.2-2017:UVM:0.9
Kasım 2018 1800.2-2017 1.0; DEVIATIONS.md ve API etiketleri geldi Accellera:1800.2-2017:UVM:1.0
Haziran 2020 1800.2-2017 1.1 —
2020 IEEE 1800.2-2020 yayımlandı; IEEE GET programıyla ücretsiz indirilebilir —
Aralık 2020 1800.2-2020 1.0 —
Şubat 2021 1800.2-2020 1.1 —
Şubat 2023 1800.2-2020 2.0; aynı yıl accellera-official/uvm-core GitHub deposu halka açıldı Accellera:1800.2-2020:UVM:2.0
Şubat 2024 2020.3.0 (numaralandırma 2020-2.0 biçiminden 2020.3.0 biçimine geçti) Accellera:1800.2:UVM:2020.3.0
Ağustos 2024 2020.3.1 Accellera:1800.2:UVM:2020.3.1
Ağustos 2026 2020.3.2 Accellera:1800.2:UVM:2020.3.2

Benzetme: UVM 1.2, bir şirketin kendi yazdığı ve kendi dağıttığı bir kılavuzdu. 1800.2 ile kılavuz resmî bir standart oldu; Accellera'nın kütüphanesi artık "standardın bir uygulaması" sıfatını taşıyor. Tıpkı C dilinde K&R C'den ANSI C'ye geçişte derleyicilerin "standarda uyum" iddiasında bulunmaya başlaması gibi.

Sayılarla Yedi Kit

Yalnızca src/ altındaki .sv/.svh dosyaları sayıldı. Sınıf sayısı m_ önekli iç sınıfları da içerir.

Kit SV dosyası Satır Sınıf Metot prototipi (~) `define
UVM 1.2 145 75.639 331 1.962 403
2017-0.9 157 76.252 332 2.065 510
2017-1.0 157 77.042 332 2.081 513
2020-2.0 166 80.125 351 2.259 536
2020.3.0 170 88.803 356 2.295 540
2020.3.1 170 86.476 358 2.301 563
2020.3.2 174 87.344 366 2.329 569

Ardışık sürümler arasındaki hareket (yorum satırları dahil, satır ekleme / silme):

Geçiş Değişen dosya Eklenen / silinen satır Sınıf (−/+) Metot (−/+) Makro (−/+)
1.2 → 2017-0.9 150 +18.1k / −18.3k 14 / 15 162 / 265 81 / 188
2017-0.9 → 2017-1.0 64 +2.6k / −1.9k 0 / 0 1 / 17 0 / 3
2017-1.0 → 2020-2.0 165 +11.0k / −8.2k 0 / 19 22 / 200 1 / 24
2020-2.0 → 2020.3.0 175 +14.4k / −8.0k 0 / 5 0 / 36 0 / 4
2020.3.0 → 2020.3.1 17 +0.4k / −2.6k 0 / 2 0 / 6 0 / 23
2020.3.1 → 2020.3.2 180 +2.1k / −2.0k 0 / 8 1 / 29 0 / 6

İki sayı yanıltıcı olabilir. 1.2 → 2017 geçişinde satırların yarısına yakını yorum: her metodun üstüne IEEE madde numarası taşıyan // @uvm-ieee 1800.2-2017 auto 16.5.3.2 biçiminde etiketler eklendi. Yorum satırları çıkarıldığında gerçek kod hareketi yaklaşık +10.9k / −8.0k'dir. 2020.3.0 ve 2020.3.2'de "değişen dosya" sayısının neredeyse tüm dosyaları kapsaması ise her dosyanın başına eklenen git izleme başlığından ($File$, $Rev$, $Hash$) kaynaklanır; tarball'larda bu alanlar gerçek değerlerle doldurulduğu için aynı etiketin GitHub ve tarball kopyaları bile birbirinden "farklı" görünür.

Kitin içinde ne var, ne yok?

İçerik 1.2 2017-0.9 2017-1.0 2020-2.0 2020.3.x
src/ kütüphane ✓ ✓ ✓ ✓ ✓
examples/ (ubus, apb, codec, hello_world…) ✓ — — — —
bin/ dönüşüm betikleri (ovm-to-uvm10.pl, uvm11-to-uvm12.pl) ✓ — — — —
Sınıf referansı (HTML) ✓ — ✓ ✓ ✓
Kullanıcı kılavuzu (User Guide) ✓ (ayrı PDF) — — — —
DEVIATIONS.md (standarttan sapmalar) — — ✓ (10 madde) ✓ (3 madde) ✓ (3 madde)
compat/ uyumluluk paketi — — — ✓ ✓
CONTRIBUTING.md, DEVELOPMENT.md — — — — ✓

1800.2 kitleriyle birlikte örnekler ve kullanıcı kılavuzu dağıtımdan çıktı. Yeni başlayan biri için bu önemli bir kayıp; examples/integrated/ubus hâlâ en iyi uçtan uca UVM örneklerinden biridir ve yalnızca 1.2 kitinde bulunur. Standart metni ise IEEE GET programı sayesinde ücretsizdir; 1.2 döneminde Accellera'nın kendi PDF'i de ücretsizdi, dolayısıyla erişimde gerileme yok, ama "kitap" ile "kod" artık iki ayrı yerden geliyor.

Katkıcılar

NOTICE.txt dosyaları da bir hikâye anlatır. UVM 1.2'nin telif sahipleri dört şirkettir: Mentor, Cadence, Synopsys ve Cypress. 2017-1.0'da liste 16 kuruluşa çıkar (AMD, NVIDIA, Intel, Cisco, Qualcomm, Verilab, Semifore, Aldec, Verific…). 2020.3.1'de 20 kuruluş vardır; Marvell, NXP, Microsoft ve Siemens eklenmiştir. Kütüphane, üç EDA firmasının ortak projesinden geniş bir sektör konsorsiyumunun bakımına geçmiştir.

Büyük Resim: Üç Nesil, Üç Felsefe

Kodun kendisine inmeden önce, üç neslin "eski API ile ne yapılır" sorusuna verdiği cevabı yan yana koymak gerekir; çünkü diğer tüm farklar bu cevaptan türer.

UVM 1.2 1800.2-2017 (0.9 / 1.0 / 1.1) 1800.2-2020 (1.0 … 3.2)
Deprecated kodun durumu Varsayılan açık. UVM_NO_DEPRECATED tanımlanırsa kapanır Varsayılan kapalı. UVM_ENABLE_DEPRECATED_API tanımlanırsa açılır; 1.2'de deprecated olan her şey tamamen silindi "Bu sürümde hiçbir şey deprecate edilmedi." Önceki sürümlerde silinen pek çok API // @uvm-compat etiketiyle geri getirildi ve varsayılan olarak derlenir
Standart dışı API nasıl işaretlenir? İşaretlenmez @uvm-ieee (standart), @uvm-contrib (standarda önerilecek), @uvm-accellera (uygulamaya özel) Aynı üçlü + @uvm-compat
Standarttan sapmalar Standart = kütüphane, sapma kavramı yok DEVIATIONS.md: 10 madde DEVIATIONS.md: 3 madde
Uyumluluk paketi — — uvm_compat_pkg (compat/)

Etiket sayıları eğilimi somutlaştırır:

Kit @uvm-ieee @uvm-contrib @uvm-accellera @uvm-compat
2017-0.9 1.634 0 0 0
2017-1.0 1.636 34 56 0
2020-2.0 1.765 76 87 120
2020.3.0 1.765 90 113 122
2020.3.1 1.765 95 113 148
2020.3.2 1.765 119 114 155

@uvm-ieee sayısı 2020-2.0'dan sonra sabittir: standart metni değişmedi, kütüphane standardın etrafına büyüdü. @uvm-contrib sayısındaki artış ise Accellera'nın bir sonraki IEEE revizyonuna taşımayı düşündüğü API'lerin (phase hopper, process guard, test runner, polling API…) listesidir.

Deprecated politikasındaki bu salınım (1.2'de "her şey var", 2017'de "temizlik", 2020'de "geri getir") tesadüf değil. 2017 kitleri sektörde beklenenden yavaş benimsendi; en sık şikâyet, çalışan 1.2 kodunun derlenmemesiydi. 2020 kitlerinin README'si bunu açıkça kabul eder: "Geçişi kolaylaştırmak için önceki sürümlerde kaldırılmış birçok deprecated özellik yeniden eklendi." Yani 1.2 kodunuz 2020.3.x ile, 2017-1.0 ile olduğundan daha kolay derlenir.

1.2 → 1800.2-2017: Büyük Temizlik ve Yeniden Tasarım

Bu geçiş yedi kit içindeki en büyük kırılmadır: 14 sınıf silindi, 15 sınıf eklendi, 160'tan fazla metot ve 80'den fazla makro kaldırıldı.

Silinenler: OVM mirasının sonu

UVM 1.1 ve 1.2'de "deprecated" damgası taşıyan ve UVM_NO_DEPRECATED ile kapatılabilen her şey 2017 kitinden fiziksel olarak çıkarıldı:

Kaldırılan Yerine ne kullanılır? Not
uvm_component::stop(), stop_phase(), kill(), do_kill_all(), status(); uvm_root::stop_request(), global_stop_request(); global uvm_test_done Faz objection'ları (phase.raise_objection / drop_objection) OVM'den gelen "stop request" mekanizmasının tamamı
uvm_component::set_config_int/string/object(), get_config_*() uvm_config_db#(T)::set/get 2020'de @uvm-compat olarak geri geldi
Sequencer içi sequence kütüphanesi: add_sequence(), remove_sequence(), start_default_sequence(), get_seq_kind(), num_sequences() uvm_sequence_library sınıfı; varsayılan sequence için uvm_config_db ile default_sequence Beraberinde `uvm_sequence_utils, `uvm_sequencer_utils, `uvm_update_sequence_lib* makroları ve uvm_deprecated_defines.svh dosyası gitti
Hazır sequence'ler: uvm_random_sequence, uvm_exhaustive_sequence, uvm_simple_sequence (uvm_sequence_builtin.svh) Kendi sequence'leriniz ya da uvm_sequence_library
uvm_report_object::report_hook(), report_info_hook(), …, report_header(), report_summarize(), die(), set_report_max_quit_count() uvm_report_catcher, uvm_report_server::get_server() Hook'lar 2020'de compat olarak geri geldi
uvm_report_object::get_report_server() uvm_report_server::get_server() ya da uvm_coreservice_t::get().get_report_server() 2020.3.1'de compat olarak geri geldi
uvm_printer_knobs (public knobs alanı) uvm_printer::set_*() erişimcileri Sınıf m_uvm_printer_knobs adıyla iç kullanıma alındı
uvm_comparer::init(), print_rollup(); uvm_table_printer::calculate_max_widths() — Uygulama detayıydı
uvm_scope_stack, uvm_status_container, uvm_bogus_class — İç sınıflar
uvm_config_object_wrapper — 2020'de geri geldi
uvm_tlm_time sınıfı uvm_time (dosya adı uvm_tlm_time.svh oldu; typedef uvm_time uvm_tlm_time korunuyor) Mevcut kod derlenir
uvm_path_e uvm_door_e (typedef uvm_door_e uvm_path_e korunuyor); set_default_path() → set_default_door() UVM_FRONTDOOR / UVM_BACKDOOR değerleri aynı

Bazı silinenler "sessiz" davranış değişikliği yarattı. Örneğin uvm_sequence_base 1.2'de somut bir sınıftı; 1800.2'de virtual class oldu. uvm_sequence_base s = new("s") yazan kod artık derlenmez. 1.2'nin uvm_sequence#(REQ,RSP) sınıfı zaten virtual idi; değişen yalnızca tabandır.

Yeniden tasarlananlar: Policy mimarisi ve do_execute_op

1800.2'nin kalbindeki değişiklik, print/copy/compare/pack/record işlemlerinin tek bir çatı altına alınmasıdır. 1.2'de bu işlemleri yürüten uvm_printer, uvm_comparer, uvm_packer ve uvm_recorder sınıfları birbirinden bağımsızdı; kopyalama ise uvm_object::copy() içinde elle yazılmıştı. 1800.2'de:

  • uvm_policy adlı ortak bir taban sınıf geldi. Tüm policy'ler ondan türer; flush(), aktif nesne yığını (push_active_object / get_active_object_depth) ve genişletme mekanizması (set_extension / get_extension) ortaktır.
  • uvm_copier adında yeni bir policy eklendi; copy() artık bir copier nesnesiyle çalışır ve uvm_object::do_copy() kancası bu policy üzerinden çağrılır.
  • Her policy'nin varsayılan örneği get_default() / set_default() statik metotlarıyla yönetilir. uvm_coreservice_t de get_default_printer(), get_default_packer(), get_default_comparer(), get_default_copier() kazandı.
  • uvm_object tek bir yeni kanca aldı: do_execute_op(uvm_field_op op). Field makroları artık her işlem için ayrı kod üretmek yerine bu kancayı çağırır; uvm_field_op nesnesi hangi işlemin (UVM_COPY, UVM_COMPARE, UVM_PRINT…) hangi policy ve hangi karşı nesneyle (get_rhs()) yapıldığını taşır.

Pratikte en çok hissedilen yüz, printer yapılandırmasıdır:

// UVM 1.2: knobs alanlarına doğrudan erişim
uvm_table_printer p = new();
p.knobs.depth         = 1;
p.knobs.default_radix = UVM_DEC;
p.knobs.full_name     = 1;
tr.print(p);

// IEEE 1800.2: erişimci metotlar (knobs alanı iç kullanıma alındı)
uvm_table_printer p = new();
p.set_max_depth(1);
p.set_default_radix(UVM_DEC);
p.set_name_enabled(1);
tr.print(p);

İkinci biçim 1.2'de derlenmez, ilk biçim 2017-1.0'da derlenmez. 2020.3.2'de knobs alanı @uvm-compat etiketiyle yeniden public yapıldı; ancak 3.2 sürüm notu açıkça söylüyor: alanlar geri gelmiştir, 1800.2 öncesi biçimlendirme davranışı geri gelmemiştir. Yani eski kod derlenir ama çıktısı farklı olabilir.

do_execute_op, field makrolarına güvenmeyip kendi do_print/do_copy metotlarını yazan ekipler için şeffaftır. Makro kullananlar içinse önemli bir anlam değişikliği vardır:

// 1.2'de bu satır nesneyi print/compare/copy'ye dahil eder
// (FLAG'e örtük olarak UVM_ALL_ON eklenirdi):
`uvm_field_object(cfg, UVM_REFERENCE)

// 1800.2'de yalnızca açıkça etkinleştirilen işlemler yapılır;
// yukarıdaki satır hiçbir işlem seçmediği için NO-OP olur.
// Tüm sürümlerde aynı davranan yazım:
`uvm_field_object(cfg, UVM_ALL_ON | UVM_REFERENCE)

2017 kitleri bu değişikliği sessizce uygular. 2020 kitleri UVM/FIELDS/NO_FLAG kimlikli bir uyarı basar ve UVM_LEGACY_FIELD_MACRO_SEMANTICS tanımıyla eski davranışı seçme imkânı verir.

Diğer önemli 2017 değişiklikleri

Factory ve kayıt. Soyut sınıfların factory'ye kaydı için `uvm_object_abstract_utils / `uvm_component_abstract_utils makroları geldi; soyut sınıf create() edilemez ama override hedefi olabilir. 1.0'da `uvm_declare_type_alias ve set_type_alias() ile bir tipe ikinci bir kayıt adı verebilme özelliği eklendi. uvm_factory::is_type_registered() sorgusu geldi.

Çekirdek servis ve globaller. 1.2'de uvm_top const bir globaldi; 2017'de const kaldırıldı çünkü statik ilklendirme sırasındaki yarış koşulları (uvm_root::new() içinde atanıyor) buna izin vermiyordu. uvm_coreservice_t arayüzü 9 metottan 26 metoda çıktı: varsayılan policy'ler, kaynak havuzu (get_resource_pool), global tohum (get_global_seed) ve set_uvm_seeding() ile nesnelerin tam adlarına göre tohumlanması (rastgelelik kararlılığı için). uvm_default_printer, uvm_default_packer gibi global değişkenler silinmedi ama standardın parçası değildir; 2020'de @uvm-compat etiketini aldılar.

Fazlama. uvm_phase::set_max_ready_to_end_iterations() ile ready_to_end döngüsüne üst sınır geldi (standart gereği varsayılan 20). uvm_run_test_callback sınıfı run_test() öncesi/sonrası ve pre_abort kancaları sağladı. uvm_root::finish_on_completion ve enable_print_topology değişkenleri set_*() / get_*() erişimcilerine dönüştü.

Driver bağlantı denetimi (1.0). uvm_driver artık end_of_elaboration_phase'de seq_item_port bağlı değilse DRVCONNECT uyarısı verir. Sequencer'sız kullanılan driver'larda set_report_severity_id_action(UVM_WARNING, "DRVCONNECT", UVM_NO_ACTION) ile susturulabilir.

Register katmanı. İki geriye dönük uyumsuz düzeltme var. Mantis 6644: 1.2'de UVM_BIG_ENDIAN ayarlı bir uvm_reg_map byte sırasını fiilen değiştirmiyordu; 1800.2 bunu düzeltti, adapter'a giden veri artık gerçekten big-endian sıralı. Mantis 6773: map genişliğinden dar belleklerde adres hesabı "unpacked"tan "packed" adreslemeye geçti; N'inci kelimenin adresi 1.2'dekinden farklı çıkabilir ve bellek genişliğinin 8'in katı olması gerekir. Ayrıca uvm_reg_block::unlock_model(), set_lock(), wait_for_lock(), uvm_reg::unregister(), uvm_reg_map::unregister() ile model kilitlendikten sonra düzenlenebilir hâle geldi.

Packer. set_packed_bits/bytes/ints/longints() ve get_packed_*() aileleri eklendi. big_endian düğmesinin varsayılanı 1'den 0'a çevrildi ve bit akışının (stream) ham içeriği değişti: aynı nesneyi pack → unpack etmek her sürümde doğru sonuç verir, ama akışı dosyaya yazıp başka sürümle okumak vermez. 2020'deki uvm_compat_packer tam da bu durum için var.

Diğer. uvm_text_tr_database ve uvm_text_tr_stream ayrı dosyalara taşındı; uvm_component::set_tr_database() geldi. Resource veritabanı için uvm_resource_db_options ve `uvm_resource_read makro ailesi eklendi. DPI tarafında uvm_hdl_inca.c dosyası uvm_hdl_xcelium.c oldu (Cadence'ın simülatör adı değişikliğini yansıtır). UVM_VERSION_STRING makrosu yerine uvm_pkg::UVM_VERSION_STRING paket parametresi geldi; meraklısına not: 2017 kitlerinde `UVM_VERSION makrosu 2016 değerini taşır.

0.9 → 1.0: Olgunlaşma

Beş ay arayla çıkan iki 2017 kiti arasında 64 dosya değişti ama API neredeyse sabit kaldı (1 metot silindi, 17 eklendi). Asıl fark süreçte: 0.9'un README'si "dokümantasyon eksik, etiketsiz API'leri dikkatle kullanın" diyordu; 1.0 ile DEVIATIONS.md dosyası, @uvm-contrib / @uvm-accellera etiketleri ve üç adımlı geçiş tarifi geldi. 1.0'ın DEVIATIONS.md dosyasındaki 10 madde, standardın kendisinde yakalanan hataların listesidir: uvm_callbacks::get_all() örnek bazlı filtreleme yapamıyor, uvm_packer::set_packed_* metotları standartta signed ama uvm_object::pack unsigned, uvm_sequencer_base::ungrab() standartta task ama sıfır zamanda çağrılabilmesi için function olmalı gibi. Bu liste 1800.2-2020 revizyonunun gündemini oluşturdu; 2020 kitinin DEVIATIONS.md dosyasında 3 madde kalmıştır.

1800.2-2017 → 1800.2-2020 (2.0): Standart Düzeltmesi, Kütüphane Yeniden Yapılanması

IEEE 1800.2-2020, çalışma grubu başkanının ifadesiyle "2017'de hatalı belirtilmiş az sayıda API'nin düzeltilmesi"dir. Kütüphane tarafındaki değişiklik ise bundan çok daha büyüktür: 165 dosya, 19 yeni sınıf, 200 yeni metot. 2020-2.0 kitini 2017-1.0 ile karşılaştırınca dört ana tema çıkıyor.

1. Geri getirme politikası ve uvm_compat_pkg

Yukarıda anlatıldı: set_config_*, report hook'ları, uvm_config_object_wrapper gibi 2017'de silinen API'ler @uvm-compat etiketiyle döndü (120 etiket). Birbiriyle bir arada var olamayan API'ler için ise ayrı bir paket geldi: compat/uvm_compat_pkg.sv. İçinde iki şey var:

  • uvm_compat_packer: 1.2 ile bit-uyumlu akış üreten packer. Sürüm makrolarına bakarak ya kütüphanenin uvm_packer'ına typedef olur ya da onu genişletip 1.2 davranışını yeniden kurar.
  • uvm_compat_proxy_sequence#(): soyut hâle gelen uvm_sequence_base yerine örneklenebilen boş bir uvm_sequence#() alt sınıfı.

Paket, uvm_pkg ile aynı şekilde derleme listesine eklenir (+incdir+.../compat ve compat/uvm_compat_pkg.sv) ve herhangi bir uvm_pkg sürümüyle çalışmak üzere tasarlanmıştır.

2. Faz motoru: uvm_phase_hopper

1.2 ve 2017'de fazları yürüten kod uvm_phase::execute_phase() ve uvm_root içinde dağılmış durumdaydı. 2020-2.0 bunu uvm_phase_hopper adlı tek bir nesneye topladı: fazlar bir kuyruğa konur (try_put), oradan alınır (get/peek), durum geçişleri (start_phase, execute_phase, end_phase, cleanup_phase) hopper tarafından yürütülür ve nesneye uvm_coreservice_t::get().get_phase_hopper() ile erişilir. uvm_phase sınıfı get_predecessors(), get_successors(), is_jumping_forward(), is_ending_prematurely() gibi sorgular kazandı; execute_phase() ise sınıftan çıktı. Kullanıcı kodu için görünür etki küçüktür, ama faz davranışını özelleştirmek isteyenler artık uvm_phase_hopper'ı factory ile değiştirebilir. Sınıf @uvm-contrib etiketlidir; bir sonraki standarda aday.

3. Resource ve config veritabanı: performans ve takılabilirlik

Büyük hiyerarşilerde uvm_config_db::get() çağrılarının yavaşlığı yıllardır bilinen bir sorundu. 2020-2.0 buna üç cepheden saldırdı:

  • uvm_resource_pool kendi dosyasına ayrıldı ve iç tablolar (rtab, ttab) uvm_queue#(uvm_resource_base) yerine uvm_shared#(uvm_resource_base[$]) tipine geçti (geri dönüş için UVM_DISABLE_RESOURCE_POOL_SHARED_QUEUE).
  • uvm_cache, uvm_lru_cache ve uvm_regex_cache sınıfları geldi; UVM_ENABLE_RE_MATCH_CACHE tanımlanırsa düzenli ifade eşleştirme sonuçları önbelleğe alınır. Varsayılan olarak kapalıdır çünkü save/restore kullanan ortamlarda DPI tarafındaki önbellek doğru kaydedilmeyebilir.
  • uvm_config_db_implementation_t ve uvm_resource_db_implementation_t soyut sınıflarıyla veritabanı uygulaması takılabilir oldu; set_imp() / get_imp() ile kendi uygulamanızı yerleştirebilirsiniz. uvm_resource_debug sınıfı erişim kayıtlarını (audit trail) tutar.

Aynı aileden bir karar DEVIATIONS.md'ye girdi: standart, apply_config_settings()'in bileşen kapsamındaki tüm eşleşen alanları aramasını ister; bu her kaynak için regex denetimi demektir. Kütüphane yalnızca `uvm_field_* ile bildirilen alanları arar (CONFIG_FIELDS modu). LRM davranışı isteyen +define+UVM_COMPONENT_CONFIG_MODE_DEFAULT=CONFIG_STRICT ile derler.

4. Register katmanı ve mesajlaşma

  • uvm_reg_item alanlarına get_*() / set_*() erişimcileri geldi (alanların kendisi hâlâ public; rw.value[0] yazan kod kırılmaz).
  • uvm_reg_block::get_block_by_full_name(), uvm_reg::get_reg_by_full_name(), uvm_reg_field::get_field_by_full_name() statik metotları ile tam ada göre O(1) arama; +UVM_ENABLE_REG_LOOKUP_CACHE ile find_blocks() sonuçlarının önbelleği.
  • uvm_reg_err_service: uvm_reg hata mesajlarını üreten, factory ile değiştirilebilen sınıf.
  • uvm_reg_randval ve uvm_reg_field::set_rand_mode().
  • Mantis listesinden öne çıkan düzeltmeler: uvm_reg::mirror() map null iken kilidi bırakmıyordu (6273), predictor bus_op durumunu yok sayıyordu (5449), uvm_reg_field::write() istenen değeri set() ile güncellemiyordu (7240), bir sequence'i öldürmek get_next_item içinde takılmaya yol açabiliyordu (7276).
  • Komut satırı: +uvm_set_verbosity, +uvm_set_severity, +uvm_set_action için uvm_cmdline_set_* sınıfları ve kullanılmayan ayarları raporlayan uvm_cmdline_report.svh.
  • Mesaj makroları artık mesajı oluşturmadan önce action'ı da denetler (7715): UVM_NO_ACTION verilen bir ID için `uvm_info içindeki $sformatf hiç çalışmaz. Yeni `uvm_report_begin / `uvm_report_end makro çifti ise pahalı mesaj hazırlıklarını yalnızca mesaj basılacaksa yürüten bir kod bloğu açar.

Sürüm merdiveni

2020-2.0 ile koşullu derleme için tutarlı bir makro seti geldi:

// uvm_version_defines.svh (2020.3.2)
`define UVM_VERSION 2020
`define UVM_VERSION_POST_2017
`define UVM_VERSION_POST_2017_1_0
`define UVM_VERSION_POST_2017_1_1
`define UVM_VERSION_POST_2020_1_0
`define UVM_VERSION_POST_2020_1_1
`define UVM_VERSION_POST_2020_2_0
`define UVM_VERSION_POST_2020_3_0   // 3.1'de unutulmuştu, 3.2'de eklendi (Mantis 8514)
`define UVM_VERSION_POST_2020_3_1
`define UVM_MAJOR_REV 2020
`define UVM_MINOR_REV 3.2
`define UVM_POST_VERSION_1_1
`define UVM_POST_VERSION_1_2

Her sürüm, kendisinden önceki tüm sürümlerin POST makrosunu tanımlar; böylece "en az X sürümü" denetimi tek `ifdef ile yapılır. 1.2 ise UVM_MAJOR_REV_1, UVM_MINOR_REV_2, UVM_VERSION_1_2 ve UVM_POST_VERSION_1_1 makrolarını tanımlar.

2020.3.0 (Şubat 2024): Deneysel Polling ve Process Guard

Beş yeni dosya, 36 yeni metot; dört ana başlık:

Polling API (deneysel). uvm_hdl_polling sınıfı, hiyerarşik bir sinyal yolunu string olarak alır (register_hdl_path("top.dut.ready")) ve değişimini wait_for_hdl_change() göreviyle ya da uvm_hdl_polling_cbs::do_on_path_change() callback'iyle izler. Register modelindeki volatile alanları donanım değiştirdiğinde tahmin (prediction) güncellemek için tasarlandı. Arka planda VPI value-change callback'leri kullanır (dpi/uvm_hdl_polling.c); performans için uvm_polling_backdoor ile kendi backdoor'unuzu yazabilirsiniz. Tamamı UVM_ENABLE_EXPERIMENTAL_POLLING_API tanımının arkasındadır ve README "API değişebilir" uyarısı taşır.

uvm_process_guard. Bir SystemVerilog process nesnesini sarar ve süreç FINISHED ya da KILLED durumuna geçtiğinde do_trigger() kancasını çağırır. Kütüphane bunu iki kritik yerde kullanıyor: uvm_reg_frontdoor register erişimi sırasında öldürülürse atomic_unlock() ile kilidi bırakır; uvm_sequence_base::process_guard_triggered() ise öldürülen sequence'lerin arkada bıraktığı kaynakları temizler. 2020-2.0'daki "sequence kill → hang" düzeltmesinin genelleştirilmiş hâlidir.

Diğer. uvm_phase_hopper::schedule_phase(); uvm_resource#(T)::get_by_name() / get_by_type() metotlarının dönüşü; CONTRIBUTING.md ve DEVELOPMENT.md ile halka açık katkı süreci; tüm dosyalara git izleme başlıkları.

2020.3.1 (Ağustos 2024): Uyumluluk Dalgası

On yedi dosyalık küçük bir sürüm ama 11 maddelik düzeltme listesinin yarısı "Compatibility:" ile başlıyor. Geri gelenler: uvm_event#(T)::add_callback() / delete_callback(), uvm_transaction::begin_event / end_event, 21 adet `uvm_print_int3, `uvm_print_object_queue3 tarzı sayı sonekli yazdırma makrosu ve uvm_report_object::get_report_server(). Buna ek olarak:

  • +uvm_set_verbosity=comp,ID,UVM_HIGH,phase,time biçiminde sıfır dışı zaman verildiğinde çalışmayan ayar düzeltildi (7365).
  • uvm_bit_vector_utils#(T)::to_string() / from_string(): belgelenmemiş ve ölçeklenmeyen uvm_bitstream_to_string yardımcılarının yerini aldı (5000).
  • uvm_packer_array_extension: dizi pack/unpack işlemlerini policy genişletmesi olarak işaretleme (8446).
  • transaction_id için açık tip (7340) ve static const sınıf üyelerindeki statik ilklendirme yarışlarının giderilmesi (8376, GitHub #6). Bu son madde, GitHub deposunun halka açılmasının ilk somut meyvesidir: hata bir GitHub issue olarak geldi.

2020.3.2 (Ağustos 2026): Verilator, 4-State Register ve run_test Refaktörü

En yeni kit 21 Mantis düzeltmesi, 5 yeni dosya ve 8 yeni sınıf içeriyor. Üç başlık öne çıkıyor.

Verilator arka ucu. src/dpi/uvm_hdl_verilator.c eklendi ve uvm_hdl.c artık #ifdef VERILATOR dalı içeriyor; dosyanın telif satırlarında Marvell ve NVIDIA'nın 2026 tarihli katkıları var. Bu, resmî UVM kitinde ilk kez açık kaynak bir simülatörün HDL erişim (backdoor) hedefi olarak tanınmasıdır. UVM'i Verilator ile çalıştırmak hâlâ simülatör tarafında ciddi SystemVerilog sınıf desteği gerektirir; ama kütüphane tarafındaki kapı açılmıştır.

4-state register verisi. UVM_REG_4STATE_DATA_TYPE tanımlanırsa register modeli bit yerine logic tabanlı veri tipi (UVM_REG_DATA_TYPE) kullanır; X/Z yayılımı register seviyesinde görünür olur. Bellek ve koşum süresi maliyeti yüzünden varsayılan kapalıdır ve README geriye dönük uyumluluk garantisi vermez.

run_test ve çekirdek yaşam döngüsü. uvm_root::run_test() artık işi uvm_test_runner sınıfına devreder; test adının çözülmesi, uvm_test_top'un yaratılması, fazların hopper'a verilmesi ve rapor özeti bu sınıfta sıralanmış adımlardır. uvm_run_test_callback, daha genel uvm_core_state_callback sınıfının bir alt sınıfı oldu; çekirdek UVM_CORE_PRE_RUN → RUNNING → POST_RUN → FINISHED durumlarından geçerken callback'ler tetiklenir. Statik ilklendirme yarışlarını bitirmek için uvm_deferred_initialization.svh ve iki yeni makro geldi:

package my_pkg;
  int my_value;
  static function void init_my_value();
    uvm_cmdline_processor clp = uvm_cmdline_processor::get_inst();
    string s;
    my_value = clp.get_arg_value("+MY_VALUE=", s) ? s.atoi() : 10;
  endfunction
  // Çekirdek servis hazır olduktan sonra, run_test() öncesinde çalışır
  `uvm_post_init_decl(init_my_value())
endpackage

`uvm_post_init_decl zaman tüketmeyen, `uvm_pre_run_decl ise run_test() içinde zaman tüketebilen ve process başlatabilen eylemler içindir. Aynı ihtiyaçtan doğan uvm_sequence_library_adder, sequence library'ye sequence eklemeyi uvm_init() sonrasına erteler (8562).

Diğer düzeltmeler. uvm_reg_block::get_block_by_name() / get_reg_by_name() alt bloklardaki ve uvm_reg_file içindeki öğeleri kaçırabiliyordu (8572, 8573) ve yalnızca lock_model() sonrası çalışıyordu (8599); uvm_printer döngüsel nesne grafiklerinde sonsuz döngüye girebiliyordu (8522); test sonunda sonsuz çalışan sequence'ler için basılan SEQPRTZMB uyarısı susturuldu (8716, isteyen UVM_SEQPRTZMB_WARN_ON_TEST_END ile geri açar); uvm_sequence_base::kill_child_sequences() eklendi; uvm_tr_handle_t tipi uvm_component'in transaction API'lerinden geçirildi (8550).

Pratik Rehber

Hangi sürümü seçmeli?

Durum Öneri Gerekçe
UVM öğreniyorum, EDA Playground kullanıyorum UVM 1.2 Tüm simülatörlerde hazır; bu sitedeki dersler onunla doğrulandı; kavramlar 1800.2'de aynı
Yeni proje / yeni VIP 2020.3.x (simülatörünüzün paketlediği en yeni) Standart uyumlu, geri uyumluluk en geniş, hata düzeltmeleri en güncel
1.2 ile yazılmış büyük kod tabanını taşıyacağım Doğrudan 2020.3.x 2017 kitleri değil: 2020, 2017'nin sildiği API'lerin çoğunu geri getirdi
Simülatör üreticisinin referans ortamı 2017-1.1 2017-1.1'de kalın ama kodu 2020-uyumlu yazın UVM_ALL_ON açık yazımı, uvm_config_db, erişimci metotlar her sürümde çalışır
Verilator ile deniyorum 2020.3.2 uvm_hdl_verilator.c ilk kez bu kitte

1.2 kodunu 1800.2'ye taşırken kontrol listesi

Accellera'nın 2017-1.0 README'sindeki üç adımlı tarif hâlâ geçerlidir: önce 1.2'yi UVM_NO_DEPRECATED ile derleyin (1.2 içinde deprecated kullanımını yakalar), sonra 1800.2'yi UVM_ENABLE_DEPRECATED_API ile derleyin, en sonunda tanım olmadan derleyin. 2020 kitlerinde ikinci adım büyük ölçüde gereksizdir çünkü uyumluluk API'leri zaten açıktır; onun yerine derleyici çıktısında UVM/FIELDS/NO_FLAG ve DRVCONNECT uyarılarını tarayın.

Kodda aranacaklar ve karşılıkları:

// 1) set_config_* → uvm_config_db
set_config_int("env.agent.*", "is_active", UVM_ACTIVE);          // 1.2 (2017'de yok, 2020'de compat)
uvm_config_db#(int)::set(this, "env.agent.*", "is_active", UVM_ACTIVE);

// 2) Field makrolarında açık bayrak
`uvm_field_object(cfg, UVM_REFERENCE)                             // 1800.2'de NO-OP
`uvm_field_object(cfg, UVM_ALL_ON | UVM_REFERENCE)                // her sürümde aynı

// 3) uvm_sequence_base örneği
uvm_sequence_base seq = new("seq");                               // 1800.2'de derlenmez (soyut)
uvm_compat_pkg::uvm_compat_proxy_sequence#() seq = new("seq");    // ya da kendi boş alt sınıfınız

// 4) Printer ayarları
printer.knobs.depth = 1;                                          // 2017'de erişilemez, 2020'de compat
printer.set_max_depth(1);

// 5) Test bitişi
uvm_test_done.drop_objection(this);                               // 1800.2'de yok
phase.drop_objection(this);

// 6) Report server'a erişim
uvm_report_server rs = get_report_server();                       // 2017'de yok, 2020.3.1'de compat
uvm_report_server rs = uvm_report_server::get_server();

// 7) TLM2 zamanı ve register kapısı (typedef'ler sayesinde eski adlar da derlenir)
uvm_tlm_time t = new("t");   →   uvm_time t = new("t");
uvm_path_e path;             →   uvm_door_e door;

Derleme hatası vermeyen ama davranışı değişen noktalar daha tehlikelidir; bunları test sonuçlarında arayın:

  • Register map UVM_BIG_ENDIAN ise adapter'a gelen byte sırası değişti.
  • Map genişliğinden dar bellekler için adres hesabı değişti; bellek genişliği 8'in katı olmalı.
  • uvm_packer akışının ham içeriği ve big_endian varsayılanı değişti; akışı dosyaya yazan/okuyan kod için uvm_compat_packer.
  • Sequence'e geç gelen response artık info değil warning üretir.
  • Field makrosunda bayrak verilmemişse işlem artık yapılmaz (yukarıdaki 2. madde).

Sürümü koddan tespit etmek

// Çalışma zamanında
`uvm_info("VER", uvm_revision_string(), UVM_NONE)
// 1.2       : UVM-1.2
// 2017-1.0  : Accellera:1800.2-2017:UVM:1.0
// 2020.3.2  : Accellera:1800.2:UVM:2020.3.2

// Derleme zamanında
`ifdef UVM_VERSION_POST_2020_2_0
  // uvm_phase_hopper, uvm_reg_item erişimcileri, uvm_report_begin vb. kullanılabilir
`elsif UVM_VERSION_POST_2017
  // 1800.2-2017 ya da 2020-1.x
`elsif UVM_VERSION_1_2
  // UVM 1.2
`endif

UVM_VERSION_POST_2017 makrosunun yalnızca 2020 kitlerinde tanımlı olduğuna dikkat edin; 2017 kitlerini ayırt etmek için uvm_pkg::UVM_VERSION_STRING parametresine bakmak gerekir.

Bu Sitedeki Derslerle İlişkisi

UVM serisindeki sekiz ders EDA Playground'da UVM 1.2 ile çalıştırıldı. Öğretilen her kavram (bileşen hiyerarşisi, fazlar, objection, uvm_config_db, factory override, TLM analysis port, sequence/sequencer el sıkışması, virtual sequence) 1800.2-2020'de aynı adlarla ve aynı anlamla vardır. Derslerdeki kod, aşağıdaki dört alışkanlıkla yazıldığı için 2020.3.x kitiyle de derlenir:

  1. Konfigürasyon yalnızca uvm_config_db ile yapıldı, set_config_* hiç kullanılmadı.
  2. Transaction sınıflarında field makroları yerine açık do_copy / do_compare / convert2string yazıldı; bayrak semantiği sorunu oluşmaz.
  3. uvm_sequence_base hiçbir yerde doğrudan örneklenmedi.
  4. Test bitişi her zaman faz objection'larıyla yönetildi.

Bir şirkette 1800.2 kitiyle karşılaştığınızda değişen şey kavramlar değil, kütüphanenin kenarlarıdır: printer ayarları, packer akışı, register katmanının adres aritmetiği ve kaldırılıp geri gelen birkaç yardımcı. Bu yazıdaki tablolar o kenarları bulmanız için hazırlandı.

Kaynaklar