MỤC LỤC
Trang
TRANG BÌA
LỜI CẢM ƠN . i
QUYẾT ĐỊNH GIAO ĐỀ TÀI ii
NHẬN XÉT CỦA GIÁO VIÊN HưỚNG DẪN . iii
NHẬN XÉT CỦA GIÁO VIÊN PHẢN BIỆN . iv
LỜI NÓI ĐẦU . v
MỤC LỤC . vii
LIỆT KÊ HÌNH . x
LIỆT KÊ BẢNG xii
PHẦN B: NỘI DUNG 13
CHưƠNG 1: TỔNG QUAN HỆ THỐNG THÔNG TIN SỐ 14
1.1 Vị trí của mã hóa kênh trong hệ thống thông tin số 14
1.2 Khái niệm mã hóa kênh và phân loại . 14
1.2.1 Khái niệm . 14
1.2.2 Phân loại mã hóa kênh 15
1.3 Khái quát về mã khối và mã trellis 16
1.3.1 Mã khối 16
1.3.2 Mã trellis 17
CHưƠNG 2: THUẬT TOÁN GIẢI MÃ VITERBI . 19
2.1 Khái niệm mã chập 19
2.2 Phân tích mã hóa dùng mã chập 19
2.3 Cấu trúc mã chập . 23
2.4 Biểu diễn mã chập 27
2.5 Ưu nhược điểm của mã chập 30
2.5.1 Ưu điểm . 30
2.5.2 Nhược điểm 30
2.6 Định nghĩa thuật toán Viterbi 30
2.7 Phân tích thuật giải Viterbi 31
2.8 Giải mã quyết định cứng và giải mã quyết định mềm 43 Thực hiện bộ giải mã Viterbi trên FPGA
2.8.1 Thuật toán Viterbi quyết định cứng 43
2.8.2 Thuật toán Viterbi quyết định mềm 48
2.8.2.1 Thuật toán Viterbi quyết định mềm (phương pháp 1) 48
2.8.2.2 Thuật toán Viterbi quyết định mềm (phương pháp 2) 49
2.8.3 Ưu điểm của giải mã quyết định mềm so với giải mã quyết định cứng
. 51
2.9 Xác suất lỗi 54
2.10 Ưu nhược điểm của thuật toán giải mã Viterbi 54
2.10.1 Ưu điểm . 54
2.10.2 Nhược điểm 55
CHưƠNG 3: MÔ PHỎNG THUẬT TOÁN VITERBI TRÊN MATLAB . 56
3.1 Giới thiệu . 56
3.2 Sơ đồ khối hệ thống . 56
3.3 Lưu đồ mô phỏng 57
3.3.1 Khối tạo bit ngõ vào . 57
3.3.2 Khối mã hóa . 58
3.3.3 Khối cộng nhiễu Gausse trắng 58
3.3.4 Khối giải mã . 58
3.3.5 Tính toán và vẽ BER 59
3.4 Hình ảnh về chương trình mô phỏng 59
CHưƠNG 4: XÂY DỰNG THUẬT TOÁN VITERBI TRÊN KIT DE2 65
4.1 Giới thiệu sơ lược KIT DE2 và phần mềm Quartus . 65
4.1.1 KIT DE2 của Altera 65
4.1.1.1 Tổng quan kit DE2 . 65
4.1.1.2 Sử dụng nút nhấn và Switch 67
4.1.1.3 Sử dụng LCD . 68
4.1.2 Phần mềm lập trình Quatus II 68
4.2 Giải quyết vấn đề 69
4.2.1 Giải mã viterbi quyết định cứng 69
4.2.2 Giải mã viterbi quyết định mềm 73
4.3 Lưu dồ thuật toán lập trình . 75
4.4 Kết quả . 82
CHưƠNG 5: KẾT LUẬN . 88
5.1 Tổng kết nhận xét . 88
5.2 Tồn tại và hướng phát triển của đề tài . 88
PHẦN C: PHỤ LỤC VÀ TÀI LIỆU THAM KHẢO 90
I. Phụ lục . 91
1. Hướng dẫn sử dụng kit DE2 để mô phỏng 91
2. Tài nguyên sử dụng trên Kit DE2 . 91
3. Mã nguồn Matlab . 93
4. Mã nguồn VHDL 105
II. Tài liệu tham khảo 123
124 trang |
Chia sẻ: banmai | Lượt xem: 2049 | Lượt tải: 3
Bạn đang xem trước 20 trang tài liệu Thực hiện bộ giải mã viterbi trên fpga, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
thực hiện tính toán và lưu trữ một bảng bao
gồm các giá trị của ngõ ra và giá trị tiếp theo tương ứng với tất cả các giá trị ngõ
vào. Bảng này gọi là bảng trạng thái tiếp theo. Bảng trạng thái tiếp theo được sử
dụng kết hợp với giá trị của đường tối ưu để tìm ra chuỗi bit ban đầu.
Việc tạo ra các giá trị tiếp theo giống như tạo mã chập cho các giá trị ngõ vào
được cho trước. Các giá trị này nằm ở các vị trí đã được xác định, để bộ giải mã có
thể truy cập đến một cách chính xác để tìm ra bit ngõ vào chính xác.
Thực hiện bộ giải mã Viterbi trên FPGA Trang 80
Chương 4: Xây dựng thuật toán giải mã Viterbi trên Kit DE2
Bảng trạng thái tiếp theo của bộ mã được sử dụng trong bài báo cáo này được
xác định như sau:
Bảng 4.4: Bảng trạng thái tiếp theo
Previous
State
INPUT 0 INPUT 1
Next State Output Bit Next State Output Bit
00 00 00 10 11
01 00 11 10 00
10 01 01 11 10
11 01 10 11 01
Khối tính khoảng cách nhánh
Vào 3 bit
Tính khoảng cách
Euclidean
3 bit 3 bit
Vào 1 bit
Tính khoảng cách
Hamming
1 bit 1 bit
input0 input1 input0 input1
Quyết định cứng / mềm
Chọn chế độ
Các khoảng cách
Dist_00 Dist_01 Dist_10 Dist_11
Hình 4.10: Lưu đồ khối tính khoảng cách nhánh
Tương ứng với mỗi cặp bit vào, bộ giải mã tính ra 4 khoảng cách nhánh tương ứng
với các cặp bit chuẩn 00, 01, 10, 11.
Thực hiện bộ giải mã Viterbi trên FPGA Trang 81
Chương 4: Xây dựng thuật toán giải mã Viterbi trên Kit DE2
Khối cộng so sánh lựa chọn
+
Dist_00
Bảng thông số tích lũy
+
Dist_11
<
0 1
Hình 4.11: Lưu đồ khối ACS
Khoảng cách nhánh tại trrạng thái hiện tại được cộng dồn với giá trị đã tích lũy
trước đó trên cùng đường đi của sơ đồ trellis. Sau khi cộng, bộ giải mã sẽ so sánh 2
kết quả cộng trên, giả sử tại thời điểm này, hai kết quả này bằng nhau, bộ so sánh sẽ
tiếp tục dịch lên một trạng thái và tiến hành so sánh lần thứ hai, lúc này bộ giải mã
sẽ tìm ra giá trị nhỏ nhất, từ đó bộ so sánh truy ngược lại và xác định giá trị lựa
chọn ở trạng thái trước. Giá trị sau khi được lựa chọn sẽ được lưu vào bảng tích lũy,
bảng này sẽ phục vụ cho việc tìm đường tồn tại sau này.
Khối truy hồi
Tăng trạng thái lên 1
So sánh các khoảng cách
nhánh tích lũy trong trạng
thái
Trạng thái 0
Trạng thái cuối ?
Lưu lại khoảng cách nhỏ
nhất
S
Đ
Đường tối ưu nhất
Hình 4.12: Lưu đồ khối truy hồi
Thực hiện bộ giải mã Viterbi trên FPGA Trang 82
Chương 4: Xây dựng thuật toán giải mã Viterbi trên Kit DE2
Từ trạng thái đầu tiên, khối truy hồi sẽ so sánh các giá trị trong bảng tích lũy để
tìm ra đường tồn tại tối ưu nhất.
Khối giải mã
Bảng trạng thái tiếp theo
Đường tối ưu nhất
Giống nhau ?
Dữ liệu ra
Bộ đếm
Bit 0 vào Bit 1 vàoTrạng thái tiếp theo
Hình 4.13: Lưu đồ khối giải mã
Sau khi qua khối truy hồi, bộ giải mã đã tìm được đường tồn tại. Bộ giải mã sẽ
tiến hành so sánh giá trị tiếp theo của đường tồn tại tại thời điểm hiện tại với giá trị
của đường tồn tại tại thời điểm sau một trạng thái. Với mỗi lần so sánh, bộ giải mã
sẽ thử với một trong hai bit vào là 0 hay 1, so sánh sự giống nhau tương ứng với giá
trị vào là 0 hay 1, bộ giải mã sẽ xác định được bit được mã hóa ban đầu ở khối phát
là 0 hay 1.
Sau khi hoàn thành so sánh tất cả các trạng thái, bộ giải mã đã xác định được
chuỗi bit ban đầu.
4.4 Kết quả
Quá trình thực hiện được chia làm hai quá trình, thứ nhất là lập trình giải thuật
mã hóa mã chập và thuật giải Viterbi chạy mô phỏng sử dụng phần mềm mô phỏng
có sẵn trong Quartus II; thứ hai là tiến hành biên dịch tổng hợp và đổ chương trình
lên Kit DE2 có kèm theo chương trình hiển thị trên LCD cà các Led đơn, trong
chương trình đổ lên Kit DE2 thì người lập trình đã loại bỏ khối mã hóa mã chập.
Giả sử cho chuỗi bit ban đầu trước khi mã hóa mã chập là: 11100101.
Sau khi mã hóa mã chập cho ra chuỗi bit sau: 1110011011110100
Thực hiện bộ giải mã Viterbi trên FPGA Trang 83
Chương 4: Xây dựng thuật toán giải mã Viterbi trên Kit DE2
Cho ngược chuỗi 16 bit trên vào ngõ vào của bộ giải mã Viterbi. Kết quả ngõ ra
là: 11100101
Vì không có nhiễu tác động nên kết quả của hai quyết định cứng và mềm là như
nhau.
Kết quả mô phỏng trên phần mềm Quartus II như sau:
Hình 4.14: Kết quả mô phỏng 1
Giả sử ngõ vào bộ giải mã Viterbi bị sai 2 bit: 1010011010110100
Kết quả ra vẫn chính xác: 11100101
Hình 4.15: Kết quả mô phỏng 2
Thực hiện bộ giải mã Viterbi trên FPGA Trang 84
Chương 4: Xây dựng thuật toán giải mã Viterbi trên Kit DE2
Giả sử ngõ vào bộ giải mã Viterbi bị sai 3 bit : 1010011010110101
Kết quả 1 bit cuối bị giải mã sai: 11100100
Hình 4.16: Kết quả mô phỏng 3
Giả sử ngõ vào bộ giải mã Viterbi bị sai 4 bit : 1010001010110101
Kết quả 1 bit cuối bị giải mã sai: 11100100
Hình 4.17: Kết quả mô phỏng 4
Kết quả trên chứng minh bộ giải mã Viterbi có khả năng sửa sai bit đơn rất tốt.
Giả sử ngõ vào bộ giải mã Viterbi bị sai 1 cặp bit : 1101011011110100
Kết quả 2 bit bị giải mã sai: 10110101
Thực hiện bộ giải mã Viterbi trên FPGA Trang 85
Chương 4: Xây dựng thuật toán giải mã Viterbi trên Kit DE2
Hình 4.18: Kết quả mô phỏng 5
Giả sử ngõ vào bộ giải mã Viterbi bị sai 1 bit đơn và 1cặp bit :
1101011011111100
Kết quả 5 bit bị giải mã sai: 10110010
Hình 4.19: Kết quả mô phỏng 6
Kết quả trên cho thấy, thuật giải mã Viterbi không có khả năng sửa lỗi sai trong
trường hợp lỗi đa bit.
So sánh với kết quả đã mô phỏng trên Matlab
Vẫn chuỗi bit vào như trên: 11100101. Với mô phỏng trên Matlab, hệ thống có
tác động của nhiễu trắng Gaussian. Kết quả giải mã bị sai 1 bit với quyết định
mềm.
Thực hiện bộ giải mã Viterbi trên FPGA Trang 86
Chương 4: Xây dựng thuật toán giải mã Viterbi trên Kit DE2
Hình 4.20: Mô phỏng trên Matlab
Vì mô phỏng trên Kit DE2 là môi trường lý tưởng, dữ liệu bit nhận được nhập
vào bởi người sử dụng, không bị tác động của kênh truyền, do đó kết quả giải mã
cho chính xác hơn so với giải mã trên Matlab.
Hình ảnh thực tế trên Kit DE2 như sau:
Hình 4.21: Hình thực tế bộ kit 1
Khởi động chương trình mô
phỏng, LCD hiển thị DH
SPKT TPHCM và dòng chữ
DO AN TOT NGHIEP
Thực hiện bộ giải mã Viterbi trên FPGA Trang 87
Chương 4: Xây dựng thuật toán giải mã Viterbi trên Kit DE2
Hình 4.22: Hình thực tế bộ kit 2
Hình 4.23: hình thực tế bộ kit 3
Tiếp theo, LCD hiển thị
nhóm thực hiện đề tài
4. LCD hiển
thị chuỗi dữ
liệu cần giải
mã và chuỗi
dữ liệu sau giải
mã.
5. 8 LED biễu diễn
chuỗi dữ liệu sau giải
mã.
2. 16 SW để gán dữ
liệu cần giải mã.
3. Mức 1
để bắt
đầu giải
mã.
1. Mức 0
để chọn
giải mã
quyết định
mềm
Key 0 để
reset mạch
Thực hiện bộ giải mã Viterbi trên FPGA Trang 88
Chương 5: Kết luận
CHƢƠNG 5: KẾT LUẬN
5.1 Tổng kết nhận xét
Tổng kết lại, trong cuốn đồ án này nhóm đã thực hiện được những nội dung
sau:
Giới thiệu về vị trí vai trò của mã hóa kênh truyền trong hệ thống thông tin
số, so sánh hai hình thức mã hóa là mã khối và mã trellis.
Khái niệm và phân tích mã chập, cách thức mã hóa sử dụng mã chập, cũng
như cấu trúc của bộ mã hóa chập.
Khái niệm và phân tích thuật toán giải mã Viterbi, cách mà thuật toán
Viterbi giải mã một tín hiệu và sửa sai các lỗi xảy ra trên kênh truyền, phân
biệt hai phương pháp giải mã là giải mã quyết định cứng và quyết định
mềm.
Thực hiện mô phỏng Matlab để xem hiệu quả của thuật toán Viterbi.
Thực hiện mô tả trên Kit DE2 bằng ngôn ngữ VHDL để kiểm chứng kết quả
mô phỏng.
Qua kết quả mô phỏng bằng Matlab và kết quả mô tả trên kit DE2, nhóm đã rút
ra được những nhận xét sau:
Mã hóa kênh truyền giúp giảm thiểu tác động của nhiễu và cải thiện tin tức
tốt.
Thuật toán giải mã viterbi đạt hiệu quả cao, xác suất lỗi thấp
Trên kênh truyền có lỗi Gauss trắng, tín hiệu có thể được phục hồi tốt.
Thuật toán viterbi với quyết định mềm cho kết quả tốt hơn quyết định cứng.
Vì với quyết định mềm tín hiệu sau khi được nhận ở bộ thu được lượng tử
với nhiều mức, do đó dẫn đến xác suất sai sẽ thấp hơn so với quyết định
cứng.
Đối với các lỗi nhiều bit liên tiếp, thuật toán Viterbi không mang lại hiệu
quả.
Trong kênh truyền có tỉ số SNR cao, thuật toán viterbi với cả 2 quyết định
cứng và mềm đều cho kết quả tốt gần như nhau.
5.2 Tồn tại và hướng phát triển của đề tài
Những mặt còn tồn tại:
- Việc mô phỏng trên matlab cũng như mô tả trên kit DE2 đều chỉ mới tiến
hành với bộ mã đơn giản tốc độ ½ với chiều dài ràng buộc thấp. Vì thế,
kết quả mô phỏng có thể sẽ không bao quát và nói hết được ưu nhược
điểm của thuật toán.
Thực hiện bộ giải mã Viterbi trên FPGA Trang 89
Chương 5: Kết luận
- Việc mô tả trên kit DE2 chỉ là khâu giải mã với chuỗi bit nhận được nhập
bởi người sử dụng. Do đó, ta không thể đánh giá được hết tác động của
nhiễu chỉ với vài lần thử nghiệm với các bit nhận được là sai.
- Việc giải mã Viterbi quyết dịnh mềm chỉ mới thực hiện với phương pháp
dùng khoảng cách Euclidean.
Hướng phát triển đề tài:
- Với giới hạn thời gian cũng như khả năng có hạn nên nhóm tác giả vẫn
còn chưa tìm hiểu hoàn chỉnh về mã chập cũng như thuật giải Viterbi. Vì
vậy, có thể phương pháp thực hiện cũng như lập trình sẽ không là giải
pháp tối ưu. Nếu có cơ hội để nghiên cứu tiếp thì đề tài có thể nâng lên để
thực hiện tối ưu hóa cho bộ thu Viterbi, thử nghiệm với các bộ mã khác
nhau để từ đó tìm ra bộ mã tối ưu nhất cho kênh truyền AWGN.
- Cải thiện việc mô tả trên kit DE2 bằng cách thêm phần tạo bit nhận ngẫu
nhiên chứ không nhập trực tiếp bằng tay, từ đó tổng hợp đánh giá tác động
của nhiễu lên tín hiệu một cách tổng quát hơn.
- Từ kết quả của đề tài, chúng ta có thể thiết kế các IC thực hiện các chức
năng khác nhau trong hệ thống thông tin số.
- Nghiên cứu tiến hành xây dựng bộ mã hóa nguồn.
PHẦN C
PHỤ LỤC VÀ TÀI
LIỆU THAM KHẢO
Thực hiện bộ giải mã Viterbi trên FPGA Trang 91
Phần C: Phụ lục và tài liệu tham khảo
I. Phụ lục
1. Hướng dẫn sử dụng kit DE2 để mô phỏng
Chức năng các một số thiết bị trên Kit DE2 như sau:
- Switch 0: Chức năng start, để bắt đầu quá trình giải mã. Mức 1 tương ứng
với lệnh thực hiện bắt đầu.
- Switch 1: Chức năng lựa chọn chế độ quyết định cứng hay mềm.
1. Mức 0: Quyết định cứng
2. Mức 1: Quyết định mềm
- Switch 2 đến 17: Tương ứng với 16 bit ngõ vào.
- Nút nhấn Key 0: Chức năng reset mạch.
- LCD: Chức năng hiển thị thông tin về đồ án và dữ liệu vào ra của bộ giải
mã.
- Led 0 đến 7: Chức năng hiển thị giá trị của 8 bit ngõ ra.
1. Led sáng: Mức 1
2. Led tắt: Mức 0
Quá trình mô phỏng trên Kit DE2 nhƣ sau:
Sau khi đã nạp chương trình từ máy tính xuống Kit DE2, màn hình LCD sẽ
hiển thị một số thông tin về đồ án. Khi gạt các Switch từ 2 đến 17 để cấp dữ liệu
ngõ vào cho bộ giải mã, LCD sẽ hiển thị giá trị 16 bit này. Khi gạt Switch 0, quá
trình giải mã bắt đầu, LCD hiển thị thêm 8 bit ra ở dòng thứ 2, đồng thời các Led sẽ
sáng.
Nếu nhấn nút Key 0 (Reset), LCD sẽ hiển thị lại các thông tin ban đầu, nếu lúc này,
Switch Start đang bật thì các Led vẫn sáng, nếu Switch Start gạt xuống mức 0 thì
các Led tắt hết.
2. Tài nguyên sử dụng trên Kit DE2
Bảng: Thông báo về tài nguyên sử dụng trên kit DE2
Thực hiện bộ giải mã Viterbi trên FPGA Trang 92
Phần C: Phụ lục và tài liệu tham khảo
Bảng: Danh sách các chân sử dụng trên Kit DE2
Signal Name PIN Discription
Clock_50 PIN_N2 50 mHz clock input
SW[0] PIN_N25 Toggle Switch[0]
SW[1] PIN_N26 Toggle Switch[1]
SW[2] PIN_P25 Toggle Switch[2]
SW[3] PIN_AE14 Toggle Switch[3]
SW[4] PIN_AF14 Toggle Switch[4]
SW[5] PIN_AD13 Toggle Switch[5]
SW[6] PIN_AC13 Toggle Switch[6]
SW[7] PIN_C13 Toggle Switch[7]
SW[8] PIN_B13 Toggle Switch[8]
SW[9] PIN_A13 Toggle Switch[9]
SW[10] PIN_N1 Toggle Switch[10]
SW[11] PIN_P1 Toggle Switch[11]
SW[12] PIN_P2 Toggle Switch[12]
SW[13] PIN_T7 Toggle Switch[13]
SW[14] PIN_U3 Toggle Switch[14]
SW[15] PIN_U4 Toggle Switch[15]
SW[16] PIN_V1 Toggle Switch[16]
SW[17] PIN_V2 Toggle Switch[17]
LEDR[0] PIN_AE23 LED Red[]
LEDR[1] PIN_AF23 LED Red[]
Thực hiện bộ giải mã Viterbi trên FPGA Trang 93
Phần C: Phụ lục và tài liệu tham khảo
LEDR[2] PIN_AB21 LED Red[]
LEDR[3] PIN_AC22 LED Red[]
LEDR[4] PIN_AD22 LED Red[]
LEDR[5] PIN_AD23 LED Red[]
LEDR[6] PIN_AD21 LED Red[]
LEDR[7] PIN_AC21 LED Red[]
KEY[0] PIN_G26 Pushbutton[0]
LCD_DATA[0] PIN_J1 LCD DATA []
LCD_DATA[1] PIN_J2 LCD DATA []
LCD_DATA[2] PIN_H1 LCD DATA []
LCD_DATA[3] PIN_H2 LCD DATA []
LCD_DATA[4] PIN_J4 LCD DATA []
LCD_DATA[5] PIN_J3 LCD DATA []
LCD_DATA[6] PIN_H4 LCD DATA []
LCD_DATA[7] PIN_H3 LCD DATA []
LCD_RW PIN_K4 LCD Read/Write Select, 0 = Write, 1 =
Read
LCD_EN PIN_K3 LCD Enable
LCD_RS PIN_K1 LCD Command/Data Select, 0 =
Command, 1 = Data
LCD_ON PIN_L4 LCD Power ON/OFF
LCD_BLON PIN_L2 LCD Back Light ON/OFF
3. Mã nguồn Matlab
function varargout = viterbi2(varargin)
Thực hiện bộ giải mã Viterbi trên FPGA Trang 94
Phần C: Phụ lục và tài liệu tham khảo
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @viterbi2_OpeningFcn, ...
'gui_OutputFcn', @viterbi2_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
function viterbi2_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
h1 = getappdata(0,'GUI1_handle');
close(h1)
h2 = gcf;
setappdata(0,'GUI2_handle',h2);
axes(handles.logo);
imshow('KHOADIENTU.png');
viterbi3;
set(handles.bitin,'Enable','inactive');
global inbit numin ;
inbit =0;
function varargout = viterbi2_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
function button_back_Callback(hObject, eventdata, handles)
viterbi1;
function button_exit_Callback(hObject, eventdata, handles)
exit = questdlg('Ready to quit?',...
Thực hiện bộ giải mã Viterbi trên FPGA Trang 95
Phần C: Phụ lục và tài liệu tham khảo
'Exit Dialog','Yes','No','No');
switch exit
case 'Yes',
disp('Exiting MATLAB');
save
quit
case 'No'
quit cancel;
end
function numin_Callback(hObject, eventdata, handles)
user_entry = str2double(get(hObject,'String'));
if isnan(user_entry)
errordlg('Type the integer, maximum value is 10^6! ','Input Error !','modal')
set(hObject,'String','');
return
end
function numin_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function numin_ButtonDownFcn(hObject, eventdata, handles)
function g2_Callback(hObject, eventdata, handles)
user_entry = str2double(get(hObject,'string'));
if isnan(user_entry)
errordlg('Type the integer ! ','Input Error !','modal')
set(hObject,'String','');
return
end
function g2_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function g1_Callback(hObject, eventdata, handles)
Thực hiện bộ giải mã Viterbi trên FPGA Trang 96
Phần C: Phụ lục và tài liệu tham khảo
user_entry = str2double(get(hObject,'string'));
if isnan(user_entry)
errordlg('Type the integer ! ','Input Error !','modal')
set(hObject,'String','');
return
end
function g1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function length_Callback(hObject, eventdata, handles)
user_entry = str2double(get(hObject,'string'));
if isnan(user_entry)
errordlg('Type the integer ! ','Input Error !','modal')
set(hObject,'String','');
return
end
function length_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function numout_Callback(hObject, eventdata, handles)
user_entry = str2double(get(hObject,'string'));
if isnan(user_entry)
errordlg('Type the integer ! ','Input Error !','modal')
set(hObject,'String','');
return
end
if (user_entry > 2)||(user_entry < 1)
errordlg('The Viterbi decoder is just for maximum 2 outputs !','Input Error
!','modal')
set(hObject,'String','');
return
end
Thực hiện bộ giải mã Viterbi trên FPGA Trang 97
Phần C: Phụ lục và tài liệu tham khảo
if user_entry == 1
set(handles.g2,'Enable','inactive');
set(handles.textber,'ForegroundColor','black')
elseif user_entry == 2
set(handles.g2,'Enable','on');
set(handles.textber,'ForegroundColor','blue')
end
function numout_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function auto_Callback(hObject, eventdata, handles)
if (get(hObject,'Value') == get(hObject,'Max'))
a = 1;
set(handles.numin,'Enable','inactive');
set(handles.numin,'String','');
set(handles.bitin,'Enable','on');
set(handles.bitin,'String','');
set(handles.text7,'ForegroundColor','black');
else
a = 0;
set(handles.numin,'Enable','on');
set(handles.bitin,'Enable','inactive');
set(handles.text7,'ForegroundColor','blue');
end
function bitin_Callback(hObject, eventdata, handles)
function bitin_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function bitencoded_Callback(hObject, eventdata, handles)
function bitencoded_CreateFcn(hObject, eventdata, handles)
Thực hiện bộ giải mã Viterbi trên FPGA Trang 98
Phần C: Phụ lục và tài liệu tham khảo
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function bitout_Callback(hObject, eventdata, handles)
function bitout_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function ber_Callback(hObject, eventdata, handles)
clc;
if (get(handles.auto,'Value') == get(handles.auto,'Max'))
a = 1;
else
a = 0;
end
if a == 1
inbit = get(handles.bitin,'String');
inbit = str2num(inbit);
numin = length(inbit);
else
numin = get(handles.numin,'String');
numin = str2num(numin);
inbit = randint(1,numin);
end
numout = get(handles.numout,'String');
numout = str2num(numout);
len = get(handles.length,'String');
len = str2num(len);
g1 = get(handles.g1,'String');
g1 = str2num(g1);
g2 = get(handles.g2,'String'
g2 = str2num(g2);
Eb_N0_dB = [1:1:10];
Thực hiện bộ giải mã Viterbi trên FPGA Trang 99
Phần C: Phụ lục và tài liệu tham khảo
for i = 1:length(Eb_N0_dB)
snr_db = Eb_N0_dB(i)
if numout == 1
trellis = poly2trellis(len,g1);
elseif numout == 2
trellis = poly2trellis(len,[g1 g2]);
end
encbits = convenc(inbit,trellis);
encbits = 2*encbits - 1;
awgnbits = awgn(encbits,snr_db,'measured');
str = get(handles.typeofdec,'String');
val = get(handles.typeofdec,'Value');
switch str{val}
case 'Soft Decision'
select = 0;
case 'Hard Decision'
select = 1;
case 'Both'
select = 2;
end
if select == 0
partition = [-.8571 -.5714 -.2857 0 .2857 .5714 .8571];
codebook = [-.99 -.8571 -.5714 -.2857 0 .2857 .5714 .8571];
quanbits = quantiz(awgnbits,partition,codebook);
tblen = numin -1 ;
opmode = 'term';
dectype = 'soft';
nsdec = 3;
decbits = vitdec(quanbits,trellis,tblen,'term','soft',nsdec);
end
if select == 1
partition = [0];
codebook = [0 1];
quanbits = quantiz(awgnbits,partition,codebook);
tblen = numin-1;
opmode = 'term' ;
dectype = 'hard';
Thực hiện bộ giải mã Viterbi trên FPGA Trang 100
Phần C: Phụ lục và tài liệu tham khảo
decbits = vitdec(quanbits,trellis,tblen,'term','hard');
end
if select == 0 || select == 1
[numerr ratioerr] = biterr(inbit, decbits);
ratioerr_comp(i) = ratioerr
end
if select == 2
partition_h = [0];
codebook_h = [0 1];
quanbits_h = quantiz(awgnbits,partition_h,codebook_h);
tblen_h = numin-1;
opmode_h = 'term' ;
dectype_h = 'hard';
decbits_h = vitdec(quanbits_h,trellis,tblen_h,'term','hard');
partition_s = [-.8571 -.5714 -.2857 0 .2857 .5714 .8571];
codebook_s = [-.99 -.8571 -.5714 -.2857 0 .2857 .5714 .8571];
quanbits_s = quantiz(awgnbits,partition_s,codebook_s);
tblen_s = numin -1 ;
opmode_s = 'term';
dectype_s = 'soft';
nsdec = 3;
decbits_s = vitdec(quanbits_s,trellis,tblen_s,'term','soft',nsdec);
[numerr_s ratioerr_s] = biterr(inbit, decbits_s);
ratioerr_comp_s(i) = ratioerr_s
[numerr_h ratioerr_h] = biterr(inbit, decbits_h);
ratioerr_comp_h(i) = ratioerr_h
end
end
if select == 0
figure
semilogy(Eb_N0_dB,ratioerr_comp,'mp-','LineWidth',2);
axis([0 10 10^-8 0.5])
grid on
legend('Viterbi-Soft decision(rate-1/2, [5,7]_8)');
xlabel('Eb/No, dB');
ylabel('Bit Error Rate');
title('BER for Viterbi-Soft decision decoding in AWGN');
end
Thực hiện bộ giải mã Viterbi trên FPGA Trang 101
Phần C: Phụ lục và tài liệu tham khảo
if select == 1
figure
semilogy(Eb_N0_dB,ratioerr_comp,'bd-','LineWidth',2);
axis([0 10 10^-8 0.5])
grid on
legend('Viterbi-Hard decision(rate-1/2, [5,7]_8)');
xlabel('Eb/No, dB');
ylabel('Bit Error Rate');
title('BER for Viterbi-Hard decision decoding in AWGN');
end
if select == 2
figure
semilogy(Eb_N0_dB,ratioerr_comp_s,'mp-','LineWidth',2);
hold on;
semilogy(Eb_N0_dB,ratioerr_comp_h,'bd-','LineWidth',2);
axis([0 10 10^-8 0.5])
grid on
legend('Viterbi-Soft decision(rate-1/2, [5,7]_8)','Viterbi-Hard decision(rate-1/2,
[5,7]_8)');
xlabel('Eb/No, dB');
ylabel('Bit Error Rate');
title('BER for both types of decision of Viterbi decoding in AWGN');
end
function reset_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function start_Callback(hObject, eventdata, handles)
clc;
global inbit numin ratioerr
inbit = get(handles.bitin,'String');
inbit = str2num(inbit);
numin = length(inbit);
numout = get(handles.numout,'String');
numout = str2num(numout);
len = get(handles.length,'String');
Thực hiện bộ giải mã Viterbi trên FPGA Trang 102
Phần C: Phụ lục và tài liệu tham khảo
len = str2num(len);
g1 = get(handles.g1,'String');
g1 = str2num(g1);
g2 = get(handles.g2,'String');
g2 = str2num(g2);
if numout == 1
trellis = poly2trellis(len,g1);
elseif numout == 2
trellis = poly2trellis(len,[g1 g2]);
end
encbits = convenc(inbit,trellis);
encbits = num2str(encbits);
set(handles.bitencoded,'String',encbits)
encbits = str2num(encbits);
encbits = 2*encbits - 1;
snr = get(handles.snr,'String');
snr = str2num(snr);
awgnbits = awgn(encbits, snr, 'measured');
str = get(handles.typeofdec,'String');
val = get(handles.typeofdec,'Value');
switch str{val}
case 'Soft Decision'.
select = 0;
case 'Hard Decision'
select = 1;
case 'Both'
select = 2;
end
if select == 0
partition = [-.8571 -.5714 -.2857 0 .2857 .5714 .8571];
codebook = [-.99 -.8571 -.5714 -.2857 0 .2857 .5714 .8571];
quanbits = quantiz(awgnbits,partition,codebook);
tblen = numin -1 ;
opmode = 'term';
dectype = 'soft';
nsdec = 3;
decbits = vitdec(quanbits,trellis,tblen,'term','soft',nsdec);
Thực hiện bộ giải mã Viterbi trên FPGA Trang 103
Phần C: Phụ lục và tài liệu tham khảo
end
if select == 1
partition = [0];
codebook = [0 1];
quanbits = quantiz(awgnbits,partition,codebook);
tblen = numin-1;
opmode = 'term' ;
dectype = 'hard';
decbits = vitdec(quanbits,trellis,tblen,'term','hard');
end
decbits = num2str(decbits);
set(handles.bitout,'String',decbits)
decbits = str2num(decbits);
[numerr ratioerr] = biterr(inbit, decbits);
numerr = num2str(numerr);
set(handles.numerr,'String',numerr);
numerr = str2num(numerr);
ratioerr = num2str(ratioerr);
set(handles.ratioerr,'String',ratioerr);
ratioerr = str2num(ratioerr);
function reset_Callback(hObject, eventdata, handles)
clc;
set(handles.typeofdec,'Value',1);
set(handles.auto,'Value',0);
set(handles.bitin,'Enable','inactive');
set(handles.numin,'String','');
set(handles.numout,'String','2');
set(handles.length,'String','3');
set(handles.g1,'String','5');
set(handles.g2,'String','7');
set(handles.snr,'String','5');
set(handles.bitin,'String','');
set(handles.bitencoded,'String','');
set(handles.bitout,'String','');
set(handles.numerr,'String','');
set(handles.ratioerr,'String','');
set(handles.g2,'Enable','on');
set(handles.textber,'ForegroundColor','blue')
Thực hiện bộ giải mã Viterbi trên FPGA Trang 104
Phần C: Phụ lục và tài liệu tham khảo
function togglebutton1_Callback(hObject, eventdata, handles)
function edit17_Callback(hObject, eventdata, handles)
function edit17_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function snr_Callback(hObject, eventdata, handles)
user_entry = str2double(get(hObject,'string'));
if isnan(user_entry)
errordlg('Type the integer ! ','Input Error !','modal')
set(hObject,'String','');
return
end
function snr_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function pushbutton5_Callback(hObject, eventdata, handles)
function start_KeyPressFcn(hObject, eventdata, handles)
function taoinbit_Callback(hObject, eventdata, handles)
clc;
global inbit numin ;
if (get(handles.auto,'Value') == get(handles.auto,'Max'))
a = 1;
else
a = 0;
end
if a == 1
inbit = get(handles.bitin,'String');
Thực hiện bộ giải mã Viterbi trên FPGA Trang 105
Phần C: Phụ lục và tài liệu tham khảo
inbit = str2num(inbit);
else
numin = get(handles.numin,'String');
numin = str2num(numin);
inbit = randint(1,numin);
end
inbit = num2str(inbit);
set(handles.bitin,'Enable','on');
set(handles.bitin,'String',inbit);
inbit = str2num(inbit);
function viwebit_Callback(hObject, eventdata, handles)
close 'Gui_3' ;
function typeofdec_Callback(hObject, eventdata, handles)
function typeofdec_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'),
get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
4. Mã nguồn VHDL
Viterbi.vhd
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;
USE work.distance.all;
USE work.converter.all;
ENTITY viterbi is
GENERIC(
CONSTANT K: natural: = 1;
CONSTANT N: natural: = 2;
CONSTANT L: natural: = 3;
CONSTANT Ga: natural: = 5;
CONSTANT Gb: natural: = 7;
CONSTANT V: natural: = 8
);
Thực hiện bộ giải mã Viterbi trên FPGA Trang 106
Phần C: Phụ lục và tài liệu tham khảo
PORT(
clk : in std_logic;
reset : in std_logic;
start : in std_logic;
dec_in : in std_logic;
sel_dec: in std_logic;
data : in std_logic_vector (V*N-1 downto 0);
data_out: out std_logic_vector (V-1 downto 0);
conv_in: in std_logic_vector(V-1 downto 0);
conv_out: out std_logic_vector(V*N-1 downto 0)
);
END viterbi;
ARCHITECTURE rtl OF viterbi IS
TYPE matrix_1 is array (0 to 3, 0 to 1) of std_logic_vector(3 downto 0);
TYPE matrix_2 is array (0 to 3, 0 to 10) of integer ;
TYPE matrix_3 is array (0 to 3, 0 to 1) of integer;
TYPE matrix_4 is array (0 to 8) of integer;
TYPE matrix_7 is array (0 to 7) of std_logic_vector (1 downto 0);
TYPE matrix_8 is array (0 to 3, 0 to 10) of integer;
TYPE matrix_9 is array (0 to 10) of integer;
SIGNAL data_in : matrix_7;
SIGNAL ne_st_reg: matrix_1;
BEGIN
---------------------------------------------------------------------------------
-- the firt part is get data input
---------------------------------------------------------------------------------
get_data_in: PROCESS(dec_in,reset,sel_dec)
VARIABLE v2: integer;
BEGIN
IF reset = '0' THEN v2: = 0;
ELSIF dec_in = '1' THEN
FOR v2 in 0 to 7 LOOP
data_in(7-v2) <= data(v2*2+1 downto v2*2);
END LOOP;
END IF;
END PROCESS;
-------------------------------------------------------------------------------
-- The second part is to initialize the next state
--------------------------------------------------------------------------------
next_state_out_reg: PROCESS(reset)
VARIABLE lp1: std_logic_vector(1 downto 0);
Thực hiện bộ giải mã Viterbi trên FPGA Trang 107
Phần C: Phụ lục và tài liệu tham khảo
VARIABLE lp2: std_logic;
VARIABLE l1,l2,l3: integer;
BEGIN
IF reset = '0' THEN
lp1: = "00";
lp2: = '0';
ELSE
FOR l1 in 0 to 3 LOOP
FOR l2 in 0 to 1 LOOP
lp1: = conv_std_logic_vector(l1,2);
IF l2=0 THEN
lp2: = '0';
ELSE
lp2: = '1';
END IF;
-- next state and output bits
ne_st_reg(l1,l2) <= lp2&lp1(1)&(lp2 xor lp1(0))&(lp2 xor lp1(1) xor lp1(0));
END LOOP;
END LOOP;
END IF;
END PROCESS;
-------------------------------------------------------------------------------
-- The third part is calculate Hamming distance
--------------------------------------------------------------------------------
Hd_calculation: PROCESS(clk,start)
VARIABLE pre_state_reg: matrix_2; -- previous states for trace back
VARIABLE aem_reg : matrix_3; -- aem
VARIABLE ssa_reg: matrix_4; -- trace back
VARIABLE result : std_logic_vector(V-1 downto 0);
VARIABLE ac_reg : matrix_8; -- accumalated metric table
VARIABLE sv_reg : matrix_9; -- survier path register
VARIABLE cnt : integer: =0; -- internal cuonter
VARIABLE flag : std_logic: = '0';
VARIABLE dist_00, dist_01, dist_10, dist_11: integer;
VARIABLE v3: integer: =0;
VARIABLE t1: std_logic_vector (1 downto 0);
VARIABLE t3,t4: integer range 0 to 3;
VARIABLE l1,l2,l3: integer;
VARIABLE dec_en: std_logic: = '0';
BEGIN
IF reset = '0' THEN v3: = 0; cnt: = 0;
Thực hiện bộ giải mã Viterbi trên FPGA Trang 108
Phần C: Phụ lục và tài liệu tham khảo
ELSIF start = '1' THEN
IF Rising_edge(clk) THEN
-- cnt is a counter to count terllics diagrame to tell us which step now
cnt: = cnt + 1;
IF cnt = 10 THEN
cnt: = 0;
END IF;
-- This part is to calculate Hamming distance or Euclidean distance
IF sel_dec = '1' THEN -- Euclidean
dist_00: = euclid(data_in(cnt-1),"00");
dist_01: = euclid(data_in(cnt-1),"01");
dist_10: = euclid(data_in(cnt-1),"10");
dist_11: = euclid(data_in(cnt-1),"11");
ELSE -- Hamming
dist_00: = hamming(data_in(cnt-1),"00");
dist_01: = hamming(data_in(cnt-1),"01");
dist_10: = hamming(data_in(cnt-1),"10");
dist_11: = hamming(data_in(cnt-1),"11");
END IF;
------------------------------------------------
-- This is ACS block
-------------------------------------------------
-- This is Branch Metric Unit
CASE cnt is
WHEN 0 =>
FOR l1 in 0 to 3 LOOP
aem_reg(l1,0): = 0;
aem_reg(l1,1): = 0;
FOR l2 in 0 to 8 LOOP
ac_reg(l1,l2): = 0;
END LOOP;
END LOOP;
WHEN 1 =>
ac_reg(0,1): = dist_00 ;
ac_reg(2,1): = dist_11 ;
pre_state_reg(0,1): = 0;
pre_state_reg(2,1): = 0;
WHEN 2 =>
ac_reg(0,2): = dist_00 + ac_reg(0,1);
ac_reg(1,2): = dist_01 + ac_reg(2,1);
ac_reg(2,2): = dist_11 + ac_reg(0,1);
Thực hiện bộ giải mã Viterbi trên FPGA Trang 109
Phần C: Phụ lục và tài liệu tham khảo
ac_reg(3,2): = dist_10 + ac_reg(2,1);
pre_state_reg(0,2): = 0;
pre_state_reg(2,2): = 0;
pre_state_reg(1,2): = 2;
pre_state_reg(3,2): = 2;
WHEN others =>
aem_reg(0,0): = dist_00 + ac_reg(0,cnt-1);
aem_reg(2,0): = dist_11 + ac_reg(0,cnt-1);
aem_reg(1,0): = dist_01 + ac_reg(2,cnt-1);
aem_reg(3,0): = dist_10 + ac_reg(2,cnt-1);
aem_reg(0,1): = dist_11 + ac_reg(1,cnt-1);
aem_reg(2,1): = dist_00 + ac_reg(1,cnt-1);
aem_reg(1,1): = dist_10 + ac_reg(3,cnt-1);
aem_reg(3,1): = dist_01 + ac_reg(3,cnt-1);
END CASE;
--The following part compare each 2 possible path and select
-- a small one and write the survival path to the survival path register.
IF (cnt >= 3) and (cnt <= 8) THEN
FOR l1 in 0 to 3 LOOP
t1: = conv_std_logic_vector(l1,2);
IF aem_reg(l1, 0) <= aem_reg(l1, 1) THEN
ac_reg(l1,cnt): = aem_reg(l1, 0);
pre_state_reg(l1,cnt): = conv_int(t1(0) & '0');
ELSE
ac_reg(l1,cnt): = aem_reg(l1, 1);
pre_state_reg(l1,cnt): = conv_int(t1(0) & '1');
END IF;
END LOOP;
END IF;
-- This is the trace back part which finds the Most Likelihood Path
IF cnt = 9 THEN
sv_reg(0): = 0; -- 0 is allway the first step
IF ac_reg(0,1) < ac_reg(2,1) THEN -- the second step
sv_reg(1): = 0;
ELSIF ac_reg(0,1) > ac_reg(2,1) THEN
sv_reg(1): = 2;
ELSE -- compare the third step
IF ac_reg(0,2) <= ac_reg(2,2) THEN
l2: = ac_reg(0,2);
ELSE
l2: = ac_reg(2,2);
Thực hiện bộ giải mã Viterbi trên FPGA Trang 110
Phần C: Phụ lục và tài liệu tham khảo
END IF;
IF ac_reg(1,2) <= ac_reg(3,2) THEN
l3: = ac_reg(1,2);
ELSE
l3: = ac_reg(3,2);
END IF;
IF l2 <= l3 THEN
sv_reg(1): = 0;
ELSE
sv_reg(1): = 2;
END IF;
END IF;
FOR l1 in 2 to 8 LOOP
IF ac_reg(0,l1) <= ac_reg(1,l1) THEN
l2: = ac_reg(0,l1);
ELSE
l2: = ac_reg(1,l1);
END IF;
IF ac_reg(2,l1) <= ac_reg(3,l1) THEN
l3: = ac_reg(2,l1);
ELSE
l3: = ac_reg(3,l1);
END IF;
IF l2 < l3 THEN
IF ac_reg(0,l1) <= ac_reg(1,l1) THEN
sv_reg(l1): = 0;
ELSE
SV_reg(l1): = 1;
END IF;
ELSIF l2 > l3 THEN
ac_reg(2,l1) <= ac_reg(3,l1) THEN
sv_reg(l1): = 2;
ELSE
sv_reg(l1): = 3;
END IF;
ELSE
IF ac_reg(0,l1+1) <= ac_reg(1,l1+1) THEN
l2: = ac_reg(0,l1+1);
ELSE
l2: = ac_reg(1,l1+1);
END IF;
Thực hiện bộ giải mã Viterbi trên FPGA Trang 111
Phần C: Phụ lục và tài liệu tham khảo
IF ac_reg(2,l1+1) <= ac_reg(3,l1+1) THEN
l3: = ac_reg(2,l1+1);
ELSE
l3: = ac_reg(3,l1+1);
END IF;
IF l2 <= l3 THEN
IF ac_reg(0,l1+1) <= ac_reg(1,l1+1) THEN
sv_reg(l1): = pre_state_reg(0,l1+1);
ELSE
SV_reg(l1): = pre_state_reg(1,l1+1);
END IF;
ELSIF l2 > l3 THEN
IF ac_reg(2,l1+1) <= ac_reg(3,l1+1) THEN
sv_reg(l1): = pre_state_reg(2,l1+1);
ELSE
sv_reg(l1): = pre_state_reg(3,l1+1);
END IF;
END IF;
END IF;
IF l1 = 8 THEN flag: = '1';
ELSE flag: = '0';
END IF;
END LOOP;
END IF;
-----------------------------------------------------------------------
-- when the flag is one, it means the TB part is done.
-- Then the decoder begins to decode the data
IF flag = '1' THEN
FOR l1 in 0 to 7 LOOP
t3: = sv_reg(l1);
t4: = sv_reg(l1+1);
IF t4 = conv_int(ne_st_reg(t3, 0)(3 downto 2)) THEN
result(l1): = '0';
ELSIF t4 = conv_int(ne_st_reg(t3, 1)(3 downto 2)) THEN
result(l1): = '1';
END IF;
END LOOP;
END IF;
END IF;
FOR l1 in 0 to 7 LOOP
data_out(l1) <= result(7-l1);
Thực hiện bộ giải mã Viterbi trên FPGA Trang 112
Phần C: Phụ lục và tài liệu tham khảo
END LOOP;
IF l1 = 7 THEN dec_en: = '1';
END IF;
END IF;
END PROCESS;
-------------------------------------------------------------------------
-- This part is show convolution processor.
Convolution: PROCESS(clk,reset)
VARIABLE conv_out_v: std_logic_vector(15 downto 0);
VARIABLE ff: std_logic_vector(2 downto 0):="000";
VARIABLE i: integer: = 8;
VARIABLE j: integer: = 15;
BEGIN
IF reset = '0' THEN i:= 8; j: = 15;
ELSIF Rising_edge(clk) THEN
IF i > 0 THEN
ff: = ff(1 downto 0) & conv_in(i-1) ;
conv_out_v(j): = ff(0) xor ff(2);
conv_out_v(j-1): = ff(0) xor ff(1) xor ff(2);
END IF;
j: = j-2;
i: = i-1 ;
END IF;
IF i = 0 THEN
conv_out <= conv_out_v(15 downto 0) ;
END IF;
END PROCESS;
END ARCHITECTURE rtl;
CONVERTER.VHD
LIBRARY IEEE;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;
PACKAGE converter IS
FUNCTION conv_std_logic(gt_v: in INTEGER; sl_v: in INTEGER)
RETURN std_logic_vector;
FUNCTION conv_int(gt_i: in std_logic_vector(1 downto 0)) RETURN
integer;
END converter;
Thực hiện bộ giải mã Viterbi trên FPGA Trang 113
Phần C: Phụ lục và tài liệu tham khảo
PACKAGE BODY converter IS
FUNCTION conv_std_logic(gt_v,sl_v: integer) RETURN std_logic_vector
IS
VARIABLE i_v: integer range 0 to (gt_v - 1): = 0;
VARIABLE u_v: std_logic_vector(sl_v downto 0);
BEGIN
IF gt_v /= 0 THEN
FOR i in 0 to (gt_v - 1) LOOP
u_v: = u_v + 1;
END LOOP;
END IF;
RETURN u_v;
END conv_std_logic;
FUNCTION conv_int(gt_i: in std_logic_vector(1 downto 0)) RETURN
integer IS
VARIABLE i_i, u_i: integer;
BEGIN
CASE gt_i IS
WHEN "00" => i_i: = 0;
WHEN "01" => i_i: = 1;
WHEN "10" => i_i: = 2;
WHEN others => i_i: = 3;
END CASE;
RETURN i_i;
END conv_int;
END converter;
DISTANCE.VHD
LIBRARY IEEE;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;
USE work.converter.all;
PACKAGE distance IS
FUNCTION hamming(i1,i2: in std_logic_vector(1 downto 0)) RETURN
integer;
FUNCTION euclid(e1,e2: in std_logic_vector(1 downto 0)) RETURN
integer;
END distance;
PACKAGE BODY distance IS
Thực hiện bộ giải mã Viterbi trên FPGA Trang 114
Phần C: Phụ lục và tài liệu tham khảo
FUNCTION hamming(i1,i2: in std_logic_vector(1 downto 0)) RETURN
integer IS
VARIABLE result: integer: = 0;
VARIABLE u: std_logic_vector(1 downto 0);
BEGIN
IF i1(0) > '0' THEN
u(0): = '1';
ELSE
u(0): = '0';
END IF;
IF i1(1) > '0' THEN
u(1): = '1';
ELSE
u(1): = '0';
END IF;
IF u(0) = i2(0) THEN
result: = 0;
ELSE
result: = result + 1;
END IF;
IF u(1) = i2(1) THEN
result: = result;
ELSE
result: = result + 1;
END IF;
RETURN result;
END hamming;
END distance;
DISPLAY.VHD
LIBRARY ieee;
USE ieee.std_logic_1164.all;
package display_types is
type display_mode is ( name, information,author, inoutbit, bits);
end package display_types;
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE work.display_types.all;
USE work.lcd_types.all;
package display_components is
Thực hiện bộ giải mã Viterbi trên FPGA Trang 115
Phần C: Phụ lục và tài liệu tham khảo
component display is
PORT (
reset, clock: IN STD_LOGIC;
SW : IN std_logic_vector(17 downto 0);
DATA_OUT: IN std_logic_vector(7 downto 0);
mode: IN display_mode;
lcd_dd: OUT CHAR_VECTOR(0 to 31)
);
end component;
end package;
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
USE work.display_types.all;
USE work.lcd_types.all;
USE work.lcd_conv.all;
ENTITY display IS
PORT (
reset, clock: IN STD_LOGIC;
SW : IN std_logic_vector(17 downto 0);
DATA_OUT: IN std_logic_vector(7 downto 0);
mode: IN display_mode;
lcd_dd: OUT CHAR_VECTOR(0 to 31)
);
END ENTITY display;
ARCHITECTURE display OF display IS
SIGNAL A: char: = x"41";SIGNAL B: char: = x"42";
SIGNAL C: char: = x"43";SIGNAL D: char: = x"44";
SIGNAL E: char: = x"45";SIGNAL F: char: = x"46";
SIGNAL G: char: = x"47";SIGNAL H: char: = x"48";
SIGNAL I: char: = x"49";SIGNAL J: char: = x"4A";
SIGNAL K: char: = x"4B";SIGNAL L: char: = x"4C";
SIGNAL M: char: = x"4D";SIGNAL N: char: = x"4E";
SIGNAL O: char: = x"4F";SIGNAL P: char: = x"50";
SIGNAL Q: char: = x"51";SIGNAL R: char: = x"52";
SIGNAL S: char: = x"53";SIGNAL T: char: = x"54";
SIGNAL U: char: = x"55";SIGNAL V: char: = x"56";
SIGNAL W: char: = x"57";SIGNAL X: char: = x"58";
SIGNAL Y: char: = x"59";SIGNAL Z: char: = x"5A";
Thực hiện bộ giải mã Viterbi trên FPGA Trang 116
Phần C: Phụ lục và tài liệu tham khảo
SIGNAL s1: char: = x"31";SIGNAL s6: char: = x"36";
SIGNAL s2: char: = x"32";SIGNAL s7: char: = x"37";
SIGNAL s3: char: = x"33";SIGNAL s8: char: = x"38";
SIGNAL s4: char: = x"34";SIGNAL s9: char: = x"39";
SIGNAL s5: char: = x"35";SIGNAL s0: char: = x"30";
SIGNAL KT: char: = x"20"; -- KHOANG TRONG
BEGIN
-- the first row
with mode select lcd_dd(0 to 15) <=
-- DH SPKT TP HCM
(KT,D,H,KT,S,P,K,T,KT,T,P,KT,H,C,M,KT) when information,
-- GIAI THUAT
(KT,KT,G,I,A,I,KT,KT,T,H,U,A,T,KT,KT,KT) when name,
--SVTH LE DUY
(S,V,T,H,KT,KT,L,E,KT,D,U,Y,KT,KT,KT,KT) when author,
--16 BITS VAO
(s1,s6,KT,B,I,T,S,KT,V,A,O,KT,KT,KT,KT,KT) when inoutbit,
-- hien thi 16 bitS vao
(b162slv(SW(15 downto 0))) when bits;
-- the second row
with mode select lcd_dd(16 to 31) <=
--DO AN TOT NGHIEP
(D,O,KT,A,N,KT,T,O,T,KT,N,G,H,I,E,P) when information,
-- VITERBI
(KT,KT,KT,KT,V,I,T,E,R,B,I,KT,KT,KT,KT,KT) when name,
-- HUYNH MINH KHA
(KT,H,U,Y,N,H,KT,M,I,N,H,KT,K,H,A,KT) when author,
--8 BIT RA
(s8,KT,B,I,T,S,KT,R,A,KT,KT,KT,KT,KT,KT,KT) when inoutbit,
-- hien thi 8 bits ra
(b82slv(DATA_OUT(7 downto 0))) when bits;
END ARCHITECTURE display;
LCD.VHD
library ieee;
use ieee.std_logic_1164.all;
package lcd_types is
subtype char is std_logic_vector(7 downto 0);
type char_vector is array(natural range ) of char;
end package lcd_types;
library ieee;
Thực hiện bộ giải mã Viterbi trên FPGA Trang 117
Phần C: Phụ lục và tài liệu tham khảo
use ieee.std_logic_1164.all;
use work.lcd_types.all;
package lcd_components is
component lcd is
port(
reset, clock: IN STD_LOGIC;
dd: IN CHAR_VECTOR(0 to 31);
LCD_ON: OUT STD_LOGIC;
LCD_BLON: OUT STD_LOGIC;
LCD_RW: OUT STD_LOGIC;
LCD_EN: OUT STD_LOGIC;
LCD_RS: OUT STD_LOGIC;
LCD_DATA: INOUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
end component lcd;
end package lcd_components;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use work.lcd_types.all;
ENTITY lcd IS
PORT(
reset, clock: IN STD_LOGIC;
dd: IN CHAR_VECTOR(0 to 31);
LCD_ON: OUT STD_LOGIC;
LCD_BLON: OUT STD_LOGIC;
LCD_RW: OUT STD_LOGIC;
LCD_EN: OUT STD_LOGIC;
LCD_RS: OUT STD_LOGIC;
LCD_DATA: INOUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END ENTITY lcd;
ARCHITECTURE lcd of lcd is
SIGNAL wait_counter: INTEGER: = 0;
SIGNAL timing_counter: INTEGER: = 0;
TYPE timing_states IS (idle, setup, hold);
SIGNAL timing_state: timing_states: = idle;
TYPE timing_modes IS (idle, read_cmd, read_data, write_cmd, write_data);
SIGNAL timing_mode: timing_modes: = idle;
SIGNAL timing_done: STD_LOGIC: = '1';
Thực hiện bộ giải mã Viterbi trên FPGA Trang 118
Phần C: Phụ lục và tài liệu tham khảo
CONSTANT init_cmds_count: INTEGER: = 4;
CONSTANT init_cmds: CHAR_VECTOR(0 to init_cmds_count - 1): = (
x"38", -- set up interface
x"0C", -- set up display
x"01", -- clear screen
x"06" -- set up entry mode
);
CONSTANT init_cmds_wait: INTEGER: = 100000; -- wait 2 ms for each
init command
TYPE states IS (
init,
init_cmd,
init_cmd_complete,
update_dd,
update_dd_addr,
update_dd_addr_complete,
update_dd_data,
update_dd_data_complete
);
SIGNAL state: states: = init;
SIGNAL i, j: INTEGER: = 0;
BEGIN
LCD_ON <= '1';
LCD_BLON <= '1';
timing: PROCESS(clock, reset) IS
BEGIN
IF (reset = '1') THEN
timing_state <= idle;
timing_counter <= 0;
timing_done <= '1';
ELSIF (clock = '1' AND clock'event) THEN
IF (timing_counter > 0) THEN
timing_counter <= timing_counter - 1;
ELSE
CASE timing_state IS
WHEN idle =>
CASE timing_mode IS
WHEN idle =>
LCD_RS <= '0';
LCD_RW <= '1';
timing_done <= '1';
Thực hiện bộ giải mã Viterbi trên FPGA Trang 119
Phần C: Phụ lục và tài liệu tham khảo
timing_state <= idle;
WHEN read_cmd =>
LCD_RS <= '0';
LCD_RW <= '1';
timing_done <= '0';
timing_counter <= 3;
timing_state <= setup;
WHEN read_data =>
LCD_RS <= '1';
LCD_RW <= '1';
timing_done <= '0';
timing_counter <= 3;
timing_state <= setup;
WHEN write_cmd =>
LCD_RS <= '0';
LCD_RW <= '0';
timing_done <= '0';
timing_counter <= 3;
timing_state <= setup;
WHEN write_data =>
LCD_RS <= '1';
LCD_RW <= '0';
timing_done <= '0';
timing_counter <= 3;
timing_state <= setup;
END CASE;
WHEN setup =>
LCD_EN <= '1';
timing_counter <= 30;
timing_state <= hold;
WHEN hold =>
LCD_EN <= '0';
timing_counter <= 3000; -- a 60 microsecond wait
guarantees operation execution
timing_state <= idle;
WHEN others =>
timing_state <= idle;
END CASE;
END IF;
END IF;
END PROCESS;
Thực hiện bộ giải mã Viterbi trên FPGA Trang 120
Phần C: Phụ lục và tài liệu tham khảo
fsm: PROCESS(clock, reset) IS
BEGIN
IF (reset = '1') THEN
timing_mode <= idle;
state <= init;
ELSIF (clock = '1' AND clock'event) THEN
IF (timing_mode /= idle) THEN
timing_mode <= idle;
ELSIF (timing_done /= '1') THEN
ELSIF (wait_counter > 0) THEN
wait_counter <= wait_counter - 1;
ELSE
CASE state IS
WHEN init =>
i <= 0;
timing_mode <= idle;
wait_counter <= init_cmds_wait;
state <= init_cmd;
WHEN init_cmd =>
LCD_DATA <= init_cmds(i);
timing_mode <= write_cmd;
wait_counter <= init_cmds_wait;
state <= init_cmd_complete;
WHEN init_cmd_complete =>
IF (i = init_cmds_count - 1) THEN
state <= update_dd; -- sai
ELSE
i <= i + 1;
state <= init_cmd;
END IF;
WHEN update_dd => -- hien thi lcd 16X2
i <= 0;
j <= 0;
state <= update_dd_addr;
WHEN update_dd_addr =>
LCD_DATA <= "1" & std_logic_vector(to_unsigned(i,
1)) & "00" & std_logic_vector(to_unsigned(j, 4));
timing_mode <= write_cmd;
state <= update_dd_addr_complete;
WHEN update_dd_addr_complete =>
state <= update_dd_data;
Thực hiện bộ giải mã Viterbi trên FPGA Trang 121
Phần C: Phụ lục và tài liệu tham khảo
WHEN update_dd_data =>
LCD_DATA <= dd(i * 16 + j);
timing_mode <= write_data;
state <= update_dd_data_complete;
WHEN update_dd_data_complete =>
IF (j = 15) THEN
IF (i = 1) THEN
state <= update_dd; -- quay lai lam lai
ELSE
j <= 0;
i <= i + 1;
state <= update_dd_addr;
END IF;
ELSE
j <= j + 1;
state <= update_dd_addr;
END IF;
WHEN others =>
state <= init;
END CASE;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE lcd;
LCD_CONV.VHD
LIBRARY ieee;
USE ieee.std_logic_1164.all;
PACKAGE lcd_conv_type is
TYPE out_vector is array (0 to 15 ) of std_logic_vector(7 downto 0);
END PACKAGE lcd_conv_type;
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;
USE work.lcd_types.all;
USE work.lcd_conv_type.all;
PACKAGE lcd_conv IS
Thực hiện bộ giải mã Viterbi trên FPGA Trang 122
Phần C: Phụ lục và tài liệu tham khảo
FUNCTION b162slv(bin: in std_logic_vector(15 downto 0)) RETURN
char_vector;
FUNCTION b82slv(bin: in std_logic_vector(7 downto 0)) RETURN
char_vector;
END lcd_conv;
PACKAGE BODY lcd_conv IS
FUNCTION b162slv(bin: in std_logic_vector(15 downto 0)) RETURN char_vector
IS
VARIABLE slv: char_vector (15 downto 0) ;
VARIABLE t: integer;
BEGIN
FOR t in 0 to 15 LOOP
CASE bin(t) IS
WHEN '0' => slv(t): = x"30"; -- 0
WHEN others => slv(t): = x"31"; -- 1
END CASE;
END LOOP;
RETURN slv;
END b162slv;
FUNCTION b82slv(bin: in std_logic_vector(7 downto 0)) RETURN char_vector IS
VARIABLE slv: char_vector (15 downto 0);
VARIABLE t: integer;
BEGIN
FOR t in 0 to 7 LOOP
CASE bin(t) IS
WHEN '0' => slv(t+4): = x"30";
WHEN others => slv(t+4): = x"31";
END CASE;
END LOOP;
FOR t in 0 to 3 LOOP
slv(t): = x"20"; -- khoang trang
END LOOP;
FOR t in 12 to 15 LOOP
slv(t): = x"20"; -- khoang trang
END LOOP;
RETURN slv;
END b82slv;
END lcd_conv;
Thực hiện bộ giải mã Viterbi trên FPGA Trang 123
Phần C: Phụ lục và tài liệu tham khảo
II. Tài liệu tham khảo
[1] John Proakis, Digital Communications (Chapter 8-Block and Convolutional
Channel Codes), McGraw-Hill Science/ Engineering/ Math, 4
th
, 2000.
[2] Fu Hua Huang, Evaluation of Soft Output Decoding for Turbo
Codes(chapter 2_convolution codes), Master's Thesis, 1997.
[3] Mr. Chip Fleming, Tutorial on Convolutional Coding with Viterbi
Decoding, Spectrum Applications, 2006.
[4] Wei Chen, RTL implementation of Viterbi decoder, Master’s thesis
performed in Computer Engineering, 2006.
[5] Nguyễn Minh Khánh Ngọc, Luận văn cao học “Thiết kế và thực hiện gải
thuật Viterbi trên FPGA”, 2009.
[6] Một số trang web mà nhóm có tham khảo:
Các file đính kèm theo tài liệu này:
- thuc_hien_bo_giai_ma_viterbi_tren_fpga_5725.pdf