프로젝트 & 경진대회

Simplified FIR Filter Design

htaekjung 2024. 11. 30. 23:18

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는 가운데를 기준으로 대칭이라는 것을 알 수 있습니다. 

33 Coefficient Values

 


2. FIR Filter algorithm design

1) HW block diagram

Conceptual block diagram

위의 블록다이어그램에서 볼 수 있듯이 33개의 tap을 지닌 FIR filter를 설계해보려 합니다.

Coefficient 값들이 대칭이므로 대칭성을 이용하여 위의 그림처럼 나타낼 수 있습니다.

 

FIR Filter 동작설명

왼쪽에서  iFirIn data가 들어가면 1 clock이 지날 때마다 iFirIn이 순서대로 블록 다이어그램에 있는 레지스터에 저장됩니다

레지스터에 저장된 값들이 coefficient values와 곱해져서 다 더해져 saturation 과정을 거쳐 oFirOut으로 출력됩니다.


2) Timing diagram

Timing diagram


3) Simulation Result

  • Version 1( FIR Filter without symmetry)
    • Coefficient의 대칭성을 고려하지 않고 정직하게, 직관적으로 짠 코드입니다. 

FIR_Filter.v
0.01MB

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을 사용하여 곱셈을 진행했습니다.

 

FIR Filter with symmetry

 


4) PPA Evaluation

Version 1
Version 2

Version 1의 경우 total register이 128개로 version 2 보다 대략 90개 정도가 적게 쓰인 것을 알 수 있습니다. 

또한 power의 경우에도 정말 작은 차이로 version 1이 더 낮은 전력을 소모한다는 것을 알 수 있습니다.

 

 

다음 포스트에서는 spsram과 controller, acc, saturation 기능을 하는 sum 모듈을 포함한 FIR filter에 대해 작성할 예정입니다.