Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Industrial programming >> Verilog

Memahami Kontrol Penundaan Verilog: Teknik Waktu dan Praktik Terbaik

Terdapat dua jenis kontrol waktu dalam Verilog - delay dan event expressions. Kontrol delay hanyalah cara untuk menambahkan penundaan antara waktu simulator menemukan pernyataan dan saat sebenarnya mengeksekusinya. Event expression memungkinkan pernyataan ditunda hingga terjadinya beberapa peristiwa simulasi yang dapat berupa perubahan nilai pada jaringan atau variabel (implicit event) atau peristiwa yang dinamai secara eksplisit yang dipicu dalam prosedur lain.

Waktu simulasi dapat ditambah dengan salah satu metode berikut.

Gerbang dan jaringan yang dimodelkan untuk memiliki penundaan internal juga memajukan waktu simulasi.

Kontrol Penundaan

Jika ekspresi penundaan mengevaluasi ke nilai yang tidak diketahui atau impedansi tinggi, maka akan ditafsirkan sebagai penundaan nol. Jika mengevaluasi ke nilai negatif, maka akan ditafsirkan sebagai integer 2's complement unsigned dengan ukuran yang sama seperti variabel waktu.

`timescale 1ns/1ps
module tb;
  reg [3:0] a, b;
  initial begin
    {a, b} <= 0;
    $display ("T=%0t a=%0d b=%0d", $realtime, a, b);
    #10; a <= $random;
    $display ("T=%0t a=%0d b=%0d", $realtime, a, b);
    #10 b <= $random;
    $display ("T=%0t a=%0d b=%0d", $realtime, a, b);
    #(a) $display ("T=%0t After a delay of a=%0d units", $realtime, a);
    #(a+b) $display ("T=%0t After a delay of a=%0d + b=%0d = %0d units", $realtime, a, b, a+b);
    #((a+b)*10ps) $display ("T=%0t After a delay of %0d * 10ps", $realtime, a+b);
    #(b-a) $display ("T=%0t Expr evaluates to a negative delay", $realtime);
    #('h10) $display ("T=%0t Delay in hex", $realtime);
    a = 'hX; #(a) $display ("T=%0t Delay is unknown, taken as zero a=%h", $realtime, a);
    a = 'hZ; #(a) $display ("T=%0t Delay is in high impedance, taken as zero a=%h", $realtime, a);
    #1ps $display ("T=%0t Delay of 10ps", $realtime);
  end
endmodule

Perhatikan bahwa presisi timescale adalah 1ps dan oleh karena itu $realtime diperlukan untuk menampilkan nilai presisi untuk pernyataan dengan ekspresi penundaan (a+b)*10ps.

Log Simulasi

xcelium> run
T=0 a=x b=x
T=10000 a=0 b=0
T=20000 a=4 b=0
T=24000 After a delay of a=4 units
T=29000 After a delay of a=4 + b=1 = 5 units
T=29050 After a delay of 5 * 10ps
T=42050 Expr evaluates to a negative delay
T=58050 Delay in hex
T=58050 Delay is unknown, taken as zero a=x
T=58050 Delay is in high impedance, taken as zero a=z
T=58051 Delay of 10ps
xmsim: *W,RNQUIE: Simulation is complete.

Kontrol Peristiwa

Perubahan nilai pada jaringan dan variabel dapat digunakan sebagai peristiwa sinkronisasi untuk memicu eksekusi pernyataan prosedural lain dan merupakan peristiwa implisit. Peristiwa dapat juga berdasarkan arah perubahan seperti menuju 0 yang menjadikannya negedge dan perubahan menuju 1 menjadikannya posedge.

Transisi dari kondisi yang sama ke kondisi yang sama tidak dianggap sebagai tepi. Peristiwa tepi seperti posedge atau negedge hanya dapat terdeteksi pada LSB dari sinyal vektor atau variabel. Jika ekspresi mengevaluasi ke hasil yang sama, tidak dapat dianggap sebagai peristiwa.

module tb;
  reg a, b;
  initial begin
    a <= 0; #10 a <= 1; #10 b <= 1; #10 a <= 0; #15 a <= 1;
  end
  // Start another procedural block that waits for an update to
  // signals made in the above procedural block
  initial begin
    @(posedge a); $display ("T=%0t Posedge of a detected for 0->1", $time);
    @(posedge b); $display ("T=%0t Posedge of b detected for X->1", $time);
  end
  initial begin
    @(posedge (a + b)) $display ("T=%0t Posedge of a+b", $time);
    @(a) $display ("T=%0t Change in a found", $time);
  end
endmodule

Log Simulasi

ncsim> run
T=10 Posedge of a detected for 0->1
T=20 Posedge of b detected for X->1
T=30 Posedge of a+b
T=45 Change in a found
ncsim: *W,RNQUIE: Simulation is complete.

Peristiwa yang Dikenai

Kata kunci event dapat digunakan untuk mendeklarasikan peristiwa yang dinamai yang dapat dipicu secara eksplisit. Sebuah event tidak dapat menyimpan data apa pun, tidak memiliki durasi waktu dan dapat dibuat terjadi pada waktu tertentu. Peristiwa yang dinamai dipicu oleh operator -> dengan menambahkannya sebelum handle peristiwa yang dinamai. Peristiwa yang dinamai dapat ditunggu dengan menggunakan operator @ yang dijelaskan di atas.

module tb;
  event a_event;
  event b_event[5];
  initial begin
    #20 -> a_event;
    #30; ->a_event;
    #50 ->a_event;
    #10 ->b_event[3];
  end
  always @ (a_event) $display ("T=%0t [always] a_event is triggered", $time);
  initial begin
    #25; @(a_event) $display ("T=%0t [initial] a_event is triggered", $time);
    #10 @(b_event[3]) $display ("T=%0t [initial] b_event is triggered", $time);
  end
endmodule

Peristiwa yang dinamai dapat digunakan untuk menyinkronkan dua atau lebih proses yang berjalan secara bersamaan. Misalnya, blok always dan blok initial kedua disinkronkan oleh a_event. Peristiwa dapat dideklarasikan sebagai array seperti dalam kasus b_event yang merupakan array berukuran 5 dan indeks 3 digunakan untuk tujuan pemicu dan tunggu.

Log Simulasi

ncsim> run
T=20 [always] a_event is triggered
T=50 [always] a_event is triggered
T=50 [initial] a_event is triggered
T=100 [always] a_event is triggered
T=110 [initial] b_event is triggered
ncsim: *W,RNQUIE: Simulation is complete.

Operator Event or

Operator or dapat digunakan untuk menunggu hingga salah satu dari peristiwa yang terdaftar dipicu dalam ekspresi. Koma , juga dapat digunakan sebagai gantinya.

module tb;
  reg a, b;
  initial begin
    $monitor ("T=%0t a=%0d b=%0d", $time, a, b);
    {a, b} <= 0;
    #10 a <= 1; #5 b <= 1; #5 b <= 0;
  end
  // Use "or" between events
  always @ (posedge a or posedge b) $display ("T=%0t posedge of a or b found", $time);
  // Use a comma between
  always @ (posedge a, negedge b) $display ("T=%0t posedge of a or negedge of b found", $time);
  always @ (a, b) $display ("T=%0t Any change on a or b", $time);
endmodule

Log Simulasi

ncsim> run
T=0 posedge of a or negedge of b found
T=0 Any change on a or b
T=0 a=0 b=0
T=10 posedge of a or b found
T=10 posedge of a or negedge of b found
T=10 Any change on a or b
T=10 a=1 b=0
T=15 posedge of a or b found
T=15 Any change on a or b
T=15 a=1 b=1
T=20 posedge of a or negedge of b found
T=20 Any change on a or b
T=20 a=1 b=0
ncsim: *W,RNQUIE: Simulation is complete.

Daftar Ekspresi Peristiwa Implisit

Daftar sensitivitas atau daftar ekspresi peristiwa seringkali adalah penyebab umum banyak kesalahan fungsional dalam RTL. Ini karena pengguna mungkin lupa memperbarui daftar sensitivitas setelah memperkenalkan sinyal baru dalam blok prosedural.

module tb;
  reg a, b, c, d;
  reg x, y;
  // Event expr/sensitivity list is formed by all the
  // signals inside () after @ operator and in this case
  // it is a, b, c or d
  always @ (a, b, c, d) begin
    x = a | b;
    y = c ^ d;
  end
  initial begin
    $monitor ("T=%0t a=%0b b=%0b c=%0b d=%0b x=%0b y=%0b", $time, a, b, c, d, x, y);
    {a, b, c, d} <= 0;
    #10 {a, b, c, d} <= $random;
    #10 {a, b, c, d} <= $random;
    #10 {a, b, c, d} <= $random;
  end
endmodule

Log Simulasi

ncsim> run
T=0 a=0 b=0 c=0 d=0 x=0 y=0
T=10 a=0 b=1 c=0 d=0 x=1 y=0
T=20 a=0 b=0 c=0 d=1 x=0 y=1
T=30 a=1 b=0 c=0 d=1 x=1 y=1
ncsim: *W,RNQUIE: Simulation is complete.

Jika pengguna memutuskan untuk menambahkan sinyal baru e dan menangkap inversnya ke z, perhatian khusus harus diambil untuk menambahkan e juga ke dalam daftar sensitivitas.

module tb;
  reg a, b, c, d, e;
  reg x, y, z;
  // Add "e" also into sensitivity list
  always @ (a, b, c, d, e) begin
    x = a | b;
    y = c ^ d;
    z = ~e;
  end
  initial begin
    $monitor ("T=%0t a=%0b b=%0b c=%0b d=%0b e=%0b x=%0b y=%0b z=%0b", $time, a, b, c, d, e, x, y, z);
    {a, b, c, d, e} <= 0;
    #10 {a, b, c, d, e} <= $random;
    #10 {a, b, c, d, e} <= $random;
    #10 {a, b, c, d, e} <= $random;
  end
endmodule

Log Simulasi

ncsim> run
T=0 a=0 b=0 c=0 d=0 e=0 x=0 y=0 z=1
T=10 a=0 b=0 c=1 d=0 e=0 x=0 y=1 z=1
T=20 a=0 b=0 c=0 d=0 e=1 x=0 y=0 z=0
T=30 a=0 b=1 c=0 d=0 e=1 x=1 y=0 z=0
ncsim: *W,RNQUIE: Simulation is complete.

Verilog sekarang memungkinkan daftar sensitivitas diganti dengan * yang merupakan singkatan nyaman yang menghilangkan masalah ini dengan menambahkan semua jaringan dan variabel yang dibaca oleh pernyataan seperti yang ditunjukkan di bawah ini.

module tb;
  reg a, b, c, d, e;
  reg x, y, z;
  // Use @* or @(*)
  always @ * begin
    x = a | b;
    y = c ^ d;
    z = ~e;
  end
  initial begin
    $monitor ("T=%0t a=%0b b=%0b c=%0b d=%0b e=%0b x=%0b y=%0b z=%0b", $time, a, b, c, d, e, x, y, z);
    {a, b, c, d, e} <= 0;
    #10 {a, b, c, d, e} <= $random;
    #10 {a, b, c, d, e} <= $random;
    #10 {a, b, c, d, e} <= $random;
  end
endmodule

Log Simulasi

ncsim> run
T=0 a=0 b=0 c=0 d=0 e=0 x=0 y=0 z=1
T=10 a=0 b=0 c=1 d=0 e=0 x=0 y=1 z=1
T=20 a=0 b=0 c=0 d=0 e=1 x=0 y=0 z=0
T=30 a=0 b=1 c=0 d=0 e=1 x=1 y=0 z=0
ncsim: *W,RNQUIE: Simulation is complete.

Kontrol Peristiwa Tingkat Sensitive

Eksekusi pernyataan prosedural juga dapat ditunda hingga kondisi menjadi true dan dapat dicapai dengan kata kunci wait dan merupakan kontrol tingkat sensitif.

Pernyataan wait akan mengevaluasi kondisi dan jika false, pernyataan prosedural yang mengikutinya akan tetap diblokir hingga kondisi menjadi true.

module tb;
  reg [3:0] ctr;
  reg clk;
  initial begin
    {ctr, clk} <= 0;
    wait (ctr);
    $display ("T=%0t Counter reached non-zero value 0x%0h", $time, ctr);
    wait (ctr == 4) $display ("T=%0t Counter reached 0x%0h", $time, ctr);
    $finish;
  end
  always #10 clk = ~clk;
  always @ (posedge clk) ctr <= ctr + 1;
endmodule

Log Simulasi

ncsim> run
T=10 Counter reached non-zero value 0x1
T=70 Counter reached 0x4
T=90 Counter reached 0x5
T=170 Counter reached 0x9
Simulation complete via $finish(1) at time 170 NS + 1

Verilog

  1. Menguasai Verilog: Tutorial Lengkap untuk Desain Sirkuit Digital
  2. Menguasai Konkatenasi Verilog: Panduan Praktis
  3. Memahami Penugasan Verilog: Jenis, Sintaks, dan Praktik Terbaik
  4. Perbedaan Kunci Penugasan Blokir dan Non-Blokir Verilog
  5. Menguasai Aliran Kontrol Verilog: IF-ELSE, Case, dan Lainnya
  6. Menguasai Fungsi Verilog untuk Desain RTL yang Efisien
  7. Memahami Tugas Verilog: Fungsi vs Tugas, Sintaks, dan Penggunaan
  8. Memahami Penundaan Antar- dan Intra-Penugasan dalam Verilog
  9. Memahami Penundaan Gerbang dalam Verilog: Waktu yang Akurat untuk Desain Digital yang Handal
  10. Generator Jam Verilog: Panduan Desain dan Implementasi