Thực hiện bộ giải mã viterbi trên fpga

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

pdf124 trang | Chia sẻ: banmai | Lượt xem: 2049 | Lượt tải: 3download
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:

  • pdfthuc_hien_bo_giai_ma_viterbi_tren_fpga_5725.pdf