Sederhanakan Penggunaan Kembali Desain dengan Batasan SDC Dinamis

author-image

Oleh

Ketika Anda membuat blok desain atau komponen HDL yang dapat digunakan kembali dalam banyak desain, Anda mungkin perlu membuat batasan SDC untuk melakukannya. Hal ini berguna untuk membuat batasan yang tidak perlu diedit oleh desainer yang menggunakan kembali komponen. Kendala harus generik, sehingga blok bekerja terlepas dari di mana blok disematkan dalam hierarki desain, dan dinamis sehingga mereka bekerja terlepas dari bagaimana blok desain terhubung. Jika kendala harus diedit secara manual untuk mencerminkan perubahan desain, mereka akan menjadi tidak sinkron jika desainer membuat perubahan desain tanpa juga memperbarui kendala.

Contoh desain ini membahas teknik untuk membuat batasan SDC dinamis yang mengatasi dua masalah berikut:

  • Menentukan nama I/O tingkat atas yang terhubung langsung ke modul tingkat rendah
  • Membuat clock yang dihasilkan pada logika dalam modul tingkat rendah

Diagram pada Gambar 1 menunjukkan desain yang sangat sederhana untuk contoh ini. Ini termasuk dua contoh blok desain yang dapat digunakan kembali dengan nama reusable_block, yang ditampilkan dalam warna kuning. Gambar 2 menunjukkan konten desain reusable_block. reusable_block berfungsi sebagai clock laju data ganda untuk bus keluaran sinkron sumber. Keluarannya harus dihubungkan ke keluaran tingkat atas. Batasan untuk reusable_block harus mencakup clock yang dihasilkan, karena fungsi output sebagai clock sinkron sumber.

Gambar 1. Contoh sirkuit untuk contoh desain.

Gambar 2. Konten reusable_block.

Menentukan Nama I/O Tingkat Atas

Batasan untuk reusable_block harus mengakomodasi perubahan pada nama I/O tingkat atas. Oleh karena itu, nama I/O tingkat atas harus ditentukan selama analisis kompilasi atau waktu. Perintah get_fanouts Tcl mengembalikan kumpulan ID yang mewakili port atau register yang merupakan kipas dari nama tertentu. Perintah get_fanouts Tcl menggunakan netlist waktu yang ada selama analisis kompilasi atau waktu, sehingga secara dinamis menentukan konektivitas terlepas dari nama node fanout. Kode Tcl berikut menunjukkan cara menggunakan get_fanouts untuk mendapatkan keluaran tingkat atas yang merupakan kipas langsung dari register tingkat rendah.

foreach_in_collection fanout_id [get_fanouts $low_level_register_name] { break }
set top_level_io_name [get_node_info -name $fanout_id]

Nama hierarki lengkap register tingkat rendah tidak harus diketahui, karena Anda dapat menggunakan wildcard dan bagian hierarki yang diketahui yang ada di blok desain yang dapat digunakan kembali untuk mencocokkannya. Contoh kode terakhir di halaman ini menunjukkan contoh cara mencocokkan nama register tingkat rendah.

Dalam desain pada Gambar 1, pin keluaran modul tingkat rendah terhubung langsung ke satu keluaran tingkat atas. Kode Tcl berikut menambahkan pemeriksaan galat untuk memastikan bahwa kipas register tingkat rendah hanya ke satu lokasi dan lokasi kipas adalah port output. Kode Tcl ini harus menjadi bagian dari berkas SDC yang membatasi reusable_block.

# Dapatkan penggemar set register level rendah
fanout_collection [get_fanouts $low_level_register_name]

# Pastikan hanya ada satu fanout yang diatur
num_fanouts [get_collection_size $fanout_collection]
jika { 1 != $num_fanouts } {
    return -code error "$low_level_register_name fans out to $num_fanouts \
        node tetapi harus memberi kipas ke satu."
}

# Dapatkan nama node fanout
foreach_in_collection fanout_id $fanout_collection { break }
set fanout_name [get_node_info -name $fanout_id]

# Pastikan node fanout adalah port output
jika { [catch { get_port_info -is_output_port $fanout_id } is_output] } { # Terdapat galat - tidak menyebar
    ke port return
    -code error "$low_level_register_name fans out to $fanout_name \
        yang bukan port" }
elseif { ! $is_ output } {
    # Tidak ada galat, tetapi port bukan port output
    yang mengembalikan kesalahan -code "$fanout_name bukan port output"
} lain { set
    top_level_io_name $fanout_name
} # top_level_io_name adalah

satu-satunya kipas low_level_register_name dan itu adalah
# port output

Membuat Clock yang Dihasilkan

Clock keluaran sinkron sumber harus didefinisikan sebagai clock yang dihasilkan, berdasarkan clock yang memberi makan register keluaran laju data ganda. Clock yang dihasilkan harus dibuat tanpa informasi yang dimasukkan secara manual tentang clock dalam desain, karena blok desain dapat diinteksi dalam desain apa pun dengan skema clocking apa pun.

Perintah SDC berikut menunjukkan cara sederhana untuk membuat clock yang dihasilkan untuk clock keluaran sinkron sumber untuk desain di Gambar 1, ketika lokasi dalam hierarki tidak diketahui.

