1. Pengenalan
Apakah peranan blok always dalam Verilog?
Dalam Verilog HDL, bahasa penerangan perkakasan yang digunakan secara meluas dalam reka bentuk litar digital, blok always memainkan peranan penting. Daripada menerangkan tingkah laku perkakasan seperti perisian, Verilog mewakili litar dengan mentakrifkan “di bawah keadaan apa isyarat berubah”. Antara ini, blok always adalah konstruk dasar yang digunakan untuk menerangkan tindakan apa yang perlu dilaksanakan apabila keadaan tertentu berlaku.Mengapa kita perlukan blok always?
Dalam Verilog, terdapat dua jenis tingkah laku litar utama yang boleh anda terangkan:- Logik gabungan : output berubah serta-merta apabila input berubah
- Logik siri : output berubah selaras dengan isyarat jam atau peristiwa masa
Penetapan assign yang ringkas tidak boleh mengendalikan keadaan kompleks atau elemen ingatan. Inilah di mana blok always masuk.
Sebagai contoh, untuk menerangkan percabangan bersyarat atau tingkah laku flip-flop, anda memerlukan blok always dengan struktur kawalan seperti if atau case.Corak biasa blok always
Blok always mempunyai beberapa corak penggunaan biasa bergantung pada jenis litar yang direka:always @(*) → Digunakan untuk logik gabunganalways @(posedge clk) → Logik siri yang dicetuskan pada naik semula jamalways @(posedge clk or negedge rst) → Logik siri dengan reset asinkron atau kawalan lebih kompleks
Oleh itu, memahami blok always, sintaks teras Verilog, adalah langkah pertama yang penting untuk pereka perkakasan.Tujuan artikel ini
Artikel ini menyediakan panduan komprehensif kepada blok always dalam Verilog, meliputi sintaks asas, penggunaan praktikal, kesilapan biasa, dan sambungan SystemVerilog.- Belajar cara betul menulis blok
always - Faham mengapa ralat sintesis berlaku
- Jelaskan perbezaan antara
= dan <= - Elakkan kesilapan pemula biasa
Kami bertujuan menjadikannya panduan praktikal dan mudah difahami untuk sesiapa yang mempunyai soalan sedemikian.
2. Sintaks Asas dan Jenis Blok always
Sintaks asas blok always
Dalam Verilog, blok always melaksanakan pernyataan berulang berdasarkan senarai kepekaan khusus. Sintaks asasnya ialah:always @(sensitivity list)
begin
// statements
end
Bahagian utama di sini ialah “senarai kepekaan,” yang mentakrifkan isyarat mana yang mencetuskan pelaksanaan apabila ia berubah.Menggunakan always @(*) untuk logik gabungan
Dalam logik gabungan, output mesti dikemas kini serta-merta setiap kali input berubah. Dalam kes ini, gunakan @(*) sebagai senarai kepekaan.always @(*) begin
if (a == 1'b1)
y = b;
else
y = c;
end
Ini bermakna setiap kali a, b, atau c berubah, blok always dilaksanakan dan mengira semula y.Kelebihan menggunakan @(*)
- Secara automatik memasukkan semua isyarat yang dirujuk dalam senarai kepekaan
- Mencegah ketidakpadanan antara hasil simulasi dan sintesis
Menggunakan always @(posedge clk) untuk logik siri
Dalam logik siri, perubahan keadaan berlaku selaras dengan isyarat jam. Dalam kes ini, nyatakan posedge clk dalam senarai kepekaan.always @(posedge clk) begin
q <= d;
end
Di sini, nilai d dikunci ke dalam q pada naik semula jam. Pengendali <= mewakili penetapan tidak menyekat, yang merupakan standard untuk logik siri.posedge vs negedge
posedge : dicetuskan pada naik semulanegedge : dicetuskan pada turun semula
Pilih tepi yang sesuai bergantung pada keperluan reka bentuk.always @(posedge clk or negedge rst) dengan reset asinkron
Dalam litar yang lebih kompleks, fungsi reset sering diperlukan. Blok dengan reset asinkron boleh ditulis sebagai:always @(posedge clk or negedge rst) begin
if (!rst)
q <= 1'b0;
else
q <= d;
end
Dengan penerangan ini, q direset serta-merta apabila rst rendah, sebaliknya ia menangkap d pada tepi jam.
Litar Gabungan vs Litar Siri
| Jenis Litar | always | Kelaku |
|---|
| Kombinasi | always @(*) | Keluaran dikemas kini serta‑merta berdasarkan input |
| Berurutan | always @(posedge clk) | Beroperasi selaras dengan jam |
3. Jenis Penetapan dalam Blok always
Dua operator penetapan dalam Verilog
Di dalam blok always Verilog, anda boleh menggunakan dua operator penetapan yang berbeza:= : Penetapan blocking<= : Penetapan non-blocking
Salah faham perbezaan ini boleh menyebabkan kelakuan yang tidak dijangka danketidakserasian antara simulasi dan sintesis**, menjadikannya salah satu titik paling penting untuk dipelajari.Penetapan blocking (=)
Penetapan blocking dilaksanakan secara berurutan, satu pernyataan selepas yang lain, serupa dengan aliran kawalan perisian.always @(*) begin
a = b;
c = a;
end
Di sini, a = b dilaksanakan terlebih dahulu, dan kemudian c = a menggunakan nilai a yang telah dikemas kini. Susunan pernyataan secara langsung mempengaruhi kelakuan logik.Kes penggunaan biasa
- Struktur kawalan (
if , case ) dalam logik kombinasi - Logik yang tidak memerlukan penyimpanan keadaan
Penetapan non-blocking (<=)
Penetapan non-blocking bermakna semua pernyataan dinilai secara serentak dan dikemas kini bersama, mencerminkan sifat paralel perkakasan.always @(posedge clk) begin
a <= b;
c <= a;
end
Kedua-dua a <= b dan c <= a dinilai pada masa yang sama dan dikemas kini selepas tepi jam. Oleh itu, c menerima nilai a yang sebelumnya.Kes penggunaan biasa
- Logik berurutan (daftar, flip-flop)
- Penyebaran keadaan tepat merentasi pelbagai isyarat
Perbandingan Penetapan Blocking vs Non-blocking
| Ciri | Menyekat (=) | Tidak menyekat (<=) |
|---|
| Urutan pelaksanaan | Berurutan, satu demi satu | Dinilai serentak, dikemas kini bersama |
| Penggunaan biasa | Logik kombinasi | Logik berurutan |
| Kemas kini masa | Segera diterapkan | Diterapkan selepas tepi jam |
| Kesilapan biasa | Penjanaan latch yang tidak diingini | Nilai tidak dikemas kini atau disebarkan seperti yang dijangkakan |
Apa yang berlaku jika anda mencampurkannya?
Anda harus mengelakkan pencampuran = dan <= dalam blok yang sama atau pada isyarat yang sama. Contohnya:always @(posedge clk) begin
a = b;
a <= c;
end
Kod ini menetapkan a dua kali menggunakan kaedah yang berbeza, menjadikan nilai akhir yang disimpan tidak jelas, yang mungkin kelihatan betul dalam simulasi tetapi gagal dalam perkakasan.Garis panduan penggunaan
- Gunakan
= dalam blok always @(*) (kombinasi) - Gunakan
<= dalam blok always @(posedge clk) (berurutan)
Mengikuti peraturan mudah ini membantu mengelakkan banyak kesilapan umum. 
4. Perangkap Umum dan Amalan Terbaik dengan Blok always
Kesilapan dalam senarai sensitiviti
Senarai sensitiviti yang tidak betul boleh menyebabkan pepijat tersembunyi
Dalam Verilog, senarai sensitiviti (@(...)) mesti menakan secara eksplisit semua isyarat yang memicu pelaksanaan. Berikut ialah contoh di mana hanya sebahagian isyarat yang disertakan:always @(a) begin
if (b)
y = 1'b1;
else
y = 1'b0;
end
Kod ini tidak bertindak balas kepada perubahan pada b. Akibatnya, apabila b berubah, y tidak akan dikemas kini, menyebabkan pepijat.Penyelesaian: gunakan @(*)
Untuk mengelakkan kehilangan isyarat dalam senarai sensitiviti, gunakan @(*) seperti berikut:always @(*) begin
if (b)
y = 1'b1;
else
y = 1'b0;
end
@(*) secara automatik menyertakan semua isyarat yang dirujuk dalam blok, meningkatkan kebolehselenggaraan dan kebolehpercayaan.Penjanaan latch yang tidak diingini
Ketiadaan cabang if/case menghasilkan latch
Jika tidak semua kes menetapkan nilai, alat sintesis mengandaikan bahawa pembolehubah mesti “menyimpan” nilainya, menghasilkan latch:always @(*) begin
if (enable)
y = d; // y is undefined when enable == 0
end
Walaupun kelihatan baik, latch dimasukkan kerana y tidak dikemas kini apabila enable adalah 0.Penyelesaian: sentiasa tetapkan nilai
always @(*) begin
if (enable)
y = d;
else
y = 1'b0; // y is always defined
end
Dengan menetapkan nilai secara eksplisit dalam setiap kes, anda dapat mengelakkan latch yang tidak diingini.Syarat yang terlalu kompleks
Pernyataan if atau case yang rumit boleh menyebabkan kelakuan tidak ditakrifkan atau logik yang hilang jika tidak semua syarat diliputi.Kesilapan biasa: tiada default dalam pernyataan case
always @(*) begin
case(sel)
2'b00: y = a;
2'b01: y = b;
2'b10: y = c;
// 2'b11 not handled → y may be undefined
endcase
end
Penyelesaian tambahkan klausa default
always @(*) begin
case(sel)
2'b00: y = a;
2'b01: y = b;
2'b10: y = c;
default: y = 1'b0; // safety net
endcase
end
Menambah default memastikan output sentiasa ditakrifkan, meningkatkan ketahanan reka bentuk.Mengawal pelbagai isyarat dalam satu blok
Apabila mengawal pelbagai isyarat dalam satu blok always yang sama, susunan penugasan dan kes yang terlepas boleh menghasilkan kebergantungan yang tidak diingini. Dalam reka bentuk yang kompleks, pertimbangkan memecah logik kepada beberapa blok always untuk kejelasan dan keselamatan.Ringkasan perangkap umum
| Problem | Punca | Solution |
|---|
| Output tidak dikemas kini | Isyarat yang hilang dalam senarai sensitiviti | Gunakan @(*) untuk pengesanan automatik |
| Latch dijana | Tidak semua cabang memberikan nilai | Sentiasa sertakan else atau default |
| Kelakuan tidak ditakrifkan | Penyataan kes tiada syarat | Tambah default cawangan |
| Kawalan yang terlalu kompleks | Terlalu banyak isyarat dalam satu blok | Sila berikan potongan HTML Bahasa Inggeris yang anda ingin terjemahkan ke dalam Bahasa Melayu (Malaysia). Saya akan memecahkannya kepada beberapa blok `always` seperti yang diminta. |
5. Sambungan always dalam SystemVerilog
always_comb: untuk logik kombinasi
Gambaran keseluruhan
always_comb berfungsi serupa dengan always @(*) tetapi secara jelas menunjukkan logik kombinasi.always_comb begin
y = a & b;
end
Manfaat utama
- Secara automatik menjana senarai sensitiviti
- Alat memberi amaran apabila latch yang tidak diingini dijana
- Mencegah konflik dengan pembolehubah yang telah ditakrifkan sebelumnya
Contoh (Verilog vs SystemVerilog)
// Verilog
always @(*) begin
y = a | b;
end
// SystemVerilog
always_comb begin
y = a | b;
end
always_ff: untuk logik berurutan (flip‑flop)
Gambaran keseluruhan
always_ff direka untuk logik berurutan yang dipacu jam, memerlukan syarat tepi yang jelas seperti posedge clk atau negedge rst.always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n)
q <= 1'b0;
else
q <= d;
end
Manfaat utama
- Hanya membenarkan penugasan tidak‑blok (
<= ) - Alat memeriksa ketepatan senarai sensitiviti
- Kebolehbacaan kod meningkat kerana jelas berurutan
always_latch: untuk logik berasaskan latch
Gambaran keseluruhan
always_latch digunakan apabila anda secara sengaja menggambarkan kelakuan latch. Walau bagaimanapun, dalam kebanyakan reka bentuk, latch yang tidak diingini harus dielakkan.always_latch begin
if (enable)
q = d;
end
Perkara yang perlu diingat
- Jika beberapa cabang melangkau penugasan, latch akan dicipta secara eksplisit
- Hanya gunakan apabila latch memang diperlukan
Ringkasan penggunaan SystemVerilog
| Construct | Tujuan | Equivalent in Verilog | Ciri-ciri |
|---|
always_comb | Logik kombinasi | always @(*) | Senarai sensitiviti automatik, pengesanan latch |
always_ff | Selipar | always @(posedge clk) | Penetapan selaras jam, lebih selamat |
always_latch | Pengunci | always @(*) | Reka bentuk latch eksplisit, pengesanan ralat |
SystemVerilog semakin menjadi piawaian
Dalam pembangunan moden, konstruksi SystemVerilog semakin disarankan untuk kebolehbacaan dan keselamatan. Dengan pemeriksaan sintaks yang lebih baik, penggunaan always_ff dan always_comb membantu mengelakkan isu “kelihatan betul tetapi tidak berfungsi”. Terutama dalam projek berskala besar atau berpasukan, konstruksi yang jelas menjadikan niat reka bentuk lebih terang, meningkatkan semakan kod dan kebolehselenggaraan.
6. Soalan Lazim: Soalan Umum Mengenai Blok always
Bahagian ini menjawab soalan-soalan yang kerap ditanya mengenai blok always dalam Verilog dan SystemVerilog, menumpukan pada kebimbangan praktikal yang sering timbul dalam projek reka bentuk. Ia merangkumi isu-isu umum bagi peringkat pemula hingga pertengahan yang dilihat dalam pembangunan dunia sebenar.S1. Haruskah saya menggunakan if atau case di dalam blok always?
J. Ia bergantung pada bilangan dan kerumitan syarat:- Untuk 2–3 syarat mudah →
if lebih mudah dibaca - Untuk pelbagai keadaan berbeza →
case lebih jelas dan menyatakan niat dengan lebih baik
Menggunakan case juga menegakkan jangkaan untuk meliputi semua kes yang mungkin, membantu mengurangkan kesilapan.S2. Apa yang berlaku jika saya terlepas isyarat dalam senarai sensitiviti?
J. Jika senarai sensitiviti tidak lengkap, beberapa perubahan isyarat tidak akan memicu blok, menyebabkan output menjadi lapuk. Ini boleh menyebabkan perbezaan antara simulasi dan sintesis. Untuk mengelakkan ini, sentiasa gunakan @(*) atau always_comb dalam SystemVerilog.S3. Mengapa latch yang tidak diingini muncul dalam reka bentuk saya?
J. Jika pernyataan if atau case tidak menugaskan nilai kepada pembolehubah dalam setiap laluan yang mungkin, alat sintesis menganggap nilai tersebut perlu dipertahankan, dan mencipta latch.Contoh buruk:
always @(*) begin
if (en)
y = d; // y is held when en == 0
end
Penyelesaian:
always @(*) begin
if (en)
y = d;
else
y = 1'b0; // always assigned
end
S4. Bolehkah saya mencampur = dan <= dalam blok yang sama?
A. Secara umum, tidak. Campuran penugasan blok dan bukan blok dalam blok yang sama, terutamanya pada isyarat yang sama, boleh menyebabkan simulasi berfungsi tetapi perkakasan gagal.- Logik kombinasional → gunakan
= (blok) - Logik sekuensial → gunakan
<= (bukan blok)
Peraturan ibu jari:
Sentiasa gunakan gaya penugasan yang konsisten setiap isyarat.Q5. Apakah perbezaan antara always_ff dan always @(posedge clk)?
A. Secara fungsional, ia bertindak sama, tetapi always_ff lebih selamat dan lebih mudah dibaca.| Perbandingan | always @(posedge clk) | always_ff |
|---|
| Sensitiviti | Mesti ditentukan secara manual | Diperiksa secara automatik |
| Ralat penugasan | Penetapan blok mungkin dapat dikompil | Penetapan tidak sah menyebabkan ralat |
| Kebolehbacaan | Mungkin mengaburkan niat litar | Jelas menunjukkan logik berurutan |
Q6. Adakah boleh mengawal pelbagai isyarat dalam satu blok always?
A. Ia mungkin, tetapi jika terlalu banyak isyarat disertakan, penyahpepijatan dan penyelenggaraan menjadi sukar. Pertimbangkan memisahkan kepada pelbagai blok apabila:- Setiap output bertindak secara bebas
- Anda campur logik sinkron dan asinkron
Q7. Apakah yang berlaku jika saya gunakan <= dalam logik kombinasional?
A. Ia mungkin masih berfungsi dalam simulasi, tetapi semasa sintesis, ia boleh mencipta logik tidak dijangka. Patuh kepada penugasan blok (=) untuk logik kombinasional.
7. Kesimpulan
Blok always adalah asas reka bentuk Verilog
Dalam reka bentuk perkakasan Verilog, blok always adalah alat kuat yang membolehkan anda menerangkan litar kombinasional dan sekuensial. Ia bukan sahaja meluaskan kemungkinan reka bentuk anda tetapi juga menjelaskan aliran kawalan dan masa. Untuk pemula dan profesional, always adalah pengetahuan penting.Pengambilan utama
- Perbezaan dan penggunaan
always @(*) vs always @(posedge clk) - Perbezaan antara
= (blok) dan <= (bukan blok) penugasan - Cara mengelak kesilapan biasa seperti penjanaan latch dan senarai kepekaan tidak lengkap
- Sambungan SystemVerilog (
always_comb , always_ff , always_latch ) untuk reka bentuk lebih selamat - Jawapan praktikal kepada soalan dunia sebenar biasa (FAQ)
Ketepatan menentukan kualiti
Dalam penerangan perkakasan, apa yang anda tulis adalah tepat apa yang dilaksanakan. Walaupun kesilapan kecil boleh menjadi kesilapan perkakasan. Oleh kerana always adalah pusat kepada tingkah laku, ketepatan, jenis penugasan yang betul, dan liputan keadaan lengkap adalah kritikal.Langkah seterusnya: maju ke reka bentuk tahap lebih tinggi
Setelah anda menguasai blok always, anda boleh terus ke:- Reka bentuk Finite State Machine (FSM)
- Pipelining dan arkitektur streaming
- Membangunkan IP cores dan pelaksanaan FPGA
Anda juga boleh meluaskan kemahiran anda dengan belajar SystemVerilog dan VHDL, menjadikan anda boleh menyesuaikan diri merentasi persekitaran reka bentuk yang berbeza.Fikiran akhir untuk pereka perkakasan
Dalam reka bentuk litar, ia bukan hanya tentang “membuatnya berfungsi.” Apa yang diperlukan adalah tingkah laku betul, ketahanan untuk perubahan masa depan, dan kejelasan untuk pembangunan pasukan.
Melalui artikel ini, kami harap anda memperoleh pengetahuan asas blok always dan penghargaan untuk amalan reka bentuk selamat dan boleh dipercayai.