Cùng với sự phát triển của khoa học và công nghệ phục vụ chocuộc sống của con người, công nghệ viễn thông trong những năm qua đã có nhữngbước phát triển mạnh mẽ cung cấp ngày càng nhiều tiện ích cho con người.
Thế kỷ 21 chứng kiến sự bùng nổ thôngtin, trong đó thông tin di động đóng một vai trò rất quan trọng. Nhu cầu traođổi thông tin ngày càng tăng cả về số lượng, chất lượng và các loại hình dịchvụ kèm theo, điều này đòi hỏi phải tìm ra phương thức trao đổi thông tin mớingày càng ưu việt và mang lại hiệu quả cao hơn. Các công nghệ di động và viễnthông ngày một phát triển nhanh chóng để hướng tới mục đích tăng tốc độ cũngnhư chất lượng của các dịch vụ nhằm đáp ứng nhu cầu ngày càng cao của con ngườivề các thiết bị không dây bỏ túi.
Một trong những khâu quan trọng nhấtcủa việc thông tin không dây đó là việc truyền và nhận tín hiệu. Điều này cần thiết phải có một loại mã hóa dànhriêng cho kênh truyền có khả năng sửa chữa sai sót của tín hiệu truyền đi docác tác động của môi trường. Các hình thức được sử dụng để mã hóa kênh truyềntrước đó đều có những khuyết điểm nhất định trong việc khôi phục dữ liệu bị saisót trên đường truyền, thường chỉ có khả năng phát hiện lỗi và báo về bên phátđể thực hiện truyền lại tin tức bị sai đó. Điều này làm chậm quá trình truyềntin tức. Bộ mã hóa dùng mã chập và thuật giải mã Viterbi là một chuẩn đang đượcứng dụng rất rộng rãi trên toàn thế giới với nhiều ưu điểm vượt trội so với cáchình thức trước đó, ngoài khả năng phát hiện lỗi tốt nhờ sự kiểm soát chặt chẽtin tức truyền đi, nó còn có khả năng tự khôi phục các tin tức bị sai trong quátrình truyền trên kênh truyền. Điều này giúp giảm thiểu tối đa thời gian truyềnnhận tin tức, do đó tốc độ dữ liệu ngày một được nâng cao. Tuy vẫn còn một sốhạn chế nhất định trong việc khôi phục các đoạn tin tức sai hàng loạt, nhưngthuật toán Viterbi vẫn là sự lựa chọn ưu tiên và là nền tảng cho việc pháttriển các hình thức mã hóa và giải mã tốt hơn nữa hiện tại và sau này.
Vì những ưu điểm nổi bật và tính ứngdụng cao của thuật toán này trong hiện tại và tương lai của ngành viễn thông,nhóm thực hiện quyết định chọn đề tài là “Thực hiện bộ giải mã Viterbi trênFPGA”. Trong phạm vi của cuốn đồ án này, nhóm thực hiện đề tài sẽ giới thiệukhái quát về hai hình thức mã hóa và giải mã này và tiến hành mô phỏng thuậttoán mã hóa và giải mã đó trên Matlab cũng như mô tả phần cứng trên kit DE2 củaAltera.
Nội dung của đồ án sẽ bao gồm các vấnđề sau:
· Chương 1: Tổng quan về hệ thống thông tin số
Giới thiệu về vị trí vai trò của mã hóa kênh truyềntrong 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.
· Chương 2: Thuật toán Viterbi
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. Giới thiêu thuật toán giảimã Viterbi, nguyên lý thực hiện giải mã và phân loại một số phương pháp giảimã.
· Chương 3: Xây dựng thuật giải Viterbi dùng Matlab
Tiến hành đi mô phỏng thuật toán mã hóa mã chập vàthuật toán giải mã Viterbi. Phân tích thuật toán
· Chương 4: Xây dựng thuật giải Viterbi trên kit DE2
Mô phỏng thuật toán thực tế hơn trên kit DE2 với cácled hiển thị dữ liệu từ đó thấy được hiệu quả của thuật toán Viterbi, ứng dụngngôn ngữ thiết kế phần cứng VHDL
· Chương 5: Kết luận
Đánh giá kết quả thực hiện của đồ ánvà đưa ra phương hướng phát triển của đề tài trong tương lai.
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
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
                
              
                                            
                                
            
 
            
                 124 trang
124 trang | 
Chia sẻ: lvcdongnoi | Lượt xem: 3159 | Lượt tải: 0 
              
            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:
 DO AN TN_DUY_KHA .pdf DO AN TN_DUY_KHA .pdf
 Mo phong Matlab.rar Mo phong Matlab.rar