FIR(Finite Impulse Response) filter는 한국어로 말하면 유한 임펄스 응답으로, 더 쉽게 이야기하면 "입력에 대한 응답이 유한한 시간동안 발생하며, 그 이후에는 0"이 된다는 말이다. 이걸 더 쉽게 풀어보면 어떤 시간(T)이 지난 후에는 Impulse response가 0이 된다는 뜻이다.
아래의 그림은 FIR filter를 설명할때, 가장 많이 등장하는 그림이다. 대충 어떤건지 표현하자면, 입력 Xn에 대해서 지연시간 Z^(-1)이 발생하고, 모든 tap이 진행된 후에 어느정도 시간이 지나면 결과 Yn은 0이 된다는 것이다. (아마도..)
이론적인 부분은 넘어가고, 주제에 맞는 Verilog 코드와 함께 보면 어느정도 이해가 될 수 있을 수 있다.
module fir_4tap(
input clk,
input signed [7:0] x_in,
output reg signed [15:0] y_out
);
parameter signed [7:0] h0 = 8'h10; // 0.0625
parameter signed [7:0] h1 = 8'h20; // 0.125
parameter signed [7:0] h2 = 8'h30; // 0.1875
parameter signed [7:0] h3 = 8'h40; // 0.25
reg signed [7:0] x_delay [0:3];
always @(posedge clk) begin
x_delay[0] <= x_in;
x_delay[1] <= x_delay[0];
x_delay[2] <= x_delay[1];
x_delay[3] <= x_delay[2];
y_out <= h0 * x_delay[0] + h1 * x_delay[1] +
h2 * x_delay[2] + h3 * x_delay[3];
end
endmodule
위 코드는 Verilog HDL로 FIR filter를 만든 것이고, 여기에 대한 설명을 하나씩 해보자면,
- 4-tap filter : 4-tap이라는 것은 그림과 같이, 지연이 몇으로 되느냐를 나타낸다. 이 tap 수를 조정하면서 filter를 만들 수 있고, 이를 통해서 어떤 위상(phase)에 대해서도 응답을 만들 수 있다.. 고, 하는데 위상에 대한 부분은 필자가 더 공부가 필요하다.
- parameters : 각각의 tap에 곱해지는 계수이다. 4-tap이기 때문에 계수 또한 4개가 존재한다.
- reg x_delay[0:3] : input x_in이 4-clock 동안 shift 되면서 저장될 레지스터. x_in은 clock마다 들어오는 값이 서로 다를 수 있다.
- always 문
- clock에 맞춰 x_in이 x_delay register에 shift 된다.
- 주파수는 시간이 흐름에 따라 다른 값이 입력으로 들어오게 되고, 우리가 만들어놓은 tap의 개수만큼이 모여서 그 값들에 각기 다른 계수들이 적용되 출력 y_out을 구성.
- 맨위의 그림에서 보이는 파란색 시그마(Σ)들의 누적이 y_out
그림에서 보면 시그마도 매 clock 마다 shift 되면서 누적되는 accumulator 같은 성격을 보일 수 있다. 하지만 FIR 필터의 특성과 동작을 생각한다면, 누산을 하는 시그마의 영역은 적어도 1-cycle에 해결되어야 하고 timing의 문제각 발생한다면 tree 구조를 형성해서라도 현재 우리가 구하려는 nT(현재)에 대해서 nT-kT(tap 수 만큼 과거의 입력, x_in들) 만큼의 계수의 연산결과가 합산되어야 올바른 y_out이 만들어진다.
지금까지의 설명을 바탕으로 위 수식을 설명해보면,
- 원하는 응답값은 y(nT)이며, 이는 '현재'이다.
- y(nT)는 현재와 과거의 누적값이며, 누적되는 양은 tap의 개수라고 할 수 있는 0부터 M(code로는 3)까지이다
- ak는 계수이며, verilog 상으로는 h0 ~ h3이다.
- kT는 현재 nT에서의 과거를 의미한다. 즉, k가 0부터 3까지이므로, code 상으로는 현재와 1~3cycle 이전에 들어와서 shift되고 있는 값을 의미한다.
- 그렇기 때문에 위 수식을 풀어서 설명한다면, 입력 x_in이 shift되고 있으며, 매 cycle마다 shift 되는 값과 그에 상응하는 계수가 연산되고, 그 값을 합해 출력으로 내보내는 동작이다.
일단 Verilog 쟁이로서, verilog RTL을 역으로 계산해서 이론을 공부하다보니, 이렇게 밖에 해석이 되지 못한 점이 아쉽다. 우선은 필요한 내용을 필자가 다시 보기 위한 용도로 정리하고 있기는 하지만, 언젠가 더 심도 깊은 공부를 한 후에 멋진 내용들이 적히길 바란다.