본문 바로가기
language/Verilog

[verilog] hardware realtime DCT

by 파란하늘코더 2021. 1. 26.
반응형

DCT같은 수식도 LUT(Look Up table)로 구현할 수도 있지만 실제 연산을 통해서 구현할 수가 있습니다

 

verilog에서 어떻게 구현이 가능한지 정리를 해보겠습니다


1. DCT 수식

 

우선 dct는 아래와 같은 수식이라고 하며 cosine 함수의 조합으로 적용을 합니다

 

아래와 같이 2-dimension 수식에서 필요한 dimension만 추출 할 경우 1-dimension 처리가 가능합니다

 


2. DCT 구현을 위한 SW 검증

 

이번에 구글링하면서 정말 힘든게 이게 dct도 정확히 모르고 그냥 무작정 찾은 것도 있었지만

 

대부분 아래와 같은 그림만 주구장창 나와서 이해하는데 한참 걸렸습니다

해당 논문은 dct를 hardware로 구현하는 방식은 무수하게 많은데 compelxity를 고려하여 여러가지 방식으로

 

구현해보고 비교한 것 같습니다....

 

제가 구현한건 chen이란 사람이 개발한 건데 위의 그림처럼 단순하게 8개의 data 입력받아서 +, -, *만 이용해서 dct를 구하는 것입니다

 

그래서 우선 python에서 그냥 dct를 구하면 어떻게 나오는지 보면

dct하고 다시 바로 idct 해서 원본이 나오는 것을 확인 했습니다

 

문제는 저 dct 함수에 option들의 의미를 모르고 그냥 사용한건데,,, 나중에 좀 더 공부해봐야 알 것 같습니다

 

우선 이렇게 solution을 찾아논 담에 이제 논문을 구현해보았습니다

코드를 보면 마지막에 전체적으로 나누기2를 해줘야 기존에 구한 값과 똑같아지는데 이것도 나중에 시간이나면 좀 더 공부해봐야 할 것 같네요...

 

이렇게 해서 출력을 해보면?

이렇게 나오는데

 

이 원래의 정답과 비교해보면 똑같이 나오는 것을 확인 할 수가 있습니다

 

그리고 반대과정인 idct를 해보려는데 이게 구글링을 하면 제대로 설명은 하나도 없고

 

반대로하면 됩니다~~이런식으로만 설명되어있고 좀 나와있는 수식 적용 해봤는데 값이 나오질 않아서 좌절....

 

이런식으로 대강 설명만 되어있어서 좌절하고 있었는데

 

구글도서에서 이렇게 나와있는 걸 발견해서 똑같이 구현해봤습니다

 

화살표 방향보고 힌트를 얻었습니다

 

마지막에 왜 2로나누는지 아직 이해 못하고 있습니다...

 

이걸 출력하면 아래와 같이 나오는데

 

기존 data와 오차가 있지만 반올림 하면 똑같아지는 것을 확인 할 수가 있습니다

 

SW 구현 및 검증은 이걸로 끝내고 HW로도 검증을 해봅시다


3. DCT hardware 설계

8개 단위로 받을 수 있도록 8port로 data 입력 부분을 설계해놓고

hardware에서 dct/idct에 사용하는 parameter들을 사용하기 위해선 값을 가져와야 합니다.

 

따라서 floating으로 할지 fixed point로 할지 고민하다가 fixed로 하기로 정하고 소수점 8bit을 살리기로 했습니다

 

그러면 나오는 parameter는 다음과 같습니다

 

여기서 하위 8bit만 가져가기 위해서 아래와 같이 처리를 해주면

이렇게 결과가 나오게 됩니다

그래서 최종 적용은 부호비트를 고려하여

이렇게하고 python과 동일하게 코드를 설계해봅시다

 

기존에 공부했던 signed arithmetic을 적용하면 

 

이렇게 설계가 가능하고 입력 data의 8pixel data를 보면

 

전부다 12인것을 확인할수가 있는데 hardware에서 input과 비교합니다

이렇게 matching이 된 것을 보면 다음 차례 처리되는 값을 비교합시다

 

python은 값들이 아래와 같이 나오는 것을 확인 가능합니다

그리고 verilog로 아래와 같이 설계를 해주면

 

simulation 결과가 아래와 같이 나옵니다

 

stage1 에서 24 - 결과 확인

 

stage2 에서 48 - 결과 확인

 

stage3 에서의 17376이란 값이 67.875인지 확인해봐야 하는데

 

17376의 비트표현은 100_0011_1110_0000 이고 지금 소수점을 쓰는 것은 하위 8bit만인데

 

100_0011을 풀면 67이고, 1110_0000을 풀면 0.875로 나오는 것을 확인할 수가 있습니다

 

그리고 최종값도

2가지의 실험값이 같은 것을 확인 할 수가 있습니다.

 

여기서도 나온 값을 자세히 분석하면 소수부분은 480은 1_1110_0000이고 이를 처리하면 0.9375 나오는걸 확인 가능합니다

 

 

 

 

댓글