Procedural Statements는 순차적(Sequential)으로 실행되는 문장을 의미하며, 주로 always 블록 또는 initial 블록 내부에서 사용됩니다.
Verilog에서는 프로시저 블록(Procedural Block)을 사용하여 논리 동작을 정의합니다. 대표적으로 다음과 같은 두 가지가 있습니다.
initial 블록initial begin
a = 0;
#10 a = 1; // 10ns 후 a를 1로 설정
end
always 블록always @(posedge clk) begin
q <= d; // clk의 rising edge마다 q에 d를 저장
end
Procedural Block 내부에서 값을 할당하는 문장입니다.
= (blocking assignment)always @(posedge clk) begin
a = b; // b의 값을 a에 즉시 할당 (blocking)
c = a; // 위의 할당이 완료된 후 실행됨
end
<= (non-blocking assignment)always @(posedge clk) begin
a <= b; // b를 a에 비동기적으로 할당
c <= a; // 기존 a 값을 c에 할당 (이전 값이 유지됨)
end
Verilog에서는 특정 이벤트(Event)가 발생할 때 블록이 실행됩니다.
@() 구문을 사용하여 특정 신호 변화 시 블록을 실행 always @(clk) // clk이 변할 때마다 실행
q = d;
posedge : 상승 엣지(positive edge, 0 → 1)에서 실행 negedge : 하강 엣지(negative edge, 1 → 0)에서 실행 always @(posedge clk) // clk 상승 엣지에서 실행
q <= d;
rst가 0이면 q를 0으로 초기화 clk 상승 엣지에서 q에 d를 저장 always @(posedge clk or negedge rst) begin
if (!rst)
q <= 0; // rst가 0이면 q를 초기화
else
q <= d; // clk 상승 엣지에서 d를 저장
end
절차적 문장은 always 또는 initial 블록 내부에서 사용됩니다.
true)이 되는 조건이 실행됨 always @(posedge clk) begin
if (a > b)
result <= 1;
else if (a == b)
result <= 0;
else
result <= -1;
end
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
casex 및 casez 문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
repeat 문repeat (5) begin
a = a + 1; // a를 5번 증가
end
while 문while (a < 10) begin
a = a + 1;
end
forever 문forever begin
#10 clk = ~clk; // 10ns마다 clk 반전
end
Verilog는 기본적으로 begin...end를 사용하면 순차 실행하지만,
fork...join을 사용하면 동시에 실행(병렬 실행)됩니다.
fork
#10 a = 1;
#20 b = 2;
#30 c = 3;
join
위 코드는 a, b, c가 동시에 변경됨 (비동기 실행).
만약 begin...end를 사용했다면 순차적으로 실행됩니다.