Introduce
한번에 수행하기 위해서 여러 문장들은 블록문으로 그룹지어 진다. 키워드 begin-end를 사용해 여러 문장들을 그룹지었는데 이들은 하나의 문장을 수행하고 다음 문장을 수행하는 순차 처리 블록을 사용했다. 이번 장에서는 블록의 형태를 알아본다.
블록 형태
순차 처리와 병렬 처리. 2가지 형태의 블록이 있다.
순차 처리 블록
문장을 순차 처리 블록으로 그룹 짓기 위해서 키워드 begin과 end를 사용한다. 순차 블록은 다음과 같은 특징을 갖느다.
- 순차처리 블록의 문장들은 지정된 순서에 따라 처리된다.
- 만약 지연 또는 사건 제어가 지정되었다면, 블록 안에서 이전 문장이 완전히 수행을 끝내는 시뮬레이션 시간에 관계된다.
// 지연이 없는 순차 처리 블록
reg x, y;
reg [1:0] z, w;
initial begin
x = 1'b0;
y = 1'b1;
z = {x,y};
w = {y,x};
end
// 지연이 있는 순차 처리 블록
reg x, y;
reg [1:0] z, w;
initial begin
x = 1'b0;
#5 y = 1'b1;
#10 z = {x,y};
#20 w = {y,x};
end
첫번째 예시에서는 시뮬레이션 시간0에서 최종값은 x=0, y=1, z=1, w=2이다. 두번째는 블록이 끝날 때의 시뮬레이션 시간이 35인 것을 제외하고 최종값은 첫번째와 동일하다.
병렬 처리 블록
키워드 fork와 join으로 지정되는 병렬 처리블록은 흥미로운 시뮬레이션 형태를 제공한다.
- 병렬 처리 블록의 문장들은 동시에 수행된다.
- 각 문장에 할당된 지연 기반 또는 사건 기반 제어에 의해서 문장의 순서가 조절된다.
순차 처리와 병렬 처리의 기능적인 차이를 명심해야한다. 병렬 처리 블록은 모든 문장이 블록 안으로 들어온 시간에 수행을 시작한다. 그러므로 블록에 쓰여 지는 문장의 순서는 중요하지 않다. 다음의 예시는 모든 문장이 시간 0에서 병렬적으로 수행을 시작한다는 것을 제외하고 모두 같다. 그러므로 블록은 단위 시간 35대신 단위 시간 20에 종료된다.
reg x, y;
reg [1:0] z, w;
initial fork
x = 1'b0;
#5 y = 1'b1;
#10 z = {x,y};
#20 w = {y,x};
join
깉은 변수에 영향을 미치는 두개의 문장이 동시에 수행을 마치면, 경쟁 상태의 원인이 될 수 있기에 병렬 처리 블록을 주의해서 사용해야 한다. 다음은 경쟁 상태를 발생시키는 문장이다.
reg x, y;
reg [1:0] z, w;
initial fork
x = 1'b0;
y = 1'b1;
z = {x,y};
w = {y,x};
join
모든 문장이 시뮬레이션 시간 0에서 수행을 시작한다. 문장의 실행 순서는 알 수 없다. 만약 x=1'b0과 y=1'b1이 먼저 수행되었다면, 변수 z와 w는 1과 2의 값을 가질 것이다. 만약 x=1'b0과 y=1'b1이 뒤에 수행된다면, z와 w는 2'bxx를 가질것이다. 그러므로 z와 w의 결과는 단정지을 수 없고, 시뮬레이터에 의존한다.
※ [질문] fork-join문과 nonblocking문의 차이점 ?
fork-join은 임시저장을 못하기 때문에 경쟁상태에서 문제가 생길 수 있어 그것을 방지하기 위해 delay를 줘야 한다.
특별한 형태의 블록
블록 문장들을 가지고 만들 수 있는 3가지 특별한 형태의 블록에 대해 알아보자
- 중첩된 블록
- 명명된 블록
- 명명된 블록의 무효화
중첩된 블록
블록은 중첩될 수 있다. 다음과 같이 순차 처리와 병렬 처리 블록을 섞어서 사용할 수 있다.
initial begin
x = 1'b0;
fork
#5 y =1'b1;
#10 z = {x,y};
join
#20 w = {y,x};
end
명명된 블록
블록은 이름을 가질 수 있다.
- 명명된 블록을 위해 지역 변수가 선언될 수 있다.
- 명명된 블록은 설계 계층 구조의 일부분이다. 명명된 블록의 변수는 계층적 이름 참조를 사용해서 접근할 수 있다.
- 명명된 블록은 무효화시킬 수 있다.
module top;
initial begin : block1 // block1이라는 순차 처리 블록
integer i; // top.block1.i에 의해 접근할 수 있다.
...
...
end
initial fork : block2 // block2라는 병렬 처리 블록
reg i; // 레지스터 i는 정적이고, 블록2의 지역 변수이다.
... // 계층적 이름 top.block2.i에 의해 접근할 수 있다.
...
join
명명된 블록의 무효화
키워드 disable은 블록을 수행을 종결시키는 방법을 제공한다. disable은 제어 신호에 기초해서 루프를 빠져나가거나, 에러 상황을 조절하고, 코드의 일부분은 수행하기 위해 쓰인다. C에서 break문장과 매우 유사하다. break는 단지 현재 루프를 빠져나가는 반면에 disable은 설계에서 명명된 블록을 빠져 나온다는것이 차이다.
플래그에서 참값을 갖는 첫 번째 비트를 찾는 예제를 살펴보자. 다음처럼 diable문장을 써서 while 루프를 작성할 수 있다. disable문장은 참값을 갖는 비트를 만나자마자 while루프를 종료한다.
reg[15:0] flag;
integer i;
initial begin
flag = 16'b 0010_0000_0000_0000;
i = 0;
begin : block1
while(i<16) begin
if(flag[i]) begin
$display("TRUE bit at element number %d",i);
disable block1; // 참값을 찾았기 때문에 block1 무효화
end
i = i+1;
end
end
end
'UVM & RTL > Verilog HDL' 카테고리의 다른 글
[Verilog HDL] CH7 루프 (0) | 2022.06.14 |
---|---|
[Verilog HDL] CH7 조건문, 다중분기 (0) | 2022.06.14 |
[Verilog HDL] CH7 타이밍 제어 (0) | 2022.06.14 |
[Verilog HDL] CH7 구조적 프로시저 & 절차적 할당 (0) | 2022.06.14 |
[Verilog HDL] CH6 연산자 (0) | 2022.06.14 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!