---
# System prepended metadata

title: Homework2

---

# Homework2
> 資工二1 黃柏芸
> 指導老師：林宏益

### 實驗目的:
探討Blocking與Nonblocking的不同之處
### 程式碼:
blocking
```verilog=
// Blocking Descriptions (RTL)
module blocking (
        clk,
        rst_n,
        a_i,
        b_i,
        a_o,
        b_o
    );
input clk;
input rst_n;
input a_i, b_i;
output a_o, b_o;
reg a, b;
assign a_o = a;
assign b_o = b;
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        a = a_i;
        b = b_i;
    end
    else begin
        a = b;
        b = a;
    end
end
endmodule

//Blocking Descriptions (Testbench)
// `include "blocking.v"
`timescale 1ns/1ps
module blocking_tb;
reg clk;
reg rst_n;
reg a_i, b_i;
wire a_o, b_o;
parameter PERIOD = 20;
parameter real DUTY_CYCLE = 0.5;
parameter OFFSET = 0;
// clock process
initial
begin
    #OFFSET;
    forever
    begin
        clk = 1'b0;
        #(PERIOD-(PERIOD*DUTY_CYCLE)) clk = 1'b1;
        #(PERIOD*DUTY_CYCLE);
    end
end
initial begin
    rst_n = 1'b0;
    a_i = 1'b1;
    b_i = 1'b0;
    #5 rst_n = 1'b1;
    #100 $finish;
end
initial begin
    $dumpfile("blocking.vcd");
    $dumpvars(0, blocking_tb);
end
blocking blocking_tb (
        .clk(clk),
        .rst_n(rst_n),
        .a_i(a_i),
        .b_i(b_i),
        .a_o(a_o),
        .b_o(b_o) );
endmodule

//Blocking Descriptions (Makefile)
VERILOG = iverilog
TARGET = blocking.vcd
TEMP = temp.vvp
$(TARGET) : $(TEMP)
    vvp $(TEMP)
$(TEMP): blocking_tb.v blocking.v
    $(VERILOG) -o $(TEMP) blocking_tb.v blocking.v
clean:
    -del $(TARGET)
    -del $(TEMP)
```
nonblocking
```verilog=
// Nonblocking Descriptions (RTL)
module blocking (
        clk,
        rst_n,
        a_i,
        b_i,
        a_o,
        b_o
    );
input clk;
input rst_n;
input a_i, b_i;
output a_o, b_o;
reg a, b;
assign a_o = a;
assign b_o = b;
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        a <= a_i;
        b <= b_i;
    end
    else begin
        a <= b;
        b <= a;
    end
end
endmodule

//Nonblocking Descriptions (Testbench)
// `include "blocking.v"
`timescale 1ns/1ps
module blocking_tb;
reg clk;
reg rst_n;
reg a_i, b_i;
wire a_o, b_o;
parameter PERIOD = 20;
parameter real DUTY_CYCLE = 0.5;
parameter OFFSET = 0;
// clock process
initial
begin
    #OFFSET;
    forever
    begin
        clk = 1'b0;
        #(PERIOD-(PERIOD*DUTY_CYCLE)) clk = 1'b1;
        #(PERIOD*DUTY_CYCLE);
    end
end
initial begin
    rst_n = 1'b0;
    a_i = 1'b1;
    b_i = 1'b0;
    #5 rst_n = 1'b1;
    #100 $finish;
end
initial begin
    $dumpfile("blocking.vcd");
    $dumpvars(0, blocking_tb);
end
blocking blocking_tb (
        .clk(clk),
        .rst_n(rst_n),
        .a_i(a_i),
        .b_i(b_i),
        .a_o(a_o),
        .b_o(b_o) );
endmodule

//Nonblocking Descriptions (Makefile)
VERILOG = iverilog
TARGET = blocking.vcd
TEMP = temp.vvp
$(TARGET) : $(TEMP)
    vvp $(TEMP)
$(TEMP): blocking_tb.v blocking.v
    $(VERILOG) -o $(TEMP) blocking_tb.v blocking.v
clean:
    -del $(TARGET)
    -del $(TEMP)
```
### 實驗結果:
Blocking的波形:
![](https://i.imgur.com/bBu2Maw.png)
Nonblocking的波形:
![](https://i.imgur.com/O8ICKz0.png)


### 分析:
`timescale 1ns/1ps 
>敘述代表將模組中所有時間延遲的單位，設定為1ns，而且時間精度為1ps(課本101頁)

always @(posedge clk or negedge rst_n) begin
>代表用時脈clK來做「正緣觸發」觸發訊號或代表用rst_n來做「負緣觸發」觸發訊號(課本105頁)

#### 不同之處:
Blocking:
    if (~rst_n) begin
       **a = a_i;
        b = b_i;**
    end
    else begin
        **a = b;
        b = a;**
    end
>所謂的blocking，就是一行程式執行完才能執行下一行
>在執行else begin時，先將a設定成b，再將b設定成a，最後結果會是a=b

Nonblocking:
    if (~rst_n) begin
        **a <= a_i;
        b <= b_i;**
    end
    else begin
        **a <= b;
        b <= a;**
    end
>nonblocking可視為兩個步驟的行為：
>>1.在clk rising edge的一開始執行RHS。
>>2.在clk rising edge快結束時執行LHS。
>>
>因此在執行else begin時，會先執行RHS，例如a = 1，b = 0，然後再執行LHS，因此a = 0，b = 1，nonblocking因為a已經更新了，而改變b的值。

結論:
>blocking會因為程式的**撰寫順序**而有不同的值，但nonblocking卻不會因為程式的撰寫順序而有影響，原因是nonblocking的執行是2個步驟(RHS和LHS)，而blocking的執行是1個步驟。

### 參考資料:
(原創) 深入探討blocking與nonblocking (SOC) (Verilog)
### 心得:
透過這次的作業讓我了解blocking與nonblocking的不同之處，我對於使用HackMD也越來越熟悉了!