# 🪟 Thiết kế bộ lọc FIR: cửa sổ (window) và Parks-McClellan

By Everwise Intern

> Sign in to view the full content of this lesson.

## Từ bộ bốn tham số đặc tả đến hệ số $h[n]$

Bài trước, ta đã chuẩn hóa một đặc tả thành bộ bốn tham số: tần số biên dải thông $\omega_p$, tần số biên dải chặn $\omega_s$, gợn dải thông $\delta_p$ và gợn (hay suy hao) dải chặn $\delta_s$ / $A_s$. Bài này là bước biến bộ bốn đó thành tập hệ số $h[n]$ của bộ lọc FIR (finite impulse response). Bước này không chỉ mang tính lý thuyết: bậc $M$ mà bạn chọn ở đây quyết định trực tiếp số bộ nhân (multiplier), số thanh ghi và độ trễ mà FPGA của bạn phải chịu ở Module 2.

Mục tiêu của bài:

- Viết được đáp ứng xung lý tưởng của bộ lọc thông thấp và chỉ ra vì sao không dùng trực tiếp được.
- Giải thích được hiện tượng Gibbs và hệ quả của nó lên chất lượng dải chặn.
- Chọn được hàm cửa sổ (window) phù hợp với từng cặp yêu cầu $A_s$ và độ rộng dải chuyển tiếp.
- Ước lượng được bậc tối thiểu trước khi thiết kế, thay vì thử sai.
- Dùng được thuật toán Parks-McClellan để đạt cùng đặc tả với bậc nhỏ nhất.

## Vì sao phải "cắt" đáp ứng xung lý tưởng

Bộ lọc thông thấp lý tưởng có đáp ứng xung

$$
h_d[n] = \frac{\sin(\omega_c n)}{\pi n}, \quad -\infty < n < \infty
$$

Đây là một hàm dài vô hạn và không nhân quả (non-causal), nên về mặt vật lý không thể triển khai. Hai thao tác bắt buộc phải làm là cắt về độ dài hữu hạn $M$ và dịch sang phải để nhân quả.

Việc cắt tương đương nhân $h_d[n]$ với một cửa sổ chữ nhật, tức là tích chập phổ của bộ lọc với hạt nhân Dirichlet. Hệ quả là các gợn dao động quanh điểm gián đoạn, gọi là hiện tượng Gibbs (Gibbs phenomenon). Điểm cần nhớ: biên độ gợn overshoot khoảng 9% và **không giảm** khi tăng $M$; tăng $M$ chỉ làm các gợn hẹp lại và dải chuyển tiếp dốc hơn. Đỉnh búp phụ (sidelobe) của cửa sổ chữ nhật cố định ở mức $-13$ dB, tương ứng suy hao chặn chỉ khoảng $21$ dB. Với hầu hết đặc tả thực tế, mức này là không đủ.

Trong thực hành, dịch bộ lọc đi $(M-1)/2$ mẫu và chọn $h[n] = h[M-1-n]$ (đối xứng) sẽ cho pha tuyến tính (linear phase), nghĩa là trễ nhóm không đổi trên toàn dải. Đây là lý do FIR được ưu tiên trong các đường tín hiệu cần bảo toàn dạng sóng.

## Phương pháp cửa sổ (window method)

Ý tưởng: thay cửa sổ chữ nhật bằng một cửa sổ tắt dần ở hai đầu, để giảm năng lượng của búp phụ. Cái giá phải trả là búp chính rộng hơn, tức dải chuyển tiếp rộng hơn với cùng $M$.

| Cửa sổ | Độ rộng búp chính | Đỉnh búp phụ | Ước lượng $M$ | Suy hao chặn điển hình |
| --- | --- | --- | --- | --- |
| Chữ nhật (rectangular) | $4\pi/M$ | $-13$ dB | $1.8\pi/\Delta\omega$ | $\approx 21$ dB |
| Hann | $8\pi/M$ | $-31$ dB | $3.1\pi/\Delta\omega$ | $\approx 44$ dB |
| Hamming | $8\pi/M$ | $-41$ dB | $3.3\pi/\Delta\omega$ | $\approx 53$ dB |
| Blackman | $12\pi/M$ | $-57$ dB | $5.5\pi/\Delta\omega$ | $\approx 74$ dB |
| Kaiser | theo $\beta$ | theo $\beta$ | $(A-8)/(2.285\,\Delta\omega)$ | chọn trước bằng $A$ |

Cửa sổ Kaiser (Kaiser window) là lựa chọn mặc định của người làm thiết kế vì nó có tham số $\beta$ điều chỉnh liên tục được, cho phép khớp đồng thời cả $A_s$ và $\Delta\omega$. Công thức thực dụng:

