#10. verilog 문법-반복문(repeat, while, forever, for)

Verilog/Verilog HDL강의정리(KOCW) 2023. 7. 27. 20:48
반응형

verilog 에서는 몇가지 반복문을 제공하고 있다. forever, repeat, while, for 이렇게 4가지이다. for와 while은 c언어를 알고 있다면 익숙하겠지만, forever과 repeat는 새롭게 배우는 사람이 더 많을 것이다. 오늘 글에서는 이 4가지 반복문에 대해서 아랑보도록 한다.


1. repeat문

repeat문은 반복할 횟수를 정한 상황에서 사용하는 반복문이 되겠다.  예제가 조금 어려울 순 있지만, shift-add방식의 승산기에서 사용되는  repeat 문을 살펴보도록 하겠다.

module multiplier(opa, opb, result);
    parameter SIZE = 8, Longsize = 2*SIZE; //파라미터 선언, 코드상에서 상수
    input [SIZE-1:0] opa, opb; //16bit input 선언
    output [Longsize-1:0] result; ,16비트 result output으로 선언
    reg    [Longsize-1:0] result, shift_opa, shift_opb; //always 안에 들어갈 변수들 reg선언
    
    always@(opa or opb) begin //always구문 선언,
        shift_opa = opa;
        shift_opb = opb;  //input 받은 값을 shift할 변수에 할당
        result = 0;
        
        repeat(SIZE) begin //repeat구문 선언, SIZE만큼 반복(즉, 8회 반복)
            if(shift_opb[0])  //shift_opb의 맨 끝비트(LSB)가 1이면
                result = result + shift_opa; //result에 shift_opa를 더하기 시작
            //if 조건문이 참이든 거짓이든 아래 문장을 실행    
            shift_opa = shift_opa << 1;      //shift_opa를 1비트 왼쪽으로 shift
            shift_opb = shift_opb >> 1;      //shift_opb를 1비트 오른쪽으로 shift
        end
    end
endmodule

먼저, 이 코드는 승산기라고 불리는데, 디지털회로설계에서 곱셈을 하는 알고리즘중 하나로 생각하면 되겠다. 곱셈을 하는 알고리즘으로는 배열승산기와 쉬프트 승산기가 있는데, 이 코드는 쉬프트 승산기를 의미한다. opa와 opb를 곱하는 과정중인데, shift_opa를 통해 비트를 한자리씩 왼쪽으로 옮겨가며, shift_opb와 더해주면서 그 총합이 곱셈결과가 되는 코드로 생각하면 되겠다.(추후 알고리즘 부분도 따로 정리해보도록 하겠다.)

repeat문은 여기서 SIZE만큼 반복되게 되는데 총 8회 반복된다. 이렇게 되면 opa가 왼쪽으로 계속이동하면서, opb와 비트별로 곱셈을 하게 되는 원리이다. repeat문은 비교적 간단하기 때문에 이정도에서 마무리하고 넘어가도록 하겠다.


2. While문

c언어를 했다면 비교적 익숙한 문법이 되겠다. while문은 조건을 만족하는 동안 반복되고, 조건이 만족되지 않으면 반복문을 탈출하게 된다.

사용방법은 다음과 같다.

while(temp_reg) begin //while문 선언, temp_reg가 0이 아니면 반복
    if(temp_reg[0])   //temp_reg의 LSB가 1이면 아래 문장 반복
        count = count+1;     //count에 1 가산
    temp_reg = temp_reg >> 1;  //temp_reg를 오른쪽으로 한칸 쉬프트
end

이번에는 모듈의 일부분만을 가져와 while문을 작성하였다. 이 반복문은 temp_reg를 오른쪽으로 계속 쉬프트 시켜가며 1인 비트가 몇개인지 확인하는 코드가 되겠다. repeat문과 마찬가지로 begin~end구문이 들어있으며, 괄호한에 조건을 넣는 방식으로 코딩하면 된다.


3. for문

우선순위 인코더의 코드를 통해 FOR문을 확인해보도록 하겠다. 우선순위 인코더는 1의 위치에 따라 출력이 결정되는 인코더를 의미한다. 따라서, 1이 발견되는 순간 for문 및 always 구문을 탈출해야한다.

우선순위 인코더의 input과 output을 결정하는 논리

module enc_for(in, out);
    input  [7:0] in; //8bit input in 
    output [2:0] out; //3bit output
    reg    [2:0] out;
    integer        i;//for문 안에 들어가는 변수는 반드시 integer선언 필요
    
    always@(in)begin : LOOP
        out = 0;  //초기화
        for(i = 7; i>=0 ; i=i-1)begin //for문 선언
            if(in[i]) begin  //i가 7부터 시작되므로 in의 MSB부터 if문 시작
                out = i;   
                disable LOOP;    //우선순위 인코더에서는 1을 찾는 순간 always문에서 탈출하여 
                                 //다음 1을 기다려야 하기 때문에 always문을 탈출하는 의미에서
                                 //Loop ~ disable LOOP 문을 사용한다.
            end
        end
    end
endmodule

for문을 사용하는 방법은 c언어에서의 for문과 매우 유사하다.for(변수;조건문;반복문)begin~end 방식으로 작성하며, 위 코드에서는 특별하게 :LOOP~disable LOOP문을 추가로 사용하여 always문을 탈출하는 방법도 작성하였으니, 기억해두도록 하자.(LOOP는 단순히 lable일 뿐이기 때문에 LOOP대신 다른 단어를 써도 동일하게 작동한다.) 또한, for문 안의 변수는 먼저 integer로 선언해 두어야 하는 것도 기억하자.


4. forever

forever문은 무한히 반복된다는 의미이다. 보통 testbench에서 사용하게 되며, 클럭을 발생하는 등에 상황에서 사용하게 된다.

예를 들어, forever #10 clk = ~clk; 라고 작성하게 되면 10ns마다 0과 1이 무한히 반복되는 클럭을 생성할 수 있다.

또한, 다음과 같이 쓰면

initial begin
    din = 1'b0;
    forever begin
        #15 din = 1'b1;
        #20 din = 1'b0;
        #30 din = 1'b1;
        #20 din = 1'b0;
    end
end

forever문에 begin과 end 사이에 문장을 넣게 되면, 해당 문장들을 무한히 반복하는 신호가 만들어지게 된다. 이런식으로 clock이나 입력신호를 만드는데 forever를 사용하게 된다.


5. 정리

repeat : 정해진 횟수만큼 반복

repeat(횟수)begin

    statement;

end

while : 조건에 만족하는 동안 반복

while(조건)begin
    
    statement;

end

for : 조건에 만족하는 동안 반복, 조건변화에 해당하는 변수의 변화를 줄 수 있음

for(변수값;조건;변화량)begin

    statement;

end

forever : 주어진 문장을 무한히 반복

forever statement;

forever begin
    statement;
    statement;
    statement; 
end

 

반응형