본문 바로가기
Project/DSD project

[Project] Verilog Term Project-루트계산기(1)

by 끝까지 생각하고 알아내자 2023. 1. 8.

이번에는 베릴로그 언어로 텀프로젝트를 수행한 내용을 한번 알아보자. 텀 프로젝트 주제는 입력값 0~1023까지의 입력을 받아서 각각의 루트값을 근사해서 결괏값을 출력하는 모듈을 만드는 것이다. 예를 들어 입력값 10진수 892가 입력되었을 때 root(892)=29.8663... 이므로 이 근삿값인 29.875로 근사해서 출력하는 모듈을 만드는 것이다. 소수부분과 정수 부분의 출력기준은 Q(5.3)을 기준으로 출력한다. 29.875=11101.111 이므로 MSB를 기준으로 각각 4개씩 끊어서 출력하면 1110/1111 이므로 이는 16진수로 표현하면 EF이다. 따라서 29.875이면  출력은 2개의 hex로 출력하며 각각의 헥스는 segment display 2개를 통해서 최종적으로 EF가 출력되게 하는 모듈을 만드는것이 목적이다. 말로말 설명해서 굉장히 어려운 것 같은데 천천히 수식을 통해서 이해해 보자.

입력값에 대한 출력값이 나오는 Process

위와 같이 1023이 입력되었을 때는 제곱근값의 근삿값이 31.875로 근사되며 이를 8자리 2진수로 나타내면 나타낸다면 8'b11111.111이 된다. 이 2진수 숫자를 다시 4개씩 나누어서 16진수 2개로 해석하면 FF로 최종적인 결과가 된다. 이 결과를 세그먼트 디코더를 통해서 FF로 segment display로 나타내는 것이 설계목적이다. 기본적으로 베릴로그 환경에서는 소수점계산을 지원하지 않는다. 따라서 C언어나 C++ 같이 간단하게 나눗셈을 해서 구할 수없을뿐더러, 수학함수또한 사용할수없기 때문에 직접적으로 root값을 구할수 없기때문에 설계자가 이를 고려해서 직접 root값을 구하는 알고리즘 설계해야 한다는 것이 이번 프로젝트의 주목적이다. 또한 베릴로그에서는 %(모듈로 연산자) 기호나 /(몫을 구하는 기호) 기호는 합성과정에서 설계자가 의도한 대로 합성이 되지 않기때문에 근본적으로 사용하지 않는것이 일반적이다. 그렇다면 몫과 나머지로는 이 과정을 설계할수 없는데, 이 과정을 어떻게 설계해야 할까? 얼핏 보면 for분을 통해서 나눗셈으로 쉽게 구현해도 될것같지만 for문역시 베릴로그에서는 제대로 합성이 되지않기 때문에 사용하지 않는 함수이다. 따라서 우리가 일반적으로 접근하는 방법으로는 안된다. 먼저 소수점을 어떻게 다루어야 하는지 알아보자. 크게는 고정 소수점 표현방법과 부동 소수점 표현 방법이 있다. 각각이 어떤 방법인지 한번 알아보자. 

 

1. 고정 소수점 표현 방식(Fixed point number) 

고정 소수점 표현방법은 말 그대로 소수점을 고정시켜서 해석을 하겠다는 것이다. 2진수에서 정수비트와 소수비트를 각각 몇 비트로 할지 설계자가 미리 정해서 LSB로부터 소수점까지의 비트를 모두 소수점으로 해석하고 MSB로부터 소수점까지의 비트를 모두 정수로 해석하는 방법이다. 필요에 따라서 MSB를 부호비트로 사용해서 음수와 양수로 표기가 가능하게 설계할 수도 있다. 이러한 고정 소수점 방법은 구현하기 편리하지만 사용하는 비트수 대비 표현 가능한 수의 범위와 정확도는 낮기 때문에 실수를 다룰 필요가 없는 환경에서는 거의 쓰이지 않는다. 하지만 우리는 베릴로그 환경에서 소수를 구현할 것이 이기 때문에 이와 같은 소수점 표현방법이 유용하게 사용될 수 있다. 

정수5비트 소수4비트인 고정 소수점

