시뮬레이션에서만 사용하는 문법이다.
블록 안으로 들어온 시간에 수행을 시작한다. 따라서 블록에 쓰여지는 문장의 순서는 중요하지 않다.
순차처리와 병렬처리를 비교해보겠다.
// 예 1: 지연이 있는 순차 처리 블록
reg x, y;
reg [1:0] z, w;
initial
begin
x = 1'b0; // 시간 0에 수행을 마친다.
#5 y = 1'b1; // 시간 5에 수행을 마친다.
#10 z = {x, y}; // 시간 15에 수행을 마친다.
#20 w = {y, x}; // 시간 35에 수행을 마친다.
end
// 예 2: 지연이 있는 병렬 처리 블록
reg x, y;
reg [1:0] z, w;
initial
fork
x = 1'b0; // 시간 0에 수행을 마친다.
#5 y = 1'b1; // 시간 5에 수행을 마친다.
#10 z = {x, y}; // 시간 10에 수행을 마친다.
#20 w = {y, x}; // 시간 20에 수행을 마친다.
join
시뮬레이션 시간을 잘 확인해보자.
아래 코드는 경쟁상태 (시뮬레이션 시간이 같아져 변수의 값이 Unknown이 된다.) 를 발생시킨 코드이다. 이는 시뮬레이터의 한계이지 fork-join블록의 한계는 아니다.
// 고의저인 경쟁 상태를 가진 병렬 처리 블록
reg x, y;
reg [1:0] z, w;
initial
fork
x = 1'b0;
y = 1'b1;
z = {x, y};
W = {y, x};
join
fork : 하나의 흐름을 분리된 흐름들로 나누는 관점
join : 분리된 흐름들을 다시 하나의 흐름으로 모으는 것
begin : block1
fork : block2
위 처럼 블록에 이름을 붙여 사용할 수 있다. 이름을 붙인 블록은 disable을 이용해 무효화 시킬 수 있다.
disable : 블록의 수행을 종결시키는 방법을 제공한다. 제어 신호에 기초해서 루프를 빠져나가거나, 에러 상황을 조절하고, 코드의 일부분은 수행하기 위해 쓴다. (break와 비슷)
// 보기 : 플래그(벡터 변수)에서 처음으로 1의 값을 갖는 비트를 찾는다.
reg [15:0] flag;
integer i; // 카운트하기 위한 정수
initial
begin
flag = 16'b 0010_0000_0000_0000;
i = 0;
begin : block1 // while 내부의 메인 블록이 block1이라고 명명됨
while(i < 16) // 연산자를 사용한 여러 개의 조건.
begin
if (flag[i])
begin
$display("Encountered a TRUE bit at element number %d", i);
disable block1; // 참값을 갖는 비트를 찾았기 때문에 block1을 무효화
end
i = i + 1;
end
end
end
begin end가 필요하지는 않지만 단지 명명을 위해 넣을 수 있다.
위 코드는 참값을 갖는 비트를 찾을 때 블록을 무효화 하여 루프를 빠져나온다.