Verilog初級教學(22)賦值間延遲語句與賦值內延遲語句

2020-08-09 01:14:34

前言

Verilog延遲語句可以在賦值運算子的左側或右側指定延遲。

所謂的左側就是:

// Delay is specified on the left side
#<delay> <LHS> = <RHS>

右側就是:

// Delay is specified on the right side
<LHS> = #<delay> <RHS>

下面 下麪詳細講解。

正文

賦值間延遲語句

// Delay is specified on the left side
#<delay> <LHS> = <RHS>

賦值間延遲語句在賦值運算子的LHS上有延遲值。這表示語句本身在延遲到期後執行,是最常用的延遲控制形式。

module tb;
  reg  a, b, c, q;

  initial begin
    $monitor("[%0t] a=%0b b=%0b c=%0b q=%0b", $time, a, b, c, q);

    // Initialize all signals to 0 at time 0
    a <= 0;
    b <= 0;
    c <= 0;
    q <= 0;

    // Inter-assignment delay: Wait for #5 time units
    // and then assign a and c to 1. Note that 'a' and 'c'
    // gets updated at the end of current timestep
    #5  a <= 1;
    	c <= 1;

    // Inter-assignment delay: Wait for #5 time units
    // and then assign 'q' with whatever value RHS gets
    // evaluated to
    #5 q <= a & b | c;

    #20;
  end

endmodule

請注意,q在時間10單位時變成了1,因爲語句在10個時間單位時被計算,RHS是a、b和c的組合,計算爲1。

這是其模擬結果:

[0] a=0 b=0 c=0 q=0
[5000] a=1 b=0 c=1 q=0
[10000] a=1 b=0 c=1 q=1

赋值间延迟仿真

注:看到程式碼的註釋了嗎?

Inter-assignment delay: Wait for #5 time units and then assign a and c to 1. Note that ‘a’ and ‘c’ gets updated at the end of current timestep

這是很基礎的一句話,這句話說明了Verilog這門語言的基本特點,或者說Verilog中非阻塞賦值的基本特點,如下:

    // Inter-assignment delay: Wait for #5 time units
    // and then assign a and c to 1. Note that 'a' and 'c'
    // gets updated at the end of current timestep
    #5  a <= 1;
    	c <= 1;

這條語句,在第5ns時候雖然給a與c均賦值了1,但是此刻並不生效,而會在當前時間步長結束時生效,例如,我們在此刻加一個語句,使用a與c的值:

  // Inter-assignment delay: Wait for #5 time units
    // and then assign a and c to 1. Note that 'a' and 'c'
    // gets updated at the end of current timestep
    #5  a <= 1;
    	c <= 1;
    	q <= a&c;

在这里插入图片描述

此時,q的值不會爲1,而時爲0,這就是因爲此刻q的值沒有生效,我們在第6秒再看就可以看到生效了:

在这里插入图片描述

由於一般timescale預設爲1ns/1ps,因此,步長應該爲1ns。也就是在1ns末生效。

賦值內延遲語句

// Delay is specified on the right side
<LHS> = #<delay> <RHS>

賦值內延遲是指在賦值運算子的RHS上有一個延遲。這表示語句被計算,RHS上的所有信號的值首先被捕獲。然後在延時過後纔對結果信號進行賦值。

module tb;
  reg  a, b, c, q;

  initial begin
    $monitor("[%0t] a=%0b b=%0b c=%0b q=%0b", $time, a, b, c, q);

	// Initialize all signals to 0 at time 0
    a <= 0;
    b <= 0;
    c <= 0;
    q <= 0;

    // Inter-assignment delay: Wait for #5 time units
    // and then assign a and c to 1. Note that 'a' and 'c'
    // gets updated at the end of current timestep
    #5  a <= 1;
    	c <= 1;

    // Intra-assignment delay: First execute the statement
    // then wait for 5 time units and then assign the evaluated
    // value to q
    q <= #5 a & b | c;

    #20;
  end
endmodule

模擬結果爲:

在这里插入图片描述
很多人就感覺奇怪了,爲什麼q沒有了爲1的時候,不應該在10ns時候爲1嗎?

如果出現這個疑問?很正常,但是需要再次理解理解,這個賦值內延遲的含義與非阻塞賦值的特點。

在第5ns時候,a,b,q同時被賦值,a和c在第5s被非阻塞賦值,也就是在第5ns末有效。
第5ns時,q也被賦值,但是在第5ns時(起始),q經過計算爲0,它經過5ns後被賦值,因此,會一直爲0,好像1被吞掉了似的,其實理解了二者的含義,很好理解。

爲了對比,我們在第5ns時,對a和c都進行阻塞賦值:

// Non-blocking changed to blocking and rest of the
// code remains the same
    #5  a = 1;
    	c = 1;

    q <= #5 a & b | c;

我們可以得到不一樣的結果:

在这里插入图片描述
這纔是你想要的結果。
什麼原因呢?
還是在第5ns時候(初),a和c都已經爲1了,此時,q經過計算也爲1,然後延遲5ns,賦值給q,因此,q在10ns時候爲1。

往期回顧

Verilog初級教學(21)Verilog中的延遲控制語句

Verilog初級教學(20)Verilog中的`ifdef 條件編譯語句

Verilog初級教學(19)Verilog中的參數

Verilog初級教學(18)Verilog中的函數與任務

Verilog初級教學(17)Verilog中的case語句

Verilog初級教學(16)Verilog中的控制塊

Verilog初級教學(15)Verilog中的阻塞與非阻塞語句

Verilog初級教學(14)Verilog中的賦值語句

Verilog初級教學(13)Verilog中的塊語句

Verilog初級教學(12)Verilog中的generate塊

Verilog初級教學(11)Verilog中的initial塊

Verilog初級教學(10)Verilog的always塊

Verilog初級教學(9)Verilog的運算子

Verilog初級教學(8)Verilog中的assign語句

Verilog初級教學(7)Verilog模組例化以及懸空埠的處理

Verilog初級教學(6)Verilog模組與埠

Verilog初級教學(5)Verilog中的多維陣列和記憶體

Verilog初級教學(4)Verilog中的標量與向量

Verilog初級教學(3)Verilog 數據型別

Verilog初級教學(2)Verilog HDL的初級語法

Verilog初級教學(1)認識 Verilog HDL

晶片設計抽象層及其設計風格

Verilog以及VHDL所倡導的的程式碼準則

FPGA/ASIC初學者應該學習Verilog還是VHDL?

參考資料及推薦關注

https://www.chipverify.com/verilog/verilog-inter-and-intra-assignment-delay

個人微信公衆號: FPGA LAB

交個朋友