2 / 20 · 개념
부호 있는 곱과 누산기 폭
최악의 입력 범위에서 안전한 누산 폭을 유도합니다.
내용은 무료로 볼 수 있습니다. 수강 신청하면 학습 기록을 저장할 수 있어요.
최솟값까지 포함한 범위
W비트 2의 보수 입력의 범위는 −2^(W−1)부터 2^(W−1)−1입니다. 가장 큰 양수 곱은 두 최솟값을 곱할 때 생깁니다. W=8이면 (−128)×(−128)=16384이고, 127×127=16129보다 큽니다. 따라서 양수 최댓값만 보고 곱의 범위를 정하면 경계 시험을 놓칩니다. 부호 있는 W비트 두 입력의 완전한 곱을 담는 안전한 폭은 2W비트입니다.
K개 항을 더하는 누산기에 이 과정은 다음 보수적 규칙을 사용합니다. K는 1 이상이고, bias를 더하지 않으며, 모든 항의 입력 폭이 동일하다는 전제입니다.
이 규칙은 항상 최소 폭이라고 주장하지 않습니다. 구현 검토가 쉬운 여유 있는 상한입니다. W=8, K=4라면 18비트를 선택합니다. 최대 양수 합은 4×16384=65536으로 17비트 부호 있는 최댓값 65535를 한 단계 넘습니다. 18비트 범위는 −131072..131071이므로 이 합을 담습니다. K=1에서 추가 폭은 0입니다. 매개변수의 $clog2(K)를 사용할 때 K=0을 허용하지 않는 정적 검사를 함께 둡니다.
곱의 부호를 명시적으로 전달하기
SystemVerilog의 표현식 폭과 signed 속성을 추측하지 말고 중간 신호에 계약을 적습니다. 아래는 입력과 완전한 곱, 누산기에 더할 부호 확장값을 각각 선언한 조각입니다. AW는 PW 이상이어야 합니다. 이후 PE 실습에서 이 신호를 순차 누산기에 연결합니다.
localparam int PW = 2*W;
localparam int AW = PW + $clog2(K);
logic signed [W-1:0] a, b;
logic signed [PW-1:0] product;
logic signed [AW-1:0] addend, acc;
assign product = $signed(a) * $signed(b);
assign addend = {{(AW-PW){product[PW-1]}}, product};0xFE를 8비트 signed로 읽으면 −2입니다. b=3일 때 product는 −6이고, AW비트로 확장할 때 위쪽 비트도 1로 채웁니다. 0으로 확장하면 큰 양수로 바뀌어 잘못된 누산을 합니다. 비트 패턴 검사는 signed 숫자 해석과 함께 기록해야 합니다. 인터페이스에서 unsigned로 선언한 버스를 내부에서 signed로 바꾸는 경우에도 변환 위치를 하나로 고정합니다.
설계에 붙는 제약
AW는 한 PE가 한 출력에 더하는 전체 K를 기준으로 정합니다. K축을 두 타일로 나누더라도 최종 합을 같은 누산기에 보관하면 전체 K가 기준입니다. 각 타일마다 작은 폭으로 계산한 뒤 확장해 더하는 방식은 타일 안에서 이미 잃어버린 상위 비트를 복구하지 못합니다. bias, 추가 스케일, 복수 작업의 합이 있으면 각각의 범위를 더 분석해야 하며 위 식을 그대로 재사용하면 안 됩니다.
검증에서는 최소 입력×최소 입력, 최소×최대, 최대×최대, 부호가 교대하는 벡터를 만듭니다. 정상 범위 안에서 정확히 계산한다는 계약과, 계약 밖에서 랩어라운드 또는 포화한다는 계약은 별개의 검사입니다. 큰 참조 정수와 실제 AW비트 결과를 둘 다 기록하면 산술 오류와 의도한 출력 변환을 구분할 수 있습니다.
제품 입력 계약에 W와 K의 최대치를 함께 적으세요. W만 정하고 K를 런타임에서 계속 늘리면 정적으로 계산한 AW의 보장이 사라집니다. 반대로 실제 K가 최대치보다 작으면 큰 누산기를 그대로 사용하는 것은 안전합니다. 제어기의 K 검사는 값 범위와 메모리 접근 범위 모두를 보호하므로 작업을 수락하기 전에 수행합니다.
직접 생각해 보기
W=4, K=3일 때 보수적인 AW와 최대 양수 합을 구하세요. −8×7을 AW비트로 확장할 때 채우는 비트는 무엇인가요?
해설 보기
PW=8, ceil(log2 3)=2이므로 AW=10입니다. 최대 양수 합은 3×(−8)×(−8)=192입니다. −8×7=−56이며 부호 비트 1을 반복해 확장합니다. 10비트 signed 범위는 −512..511입니다.