#Project 2-순차회로로 루트계산기 만들기(멀티사이클 구조)
이번에는 순차회로로 루트계산기를 한번 만들어보자. 앞서 만든 조합회로로 계산기를 만든 것은 로직의 과정이 한 번만에 결과가 나와야 해서 코드의 길이가 길고 비교기가 많이 사용되었다. 하지만 순차회로로 만들면 input에 대한 output이 한과정만에 나오지 않아도 된다. 즉, 여러 사이클에 의해서 결과가 나오는 것을 의미하며 이로 인해서 코드의 길이가 조합회로와 비교했을 때 비교적 짧고 로직또한 비교적 간단하게 설계될 수 있다는 것을 의미한다. 이를 multi-cycle구조라고 한다. 앞서 설계한 조합회로는 클럭의 개념이 들어가 있지 않지만 구조상으로 single-cycle구조라고도 한다. 멀티사이클 구조는 로직의 사용과 코드가 단순하고, hw의 면적이 비교적 작다는 장점이 있지만 제어가 어렵고 레지스터가 많이 사용된다는 특징이 있다. 따라서 이번에는 이 멀티사이클구조로 루트계산기를 한번 설계해 보자.
ㅎㅎ
#설계의 과정
마찬가지로 설계의 과정은 입력값에 대한 루트값을 구하고 근삿값을 결정한뒤에, 근사값을 디코더를 통해서 최종결과로 변환하는 과정이다. 하지만 앞선 과정과는 다르게 멀티사이클로 구조이므로 루트값을 구하는 과정에서 비교기를 많이 사용할 필요 없이 매 클럭마다 0.125씩 더하면서 비교하는 과정으로 대체할 수 있다고 생각했다. 따라서 소수표현방식도 고정소수점 방법을 사용해서 설계했다. 따라서 정수 부분을 비교기를 통해서 미리 구할 필요 없이 1(0.125) 씩 더하면서 입력값과 비교하면서 구현이 가능하다.
1. 고정소수점의 해석과 설계(비트수)
출력의 형태는 마찬가지로 Q(5.3)을 따른다. 따라서 기본적으로 정수 5비트 소수 3비트로 비트수를 설정하는 것이 계산을 할 때 훨씬간편할것이다. 하지만 제곱을 할 때는 어떻게 비트수를 설정해야 할까? 고정소수점의 특성으로 정수 5비트+소수 3비트를 제곱하면 정수 10비트+소수 6비트로 비트수가 맞추어진다는 것을 알 수 있다. 수식을 통해서 한번 이해해 보자.
10진수 소수의 연산을 한번 생각해 보자. 1.5와1.5를 더하는연산은 정수와 소수를 따로 더하는것으로 구현될수있다. 따라서(1+1)+(0.5+0.5)=3 으로 최종적인 결과를 얻을수있다. 하지만 곱셈은 이와 다르다. 1.5*1.5는 정수부분과 소수부분을 따로 곱하는 연산으로 구현될수없을뿐더러, 연산과정에서 소수점의 위치가 바뀐다. 1.5*1.5=15*15*0.01=2.25이므로 소수점의 위치는 LSB를 기준으로 한칸옮겨진것을 확인할수있다. 따라서 곱셈연산에서는 소수점위치를 곱하는수의 소수점위치만큼 이동시켜야함을 알수있을것이다. 따라서 2진수 Q(5.3)제곱연산은 10.6으로 정수10비트+소수6비트로 소수점이 정해진다는것을 알수있다. root(input)=output에서 input은 10비트정수이고 output은 5비트정수+3비트소수형태이다. 따라서 이를 제곱하면 input=output^2이고 output^2은 앞서 설명한것과 같이 10비트정수+6비트소수로 구성된다. 멀티사이클회로로 설계하기위해서 output^2의값을 1식더하면서 input과 비교하는방법을 생각해보자. 설계자가 해석하는 숫자는 0.125씩 더하는 것이지만 툴이해석 하는 것은 1씩 더하는 것으로 해석한다. 따라서 설계자가 임의로 비트를 나누어서 정수와 소수를 나누어서 해석할 필요가 있다.
2. 9비트 카운터의 설계
1씩 더하는 모듈을 설계하기 위해서 9비트 카운터를 기반으로 설계했다. 8비트가 아닌 9비트인 이유는 입력값이 1017~1023인경우는 2진수로 표현할 때 8비트로 표현되지 않기 때문이다. 따라서 overflow를 방지하기 위해 9비트 카운터로 비트수를 설계하였다. 1씩 더하는 카운터에서 조건이 필요하다. 조건없이 1을 더하는 것이 아닌 입력값과 비교했을 때 커질 때까지 더하는 것이므로 입력값의 제곱보다 작을 때 카운터가 1씩 더 해진다는 조건이 if 문으로 사용되야 한다. 따라서 코드상에서 구현하면 다음과 같다.
result는 결괏값으로 counter에서 1씩 더 해지는 변수이고 in은 입력값이다. if문을 이용해 결괏값의 제곱이 입력값보다 작을 때만 1씩 더하는 모듈을 설계했다. 따라서 최종적으로 result는 입력값보다 1(0.125)만큼 작은 값이 저장된다.
3. 근삿값의 결정
최종적인 루트값의 근삿값을 결정해 보자. 이전단계에서 result의 값을 결정했다. 하지만 이 result의 값은 정확한 값은 아니다. 왜냐하면 입력값과 비교했을 때 입력값과 가까운지 입력값-1과 가까운지 아직 판단하지 않았기 때문이다. 10진수로 한번 다시 생각해 보자. root(10)=3.162 xxx에서 result의 값은 3.162와 가장 가까운 3.125로 결정될 것이다. 하지만 root(10)의 값이 3.125와 가까운지 3.25와 가까운지 비교과정이 필요하다. 따라서 뺄셈 기를 통해서 차이가 작은 쪽으로 근사하는 방법을 사용한다. result의 제곱과 입력값에 소수 부분을 붙인 값을 비교해 최종 근삿값인 apxresult를 결정한다.
다음과 같이 비교문을 적을 수 있으며 입력값에 따라서 비교문을 통해 apxresult(최종근삿값)이 result가 될지 result-1이 될지 결정한다.
3. 입력값이 1017~1023인 경우 코드상의 구현
입력값이 1017~1023인 경우 이전에 설계했던 것과 동일하게 출력값이 32가 될 수 없으므로, 무조건 31.875로 근사되어야 한다. 따라서 1017~1023을 이진수로 나타낼경우 이진수의 MSB가 1이므로 result [8]=1일 때 근삿값은 항상 31.875라고 코드상에서 표현되어야 한다. 따라서 조건문을 이용해 나타내면 다음과 같다.
스키매틱에 사용된 로직은 9비트 카운터를 위한 레지스터 그리고 mux, 비교기, 곱셈기, 덧셈기, 뺄셈기가 사용되었다 코드상으로 구현한 것과 동일하게 스키매틱이 설계되며 마지막구조에서 segdec를 통해 hex로 데이터가 변환되는 것을 알 수 있다.
'Project > DSD project' 카테고리의 다른 글
[Project] Verilog Term Project-2차방정식 (0) | 2023.01.14 |
---|---|
[Project] Verilog Term Project-루트계산기(2) (0) | 2023.01.11 |
[Project] Verilog Term Project-루트계산기(1) (0) | 2023.01.08 |