Verilog: Procedure

나는컴공생·2025년 2월 25일

Procedural Statements (절차적 문장)

Procedural Statements는 순차적(Sequential)으로 실행되는 문장을 의미하며, 주로 always 블록 또는 initial 블록 내부에서 사용됩니다.

1. Procedural Blocks (절차적 블록)

Verilog에서는 프로시저 블록(Procedural Block)을 사용하여 논리 동작을 정의합니다. 대표적으로 다음과 같은 두 가지가 있습니다.

(1) initial 블록

  • 시뮬레이션 시작 시 한 번만 실행되는 블록
  • Testbench(테스트벤치)에서 주로 사용됨
  • 합성(Synthesis) 불가
initial begin
    a = 0;
    #10 a = 1;  // 10ns 후 a를 1로 설정
end

(2) always 블록

  • 특정 조건(Event)에 따라 반복 실행
  • 하드웨어 설계에서 순차 논리(Flip-Flop, Latch 등) 및 조합 논리(Combinational Logic) 생성에 사용
always @(posedge clk) begin
    q <= d;  // clk의 rising edge마다 q에 d를 저장
end

2. Procedural Assignments (절차적 할당)

Procedural Block 내부에서 값을 할당하는 문장입니다.

(1) = (blocking assignment)

  • 순차적으로 실행됨 (Blocking)
  • 앞의 문장이 끝난 후 다음 문장이 실행됨
always @(posedge clk) begin
    a = b;   // b의 값을 a에 즉시 할당 (blocking)
    c = a;   // 위의 할당이 완료된 후 실행됨
end

(2) <= (non-blocking assignment)

  • 동시에 실행됨 (Non-blocking)
  • 모든 문장이 동시에 실행되므로 Register(레지스터) 동작을 표현하는 데 적합
always @(posedge clk) begin
    a <= b;   // b를 a에 비동기적으로 할당
    c <= a;   // 기존 a 값을 c에 할당 (이전 값이 유지됨)
end

3. Event Control (이벤트 제어)

Verilog에서는 특정 이벤트(Event)가 발생할 때 블록이 실행됩니다.

(1) 일반적인 이벤트 제어

  • @() 구문을 사용하여 특정 신호 변화 시 블록을 실행
always @(clk)   // clk이 변할 때마다 실행
    q = d;

(2) Edge 트리거 이벤트 제어

  • posedge : 상승 엣지(positive edge, 0 → 1)에서 실행
  • negedge : 하강 엣지(negative edge, 1 → 0)에서 실행
always @(posedge clk)  // clk 상승 엣지에서 실행
    q <= d;

(3) 비동기(Asynchronous) 리셋을 포함한 이벤트 제어

  • rst가 0이면 q를 0으로 초기화
  • 그렇지 않으면 clk 상승 엣지에서 qd를 저장
always @(posedge clk or negedge rst) begin
    if (!rst) 
        q <= 0;  // rst가 0이면 q를 초기화
    else 
        q <= d;  // clk 상승 엣지에서 d를 저장
end

4. Procedural Statements (절차적 문장)

절차적 문장은 always 또는 initial 블록 내부에서 사용됩니다.

(1) If-Else 문

  • 조건문을 사용하여 분기 처리
  • 조건이 중복될 경우, 가장 먼저 참(true)이 되는 조건이 실행됨
always @(posedge clk) begin
    if (a > b) 
        result <= 1;
    else if (a == b) 
        result <= 0;
    else 
        result <= -1;
end

(2) Case 문

  • 여러 개의 조건을 검사하는 경우 case 문 사용
  • 기본적으로 case완전히 일치하는 경우만 실행됨
always @(posedge clk) begin
    case (sel)
        2'b00: out <= in0;
        2'b01: out <= in1;
        2'b10: out <= in2;
        2'b11: out <= in3;
    endcase
end

(3) casexcasez

  • casex : x, z, ?Don't Care로 간주
  • casez : z, ?Don't Care로 간주
casex (opcode)
    4'b1xxx: out = 4'b0001;  // MSB가 1이면 실행
    4'b01xx: out = 4'b0010;  // 상위 2비트가 01이면 실행
endcase
casez (opcode)
    4'b1zz0: out = 4'b1000;  // z는 무시됨
endcase

5. Loop Statements (반복문)

(1) repeat

  • 지정한 횟수만큼 루프 실행
repeat (5) begin
    a = a + 1;  // a를 5번 증가
end

(2) while

  • 조건이 참일 동안 루프 실행
  • 합성(Synthesis) 불가능 → 시뮬레이션에서만 사용
while (a < 10) begin
    a = a + 1;
end

(3) forever

  • 무한 반복 (종료 조건 없음)
  • 하드웨어 합성 불가능 → 시뮬레이션에서만 사용
forever begin
    #10 clk = ~clk;  // 10ns마다 clk 반전
end

6. Fork-Join (병렬 실행)

Verilog는 기본적으로 begin...end를 사용하면 순차 실행하지만,
fork...join을 사용하면 동시에 실행(병렬 실행)됩니다.

fork
    #10 a = 1;
    #20 b = 2;
    #30 c = 3;
join

위 코드는 a, b, c동시에 변경됨 (비동기 실행).
만약 begin...end를 사용했다면 순차적으로 실행됩니다.

0개의 댓글