batasan waktu untuk sirkuit sinkronisasi bus

10

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_pathadalah 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?

Ben Voigt
sumber
1
Ini akan lebih baik di situs Desain FPGA yang diusulkan tetapi proposal itu belum mencapai versi beta.
Ben Voigt
Bisakah Anda memposting definisi jam untuk src_clk dan dest_clk? Apakah mereka terkait dengan cara apa pun (kelipatan sinkron)? Jika itu adalah jam yang tidak terkait maka biasanya menggunakan set_false_path dalam situasi ini.
Andy
@Andy: Saya menambahkan beberapa detail. Terima kasih telah membantu dengan ini.
Ben Voigt

Jawaban:

9

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_clkdan slow_clkkarena saya pikir itu lebih jelas untuk ilustrasi.

Opsi 1: nonaktifkan waktu dengan set_false_path

Solusi termudah adalah set_false_pathdengan menonaktifkan waktu antara jam:

set_false_path -from [get_clocks fast_clk] -to [get_clocks slow_clk]
set_false_path -from [get_clocks slow_clk] -to [get_clocks fast_clk]

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_pathumumnya 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.

set_multicycle_path 2 -from [get_clocks slow_clk] -to [get_clocks fast_clk] -end -setup
set_multicycle_path 1 -from [get_clocks slow_clk] -to [get_clocks fast_clk] -end -hold

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 -holdpenyesuaian 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 -endke -start:

set_multicycle_path 2 -from [get_clocks fast_clk] -to [get_clocks slow_clk] -start -setup
set_multicycle_path 1 -from [get_clocks fast_clk] -to [get_clocks slow_clk] -start -hold

Opsi 3: tentukan persyaratan langsung dengan set_max_delay

Ini mirip dengan efek set_multicycle_pathtetapi menghemat harus memikirkan hubungan tepi dan efek pada kendala terus.

set_max_delay 10 -from [get_clocks fast_clk] -to [get_clocks slow_clk]
set_max_delay 10 -from [get_clocks slow_clk] -to [get_clocks fast_clk]

Anda mungkin ingin memasangkan ini dengan set_min_delaycek ditahan, atau membiarkan cek bawaan ditahan di tempat. Anda juga dapat melakukan set_false_path -holduntuk 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:

1     2     3
4   5   6   7

Pemeriksaan pengaturan default menggunakan tepi 2 dan 6. Pemeriksaan penahanan standar menggunakan tepi 1 dan 4.

Menerapkan batasan multi-siklus 2 dengan -endmenyesuaikan 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.

Andy
sumber
2

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
1

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.

fbo
sumber
Terlihat seperti apa? set_false_path -from ready_spin -to ready_spin_q2? Dan set_false_path -from data -to rx_data?
Ben Voigt
set_false_path -from src_clk -to ready_spinSaya tidak yakin pantas untuk menempatkan jalur yang salah pada data karena Anda tidak menyinkronkannya.
fbo
0

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).

supercat
sumber
Bukankah set_multicycle_pathcara 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 memperbarui data. Saya kira saya bisa secara khusus membuat blok DFF di sana :(
Ben Voigt
@ BenVoigt: Saya pikir "set_multicycle_path" lebih sering digunakan untuk memberi tahu validator pengaturan waktu bahwa rantai logika kombinatorial antara dua titik kait harus diizinkan untuk mengambil N (Tc) -Ts-Tp (N kali waktu siklus dikurangi waktu sampel dikurangi latch) waktu propagasi) bukan hanya Tc-Ts-Th. Saya tidak tahu bagaimana hal seperti itu akan berinteraksi dengan mengunci oleh jam yang berbeda.
supercat