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