$$
\beta = \begin{cases} 0.5842(A-21)^{0.4} + 0.07886(A-21), & 21 \le A \le 50 \\ 0.1102(A-8.7), & A > 50 \end{cases}
$$

với $\Delta\omega = \omega_s - \omega_p$ tính bằng rad/mẫu và $A$ tính bằng dB.

```mermaid
flowchart TD
    Spec["📋<br/>Đặc tả ωp, ωs, δp, δs"] --> Need{"Cần pha tuyến tính<br/>và bậc nhỏ nhất?"}
    Need -->|Có| PM["⚙️<br/>Parks-McClellan"]
    Need -->|Cần công thức đóng, dễ kiểm soát| Win["🪟<br/>Phương pháp cửa sổ"]
```

**Bài tập 1 (gắn với capstone).** Luồng tín hiệu của bạn lấy mẫu ở $f_s = 8$ kHz, cần giữ dải thông tới $1$ kHz, chặn từ $1.5$ kHz với suy hao $60$ dB. Hãy chọn cửa sổ Kaiser và ước lượng $M$.

**Xem lời giải**

$\Delta f = 500/8000 = 0.0625$ chu kỳ/mẫu, suy ra $\Delta\omega = 2\pi(0.0625) = 0.3927$ rad/mẫu.

$\beta = 0.1102(60 - 8.7) = 5.65$.

$M \approx (60-8)/(2.285 \times 0.3927) = 57.9$, làm tròn lên và chọn số lẻ để đối xứng loại I: $M = 59$. Tần số cắt đặt ở giữa dải chuyển tiếp, $1.25$ kHz, chuẩn hóa theo Nyquist thành $0.3125$, kiểm tra bằng `firwin(59, 0.3125, window=('kaiser', 5.65))`.

## Parks-McClellan: thiết kế đẳng gợn tối ưu

Parks-McClellan là thuật toán xấp xỉ Chebyshev có trọng số, dựa trên phương pháp trao đổi Remez (Remez exchange). Thay vì nhân với một cửa sổ cố định, nó tìm trực tiếp tập $h[n]$ sao cho sai số xấp xỉ lớn nhất có trọng số là nhỏ nhất (tiêu chuẩn minimax). Kết quả có dạng đẳng gợn (equiripple): sai số dao động đều với cùng biên độ trong dải thông và dải chặn, thay vì dồn về phía tần số cắt như phương pháp cửa sổ.

Bạn không chọn cửa sổ, bạn chọn trọng số. Trọng số $W$ phân bổ gợn giữa hai dải theo tỉ lệ: muốn dải chặn "sạch" gấp 10 lần dải thông thì đặt $W_{stop}/W_{pass} \approx \delta_p/\delta_s$. Với đặc tả thông thường ($\delta_p = 0.01$, $\delta_s = 0.001$), trọng số dải chặn lớn hơn 10 lần.

Ước lượng bậc (công thức Kaiser cho Parks-McClellan):

$$
N \approx \frac{-10\log_{10}(\delta_p \delta_s) - 13}{14.6\,\Delta f}
$$

với $\Delta f$ chuẩn hóa theo tần số lấy mẫu. **Parks-McClellan cho cùng đặc tả một bộ lọc ngắn hơn đáng kể, nhưng bạn mất công thức đóng và mất quyền kiểm soát hình dạng dải chuyển tiếp.**

**Bài tập 2.** Với cùng đặc tả ở bài tập 1, nhưng chuyển sang Parks-McClellan ($\delta_p = 0.01$, $\delta_s = 0.001$), hãy ước lượng số tap và so sánh.

**Xem lời giải**

$-10\log_{10}(10^{-5}) = 50$, nên $N \approx (50-13)/(14.6 \times 0.0625) = 40.5$, chọn $N = 41$ tap. So với $M = 59$ của phương pháp cửa sổ, tiết kiệm khoảng 30% tài nguyên. Trên FPGA, đó là 18 bộ nhân ít hơn trong cấu trúc song song, một khác biệt đáng kể. Lưu ý: kết quả phải được kiểm chứng lại bằng đáp ứng tần số thực tế, vì công thức chỉ là ước lượng.

## Những cạm bẫy khi chốt bậc và chọn cửa sổ