위와 같이 임의로 비트수를 설정해서 소수가 존재하는 숫자(실수)를 구현할 수 있다. 구현환경과 요구되는 정확성에 따라서 설계자가 소수 부분과 정수부분을 몇비트로 해야될지 정할수 있다는 특징이 있다. 프로젝트의 구현환경은 Q(5.3) 으로 구현해야 하므로, 정수부분 5비트 소수부분 3비트로 설계하는 것이 간편할 것이다. 소수 3비트의 해석은 다음과 같이 해석된다. 

2진수 소수부분  해석된 10진수
000 0
001 0.125
010 0.25
011 0.375
100 0.5
101 0.625
110 0.75
111 0.875

 

2. 부동 소수점 표현 방식(Floating point number)

이번에는 부동 소수점 표현방법에 대해서 알아보자. 부동 소수점 방식은 고정소수점과는 다르게 소수점이 움직이면서 해석하는 소수 표현 방식이다. 따라서 부동 소수점 표현방식은 직접 사용하기 전에 따로 정규화의 과정이 필요하다. 이 정규화의 과정은 설계자가 어떻게 설계하냐에 따라서 달라지는데 필자는 이 과정에서 모두 정수로 바꾸어 버리는 게 편해서 그냥 정수로 바꾸는 것을 정규화라고 정의하겠다. 필요에 따라서 정규화 과정이 정수1비트만 남기고 모두 소수로 바꾸는것 또한 정규화가 될 수 있고, 정수 부분을 하나도 남기지 않고 모두 소수로 바꾸는 과정 또한 정규화가 될 수 있다. 어떤 형태를 기준으로 설정하냐에 따라서 정규화의 과정은 충분히 바뀔 수 있음을 인지하고 설명을 이해해 보자. 

 

-정규화의 과정(Normalization)

10진수를 먼저 생각해 보자. 10.258이라는 실수가 존재하는데 이 숫자는 10+0.258로 이루어져있음을 쉽게 알수 있다. 하지만 앞서 말했듯이 베릴로그에서는 이와같은 형태로 바로 해석할수없다. 따라서 정규화의 과정이 필요하다. 10.258을 정규화 한다는 의미는 모두 정수로 바꾼다는 의미이므로 10.258에 1000을 곱하면 10258로 되어서 더이상 소수부분이 없는 순수 정수만 남게 된다. 따라서 소수부분이 존재하는 10진수를 정규화를 하면 10.258=10258*10^3 이 된다. 이렇게 10진수에서는 10^n을 곱해서 정규화를 할수 있다는것은 쉽게 알 수 있다. 하지만 2진수를 정규화해보면 어떻게 될까? Q(5.3) 2진수 11111.111이 존재한다고 하자. 이 숫자는 31.875인데 이를 10진수가 아닌 2진수로 정규화를 하려고 한다. 10진수에서는 10^n을 곱해서 정규화했지만 2진수에서는 2^n을 곱해서 정규화 과정을 해결할수있다. 왜?라고 의문점이 들면 그것이 정상이다. 2^n이 2진수에서 어떤의미를 가지는지 생각해보자. 바로 쉬프트(bit shift) 개념이다. 어떤 2진수에 2^n을 곱하게 되면 비트가 왼쪽으로 쉬프트된다. 따라서 이러한 개념을 다시 소수점개념에 적용해보면 31.875를 3번 쉬프트 해보자 그러면 31875.0으로 정규화가 된것을 알수있다. 최종적으로 정규화결과는 31.875=31875.0*2^3 이되는것을 이해할수있다. 이렇게 정규화의 과정을 통해서 소수점을 정수로 바꾸어서 정수로 해석하는 개념이 부동소수점의 개념이다. 정규화의 개념은 소수부분,정수부분,정수1의자리 등 어떤것을 중점적으로 남길것인지에 따라서 기준이 다르지만 소수점이 움직여서 해석을 할수있는 형태로 만든다는것에서 그 목적은 동일하다는것을 알수있다. 

 

이렇게 2가지 방법으로 소수점을 표현할 수 있으며, 문제상황에 맞게 소수점을 계산해 보자. 특히 루트근삿값을 계산하는 과정에는 어떤 방법이 유리한지 생각해 보자.