Contoh desain ini menunjukkan prosedur kustom, yang dapat Anda gunakan dalam file SDC, yang mengembalikan daftar semua clock yang mengumpan pin. Prosedur ini dapat membantu jika Anda perlu membuat clock yang dihasilkan tanpa mengetahui nama clock lain dalam desain. Contoh Sederhanakan Penggunaan Kembali Desain dengan Batasan SDC Dinamis memberikan detail lebih lanjut dan contoh cara menggunakan prosedur kustom yang dijelaskan pada halaman ini.
Kode lengkap untuk prosedur ini ada di bagian bawah halaman, mengikuti penjelasan lengkap tentang cara kerja prosedur. Untuk menggunakan prosedur kustom get_clocks_driving_pins dalam file SDC, pastikan prosedur telah ditentukan, lalu hubungi seperti perintah SDC lainnya. Ada dua cara mudah untuk memastikan prosedur telah didefinisikan sebelum digunakan:
- Simpan kode prosedur dalam berkas SDC terpisah dan sertakan berkas SDC dalam proyek.
- Salin dan tempel kode prosedur di bagian atas file SDC apa pun, sebelum prosedur kustom get_clocks_driving_pins digunakan.
Berkas SDC Terpisah
Menyimpan kode prosedur dalam file SDC terpisah menjaga kode terpisah dari batasan lainnya dan memudahkan penggunaan kembali proyek lain. Jika Anda menggunakan file SDC terpisah, Anda harus menambahkan file SDC dengan prosedur ke daftar file dalam proyek, dan itu harus muncul di atas file SDC apa pun yang menggunakan prosedur. Mendaftarkannya di atas file SDC lainnya memastikan bahwa perangkat lunak Quartus® II menentukan prosedur sebelum menggunakannya, setiap kali file SDC dibaca.
Salin dan Tempel
Menyalin dan menempelkan kode prosedur dalam berkas SDC yang sama dengan hasil yang digunakan akan menghasilkan lebih sedikit file SDC dalam suatu proyek. Jika Anda membuat file SDC untuk modul yang akan digunakan kembali oleh desainer lain, mungkin lebih mudah untuk menyertakan semua batasan dan kode pendukung dalam satu file SDC. Anda harus menyertakan kode prosedur dalam berkas SDC sebelum penggunaan prosedur pertama sehingga didefinisikan sebelum digunakan. Biasanya, Anda akan meletakkannya di bagian atas file untuk memenuhi persyaratan ini.
Operasi Skrip
Mendapatkan daftar semua clock dalam desain yang mengumpan pin memerlukan tiga langkah utama:
- Dapatkan semua clock dan buat pemetaan dari node target mereka hingga clock di node target.
- Dapatkan daftar node dengan clock yang berada di jalur kipas ke pin yang ditentukan.
- Dari daftar node tersebut, temukan node yang paling dekat dengan pin yang ditentukan dan kembalikan clock pada node tersebut.
Langkah 1. Dapatkan Semua Clock dan Buat Pemetaan
Kode Tcl berikut mendapatkan semua clock dalam desain dan membuat pemetaan (dengan susunan Tcl) dari node hingga clock di node.
penangkapan { array unset nodes_with_clocks } array set nodes_with_clocks [list] # Iterate over each clock in the design foreach_in_collection clock_id [all_clocks] { set clock_name [get_clock_info -name $clock_id] # Setiap clock diterapkan ke node. Dapatkan koleksi node target foreach_in_collection target_id [get_clock_info -targets $clock_id] { # Hubungkan nama clock dengan set node target target_name [get_node_info -name $target_id] lappend nodes_with_clocks($target_name) $clock_name } }
Clock virtual tidak memiliki target, jadi tidak ada pemetaan yang pernah dibuat dengan clock virtual. Dalam kode prosedur lengkap yang tercantum di bawah ini, informasi tentang jenis node target (register, pin, sel, atau port) disimpan untuk digunakan nanti.
Langkah 2. Dapatkan Node dengan Clock di Fanin Path
Langkah kedua adalah menemukan subset node dengan clock yang berada di jalur kipas ke pin yang ditentukan. Untuk setiap node dengan clock (ditemukan pada langkah 1), masukkan kipas ke pin yang ditentukan melalui node. Jika ada kipas, node berada di jalur kipas ke pin. Jika tidak ada kipas, node tidak berada di jalur kipas ke pin.
Kode Tcl berikut ini mengubah semua node dengan clock dari langkah 1 dan menggunakan perintah get_fanins untuk menentukan apakah setiap node berada di jalur kipas dari pin yang ditentukan. Jika node berada di jalur kipas dari pin yang ditentukan, node disimpan di daftar pin_drivers.
set pin_drivers [list] # Iterate di semua node dalam pemetaan yang dibuat pada langkah 1 foreach node_with_clocks [array names nodes_with_clocks] { # Dapatkan kipas ke pin yang ditentukan melalui set node saat ini fanin_col [get_fanins -clock -through $node_with_clock $pin_name] # Jika ada setidaknya satu node fanin, node saat ini berada di jalur # fanin ke pin yang ditentukan, jadi simpanlah. jika { 0 < [get_collection_size $fanin_col] } { lappend pin_drivers $node_with_clocks } }
Kode prosedur lengkap yang tercantum di bawah ini menggunakan informasi tambahan tentang jenis node untuk menentukan koleksi jenis spesifik untuk nilai -through dalam perintah get_fanins.
Langkah 3. Temukan Node Paling Dekat dengan Pin Tertentu
Variabel pin_drivers kini memiliki daftar semua node dengan clock yang berada di jalur kipas ke pin yang ditentukan. Langkah ini menemukan node yang paling dekat dengan pin yang ditentukan. Meskipun ada lebih dari satu node dalam daftar pin_drivers, kode mengambil dua node pertama dalam daftar dan memeriksa apakah ada di jalur kipas ke yang lain. Jika berada di jalur kipas, node pertama harus lebih jauh dari pin daripada node kedua, sehingga dapat dihapus dari daftar.
sementara { 1 < [llength $pin_drivers] } { # Dapatkan dua node pertama dalam daftar pin_drivers yang diatur node_a [lindex $pin_drivers 0] diatur node_b [lindex $pin_drivers 1] # Periksa apakah node_b berada di jalur kipas dari node_a yang diatur fanin_col [get_fanins -clock -through $node_b $node_a] # Jika ada setidaknya satu node fanin, node_b harus jauh lebih jauh dari pin yang ditentukan daripada pin yang node_a. # Jika tidak ada node fanin, node_b harus lebih dekat ke pin yang ditentukan # daripada yang node_a. jika { 0 < [get_collection_size] } { # node_a lebih dekat ke pin. # Hapus node_b dari kumpulan daftar pin_drivers pin_drivers [lreplace $pin_drivers 1 1] } else { # node_b lebih dekat ke pin. # Hapus node_a dari set daftar pin_drivers pin_drivers [lreplace $pin_drivers 0] } } # Satu node tersisa di pin_drivers adalah node yang mengarahkan set pin yang ditentukan node_driving_pin pin_drivers [lindex $pin_drivers 0] # Cari clock pada node di pemetaan dari langkah 1 dan kembalikan $nodes_with_clocks($node_driving_pin
Kode prosedur lengkap yang tercantum di bawah ini menggunakan informasi tambahan tentang jenis node untuk menentukan koleksi jenis spesifik untuk nilai -through dalam perintah get_fanins.
Kode Prosedur Lengkap
Kode lengkap untuk prosedur kustom get_clocks_driving_pin tercantum di bawah ini. Ini termasuk pemeriksaan kesalahan tambahan dan fitur dukungan yang tidak dijelaskan secara terperinci di atas.
proc get_clocks_feeding_pin { pin_name } { # Sebelum langkah 1, lakukan pemeriksaan kesalahan untuk memastikan bahwa pin_name # yang diteruskan ke prosedur cocok dengan satu dan hanya satu pin. # Kembalikan galat jika tidak cocok dengan satu dan hanya satu pin. set pin_col [get_pins -compatibility_mode $pin_name] jika { 0 == [get_collection_size $pin_col] } { return -code error "Tidak ada pin yang cocok $pin_name" } elseif { 1 < [get_collection_size $pin_col] } { galat return -code "$pin_name cocok [get_collection_size $pin_col]\ pin tetapi harus cocok hanya satu" } # Variabel inisialisasi yang digunakan dalam penangkapan prosedur { array unset nodes_with_clocks } penangkapan { array unset node_types } array set nodes_with_clocks [list] rangkaian array node_types [daftar] diatur pin_drivers [daftar] # Langkah 1. Dapatkan semua clock dalam desain dan buat pemetaan dari # node target hingga clock pada node target # Iterate pada setiap clock dalam desain foreach_in_collection clock_id [all_clocks] { set clock_name [get_clock_info -name $clock_id] set clock_target_col [get_clock_info -targets $clock_id] # Setiap jam diterapkan ke node. Dapatkan koleksi node target yang foreach_in_collection target_id [get_clock_info -targets $clock_id] { # Hubungkan nama clock dengan set node target target_name [get_node_info -name $target_id] lappend nodes_with_clocks((get_node_info -name $target_id] lappend nodes_with_clocks(() $target_name) $clock_name # Simpan jenis node target untuk penggunaan nanti target_type [get_node_info -type $target_id] set node_types($target_name) $target_type } } # Langkah 2. Dapatkan daftar node dengan clock yang berada di jalur # fanin ke pin yang ditentukan # Iterate di semua node dalam pemetaan yang dibuat pada langkah 1 foreach node_with_clocks [nama array nodes_with_clocks] { # Gunakan jenis node target untuk membuat koleksi # khusus tipe untuk nilai -through di perintah get_fanins. switch -exact -- $node_types($node_with_clocks) { "pin" { set through_col [get_pins $node_with_clocks] } "port" { set through_col [get_ports $node_with_clocks] } "cell" { set through_col [get_cells $node_with_clocks] } "reg" { set through_col [get_registers $node_with_clocks] } default { return -code error "$node_types($node_with_clocks) tidak ditangani\ sebagai jenis fanin berdasarkan skrip" } } # Dapatkan kipas ke pin yang ditentukan melalui set node saat ini fanin_col [get_fanins -clock -through $through_col $pin_name] # Jika ada setidaknya satu node fanin, node saat ini berada di jalur # fanin ke pin yang ditentukan, jadi simpan. jika { 0 < [get_collection_size $fanin_col] } { lappend pin_drivers $node_with_clocks } } # Sebelum langkah 3, lakukan pemeriksaan kesalahan untuk memastikan bahwa setidaknya satu # node dengan clock dalam desain berada di jalur kipas ke # pin yang ditentukan. jika { 0 == [llength $pin_drivers] } { galat return -code "Tidak dapat menemukan node dengan clock yang drive $pin_name" } # Langkah 3. Dari daftar node yang dibuat pada langkah 2, temukan node # paling dekat dengan pin yang ditentukan dan kembalikan clock pada node tersebut. sementara { 1 < [llength $pin_drivers] } { # Dapatkan dua node pertama dalam daftar pin_drivers yang diatur node_a [lindex $pin_drivers 0] set node_b [lindex $pin_drivers 1] # Gunakan jenis node target untuk membuat koleksi # spesifik-jenis untuk nilai -through di perintah get_fanins. switch -exact -- $node_types($node_b) { "pin" { set through_col [get_pins $node_b] } "port" { set through_col [get_ports $node_b] } "cell" { set through_col [get_cells $node_b] } "reg" { set through_col [get_registers $node_b] } default { return -code error "$node_types($node_b) tidak ditangani\ sebagai jenis fanin berdasarkan skrip" } } # Periksa apakah node_b berada di jalur kipas node_a set fanin_col [get_fanins -clock -through $through_col $node_a] # Jika ada setidaknya satu node fanin, node_b harus jauh lebih jauh dari pin yang ditentukan daripada node_a. # Jika tidak ada node fanin, node_b harus lebih dekat ke pin yang ditentukan # daripada yang node_a. jika { 0 < [get_collection_size $fanin_col] } { # node_a lebih dekat ke pin. # Hapus node_b dari set daftar pin_drivers pin_drivers [lreplace $pin_drivers 1 1] } else { # node_b lebih dekat ke pin # Hapus node_a dari set daftar pin_drivers pin_drivers [lrange $pin_drivers 1 end] } } # Satu node tersisa di pin_drivers adalah node yang menggerakkan set pin yang ditentukan node_driving_pin [lindex $pin_drivers 0] # Cari clock pada node di pemetaan dari langkah 1 dan kembalikan $nodes_with_clocks ($node_driving_pin) }