- Luôn ước lượng bậc **trước** khi chạy thiết kế. Thử sai bằng cách tăng dần $M$ là cách nhanh nhất để tiêu hết thời gian của một buổi lab.
- Đừng quên rằng mọi công thức ở trên dùng $\Delta\omega$ tính bằng rad/mẫu. Nhầm lẫn giữa Hz và tần số chuẩn hóa là lỗi phổ biến nhất trong các báo cáo luận văn tôi từng đọc.
- Cửa sổ Blackman cho suy hao rất tốt nhưng dải chuyển tiếp rất rộng với cùng $M$. Nếu đặc tả của bạn vừa hẹp vừa sâu, hãy dùng Kaiser hoặc Parks-McClellan, đừng cố ép Blackman.
- Bậc chẵn hay lẻ không tùy tiện: bộ lọc đối xứng độ dài lẻ (loại I) nhận được đáp ứng khác 0 tại Nyquist, độ dài chẵn (loại II) thì không. Nếu cần bộ lọc thông cao hoặc chắn dải, hãy kiểm tra ràng buộc này.
- Parks-McClellan có thể không hội tụ hoặc cho gợn không đều nếu đặc tả quá chặt so với bậc đặt vào. Hãy kiểm tra số điểm cực trị và luôn vẽ đáp ứng biên độ để xác nhận.
- Làm tròn hệ số ở bước lý thuyết sẽ làm đáp ứng lệch khỏi đường tham chiếu, nên hãy giữ hệ số ở dạng số thực cho tới khi chốt bậc và cửa sổ, rồi mới đánh giá ảnh hưởng của lượng tử hóa (quantization) sau khi đã có đáp ứng chuẩn để so sánh.

## Chốt lại thiết kế FIR trước khi chuyển sang IIR

Ba kết luận cần mang theo khi bước vào bài tiếp theo:

- Phương pháp cửa sổ (window method) trực quan, có công thức đóng để ước lượng bậc, nhưng luôn "trả giá" bằng dải chuyển tiếp rộng hoặc suy hao dải chắn hạn chế do hiện tượng Gibbs.
- Cửa sổ Kaiser và thuật toán Parks-McClellan là hai công cụ chính khi đặc tả chặt. Kaiser cho phép chỉnh liên tục độ đánh đổi giữa $\beta$ và $M$; Parks-McClellan cho bậc nhỏ nhất với gợn đều, đổi lại phải lặp và kiểm chứng kỹ.
- Bậc bộ lọc là quyết định kiến trúc, không chỉ là con số trong báo cáo. Mỗi tap tiết kiệm được là một bộ nhân, một thanh ghi và một đường cộng ít hơn trên FPGA.

Ôn nhanh các con số và công thức vừa dùng:

Độ rộng dải chuyển tiếp của bộ lọc FIR thiết kế bằng phương pháp cửa sổ tỉ lệ nghịch với _____.
Cửa sổ Hamming cho suy hao dải chắn xấp xỉ _____, còn cửa sổ Blackman cho khoảng _____.
Với cửa sổ, bậc được ước lượng theo $M \approx (A - 8)/(2.285\,\Delta\omega) + 1$, trong đó $A = {{c4::-20\log_{10}(\delta_s)}}$.
Với cửa sổ Kaiser và $A > 50$ dB, tham số hình dạng là $\beta = _____$.
Parks-McClellan là thuật toán _____ dựa trên xấp xỉ minimax, nên gợn sai số _____ trên toàn bộ các dải.

Bộ thẻ ghi nhớ để tự kiểm tra trước khi làm bài tập thiết kế:

Front: Hiện tượng Gibbs trong thiết kế FIR bằng cửa sổ là gì?
Back: Gợn dao động ở dải thông và dải chắn do cắt ngắn đáp ứng xung lý tưởng; biên độ gợn không giảm khi tăng M, chỉ có dải chuyển tiếp hẹp lại.

Front: Độ rộng dải chuyển tiếp xấp xỉ của cửa sổ chữ nhật?
Back: Khoảng 1.8π/M, tức 0.9 lần độ rộng búp chính 2π/M.

Front: Cửa sổ Hann cho dải chuyển tiếp và suy hao bao nhiêu?
Back: Xấp xỉ 6.2π/M và khoảng -44 dB.

Front: Cửa sổ Hamming cho dải chuyển tiếp và suy hao bao nhiêu?
Back: Xấp xỉ 6.6π/M và khoảng -53 dB.

Front: Cửa sổ Blackman cho dải chuyển tiếp và suy hao bao nhiêu?
Back: Xấp xỉ 11π/M và khoảng -74 dB.

Front: Công thức ước lượng bậc với cửa sổ?
Back: M ≈ (A - 8)/(2.285·Δω) + 1, với Δω tính bằng rad/mẫu và A = -20log10(δs).

Front: Cửa sổ Kaiser có mấy tham số tự do và chúng điều khiển gì?
Back: Hai tham số: M quyết định độ rộng dải chuyển tiếp, β quyết định mức suy hao dải chắn.

