[Verilog] 루프문 (while, for, repeat, forever)

준치·2022년 1월 21일
0

[Verilog]

목록 보기
5/9

모든 루프문장은 기본적으로 always, initial블록 안에 위치한다.

While 루프

이 루프는 while(수식)의 수식이 거짓이 될 때 까지 수행한다.

// 보기 1 : 0에서부터 127까지 count를 증가시킨다. 128에 종료한다.
// count 변수를 출력한다.
integer count;

initial
begin
	count = 0;
    while (count < 128) // count가 127이 될 때까지 루프를 수행한다.
    			// count가 128일 때 종료한다.
    begin
    	$display("Count = %d", count);
        count = count + 1;
    end
end

// 보기 2 : 플래그(벡터 변수)에서 처음으로 1의 값을 갖는 비트를 찾는다.
`define TRUE 1'b1;
`define FALSE 1'b0;
reg [15:0] flag;
integer i; // 카운트하기 위한 정수
reg continue;

initial
begin
    flag = 16'b 0010_0000_0000_0000;
    i = 0;
    continue = `TRUE;
    
	while((i < 16) && continue ) // 연산자를 사용한 여러 개의 조건.
	begin
    		if (flag[i])
        	begin
    			$display("Encountered a TRUE bit at element number %d", i);
       	 		continue = `FALSE;
        end
	i = i + 1;
    end
end

c언어에서 조건을 주고 break를 넣어서 루프를 빠져나오는 것 처럼 조건 자체에 break되는 기준을 넣는 느낌인 것 같다.

For 루프

for(초기상태; 조건; 할당) 으로 사용한다.

integer count;

initial
	for ( count = 0; count < 128; count = count + 1)
    	$display("Count = %d", count);

아래 처럼 배열이나 메모리를 초기화하는데 쓰일 수도 있다.

// 배열 원소의 초기화
`define MX_STATES 32;
integer state [0 : `MAX_STATES-1]; // 원소 0:31을 가진 정수형 배열 상태
integer i;

initial
begin
    for(i = 0; i < 32; i = i + 2) // 모든 짝수 위치에 0으로 초기화.
    	state[i] = 0;
    for(i = 1; i < 32; i = i + 2) // 모든 홀수 위치에 1로 초기화.
    	state[i] = 1;
end    

Repeat 루프

repeat 구조는 정해진 횟수만큼 루프를 수행한다. 일반적인 논리 수식의 루프에는 쓰여 질 수 없다. 반드시 상수, 하나의 변수 또는 하나의 값이 될 수 있는 숫자를 포함해야 한다. 변수가 루프를 수행하는 도중에 바뀌더라도 적용되지 않는다.

// 보기 1 : 0에서부터 127까지 증가시키고 출력한다.
integer count;

initial
begin
	count = 0;
    repeat(128)
    begin
    	$display("Count = %d", count);
        count = count + 1;
    end
end

// 보기 2 : 데이터 버퍼 모듈의 예
// 데이터 시작 신호를 받은 후
// 다음 8 사이클 동안 데이터를 읽는다.

module data_buffer(data_start, data, clock);

parameter cycles = 8;
input data_start;
input [15:0] data;
input clock;

reg [15:0] buffer [0:7];
integer i;

always@(posedge clock)
begin
	if(data_start) // 데이터 시작 신호가 참이다.
    begin
    	i = 0;
        repeat(cycles) // 다음 8 클럭 사이클의 모서리에서 데이터를 저장
        begin
        	@(posedge clock) buffer[i] = data; // 데이터를 래치하기 위해
            					   // 다음 모서리까지 기다린다.
                i = i + 1;
        end
    end
 end
 
 endmodule

Forever 루프

어떤 수식도 포함하지 않고 $finish를 만날 때까지 수행된다. while(1)과 동일하다. 일반적으로 타이밍 제어 구조와 같이 쓰인다. 시뮬레이션에서 단독으로 쓰인다면 forever구조에서 시뮬레이션이 무한히 반복되어 나머지 부분이 수행되지 않는 문제점이 생긴다.

// 예 1 : 클럭 생성
// always 블록 대신에 forever 루프를 사용
reg clock;

initial
begin
	clock = 1'b0;
    forever #10 clock = ~clock; // 20 단위의 주기를 가진 클럭
end

// 예 2 : 매 클럭의 상승 모서리에서 두 개의 레지스터가 동기화를 이룬다.
reg clock;
reg x, y;

initial
	forever @(posedge clock) x = y;

Reference

[1] SAMIR PALNITKAR, ⌜Verilog HDL 디지털 설계와 합성의 길잡이, 2th Edition⌟ , chapter 7
profile
설계 엔지니어 지망생

0개의 댓글