Saya memiliki sirkuit bus sinkronisasi untuk melewati register luas di seluruh domain jam.
Saya akan memberikan deskripsi yang disederhanakan, menghilangkan logika reset asinkron.
Data dihasilkan dalam satu jam. Pembaruan jauh berbeda (setidaknya selusin) jam:
PROCESS (src_clk)
BEGIN
IF RISING_EDGE(clock) THEN
IF computation_done THEN
data <= computation;
ready_spin <= NOT ready_spin;
END IF;
END IF;
END PROCESS;
Sinyal kontrol untuk data baru, yang dikodekan NRZI (jadi kata yang valid di bus sesuai dengan transisi pada sinyal kontrol). Sinyal kontrol melewati rantai DFF yang bertindak sebagai sinkronisasi.
PROCESS (dest_clk)
BEGIN
IF RISING_EDGE(dest_clk) THEN
ready_spin_q3 <= ready_spin_q2;
ready_spin_q2 <= ready_spin_q1;
ready_spin_q1 <= ready_spin;
END IF;
END PROCESS;
Rangkaian sinkronisasi memperkenalkan penundaan singkat, yang menyediakan banyak waktu untuk menstabilkan bus data; bus data disampel secara langsung tanpa risiko metastabilitas:
PROCESS (dest_clk)
BEGIN
IF RISING_EDGE(dest_clk) THEN
IF ready_spin_q3 /= ready_spin_q2 THEN
rx_data <= data;
END IF;
END IF;
END PROCESS;
Ini mengkompilasi, dan bekerja dengan baik ketika disintesis menjadi FPGA Cyclone II. Namun, TimeQuest melaporkan pengaturan dan menahan pelanggaran waktu, karena tidak mengenali sinkronisasi. Lebih buruk, kata manual Quartus
Fokus pada peningkatan jalur yang menunjukkan kelonggaran terburuk. Fitter bekerja paling keras di jalur dengan kelonggaran terburuk. Jika Anda memperbaiki jalur ini, Fitter mungkin dapat meningkatkan jalur waktu gagal lainnya dalam desain.
Jadi saya ingin menambahkan batasan waktu yang tepat untuk proyek saya sehingga Quartus akan menghabiskan upaya Fitter pada bidang desain lainnya.
Saya cukup yakin itu set_multicycle_path
adalah perintah SDC (Synopsis Design Constraint) yang tepat, karena baris data akan memiliki beberapa siklus jam tujuan untuk distabilkan, tetapi saya tidak dapat menemukan contoh lengkap menggunakan perintah ini untuk menjelaskan logika crossing domain jam .
Saya benar-benar menghargai beberapa panduan tentang penulisan batasan waktu SDC untuk sinkronisasi. Jika Anda melihat masalah dengan pendekatan ini, harap beri tahu saya juga.
Detail jam:
Generator jam eksternal: Dua saluran, refclk = 20 MHz, refclk2 = refclk / 2 (10 MHz, dan yang terkait).
Altera PLL: src_clk = refclk * 9/5 = 36 MHz
Altera PLL: dest_clk = refclk2 * 10 = 100 MHz
Saya juga memiliki data yang menuju ke arah lain, dengan 100 MHz src_clk dan 36 MHz dest_clk.
TL; DR: Apa kendala waktu SDC yang benar untuk kode di atas?
Jawaban:
Saya tidak punya pengalaman dengan Quartus, jadi perlakukan ini sebagai saran umum.
Saat bekerja di jalur antara domain jam, alat timing memperluas jam ke kelipatan paling umum dari periode mereka dan memilih pasangan tepi terdekat.
Untuk jalur dari jam 36 MHz (27.777 ns) ke jam 100 MHz (10 ns), jika saya melakukan perhitungan cepat dengan benar, pasangan terdekat dari sisi naik adalah 138.888 ns pada jam sumber dan 140 ns pada jam tujuan. Itu secara efektif merupakan kendala 900 MHz untuk jalur tersebut! Tergantung pada pembulatan (atau untuk jam tanpa hubungan), itu bisa keluar lebih buruk dari itu.
Setidaknya ada tiga cara untuk menulis batasan untuk struktur ini. Saya akan menelepon jam
fast_clk
danslow_clk
karena saya pikir itu lebih jelas untuk ilustrasi.Opsi 1: nonaktifkan waktu dengan
set_false_path
Solusi termudah adalah
set_false_path
dengan menonaktifkan waktu antara jam:Ini tidak sepenuhnya benar, karena ada persyaratan waktu untuk sinkronisasi agar berfungsi dengan benar. Jika implementasi fisik menunda data terlalu banyak relatif terhadap sinyal kontrol, maka sinkronisasi tidak akan berfungsi. Namun, karena tidak ada logika apa pun di jalur, kecil kemungkinan batasan waktu akan dilanggar.
set_false_path
umumnya digunakan untuk jenis struktur ini, bahkan di ASIC, di mana upaya vs risiko tradeoff untuk kegagalan probabilitas rendah lebih berhati-hati daripada untuk FPGA.Opsi 2: kendurkan kendala dengan
set_multicycle_path
Anda dapat memberikan waktu tambahan untuk jalur tertentu dengan
set_multicycle_path
. Adalah lebih umum untuk menggunakan jalur multi-sepeda dengan jam yang terkait erat (misalnya berinteraksi 1X dan 2X jam), tetapi akan bekerja di sini jika alat mendukungnya secara memadai.Hubungan tepi default untuk pengaturan adalah siklus tunggal, yaitu
set_multicycle_path 1
. Perintah-perintah ini memungkinkan satu siklus lagi dari endpoint clock (-end
) untuk jalur pengaturan. The-hold
penyesuaian dengan nomor satu kurang dari kendala setup hampir selalu dibutuhkan ketika mengatur multi-jalur sepeda, untuk lebih lanjut lihat di bawah ini.Untuk membatasi lintasan di arah lain yang serupa (mengendurkan kendala dengan satu periode jam yang lebih cepat), ubah
-end
ke-start
:Opsi 3: tentukan persyaratan langsung dengan
set_max_delay
Ini mirip dengan efek
set_multicycle_path
tetapi menghemat harus memikirkan hubungan tepi dan efek pada kendala terus.Anda mungkin ingin memasangkan ini dengan
set_min_delay
cek ditahan, atau membiarkan cek bawaan ditahan di tempat. Anda juga dapat melakukanset_false_path -hold
untuk menonaktifkan cek terus, jika alat Anda mendukungnya.Detail pemilihan tepi berdarah untuk jalur multi-siklus
Untuk memahami penyesuaian penahanan yang dipasangkan dengan setiap penyesuaian pengaturan, pertimbangkan contoh sederhana ini dengan hubungan 3: 2. Setiap digit mewakili tepi jam naik:
Pemeriksaan pengaturan default menggunakan tepi 2 dan 6. Pemeriksaan penahanan standar menggunakan tepi 1 dan 4.
Menerapkan batasan multi-siklus 2 dengan
-end
menyesuaikan pengaturan default dan menahan pemeriksaan untuk menggunakan tepi berikutnya setelah apa yang awalnya mereka gunakan, berarti pemeriksaan pengaturan sekarang menggunakan tepi 2 dan 7 dan pemeriksaan tahan menggunakan tepi 1 dan 5. Untuk dua Jam pada frekuensi yang sama, penyesuaian ini masuk akal - setiap peluncuran data sesuai dengan satu tangkapan data, dan jika tepi tangkapan dipindahkan oleh satu, pemeriksaan penahanan juga harus bergerak dengan satu. Batasan semacam ini mungkin masuk akal untuk dua cabang dari satu jam tunggal jika salah satu cabang memiliki penundaan besar. Namun, untuk situasi di sini, pemeriksaan penahanan menggunakan tepi 1 dan 5 tidak diinginkan, karena satu-satunya cara untuk memperbaikinya adalah dengan menambahkan seluruh siklus clock keterlambatan di jalur.Batasan penahanan multi-siklus 1 (untuk penahanan, standarnya adalah 0) menyesuaikan tepi jam tujuan uesd untuk penangguhan cek mundur ke belakang dengan satu sisi. Kombinasi pengaturan MCP 2-siklus dan kendala MCP 1-siklus akan menghasilkan pemeriksaan pengaturan menggunakan tepi 2 dan 7, dan pemeriksaan tahan menggunakan tepi 1 dan 4.
sumber
Saya tidak tahu jawabannya untuk Altera, tetapi di Xilinx Land Anda dapat mengatur waktu tunda dari satu domain jam ke yang berikutnya. Anda harus menghitung matematika (tergantung desain), tetapi biasanya yang terpendek dari dua periode jam. Pikirkan saat ini sebagai kemiringan maksimum antara dua sinyal (termasuk sinyal kontrol Anda), dan Anda dapat bekerja jika sirkuit sinkronisasi Anda akan dapat mengatasinya.
set_mulicycle_path bukan hal yang benar untuk digunakan karena itu biasanya akan menangani kasus ketika sumber dan tujuan berada pada domain jam yang sama. Sekali lagi, saya mendasarkan pengalaman Xilinx saya sehingga jarak tempuh Anda dapat bervariasi.
sumber
Saya pikir aman untuk meletakkan set_false_path di atas sinkronisasi.
Anda juga dapat memasukkan "set_global_assignment -name SYNCHRONIZER_IDENTIFICATION AUTO" di qsf untuk membantu Quartus melihat sinkronisasi.
sumber
set_false_path -from ready_spin -to ready_spin_q2
? Danset_false_path -from data -to rx_data
?set_false_path -from src_clk -to ready_spin
Saya tidak yakin pantas untuk menempatkan jalur yang salah pada data karena Anda tidak menyinkronkannya.Saya menduga masalahnya adalah bahwa sementara Anda mungkin tahu bahwa sinyal bus tidak akan berubah di dekat titik di mana mereka terkunci, perangkat lunak tidak mengetahuinya. Taruhan terbaik Anda mungkin adalah untuk memberi tahu perangkat lunak secara eksplisit bahwa sinyal bus yang masuk disinkronkan dengan jam bus, dan nonaktifkan setiap optimasi sebelum tempat di mana Anda benar-benar mengunci mereka (pengoptimal secara teoritis dapat mengganti sirkuit Anda dengan satu yang akan setara dengan jika input benar-benar sinkron, tetapi yang dapat dilemparkan untuk loop jika mereka berubah pada siklus clock bahwa sirkuit yang Anda gambar tidak akan peduli).
sumber
set_multicycle_path
cara untuk memberi tahu synthesizer / timing analyzer seberapa sering sinyal sumber dapat berubah? Dan saya tidak yakin apa yang Anda maksud dengan "jam bus", ada sinyal bus di sini melintasi domain jam, jadi jam mana yang Anda sebut "jam bus"? Saya pikir Anda benar bahwa masih ada metastabilitas jika synthesizer memperkenalkan gangguan selama periode ketika saya tidak memperbaruidata
. Saya kira saya bisa secara khusus membuat blok DFF di sana :(