Htaekjung/DSD-Simplified-Fir-Filter
GitHub - Htaekjung/DSD-Simplified-Fir-Filter
Contribute to Htaekjung/DSD-Simplified-Fir-Filter development by creating an account on GitHub.
github.com
1. FIR Filter algorithm design
1) FIR filter 사양
- Operation clock : 12MHz
- Sampling rate: 600kHz
- Symbol rate: 200kHz
Impulse response가 선형 위상 그래프를 띄기에 coefficient value는 가운데를 기준으로 대칭이라는 것을 알 수 있습니다.
2. FIR Filter algorithm design
1) HW block diagram
위의 블록다이어그램에서 볼 수 있듯이 33개의 tap을 지닌 FIR filter를 설계해보려 합니다.
Coefficient 값들이 대칭이므로 대칭성을 이용하여 위의 그림처럼 나타낼 수 있습니다.
FIR Filter 동작설명
왼쪽에서 iFirIn data가 들어가면 1 clock이 지날 때마다 iFirIn이 순서대로 블록 다이어그램에 있는 레지스터에 저장됩니다
레지스터에 저장된 값들이 coefficient values와 곱해져서 다 더해져 saturation 과정을 거쳐 oFirOut으로 출력됩니다.
2) Timing diagram
3) Simulation Result
- Version 1( FIR Filter without symmetry)
- Coefficient의 대칭성을 고려하지 않고 정직하게, 직관적으로 짠 코드입니다.
3비트 입력신호 iFirIn에 3'b001(단위 임펄스)을 넣었기에 FIR Filter의 output은 impulse response와 동일한 형태를 띔을 알 수 있습니다.
- Version 2( FIR Filter with symmetry)
assign wFirSum1st = {{13{rFirDelay1st[2]}}, rFirDelay1st[2:0]}
+ {{13{rFirDelay33rd[2]}}, rFirDelay33rd[2:0]};
// rFirDelay[3] & rFirDelay[31]
assign wFirSum2nd = {{13{rFirDelay3rd[2]}}, rFirDelay3rd[2:0]}
+ {{13{rFirDelay31st[2]}}, rFirDelay31st[2:0]};
// rFirDelay[4] & rFirDelay[30]
assign wFirSum3rd = {{13{rFirDelay4th[2]}}, rFirDelay4th[2:0]}
+ {{13{rFirDelay30th[2]}}, rFirDelay30th[2:0]};
// rFirDelay[6] & rFirDelay[28]
assign wFirSum4th = {{13{rFirDelay6th[2]}}, rFirDelay6th[2:0]}
+ {{13{rFirDelay28th[2]}}, rFirDelay28th[2:0]};
// rFirDelay[7] & rFirDelay[27]
assign wFirSum5th = {{13{rFirDelay7th[2]}}, rFirDelay7th[2:0]}
+ {{13{rFirDelay27th[2]}}, rFirDelay27th[2:0]};
// rFirDelay[9] & rFirDelay[25]
assign wFirSum6th = {{13{rFirDelay9th[2]}}, rFirDelay9th[2:0]}
+ {{13{rFirDelay25th[2]}}, rFirDelay25th[2:0]};
// rFirDelay[10] & rFirDelay[24]
assign wFirSum7th = {{13{rFirDelay10th[2]}}, rFirDelay10th[2:0]}
+ {{13{rFirDelay24th[2]}}, rFirDelay24th[2:0]};
// rFirDelay[12] & rFirDelay[22]
assign wFirSum8th = {{13{rFirDelay12th[2]}}, rFirDelay12th[2:0]}
+ {{13{rFirDelay22nd[2]}}, rFirDelay22nd[2:0]};
// rFirDelay[13] & rFirDelay[21]
assign wFirSum9th = {{13{rFirDelay13th[2]}}, rFirDelay13th[2:0]}
+ {{13{rFirDelay21st[2]}}, rFirDelay21st[2:0]};
// rFirDelay[15] & rFirDelay[19]
assign wFirSum10th = {{13{rFirDelay15th[2]}}, rFirDelay15th[2:0]}
+ {{13{rFirDelay19th[2]}}, rFirDelay19th[2:0]};
// rFirDelay[16] & rFirDelay[18]
assign wFirSum11th = {{13{rFirDelay16th[2]}}, rFirDelay16th[2:0]}
+ {{13{rFirDelay18th[2]}}, rFirDelay18th[2:0]};
// rFirDelay[17]
assign wFirSum12th = {{13{rFirDelay17th[2]}}, rFirDelay17th[2:0]};
Coefficient의 대칭성과 coefficient의 값이 양수, 0, 음수가 규칙적으로 반복된다는 특성을 이용하여 33개의 shift register를 wFirSum으로 합쳤습니다.
/******************************************************************/
// Middle multiplier (CSD: Canonic Signed Digit)
/******************************************************************/
// Tap n-16 & n+16 : +(0_0000_0011) <= 2ea One
//
// Tap n-14 & n+14 : -(0_0000_0101) <= 2ea One
// Tap n-13 & n+13 : +(0_0000_0110) <= 2ea One
//
// Tap n-11 & n+11 : -(0_0000_1010) <= 2ea One
// Tap n-10 & n+10 : +(1_0000_1100) <= 2ea One
//
// Tap n-8 & n+8 : -(0_0001_0011) <= 3ea One
// Tap n-7 & n+7 : +(0_0001_0111) <= 4ea One
//
// Tap n-5 & n+5 : -(0_0010_0100) <= 2ea One
// Tap n-4 & n+4 : +(0_0011_0000) <= 2ea One
//
// Tap n-2 & n+2 : -(0_0110_0101) <= 4ea One
// Tap n-1 & n+1 : +(0_1100_1101) <= 5ea One
// Tap n : +(1_1111_0011) <= 7ea One
/******************************************************************/
// Tap n-16 & n+16
assign wFirMul1st = {wFirSum1st[15:0]}
+ {wFirSum1st[14:0], 1'h0};
// Tap n-14 & n+14
assign wFirMul2nd = {wFirSum2nd[15:0]}
+ {wFirSum2nd[13:0], 2'h0};
// Tap n-13 & n+13
assign wFirMul3rd = {wFirSum3rd[14:0], 1'h0}
+ {wFirSum3rd[13:0], 2'h0};
// Tap n-11 & n+11
assign wFirMul4th = {wFirSum4th[14:0], 1'h0}
+ {wFirSum4th[12:0], 3'h0};
// Tap n-10 & n+10
assign wFirMul5th = {wFirSum5th[13:0], 2'h0}
+ {wFirSum5th[12:0], 3'h0};
// Tap n-8 & n+8
assign wFirMul6th = {wFirSum6th[15:0]}
+ {wFirSum6th[14:0], 1'h0}
+ {wFirSum6th[11:0], 4'h0};
// Tap n-7 & n+7
assign wFirMul7th = {wFirSum7th[15:0]}
+ {wFirSum7th[14:0], 1'h0}
+ {wFirSum7th[13:0], 2'h0}
+ {wFirSum7th[11:0], 4'h0};
// Tap n-5 & n+5
assign wFirMul8th = {wFirSum8th[13:0], 2'h0}
+ {wFirSum8th[10:0], 5'h0};
// Tap n-4 & n+4
assign wFirMul9th = {wFirSum9th[11:0], 4'h0}
+ {wFirSum9th[10:0], 5'h0};
// Tap n-2 & n+2
assign wFirMul10th = {wFirSum10th[15:0]}
+ {wFirSum10th[13:0], 2'h0}
+ {wFirSum10th[10:0], 5'h0}
+ {wFirSum10th[9:0], 6'h0};
// Tap n-1 & n+1
assign wFirMul11th = {wFirSum11th[15:0]}
+ {wFirSum11th[13:0], 2'h0}
+ {wFirSum11th[12:0], 3'h0}
+ {wFirSum11th[ 9:0], 6'h0}
+ {wFirSum11th[ 8:0], 7'h0};
// Tap n
assign wFirMul12th = {wFirSum12th[15:0]}
+ {wFirSum12th[14:0], 1'h0}
+ {wFirSum12th[11:0], 4'h0}
+ {wFirSum12th[10:0], 5'h0}
+ {wFirSum12th[9:0], 6'h0}
+ {wFirSum12th[8:0], 7'h0}
+ {wFirSum12th[7:0], 8'h0};
Canonic Signed Digit을 사용하여 곱셈을 진행했습니다.
4) PPA Evaluation
Version 1의 경우 total register이 128개로 version 2 보다 대략 90개 정도가 적게 쓰인 것을 알 수 있습니다.
또한 power의 경우에도 정말 작은 차이로 version 1이 더 낮은 전력을 소모한다는 것을 알 수 있습니다.
다음 포스트에서는 spsram과 controller, acc, saturation 기능을 하는 sum 모듈을 포함한 FIR filter에 대해 작성할 예정입니다.
'프로젝트 & 경진대회' 카테고리의 다른 글
Developing Vision Intelligence Applications on Furiosa WARBOY (0) | 2025.01.12 |
---|---|
Direct FIR Filter Digital Design in 2 versions with PPA results (0) | 2024.12.08 |
Furiosa Warboy tutorial (1) | 2024.10.21 |
RISC-V Single-Cycle Processor Design (0) | 2024.10.12 |
차세대반도체 경진대회 회고록 (3) | 2024.09.08 |