[Verilog] Blocking Assignment, Non-blocking Assignment

pikamon·2022년 4월 21일
0

Verilog

목록 보기
5/12

문득 Blocking과 Non-blocking의 차이를 직접 파형을 통해 확인해보고 싶었다.

1. Blocking Assignment

Blocking Assignment는 해당 라인이 실행 완료될 때까지 뒤에 있는 Blocking Assignment들을 잠시 블로킹하는 특성을 가지고 있다.

아래의 예제를 보자.
b=a 부분이 실행되는 동안 뒤에 있는 c=b, d=c, e=d 라인이 실행되지 않는다. b=a가 끝나고서야 뒤에 있는 문장이 실행된다. c=b, d=c 등도 마찬가지다.

(사실 '실행' 된다고 하면 틀린 표현이고, 그렇게 되도록 회로가 '합성' 된다고 보는게 맞다. Schematic을 그려서 설명하고 싶지만 생략..)

  1. blocking.v
`ifndef __BLOCKING_V__
`define __BLOCKING_V__

module blocking(
	input a,
	output reg b, c, d, e
	);

	always @ (a) begin
		b = a; // blocking
		c = b;
		d = c;
		e = d;
	end

endmodule

`endif /*__BLOCKING_V__*/

b에 a가 들어가고 난 후 c에 b가 들어가는 구조이기 때문에, 결과적으로 a의 값이 e에까지 전달된다. 즉 a가 변함에 따라 b, c, d, e가 동시에 같이 변한다.

  1. tb_blocking.v
`timescale 1ms/1ms

`include "blocking.v"

module tb_blocking();
	reg a;
	wire b, c, d, e;

	blocking _blocking(
		.a(a),
		.b(b),
		.c(c),
		.d(d),
		.e(e)
	);

	initial begin
		// for simulation
		$dumpfile("test.vcd");
		$dumpvars(-1, _blocking);

		// initialize
		a <= 1'b0;

		// start
		#1 a = 1'b1;
		#1 a = 1'b0;
		#1 a = 1'b1;
		#1 a = 1'b0;
		#1 a = 1'b1;
		#1 a = 1'b0;
		#1 a = 1'b1;
		#1 a = 1'b0;
		#1 a = 1'b1;
		#1 a = 1'b0;

		// end
		#1 $finish;
	end

endmodule
  1. 실행
> iverilog -o test.vvp blocking.v tb_blocking.v
> vvp test.vvp
> gtkwave test.vcd
  1. 파형 결과

위에서 말한 대로 b, c, d, e의 값이 동시에 같이 바뀌는 것을 볼 수 있다.

2. Non-blocking Assignment

Non-blocking Assignment는 event 발생 시 block 내의 모든 Non-blocking Assignment들이 동시에 동작한다.

아래의 예제를 보자.

b<=a 부분이 수행됨과 동시에 뒤에 있는 c<=b, d<=c, e<=d 라인도 같이 수행되도록 합성된다.

  1. nonblocking.v
`ifndef __NONBLOCKING_V__
`define __NONBLOCKING_V__

module nonblocking(
	input a,
	output reg b, c, d, e
	);

	always @ (a) begin
		b <= a; // non-blocking
		c <= b;
		d <= c;
		e <= d;
	end

endmodule

`endif /*__NONBLOCKING_V__*/

b에 a의 값이 들어감과 동시에 b에 있던 값이 c로 들어가기 때문에, c에는 b에 a가 들어오기 전 값이 들어간다. d, e도 마찬가지이므로, 처음에 a가 변하면 같이 변하는 것은 b 뿐이다.

  1. tb_nonblocking.v
`timescale 1ms/1ms

`include "nonblocking.v"

module tb_nonblocking();
	reg a;
	wire b, c, d, e;

	nonblocking _nonblocking(
		.a(a),
		.b(b),
		.c(c),
		.d(d),
		.e(e)
	);

	initial begin
		// for simulation
		$dumpfile("test.vcd");
		$dumpvars(-1, _nonblocking);

		// initialize
		a <= 1'b0;

		// start
		#1 a = 1'b1;
		#1 a = 1'b0;
		#1 a = 1'b1;
		#1 a = 1'b0;
		#1 a = 1'b1;
		#1 a = 1'b0;
		#1 a = 1'b1;
		#1 a = 1'b0;
		#1 a = 1'b1;
		#1 a = 1'b0;

		// end
		#1 $finish;
	end

endmodule
  1. 실행
> iverilog -o test.vvp nonblocking.v tb_nonblocking.v
> vvp test.vvp
> gtkwave test.vcd
  1. 파형 결과

c, d, e에 각각 b, c, d의 이전 값이 들어가기 때문에, 지그재그 모양의 파형이 나오는 것을 볼 수 있다.

3. 결론

Verilog에서는 한 event block 내에서 Blocking Assignment와 Non-blocking Assignment의 혼용을 지양하고 있다.

둘의 차이를 알고 용도에 따라 적절히 사용하면 될 것 같다.

profile
개발자입니당 *^^* 깃허브 https://github.com/pikamonvvs

0개의 댓글