Tài liệu Đề tài Thực hiện bộ lọc FIR thích nghi dùng thuật toán LMS: ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
1
MỤC LỤC
BẢNG KÝ HIỆU VIẾT TẮT ............................................................................................................................... 2
LỜI MỞ ĐẦU ........................................................................................................................................................ 4
CHƯƠNG 1............................................................................................................................................................ 5
TỔNG QUAN VỀ FPGA VÀ NGÔN NGỮ VHDL............................................................................................ 5
1.1. TỔNG QUAN VỀ FPGA............................................................................................................................. 5
1.1.1. Lịch sử ra đời của FPGA.....................................................................................................................
65 trang |
Chia sẻ: hunglv | Lượt xem: 1515 | Lượt tải: 0
Bạn đang xem trước 20 trang mẫu tài liệu Đề tài Thực hiện bộ lọc FIR thích nghi dùng thuật toán LMS, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
1
MỤC LỤC
BẢNG KÝ HIỆU VIẾT TẮT ............................................................................................................................... 2
LỜI MỞ ĐẦU ........................................................................................................................................................ 4
CHƯƠNG 1............................................................................................................................................................ 5
TỔNG QUAN VỀ FPGA VÀ NGÔN NGỮ VHDL............................................................................................ 5
1.1. TỔNG QUAN VỀ FPGA............................................................................................................................. 5
1.1.1. Lịch sử ra đời của FPGA.................................................................................................................... 5
1.1.2. Khái niệm cơ bản và cấu trúc của FPGA .......................................................................................... 6
1.1.3. Các ứng dụng của FPGA ................................................................................................................... 8
1.2. TỔNG QUAN VỀ NGÔN NGỮ VHDL ...................................................................................................... 8
1.2.1. Giới thiệu về ngôn ngữ mô tả phần cứng VHDL .............................................................................. 8
1.2.2. Cấu trúc một mô hình hệ thống mô tả bằng ngôn ngữ VHDL ....................................................... 10
CHƯƠNG 2.......................................................................................................................................................... 12
BỘ LỌC FIR........................................................................................................................................................ 12
2.1. BỘ LỌC FIR TRUYỀN THỐNG .............................................................................................................. 12
2.2. BỘ LỌC FIR SỬ DỤNG KIẾN TRÚC SYSTOLIC ARRAY.................................................................... 13
2.2.1. Tổng quan về systolic array .............................................................................................................. 13
2.2.2. Bộ lọc FIR thực hiện theo kiến trúc systolic array một chiều......................................................... 14
CHƯƠNG 3.......................................................................................................................................................... 16
BỘ LỌC FIR THÍCH NGHI DÙNG THUẬT TOÁN LMS............................................................................ 16
3.1. ĐẶT VẤN ĐỀ............................................................................................................................................ 16
3.2. CẤU TRÚC CỦA MẠCH LỌC THÍCH NGHI ......................................................................................... 18
3.3. MẠCH LỌC WIENER FIR ....................................................................................................................... 19
3.4. CÁC THUẬT TOÁN THÍCH NGHI VÀ ỨNG DỤNG............................................................................. 22
3.4.1. Phương pháp giảm bước nhanh nhất .............................................................................................. 22
3.4.2. Thuật toán toàn phương trung bình tối thiểu (LMS) ...................................................................... 25
CHƯƠNG 4.......................................................................................................................................................... 29
HỆ THỐNG SỐ BÙ HAI VÀ CÁC PHÉP TOÁN............................................................................................ 29
4.1. BIỂU DIỄN SỐ ÂM TRONG HỆ THỐNG SỐ BÙ HAI ........................................................................... 29
4.2. THỰC HIỆN CÁC PHÉP TÍNH TRONG HỆ THỐNG SỐ BÙ HAI ......................................................... 30
4.2.1. Thực hiện phép cộng trong hệ thống số bù hai ............................................................................... 30
4.2.2. Thực hiện phép trừ trong hệ thống số bù hai .................................................................................. 31
4.2.3. Hiện tượng tràn số ............................................................................................................................ 32
4.2.4. Thực hiện phép nhân trong số bù hai .............................................................................................. 33
CHƯƠNG 5.......................................................................................................................................................... 35
THỰC NGHIỆM ................................................................................................................................................. 35
5.1. MÔ TẢ PHẦN CỨNG CỦA KIT VIRTEX-II PRO................................................................................... 35
5.2. KẾT QUẢ THU ĐƯỢC VỚI BỘ LỌC FIR TRUYỀN THỐNG................................................................ 36
5.3. KẾT QUẢ THU ĐƯỢC VỚI BỘ LỌC FIR THEO KIẾN TRÚC SYSTOLIC .......................................... 38
5.4. KẾT QUẢ THU ĐƯỢC VỚI BỘ LỌC FIR THÍCH NGHI ....................................................................... 38
KẾT LUẬN .......................................................................................................................................................... 41
TÀI LIỆU THAM KHẢO................................................................................................................................... 42
PHỤ LỤC ............................................................................................................................................................. 43
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
2
BẢNG KÝ HIỆU VIẾT TẮT
Ký Hiệu Diễn Giải
ASIC Application Specific Integrated Circuit
ADC Analog to Digital Converter
ALU Arithmetic Logic Unit
ASM Auto Senquencing Memory
CPLD Complex Programmable Logic Device
CPU Central Processing Unit
DSP Digital Signal Processing
DAC Digital to Analog Converter
DPU Data Processing Unit
FIR Finite Impulse Response
FPGA Field Programmable Gate Array
HDL Hardware Description Language
IC Integrated Circuit
IEEE Institute of Electrical and Electronics Engineers
JTAG Joint Test Action Group
LED Light Emitting Diode
LUT Look Up Table
LMS Least Mean Square
PAL Programmable Array Logic
PLA Programmable Logic Array
PCI Peripheral Component Interconnect
PE Process Element
RAM Random Access Memory
ROM Read Only Memory
RS232 Recommended Standard 232
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
3
SoC System on chip
SRAM Static Random Access Memory
SPLD Simple Programable Logic Device
USB Universal Serial Bus
VHDL
Very High Speed Itergrated Circuit
Hardware Description Language
VHSIC Very High Speed Itergrated Circuit
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
4
LỜI MỞ ĐẦU
Ngày nay, xử lý tín hiệu và lọc số là một ngành phát triển hết sức mạnh mẽ, các
công nghệ, thuật toán ngày càng được đổi mới và tối ưu hoá nhằm nâng cao tính hiệu
quả của nó. Tuy nhiên, công nghệ phát triển càng cao thì đòi hỏi phần cứng phải đủ
nhanh để xử lý. Các mạch lọc tương tự trước đây không còn đủ khả năng để đáp ứng
yêu cầu đó nữa. Vì vậy, FPGA đã ra đời như một giải pháp cung cấp môi trường làm
việc hiệu quả cho các ứng dụng thực tế. Tính linh động cao trong quá trình thiết kế cho
phép FPGA giải quyết những bài toán phức tạp mà trước kia chỉ thực hiện nhờ phần
mềm máy tính. Ngoài ra, nhờ mật độ cổng logic cao, FPGA được ứng dụng cho những
bài toán đòi hỏi khối lượng tính toán lớn và dùng trong các hệ thống làm việc theo thời
gian thực. Những ứng dụng trong thực tế của FPGA rất rộng rãi, bao gồm: các hệ
thống hàng không, vũ trụ, quốc phòng, tiền thiết kế mẫu ASIC(ASIC prototyping), các
hệ thống điều khiển trực quan, phân tích nhận dạng ảnh, nhận dạng tiếng nói, mật mã
học, mô hình phần cứng máy tính...Đặc biệt, với khả năng tái lập trình, người sử dụng
có thể thay đổi lại thiết kế của mình chỉ trong vài giờ.
Chính vì tính thiết thực mà FPGA đã mang lại, em quyết định chọn FPGA làm
hướng nghiên cứu của mình. Trong bài khoá luận này, em xin trình bày một ứng dụng
cụ thể của FPGA trong xử lý tín hiệu số đó là “Thực hiện bộ lọc FIR thích nghi
dùng thuật toán LMS”. Đề tài được thực hiện tại phòng thí nghiệm mục tiêu “Các hệ
tích hợp thông minh ( SIS LAB)” trực thuộc trường Đại học Công nghệ - ĐHQG HN.
Em xin chân thành cảm ơn các thầy cô giáo đặc biệt là PGS.TS Trần Quang Vinh
và Th.S Nguyễn Kiêm Hùng đã tận tình hướng dẫn và giúp đỡ em để hoàn thành bản
luận văn này một cách tốt đẹp.
Do thời gian và kiến thức có hạn nên công trình này không thể tránh khỏi sai sót,
vì vậy em rất mong nhận được các ý kiến đóng góp của các thầy cô và các bạn.
Em xin chân thành cảm ơn !
Hà Nội, Ngày 27 Tháng 3 Năm 2008
Nguyễn Anh Cường
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
5
Chương 1
TỔNG QUAN VỀ FPGA VÀ NGÔN NGỮ VHDL
1.1. TỔNG QUAN VỀ FPGA
1.1.1. Lịch sử ra đời của FPGA
FPGA được thiết kế đầu tiên bởi Ross Freeman, người sáng lập công ty Xilinx
vào năm 1984, kiến trúc mới của FPGA cho phép tích hợp số lượng tương đối lớn các
phần tử bán dẫn vào 1 vi mạch so với kiến trúc trước đó là CPLD. FPGA có khả năng
chứa tới từ 100.000 đến hàng vài tỷ cổng logic, trong khi CPLD chỉ chứa từ 10.000
đến 100.000 cổng logic; con số này đối với PAL, PLA còn thấp hơn nữa chỉ đạt vài
nghìn đến 10.000.
CPLD được cấu trúc từ số lượng nhất định các khối SPLD (Simple programable
logic device) thuật ngữ chung chỉ PAL, PLA. SPLD thường là một mảng logic
AND/OR lập trình được có kích thước xác định và chứa một số lượng hạn chế các
phần tử nhớ đồng bộ (clocked register). Cấu trúc này hạn chế khả năng thực hiện
những hàm phức tạp và thông thường hiệu suất làm việc của vi mạch phụ thuộc vào
cấu trúc cụ thể của vi mạch hơn là vào yêu cầu bài toán.
Kiến trúc của FPGA là kiến trúc mảng các khối logic, mỗi khối này nhỏ hơn
nhiều nếu đem so sánh với một khối SPLD, ưu điểm này giúp FPGA có thể chứa nhiều
hơn các phần tử logic và phát huy tối đa khả năng lập trình của các phần tử logic và hệ
thống mạch kết nối, để đạt được mục đích này thì kiến trúc của FPGA phức tạp hơn
nhiều so với CPLD.
Một điểm khác biệt nữa với CPLD là trong những FPGA hiện đại được tích hợp
nhiều bộ logic số học đã được tối ưu hóa, hỗ trợ RAM, ROM, tốc độ cao, hay các bộ
nhân, cộng dùng cho những ứng dụng xử lý tín hiệu số.
Ngoài khả năng cấu trúc lại vi mạch ở mức toàn cục, một số FPGA hiện đại còn
hỗ trợ cấu trúc lại ở mức cục bộ, tức là khả năng cấu trúc lại một bộ phận riêng lẻ
trong khi vẫn đảm bảo hoạt động bình thường cho các bộ phận khác
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
6
1.1.2. Khái niệm cơ bản và cấu trúc của FPGA
FPGA (Field-programmable gate array) là vi mạch dùng cấu trúc mảng phần tử
logic mà người dùng có thể lập trình được. Chữ field ở đây muốn chỉ đến khả năng tái
lập trình “bên ngoài” tuỳ theo mục đích ứng dụng của người sử dụng, không phụ thuộc
vào dây chuyền sản xuất phức tạp của nhà máy bán dẫn. Kiến trúc tổng quan về FPGA
được mô tả như hình 1:
Hình 1: Kiến trúc tổng quan của FPGA
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
7
Vi mạch FPGA được cấu thành từ các bộ phận:
• Các khối logic cơ bản lập trình được (logic block)
Phần tử chính của FPGA là các khối logic (logic block). Khối logic được cấu
thành từ LUT và một phần tử nhớ đồng bộ flip-flop. LUT (Look up table) là
khối logic có thể thực hiện bất kì hàm logic nào từ 4 đầu vào, kết quả của hàm
này tùy vào mục đích mà gửi ra ngoài khối logic trực tiếp hay thông qua phần
tử nhớ flip-flop.
Khối logic được mô tả như hình 2:
Hình 2: Khối logic lập trình được của FPGA
Trong tài liệu hướng dẫn của các dòng FPGA của Xilinx còn sử dụng khái niệm
SLICE, 1 Slice gồm 4 khối logic tạo thành, số lượng các Slices thay đổi từ vài
nghìn đến vài chục nghìn tùy theo loại FPGA.
• Hệ thống mạch liên kết lập trình được
Mạng liên kết trong FPGA được cấu thành từ các đường kết nối theo hai
phương ngang và đứng, tùy theo từng loại FPGA mà các đường kết nối được
chia thành các nhóm khác nhau, ví dụ trong XC4000 của Xilinx có 3 loại kết
nối: ngắn, dài và rất dài. Các đường kết nối được nối với nhau thông qua các
khối chuyển mạch lập trình được (programable switch), trong một khối chuyển
mạch chứa một số lượng nút chuyển lập trình được, đảm bảo cho các dạng liên
kết phức tạp khác nhau.
• Khối vào/ra (IO Pads)
Khối vào/ra nhiều hay ít là tuỳ thuộc vào từng loại FPGA. Chúng có thể được
kết nối với các thiết bị bên ngoài như LED, USB, RS232, RAM....tuỳ theo mục
đích sử dụng
• Các phần tử tích hợp sẵn
Ngoài các khối logic, tùy theo các loại FPGA khác nhau mà có các phần tử tích
hợp thêm khác nhau, ví dụ để thiết kế những ứng dụng SoC, trong dòng Virtex
4, 5 của Xilinx có chứa nhân xử lý PowerPC, hay cho những ứng dụng xử lý tín
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
8
hiệu số trong FPGA được tích hợp các DSP Slice là bộ nhân, cộng tốc độ cao,
thực hiện hàm A*B+C, ví dụ dòng Virtex của Xilinx chứa từ vài chục đến hàng
trăm DSP slices với A, B, C 18-bit.
1.1.3. Các ứng dụng của FPGA
Ứng dụng của FPGA bao gồm: xử lý tín hiệu số, các hệ thống hàng không, vũ trụ,
quốc phòng, tiền thiết kế mẫu ASIC(ASIC prototyping), các hệ thống điều khiển trực
quan, phân tích nhận dạng ảnh, nhận dạng tiếng nói, mật mã học, mô hình phần cứng
máy tính...
Do tính linh động cao trong quá trình thiết kế cho phép FPGA giải quyết lớp
những bài toán phức tạp mà trước kia chỉ thực hiện nhờ phần mềm máy tính, ngoài ra
nhờ mật độ cổng logic lớn FPGA được ứng dụng cho những bài toán đòi hỏi khối
lượng tính toán lớn và dùng trong các hệ thống làm việc theo thời gian thực.
1.2. TỔNG QUAN VỀ NGÔN NGỮ VHDL
Thiết kế hay lập trình cho FPGA được thực hiện chủ yếu bằng các ngôn ngữ mô
tả phần cứng HDL như VHDL, Verilog ...các hãng sản xuất FPGA lớn như Xilinx,
Altera thường cung cấp các gói phần mềm và thiết bị phụ trợ cho quá trình thiết kế,
cũng có một số các hãng thứ ba cung cấp các gói phần mềm kiểu này như Synopsys,
Synplify... Các gói phần mềm này có khả năng thực hiện tất cả các bước của toàn bộ
quy trình thiết kế IC chuẩn với đầu vào là mã thiết kế trên HDL (còn gọi là mã RTL).
Trong bài Luận văn này, có sử dụng ngôn ngữ mô tả phần cứng VHDL, do đó ta
chỉ tập chung tìm hiểu về ngôn ngữ VHDL.
1.2.1. Giới thiệu về ngôn ngữ mô tả phần cứng VHDL
VHDL là ngôn ngữ mô tả phần cứng cho các mạch tích hợp tốc độ rất cao, là một
loại ngôn ngữ mô tả phần cứng được phát triển dùng cho trương trình VHSIC( Very
High Speed Itergrated Circuit) của bộ quốc phòng Mỹ. Mục tiêu của việc phát triển
VHDL là có được một ngôn ngữ mô phỏng phần cứng tiêu chuẩn và thống nhất cho
phép thử nghiệm các hệ thống số nhanh hơn cũng như cho phép dễ dàng đưa các hệ
thống đó vào ứng dụng trong thực tế. Ngôn ngữ VHDL được ba công ty Intermetics,
IBM và Texas Instruments bắt đầu nghiên cứu phát triển vào tháng 7 năm 1983. Phiên
bản đầu tiên được công bố vào tháng 8-1985. Sau đó VHDL được đề xuất để tổ chức
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
9
IEEE xem xét thành một tiêu chuẩn chung. Năm 1987 đã đưa ra tiêu chuẩn về
VHDL( tiêu chuẩn IEEE-1076-1987).
VHDL được phát triển để giải quyết các khó khăn trong việc phát triển, thay đổi
và lập tài liệu cho các hệ thống số. Như ta đã biết, một hệ thống số có rất nhiều tài liệu
mô tả. Để có thể vận hành bảo trì sửa chữa một hệ thống ta cần tìm hiểu kỹ lưỡng tài
liệu đó. Với một ngôn ngữ mô phỏng phần cứng tốt việc xem xét các tài liệu mô tả trở
nên dễ dàng hơn vì bộ tài liệu đó có thể được thực thi để mô phỏng hoạt động của hệ
thống. Như thế ta có thể xem xét toàn bộ các phần tử của hệ thống hoạt động trong
một mô hình thống nhất.
VHDL được phát triển như một ngôn ngữ độc lập không gắn với bất kỳ một
phương pháp thiết kế, một bộ mô tả hay công nghệ phần cứng nào. Người thiết kế có
thể tự do lựa chọn công nghệ, phương pháp thiết kế trong khi chỉ sử dụng một ngôn
ngữ duy nhất. Và khi đem so sánh với các ngôn ngữ mô phỏng phần cứng khác đã kể
ra ở trên ta thấy VHDL có một số ưu điểm hơn hẳn các ngôn ngữ khác:
- Thứ nhất là tính công cộng: VHDL được phát triển dưới sự bảo trợ của chính
phủ Mỹ và hiện nay là một tiêu chuẩn của IEEE. VHDL được sự hỗ trợ của
nhiều nhà sản xuất thiết bị cũng như nhiều nhà cung cấp công cụ thiết kế mô
phỏng hệ thống.
- Thứ hai là khả năng hỗ trợ nhiều công nghệ và phương pháp thiết kế. VHDL
cho phép thiết kế bằng nhiều phương pháp, ví dụ phương pháp thiết kế từ trên
xuống, hay từ dưới lên dựa vào các thư viện sẵn có. VHDL cũng hỗ trợ cho
nhiều loại công cụ xây dựng mạch như sử dụng công nghệ đồng bộ hay không
đồng bộ, sử dụng ma trận lập trình được hay sử dụng mảng ngẫu nhiên.
- Thứ ba là tính độc lập với công nghệ: VHDL hoàn toàn độc lập với công nghệ
chế tạo phần cứng. Một mô tả hệ thống dùng VHDL thiết kế ở mức cổng có thể
được chuyển thành các bản tổng hợp mạch khác nhau tuỳ thuộc công nghệ chế
tạo phần cứng mới ra đời nó có thể được áp dụng ngay cho các hệ thống đã thiết
kế .
- Thứ tư là khả năng mô tả mở rộng: VHDL cho phép mô tả hoạt động của phần
cứng từ mức hệ thống số cho đến mức cổng. VHDL có khả năng mô tả hoạt
động của hệ thống trên nhiều mức nhưng chỉ sử dụng một cú pháp chặt chẽ
thống nhất cho mọi mức. Như thế ta có thể mô phỏng một bản thiết kế bao gồm
cả các hệ con được mô tả chi tiết.
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
10
- Thứ năm là khả năng trao đổi kết quả: Vì VHDL là một tiêu chuẩn được chấp
nhận, nên một mô hình VHDL có thể chạy trên mọi bộ mô tả đáp ứng được tiêu
chuẩn VHDL. Các kết quả mô tả hệ thống có thể được trao đổi giữa các nhà
thiết kế sử dụng công cụ thiết kế khác nhau nhưng cùng tuân theo tiêu chuẩn
VHDL. Cũng như một nhóm thiết kế có thể trao đổi mô tả mức cao của các hệ
thống con trong một hệ thống lớn (trong đó các hệ con đó được thiết kế độc lập).
- Thứ sáu là khả năng hỗ trợ thiết kế mức lớn và khả năng sử dụng lại các thiết
kế: VHDL được phát triển như một ngôn ngữ lập trình bậc cao, vì vậy nó có thể
được sử dụng để thiết kế một hệ thống lớn với sự tham gia của một nhóm nhiều
người. Bên trong ngôn ngữ VHDL có nhiều tính năng hỗ trợ việc quản lý, thử
nghiệm và chia sẻ thiết kế. Và nó cũng cho phép dùng lại các phần đã có sẵn.
1.2.2. Cấu trúc một mô hình hệ thống mô tả bằng ngôn ngữ VHDL
Mục đích của phần này sẽ nhằm giới thiệu sơ qua về cấu trúc khung cơ bản của
VHDL khi mô tả cho một mô hình thiết kế thực.
Thông thường một mô hình VHDL bao gồm ba phần: thực thể, kiến trúc và các
cấu hình. Đôi khi ta xử dụng các gói (packages) và mô hình kiểm tra hoạt động của hệ
thống (testbench).
+ Thực thể (entity): Khai báo thực thể trong VHDL là phần định nghĩa các chỉ
tiêu phía ngoài của một phần tử hay một hệ thống. Thực chất của việc khai báo thực
thể chính là khai báo giao diện của hệ thống với bên ngoài. Ta có thể có tất cả các
thông tin để kết nối mạch vào mạch khác hoạc thiết kế tác nhân đầu vào phục vụ cho
mục đích thử nghiệm. Tuy nhiên hoạt động thật sự của mạch không nằm ở phần khai
báo này
+ Kiến trúc (Architecture): Phần thứ 2 trong mô hình VHDL là khai báo kiến
trúc. Mỗi một khai báo thực thể đều phải đi kèm với ít nhất một kiến trúc tương ứng.
VHDL cho phép tạo ra hơn một kiến trúc cho một thực thể. Phần khai báo kiến trúc có
thể bao gồm các khai báo về các tín hiệu bên trong, các phần tử bên trong hệ thống,
hay các hàm và thủ tục mô tả hoạt động của hệ thống. Tên của kiến trúc là nhãn được
đặt tuỳ theo người sử dụng. Có hai cách mô tả kiến trúc của một phần tử ( hoặc hệ
thống) đó là mô hình hoạt động (Behaviour) hay mô tả theo mô hình cấu trúc
(Structure). Tuy nhiên một hệ thống có thể bao gồm cả mô tả theo mô hình hoạt động
và mô tả theo mô hình cấu trúc.
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
11
+ Mô tả kiến trúc theo mô hình hoạt động: Mô hình hoạt động mô tả các hoạt
động của hệ thống ( hệ thống đáp ứng với các tín hiệu vào như thế nào và đưa ra kết
quả gì ra đầu ra) dưới dạng các cấu trúc ngôn ngữ lập trình bậc cao. Cấu trúc đó có thể
là PROCESS, WAIT, IF, CASE, FOR-LOOP…
+ Mô tả kiến trúc theo mô hình cấu trúc: Mô hình cấu trúc của một phần tử
(hoặc hệ thống) có thể bao gồm nhiều cấp cấu trúc bắt đầu từ một cổng logic đơn giản
đến xây dựng mô tả cho một hệ thống hoàn thiện. Thực chất của việc mô tả theo mô
hình cấu trúc là mô tả các phần tử con bên trong hệ thống và sự kết nối của các phần tử
con đó. Như với ví dụ mô tả mô hình cấu trúc một flip-flop RS gồm hai cổng NAND
có thể mô tả cổng NAND được định nghĩa tương tự như ví dụ với cổng NOT, sau đó
mô tả sơ đồ móc nối các phần tử NAND tạo thành trigơ RS
+ Cấu trúc Process: Process là khối cơ bản của việc mô tả theo hoạt động.
Process được xét đến như là một chuỗi các hành động đơn trong suốt quá trình dịch.
Cấu trúc tổng quát:
+ Môi trường kiểm tra (testbench): Một trong các nhiệm vụ rất quan trọng là
kiểm tra bản mô tả thiết kế. Kiểm tra một mô hình VHDL được thực hiện bằng cách
quan sát hoạt động của nó trong khi mô phỏng và các giá trị thu được có thể đem so
sánh với yêu cầu thiết kế.
Môi trường kiểm tra có thể hiểu như một mạch kiểm tra ảo. Môi trường kiểm
tra sinh ra các tác động lên bản thiết kế và cho phép quan sát hoặc so sánh kết quả hoạt
động của bản mô tả thiết kế. Thông thường thì các bản mô tả đều cung cấp chương
trình thử. Nhưng ta cũng có thể tự xây dựng chương trình thử (testbench). Mạch thử
thực chất là sự kết hợp của tổng hợp nhiều thành phần. Nó gồm ba thành phần: mô
hình VHDL đã qua kiểm tra, nguồn dữ liệu và bộ quan sát. Hoạt động của mô hình
VHDL được kích thích bởi các nguồn dữ liệu và kiểm tra tính đúng đắn thông qua bộ
quan sát.
[tên nhãn]: process
[(danh sách các yếu tố kích thích hoạt động)]
[khai báo các biến]
begin
[các câu lệnh]
end process;
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
12
Chương 2
BỘ LỌC FIR
2.1. BỘ LỌC FIR TRUYỀN THỐNG
Bộ lọc FIR là bộ lọc có đáp ứng xung chiều dài hữu hạn, tức là đáp ứng xung chỉ
khác không trong một khoảng có chiều dài hữu hạn N (từ 0 đến N-1). Bộ lọc FIR với
bậc của bộ lọc là N được biểu diễn như hình 3:
Hình 3: Cấu trúc của bộ lọc FIR truyền thống
Trong đó:
x[n]: là tín hiệu lối vào của mạch
y[n]: là tín hiệu lối ra của mạch
h[n]: là đáp ứng xung của mạch
Lối ra y[n] và lối vào x[n] liên hệ với nhau bởi công thức:
y[n] = ∑
−
=
−
1
0
][][
N
k
knxkh
Để tính được các giá trị y[k] từ các mẫu lối vào x[k] thì các mẫu lần lượt qua các
bộ trễ, bộ nhân và bộ cộng. Với bộ lọc FIR có bậc là N thì phải sau N phép nhân và N-
1 phép cộng thì mới tính được giá trị của lối ra.
Như vậy, bộ lọc FIR có cấu trúc như trên có nhược điểm là khả năng đáp ứng
chậm, các mẫu lối ra không được liên tục mà sau một khoảng thời gian tính toán xong
các phép nhân và phép cộng mới được xuất ra.
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
13
Để khắc phục nhược điểm đó, ta sử dụng kiến trúc systolic array để nâng cao khả
năng đáp ứng của mạch
2.2. BỘ LỌC FIR SỬ DỤNG KIẾN TRÚC SYSTOLIC ARRAY
2.2.1. Tổng quan về systolic array
Systolic array là cấu trúc xử lý song song đặc biệt chứa các khối xử lý dữ liệu
(data processing unit gọi tắt là DPU), các khối xử lý này được sắp xếp thành một
mạng. DPU tương tự như CPU nhưng nó không có bộ đếm chương trình. Từng khối
DPU như là một trigger truyền thông bởi sự luân chuyển dữ liệu từ DPU này đến các
DPU lân cận. Thông thường, những dữ liệu khác nhau thì sẽ luân chuyển theo các
hướng khác nhau. Các luồng dữ liệu tới và rời khỏi các cổng DPU được phát từ ASM
(Auto senquencing memory là thành phần không thể thiếu của cấu trúc Non-Von-
Neumann. Trong cấu trúc này, cơ chế senquencing đóng vai trò là bộ đếm chương
trình). Mỗi ASM đóng vai trò là bộ đếm dữ liệu. Trong hệ thống này, luồng dữ liệu
vào có thể vào từ đầu ra của thiết bị ngoại vi và ngược lại.
Các bộ xử lý (DPU) tính toán dữ liệu, lưu trữ dữ liệu theo những cách độc lập với
nhau. Các bộ xử lý này có thể có một vài thanh ghi và khối ALU. Các DPU có khả
năng lưư trữ và xử lý dữ liệu độc lập với nhau. Mỗi DPU sau khi xử lý dữ liệu xong sẽ
chia sẻ dữ liệu cho các Cell lân cận.
Trong hình 4, mô tả kiến trúc Systolic array một chiều, dữ liệu chuyển động theo
một hướng
Hình 4: Cấu trúc systolic array một chiều
Hình 5 mô tả kiến trúc systolic array hai chiều, dữ liệu chuyển động hai hướng
theo chiều của mũi tên qua các bộ DPU. Dữ liệu ra cũng theo hai hướng
PE PE PE PE PE
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
14
Hình 5: Kiến trúc systolic array hai chiều
2.2.2. Bộ lọc FIR thực hiện theo kiến trúc systolic array một chiều
Để cho việc xử lý dữ liệu được nhanh hơn, bộ lọc FIR theo kiến trúc Systolic
array sẽ bao gồm một dãy các phần tử xử lý hay còn gọi là PE (Process Element).
Trong cùng một thời điểm, các PE sẽ thực hiện đồng thời các nhiệm vụ riêng, và do
đó, tín hiệu ở lối ra sẽ được đưa ra một cách liên tục mà không phải mất một khoảng
thời gian để tính toán do nó đã được tính từ trước đó.
Cấu trúc của một PE của bộ lọc FIR SYSTOLIC được trình bày như trong hình 6
Hình 6: Cấu trúc của một PE
Như vậy, cấu trúc của bộ lọc FIR Systolic với bậc bộ lọc là N, gồm N+1 PE
được trình bày như hình 7
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
15
Khác với bộ lọc FIR thông thường, đầu ra của bộ cộng lại được đưa qua 2 bộ
chốt để làm trễ, nó có tác dụng chia đường truyền tín hiệu của mạch thành những đoạn
nhỏ, do đó làm tăng tần số hoạt động của mạch, đồng thời làm cho tín hiệu xin và yin
vào bộ cộng cùng một lúc, do đó, tín hiệu ra sẽ được liên tục, đáp ứng nhanh, bởi việc
tính toán đã được thực hiện trước đó.
Với việc chia đường truyền dài nhất của mạch thành những đoạn nhỏ nhờ các
thanh ghi chốt, ta còn có thể tối ưu bộ lọc FIR systolic hơn nữa. Hình 8 mô tả cấu trúc
tối ưu của bộ lọc FIR systolic.
Mô hình này về ý tưởng vẫn giống mô hình trước, bao gồm các thanh ghi chốt,
bộ cộng, bộ nhân của mô hình trước, tuy nhiên, có sự thay đổi vị trí của các thanh ghi
chốt, trước bộ nhân và bộ cộng ta chèn thêm một thanh ghi chốt vào để chia nhỏ
đường truyền tín hiệu. Do đó, làm cho tần số hoạt động của mạch tăng lên.
x aN
+
…..
…..
x ao
+
xin
Yin
xout
Hình 8: Cấu trúc tối ưu của bộ lọc FIR systolic bậc N
yout
x aN
+
…..
…..
x ao
+
xin
Yin
xout
Hình 7: Cấu trúc bộ lọc FIR systolic bậc N
yout
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
16
Chương 3
BỘ LỌC FIR THÍCH NGHI DÙNG THUẬT TOÁN LMS
3.1. ĐẶT VẤN ĐỀ
Thuật ngữ lọc dùng để chỉ tất cả các hệ thống có khả năng khôi phục lại dạng của
các thành phần tần số của tín hiệu lối vào để tạo ra tín hiệu lối ra thỏa mãn các yêu cầu
mong muốn. Với bộ lọc FIR trình bày ở trên, thì hệ số của bộ lọc luôn không đổi. Do
đó, nếu có sự thay đổi đột ngột của một hoặc một vài yếu tố đầu vào(như tín hiệu
nhiễu chẳng hạn) thì bộ lọc sẽ không còn được tối ưu nữa. Hay nói cách khác, ta
không thu được tín hiệu mong muốn.
Để khắc phục nhược điểm trên, người ta đưa ra một bộ lọc FIR có cấu trúc mới,
mà trong đó, các hệ số của bộ lọc có thể thay đổi được để có thể thích ứng với sự thay
đổi bất ngờ của các yếu tố lối vào. Mạch lọc FIR có các hệ số thay đổi như vậy được
gọi là mạch lọc FIR thích nghi. Giản đồ khối của mạch lọc như vậy được trình bày
trong hình 9.
Trong sơ đồ này, tín hiệu lối vào là một dãy thời gian rời rạc x[n], mạch lọc được
đặc trưng bởi đáp ứng xung h[n], còn tín hiệu lối ra ở thời điểm n là một dãy y[n].
h[n]=h0,h1... +
Tín hiệu vào x[n]
__
Hình 9: Giản đồ khối của mạch lọc thích nghi
y[n]
Tín hiệu mong muốn
d(n)
Tín hiệu sai số
e[n]
+
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
17
Lối ra này được sử dụng để xác định một đáp ứng mong muốn d[n]. Các hệ số
của mạch lọc phải được chọn lựa sao cho dãy tín hiệu mong muốn có dạng phù hợp
nhất với tín hiệu lối vào. Điều này có thể được thực hiện nếu dãy tín hiệu sai số e[n]
hội tụ về không nhanh nhất. Để làm được điều này, ta phải tối ưu hoá một hàm sai số
được xác định theo phương pháp thống kê hoặc phương pháp quyết định. Đối với
phương pháp thống kê, thì hàm sai số được sử dụng là giá trị toàn phưong trung bình
của tín hiệu sai số e[n]. Nếu tín hiệu vào và tín hiệu mong muốn là những tín hiệu
dừng, thì việc cực tiểu hoá sai số toàn phương trung bình đưa đến một mạch lọc rất nổi
tiếng đó là mạch lọc Wiener, được gọi là tối ưu theo nghĩa toàn phương trung bình.
Hầu hết các thuật toán thích nghi là áp dụng cho các loại mạch lọc Wiener. Trong
phương pháp quyết định, cách chọn hàm sai số là một tổng trọng số của tín hiệu sai số
toàn phương. Việc cực tiểu hoá hàm này dẫn đến một mạch lọc tối ưu đối với dãy dữ
liệu đã cho.
Như vậy, mạch lọc được thiết kế hoặc bằng các công thức thống kê hoặc bằng
các công thức xác định. Trong các thiết kế xác định, cần phải tính toán một số đại
lượng trung bình khi sử dụng dãy dữ liệu đã cho mà mạch lọc cần xử lý. Nói cách khác,
để thiết kế được mạch lọc Wiener cần phải biết trước các tính chất thống kê của các tín
hiệu cơ sở. Trong trường hợp này, các dãy tín hiệu cơ sở thường được cho là tín hiệu
dừng và trung bình theo thời gian bằng trung bình thống kê.
Mặc dù phép đo trực tiếp các giá trị trung bình của tín hiệu có thể được thực hiện
để thu được những thông tin cần thiết cho việc thiết kế mạch lọc Wiener hoặc các
mạch lọc tối ưu, nhưng trong nhiều ứng dụng thực tế, các giá trị trung bình của tín hiệu
lại được sử dụng theo cách gián tiếp, trong đó sai số lối ra của mạch lọc tương quan
với các mẫu của tín hiệu vào của mạch lọc theo một số cách và sử dụng kết quả của
phương trình đệ quy để điều chỉnh các hệ số của mạch theo kiểu lặp.
Sử dụng phương pháp lặp có thể đưa đến các lời giải thích nghi có khả năng tự
hiệu chỉnh. Có nghĩa là nếu các tính chất thống kê của tín hiệu thay đổi đối với thời
gian, thì nhờ nghiệm lặp, các hệ số của mạch lọc có thể tự điều chỉnh để thích nghi
với các tính chất thống kê mới.
Nghiệm lặp, nói chung rất được ưa chuộng vì nó dễ mã hoá trong phần mềm và
dễ thực thi trong phần cứng hơn các nghiệm không lặp.
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
18
3.2. CẤU TRÚC CỦA MẠCH LỌC THÍCH NGHI
Cấu trúc thường được sử dụng trong mạch lọc thích nghi được mô tả như hình
10:
Hình 10: Cấu trúc của mạch lọc FIR thích nghi
Trong đó:
x[n] : Vector tín hiệu đầu vào của mạch lọc.
x[n] = [xn xn-1 xn-2… xn-N+1]T
w: Là vector trọng số của bộ lọc thích nghi
w = [w0 w1…wN-1]T
y[n] : là lối ra của mạch lọc
y[n] = ∑−
=
−
1
0
][][
N
k
knxkw wT x[n] (3.1)
d[n] : là lối ra mong muốn
e[n] : là sai số giữa tín hiệu mong muốn d[n] và tín hiệu đầu ra y[n]
e[n]=d[n]-y[n] (3.2)
z-1 z-1
x
z-1
+
x x
wo[n] w1[n]
wN-1[n]
x[n]
x[n-1]
+
e[n]
x
Thuật toán thích nghi
x[n-N+1]
y[n]
d[n]
+
-
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
19
Bài toán thích nghi sẽ tự điều chỉnh ma trận các trọng số w sao cho sai số e[n] là
nhỏ nhất.
3.3. MẠCH LỌC WIENER FIR
Vì wTx[n] là một vô hướng nên bằng chuyển vị của nó, tức là:wTx[n]=xT[n]w.
Do đó, từ (3.1) và (3.2) ta có:
e[n]=d[n]-y[n]=d[n]-wTx[n]=d[n]-xT[n]w (3.3)
Đối với mạch lọc Wiener, hàm hiệu năng được chọn là sai số toàn phương trung
bình:
J= E[|e[n]|2] (3.4)
Trong đó ký hiệu E[.] là kỳ vọng thống kê. Thay (3.3) vào (3.4) ta được:
J= E[(d[n]-wTx[n])(d[n]-xT[n]w)] (3.5)
Khai triển (3.5) và chú ý w có thể đưa ra ngoài toán tử E[.] vì nó không phải là
biến số thống kê, ta thu được:
J=E[d2[n]]–wTE[x[n]d[n]]– E[d[n]xT[n]]w + wTE[x[n]xT[n]]w (3.6)
Ta định nghĩa vector tương quan chéo bậc Nx1:
P = E[x[n]d[n]] = [P0 P1 … PN-1 ] T (3.7)
Và ma trận tương quan:
R00 R01 R02 …… R0 N-1
R10 R11 R12 …… R1 N-1
R=E[x[n]xT[n]] = .. .. .. …… …. (3.8)
.. .. .. …. ….
.. .. …. ..... …
RN-1 0 RN-1 1 RN-1 2 …… RN-1 N-1
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
20
Chú ý là: E[d[n]xT[n]] = PT; wTP = PTw, ta thu được:
J = E[d2[n]] – 2wTP + wTRw (3.9)
Để thu được táp trọng số ứng với hàm phí tổn J có giá trị cực tiểu, ta cần phải
giải hệ phương trình được tạo thành từ đạo hàm bậc nhất của J đối với mỗi táp trọng số
wi bằng không, tức là:
wi
J
∂
∂ = 0 , với i = 0,1,2…N-1 (3.10)
Các phương trình trên có thể viết dưới dạng ma trận:
∇J = 0 (3.11)
ở đây ∇ là toán tử vi phân được xác định như một vectơ cột:
∇ =
⎥⎥
⎥⎥
⎥⎥
⎥⎥
⎥⎥
⎥⎥
⎦
⎤
⎢⎢
⎢⎢
⎢⎢
⎢⎢
⎢⎢
⎢⎢
⎣
⎡
−∂
∂
∂
∂
∂
∂
]1[
.
.
.
]1[
]0[
Nw
w
w
(3.12)
Để tìm các đạo hàm riêng của J đối với các táp trọng số wi của mạch lọc, trước
hết phải khai triển hệ thức (3.9) thành dạng tường minh:
J = E[d2[n]] – 2∑−
=
1
0
][][
N
k
kwkP +∑∑−
=
−
=
1
0
1
0
],[][][
N
k
N
m
mkRmwkw (3.13)
Tổng kép trong (3.13) có thể khai triển dưới dạng:
∑∑−
=
−
=
1
0
1
0
],[][][
N
k
N
m
mkRmwkw = ∑∑−
=
−
−
1
#
0
1
#
0
],[][][
N
ik
k
N
im
m
mkRmwkw +wi ∑−
=
1
#
0
],[][
N
ik
k
ikRkw +wi ∑−
=
1
#
0
],[][
N
km
m
mkRmw
+wi2R[k,i] (3.14)
Thay (3.14) vao` (3.13), sau đó lấy đạo hàm riêng phần của J theo wi và thay
thế m cho k ta được:
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
21
][iw
J
∂
∂ = -2Pi + ∑−
=
+
1
0
],[],[]([
N
k
kiRikRkw ) , với i=0,1,2,…,N-1 (3.15)
Trong trường hợp này ta thấy:
Rki = E[x[n-k]x[n-i]] = Φxx[i-k] (3.16)
ở đây Φxx[i-k] là hàm tự tương quan của x[n]
Tương tự:
Rik = Φxx[k-i] (3.17)
Do tính chất đối xứng của hàm tự tương quan nên Φxx[k] =Φxx[-k], ta thu được:
Rki = Rik (3.18)
Thay (3.18) vào phương trình (3.15) ta được:
][iw
J
∂
∂ = -2Pi + 2 ∑−
=
1
0
][],[
N
k
kwkiR , với i = 0,1,2…,N-1 (3.19)
Phương trình trên có thể biểu diễn dưới dạng ma trận:
∇J = 2Rw – 2P (3.20)
Đặt ∇J=0 ta sẽ thu được phương trình tối ưu hoá táp trọng số của mạch lọc
Wiener
Rwo = P (3.21)
Đây là phương trình Wiener-Hopf đối với vetor trọng số tối ưu wo:
wo = R-1P (3.22)
Thay giá trị wo vừa tìm được từ phương trình Wiener-Hopf và Rwo=P vào
phương trình (3.9) ta sẽ tìm được giá trị cực tiểu của hàm phí tổn J:
Jmin = E[d2[n]] - woT P
= E[d2[n]] - woTRwo (3.23)
Đó là sai số cực tiểu mà mạch lọc Wiener FIR W(z) có thể đạt được khi táp trọng
số của nó là nghiệm của phương trình Wiener-Hopf, nghĩa là nghiệm tối ưu ở (3.22)
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
22
3.4. CÁC THUẬT TOÁN THÍCH NGHI VÀ ỨNG DỤNG
Trong phần này, chúng ta nghiên cứu chủ yếu thuật toán toàn phương trung bình
tối thiểu LMS. Thuật toán này được áp dụng rộng rãi trong xử lý số thích nghi và
thống kê do tính chất bền vững và đơn giản của nó. Nhờ thuật toán này mà dãy sai số
hội tụ về không với tốc độ nhanh, tuỳ theo bước giảm cấp. Vì vậy, dựa trên thuật toán
này, người ta đã phát triển nhiều thuật toán nhanh
3.4.1. Phương pháp giảm bước nhanh nhất
Đây là phương pháp lặp để tìm táp trọng số tương ứng với điểm cực tiểu của mặt
sai số của mạch lọc Wiener FIR. Trong phương pháp này, hàm phí tổn cần cực tiểu
hoá được giả thiết là phân kỳ và xuất phát từ một đểm bất kỳ trên mặt sai số, ta lấy một
bước nhỏ theo hướng mà trong đó hàm phí tổn giảm nhanh nhất. Tại điểm đó, hàm phí
tổn của mạch lọc Wiener sẽ có giá trị tối ưu.
Hình 11: Mạch lọc Wiener FIR
Đối với mạch lọc Wiener như hình, dãy tín hiệu vào mạch lọc là x[n] và dãy tín
hiệu mong muốn d[n] và táp trọng số wi được giả thiết là những dãy số thực. Khi đó,
dãy lối ra của mạch lọc:
z-1 z-1
x
z-1
+
x x
wo[n] w1[n]
wN-1[n]
x[n]
x[n-1]
+
e[n]
Thuật toán thích nghi
x
y[n] __
d[n]
+
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
23
y[n] = wTx[n] = w xT[n] (4.1)
Nhắc lại rằng khi hàm phí tổn đạt giá trị cực tiểu thì táp vector trọng số đạt đến
giá trị tối ưu, thoả mãn phương trình Wiener-Hopf:
Rwo=P (4.2)
Ở đây, thay cho việc giải phương trình một cách trực tiếp, ta giải bài toán bằng
cách tìm một phương pháp lặp.
Theo phương pháp này, xuất phát từ giá trị dự đoán trước đối với wo, gọi là w(0),
nhờ tính toán đệ quy thực hiện nhiều phép lặp để hội tụ tới wo. Thuật toán lặp này
thường xuyên được sử dụng trong các mạch lọc thích nghi.
Phương pháp giảm bước nhanh nhất được thực hiện theo các bước sau:
1. Xuất phát từ các thông số dự đoán ban đầu mà các giá trị tối ưu của nó
tìm được để cực tiểu hoá hàm phí tổn.
2. Tìm gradient của hàm phí tổn ứng với các thông số tại điểm xuất phát
3. Cập nhật các thông số bằng cách lấy một bước theo hướng ngược với
vector gradient thu được trong bước 2. Điều đó tương ứng với bước giảm
nhanh nhất trong hàm phí tổn. Ngoài ra, kích thước của bước được chọn tỉ
lệ với kích thước của vector gradient
4. Lặp lại các bước 2 và 3 cho đến khi không thể thay đổi được nữa trong
các thông số
Theo các thủ tục trên, nếu w(k) là vector táp trọng số tại phép lặp thứ k, thì
phương trình truy hồi sau đây có thể được sử dụng để cập nhật w(k):
w(k+1) = w(k) - µ∇kJ (4.3)
trong đó:
∇kJ = 2Rw(k)-2P (4.4)
Thông số µ là đại lượng vô hướng dương được gọi là kích thước của bước. Đây
là thông số rất quan trọng vì tốc độ hội tụ của w(k) tới giá trị tối ưu wo phụ thuộc vào
thông số này, tức là vào kích thước của bước đã lựa chọn. Nếu kích thước bước lớn có
thể sự hội tụ sẽ nhanh hơn, nhưng bù lại tính ổn định sẽ kém hơn
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
24
Thay (4.4) vào (4.3) ta được:
w(k+1) = w(k) - 2µ(Rw(k) – P) (4.5)
Để có thể thấy sự cập nhật các giá trị w(k) cho hội tụ tới wo, ta viết lại (4.5) :
w(k+1) - wo = (I-2µR)(w(k)-wo) (4.6)
Ta định nghĩa vector:
v(k) = w(k) - wo (4.7)
Khi đó (4.6) trở thành:
v(k+1) = (I-2µR)v(k) (4.8)
Phương trình (4.8) sẽ có dạng đơn giản hơn nữa nếu ta đưa ma trận tương quan R
về dạng chéo. Nghĩa là ta đặt:
R=QλQT (4.9)
Và thay ma trận đơn vị I=QQT, khi đó (4.8) trở thành:
v(k+1) = (QQT - 2µQλQT)v(k) = Q(I-2µλ)QTv(k) (4.10)
Trong đó λ là ma trận chéo được tạo thành từ các giá trị riêng của ma trận tương
quan R, còn Q là ma trận được tạo thành từ các vector riêng trực giao tương ứng
Đặt:
v’(k) = QTv(k) (4.11)
Như vậy ta thu được phương trình truy hồi đối với vector v’(k) như sau:
v’(k+1) =(I-2µλ)v’(k) (4.12)
phương trình vector (4.12) có thể tách thành các phương trình vô hướng :
v’i(k+1) = (1-2µλi) v’i(k) với i=0,1,…,N-1 (4.13)
ở đây, v’i(k) là phần tử thứ i của vector v’(k)
Nếu bắt đầu từ dãy giá trị ban đầu v’o(0), v’1(0),…,v’N-1(0) và sau k phép lặp
chúng ta sẽ thu được:
v’i(k) = (1-2µλi)v’i(0) với i=0,1,…,N-1 (4.14)
Từ (4.7) và (4.11) ta thấy rằng w(k) hội tụ tới wo khi và chỉ khi v’(k) hội tụ tới
vector không. Nhưng (4.14) lại cho thấy v’i(k) hội tụ tới không khi và chỉ khi thông số
bước µ được chọn sao cho:
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
25
|1-2µλi| < 1 , với i=0,1,…,N-1 (4.15)
Khi (4.15) thoả mãn thì thành phần thứ i của vector v’i(k) sẽ hội tụ nhanh về
không theo hàm e-mũ khi số lượng phép lặp tăng lên. Ngoài ra (4.15) cũng là điều kiện
để chọn kích thước của bước µ sao cho thuật toán giảm cấp nhanh nhất và ổn định.
Điều kiện đó có thể khai triển dưới dạng :
-1<1-2µλi<1 hay: 0 < µ < iλ
1 (4.16)
Do kích thước bước µ được áp dụng cho tất cả các giá trị của i, nên tính chất hội
tụ và ổn định của thuật toán giảm bước nhanh nhất được đảm bảo khi:
0 < µ <
max
1
λ (4.17)
Với λmax là giá trị riêng cực đại của các giá trị riêng: λ0,λ1,… λN-1
Bây giờ ta viết thuật toán giảm bước nhanh nhất cho vector táp trọng số w(k) của
mạch lọc. Ta thấy :
w(k) = wo + v(k) = wo + Qv’(k)
= wo+[qo q1…qN-1 ] [v’o(k) v’1(k) ….v’N-1(k)]T
= wo + ∑−
=
1
0
)](['][
N
i
kiviq (4.18)
ở đây qo,q1,…qN-1, là các vector riêng gắn với các giá trị riêng λo, λ1,… λN-1 của ma trận
tương quan R.
Thay (4.14) vào (4.18) ta thu được:
w(k) = wo+ ∑−
=
1
0
'
N
i
v i(0)(1-2µλi)k qi (4.19)
Kết quả này cho thấy mỗi giá trị riêng λi xác định một kiểu hội tụ riêng theo một
hướng được xác định bởi vector riêng tương ứng qi của nó. Các kiểu hội tụ khác nhau
hoạt động độc lập với nhau. Với một giá trị chọn lựa của thông số bước µ, thì thừa số
1-2µλi xác định giá trị λi để kiểu hội tụ thứ i hội tụ nhanh nhất.
3.4.2. Thuật toán toàn phương trung bình tối thiểu (LMS)
Thuật toán toàn phương trung bình tối thiểu LMS (Least – Mean –Square) là
thuật toán được áp dụng rộng rãi trong xử lý số tín hiệu thích nghi. Nó thuộc họ các
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
26
thuật toán gradient thống kê lần đầu tiên được Windrow-Hoff áp dụng năm 1960 và
sau đó phát triển thành nhiều thuật toán mới nhờ tính chất đơn giản và bền vững của
thuật toán này. Nó là thuật toán lọc thích nghi tuyến tính bao gồm hai quá trình: quá
trình lọc và thích nghi. Trong quá trình lọc, thuật toán này sử dụng mạch lọc ngang
tuyến tính có lối vào x(n) và lối ra y(n). Quá trình thích nghi được thực hiện nhờ sự
điều khiển tự động các táp trọng số của các hệ số của mạch lọc sao cho nó tương đồng
với tín hiệu sai số là hiệu của tín hiệu lối ra với tín hiệu mong muốn d(n). Sơ đồ của
thuật toán như trong hình.
Hình 12: Mạch lọc FIR thích nghi dùng thuật toán LMS
Giả sử mạch lọc ngang có N- táp trọng số và là dãy số thực, khi đó tín hiệu lối ra
được viết:
y[n] = ∑−
=
1
0
N
k
w k[n] x[n-k] (4.20)
Trong đó táp trọng số wo[n]…..,wN-1 [n] được chọn lựa như thế nào để sai số:
e[n]= d[n] - y[n] (4.21)
có giá trị cực tiểu. Nói chung trong mạch lọc thích nghi, táp trọng số là hàm của
chỉ số thời gian n, vì chúng được thích nghi liên tục với sự thay đổi thống kê của tín
hiệu. Thuật toán LMS điều chỉnh táp trọng số của mạch lọc sao cho sai số e[n] được
z-1 z-1
x
z-1
+
x x
wo[n] w1[n]
wN-1[n]
x[n]
x[n-1]
+
e[n]
x
y[n] __
Thuật toán LMS
+
d[n]
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
27
cực tiểu hoá theo nghĩa toàn phương trung bình, vì thế mới có tên là thuật toán toàn
phương trung bình tối thiểu. Khi các quá trình x[n] và d[n] là các quá trình ngẫu nhiên
dừng, thì thuật toán này hội tụ đến nghiệm của phương trình Wiener-Hopf. Nói cách
khác, thuật toán LMS là một sơ đồ thực tế để thực hiện các mạch lọc Wiener-Hopf,
nhưng không giải một cách tường minh phương trình Wiener-Hopf. Nó là một thuật
toán tuần tự được sử dụng để thích nghi táp trọng số của mạch lọc nhờ sự quan sát liên
tục tín hiệu lối vào x[n] và tín hiệu lối ra mong muốn d[n].
Như vậy, thuật toán LMS chính là sự thực thi thống kê của thuật toán giảm bước
nhanh nhất, trong đó hàm phí tổn J=E[e2[n]] được thay bằng giá trị xác định tức thời
j^[n] = e2[n]. Khi đó phương trình truy hồi để tính táp trọng số của mạch lọc được xác
định bằng phương trình:
w[n+1] = w[n] - µ∇e2[n] (4.22)
trong đó w[n] = [wo[n],w1[n],….,wN-1[n]]T, µ là thông số bước của thuật toán còn
∇ là toán tử vi phân được xác định bằng vector cột như sau:
∇ =
⎥⎥
⎥⎥
⎥⎥
⎥⎥
⎥⎥
⎥⎥
⎦
⎤
⎢⎢
⎢⎢
⎢⎢
⎢⎢
⎢⎢
⎢⎢
⎣
⎡
−∂
∂
∂
∂
∂
∂
]1[
.
.
.
]1[
]0[
Nw
w
w
(4.23)
Như vậy thành phần thứ k của vector ∇e2[n] là:
wi∂
∂ e2 [n] = 2e[n]
wi
ne
∂
∂ ][ (4.24)
Thay e[n]=d[n]-y[n] vào phương trình trên và do d[n] độc lập với wi, ta được:
wi∂
∂ e2 [n] = -2e[n]
wi
ny
∂
∂ ][ (4.25)
Bây giờ, thay y[n] từ (4.20) vào (4.25) ta được:
wi∂
∂ e2 [n] = - 2e[n]x[n-i] (4.26)
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
28
Hoặc dưới dạng tổng quát là:
∇e2[n] = -2e[n]x[n] (4.27)
Trong đó: x[n]=[ x[n], x[n-1]….x[n-N+1]]T
Thay kết quả từ (4.27) vào (4.22) ta được:
w[n+1] = w[n] + 2µe[n]x[n] (4.28)
Đây là phương trình truy hồi để xác định táp trọng số của mạch lọc đối với các
dãy lối vào và dãy sai số. Nó được gọi là thuật toán LMS đệ qui, thích nghi một cách
đệ quy các hệ số của mạch lọc cứ sau mỗi mẫu mới của tín hiêu lối vào x[n] và mẫu tín
hiệu mong muốn d[n]. Các phương trình (4.20), (4.21), (4.28), theo thứ tự là ba bước
để hoàn chỉnh mỗi một phép lặp của thuật toán LMS. Phương trình (4.20) là quá trình
lọc, nó được tạo thành để thu được tín hiệu lối ra của mạch lọc. Phương trình (4.21)
được sử dụng để tính sai số. Còn phương trình (4.28) dùng để thích nghi một cách đệ
quy táp trọng số của mạch lọc sao cho sai số xác định đạt giá trị cực tiểu. Trong
phương trình này, µ là thông số bước, nó điều khiển tốc độ hội tụ của thuật toán tới
nghiệm tối ưu. Nếu chọn µ lớn thì tốc độ hội tụ nhanh; còn nếu chọn µ giá trị bé thì tốc
độ hội tụ sẽ chậm hơn. Tuy nhiên, nếu µ quá lớn thì thuật toán sẽ không ổn định và do
vậy để đảm bảo tính chất ổn định của thuật toán LMS, µ phải được chọn sao cho:
0 < µ <
][3
1
Rtrace
(4.29)
trong đó: trace[R] = ∑−
=
1
0
][
N
k
kλ , Với N là bậc của bộ lọc
------------------------------
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
29
Chương 4
HỆ THỐNG SỐ BÙ HAI VÀ CÁC PHÉP TOÁN
4.1. BIỂU DIỄN SỐ ÂM TRONG HỆ THỐNG SỐ BÙ HAI
Trong hệ thống số bù hai, số dương vẫn được biểu diễn như các số không dấu
khác. Do vậy, ta chỉ tìm hiểu cách biểu diễn số âm trong hệ thống số bù 2.
Giả sử P là số dương, được biểu diễn bởi n bit trong số bù hai, khi đó:
-P = K = 2n – P.
Ví dụ: nếu ta sử dụng số 4 bit để biểu diễn thì +5 =0101 và -5 = 10000-
0101=1011 và -3=10000-0011=1101
Việc tìm số bù hai như cách trên thường ít được sử dụng, do sự phức tạp của nó
khi phải sử dụng các phép tính. Vì thế, ta đưa ra một phương pháp khác dễ dàng hơn:
Giả sử số B = bn-1 bn-2…b1 bo và K = kn-1 kn-2…k1 ko là số bù hai của B.
Khi đó, số K có thể được tạo ra từ B bằng cách : giữ nguyên các số bằng 0 từ
phải sang trái của B cho đến số đầu tiên bằng 1 của B;các số tiếp theo của B sẽ được
đảo ngược lại(1 thành 0 và 0 thành 1).
Ví dụ: B=0110, khi đó k0=b0 =0 và k1=b1=1, các số còn lại thu được B bằng việc
đảo các bit tương ứng : k2=0 và k3 = 1. Kết quả là: K=1010 là số bù hai của B=0110
Hình dưới biểu diễn số bù hai 4 bit
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
30
Hình 13:Số bù hai được biểu diễn bởi 4 bit
Các số được biểu diễn trong hệ thống số bù hai được biểu diễn bởi công thức:
B=(-bn-1 x 2n-1) + bn-2 x 2n-2 +….+ b1 x 21 + bo
Trong đó B = bn-1 bn-2…b1 bo là số n bit được biểu diễn trong hệ thống số bù hai.
4.2. THỰC HIỆN CÁC PHÉP TÍNH TRONG HỆ THỐNG SỐ BÙ HAI
4.2.1. Thực hiện phép cộng trong hệ thống số bù hai
Thực hiện phép cộng trong số bù hai hết sức đơn giản, như cộng số nhị phân
thông thường. Ta xét một vài ví dụ về việc thực hiện phép cộng với các số bù hai 4 bit:
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
31
Lưu ý: với phép cộng:(+5)+(-2)=(+3) và (-5)+(-2)=(-7) thì trong trường hợp này
ta có thể bỏ qua bit thứ 5
4.2.2. Thực hiện phép trừ trong hệ thống số bù hai
Để thực hiện phép trừ trong số bù hai, ta chỉ việc tìm số bù hai của số bị trừ rồi
thực hiện phép cộng với số trừ.Ta xét các ví dụ sau:
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
32
Lưu ý: với ví dụ (+5)-(+2) =(+3) và (-5)-(+2)=(-7) ta có thể bỏ qua bit thứ 5.
4.2.3. Hiện tượng tràn số
Nếu dùng n bit để biểu diễn số có dấu thì ta có thể biểu diễn các số trong khoảng
từ --2n-1 đến 2n-1 – 1. Nếu sau quá trình thực hiện phép toán(cộng, trừ, nhân) mà kết
quả thu được không nằm trong dải trên thì ta nói có hiện tượng tràn số.
Ta xét các ví dụ sau:
Trong ví dụ trên, ta thấy: (+7)+(+2) = (+9) và (-7)+(-2) = (-9) có kết quả bị tràn
do (+9) và (-9) không có trong dải biểu diễn số có dấu 4 bit(từ -8 đến 7). Các kết quả
còn lại không tràn do vẫn nằm trong dải biểu diễn.
Ngoài ra, có một cách khác nhận biết được kết quả có tràn hay không mà không
cần quan tâm đến dải biểu diễn đó là:
Overflow = c3 xor c4
Nếu dùng n bit để biểu diễn số có dấu thì ta có:
Overflow = cn xor cn-1
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
33
4.2.4. Thực hiện phép nhân trong số bù hai
Trước khi thảo luận về phép nhân hai số bù hai, ta cần phải biết về phép nhân với
luỹ thừa của 2.
Giả sử B=bn-1bn-2…b1bo. Khi đó: 2 x B = bn-1bn-2…b1bo0.
Ta chỉ việc dịch B sang trái 1 số rồi thêm 1 số 0 vào cuối.
Tổng quát hơn, nếu ta thực hiện phép nhân: 2k x B thì ta chỉ việc dịch B sang trái
k số rồi thêm k số 0 vào cuối.
Ta thấy phép nhân của số có dấu với luỹ thừa của 2 giống như của số không dấu.
Tuy nhiên, với phép chia thì lại khác hẳn. Để chia số B cho 2k, ta dịch số B sang phải k
số(tức là bỏ đi k số cuối). Sau đó, ta thêm vào trước số B k bit dấu(bit dấu là bit có
trọng số cao nhất).
Ví dụ:
B = 011000 = (24)10 , B:2 = 001100 = (12)10, và B:4= 000110 =(6)10
Tương tự với số âm: B=101000=(-24)10 , B:2= 110100 =(-12)10
Như vậy, ta đã biết cách thực hiện phép nhân và chia của số bù hai với luỹ thuỳ
của 2. Bây giờ ta thảo luận xem cách nhân 2 số bù hai được thực hiện như thế nào.
Ta xét hai ví dụ sau:
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
34
Từ 2 ví dụ trên, ta rút ra được cách nhân 2 số bù hai n bit A=an-1an-2… a1ao và
B=bn-1bn-2....b1bo tương tự như trên.
---------------------------------
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
35
Chương 5
THỰC NGHIỆM
5.1. MÔ TẢ PHẦN CỨNG CỦA KIT VIRTEX-II PRO
Phần cứng của kit Virtex-II Pro bao gồm:
• FPGA Spartan-II dùng để tạo giao tiếp PCI hoặc USB
• 2 LED trạng thái hiển thị 3 màu:cam, đỏ, vàng
• Giắc cắm cho mạch nạp JTAG
• 2 kênh ADC độc lập(ADC 14 bit) với tốc độ lấy mẫu tối đa là 105Mhz
• 2 kênh DAC độc lập(DAC 14 bit) với tốc độ biến đổi tối đa là 160Mhz
• 2 rãnh ZBT SRAM độc lập với bộ nhớ 512K x 32
• FPGA virtex-II XC2V80-4CS144 để tạo clock
• FPGA virtex-II pro XC2VP30-4FF1152 là FPGA chính cho người sử dụng
• Có đường kết nối với clock ngoài
• Có thạch anh 65Mhz trong mạch
Tổng thể về kit virtex-II Pro được mô tả như hình 14:
Hình 14: Toàn bộ mặt trên của Kit virtex-II pro
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
36
5.2. KẾT QUẢ THU ĐƯỢC VỚI BỘ LỌC FIR TRUYỀN THỐNG
Lưu đồ tiến hành thực hiện bộ lọc FIR truyền thống như hình 15:
Hình 15: Lưu đồ thực hiện bộ lọc FIR truyền thống
Sau khi qua biến đổi ADC, dữ liệu được biểu diễn dưới dạng số bù hai sẽ được
đưa vào FPGA để xử lý. FPGA có nhiệm vụ thực hiện thuật toán lọc theo yêu cầu của
người lập trình. Sơ đồ thực hiện thuật toán đối với bộ lọc FIR được trình bày như trong
hình 3 của chương 2. Trong đó, lối vào x[n] của bộ lọc chính là các giá trị sau khi qua
biến đổi ADC, các hệ số h[n] là các hằng số đã được cho trước(được tính toán bằng
Matlab) và y[n] là kết quả sau khi đã qua bộ lọc FIR. Các kết quả này cũng được biểu
diễn dưới dạng số bù hai và được đưa qua bộ biến đổi DAC để hiện lên trên dao động
ký.
Trong bài luận văn này, em thiết kế bộ lọc FIR thông thấp, với bậc bộ lọc là 50,
tần số mà bộ lọc bắt đầu suy giảm và triệt tiêu là từ 800Hz đến 1250Hz, tần số lấy
mẫu là 20Khz.
Các hệ số h[n] sẽ được tính toán bằng công cụ fdatool trong Matlab. Đáp ứng tần
số tính toán bằng Matlab được mô tả như hình 16:
Hình 16: Đáp ứng tần số của mạch lọc FIR
Máy
phát
ADC
FPGA
DAC
Dao động ký
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
37
Kết quả thu được khi thực hiện trên chíp FPGA:
• Tín hiệu bắt đầu suy giảm tại tần số 700Mhz, được cho bởi hình 17:
Hình 17: Tín hiệu bắt đầu suy giảm
• Tín hiệu bị triệt tiêu tại tần số 1237Hz, được cho bởi hình 18:
Hình 18: Tín hiệu bị triệt tiêu
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
38
5.3. KẾT QUẢ THU ĐƯỢC VỚI BỘ LỌC FIR THEO KIẾN TRÚC SYSTOLIC
Với bộ lọc FIR thực hiện theo kiến trúc systolic array, lưu đồ và kết quả đạt được
cũng tương tự như với bộ lọc FIR thông thường. Tuy nhiên, tốc độ thực hiện lại nhanh
hơn nhiều. Với công cụ “place and route tools” của phần mềm ISE, cho ta kết quả như
sau:
• Với bộ lọc FIR thực hiện theo kiến trúc systolic array, tần số hoạt động lớn nhất
của mạch là 141.947 Mhz và sử dụng hết 1775 slice.
• Với bộ lọc FIR truyền thống, tần số hoạt động của lớn nhất của mạch là 19.857
Mhz và sử dụng hết 417 slice.
Như vậy, ta có thể thấy bộ lọc FIR thực hiện theo kiến trúc systolic array có tốc độ đáp
ứng nhanh hơn nhiều so với bộ lọc FIR thông thường, tuy nhiên, nó lại tốn nhiều tài
nguyên hơn. Do đó, tuỳ theo từng ứng dụng cụ thể mà ta chọn thiết kế theo phương
pháp nào
5.4. KẾT QUẢ THU ĐƯỢC VỚI BỘ LỌC FIR THÍCH NGHI
Bộ lọc FIR thích nghi có rất nhiều ứng dụng như: Khử nhiễu, nhận dạng hệ thống
chưa biết, dự báo kết quả với hệ thống có tín hiệu vào là ngẫu nhiên….
Trong bài luận văn này, em xin trình bày về ứng dụng của bộ lọc FIR thích nghi
để khử nhiễu 50Hz-là nhiễu do nguồn sinh ra. Đây là loại nhiễu phổ biến và gây ảnh
hưởng lớn đến các thiết bị điện tử.
Lưu đồ cho việc khử nhiễu 50HZ được mô tả như hình 19:
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
39
Hình 19: Mô hình khử nhiễu 50 Hz
Trong đó:
• s(n) là tín hiệu mong muốn
• v(n) là tín hiệu nhiễu
• v1(n) là tín hiệu cùng dạng với v(n)(có thể khác nhau về biên độ và pha)
• v’(n) đầu ra của bộ lọc FIR thích nghi
• e(n) là tín hiệu sai số, đồng thời là lối ra.
Thuật toán LMS sẽ có nhiệm vụ điều chỉnh các hệ số của bộ lọc FIR sao cho lối
ra v’(n) có dạng gần nhất với tín hiệu nhiễu v(n). Khi đó, e(n)=d(n) - v’(n) sẽ đạt đến
tín hiệu mong muốn s(n). Tức là ta đã khử được nhiễu.
Kết quả thu được khi tiến hành trên chip FPGA:
• Tín hiệu lẫn với nhiễu 50Hz trước khi lọc, được cho bởi hình 20
Hình 20: Tín hiệu lẫn với nhiễu
d(n) = s(n)+v(n)
FIR
+
LMS
v’(n) __
v1(n)
+
e(n)
output
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
40
• Tín hiệu sau khi lọc được cho bởi hình 21
Hình 21: Tín hiệu thu được sau khi lọc
Tín hiệu thu được sau khi qua bộ lọc FIR thích nghi đã loại bỏ được nhiễu 50Hz.
Tuy nhiên, vẫn không được trơn tru và có độ mấp mô nhỏ. Sở dĩ như vậy là do các
nguyên nhân sau:
• Do bộ biến đổi ADC là 14 bit, nên khi qua bộ lọc FIR(bao gồm các bộ nhân và
bộ cộng) thì dữ liệu lên tới 28 bit, mà đầu ra DAC chỉ hỗ trợ 14 bit, vì vậy,
trước khi dữ liệu được đưa vào bộ lọc FIR, ta phải chia dữ liệu cho 27 để đầu ra
DAC là 14 bit. Do đó, kết quả có sai số nhất định
• Bộ biến đổi DAC chỉ hỗ trợ các số nguyên, do đó, ta phải làm tròn các hệ số
thành số nguyên, vì vậy, kết quả đạt được cũng không được như lý thuyết
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
41
KẾT LUẬN
Trong thời gian tiến hành hoàn thiện khoá luận tốt nghiệp, ngoài việc củng cố lại
những kiến thức đã được học trong suốt 4 năm qua, em còn thu được một số kiến thức
và kết quả nhất định:
• Được tìm hiểu và thực hành trên chip FPGA của hãng Xilinx
• Biết sử dụng thành thạo phần mềm ISE
• Có thêm nhiều kinh nghiệm trong việc lập trình với ngôn ngữ VHDL
• Thực hiện thành công bộ lọc FIR thông thấp trên FPGA theo kiến trúc
truyền thống và theo kiến trúc systolic array. So sánh được ưu điểm,
nhược điểm của từng loại
• Thực hiện thành công bộ lọc FIR thích nghi dùng thuật toán LMS trên
FPGA để loại bỏ nhiễu 50 Hz
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
42
TÀI LIỆU THAM KHẢO
[1] Simon Haykin. Adaptive filter theory, Third edition
[2] Uwe Meyer-Baese.Digital Signal Processing with Field Programmable Gate
Arrays, Third Edition
[3] John G.Proaskis,Dimitris G.Manolakis. Digital Signal Processing, Third edition
[4] Alexander D.Poularikas, Zayed M.Ramanda. Adaptive filtering primer with matlab,
2006.
[5] Douglas L.Perry. VHDL: Programming by Example .McGraw – Hill, Fourth
Edition
[6]. Volnei A.Pedroni, Circuit Design With VHDL, MIT Press, 2004
[7] Jan Van der Spiegel. VHDL tutorial
[8] Nguyễn Kim Giao, Kỹ thuật điện tử số, Nhà xuất bản Đại học Quốc gia Hà Nội,
2006.
[9]. Tống Văn On, Thiết kế mạch số với VHDL và Verilog, Nhà xuất bản lao động xã
hội, 2007.
[10] Hồ Văn Sung. Xử lý số tín hiệu đa tốc độ và dàn lọc, Nhà xuất bản KH-KT, 2007
[11]
[12]
[13]
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
43
PHỤ LỤC
PHẦN CHƯƠNG TRÌNH
1. Chương trình thiết kế bộ lọc FIR theo kiến trúc truyền thống
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity Toplevel is
port ( -- main clock input from oscilator
CLK1_FB : in std_logic;
-- main reset input from mb
RESETl : in std_logic;
-- configuration done signal
CONFIG_DONE : out std_logic;
-- dac 14 bit data outputs
DAC1_D : out std_logic_vector(13 downto 0);
DAC2_D : out std_logic_vector(13 downto 0);
-- adc 14 bit data inputs
ADC1_D : in std_logic_vector(13 downto 0);
ADC2_D : in std_logic_vector(13 downto 0);
-- dac reset signals
DAC1_RESET : out std_logic;
DAC2_RESET : out std_logic;
-- dac setup
DAC1_MOD0 : out std_logic;
DAC1_MOD1 : out std_logic;
DAC2_MOD0 : out std_logic;
DAC2_MOD1 : out std_logic;
-- dac clock divider setup
DAC1_DIV0 : out std_logic;
DAC1_DIV1 : out std_logic;
DAC2_DIV0 : out std_logic;
DAC2_DIV1 : out std_logic;
-- led flash signals
LED1_Red : out std_logic;
LED2_Red : out std_logic;
LED1_Green : out std_logic;
LED2_Green : out std_logic
);
end Toplevel;
architecture Behavioral of Toplevel is
-- clock components
component BUFG
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
44
port (
I : in std_logic;
O : out std_logic
);
end component;
component IBUFG
port (
I : in std_logic;
O : out std_logic
);
end component;
component DCM
generic (
DLL_FREQUENCY_MODE : string := "LOW";
DUTY_CYCLE_CORRECTION : string := "TRUE";
STARTUP_WAIT : string := "FALSE"
);
port (
CLKIN : in std_logic;
CLKFB : in std_logic;
DSSEN : in std_logic;
PSINCDEC : in std_logic;
PSEN : in std_logic;
PSCLK : in std_logic;
RST : in std_logic;
CLK0 : out std_logic;
CLK90 : out std_logic;
CLK180 : out std_logic;
CLK270 : out std_logic;
CLK2X : out std_logic;
CLK2X180 : out std_logic;
CLKDV : out std_logic;
CLKFX : out std_logic;
CLKFX180 : out std_logic;
LOCKED : out std_logic;
PSDONE : out std_logic;
STATUS : out std_logic_vector(7 downto 0)
);
end component;
-- end of clock components
-- internal clock and reset signals
Component FIR_Filter
Generic(n: integer :=14; -- width of data
m: integer := 51); -- order of FIR
Port (
Xin: in std_logic_vector(n-1 downto 0);
clk,reset: in std_logic;
Yout: out std_logic_vector(n-1 downto 0)
);
end Component;
component chiatan
port ( clk_i : in std_logic;
sochia : in integer;
clk_o : out std_logic
);
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
45
end component;
signal CLKIN_OSC, CLKFB_OSC, CLK_OSC, RESET, RSTl : std_logic;
-- temporary registers
signal ADC1, ADC2 : std_logic_vector(13 downto 0);
signal DAC1 :std_logic_vector(13 downto 0);
signal data :std_logic_vector(13 downto 0);
-- common ground
signal GND : std_logic;
signal clk:std_logic;
begin
GND <= '0';
RESET <= not RESETl;
-----------------------------clock deskew section--------------------------
---
-- IBUFG Instantiation for CLK_IN
U0_IBUFG : IBUFG
port map (
I => CLK1_FB,
O => CLKIN_OSC
);
-- BUFG Instantiation for CLKFB
U0_BUFG : BUFG
port map (
I => CLKFB_OSC,
O => CLK_OSC
);
-- DCM Instantiation for internal deskew of CLK0
U0_DCM : DCM
port map (
CLKIN => CLKIN_OSC,
CLKFB => CLK_OSC,
DSSEN => GND,
PSINCDEC => GND,
PSEN => GND,
PSCLK => GND,
RST => RESET,
CLK0 => CLKFB_OSC,
LOCKED => RSTl
);
-----------------------------end of clock deskew---------------------------
--
-- module configured
CONFIG_DONE <= '0';
-- set low pass filter response and no zero stuffing for both DACs
DAC1_MOD0 <= '0';
DAC1_MOD1 <= '0';
DAC2_MOD0 <= '0';
DAC2_MOD1 <= '0';
-- disable resets for DACs
DAC1_RESET <= '0';
DAC2_RESET <= '0';
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
46
-- optimum settings for sampling rate
DAC1_DIV0 <= '1';
DAC1_DIV1 <= '0';
DAC2_DIV0 <= '1';
DAC2_DIV1 <= '0';
-- digital output of adc to digital input of DAC
U0: chiatan port map(CLK_OSC,5250,clk);
DataRegisters : process (clk,RSTl)
begin
if RSTl = '0' then
ADC1 <= "00000000000000";
ADC2 <= "00000000000000";
DAC1_D <= "00000000000000";
DAC2_D <= "00000000000000";
elsif clk = '1' and clk'event then
--ADC1 <= ADC1_D;
--ADC2 <= ADC2_D;
if(ADC1_D(13)='1') then
ADC1<="1111111"&ADC1_D(13 downto 7);
else
ADC1<="0000000"&ADC1_D(13 downto 7);
end if;
DAC1_D <= not (not DAC1(13) & DAC1(12 downto 0));
--DAC2_D <= not (not ADC2(13) & ADC2(12 downto 0));
end if;
end process;
thuchien:FIR_Filter port map (ADC1(13 downto 0),clk,RSTl,DAC1);
-----------------------------led flasher section---------------------------
--
-- led flash counter
process (CLK_OSC, RSTl)
variable COUNT : std_logic_vector(26 downto 0);
begin
if RSTl = '0' then
COUNT := (others => '0');
-- led assignments
LED1_Red <= '0';
LED2_Red <= '0';
LED1_Green <= '0';
LED2_Green <= '0';
elsif CLK_OSC = '1' and CLK_OSC'event then
COUNT := COUNT + 1;
-- led assignments
LED1_Red <= COUNT(26);
LED2_Red <= COUNT(25);
LED1_Green <= COUNT(25);
LED2_Green <= COUNT(26);
end if;
end process;
-----------------------------end of led flasher----------------------------
-
end Behavioral;
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
47
Library ieee;
Use ieee.std_logic_1164.all;
Entity FIR_Filter is
Generic(n: integer :=14; -- width of data
m: integer := 51); -- order of FIR
Port (
Xin: in std_logic_vector(n-1 downto 0);
clk,reset: in std_logic;
Yout: out std_logic_vector(n-1 downto 0)
);
end FIR_FIlTER;
architecture arch_FIR of FIR_FILTER is
Component FF_D
Generic(n: integer :=14);
Port (
D :in std_logic_vector(n-1 downto 0);
Clk,Reset: in std_logic;
--enable: in std_logic;
Q: out std_logic_vector(n-1 downto 0)
);
end Component;
component PE is
Generic(n: integer :=14);
Port (
Xin,Ain: in std_logic_vector(n-1 downto 0);
Yin: in std_logic_vector(n-1 downto 0);
clk,reset : in std_logic;
Xout: inout std_logic_vector(n-1 downto 0);
Yout: out std_logic_vector(n-1 downto 0)
);
end component;
type A_cof is array(natural range m-1 downto 0) of std_logic_vector(n-1
downto 0);
type Y_cof is array(natural range m-1 downto 0) of std_logic_vector(n-1
downto 0);
constant Ain : A_cof :=
("00000000000001","00000000000001","00000000000001","00000000000001","00000
000000001","00000000000000","00000000000000","11111111111111","111111111111
11","11111111111110","11111111111110","11111111111110","11111111111110","11
111111111110","11111111111111","00000000000000","00000000000001","000000000
00010","00000000000100","00000000000101","00000000000110","00000000001000",
"00000000001001","00000000001010","00000000001010","00000000001010","000000
00001010","00000000001010","00000000001001","00000000001000","0000000000011
0","00000000000101","00000000000100","00000000000010","00000000000001","000
00000000000","11111111111111","11111111111110","11111111111110","1111111111
1110","11111111111110","11111111111110","11111111111111","11111111111111","
00000000000000","00000000000000","00000000000001","00000000000001","0000000
0000001","00000000000001","00000000000001");
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
48
signal Xout: std_logic_vector(n-1 downto 0);
signal Ytin,Ytout: std_logic_vector(n-1 downto 0);
signal X: a_cof;
signal Y: Y_cof;
begin
Y(m-1) '0');
PE_for:
for i in 0 to m-2 generate
-- Concurrent Statement(s)
PE1: PE port map (X(m-2-i),Ain(i),Y(m-1-i),clk,reset,X(m-1-
i),Y(m-2-i));
end generate;
PE2: PE port map (Xin,Ain(m-1),Y(0),clk,reset,X(0),Ytout);
REGST1: FF_D port map (ytout,clk,reset,Yout);
--REGST2: FF_D port map (Ytout,clk,reset,Yout);
end arch_FIR;
------------
Library ieee;
Use ieee.std_logic_1164.all;
Entity PE is
Generic(n: integer :=14);
Port (
Xin,Ain: in std_logic_vector(n-1 downto 0);
Yin: in std_logic_vector(n-1 downto 0);
clk,reset : in std_logic;
Xout: inout std_logic_vector(n-1 downto 0);
Yout: out std_logic_vector(n-1 downto 0)
);
end PE;
architecture arch_PE of PE is
Component adder
PORT
(
dataa : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
datab : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (13 DOWNTO 0)
);
END Component;
Component mult
PORT
(
dataa : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
datab : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (13 DOWNTO 0)
);
END Component;
-- Declarations (optional)
Component FF_D
Generic(n: integer :=14);
Port (
D :in std_logic_vector(n-1 downto 0);
Clk,Reset: in std_logic;
--Enable: in std_logic;
Q: out std_logic_vector(n-1 downto 0)
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
49
);
end Component;
signal S1,S2,S3: STD_LOGIC_VECTOR (n-1 DOWNTO 0);
signal rmul: STD_LOGIC_VECTOR (n-1 DOWNTO 0);
begin
REGX: FF_D
generic map (n => 14)
port map (Xin,clk,reset,Xout);
Multi: mult port map (xout,ain,rmul);
--REGS0: FF_D port map (s1,clk,reset,rmul);
adderS: adder port map (rmul,Yin,Yout);
--REGS1: FF_D port map (S2,clk,reset,S3);
--REGS2: FF_D port map (S3,clk,reset,Yout);
end arch_PE;
------------
Library ieee;
Use ieee.std_logic_1164.all;
Entity FF_D is
Generic(n: integer :=14);
Port (
D :in std_logic_vector(n-1 downto 0);
Clk,Reset: in std_logic;
--Enable: in std_logic;
Q: out std_logic_vector(n-1 downto 0)
);
end FF_D;
architecture arch_FFD of FF_D is
Begin
Process (clk,reset)
begin
if clk'event and clk = '1' then
--if enable = '1' then
if reset = '0' then
Q '0');
else
Q <= D;
end if;
--end if;
end if;
end process;
end arch_FFD;
--------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_SIGNED.all;
entity mult is
PORT
(
dataa : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
datab : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (13 DOWNTO 0)
);
END mult;
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
50
architecture run_mult of mult is
begin
result <= dataa*datab;
--result(13)<= dataa(7) xor datab(7);
end run_mult;
-------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_SIGNED.all;
entity adder is
PORT
(
dataa : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
datab : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (13 DOWNTO 0)
);
END adder;
architecture run_add of adder is
begin
result<=dataa+datab;
end run_add;
--------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_SIGNED.all;
entity chiatan is
port( clk_i : in std_logic;
sochia : in integer;
clk_o : out std_logic
);
end chiatan;
architecture run_chia of chiatan is
begin
process(clk_i)
variable i : integer range 0 to 50001 :=0;
variable j : integer range 0 to 50000 :=0;
variable temp : std_logic:='1';
begin
j:=sochia/2;
if(clk_i'event and clk_i='1') then
i:=i+1;
if(i>=j) then i:=0;temp:=not(temp);--;j:=j+1;
--if(j>=sochia) then j:=0; temp:=not(temp);
end if;
end if;
--end if;
clk_o<=temp;
end process;
end run_chia;
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
51
2. Chương trình thiết kế bộ lọc FIR theo kiến trúc systolic array
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity Toplevel is
port ( -- main clock input from oscilator
CLK1_FB : in std_logic;
-- main reset input from mb
RESETl : in std_logic;
-- configuration done signal
CONFIG_DONE : out std_logic;
-- dac 14 bit data outputs
DAC1_D : out std_logic_vector(13 downto 0);
DAC2_D : out std_logic_vector(13 downto 0);
-- adc 14 bit data inputs
ADC1_D : in std_logic_vector(13 downto 0);
ADC2_D : in std_logic_vector(13 downto 0);
-- dac reset signals
DAC1_RESET : out std_logic;
DAC2_RESET : out std_logic;
-- dac setup
DAC1_MOD0 : out std_logic;
DAC1_MOD1 : out std_logic;
DAC2_MOD0 : out std_logic;
DAC2_MOD1 : out std_logic;
-- dac clock divider setup
DAC1_DIV0 : out std_logic;
DAC1_DIV1 : out std_logic;
DAC2_DIV0 : out std_logic;
DAC2_DIV1 : out std_logic;
-- led flash signals
LED1_Red : out std_logic;
LED2_Red : out std_logic;
LED1_Green : out std_logic;
LED2_Green : out std_logic
);
end Toplevel;
architecture Behavioral of Toplevel is
-- clock components
component BUFG
port (
I : in std_logic;
O : out std_logic
);
end component;
component IBUFG
port (
I : in std_logic;
O : out std_logic
);
end component;
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
52
component DCM
generic (
DLL_FREQUENCY_MODE : string := "LOW";
DUTY_CYCLE_CORRECTION : string := "TRUE";
STARTUP_WAIT : string := "FALSE"
);
port (
CLKIN : in std_logic;
CLKFB : in std_logic;
DSSEN : in std_logic;
PSINCDEC : in std_logic;
PSEN : in std_logic;
PSCLK : in std_logic;
RST : in std_logic;
CLK0 : out std_logic;
CLK90 : out std_logic;
CLK180 : out std_logic;
CLK270 : out std_logic;
CLK2X : out std_logic;
CLK2X180 : out std_logic;
CLKDV : out std_logic;
CLKFX : out std_logic;
CLKFX180 : out std_logic;
LOCKED : out std_logic;
PSDONE : out std_logic;
STATUS : out std_logic_vector(7 downto 0)
);
end component;
-- end of clock components
-- internal clock and reset signals
Component FIR_Filter
Generic(n: integer :=14; -- width of data
m: integer := 51); -- order of FIR
Port (
Xin: in std_logic_vector(n-1 downto 0);
clk,reset: in std_logic;
Yout: out std_logic_vector(n-1 downto 0)
);
end Component;
component chiatan
port( clk_i : in std_logic;
sochia : in integer;
clk_o : out std_logic
);
end component;
signal CLKIN_OSC, CLKFB_OSC, CLK_OSC, RESET, RSTl : std_logic;
-- temporary registers
signal ADC1, ADC2 : std_logic_vector(13 downto 0);
signal DAC1 :std_logic_vector(13 downto 0);
signal DAC2 :std_logic_vector(13 downto 0);
signal data :std_logic_vector(13 downto 0);
-- common ground
signal GND : std_logic;
signal clk:std_logic;
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
53
begin
GND <= '0';
RESET <= not RESETl;
-----------------------------clock deskew section--------------------------
---
-- IBUFG Instantiation for CLK_IN
U0_IBUFG : IBUFG
port map (
I => CLK1_FB,
O => CLKIN_OSC
);
-- BUFG Instantiation for CLKFB
U0_BUFG : BUFG
port map (
I => CLKFB_OSC,
O => CLK_OSC
);
-- DCM Instantiation for internal deskew of CLK0
U0_DCM : DCM
port map (
CLKIN => CLKIN_OSC,
CLKFB => CLK_OSC,
DSSEN => GND,
PSINCDEC => GND,
PSEN => GND,
PSCLK => GND,
RST => RESET,
CLK0 => CLKFB_OSC,
LOCKED => RSTl
);
-----------------------------end of clock deskew---------------------------
--
-- module configured
CONFIG_DONE <= '0';
-- set low pass filter response and no zero stuffing for both DACs
DAC1_MOD0 <= '0';
DAC1_MOD1 <= '0';
DAC2_MOD0 <= '0';
DAC2_MOD1 <= '0';
-- disable resets for DACs
DAC1_RESET <= '0';
DAC2_RESET <= '0';
-- optimum settings for sampling rate
DAC1_DIV0 <= '1';
DAC1_DIV1 <= '0';
DAC2_DIV0 <= '1';
DAC2_DIV1 <= '0';
-- digital output of adc to digital input of DAC
U0: chiatan port map(CLK_OSC,5250,clk);
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
54
DataRegisters : process (clk,RSTl)
begin
if RSTl = '0' then
ADC1 <= "00000000000000";
ADC2 <= "00000000000000";
DAC1_D <= "00000000000000";
DAC2_D <= "00000000000000";
elsif clk = '1' and clk'event then
--ADC1 <= ADC1_D;
--ADC2 <= ADC2_D;
if(ADC1_D(13)='1') then
ADC1<="1111111"&ADC1_D(13 downto 7);
else
ADC1<="0000000"&ADC1_D(13 downto 7);
end if;
DAC2<=ADC1_D;
DAC1_D <= not (not DAC1(13) & DAC1(12 downto 0));
DAC2_D <= not (not DAC2(13) & DAC2(12 downto 0));
end if;
end process;
thuchien:FIR_Filter port map (ADC1(13 downto 0),clk,RSTl,DAC1);
-----------------------------led flasher section---------------------------
--
-- led flash counter
process (CLK_OSC, RSTl)
variable COUNT : std_logic_vector(26 downto 0);
begin
if RSTl = '0' then
COUNT := (others => '0');
-- led assignments
LED1_Red <= '0';
LED2_Red <= '0';
LED1_Green <= '0';
LED2_Green <= '0';
elsif CLK_OSC = '1' and CLK_OSC'event then
COUNT := COUNT + 1;
-- led assignments
LED1_Red <= COUNT(26);
LED2_Red <= COUNT(25);
LED1_Green <= COUNT(25);
LED2_Green <= COUNT(26);
end if;
end process;
-----------------------------end of led flasher----------------------------
end Behavioral;
Library ieee;
Use ieee.std_logic_1164.all;
Entity FIR_Filter is
Generic(n: integer :=14; -- width of data
m: integer := 51); -- order of FIR
Port (
Xin: in std_logic_vector(n-1 downto 0);
clk,reset: in std_logic;
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
55
Yout: out std_logic_vector(n-1 downto 0)
);
end FIR_FIlTER;
architecture arch_FIR of FIR_FILTER is
Component FF_D
Generic(n: integer :=14);
Port (
D :in std_logic_vector(n-1 downto 0);
Clk,Reset: in std_logic;
--enable: in std_logic;
Q: out std_logic_vector(n-1 downto 0)
);
end Component;
component PE is
Generic(n: integer :=14);
Port (
Xin,Ain: in std_logic_vector(n-1 downto 0);
Yin: in std_logic_vector(n-1 downto 0);
clk,reset : in std_logic;
Xout: inout std_logic_vector(n-1 downto 0);
Yout: out std_logic_vector(n-1 downto 0)
);
end component;
type A_cof is array(natural range m-1 downto 0) of std_logic_vector(n-1
downto 0);
type Y_cof is array(natural range m-1 downto 0) of std_logic_vector(n-1
downto 0);
constant Ain : A_cof :=
("00000000000001","00000000000001","00000000000001","00000000000001","00000
000000001","00000000000000","00000000000000","11111111111111","111111111111
11","11111111111110","11111111111110","11111111111110","11111111111110","11
111111111110","11111111111111","00000000000000","00000000000001","000000000
00010","00000000000100","00000000000101","00000000000110","00000000001000",
"00000000001001","00000000001010","00000000001010","00000000001010","000000
00001010","00000000001010","00000000001001","00000000001000","0000000000011
0","00000000000101","00000000000100","00000000000010","00000000000001","000
00000000000","11111111111111","11111111111110","11111111111110","1111111111
1110","11111111111110","11111111111110","11111111111111","11111111111111","
00000000000000","00000000000000","00000000000001","00000000000001","0000000
0000001","00000000000001","00000000000001");
signal Xout: std_logic_vector(n-1 downto 0);
signal Ytin,Ytout: std_logic_vector(n-1 downto 0);
signal X: a_cof;
signal Y: Y_cof;
begin
X(0) <= Xin;
Y(0) '0');
PE_for:
for i in 0 to m-2 generate
-- Concurrent Statement(s)
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
56
PE1: PE port map (X(i),Ain(i),Y(i),clk,reset,X(i+1),Y(i+1));
end generate;
PE2: PE port map (X(49),Ain(49),Y(49),clk,reset,Xout,Yout);
end arch_FIR;
------------
Library ieee;
Use ieee.std_logic_1164.all;
Entity PE is
Generic(n: integer :=14);
Port (
Xin,Ain: in std_logic_vector(n-1 downto 0);
Yin: in std_logic_vector(n-1 downto 0);
clk,reset : in std_logic;
Xout: inout std_logic_vector(n-1 downto 0);
Yout: out std_logic_vector(n-1 downto 0)
);
end PE;
architecture arch_PE of PE is
Component adder
PORT
(
dataa : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
datab : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (13 DOWNTO 0)
);
END Component;
Component mult
PORT
(
dataa : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
datab : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (13 DOWNTO 0)
);
END Component;
-- Declarations (optional)
Component FF_D
Generic(n: integer :=14);
Port (
D :in std_logic_vector(n-1 downto 0);
Clk,Reset: in std_logic;
--Enable: in std_logic;
Q: out std_logic_vector(n-1 downto 0)
);
end Component;
signal S1,S2,S3: STD_LOGIC_VECTOR (n-1 DOWNTO 0);
signal rmul: STD_LOGIC_VECTOR (n-1 DOWNTO 0);
begin
REGX: FF_D
generic map (n => 14)
port map (Xin,clk,reset,Xout);
Multi: mult port map (xout,ain,rmul);
--REGS0: FF_D port map (s1,clk,reset,rmul);
adderS: adder port map (rmul,Yin,S2);
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
57
REGS1: FF_D port map (S2,clk,reset,S3);
REGS2: FF_D port map (S3,clk,reset,Yout);
end arch_PE;
------------
Library ieee;
Use ieee.std_logic_1164.all;
Entity FF_D is
Generic(n: integer :=14);
Port (
D :in std_logic_vector(n-1 downto 0);
Clk,Reset: in std_logic;
--Enable: in std_logic;
Q: out std_logic_vector(n-1 downto 0)
);
end FF_D;
architecture arch_FFD of FF_D is
Begin
Process (clk,reset)
begin
if clk'event and clk = '1' then
--if enable = '1' then
if reset = '0' then
Q '0');
else
Q <= D;
end if;
--end if;
end if;
end process;
end arch_FFD;
--------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_SIGNED.all;
entity mult is
PORT
(
dataa : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
datab : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (13 DOWNTO 0)
);
END mult;
architecture run_mult of mult is
begin
result <= dataa*datab;
--result(13)<= dataa(7) xor datab(7);
end run_mult;
-------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_SIGNED.all;
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
58
entity adder is
PORT
(
dataa : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
datab : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (13 DOWNTO 0)
);
END adder;
architecture run_add of adder is
begin
result<=dataa+datab;
end run_add;
--------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_SIGNED.all;
entity chiatan is
port( clk_i : in std_logic;
sochia : in integer;
clk_o : out std_logic
);
end chiatan;
architecture run_chia of chiatan is
begin
process(clk_i)
variable i : integer range 0 to 50001 :=0;
variable j : integer range 0 to 50000 :=0;
variable temp : std_logic:='1';
begin
j:=sochia/2;
if(clk_i'event and clk_i='1') then
i:=i+1;
if(i>=j) then i:=0;temp:=not(temp);--;j:=j+1;
--if(j>=sochia) then j:=0; temp:=not(temp);
end if;
end if;
--end if;
clk_o<=temp;
end process;
end run_chia;
----------------------------------------------------
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
59
3. Chương trình thiết kế bộ lọc FIR thích nghi dùng thuật toán LMS
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_SIGNED.all;
entity Toplevel is
port ( -- main clock input from oscilator
CLK1_FB : in std_logic;
-- main reset input from mb
RESETl : in std_logic;
-- configuration done signal
CONFIG_DONE : out std_logic;
-- dac 14 bit data outputs
DAC1_D : out std_logic_vector(13 downto 0);
DAC2_D : out std_logic_vector(13 downto 0);
-- adc 14 bit data inputs
ADC1_D : in std_logic_vector(13 downto 0);
ADC2_D : in std_logic_vector(13 downto 0);
-- dac reset signals
DAC1_RESET : out std_logic;
DAC2_RESET : out std_logic;
-- dac setup
DAC1_MOD0 : out std_logic;
DAC1_MOD1 : out std_logic;
DAC2_MOD0 : out std_logic;
DAC2_MOD1 : out std_logic;
-- dac clock divider setup
DAC1_DIV0 : out std_logic;
DAC1_DIV1 : out std_logic;
DAC2_DIV0 : out std_logic;
DAC2_DIV1 : out std_logic;
-- led flash signals
LED1_Red : out std_logic;
LED2_Red : out std_logic;
LED1_Green : out std_logic;
LED2_Green : out std_logic
);
end Toplevel;
architecture Behavioral of Toplevel is
-- clock components
component BUFG
port (
I : in std_logic;
O : out std_logic
);
end component;
component IBUFG
port (
I : in std_logic;
O : out std_logic
);
end component;
component DCM
generic (
DLL_FREQUENCY_MODE : string := "LOW";
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
60
DUTY_CYCLE_CORRECTION : string := "TRUE";
STARTUP_WAIT : string := "FALSE"
);
port (
CLKIN : in std_logic;
CLKFB : in std_logic;
DSSEN : in std_logic;
PSINCDEC : in std_logic;
PSEN : in std_logic;
PSCLK : in std_logic;
RST : in std_logic;
CLK0 : out std_logic;
CLK90 : out std_logic;
CLK180 : out std_logic;
CLK270 : out std_logic;
CLK2X : out std_logic;
CLK2X180 : out std_logic;
CLKDV : out std_logic;
CLKFX : out std_logic;
CLKFX180 : out std_logic;
LOCKED : out std_logic;
PSDONE : out std_logic;
STATUS : out std_logic_vector(7 downto 0)
);
end component;
-- end of clock components
-- internal clock and reset signals
component fir_lms IS ------> Interface
GENERIC (W1 : INTEGER := 8; -- Input bit width
W2 : INTEGER := 16; -- Multiplier bit width 2*W1
L : INTEGER := 2 -- Filter length
);
PORT ( clk : IN STD_LOGIC;
x_in : IN STD_LOGIC_VECTOR(W1-1 DOWNTO 0);
d_in : IN STD_LOGIC_VECTOR(W1-1 DOWNTO 0);
e_out : OUT STD_LOGIC_VECTOR(W2-1 DOWNTO 0);
y_out :OUT STD_LOGIC_VECTOR(W2-1 DOWNTO 0)
);
END component;
component chiatan
port( clk_i : in std_logic;
sochia : in integer;
clk_o : out std_logic
);
end component;
signal CLKIN_OSC, CLKFB_OSC, CLK_OSC, RESET, RSTl : std_logic;
-- temporary registers
signal ADC1, ADC2 : std_logic_vector(7 downto 0);
signal DAC1 :std_logic_vector(13 downto 0);
signal DAC2 :std_logic_vector(13 downto 0);
signal data :std_logic_vector(13 downto 0);
-- common ground
signal GND : std_logic;
signal clk:std_logic;
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
61
signal e,y: std_logic_vector(15 downto 0);
begin
GND <= '0';
RESET <= not RESETl;
-----------------------------clock deskew section--------------------------
---
-- IBUFG Instantiation for CLK_IN
U0_IBUFG : IBUFG
port map (
I => CLK1_FB,
O => CLKIN_OSC
);
-- BUFG Instantiation for CLKFB
U0_BUFG : BUFG
port map (
I => CLKFB_OSC,
O => CLK_OSC
);
-- DCM Instantiation for internal deskew of CLK0
U0_DCM : DCM
port map (
CLKIN => CLKIN_OSC,
CLKFB => CLK_OSC,
DSSEN => GND,
PSINCDEC => GND,
PSEN => GND,
PSCLK => GND,
RST => RESET,
CLK0 => CLKFB_OSC,
LOCKED => RSTl
);
-----------------------------end of clock deskew---------------------------
--
-- module configured
CONFIG_DONE <= '0';
-- set low pass filter response and no zero stuffing for both DACs
DAC1_MOD0 <= '0';
DAC1_MOD1 <= '1';
DAC2_MOD0 <= '0';
DAC2_MOD1 <= '0';
-- disable resets for DACs
DAC1_RESET <= '0';
DAC2_RESET <= '0';
-- optimum settings for sampling rate
DAC1_DIV0 <= '0';
DAC1_DIV1 <= '1';
DAC2_DIV0 <= '1';
DAC2_DIV1 <= '0';
-- digital output of adc to digital input of DAC
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
62
U0: chiatan port map(CLK_OSC,5000,clk);
DataRegisters : process (clk,RSTl)
begin
if RSTl = '0' then
--e <= "0000000000000000";
--y <= "0000000000000000";
DAC1_D <= "00000000000000";
DAC2_D <= "00000000000000";
elsif clk = '1' and clk'event then
ADC1<=ADC1_D(13 downto 6);--tin hieu+nhieu
ADC2<=ADC2_D(13 downto 6);--nhieu
DAC1_D <= e(15) ¬(e(14 downto 2));--loc
DAC2_D <= ADC1_D(13) & not (ADC1_D(12 downto 0));--tin hieu +nhieu
end if;
end process;
thuchien:FIR_LMS port map (clk,ADC2,ADC1,e,y);
-----------------------------led flasher section---------------------------
--
-- led flash counter
process (CLK_OSC, RSTl)
variable COUNT : std_logic_vector(26 downto 0);
begin
if RSTl = '0' then
COUNT := (others => '0');
-- led assignments
LED1_Red <= '0';
LED2_Red <= '0';
LED1_Green <= '0';
LED2_Green <= '0';
elsif CLK_OSC = '1' and CLK_OSC'event then
COUNT := COUNT + 1;
-- led assignments
LED1_Red <= COUNT(26);
LED2_Red <= COUNT(25);
LED1_Green <= COUNT(25);
LED2_Green <= COUNT(26);
end if;
end process;
end Behavioral;
-----------------------------end of led flasher----------------------------
-
-- This is a generic LMS FIR filter generator
-- It uses W1 bit data/coefficients bits
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_signed.ALL;
ENTITY fir_lms IS ------> Interface
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
63
GENERIC (W1 : INTEGER := 8; -- Input bit width
W2 : INTEGER := 16; -- Multiplier bit width 2*W1
L : INTEGER := 2 -- Filter length
);
PORT ( clk : IN STD_LOGIC;
x_in : IN STD_LOGIC_VECTOR(W1-1 DOWNTO 0);
d_in : IN STD_LOGIC_VECTOR(W1-1 DOWNTO 0);
e_out : OUT STD_LOGIC_VECTOR(W2-1 DOWNTO 0);
y_out :OUT STD_LOGIC_VECTOR(W2-1 DOWNTO 0)
);
END fir_lms;
ARCHITECTURE fpga OF fir_lms IS
component mult is
PORT
(
dataa : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
datab : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
);
END component;
SUBTYPE N1BIT IS STD_LOGIC_VECTOR(W1-1 DOWNTO 0);
SUBTYPE N2BIT IS STD_LOGIC_VECTOR(W2-1 DOWNTO 0);
TYPE ARRAY_N1BIT IS ARRAY (0 TO L-1) OF N1BIT;
TYPE ARRAY_N2BIT IS ARRAY (0 TO L-1) OF N2BIT;
SIGNAL d : N1BIT;
SIGNAL emu : N1BIT;
SIGNAL y, sxty : N2BIT;
SIGNAL e, sxtd : N2BIT;
SIGNAL x, f : ARRAY_N1BIT; -- Coeff/Data arrays
SIGNAL p, xemu : ARRAY_N2BIT; -- Product arrays
BEGIN
dsxt: PROCESS (d) -- 16 bit signed extension for input d
BEGIN
sxtd(7 DOWNTO 0) <= d;
FOR k IN 15 DOWNTO 8 LOOP
sxtd(k) <= d(d'high);
END LOOP;
END PROCESS;
Store: PROCESS ------> Store these data or coefficients
BEGIN
WAIT UNTIL clk = '1';
d <= d_in;
x(0) <= x_in;
x(1)<=x(0);
f(0) <= f(0) + xemu(0)(15 DOWNTO 8);
f(1) <= f(1) + xemu(1)(15 DOWNTO 8);
END PROCESS Store;
MulGen1: FOR I IN 0 TO L-1 GENERATE
FIR: mult PORT MAP ( x(I), f(I),p(I));
END GENERATE;
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
64
y <=p(0)+p(1);
ysxt: PROCESS (y) -- Scale y by 128 because x is fraction
BEGIN
sxty(8 DOWNTO 0) <= y(15 DOWNTO 7);
FOR k IN 15 DOWNTO 9 LOOP
sxty(k) <= y(y'high);
END LOOP;
END PROCESS;
e <= sxtd - sxty;
emu <= e(8 DOWNTO 1); -- e*mu divide by 2 and
-- 2 from xemu makes mu=1/4
MulGen2: FOR I IN 0 TO L-1 GENERATE
FUPDATE: mult PORT MAP (x(I), emu,xemu(I));
END GENERATE;
y_out <= sxty; -- Monitor some test signals
e_out <= e;
END fpga;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_SIGNED.all;
entity mult is
PORT
(
dataa : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
datab : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
);
END mult;
architecture run_mult of mult is
begin
result <= dataa*datab;
--result(13)<= dataa(7) xor datab(7);
end run_mult;
-------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_SIGNED.all;
entity adder is
PORT
(
dataa : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
datab : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (13 DOWNTO 0)
);
END adder;
architecture run_add of adder is
begin
result<=dataa+datab;
ĐH Công Nghệ- ĐHQG Hà Nội Khoá luận tốt nghiệp
Nguyễn Anh Cường
65
end run_add;
--------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_SIGNED.all;
entity chiatan is
port( clk_i : in std_logic;
sochia : in integer;
clk_o : out std_logic
);
end chiatan;
architecture run_chia of chiatan is
begin
process(clk_i)
variable i : integer range 0 to 50001 :=0;
variable j : integer range 0 to 50000 :=0;
variable temp : std_logic:='1';
begin
j:=sochia/2;
if(clk_i'event and clk_i='1') then
i:=i+1;
if(i>=j) then i:=0;temp:=not(temp);--;j:=j+1;
--if(j>=sochia) then j:=0; temp:=not(temp);
end if;
end if;
--end if;
clk_o<=temp;
end process;
end run_chia;
Các file đính kèm theo tài liệu này:
- Thuc_hien_bo_loc_FIR_thich_nghi_dung_thuat_toan__LMS.pdf