Front: Parks-McClellan dựa trên cơ sở toán học nào?
Back: Thuật toán trao đổi Remez cho xấp xỉ minimax có trọng số, dẫn tới gợn đều (equiripple).

Front: Ưu điểm chính của Parks-McClellan so với phương pháp cửa sổ?
Back: Đạt cùng đặc tả với bậc nhỏ nhất, vì sai số được phân bố đều thay vì dồn về biên dải.

Front: Nhược điểm của Parks-McClellan?
Back: Không có công thức đóng cho bậc, phải lặp; có thể không hội tụ nếu đặc tả quá chặt so với bậc đặt vào.

Front: Quan hệ giữa gợn dải chắn δs và suy hao A?
Back: A = -20log10(δs) dB, ví dụ δs = 0.001 tương ứng 60 dB.

Front: Khác biệt giữa bộ lọc FIR đối xứng loại I và loại II?
Back: Loại I có M lẻ, đáp ứng khác 0 tại Nyquist; loại II có M chẵn, đáp ứng bằng 0 tại Nyquist nên không dùng cho thông cao hay chắn dải.

Front: Vì sao phải ước lượng bậc trước khi chạy thiết kế?
Back: Để tránh lặp thử sai tốn thời gian; công thức chỉ là ước lượng nên vẫn phải kiểm chứng bằng đáp ứng biên độ thực tế.

Bài tiếp theo chuyển sang nhánh IIR: biến đổi song tuyến tính (bilinear transform), nơi cùng một đặc tả sẽ được ánh xạ từ bộ lọc tương tự sang bộ lọc số, kèm theo vấn đề méo tần số (frequency warping) mà bạn sẽ phải bù trước khi tính toán.

---

## Contents

Part of [🎛️ Thiết kế DSP trên FPGA: triển khai bộ lọc thời gian thực](https://everwise.study/courses/thiet-ke-dsp-tren-fpga-trien-khai-bo-loc-thoi-gian-thuc.md)

- **📐 Thiết kế bộ lọc số từ đặc tả**
  - [🧭 Đặc tả thiết kế và ôn nhanh nền tảng DSP](https://everwise.study/courses/thiet-ke-dsp-tren-fpga-trien-khai-bo-loc-thoi-gian-thuc/dsp-spec-and-foundations-review.md)
  - [🪟 Thiết kế bộ lọc FIR: cửa sổ (window) và Parks-McClellan](https://everwise.study/courses/thiet-ke-dsp-tren-fpga-trien-khai-bo-loc-thoi-gian-thuc/fir-filter-design-window-parks-mcclellan.md) (sign-in required) — this lesson
  - [🌀 Thiết kế bộ lọc IIR: biến đổi song tuyến tính (bilinear transform)](https://everwise.study/courses/thiet-ke-dsp-tren-fpga-trien-khai-bo-loc-thoi-gian-thuc/iir-filter-design-bilinear-transform.md)
  - [✅ Checkpoint: thiết kế bộ lọc số](https://everwise.study/courses/thiet-ke-dsp-tren-fpga-trien-khai-bo-loc-thoi-gian-thuc/checkpoint-filter-design.md)
- **⚙️ Mô phỏng và triển khai nhúng thời gian thực trên FPGA**
  - [🧪 Mô phỏng, kiểm thử với scipy.signal và lượng tử hóa fixed-point](https://everwise.study/courses/thiet-ke-dsp-tren-fpga-trien-khai-bo-loc-thoi-gian-thuc/simulation-and-fixed-point-quantization.md)
  - [🧱 Kiến trúc phần cứng: pipeline và song song tài nguyên](https://everwise.study/courses/thiet-ke-dsp-tren-fpga-trien-khai-bo-loc-thoi-gian-thuc/fpga-pipeline-and-resource-parallelism.md)
  - [🛠️ Capstone: bộ lọc thời gian thực trên FPGA bằng Verilog](https://everwise.study/courses/thiet-ke-dsp-tren-fpga-trien-khai-bo-loc-thoi-gian-thuc/capstone-realtime-filter-on-fpga.md) (premium content)
  - [✅ Checkpoint: triển khai nhúng trên FPGA](https://everwise.study/courses/thiet-ke-dsp-tren-fpga-trien-khai-bo-loc-thoi-gian-thuc/checkpoint-fpga-implementation.md) (premium content)
- [Course cheatsheet](https://everwise.study/courses/thiet-ke-dsp-tren-fpga-trien-khai-bo-loc-thoi-gian-thuc/cheatsheet.md) (premium content)