create_generated_clock -name reusable_generated -source [get_pins \
    *|reusable_block_clock_out|altddio_out_component|auto_generated|ddio_outa[0]|muxsel] \
    $top_level_io_name

Ini adalah pendekatan sederhana yang bekerja untuk satu instantiasi reusable_block di mana saja dalam hierarki desain, tetapi tidak menangani beberapa instantiasi atau situasi multiclock. Ketika skema clocking tidak diketahui, batasan clock yang dihasilkan harus dapat menangani situasi di mana beberapa clock telah didefinisikan pada sinyal clock tunggal yang memakan blok desain. Beberapa clock pada sinyal clock tunggal sering ada dalam desain yang mendukung kecepatan protokol I/O yang berbeda, atau desain yang mendukung switchover clock untuk redundansi. Contoh clock yang dihasilkan sederhana di atas gagal dalam situasi multiclock karena tidak termasuk opsi -master_clock untuk membedakan antara beberapa clock sumber.

Untuk menangani beberapa instantiasi, gunakan loop untuk membuat clock unik yang dihasilkan untuk setiap instantiation. Untuk menangani situasi multiclock, gunakan prosedur kustom yang disebut get_clocks_driving_pin, yang dijelaskan dalam contoh desain Clocks Feeding a Pin. Untuk menggunakan prosedur kustom, Anda harus menyalinnya dari halaman contoh desain Clocks Feeding a Pin. Anda dapat menyimpannya sebagai file SDC terpisah yang ditambahkan ke proyek, atau menyalin dan menempelkannya ke dalam satu file SDC dengan semua batasan lain yang membatasi blok yang dapat digunakan kembali. Jika Anda menyimpannya sebagai file SDC yang ditambahkan ke proyek, pastikan file tersebut tercantum sebelum file SDC yang menggunakan prosedur kustom get_clocks_driving_pin.

Kode Tcl berikut menunjukkan cara membuat batasan clock yang dihasilkan pada output tingkat atas yang didorong oleh register tingkat rendah dalam desain yang ditunjukkan pada Gambar 1. Clock yang dihasilkan menggunakan output tingkat atas sebagai target mereka, dan pin lendir altddio_output register sebagai sumbernya. Kode menggunakan loop untuk iterasi melalui semua instansi reusable_block dalam desain, dan lingkaran bersarang untuk menangani situasi multiclock dengan prosedur kustom get_clocks_driving_pin. Ini mengasumsikan prosedur get_clocks_driving_pin telah didefinisikan.

# get_pins mengembalikan satu pin muxsel untuk setiap instantiation reusable_block
# foreach_in_collection iterate pada setiap pin muxsel
foreach_in_collection pin_id [get_pins -compatibility_mode \
    *|reusable_block_clock_out|altddio_out_component|auto_generated|ddio_outa[0]|muxsel] {

    # pin_name memiliki hierarki desain lengkap pin muxsel untuk satu #
    instantiasi set reusable_block
    pin_name [get_node_info -name $pin_id]
    
    # Gunakan kode yang ditunjukkan di atas, tanpa pemeriksaan kesalahan, untuk mendapatkan
    # nama keluaran tingkat atas
    foreach_in_collection port_id [get_fanouts $pin_name] { break }
    set port_name [get_node_info -name $port_id] # Ada beberapa clock yang
    
    memakan register altddio_output # Satu clock yang dihasilkan diperlukan untuk setiap clock yang memakan
    pin muxsel. Setiap clock yang memberi makan pin muxsel adalah master clock.
    foreach master_clock [get_clocks_feeding_pin $pin_name] { post_message

        "Membuat clock yang dihasilkan pada $port_name fed by $pin_name"
        # Buat clock yang dihasilkan dengan master clock yang sesuai.
        # Sumber adalah pin lendir sel altddio_output dalam
        # instantiasi saat ini dari reusable_block.
        # Nama adalah kombinasi dari master clock dan
        # nama hierarki penuh dari pin muxsel.
        # Target adalah port tingkat atas yang merupakan kipas pin muxsel.
        create_generated_clock -add -master_clock $master_clock \
            -source [get_pins $pin_name] -name ${master_clock}-${pin_name} \
            [get_ports $port_name]
    } }
}

Dengan kode ini dalam file SDC yang disertakan dalam proyek, semua instantiasi dari reusable_block secara otomatis dibatasi dengan clock yang dihasilkan. Clock yang dihasilkan selalu benar dan terbaru, bahkan dalam situasi berikut:

  • reusable_block disempurnakan atau dipindahkan ke titik lain dalam hierarki desain
  • I/Os tingkat atas diubah namanya
  • Desainer menggunakan beberapa definisi clock dalam desain

Isi halaman ini adalah kombinasi terjemahan manusia dan komputer dari konten berbahasa Inggris. Konten ini diberikan hanya untuk kenyamanan Anda serta sebagai informasi umum dan tidak bisa dianggap sebagai lengkap atau akurat. Jika terdapat kontradiksi antara versi bahasa Inggris halaman ini dan terjemahannya, versi bahasa Inggris akan didahulukan. Lihat versi bahasa Inggris halaman ini.