모든 이야기

fixed-point 스케일: 소수점이 없는 비트열에서 숫자가 어긋나는 순간

소수점이 찍힌 숫자를 계산한다고 해서 회로 안에 소수점 전용 저장소가 생기는 것은 아니다. fixed-point 데이터패스가 보관하는 것은 정수 비트열이다. 그 비트열에 어떤 단위를 붙이느냐가 소수점을 만든다. 두 입력의 비트 폭이 같아도 단위가 다르면, 평범한 정수 덧셈기가 아주 그럴듯한 오답을 낼 수 있다.

fixed-point 스케일을 이해할 때는 Q 표기부터 외우기보다 저장 정수와 실제 값을 나누어 적는 편이 명확하다. 여기서는 전체 폭을 W, 소수부 비트 수를 F라고 하고, 2의 보수로 해석한 저장 정수 r의 실제 값을 r×2^-F로 정의하자. Q 표기는 문헌에 따라 부호 비트를 정수부에 포함하는 방식이 달라 이 정의를 먼저 고정하는 것이 좋다.

같은 비트열에 붙은 다른 단위

W=8, F=4이면 저장 정수의 범위 −128127은 실제 값 −87.9375가 된다. 인접한 두 표현의 차이는 1/16이다. 비트열 00011000은 정수로 24이고, 이 형식에서는 1.5다. 똑같은 비트열을 F=6으로 읽으면 0.375다. 소수점 위치를 바꾸었다는 말은 비트를 움직였다는 말과 같지 않다. 비트의 무게를 바꾸어 해석했을 수도 있기 때문이다.

AMD의 Vitis HLS 문서는 ap_fixed의 W를 전체 비트 수, I를 부호 비트를 포함한 정수부 비트 수로 정의한다. 이 표기에서는 F=W−I다. 서로 다른 정밀도의 연산에서 이진 소수점 위치를 정렬한다는 설명도 나온다. 직접 정수 RTL을 작성할 때는 그 정렬을 설계자가 명시해야 한다. AMD UG1399 fixed-point 형식 정의

가상의 덧셈을 해 보자. a=1.5를 F=4로 저장하면 r_a=24다. b=0.75도 F=4로 저장하면 r_b=12다. 정수 덧셈 24+12=36을 한 뒤 F=4로 해석하면 2.25가 된다. 두 입력과 출력이 같은 단위를 쓰므로 정수 덧셈이 그대로 실제 값의 덧셈이 된다.

하지만 b를 F=6으로 저장했다면 r_b=48이다. 비트 폭만 확인하고 24+48을 계산한 다음 F=4 출력으로 읽으면 4.5가 나온다. 덧셈기는 고장이 없다. 서로 다른 단위의 정수를 더한 것이 문제다. 이 예에서는 48을 4로 나눈 12로 바꾸거나, a를 F=6의 정수 96으로 바꾸어 96+48=144를 계산해야 한다. 후자는 같은 8비트 signed 폭에 144를 담을 수 없으므로 중간 폭도 늘려야 한다.

곱셈은 소수부 비트 수까지 더한다

같은 F=4 입력끼리 곱하면 저장 정수 24×12=288의 소수부 비트 수는 8이 된다. 실제 값은 288/256=1.125다. 입력에 붙은 두 스케일이 곱해지기 때문이다. 이 288을 아무 변환 없이 F=4 출력에 넣고 읽으면 스케일이 16배 어긋난다. 출력도 F=4라면 288을 16으로 나눈 정수 18을 저장해야 한다.

이 예는 버리는 하위 비트가 모두 0이라 변환이 정확하다. 일반 입력은 그렇지 않다. 곱의 정밀한 정수 결과를 만든 뒤 어느 비트를 남길지 정하고, 버리는 비트가 답을 올릴 조건인지 판단해야 한다. 결과 저장 폭을 먼저 줄이면 반올림 판단에 필요한 정보까지 사라질 수 있다.

음수에서는 ‘오른쪽으로 밀어서 버린다’는 표현도 조심해야 한다. F=8의 저장 정수 −19를 F=4로 바꾸려면 새 저장 정수는 정확히 −19/16=−1.1875다. 이를 아래 정수로 내리면 −2, 0 방향으로 자르면 −1이다. 실제 출력도 각각 −0.125와 −0.0625로 달라진다. signed 산술 오른쪽 이동이 하위 비트를 버리는 방식은 일반적으로 전자에 해당한다. 양수 예제만 보면 놓치기 쉬운 차이다.

UG1399는 양자화 모드와 overflow 모드를 별도 항목으로 정의하고, 이 모드가 대상 변수의 대입이나 초기화에서 적용된다는 점을 설명한다. 특정 저장 형식의 정책을 지정했다고 해서 계산 중 모든 임시 결과가 그 정책을 따른다고 가정할 수는 없다. AMD UG1399의 Q·O 및 대입 동작 설명

소수점 위치는 인터페이스 계약이다

F를 늘리면 한 칸이 작아져 더 세밀한 값을 표현한다. 같은 W를 유지하면 대신 표현 가능한 크기가 줄어든다. 작은 평균 오차가 나왔다는 사실만으로 큰 입력에서 범위가 충분한지 알 수 없고, 넉넉한 범위만 확인해서 작은 신호가 살아남는지 알 수도 없다.

따라서 fixed-point 설계에서 검토할 대상은 입력 형식 하나가 아니다. 입력의 W와 F, 중간 합과 곱의 폭, 스케일을 바꾸는 위치, 출력의 버림 또는 반올림을 함께 적어야 한다. 여러 항을 더한다면 최종 출력이 범위 안에 들어오더라도 중간 합은 그 범위를 넘을 수 있다. 시뮬레이션의 기준 모델 역시 같은 위치에서 폭을 줄여야 비트 단위 비교가 의미 있다.

회로에 소수점은 어디 있느냐는 질문의 답은 결국 비트의 무게와 변환 규칙에 있다. 정수 연산 자체가 맞는지 확인한 다음, 그 정수가 어느 단위의 값을 뜻하는지 확인해야 한다. 이 두 검토를 연결하면 비트는 정상인데 숫자는 틀리는 오류가 보이기 시작한다.

fixed-point 스케일: 소수점이 없는 비트열에서 숫자가 어긋나는 순간 · ariser