# 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的波形:

Nonblocking的波形:

### 分析:
`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也越來越熟悉了!