20 / 37 · 개념
generate: 반복문으로 정적 회로 만들기
genvar와 generate-if를 사용해 이름 붙은 회로 인스턴스를 만들고 버스의 lane 배치를 확인합니다.
내용은 무료로 볼 수 있습니다. 수강 신청하면 학습 기록을 저장할 수 있어요.
generate 반복은 사이클이 아니라 인스턴스를 만듭니다
genvar와 generate 반복문은 반복되는 정적 구조를 기술합니다. elaborator가 실행 전에 모든 인스턴스를 만듭니다. always_comb 안의 반복문은 절차적 계산을 표현하며 실제 하드웨어는 합성이 정합니다. 어느 쪽도 자동으로 클록당 한 번씩 반복한다는 뜻이 아닙니다. 직렬 처리에는 명시적인 상태와 클록 제어기가 필요합니다.
다음 예제는 packed 입력 버스를 W비트짜리 LANES개의 워드로 나누어 워드별 패리티를 계산합니다. W와 LANES는 모두 양의 정수여야 합니다.
module lane_parity #(
parameter integer W = 8,
parameter integer LANES = 3
) (
input logic [W*LANES-1:0] data,
output logic [LANES-1:0] parity
);
genvar lane;
generate
for (lane = 0; lane < LANES; lane = lane + 1) begin : g_lane
wire [W-1:0] word_data;
assign word_data = data[lane*W +: W];
assign parity[lane] = ^word_data;
end
endgenerate
endmoduledata[base +: W]는 base에서 더 큰 비트 인덱스 방향으로 W비트를 고릅니다. elaboration한 인스턴스에서 W는 상수입니다. W=8,LANES=3이면 lane 0은 7:0, lane 1은 15:8, lane 2는 23:16을 받습니다. 이름 붙인 g_lane 블록은 g_lane[1].word_data처럼 확인할 수 있는 안정적인 계층을 제공합니다.
선언에서 lane 순서를 읽습니다
data=24'h03_01_80이면 lane 0부터 값이 80,01,03입니다. 패리티는 각각 1,1,0이므로 parity[2:0] 벡터는 3'b011입니다. 맨 왼쪽 16진 바이트는 lane 0이 아니라 lane 2입니다. 수치 인덱스·화면 표시 순서·전송 순서를 분리하세요.
모든 lane은 동시에 계산합니다. 이 설계에는 등록된 사이클 지연이 없습니다. LANES를 늘리면 조합논리가 늘어나며 실행 사이클이 길어지는 것이 아닙니다. 물리적인 fanout·배선·타이밍은 별도 구현 검증이 필요합니다.
generate-if는 고정 구조 하나를 선택합니다
generate-if의 조건은 선택적인 레지스터 포함 여부를 정하는 parameter처럼 elaboration 중 상수여야 합니다. 실행 중 신호는 조합 또는 클록 블록에서 동작을 선택해야 합니다. registered/unregistered 설정을 바꾸면 유효 시점 계약도 달라지므로 포트 문서와 검사기에 반영해야 합니다.
이 버스를 “끄기” 위해 매개변수 0을 쓰지 마세요. [−1:0] 같은 범위는 안전한 0비트 객체가 아닙니다. 지원하지 않는 설정을 거부하거나 외부 인터페이스가 명확하게 유지되는 generate 분기를 작성하세요.
실습 · lane이 뒤바뀐 오류 찾기
위 예제를 검사한 뒤 lane마다 비트 하나만 차례로 켜세요. 대응하는 패리티 비트만 바뀌어야 합니다. 한 워드의 두 비트를 켜면 짝수 패리티이므로 0이어야 합니다. 모든 lane에 같은 값을 넣는 검사는 슬라이스가 뒤바뀐 오류를 가립니다.
참조 검사기는 수치 연산으로 lane을 추출하고 1인 비트 수를 셉니다. W=1,W=8,LANES=1,LANES=3을 검사하세요. 바이트 폭·반복 계층·최소 설정을 고정값으로 가정한 오류를 드러냅니다.
마지막으로 별도 실험에서 패리티 벡터를 상승 에지 레지스터에 저장하세요. reset·enable을 정하고 검사기가 현재 버스와 비교하는지, 이전 에지에서 샘플한 버스와 비교하는지 명세합니다.