KOMPRESI CITRA JPEG BERBASIS FPGA XILINX SPARTAN-3E Tesis untuk memenuhi sebagian persyaratan mencapai derajat sarjana S-2 Program Studi Teknik Elektro Jurusan Ilmu-ilmu Teknik
diajukan oleh: Enas Dhuhri Kusuma 07/260190/PTK/4715
Kepada PROGRAM PASCASARJANA FAKULTAS TEKNIK UNIVERSITAS GADJAH MADA YOGYAKARTA 2010
TESIS KOMPRESICITRA JPEGBERBASISFPGA XILINX SPARTAN-3E dipersiapkandandisusunoleh EnasDhuhri Kusuma 07/260199{PTW04715 Telahdipertatrankandi depanDewanPenguji Padatanggal25Mei 2010 SusirnilnDewm Pengiji AnggotaDewanPengujiLain
PembimbingUtama
M
Prof.Dr. Ir. ThomasSri Widodo.DEA
Tesisini telah diterima sebagaisalahsatupersyaratan untuk memperolehgelar Magister Tanggal14Juni2010 PengelolaProgramStudi : Teknik Elektro
M.Sc..Ph.D. k. P.InsapSantosa. NrP. I 96101081 985031002
Wakil
Studi Teknik Elektro
t99103t002 NIP. r 9660327
PBRNYATAAN
Dengan ini saya menyatakan bahwa dalam tesis ini tidak terdapat karya yang pernah diajukan untuk memperoleh gelar kesarjanaandi suatu PerguruanTinggi, dan sepanjang pengetahuan saya juga tidak terdapat karya atau pendapat yang pemah ditulis atau diterbitkan oleh orang lain, kecuali yang secara tertulis diacu dalam naskah ini dan disebutkandalam daftar pustaka
10M ei 2010
iv
HALAMAN PERSEMBAHAN
Tesis ini Penulis persembahkan untuk : 5 Ummu Fida
5 The Special One, Mufida 5 Bapak/Ibu Asyhuri 5 Nidjar, the skinny
v
PRAKATA
Sungguh suatu anugerah yang luar biasa, sehingga Tesis dengan judul “Kompresi Citra
JPEG Berbasis FPGA Spartan-3E“ ini akhirnya dapat Penulis susun dan selesaikan. Segala puji bagi Allah SWT atas segala rahmat dan hidayah yang senantiasa tercurah. Tesis ini disusun untuk memenuhi salah satu syarat untuk menyelesaikan program pendidikan S-2 di Program Studi Teknik Elektro, Jurusan Ilmu-ilmu Teknik, Program Pascasarjana Universitas Gadjah Mada, Jogjakarta. Pada kesempatan ini, dengan segala keikhlasan dan kerendahan hati, Penulis menyampaikan banyak terima kasih kepada: 1. Bapak Prof. Dr. Ir. Thomas Sri Widodo, DEA., Selaku Pembimbing Utama yang telah banyak meluangkan waktu, memberikan banyak perhatian dan arahan yang tegas serta warna yang lain dalam pembimbingan dari awal hingga akhir sehingga Penulis mempunyai pemahaman dunia elektro yang baru. 2. Bapak Dr. Ir. P. Insap Santosa M.Sc., Bapak Dr. Ir. Risanuri Hidayat M.Sc., dan Ir. Litasari, M.Sc, selaku pengelola Program Studi Teknik Elektro, Jurusan Ilmu-ilmu Teknik, Program Pascasarjana Universitas Gadjah Mada. 3. Bapak Ir. Wahyu Dewanto, MT selaku Pembimbing Pendamping dengan kesabarannya dalam membantu dan memberikan saran dalam proses pembuatan tesis ini. 4. Isteriku tercinta, Wina Ummu Fida dan the special one Mufida yang manis dan cerdas, atas dukungannya yang riil dan setia. 5. Ibu/Bapakku Asyhuri yang senantiasa mengiringi setiap langkahku dengan do’a dan kasihnya. Ibu/Bapak Mertua dan keluarga di Sukabumi atas do’a dan pengertiannya. 6. Adikku Nidjar atas segala dukungan yang diberikan.
vi 7. Dr. Ir. Tumiran, Ph.D, selaku pribadi, sesepuh dan selaku Dekan FT Universitas Gadjah Mada. 8. Dr. Ir. Lukito Edi Nugroho, M.Sc., selaku Ketua Jurusan Teknik Elektro dan Teknologi Informasi atas segala kebijakannya. 9. Ir. Bambang Sutopo M.Phil., atas ide-idenya dan perkenalan tentang FPGA terhadap penulis 10. Semua pihak yang ikut membantu terselesaikannya tesis ini, yang tak sempat tersebutkan namanya. Semoga Allah SWT memberikan rahmat dan karunia yang berlipat ganda atas segala bimbingan, bantuan dan motivasinya. Penulis menyadari bahwa tesis ini masih banyak kekurangan. Namun demikian semoga dapat memberikan manfaat yang besar bagi pengembangan ilmu pengetahuan dan teknologi.
Jogjakarta, 10 Mei 2010 Penulis
Enas Dhuhri Kusuma
vii DAFTAR ISI halaman HALAMAN JUDUL.......................................................................................... i HALAMAN PENGESAHAN............................................................................ ii HALAMAN PERNYATAAN.............................................................................. iii HALAMAN PERSEMBAHAN.......................................................................... iv PRAKATA............................................................................................................ v DAFTAR ISI...................................................................................................... vii DAFTAR GAMBAR …..................................................................................... x DAFTAR TABEL ….......................................................................................... xii INTISARI........................................................................................................... xv ABSTRACT …................................................................................................... xvi I. PENDAHULUAN …....................................................................................... 1 1.1. Latar Belakang …........................................................................ 1 1.2. Tujuan Penelitian …..................................................................... 5 II. TINJAUAN PUSTAKA DAN DASAR TEORI …........................................ 6 2.1. Kajian Pustaka …......................................................................... 6 2.2. Dasar Teori ….............................................................................. 9 2.2.1 Kompresi Citra Berbasis DCT …......................................... 9 2.2.2. Kompresi Citra Baseline JPEG …....................................... 15 2.2.3. FPGA (Field Programmable Gate Array) XCS500E …...... 21 2.3. Hipotesis ….................................................................................. 23 III. METODA PENELITIAN …......................................................................... 25 3.1. Bahan Penelitian …...................................................................... 25 3.2. Alat Penelitian …......................................................................... 25
viii 3.3. Jalan Penelitian …....................................................................... 25 3.3.1. Perancangan sistem secara global …....................................26 3.3.2. Perancangan algoritma dan modul DCT 1 D ….................. 28 3.3.3. Perancangan pipeline modul DCT-1D …............................ 30 3.3.4. Aritmatika komputasi DCT-1D …....................................... 36 3.3.5. Perancangan DCT-2D …..................................................... 39 3.3.6. Perancangan Transpose Buffer …....................................... 40 3.3.7. Perancangan Pengendali DCT-2D ….................................. 42 3.3.8. Unit Zigzag …..................................................................... 44 3.3.9. Perancangan Quantizer….................................................... 45 3.3.10. Penanda nilai DC…............................................................48 3.3.11. Perancangan penyandi entropi …...................................... 48 3.3.12. AC Coder. …..................................................................... 49 3.3.13. Penyandi RLE................................................................... 50 3.3.14. Pemeta kategori dan generator simbol …......................... 51 3.3.15. DC differentiator............................................................... 52 3.3.16. Penyandi koefisien DC...........…....................................... 53 3.3.17. Code Multiplexer ….......................................................... 54 3.3.18. Bit Stuffer........................................................................... 54 3.4. Metode Pengujian Sistem …........................................................... 56 3.5. Source code dan hirarkinya …........................................................ 60 IV. HASIL PENELITIAN DAN PEMBAHASAN …....................................... 61 4.1. Simulasi Rancangan ….................................................................. 61 4.1.1. Simulasi modul DCT-1D.................................................... 61 4.1.2. Pengujian rangkaian DCT-2D terskala .............................. 67
ix 4.1.3. Pengujian zig-zag buffer......................................................73 4.1.4. Pengujian Quantizer........................................................... 75 4.1.5. Pengujian penanda nilai DC............................................... 77 4.1.6 Pengujian unit penghasil nilai beda pada koefisien DC...... 78 4.1.7. Pengujian unit penyandi entropi......................................... 78 4.1.8. Pengujian unit bit stuffer ....................................................81 4.1.9. Latensi sistem secara keseluruhan …................................. 83 4.1.11. Pengujian dekompresi data .............................................. 83 4.2. Pengujian Hardware ......................................................................... 84 4.2.1. Utilisasi komponen ............................................................ 85 4.2.2. Spesifikasi pewaktuan …............. …................................. 87 4.2.3. Perhitungan Pesat Frame …................................................ 88 4.2.4. Pengujian Rasio Kompresi ................................................. 91 4.3. Permasalahan dalam penelitian ......................................................... 94 V. KESIMPULAN DAN SARAN …................................................................ 98 DAFTAR PUSTAKA.........................................................................................101 LAMPIRAN A : Citra Uji …...........................................................................A-1 LAMPIRAN B: Hirarki Desain dan Source Code …......................................B-1 LAMPIRAN C: Tabel Huffman …..................................................................C-1 LAMPIRAN D: Komentar Responden terhadap Citra Kompresi ….............. D-1
x DAFTAR GAMBAR halaman Gambar 2.1 Diagram kompresi JPEG baseline …....................................................15 Gambar 2.2 Urutan pengeluaran data secara zig-zag pada standar JPEG …............18 Gambar 2.3 Visualisasi pengeluaran data zig-zag secara numeris ….......................19 Gambar 3.1 Interkoneksi modul-modul dalam piranti kompresi ….........................26 Gambar 3.2 Signal flow graph algoritma DCT Arai …............................................29 Gambar 3.3 Proses akusisi input, komputasi, dan pengeluaran output DCT-1D …..30 Gambar 3.4 Visualisasi proses DCT-1D dengan eksekusi single-cycle …...............31 Gambar 3.5 Rancangan timing diagram proses pipeline DCT-1D ….......................33 Gambar 3.6 Skema interkoneksi 2 stage DCT-1D …...............................................40 Gambar 3.7 Rancangan modul transpose buffer …..................................................41 Gambar 3.8 Susunan data input dan output pada transpose buffer …......................41 Gambar 3.9 Visualisasi input dan output data menuju dan dari transpose buffer …43 Gambar 3.10 Struktur unit zigzag …........................................................................46 Gambar 3.11 Skema kuantisasi dan penskalaan ulang ….........................................48 Gambar 3.12 Rancangan modul penyandi entropi …...............................................49 Gambar 3.13 Diagram blok sub modul sandi Huffman ….......................................50 Gambar 3.14 Diagram blok penyandi komponen AC ….............. .…......................51 Gambar 3.15 Rangkaian penyandi RLE …...............................................................52 Gambar 3.16 Skema penyandi koefisien DC ….......................................................53 Gambar 3.17 Interkoneksi penyandi dengan bit stuffer........................................... .55 Gambar 3.18 Skema pengujian simulasi dan hardware............................................56
xi Gambar 3.19 Skema konversi bitmap ke VHDL …..................................................58 Gambar 3.20 Diagram blok pengujian rangkaian......................................................59 Gambar 4.1 Citra asal untuk pengujian sistem kompresi ….....................................61 Gambar 4.2 Diagram pewaktuan modul DCT-1D …................................................66 Gambar 4.3 Simulasi awal pengisian data ke transpose buffer ….............................68 Gambar 4.4 Diagram pewaktuan awal pengeluaran data transpose buffer …...........69 Gambar 4.5 Diagram pewaktuan penulisan 64 data keluaran DCT-1D ke transpose buffer ….....................................................................................................................69 Gambar 4.6 Diagram pewaktuan pengeluaran 64 titik data output …......................70 Gambar 4.7 Diagram pewaktuan DCT-2D …...........................................................73 Gambar 4.8 Diagram pewaktuan input data dari DCT2D ke zigzag buffer …..........74 Gambar 4.9 Diagram pewaktuan pembacaan data dari zig-zag buffer ….................74 Gambar 4.10 Diagram pewaktuan penanda koefisien DC …....................................77 Gambar 4.11 Diagram pewaktuan untuk menguji penghasil selisih koefisien DC ...78 Gambar 4.12 Diagram pewaktuan unit RLE dengan jumlah nol kurang dari 16 …...79 Gambar 4.13 Diagram pewaktuan unit RLE dengan jumlah nol 16 atau lebih …......80 Gambar 4.14 Diagram pewaktuan latensi sistem …...................................................83 Gambar 4.15 Screenshot teks file hasil simulasi kompresi …................................. ..84 Gambar 4.16. Rangkaian penghitung siklus clock untuk pengolahan satu frame ......89 Gambar 4.17. Skema deteksi kesalahan .....................................................................90
xii DAFTAR TABEL halaman Tabel 1.1 Beberapa IC dan intellectual property untuk kompresi JPEG …..............3 Tabel 2.1 Langkah-langkah algoritma DCT-1D …...................................................13 Tabel 2.2 Nilai-nilai pada matriks kuantisasi untuk citra grayscale. …...................16 Tabel 2.3 Kode Huffman untuk pemetaan simbol dan kategori koefisien DC dan AC …........................................................................................................................18 Tabel 2.4 Kode Huffman luminance citra untuk komponen DC dan AC …............17 Tabel 2.5 Parameter-parameter FPGA Xilinx XCS500E. …...................................21 Tabel 3.1 Tabel pipeline modul DCT-1D …............................................................33 Tabel 3.2 Delapan state sebagai acuan implementasi …..........................................33 Tabel 4.1 Nilai 8 x 8 piksel sebelum dikurangi 128 untuk pengujian DCT-1D …..62 Tabel 4.2 Nilai pixel sesudah dikurangi 128 untuk pengujian DCT-1D ….............62 Tabel 4.3 Perbandingan komputasi DCT-1D pada VHDL dan Matlab …...............63 Tabel 4.4 Hasil komputasi DCT-2D terskala pada Matlab dan simulasi VHDL ….72 Tabel 4.5 Selisih komputasi DCT-2D terskala pada Matlab dan VHDL …............72 Tabel 4.6 Hasil komputasi DCT-zigzag-kuantisasi pada VHDL dan Matlab ….....76 Tabel 4.7 Hasil penyandian entropi blok ke 1 …....................................................81 Tabel 4.8 Hasil penyandian blok ke-0 dalam paket 8 bit …...................................82 Tabel 4.9 Perbandingan data yang dipulihkan dengan citra asli …........................85 Tabel 4.10 Utilisasi komponen FPGA …............................................................... 86 Tabel 4.11 Spesifikasi pewaktuan rangkaian yang dirancang …............................87 Tabel 4.12 Unit-unit penyumbang delay pada sistem …........................................87
xiii Tabel 4.13. Jumlah siklus clock yang dibutuhkan untuk pengolahan frame pada beberapa sampel .....................................................................................................89 Tabel 4.14. Perbandingan frame rate dan frekuensi maksimal antara rangkaian yang dirancang dan intellectual property JPEG serta chip kompresi JPEG .....................91 Tabel 4.15. Perbandingan rasio kompresi antara FPGA dan Image Analyzer ........ 91 Tabel 4.16. MSE (Mean Square Error) antara hasil kompresi rangkaian dan citra asal serta citra hasil kompresi software ..........................................................................94 Tabel 4.17. Penilaian secara subjektif terhadap citra hasil kompresi rangkaian dibandingkan dengan citra asal ...............................................................................94 Tabel 4.18. Banyaknya kejadian error pada lima kali pengiriman data ................. 96 Tabel 4.19. Hubungan antara delay dan error yang muncul pada transmisi ...........97
xiv INTISARI Implementasi kompresi citra pada suatu chip digunakan untuk kompresi yang membutuhkan kecepatan yang real-time. Kompresi citra secara hardware digunakan pada berbagai piranti untuk penyimpanan seperti pada kamera digital dan transmisi citra seperti pada sistem video conferencing. Pada tesis ini dibahas implementasi kompresi citra dengan metode JPEG dalam keping FPGA Xilinx Spartan-3E. Penelitian ini bertujuan membuat suatu sistem kompresi citra yang unjuk kerjanya dapat menyamai chip kompresi citra yang ada di pasaran. Chip yang dirancang dapat digunakan untuk penyimpanan dan transmisi. Rangkaian kompresi citra dirancang supaya sesuai untuk FPGA low-cost seperti Xilinx Spartan-3E. Citra masukan untuk pengujian adalah citra grayscale. Sistem kompresi terdiri dari modul DCT-2D, quantizer, unit zig-zag, dan penyandi entropi. Rangkaian kompresi dideskripsikan menggunakan VHDL. Rangkaian sudah berhasil disimulasi dalam software Xilinx ISE 10 dan disintesis untuk FPGA serta dijalankan secara hardware. Port serial digunakan sebagai media input citra ke dalam FPGA. Latensi pipeline pada rangkaian yang didapat adalah 170 siklus clock. Data yang diolah dibagi dalam beberapa blok yang berukuran 8x8 pixel. Untuk melakukan kompresi terhadap n buah blok dibutuhkan 170 + 1280n siklus clock. Frekuensi clock maksimal yang diperbolehkan pada rancangan sistem ini adalah 25.724MHz. Hal itu membuat pesat data yang diperbolehkan adalah 25.724 Mega byte per detik. Utilisasi rangkaian yang didapatkan dari proses sintesis yaitu slice sebanyak 1421, look up table (LUT) sebanyak 2485 dan pengali sebanyak 11 unit. Frame rate rerata maksimal yang dapat dicapai oleh rangkaian kompresi JPEG pada citra grayscale adalah 370.04 fps (frame per second) untuk ukuran 240x320 sedangkan untuk ukuran 480x640 adalah 92.73 fps. Rasio kompresi yang dicapai oleh rangkaian kompresi JPEG dapat menyamai rasio yang dicapai oleh software pengolah citra. Untuk citra berukuran kecil (80x80 dan 40x40), rasio kompresi rangkaian bahkan lebih kecil daripada rasio kompresi software. kata kunci : kompresi, citra, JPEG, DCT-2D, FPGA
xv ABSTRACT Implementation of image compression on a chip used for the compression that requires real-time speed. Image compression in hardware for use on various storage devices such as digital cameras and image transmission such as video conferencing systems. This thesis discuss about implementation of the JPEG image compression method in the FPGA chip Xilinx Spartan-3E. This research aims to create an image compression system which can match its performance image compression chip on the market. Designed chip can be used for storage and transmission. Image compression circuit is designed to fit for low-cost FPGA such as Xilinx Spartan-3E. Input images are gray scale images for testing. The compression system consists of modules-2D DCT, quantizer, zig-zag unit, and entropy coding. Compression circuits are described using VHDL. Circuit has been successfully simulated in Xilinx ISE software and synthesized for FPGA 10 and executed in hardware. Serial port is used as a medium of image input into the FPGA. Pipeline latency in the circuit obtained is 170 clock cycles. Data were processed divided into different sized blocks of 8x8 pixels. For compression of block n + 1280n required 170 clock cycles. Maximum clock frequency allowed in the design of this system is 25.724MHz. It makes rapid data that allowed the 25 724 Mega bytes per second. Utilization circuit synthesis process that is obtained from a slice of 1421, look up table (LUT) of multipliers 2485 and as many as 11 units. Mean maximum frame rate that can be achieved by a series of JPEG compression on grayscale images is 370.04 fps (frames per second) for the size of 240x320 while the size is 480x640 92.73 fps. The compression ratio achieved by a series of JPEG compression can be achieved by matching the ratio of the image processing software. For small images (80x80 and 40x40), a series of compression ratio even smaller than software compression ratio. keyword : compression, image, JPEG, DCT-2D, FPGA
1 BAB I PENDAHULUAN 1.1. Latar Belakang 1.1.1. Perumusan Masalah Dewasa ini, komunikasi dan informasi merupakan bagian tidak terpisahkan dalam kehidupan manusia. Media komunikasi elektronik seperti internet dan telepon selular sudah menjadi kebutuhan pokok. Kecenderungan komunikasi sudah beralih dari komunikasi analog menuju komunikasi digital atau komunikasi data. Untuk membuat komunikasi data menjadi lebih efisien, diperlukan suatu metode untuk menyandikan data yang dikirimkan. Jalur komunikasi yang tersedia sudah memiliki spesifikasi tertentu yaitu pesat bit maksimal yang dapat dilewatkan pada jalur tersebut. Penyandian diperlukan supaya informasi dapat ditransmisikan melalui jalur komunikasi yang tersedia dengan pesat data yang dapat diterima. Model penyandian yang diperlukan untuk keperluan tersebut adalah kompresi atau pemampatan data. Metode kompresi data ada bermacam-macam tergantung pada jenis datanya. Untuk informasi yang berbentuk citra, salah satu metode kompresi yang populer adalah JPEG. JPEG merupakan singkatan dari Joint Photographic Expert Group. Menurut Magli (2004), JPEG banyak digunakan pada citra yang disertakan pada halaman web internet. Penggunaan JPEG membuat halaman web yang bergambar dapat diakses dengan lebih cepat dibanding halaman web dengan citra tanpa kompresi. Kompresi JPEG dapat dilakukan baik secara software maupun hardware. 1
2 Masing-masing mempunyai penggunaan yang berbeda. Kompresi secara software umumnya digunakan untuk oleh desainer grafis mengolah dan menyimpan file citra pada komputer. Metode kompresi JPEG secara hardware digunakan pada piranti-piranti yang berhubungan dengan citra digital seperti kamera digital, scanner, perekam video digital, set-top-box, sampai dengan aplikasi video conferencing (Zoran, 1998; Inrevium, 2005). JPEG tidak hanya digunakan sebagai metode kompresi untuk citra diam, tetapi juga dimanfaatkan untuk kompresi citra bergerak dalam format Motion JPEG
atau M-JPEG (Okada,
1997 ). M-JPEG menangani kumpulan frame citra yang masing-masing terkompresi secara JPEG. Walaupun relatif kurang efisien, Kompresi M-JPEG dipilih sebagai metode kompresi video karena tingkat kerumitan yang lebih rendah daripada metode kompresi video lainnya yaitu MPEG (Pillai, 2002). Secara struktur, MPEG juga terdiri dari unit kompresi citra JPEG-like ditambah dengan kompensasi gerakan. Metode kompresi JPEG secara hardware juga dapat dilakukan dengan dua cara. Pertama, algoritma kompresi diimplementasikan pada mikrokontroler atau DSP melalui program (Zulkarnain, 2000). Cara kedua adalah implementasi algoritma JPEG pada rangkaian digital (ASIC atau FPGA) yang banyak diterapkan pada berbagai piranti (Agostini, 2001). Implementasi pada rangkaian digital banyak dipilih karena kinerjanya lebih baik dilihat dari segi waktu kompresi. Operasi kompresi dapat dilakukan secara cepat dan realtime memakai rangkaian digital. Pada piranti berbasis mikroprosesor, kompresi dilakukan dengan mengeksekusi kumpulan instruksi satu demi satu. Karena pada algoritma JPEG dibutuhkan komputasi dan iterasi yang banyak, proses eksekusinya menjadi 2
3 lebih lama. Beberapa contoh chip dan intellectual property kompresi JPEG baseline beserta spesifikasinya ditunjukkan pada Tabel 1.1. Rangkaian terintegrasi untuk kompresi JPEG sebenarnya sudah terdapat di pasaran. Sebagai contoh adalah produk Zoran (1998) dan Inverium (2005) serta beberapa properti intelektual dari Barco (2005) dan Cast-JPEG (2008). Permasalahan yang dihadapi yaitu, pembuat produk-produk tersebut tidak mempublikasikan rancangannya secara umum sampai pada tingkat rancangan hardware. Keadaan seperti itu membuat teknologi perancangan piranti tersebut tidak banyak dikuasai, terutama di negara-negara dengan teknologi yang baru berkembang. Alih teknologi di negara-negara berkembang menjadi suatu kebutuhan. Untuk menguasai teknologi rangkaian kompresi JPEG, dibutuhkan usaha perancangan prototype rangkaian tersebut berdasarkan ilmu yang sudah dikuasai. Tabel 1.1 Beberapa IC dan intellectual property untuk kompresi JPEG Seri chip/ Jenis pabrikan produk
FPGA target
Spesifikasi
BA119JPEGC Intellectual Virtex Frekuensi maksimum 82 MHz OD/ property XC2V1500- Jumlah slice = 7497 Barco 6 Frame rate 120 fps pada 640 x 480, YcrCb=4:1:1 CASTIntellectual Altera Frekuensi maksimum 86 MHz JPEG/Cast-inc property Cyclone Frame rate = 162 fps pada resolusi EP1C20-C6 480x640, YcrCb=4:1:1 Jumlah logic element = 15,305 ZR3606029.5 / Zoran
IC
Frekuensi maksimum 29.5 MHz Frame rate 33 fps pada 640 x 480, YcrCb=4:1:1
TE3310RPFE/ Inrevium
IC
Frekuensi maksimum 27 MHz Frame rate 50 fps pada 640 x 480, YcrCb=4:1:1
3
4 Perancangan prototype rangkaian digital memerlukan suatu piranti yang dapat dikonfigurasi ulang berkali-kali. FPGA (Field Programmable Gate Array) merupakan piranti yang sesuai untuk keperluan perancangan prototype rangkaian digital, terutama dengan skala kompleksitas besar. Selain karena dapat dikonfigurasi ulang, jumlah gerbang dan flip-flop pada FPGA juga sangat banyak. FPGA Spartan 3E XC3S500E keluaran Xilinx mempunyai gerbang sebanyak 500.000 dan slice sebanyak 4.656 unit (Xilinx, 2009). Berdasarkan spesifikasi tersebut, perancangan prototype rangkaian kompresi JPEG diperkirakan dapat diterapkan pada keping FPGA XC3S500E dengan penerapan algoritma tertentu. Rangkaian kompresi JPEG sesuai untuk dikembangkan pada FPGA low cost seperti XC3S500E karena JPEG mempunyai kompleksitas yang lebih rendah dibanding MPEG dan tidak membutuhkan operasi yang harus dibantu dengan suatu prosesor. 1.1.2. Keaslian Penelitian Sejauh ini penelitian mengenai kompresi citra JPEG dan bagian-bagiannya berbasis FPGA telah dilakukan. Sun, dkk(1989) membuat rancangan DCT (Discrete Cosine Transform)2D 16x16 pada VLSI. Rancangan tersebut belum dapat diterapkan pada kompresi JPEG karena JPEG memakai ukuran blok 8x8 pada DCT 2D nya. Jang (1994) membuat suatu prosesor DCT 2D 8x8 dengan metode dekomposisi matriks DCT. DCT 1D pada penelitian tersebut masingmasing memakai 32 dan 16 operasi perkalian. Agostini (2001,2002) melakukan kompresi JPEG pada FPGA Altera Flex10KE. Algoritma yang digunakan adalah DCT 1D dari Arai(1988). Secara keseluruhan, operasi dilakukan secara pipeline. Operasi aritmetika terhadap masukan dilakukan bergantian untuk tiap stage. 4
5 Tesis ini membahas mengenai rancang bangun sistem kompresi citra dengan metode JPEG. Sistem ini diimplementasikan pada FPGA Spartan 3E. Berbeda dengan penelitian Agostini, pada tesis ini akan dilakukan operasi aritmetika secara paralel untuk tiap stage. Hal ini belum dilakukan penulis sebelumnya, mengingat uraian lengkap dan teknis pada paper sebelumnya sulit diperoleh karena tidak dipublikasikan. 1.1.3. Faedah Penelitian Penelitian ini diharapkan dapat memperkaya khasanah pengetahuan pada dunia komunikasi dan informasi, serta pengembangan perangkat keras, khususnya mengenai kompresi citra. 1.2. Tujuan Penelitian 1. Merancang dan membuat prototype rangkaian terintegrasi untuk kompresi citra JPEG baseline menggunakan FPGA Xilinx XC3S500E. 2. Rangkaian kompresi yang dibangun memilki spesifikasi yang kompatibel dengan IC kompresi JPEG yang terdapat di pasaran, yaitu dapat diterapkan pada aplikasi-aplikasi berikut. a)
Kompresi citra diam (JPEG) dan video (MJPEG) untuk keperluan penyimpanan.
b)
Kompresi video (MJPEG) untuk keperluan transmisi atau video streaming.
5
6 BAB II TINJAUAN PUSTAKA DAN DASAR TEORI 2.1. Kajian Pustaka Berdasarkan Agostini (2001), komponen utama dari kompresi citra JPEG adalah DCT (Discrete Cosine Transform) dua dimensi (DCT-2D). DCT-2D adalah bagian dari kompresi JPEG yang
paling
kritis.
Karena kompleksitas
komputasinya, sumber daya dan waktu komputasi lebih banyak terfokus pada bagian tersebut. Kompleksitas juga telah menghasilkan beberapa penelitian yang bertujuan menyederhanakan komputasi DCT. Penelitian-penelitian tersebut banyak terfokus pada algoritma komputasi DCT satu dimensi dengan panjang 8 titik. DCT dikembangkan pertama kali oleh Ahmed, dkk (1974). Chen, dkk (1977) merintis penelitian mengenai algoritma komputasi DCT satu dimensi (DCT 1D). Penyederhanaan dilakukan dengan cara dekomposisi matriks DCT dari ukuran 8 x 8 menjadi dua buah matriks 4 x 4. Jumlah operasi perkalian dapat dikurangi hingga menjadi 16 perkalian. Pada algoritma ini, komputasi invers DCT (IDCT) dapat dilakukan dengan menukar input dan output DCT pada data flow graph-nya (reversible). Algoritma yang diusulkan oleh Arai, dkk(1988) mampu mengurangi jumlah perkalian pada komputasi DCT 1D menjadi sejumlah lima perkalian saja. Hal itu dimungkinkan karena nilai yang didapat pada output adalah nilai yang terskala
(DCT terskala).
Nilai
output
bukanlah
koefisien
DCT yang
sesungguhnya. Untuk mendapatkan nilai yang sesungguhnya, dilakukan penskalaan ulang. Pada berbagai sistem, proses penskalaan ulang dapat disertakan 6
7 pada proses pasca DCT. Misalnya seperti proses kuantisasi pada kompresi citra. Kelima perkalian pada algoritma DCT Arai dilakukan secara paralel. Pada flow graph-nya, tidak ada jalur yang memiliki lebih dari satu perkalian. Flow graph pada algoritma ini tidak reversible. Loffler, dkk (1989) kemudian mengusulkan suatu algoritma komputasi DCT yang tidak terskala. Algoritma tersebut memerlukan 11 perkalian untuk komputasi DCT 1D. Sama dengan algoritma Arai, pada flow graph algoritma Loeffler juga tidak terdapat jalur yang memiliki lebih dari satu perkalian. Penerapan DCT dua dimensi (DCT-2D) pada VLSI diusulkan oleh Sun,dkk (1989). Usulan yang disampaikan berupa DCT terhadap matriks 16 x 16. Ukuran ini kurang lazim untuk kompresi citra, yang menggunakan ukuran blok 8x8. Meskipun begitu, usulan ini cukup memberikan gambaran yang jelas mengenai aristektur rangkaian DCT-2D. Rancangan ini menggunakan dua unit DCT-1D 16 titik yang dihubungkan oleh suatu transpose buffer yang diatur oleh rangkaian pewaktuan dan kendali. DCT dua dimensi (DCT 2D) 8x8 dikembangkan menjadi suatu rancangan hardware oleh Jang (1994) untuk kompresi MPEG dan untuk prosesor HDTV. Komputasi DCT 2D direalisasi dengan dua kali pemrosesan DCT 1D. Pemrosesan DCT 1D yang kedua berasal dari operasi transpose hasil DCT 1D yang pertama. Untuk mendukung hal itu, digunakan suatu transpose buffer. Pada rancangan hardware-nya, hanya digunakan 1 blok DCT 1D.
Pada bagian input DCT 1D,
dipasang multiplekser untuk memilih masukan. Masukan yang dipilih adalah masukan dari input port atau masukan dari output transpose buffer. Algoritma DCT 1D yang digunakan adalah dengan dekomposisi matriks DCT 8x8 menjadi 7
8 dua matriks 4x4. Pengali yang dibutuhkan untuk DCT 1D sebanyak 32 unit. Wallace (1991) mengusulkan suatu metode kompresi citra yang dinamai dengan JPEG. JPEG baseline yang diusulkan pada paper tersebut merupakan kompresi yang mempunyai rugi-rugi (lossy) karena ada komponen informasi yang dibuang. Kompresi ini menggunakan DCT 2D untuk mencari komponen frekuensi citra. Koefisien DCT 2D yang didapat kemudian direduksi melalui proses kuantisasi untuk menghilangkan komponen frekuensi tinggi. Nilai terkuantisasi disandikan lagi menggunakan sandi Huffman. Perancangan hardware berbasis FPGA untuk komputasi DCT 2D sudah dilakukan oleh Agostini (2001). DCT 2D yang dirancang ditujukan untuk kompresi citra JPEG. Pada tulisannya yang lain Agostini (2002) juga merancang suatu entropy encoder untuk pengolahan lebih lanjut keluaran DCT 2D sehingga didapatkan citra terkompresi JPEG. FPGA yang digunakan pada penelitian tersebut adalah Altera Flex 10kE dengan jumlah gerbang maksimal 200.000, logic element sejumlah 9.984 unit, dan LUT sejumlah 24. DCT 2D dikerjakan menggunakan dua unit DCT 1D yang dihubungkan melalui suatu transpose buffer. Algoritma DCT 1D yang digunakan adalah algoritma DCT dari Arai(1988). Penelitian ini menggunakan pengali yang dibuat sendiri. Pengali dibuat memakai teknik shift and add. Pada tulisan tersebut, proses komputasi pada masing-masing stage dilakukan secara bergantian (multiplexed). Keseluruhan proses pada kompresi citra dilakukan secara pipeline. Pada tulisan ini disebutkan, piranti DCT 2D yang dihasilkan menggunakan 4.792 logic cell, mempunyai frekuensi operasi maksimal 12,2 MHz. Latensi pipeline yang terbentuk adalah sebesar 160 siklus clock. 8
9
Meskipun telah diketahui beberapa algoritma komputasi DCT dan kompresi JPEG dari hasil-hasil penelitian terdahulu, akan tetapi uraian lengkap dan teknis proses tersebut sulit diperoleh karena tidak dipublikasikan. Pada tesis ini akan dirancang perangkat keras untuk kompresi citra dengan metode JPEG baseline berbasis FPGA Xilinx Spartan 3E XC3S500E. Algoritma DCT 1D yang digunakan pada tesis ini adalah algoritma usulan Arai, dkk(1988). Agoritma tersebut hanya memiliki 5 perkalian dan bila dikembangkan menjadi DCT 2D hingga kompresi JPEG, masih dapat diimplementasikan pada FPGA Spartan 3E. Berdasarkan datasheet dari Xilinx(2007), FPGA tersebut memiliki 20 pengali. Untuk metode pemasukan data input, tesis ini mengadopsi teknik dari paper Sun, dkk(1989). Modul DCT hanya memiliki satu port untuk data input selebar 1 byte(8 bit). Data-data input dimasukkan secara sekuensial, bergantian untuk tiap byte. Metode pipeline untuk pengerjaan DCT 2D dan penyandian entropi merupakan modifikasi dari metode yang diusulkan oleh Agostini (2001,2002). Pada dua paper tersebut, operasi aritmetika untuk tiap stage dikerjakan secara bergantian. Pada tesis ini operasi untuk tiap stage dikerjakan secara paralel.
2.2. Dasar Teori 2.2.1 Kompresi Citra berbasis DCT (Discrete Cosine Transform) Menurut Wallace(1991), Discrete Cosine Transform dua dimensi (DCT2D) digunakan sebagai bagian dari kompresi citra. Menggunakan DCT-2D, nilainilai piksel suatu citra di kawasan spatial akan ditransformasi menjadi suatu himpunan koefisien DCT di kawasan frekuensi. Sebelum dilakukan operasi 9
10 kompresi, data citra dalam memori dibagi-bagi menjadi beberapa blok MCU (Minimum Code Unit). Setiap blok terdiri atas 8x8 piksel. Operasi kompresi termasuk DCT-2D di dalamnya akan dilakukan terhadap setiap blok. a. DCT satu dimensi Komputasi DCT-1D N titik ditunjukkan oleh persamaan (2.1) N −1
y n=a n ∑ x k cos k=0
2⋅⋅n⋅2k 1 4⋅N
.............................(2.1)
dengan a0 = 1/√N dan an = √(2/N) untuk 1< n < N – 1. Untuk N=8, persamaan (2.1) dapat dijadikan dalam bentuk perkalian matriks seperti persamaan (2.2) sebagai berikut: y=Cx
..........(2.2)
dengan cn = cos (nπ/16). Menurut Arai, dkk (1988), matriks C dapat difaktorisasi menjadi perkalian beberapa matriks pada persamaan (2.3) sebagai berikut:
C = S * G * F * E * D * B * A ......................................(2.3) A, B, C, D, E, F, dan G adalah matriks faktor dan S matriks penskala dengan
10
11
[ [
A=
B=
D=
E=
0 0 0 0 0 0 0 1
1 0 1 0 0 0 0 0
0 0 0 1 0 1 1 0
0 0 0 1 0 1 −1 0 0 0 0 0 0 −1 0 0 0 1 0 0 1 1 0 0 0 0 0 −1 0 0 0 0 −1 0 0 0 0 0 0 −1
1 0 0 0 1 0 0 0
0 1 0 1 0 0 0 0
0 0 1 0 0 0 0 0
0 0 1 0 0 0 −1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 −1 0 0 1 0 0 0 1 1 0 0 1 0 0 0 0 0 1
[
1 1 0 0 0 0 0 0 0
[
1 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0
0 1 0 0 0 0 0 −1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 −1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1
]
]
]
0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 m3 0 0 0 0 0 0 0 0 0 0 0 0 m1 0 0 0 0 0 0 m4 0 0 0 0 0 0 1 0 0 0 0 0 m1 0 0 0 0 0 0 0 0 m2 0 0 0 0 0 0 0 0 0 0 0 1
11
]
12
F=
[
1 0 0 0 0 0 0 0
G=
S=0.5
0 1 0 0 0 0 0 0
[
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 −1 0 0 0 1 0 0 0 0 1 0 −1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0
0 0 1 0 0 0 0 0
0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 1
0 0 0 0 0 1 0 0 0 1 −1 0 0 0 0 1 1 0 0 0 0 0 0 −1
]
]
[
c4 0 0 0 0 0 0 0 0 c7 /c6 0 0 0 0 0 0 0 0 c6 /c4 0 0 0 0 0 0 0 0 c5 /c2 0 0 0 0 0 0 0 0 c4 0 0 0 0 0 0 0 0 c3/ c2 0 0 0 0 0 0 0 0 c2/c4 0 0 0 0 0 0 0 0 c1/c6
]
serta m1= cos (4π/16) m2= cos (6π/16) m3= cos (2π/16) - cos (6π/16) m4= cos (2π/16) + cos (6π/16) cn = cos (nπ/16). Kemudian persamaan (2.3) diubah menjadi persamaan (2.4) Cs = G * F * E * D * B * A ............................................(2.4)
12
13 Tabel 2.1 Langkah-langkah algoritma DCT-1D (Agostini, dkk, 2001) Step 1:
Step 2:
Step 3:
Step 4:
Step 5:
Step 6:
a0 = x0 + x7 a1 = x1 + x6 a2 = x3 – x4 a3 = x1 - x6 a4 = x2 + x5 a5 = x3 + x4 a6 = x2 – x5 a7 = x0 – x7 b0 = a0 + a5 b1 = a1 - a4 b2 = a2 + a6 b3 = a1 + a4 b4 = a0 - a5 b5 = a3 + a7 b6 = a3 + a6 b7 = a7 d0 = b0 + b3; d1 = b0 - b3; d2 = b2; d3 = b1 + b4; d4 = b2 - b5; d5 = b4;`1 d6 = b5; d7 = b6; d8 = b7; e0 = d0; e1 = d1; e2 = m3 * d2; e3 = m1 * d7; e4 = m4 * d6; e5 = d5; e6 = m1 * d3; e7 = m2 * d4; e8 = d8; f0 = e0; f1 = e1; f2 = e5 + e6; f3 = e5 - e6; f4 = e3 + e8; f5 = e8 - e3; f6 = e2 + e7; f7 = e4 + e7; y0 = f0; y1 = f4 + f7; y2 = f2; y3 = f5 - f6; y4 = f1; y5 = f5 + f6; y6 = f3; y7 = f4 - f7;
13
14 Pada dasarnya Cs pada persamaan (2.4) adalah C pada persamaan (2.3) tanpa matriks penskala S. matriks S dihilangkan untuk mengurangi jumlah perkalian pada komputasi DCT. Persamaan (2.4) disebut DCT terskala. Penskalaan tersebut memungkinkan karena DCT digunakan pada kompresi citra. Pada kompresi, proses DCT akan diikuti dengan proses kuantisasi. matriks penskalaan akan diikutkan pada proses kuantisasi. Agostini, dkk (2001) menjabarkan persamaan (2.4) menjadi suatu langkahlangkah algoritma DCT-1D. Algoritma DCT-1D 8 titik dapat didefinisikan pada Tabel 2.1 dengan input x = [ x0 x1 x2 x3 x4 x5 x6 x7 ] dan output y = [ y0 y1 y2 y3 y4 y5 y6 y7 ]. b. DCT 2 dimensi 8X8 Pada DCT 2 dimensi 8X8 titik, masukan dan keluaran adalah berupa matriks 8X8. Menurut Rao,dkk (1974), komputasi DCT 2 dimensi dikerjakan melalui persamaan (2.5) sebagai berikut 7
yv , u=
7
C v C u ⋅ 2m1⋅u ⋅2m1⋅u x n , m cos cos , 0≤u , v≥7 ∑ ∑ 2 2 n=0 m=0 16 16
..(2.5) Jika dibuat dalam notasi matriks, dengan matriks X sebagai input dan Y
sebagai output, DCT 2D memiliki persamaan (2.6) sebagai berikut. Y = [C] [X] [C]T …..........................................(2.6)
X = matriks input DCT 8x8 Y = matriks input DCT 8x8 C = matriks DCT , sama dengan matriks C pada persamaan (2.1) Menurut Agostini (2000), komputasi DCT 2D terskala memakai persamaan (2.7). Y = [S2D] .* [Cs]*[X]*[Cs]T ................................ (2.7) 14
15 dengan Cs = matriks DCT terskala pada persamaan (2.4) S2D = matriks penskalaan DCT-2D “ .* ” = operasi perkalian antar elemen matriks “ * “ = operasi perkalian matriks biasa
2.2.2. Kompresi Citra Baseline JPEG Pemampatan Citra JPEG baseline adalah salah satu metode pemampatan yang lossy atau bersifat menghilangkan informasi terhadap citra input. Nilai informasi yang terdapat pada citra output akan berkurang. Informasi yang dibuang pada proses ini adalah koefisien DCT frekuensi tinggi. Bagi mata manusia, pembuangan frekuensi tinggi tidak berpengaruh pada citra yang diamati (Wallace, 1991). Operasi kompresi meliputi DCT-2D dilanjutkan dengan kuantisasi, zig-zag dan penyandian entropi. Berdasarkan Miano(1999), diagram lengkap kompresi JPEG ditunjukkan pada Gambar 2.1.
Gambar 2.1 Diagram kompresi JPEG baseline Berdasarkan Gambar 2.1, citra yang akan dikompresi dibagi dalam beberapa blok. Masing-masing blok berukuran 8x8 piksel. Blok-blok inilah yang akan dimasukkan modul kompresi. Data piksel pada citra disimpan dalam format bilangan 8 bit tidak bertanda (unsigned) yaitu 0 sampai dengan 255. Meskipun 15
16 demikian, berdasarkan spesifikasi JPEG (Solomon,2004) data citra yang akan dikompresi dikurangi terlebih dahulu dengan 128 untuk membuat suatu bilangan unsigned menjadi bilangan signed. Masing-masing blok akan mengalami proses DCT-2D 8x8, kuantisasi, dan entropy encoding. a. Operasi kuantisasi Pada kompresi citra JPEG lossy (Wallace, 1991) Operasi kuantisasi dilakukan untuk menghilangkan komponen-komponen frekuensi tinggi dari citra hasil DCT-2D. Untuk melakukan operasi ini, citra hasil DCT dibagi dengan suatu nilai yang sudah terdefinisi pada tabel kuantisiasi. Tabel kuantisasi disajikan dalam bentuk matriks 8x8 seperti pada persamaan (2.8). Nilai pembagi dalam matriks kuantisasi ditunjukkan pada Tabel 2.2. Tabel 2.2 Nilai-nilai pada matriks kuantisasi untuk citra grayscale, atau komponen luminance.
Q=
[
q 00 q 10 q 20 q 30 q 40 q 50 q 60 q 70
q 01 q11 q 21 q31 q 41 q51 q61 q 71
q02 q12 q22 q32 q42 q52 q62 q72
q 03 q13 q 23 q 33 q 43 q53 q63 q 73
q 04 q 14 q 24 q 34 q 44 q 54 q 64 q 74
q05 q15 q 25 q35 q 45 q55 q65 q75
q06 q16 q26 q36 q46 q56 q66 q76
q 07 q 17 q 27 q 37 q 47 q 57 q 67 q 77
]
Proses kuantisasi ditunjukkan pada persamaan (2.9) berikut: 16
…................(2.8)
17 yq mn = integer_round (ymn / qmn)...............................(2.9) dengan yq = nilai terkuantisasi dan y = nilai sebelum dikuantisasi. Kuantisasi menyebabkan citra kehilangan sebagian dari informasinya. Nilai informasi yang dikurangi adalah komponen frekuensi tinggi spatial. Menurut Magli (2004), pengurangan komponen frekuensi tinggi spatial tidak mempengaruhi persepsi visual mata terhadap citra. Nilai kuantisasi yang terdapat pada Tabel 2.2 merupakan rekomendasi yang dikeluarkan oleh CCITT (Consultative Comitee of International Telegraph and Telephone) pada dokumen T.81 (Magli, 2004). Sesuai dengan kualitas kompresi yang dibutuhkan, nilai-nilai pada tabel kuantisasi dapat diatur. Kualitas kompresi diukur dalam skala 1 sampai 99 dan dihitung menggunakan
persamaan 2.10. Matriks kuantisasi pada Tabel 2.2 digunakan
sebagai basis.
...............(2.10)
α = faktor kompresi q_JPEG = kualitas kompresi ( 1 < q_JPEG < 99). Nilai α kemudian dikalikan dengan matriks kuantisasi pada Tabel 2.2 untuk menghasilkan matriks kuantisasi sesuai kualitas kompresi yang diinginkan. Matriks kuantisasi pada Tabel 2.2 mempunyai kualitas kompresi 50. b. Operasi zigzag Data hasil kompresi akan dikeluarkan secara sekuensial pada kompresi JPEG standar. Urutan pengeluaran data disusun secara zig-zag(Wallace,1991) dan secara grafis ditunjukkan oleh Gambar 2.2. 17
18
Gambar 2.2 Urutan pengeluaran data secara zig-zag pada standar JPEG Urutan data yang dikeluarkan pada suatu matriks 8 x 8 ditunjukkan secara numeris pada Gambar 2.3. Data yang keluar pertama kali dari proses zig-zag adalah koefisien DC, yang disusul 63 koefisien AC. Urutan pengeluaran data seperti pada Gambar 2.2 dan Gambar 2.3 adalah, DC, AC01, AC10, AC20, AC11, ..., AC67, AC76, AC77. Gambar 2.3 menunjukkan suatu memori dua dimensi yang menyimpan koefisien-koefisien DCT yang terkuantisasi. Nomornomor yang ditampilkan pada Gambar 2.3 merupakan nomor urut keluarnya koefisien-koefisien tersebut dari memori. c. Entropy Coding Koefisien-koefisien yang menjadi output unit zig-zag akan menjadi input bagi unit entropy coding. Pada bagian inilah proses pemampatan data berlangsung. Kode yang digunakan dalam penyandian koefisien-koefisien adalah kode Huffman. Kode Huffman secara eksplisit memetakan simbol input pada suatu kata sandi. Simbol input yang mempunyai peluang paling besar dikodekan dengan kata sandi yang paling pendek. Sementara itu, simbol input dengan peluang terkecil dikodekan dengan kata sandi yang panjang. Penyandian Huffman untuk JPEG tidak dilakukan melalui operasi matematis atau perhitungan
18
19 probabilitas, melainkan langsung menggunakan suatu look-up table (Salomon, 2004).
Gambar 2.3 Visualisasi pengeluaran data zig-zag secara numeris(Salomon, 2004)
Koefisien DC disandikan terpisah dan berbeda dengan koefisien AC. Representasi koefisien DC yang dipakai adalah selisih antara koefisien DC blok yang satu dengan koefisien DC blok sebelumnya. Misalnya koefisien DC blok 0,1, dan 2 berturut-turut 20, 18, dan 22, maka representasi koefisien DC yang akan disandikan adalah 20, -2, dan -4. Selisih ini disandikan dengan kode Huffman. Penyandian Huffman dilakukan dengan memetakan bilangan yang akan dikodekan menggunakan Tabel 2.3. Untuk menentukan kata sandinya, koefisien DC ditentukan letak barisnya berdasarkan interval tempat bilangan itu berada. Berdasarkan Tabel 2.3, setelah diketahui letak baris, akan diketahui juga unary code dari bilangan itu. Langkah berikutnya adalah menentukan letak kolom bilangan tersebut pada tabel, dan mengkonversi letak kolom ke dalam bilangan biner. Sandi untuk koefisien DC didapat dengan menggabungkan nilai biner unary code dengan nilai biner letak kolom.
19
20 Tabel 2.3 Kode Huffman untuk pemetaan simbol dan kategori koefisien DC dan AC (Salomon, 2004)
Sebagai contoh, bilangan yang akan dikodekan adalah -2. Bilangan tersebut terletak pada baris 2 (dihitung dari 0) dan mempunyai unary code 110. Nilai -2 terletak pada kolom 1 interval. Nilai biner 2 bit dari bilangan 1 adalah 01. Sehingga kode untuk nilai -2 adalah 110|01.
Tabel 2.4 Kode Huffman luminance citra untuk komponen DC(a) dan AC(b) (a) Cat
Code word
0
00
1
010
2
011
3
100
4
101
5
110
6
1110
7
11110
8
111110
9
11111110
10
111111110
11
11111111110
20
21 (b)
Koefisien AC disandikan dengan gabungan sandi RLE (Run Length Encoding) dan Huffman. Deret yang berisi koefisien AC normalnya mempunyai banyak nilai nol di dalamnya dan hanya ada beberapa nilai nonzero. Berikut adalah proses penyandian adalah untuk setiap bilangan nonzero (x). 1. Menghitung jumlah nol (Z) sebelum bilangan tersebut. 2. Memetakan x pada Tabel 2.3 dan menentukan letak kolom dan baris (R dan C). 3. Pasangan (R,Z) digunakan untuk menentukan baris dan kolom pada Tabel 2.4(b). 4. Kode Huffman dari baris dan kolom step (3) digabungkan ke C.
21
22 Hasil dari proses tersebut adalah sandi RLE-Huffman untuk koefisien AC x dan bilangan nol sebelum koefisien tersebut. 2.2.3. FPGA (Field Programmable Gate Array) XC3S500E XC3S500E merupakan keluarga FPGA dari seri Spartan 3E. Spartan 3E mampu mendukung sistem dengan kecepatan clock hingga 300 MHz. Piranti tersebut dilengkapi dengan RAM di dalam chip dan dekoder input yang lebar sehingga lebih berdaya guna untuk aplikasi-aplikasi sistem digital. Spartan 3E juga dilengkapi dengan blok pengali dengan jumlah berkisar 4 sampai 36. Keluarga Spartan 3E mempunyai beberapa varian dengan kapasitas berkisar 100.000 sampai 1.600.000 gerbang. Pada tesis ini digunakan XC3S500E yang mempunyai parameter seperti pada Tabel 2.5 berikut. Tabel 2.5 Parameter-parameter FPGA Xilinx XC3S500E. PARAMETER jumlah gerbang jumlah CLB jumlah blok RAM jumlah max IOB Jumlah pengali
XC3S500E 500.000 1164 360 Kb 232 20
2.2.4. Perangkat Lunak Yang Berhubungan Dengan Perancangan FPGA Penggunaan perangkat lunak dalam suatu perancangan sistem elektronis bertujuan untuk memperoleh efisiensi dalam hal sintesis dan optimalisasi rancangan. Karakter suatu rancangan dapat diketahui sebelum diimplementasikan dalam bentuk perangkat keras sehingga memudahkan untuk melakukan perbaikan terhadap rancangan tersebut. Berdasarkan pedoman yang didokumentasikan oleh Xilinx (2007), rancangan suatu sistem digital yang akan diimplementasikan dalam bentuk 22
23 perangkat keras menggunakan FPGA dibuat melalui beberapa tahap sebagai berikut. 1. Pembuatan desain (Design Entry), yaitu proses pembuatan rangkaian yang akan diimplementasikan menggunakan FPGA. 2. Verifikasi desain (Design Verification), yaitu memerikasa desain yang telah dibuat dengan cara simulasi. 3. Pemetaan, penempatan dan routing desain (Mapping, placing and routing), yaitu pemetaan gerbang, penempatan pin dan routing pembuatan jalur jalur koneksi desain ke dalam FPGA. 4. Implementasi desain (Design Imlementation), yaitu mengimplementasikan rancangan dalam bentuk perangakat keras. Langkah-langkah tersebut dapat dilakukan dengan bantuan perangkat lunak komputer yaitu Xilinx ISE 10. Pembuatan desain (rangkaian) bisa dilakukan secara skematis atau menggunakan VHDL (Very High Speed IC Description Language). Pada desain menggunakan skematis, pengguna software menggambar rangkaian menggunakan simbol-simbol rangkaian digital pada lembar gambar Xilinx ISE. Penggunaan skematis ini efisien untuk rangkaian-rangkaian yang sederhana atau dengan kompleksitas rendah. VHDL merupakan tool desain rangkaian digital yang menggunakan sintaks bahasa pemrograman. Bahasa pemrograman tersenut digunakan untuk mendefinisikan kerja rangkaian. VHDL sesuai untuk rangkaian dengan kompleksitas tinggi, seperti yang dirancang pada tesis ini. Untuk mendeasain 23
24 rangkaian yang kompleks, VHDL cukup efektif, karena pengguna cukup mendefiniskan kerja rangkaian saja dan tidak perlu menggambar realisasi rangkaiannya. 2.3. Hipotesis 1. Rangkaian penyandi JPEG baseline dapat diterapkan pada satu keping FPGA Xilinx Spartan-3E XC3S500E menggunakan algoritma DCT Agostini (2001) dan teknik komputasi sekuensial-pipeline. 2. Selain untuk kompresi citra diam dalam format JPEG, rangkaian dapat digunakan untuk kompresi citra bergerak dalam format Motion JPEG. 3. Rasio kompresi yang dihasilkan oleh rangkaian yang dirancang dapat menyamai rasio kompresi yang dihasilkan oleh software kompresi komersial untuk input citra yang sama. 4. Frame rate yang dapat dicapai oleh rangkaian yang dirancang dapat menyamai frame rate IC komersial dan intellectual property untuk kompresi JPEG baseline pada tabel 1.1.
24
25 BAB III METODA PENELITIAN 3.1. Bahan Penelitian Bahan penelitian terdiri atas : a. FPGA Spartan-3E starter board Keping XC3S500E mempunyai 500.000 gerbang dengan jumlah CLB sebesar 1164, IOB sebesar 232 pengali sebanyak 20 unit, dan interkoneksi yang dapat diprogram. b. ARM7 Development Board Sistem komputer berbasis mikrokontroler ARM7 yang digunakan untuk mengeluarkan data-data uji ke FPGA. Piranti ini dipilih karena memiliki general purpose I/O. 3.2. Alat Penelitian Alat penelitian terdiri atas : a. Satu set komputer Pentium 4 b. Satu perangkat lunak Sistem Operasi Linux. c. Satu perangkat lunak Xilinx ISE 10.1 3.3. Jalan Penelitian Pelaksanaan penelitian dimulai dengan merancang gambaran keseluruhan sistem. Piranti kompresi data pada penelitian ini tersusun atas enam modul yang saling terhubung sesuai Gambar 3.1. Enam modul itu adalah modul DCT-2D, zigzag buffer, quantizer, penyandi entropi, byte stuffer, dan unit pengendali. Masing-masing modul dirancang dan saling dihubungkan menggunakan bahasa VHDL pada perangkat lunak Xilinx ISE. 25
26 3.3.1. Perancangan sistem secara global
Gambar 3.1 Interkoneksi modul-modul dalam piranti kompresi Data input merupakan piksel-piksel citra yang akan dikompresi. Sesuai dengan spesifikasi JPEG yang dijelaskan pada Bagian 2.2.2, data piksel citra yang akan dikompresi sebelumnya dikurangi terlebih dahulu dengan 128 untuk mendapatkan format bilangan signed. Data piksel dengan format signed tersebut kemudian dimasukkan byte demi byte ke dalam unit kompresi JPEG. Berikut ini keterangan singkat mengenai masing-masing modul. a. DCT 1D, transpose buffer, dan DCT 2D Unit kompresi diawali dengan operasi DCT 2 Dimensi. Operasi DCT 2 dimensi (DCT-2D) dikerjakan menggunakan dua modul DCT 1 dimensi yang dihubungkan melalui transpose buffer. DCT 1D diterapkan pada setiap 8 titik data yang masuk. Data hasil DCT 1D disimpan di dalam transpose buffer. Data dikeluarkan dari transpose buffer dalam urutan yang ter-transpose untuk masuk ke modul DCT 1D berikutnya. Keluaran modul DCT 1D yang kedua merupakan hasil operasi DCT 2D atau koefisien DCT 2D dari data masukan. b. Zigzag buffer Koefisien DCT 2D disimpan dalam zigzag buffer. Data yang tersimpan dalam zigzag buffer akan dikeluarkan secara zigzag untuk masuk pada operasi 26
27 selanjutnya, yaitu kuantisasi. Koefisien DCT 2D dikeluarkan secara zigzag untuk diurutkan berdasarkan komponen frekuensinya.
Koefisien yang dikeluarkan
terlebih dahulu merupakan komponen frekuensi yang lebih rendah daripada komponen yang dikeluarkan selanjutnya. c. Quantizer Proses kompresi pada dasarnya dimulai pada bagian ini. Keluaran zigzag buffer yang merupakan koefisien DCT 2D, satu persatu dibagi dengan suatu bilangan sesuai dengan urutannya. Bilangan pembagi tersebut terdapat pada tabel kuantisasi (Tabel 2.2) sesuai dengan spesifikasi JPEG baseline. Keluaran modul ini merupakan koefisien DCT 2D yang telah terkuantisasi dan memiliki lebar bit yang lebih kecil dari koefisien semula. Komponen frekuensi tinggi dibagi dengan bilangan yang lebih besar, sehingga koefisien yang terkuantisasi memiliki nilai yang besar pada frekuensi rendah dan kecil atau bahkan nol pada frekuensi tinggi. d. Entropy Encoder Entropy encoder (penyandi entropi) menyandikan koefisien DCT 2D yang sudah terkuantisasi dan diurutkan secara zigzag. Penyandian entropy pada JPEG merupakan kombinasi Run Length Encoder (RLE) pada koefisien-koefisien bernilai nol dan sandi Huffman. Penyandi ini menghasilkan kode untuk masingmasing kofisien dalam dengan panjang variabel. Panjang kode ditentukan oleh tabel kode Huffman yang telah didefinisikan dalam rangkaian. Walaupun panjang sandi variabel, tetapi lebar bit keluaran penyandi entropi dibuat tetap dengan menambahkan isyarat yang menyatakan panjang sandi. e. Byte stuffer Penyandi entropi menghasilkan sandi dengan panjang variabel, karena itu 27
28 data hasil kompresi dikeluarkan menuju pinout rangkaian tiap satu bit. Byte stuffer digunakan untuk mengeluarkan hasil penyandian entropi satu demi satu bit. Keluaran unit ini sudah merupakan data yang terkompresi. f. Pengendali (controller) Unit pengendali dihubungkan pada isyarat status, kendali, dan isyarat alamat pada masing-masing modul. Unit ini berfungsi menerjemahkan isyarat status dari masing-masing unit dan menghasilkan isyarat kendali dan alamat untuk unit yang lain sehingga masing-masing unit bekerja secara sinkron. 3.3.2. Perancangan algoritma dan modul DCT 1 D Algoritma DCT satu dimensi yang akan dipakai dalam penelitian ini mengikuti langkah-langkah yang didefinisikan pada Tabel 2.1. Langkah-langkah tersebut sudah dirancang oleh Agostini, dkk (2001) yang berdasar pada algoritma usulan Arai, dkk(1989). Signal flow graph algoritma Arai ditunjukkan pada Gambar 3.2 yang didasarkan pada Tabel 2.1. Pada Gambar 3.2, x adalah vektor iyarat input. Vektor a, b, d, e, f adalah isyarat-isyarat yang menjadi input dan output pada masing-masing step algoritma. Vektor f adalah isyarat output. Sesuai dengan algoritma pada Tabel 2.1, vektor a yang menjadi isyarat keluaran step 1 merupakan hasil olahan dari vektor input x. Vektor b merupakan hasil olahan step 2 dengan masukan vektor a, dan begitulah seterusnya untuk vektor d, e, f yang merupakan hasil olahan step algoritma Arai pada Tabel 2.1. Pada akhirnya, step 6 digunakan untuk mengolah isyarat f menjadi vektor output y. Karena modul digunakan untuk mengolah 8 titik, maka lebar bit maksimal data output dapat dihitung sebagai berikut: •
Nilai maksimal untuk tiap titik masukan adalah 28 – 1 = 255 (semua bit 28
29 bernilai '1') •
Nilai maksimal keluaran untuk pengolah 8 titik adalah 8 x 255 = 2040
•
Bilangan biner unsigned untuk 2040 adalah 11111111000 yang mempunyai lebar 11 bit
Dari uraian tersebut didapatkan lebar output 11 bit. Secara umum dapat dirumuskan menjadi persamaan (3.1) sebagai berikut: lebar_out = lebar_in + 2log(jumlah_titik)...................(3.1)
x
aa
b
d
e
f
y
Gambar 3.2 Signal flow graph algoritma DCT Arai Metode akuisisi data input dan pengeluaran output ini diadopsi dari rancangan Sun, dkk(1989) dan ditunjukkan pada Gambar 3.3. Data input dimasukkan secara sekuensial pada register-register input setiap transisi clock naik. Karena DCT 1D mengolah 8 titik data, maka dibutuhkan 8 kali siklus clock
29
30 untuk memasukkan seluruh data. Begitu pula dengan proses pengeluaran data yang dilakukan secara sekuensial. Seluruh data dikeluarkan dalam 8 siklus clock. Jadi, waktu yang dibutuhkan dari proses akuisisi data input sampai pengeluaran output adalah 8 (akuisisi input) ditambah 6(komputasi DCT) dan ditambah 8(pengeluaran) yaitu 22 siklus clock. Berdasarkan Gambar 3.3, pada tesis ini dirancang operasi-operasi aritmetika pada setiap step algoritma DCT untuk dikerjakan secara paralel pada tiap transisi positif clock. 3.3.3. Perancangan pipeline modul DCT-1D. Menurut Lu, dkk(2009), pipelining adalah teknik implementasi algoritma komputasi pada suatu piranti, yang membuat beberapa instruksi dikerjakan dalam waktu bersamaan (overlap). Kebalikan dari teknik pipeline ini adalah single-cycle execution yang hanya mengerjakan satu instruksi pada satu siklus.
Gambar 3.3 Proses akusisi input, komputasi, dan pengeluaran output DCT-1D Modul DCT-1D pada tesis ini bekerja secara sekuensial. Ada dua pilihan untuk merealisasikan sistem komputasi sekuensial ini, yang pertama dengan cara 30
31 single-cycle, yang kedua dengan pipelining. Komputasi DCT-1D sekuensial secara single-cycle akan mengurangi pesat data yang dapat diproses. Sesuai dengan ilustrasi proses single cycle pada Gambar 3.4, akuisisi (pemasukan) data hanya terjadi pada saat clock ke-1 hingga ke 8. Pada fase komputasi dan pengeluaran data output, akuisisi data tidak terjadi, dan saat itu, data tidak diperbolehkan untuk masuk ke dalam modul. Jika ada kelompok 8 titik data berikutnya yang akan diproses, harus ditunggu sampai fase pengeluaran data output selesai. Visualisasi proses single cycle ditunjukkan pada Gambar 3.4. Pada komputasi yang dikerjakan secara pipeline, dalam satu siklus clock ada beberapa proses yang dikerjakan bersamaan. Berkaitan dengan modul DCT yang dirancang, dengan pipeline, proses akuisisi data, komputasi DCT dan pengeluaran data dapat berlangsung bersamaan. Karena itu, pesat data yang masuk dan keluar dari modul menjadi lebih besar dari proses single cycle. Dalam tesis ini, dirancang suatu komputasi DCT yang dapat dikerjakan secara pipeline.
Gambar 3.4 Visualisasi proses DCT-1D dengan eksekusi single-cycle Dalam merancang suatu proses pipeline, diperlukan metode penempatan proses pada waktu yang tepat. Hal itu disebabkan suatu proses memerlukan suatu prasyarat proses sebelumnya, yang harus selesai terlebih dahulu. Misalnya, suatu komputasi DCT 8 titik baru dapat dikerjakan setelah kedelapan data input sudah
31
32 diakuisisi, kemudian data output baru dapat dikeluarkan setelah komputasi DCT selesai. Untuk dapat memenuhi kebutuhan tersebut, proses pipeline untuk modul DCT-1D dirancang sesuai timing diagram yang disederhanakan pada Gambar 3.5. Sesuai Gambar 3.5, terdapat 3 stage pipeline yang dirancang, yaitu akuisisi data input, komputasi DCT, dan pengeluaran data. Pada saat akuisisi kelompok data input pertama (8 titik pertama), komputasi DCT dan pengeluaran data belum berjalan. Komputasi DCT untuk kelompok data pertama dilakukan bersamaan dengan akuisisi kelompok data ke-2. Karena komputasi DCT 1D hanya membutuhkan 6 clock dan proses input membutuhkan 8 clock, pada proses komputasi DCT 1D setelah clock ke-6 terdapat daerah idle. Pada saat itu, yang dikerjakan hanya akuisisi data ke-7 dan ke-8 pada kelompok data ke-2. Proses pipeline yang lengkap dilakukan pada akuisisi kelompok data ke-3. Akuisisi kelompok data ke-3 dilakukan bersamaan dengan komputasi DCT 1D untuk kelompok data ke-2 dan pengeluaran data output DCT untuk kelompok pertama. Rancangan proses pipeline DCT tersebut kemudian dibuat dalam bentuk tabel pipeline. Tabel pipeline akan menjadi panduan dalam implementasi rangkaian dalam bentuk VHDL. Rancangan pipeline ditunjukkan pada Tabel 3.1. Pada Tabel 3.1 terdapat perulangan proses setiap 8 clock. Mulai siklus clock yang ke-17, sudah terdapat pipeline stage yang lengkap, yang terdiri dari input data, komputasi DCT, dan output data. Berdasarkan Tabel 3.1, implementasi pada VHDL dimulai dari clock ke-17. Karena terjadi perulangan setiap 8 clock, pada implementasi di VHDL, proses dibagi dalam 8 state. Tiap state dikerjakan dalam satu siklus clock. Implementasi proses dalam state ditunjukkan pada Tabel 3.2. 32
33
Gambar 3.5 Rancangan timing diagram proses pipeline DCT-1D Tabel 3.1 Tabel pipeline modul DCT-1D clock ke-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
en_dct
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
dct_rdy 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 kelompok pipeline stage data ke1 x0 x1 x2 x3 x4 x5 x6 x7 s1 s2 s3 s4 s5 s6 y0 y1 y2 y3 y4 y5 y6 y7 - 2 x0 x1 x2 x3 x4 x5 x6 x7 s1 s2 s3 s4 s5 s6 y0 y1 y2 y3 y4 y5 y6 y7 - 3 x0 x1 x2 x3 x4 x5 x6 x7 s1 s2 s3 s4 s5 s6 y0 y1 y2 y3 y4 y5 y6 y7 - …n xn = proses input data ke-n sn = step ke-n algoritma DCT 1D yn = proses pengeluaran data ke-n
Tabel 3.2 Delapan state sebagai acuan implementasi state
0
y2 proses yang s1 dikerjakan x0
1 y3 s2 x1
2 y4 s3 x2
3 y5 s4 x3
4 y6 s5 x4
5 y7 s6 x5
6 y0 x6
7 y1 x7
Menggunakan acuan Tabel 3.2, kemudian dapat dibuat kode VHDL dalam delapan state sebagai berikut. • Implementasi state ke-0
33
34 case cnt is when "0000" => -- state ke-0 vin_0<=vin(n)&vin(n)&vin(n)&vin;-->akuisisi x0 ---------------------------------b0<=vin_0+vin_7; -->komputasi step 1 algoritma DCT b1<=vin_1+vin_6; b2<=vin_3-vin_4; b3<=vin_1-vin_6; b4<=vin_2+vin_5; b5<=vin_3+vin_4; b6<=vin_2-vin_5; b7<=vin_0-vin_7; ---------------------------------vout<=s2(p+k downto p)+ofset2;-->pengeluaran y2
•
Implementasi state ke-1
when "0001" => vin_1<=vin(n)&vin(n)&vin(n)&vin; --> akuisisi data input x1 ---------------------------------c0<=b0+b5; --> komputasi step 2 c1<=b1-b4; c2<=b2+b6; c3<=b1+b4; c4<=b0-b5; c5<=b3+b7; c6<=b3+b6; c7<=b7; ---------------------------------vout<=s3(p+k downto p)+ofset3; --> pengeluaran output y3
•
Implementasi state ke-2
when "0010" => vin_2<=vin(n)&vin(n)&vin(n)&vin; --> akuisisi data input x2 ---------------------------------d0<=c0+c3; -->komputasi step 3 algoritma DCT d1<=c0-c3; d2<=c2; d3<=c1+c4; d4<=c2-c5; d5<=c4; d6<=c5; d7<=c6; d8<=c7; ---------------------------------vout<=s4(p+k downto p)+ofset4;--> pengeluaran output y4
•
Implementasi state ke-3
when "0011" => vin_3<=vin(n)&vin(n)&vin(n)&vin; --> akuisisi data input x3 ---------------------------------e0<=d0(k)&d0(k)&d0&"000000000000"; -->komputasi step 4 e1<=d1(k)&d1(k)&d1&"000000000000"; e2<=m3*d2; e3<=m1*d7;
34
35 e4<=m4*d6; e5<=d5(k)&d5(k)&d5&"000000000000"; e6<=m1*d3; e7<=m2*d4; e8<=d8(k)&d8(k)&d8&"000000000000"; ---------------------------------vout<=s5(p+k downto p)+ofset5;--> pengeluaran output y5
•
Implementasi state ke-4
when "0100" => vin_4<=vin(n)&vin(n)&vin(n)&vin;--> akuisisi data input x4 ---------------------------------f0<=e0; -->komputasi step 5 algoritma DCT f1<=e1; f2<=e5+e6; f3<=e5-e6; f4<=e3+e8; f5<=e8-e3; f6<=e2+e7; f7<=e4+e7; ---------------------------------vout<=s6(p+k downto p)+ofset6;--> pengeluaran output y6
•
Implementasi state ke-5
when "0101" => vin_5<=vin(n)&vin(n)&vin(n)&vin;--> akuisisi data input x5 ---------------------------------s0<=f0; -->komputasi step 6 algoritma DCT s1<=f4+f7; s2<=f2; s3<=f5-f6; s4<=f1; s5<=f5+f6; s6<=f3; s7<=f4-f7; ofset0(k downto 1)<=(others=>'0'); ofset0(0)<=f0(p-1); ofset4(k downto 1)<=(others=>'0'); ofset4(0)<=f1(p-1); ofset2(k downto 1)<=(others=>'0'); ofset2(0)<=f2(p-1); ofset6(k downto 1)<=(others=>'0'); ofset6(0)<=f3(p-1); ---------------------------------vout<=s7(p+k downto p)+ofset7;--> pengeluaran output y7 ----------------------------------
•
Implementasi state ke-6
when "0110" => vin_6<=vin(n)&vin(n)&vin(n)&vin; --> akuisisi data input x6 ---------------------------------vout<=s0(p+k downto p)+ofset0; -->pengeluaran output y0 ofset1(k downto 1)<=(others=>'0'); ofset1(0)<=s1(p-1);
35
36 ofset3(k downto 1)<=(others=>'0'); ofset3(0)<=s3(p-1); ofset5(k downto 1)<=(others=>'0'); ofset5(0)<=s5(p-1); ofset7(k downto 1)<=(others=>'0'); ofset7(0)<=s7(p-1);
•
Implementasi state ke-7
when others => vin_7<=vin(n)&vin(n)&vin(n)&vin;--> akuisisi data input x7 ---------------------------------vout<=s1(p+k downto p)+ofset1; --> pengeluaran output y1 ----------------------------------
3.3.4. aritmetika komputasi DCT-1D a. Operasi aritmetika secara umum Operasi aritmetika pada komputasi DCT-1D terdiri dari penjumlahan, pengurangan, dan perkalian. Dalam melakukan operasi-operasi tersebut, pada tesis ini tidak dirancang untai atau modul khusus untuk penjumlah, pengurang, dan pengali khusus. Rancangan DCT pada tesis ini memakai modul aritmetika yang sudah tersedia di dalam FPGA. Penggunaan modul-modul aritmetika di dalam VHDL cukup dilakukan dengan menuliskan operator aritmetika yang lazim digunakan, seperti '+' untuk penjumlahan, ' - ' untuk pengurangan, dan ' *' untuk perkalian. Supaya dalam VHDL dapat digunakan operasi-operasi aritmetika untuk bilangan
bertanda,
digunakan
library
std_logic_arith, std_logic_signed, dan deklarasi library dalam VHDL. library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_signed.all; use ieee.numeric_std.all;
36
VHDL
yang
mendukung,
yaitu
numeric_std. Berikut ini adalah
37 b. Operasi perkalian Pengali yang digunakan pada tesis ini adalah pengali internal yang terdapat pada FPGA.
Sebelum
memutuskan
untuk
memakai
pengali
internal,
perlu
diperhitungkan jumlah pengali yang dibutuhkan untuk keseluruhan operasi kompresi JPEG. Letak-letak perkalian ada pada modul-modul berikut. •
Modul DCT-1D pertama : 5 perkalian
•
Modul DCT-1D kedua : 5 perkalian
•
Modul kuantisasi : 1 perkalian, karena kuantisasi dilakukan secara sekuensial. Berdasarkan uraian tersebut, jumlah pengali yang dibutuhkan ada 11 unit.
Sementara, pengali yang terdapat di dalam FPGA Spartan 3E XC3S500E ada 20 unit. Oleh karena itu, jumlah pengali yang ada di dalam FPGA sudah mencukupi untuk keseluruhan operasi, sehingga tidak perlu membuat modul pengali tersendiri. Pengali yang terdapat pada algoritma DCT maupun proses kuantisasi merupakan bilangan pecahan. Oleh karena itu untuk menjalakan proses perkalian, bilangan pecahan diubah terlebih dahulu menjadi bilangan integer melalui perkalian dengan suatu bilangan penskala 2n. Pada tesis ini, bilangan penskala untuk komputasi DCT adalah 4096. Bilangan pengali yang digunakan pada algoritma DCT1D Arai adalah sebagai berikut. m1 = cos(4*π/16) = 0.70711 m2 = cos(6*π/16) = 0.38268
37
38 m3 = cos(2*π/16)
cos(6*π/16) = 0.54120
m4 = cos(2*π/16)+cos(6*π/16) = 1.3066 Representasi integer dari bilangan pengali diperoleh dengan mengalikan bilangan tersebut dengan 212 dan dibulatkan ke bilangan integer terdekat sebagai berikut. Bilangan yang didapat disandikan dalam bilangan 14 bit bertanda. m1' = round(m1*4096) = 2896 = 00101101010000b, m2' = round(m2*4096) = 1568 = 00011000100000b, m3' = round(m3*4096) = 2217 = 00100010101001b, m4' = round(m4*4096) = 5352 = 01010011101000b. Proses perkalian dilakukan antara bilangan 11 bit keluaran step 3 dengan pengali. Hasil kali disimpan dalam bilangan 24 bit. Bilangan yang tidak dikalikan, digeser ke kiri 12 bit. Berikut implementasi perkalian dalam VHDL. e0<=d0(k)&d0(k)&d0&"000000000000"; e1<=d1(k)&d1(k)&d1&"000000000000"; e2<=m3*d2; e3<=m1*d7; e4<=m4*d6; e5<=d5(k)&d5(k)&d5&"000000000000"; e6<=m1*d3; e7<=m2*d4; e8<=d8(k)&d8(k)&d8&"000000000000";
Untuk mendapatkan hasil kali yang sebenarnya, hasil kali diskala ulang dengan cara dibagi lagi dengan 4096 (212). Proses pembagian dilakukan dengan menggeser 12 bit ke kanan. Penggeseran dilakukan pada saat data akan dikeluarkan ke output. Proses pembagian ini disertai dengan pembulatan. Pembulatan dilakukan ke bilangan bulat terdekat. Bilangan 0.5 ke atas dibulatkan menjadi 1 dan bilangan kurang dari 0.5 dibulatkan menjadi 0. Teknis pembulatan
38
39 dilakukan sebagai berikut. •
Bilangan hasil kali mempunyai lebar 25 bit. Hasil kali yang diharapkan hanya selebar 11 bit. Dari 25 bit tersebut, diambil bit 12 sampai 22.
•
Untuk melakukan pembulatan bilangan pada kelompok bit 22 downto 12 dijumlahkan dengan bit ke 11.
Berikut adalah implementasi teknik tersebut dalam VHDL untuk komputasi keluaran y1. ofset1(10 downto 1)<=(others=>'0'); ofset1(0)<=s1(11); vout<=s1(22 downto 12)+ofset1;
3.3.5. Perancangan DCT-2D Komputasi DCT-2D dilakukan berdasarkan persamaan 2.7. Karena yang akan diproses adalah DCT-2D yang terskala, matriks penskala S2D belum dikalikan terlebih dahulu. Penghitungan DCT-2D merupakan dua tingkat operasi DCT-1D yang disusun sedemikian rupa. Input DCT-1D tingkat kedua berasal dari output DCT-1D tingkat pertama. Jumlah titik operasi kedua DCT sama, yaitu 8 titik. Karena output DCT tingkat pertama mempunyai lebar 10 bit, input DCT tingkat kedua juga mempunyai lebar 10 bit dan output DCT tingkat kedua memiliki lebar 10 ditambah 2log 8 yaitu 13 bit. DCT-1D pada tingkat yang pertama mengoperasikan data-data pada tiap baris citra input. Pada DCT-1D tingkat ke-2, inputnya adalah keluaran DCT-1D, tetapi dioperasikan secara per kolom. Hal ini menghendaki suatu operasi transpose terhadap keluaran DCT-1D tingkat pertama. Untuk melakukan transpose, data keluaran tingkat pertama dimasukkan ke dalam suatu memori terlebih dahulu. Setelah sejumlah data output DCT 1-D untuk baris masuk ke 39
40 dalam memori, data dari memori tersebut dikeluarkan satu persatu secara tertranspose. Ter-transpose berarti data dikeluarkan secara per kolom. Akses terhadap memori tersebut dikendalikan oleh sebuah controller. Skema interkoneksi dua modul DCT-1D ditampilkan pada Gambar 3.6.
Gambar 3.6 Skema interkoneksi 2 stage DCT-1D 3.3.6. Perancangan Transpose Buffer Modul transpose buffer dirancang dari suatu RAM statis. Transpose buffer memiliki jalur data dan alamat. Data tulis dan baca memiliki urutan yang berbeda. Karena itu, modul ini dirancang memiliki pasangan jalur data dan alamat yang terpisah untuk masing-masing operasi baca dan tulis. Rancangan modul transpose buffer ditunjukkan pada Gambar 3.7. Proses tulis dan baca data pada transpose buffer dideskripsikan pada Gambar 3.8. Satu blok data pada DCT mempunyai ukuran 8x8 atau 64 byte. Transpose buffer dirancang untuk dapat menampung dua blok data atau 128 byte. Fungsinya adalah supaya ketika blok pertama baru dibaca, keluaran DCT-1D berikutnya dapat ditampung di blok kedua.
40
41
Gambar 3.7 Rancangan modul transpose buffer
Gambar 3.8 Susunan data input dan output pada transpose buffer: Kotak putih menggambarkan jalur input, kotak abu-abu menggambarkan output. Perancangan transpose buffer dilakukan dengan membuat deskripsi dalam bahasa VHDL sesuai dengan Gambar 3.7 dan 3.8. Cuplikan kode berikut merupakan definisi input dan output transpose buffer dalam bahasa VHDL. entity memori is port( addr_baca: in std_logic_vector(7 downto 0); addr_tls: in std_logic_vector(7 downto 0); data_tls: in std_logic_vector(lebar_data downto 0); data_baca: out std_logic_vector(lebar_data downto 0); we:in std_logic; clk: in std_logic ); end entity;
41
42 Definisi input dan output pada transpose buffer tersebut diikuti dengan definisi sifat yang dirancangkan pada transpose buffer. Sifat tersebut yaitu transpose buffer memiliki pasangan bus data dan alamat untuk proses baca maupun tulis. Sifat tersebut dijelaskan pada potongan program berikut. --proses tulis process(clk) begin if(falling_edge(clk) and we='1') then mem(conv_integer(addr_tls)) <= data_tls; end if; end process; --proses baca data_baca<=mem(conv_integer(addr_baca));
3.3.7. Perancangan Pengendali DCT-2D Pengendali berfungsi untuk menghasilkan isyarat enable untuk DCT-1D tingkat dua. Selain itu modul ini berfungsi untuk menghasilkan alamat tulis dan alamat baca modul transpose buffer. Seperti yang telah dibahas pada bagian perancangan DCT-2D, data untuk input DCT-1D tingkat dua baru dikeluarkan dari transpose buffer saat output DCT tingkat pertama yang tersimpan pada buffer mencapai jumlah tertentu. Untuk menentukan secara spesifik waktu mulai pengiriman data dari transpose buffer, dipergunakan aturan sebagai berikut. a) Data dikirimkan ke modul DCT-1D kedua secara per kolom, maka pada saat pengiriman suatu larik pada kolom, jumlah data pada kolom itu harus lengkap sejumlah 8 titik. b) Berdasarkan aturan tersebut, data dari transpose buffer mulai dikeluarkan setelah kolom 0 baris ke-6 terisi data dari DCT-1D pertama. Visualisasi proses tersebut ditampilkan pada Gambar 3.9. Berdasarkan Gambar 3.9, lokasi tulis merupakan alamat yang dihasilkan oleh unit controller untuk menunjuk lokasi memori yang akan ditulisi data keluaran DCT 1D. Data 42
43 yang disimpan tersebut kemudian dikeluarkan secara transpose dengan isyarat lokasi baca sebagai penunjuk lokasi memori yang akan dibaca. Data mulai dikeluarkan pada saat penulisan data dengan koordinat (6,2) pada citra. Fitur ini dirancang dengan mendeskripsikan dalam program VHDL.
Gambar 3.9 Visualisasi input dan output data menuju dan dari transpose buffer Berikut adalah definisi isyarat untuk mengakses alamat yang tertranspose. Alamat dengan urutan ter-transpose dihubungkan pada alamat baca (a_out). a_out(5 downto 3)<=a_out1(2 downto 0); a_out(2 downto 0)<=a_out1(5 downto 3); a_out(7 downto 6)<=a_out1(7 downto 6);
Pengaksesan alamat tulis dilakukan pada proses dct_proc pada VHDL ..... elsif(rising_edge(clk))then en_dct<=ctr_en; if(dct_rdy='1')then we<='1'; if(cntia="111") then cntib<=cntib+1; cntia<="000"; else cntia<=cntia+1; end if; if(a_in1="00111111")then en2<='1'; a_in1<=a_in1+1; elsif(a_in1="01111111")then a_in1<="00000000"; else a_in1<=a_in1+1;
43
44 end if; .....
Pengaksesan alamat baca dilakukan pada proses yang terpisah, yaitu dct2_proc dct2_proc: process(clk,rst,en2) begin if(rst='1')then a_out1<="01111111"; en_dct2<='0'; elsif(rising_edge(clk))then if(en2='1') then en_dct2<='1'; if(a_out1="01111111")then a_out1<="00000000"; else a_out1<=a_out1+1; end if; else en_dct2<='0'; end if; end if; end process;
3.3.8. Unit Zigzag Data dikeluarkan dari modul DCT-2D secara satu persatu. Urutan pengeluarannya dilakukan secara Zigzag. Pada penelitian ini, untuk membuat data keluar secara zigzag, data ditampung pada zigzag buffer setelah keluar dari DCT2D. Zigzag buffer dirancang seperti transpose buffer, yaitu SRAM yang mempunyai bus data baca dan tulis serta bus alamat baca dan tulis. Sequence alamat baca dan tulis dihasilkan oleh unit controller. Bus alamat tulis diakses secara linear, tetapi bus alamat baca diakses dalam urutan alamat yang zigzag seperti pada Gambar 2.2 dan 2.3. Ukuran modul tersebut adalah 128 byte atau dua blok, dengan tujuan jika blok ke-1 sedang dibaca, controller akan mengakses blok ke-2 untuk ditulisi. Begitu pula dengan sebaliknya. Data dari buffer mulai dibaca setelah data ke-28 dari keluaran DCT-2D ditulis ke memori, untuk menghindari data pada alamat yang belum ditulis ikut dikirim lebih dahulu. Demikian cuplikan kode VHDL 44
45 untuk fungsi ini
if(a_in2a(5 downto 0)="011100")then --> jika address input =28=011100b rom_rd<='1'; --> flag tanda buffer siap dibaca
. . . . . .
elsif(rising_edge(clk) and rom_rd='1')then --> flag aktif, if(a_out2a="01111111")then a_out2a<="00000000"; else a_out2a<=a_out2a+1; --> increment ROM zigzag end if; end if;
Bilangan zigzag dihasilkan oleh suatu unit generator zigzag. Unit ini berbentuk suatu ROM yang didalamnya tersimpan bilangan dalam urutan zigzag sesuai Gambar 2.2 dan 2.3. Jika bus alamat ROM zigzag diakses secara linear, ROM akan mengeluarkan data zigzag pada bus datanya. Bus data ROM zigzag ini dihubungkan ke bus alamat baca zigzag buffer. Struktur modul zigzag selengkapnya ditunjukkan pada Gambar 3.10. 3.3.9. Perancangan Quantizer Quantizer pada dasarnya adalah suatu untai pembagi. Supaya dapat diimplementasikan pada FPGA, operasi pembagian diubah menjadi perkalian. Nilai pengali didapat dari 1/pembagi. Nilai kuantisasi pada Tabel 2.2 adalah nilai pembagi. Setelah diubah menjadi pengali, matriks kuantisasi Qk ditunjukkan pada persamaan (3.2). Masukannya berasal dari output unit zigzag. Besarnya masukan sama dengan keluaran DCT-2D. Karena nilai output DCT-2D adalah nilai yang terskala, nilai pengali adalah hasil penskalaan ulang dari matriks Qk.
45
46
Gambar 3.10 Struktur unit zigzag
Qk =
[
0.0625 0.0833 0.0714 0.0714 0.0555 0.0416 0.0204 0.0138
0.0909 0.0833 0.0769 0.0588 0.0454 0.0285 0.0156 0.0108
0.1 0.0714 0.0625 0.0454 0.027 0.0181 0.0128 0.0105
0.0625 0.0526 0.0416 0.0344 0.0178 0.0156 0.0114 0.0102
0.0416 0.0384 0.025 0.0196 0.0147 0.0123 0.0097 0.0089
0.025 0.0172 0.0175 0.0114 0.0091 0.0096 0.0082 0.01
0.0196 0.0166 0.0144 0.0125 0.0097 0.0088 0.0083 0.0097
0.0163 0.0181 0.0178 0.0161 0.0129 0.0108 0.0099 0.0101
]
................. ...(3.2)
Vektor penskala s didapat dari nilai-nilai bukan nol matriks S pada persamaan (2.3) dan disusun pada persamaan (3.3)
s=
[] c4 c7 /c6 c6 /c4 c5/c2 c4 c3/c2 c2/c4 c1 /c6
dan nilai pengali terskala Qs didapat dengan cara
46
.......................................(3.3)
47 Qs = Qk * (s*s')............................................(3.4) Nilai Qs masih berbentuk bilangan pecahan. Untuk mendapatkan representasi integernya, digunakan cara yang sama dengan pengali pada DCT. Masing-masing bilangan pada Qs dikalikan dengan 4096 menjadi Qis pada persamaan (3.5). Qis = Qs x 4096.......................................(3.5) dan dihasilkan
Qis =
….........................(3.6)
Nilai Qis inilah yang akan disimpan di ROM pengali dan dikalikan dengan keluaran DCT-2D. Qis dikodekan menggunakan bilangan 8 bit bertanda. Karena data yang dikuantisasi berasal dari zigzag buffer, maka alamat pada ROM pengali juga diakses secara zigzag. ROM zigzag sama dengan ROM pada zigzag buffer. Perkalian dilakukan secara sekuensial pada tiap byte data yang keluar dari DCT2D. Nilai pengali juga dikeluarkan secara sekuensial satu demi satu dari ROM pengali. Hasil kali pada quantizer digeser 12 bit ke kanan untuk mendapatkan hasil kali yang sebenarnya. Skema kuantisasi ditunjukkan pada Gambar 3.11 berikut. Sebagaimana pengali pada DCT, pengali pada quantizer juga diambil dari pengali internal FPGA. Implementasi quantizer pada VHDL ditunjukkan pada cuplikan source code berikut. hasil_kali<=dct_in*rom_in; quant_out<=hasil_kali(20 downto 12)+(ofset&hasil_kali(11));
47
48 Quantized Value x 4096 Zigzag buffer
14 bit
22 bit
x
Out
8 bit
hasil_kali (20..12) 9 bit
9 bit
+
>>12
yq
Quantized Value
yq'
Post scaler & quantizer
y
yq(11) hasil_kali (11)
ScalerQuantizer ROM
Gambar 3.11 Skema kuantisasi dan penskalaan ulang 3.3.10. Penanda nilai DC Nilai DC terletak pada posisi (0,0) dari bidang 8x8. Setiap kali mengeluarkan data dari posisi tersebut, sistem akan mengaktifkan 1 bit penanda nilai DC. Penanda ini dihasilkan oleh modul controller. Sinyal penanda diaktifkan saat output DCT mengeluarkan data pada posisi (0,0). Data pada posisi tersebut dikeluarkan bersamaan dengan pemasukan data input pada alamat 28. Implementasi fitur ini di VHDL adalah sebagai berikut. if(a_in2a(5 downto 0)="011100")then rom_rd<='1'; dc<='1'; a_in2a<=a_in2a+1; elsif(a_in2a="01111111")then a_in2a<="00000000"; dc<='0'; else a_in2a<=a_in2a+1; dc<='0'; end if;
3.3.11. Perancangan penyandi entropi Data output dari quantizer akan masuk penyandi entropi. Data yang sudah diatur secara zigzag ini dimasukkan secara paralel-sekuensial ke dalam entropy encoder. Lebar bit data yang masuk penyandi entropi adalah 9 bit. Keluaran 48
49 penyandi entropi sebenarnya adalah bit-stream yang dikeluarkan secara serial tiap satu bit. Pada rancangan ini, bit-bit keluaran penyandi entropi dikelompokkan tiap 8 bit (bit-stuffed) dan dikeluarkan secara paralel 8 bit. Rancangan modul penyandi entropi secara umum ditunjukkan pada Gambar 3.12.
Gambar 3.12 Rancangan modul penyandi entropi Penyandi entropi terdiri dari modul penyandi Huffman dan bit-stuffer. Dalam modul sandi Huffman terdapat beberapa submodul yaitu AC coder, DC differentiator, DC coder, dan code multiplexer. Bit stuffer adalah submodul untuk pemaketan data. Struktur penyandi Huffman ditunjukkan pada Gambar 3.13. 3.3.12. AC Coder AC coder merupakan bagian dari penyandi entropi yang berfungsi untuk menyandikan koefisien AC dari data output quantizer. Bagian-bagian dari AC coder adalah penyandi RLE, pemeta kategori, generator simbol data, dan generator kode Huffman. Struktur AC coder ditampilkan pada Gambar 3.14. Sandi komponen AC keluaran penyandi mempunyai panjang 40 bit yang terdiri dari 16 bit sandi Huffman, 4 bit panjang sandi, 16 bit simbol, dan 4 bit panjang simbol. Sandi Huffman dan simbol masing-masing adalah sandi dengan panjang variabel (Variable Length Code) dan panjang maksimum 16 bit. Karena panjang sandi variabel, perlu didampingi dengan nilai 4 bit (0-15) yang berisi informasi panjang sandi.
49
50
Gambar 3.13 Diagram blok sub modul sandi Huffman
3.3.13. Penyandi RLE RLE (Run Length Encoding) diterapkan pada hasil kuantisasi karena pada data tersebut banyak deretan bilangan nol. Cara kerja RLE sebagai berikut. a)
Pada deretan yang terdiri 63 bilangan koefisien AC DCT terdapat bilangan nol dan bukan nol.
b)
Pada setiap bilangan bukan nol, dibuat suatu susunan bilangan (R,B). Dengan R adalah jumlah bilangan nol sebelum bilangan tersebut dan B adalah bilangan bukan nol itu sendiri.
c)
Jika terdapat deretan bilangan nol yang jumlahnya kurang dari 16, bilangan nol tidak disandikan.
d)
Jika terdapat jumlah bilangan nol lebih dari 15, maka pada bilangan nol ke16, dibuat sandi (15,0).
50
51
Gambar 3.14 Diagram blok penyandi komponen AC (AC coder) Realisasi RLE dalam rangkaian digital adalah sebuah pencacah 4-bit. Pencacah ini digunakan untuk mencacah jumlah nilai nol yang masuk sebelum ada nilai bukan nol. Pencacah ini akan bekerja jika data yang masuk bernilai nol. Untuk mendeteksi adanya bilangan nol, digunakan rangkaian gerbang OR. Rangkaian RLE dirancang sesuai Gambar 3.15. Output utama rangkaian ini adalah nilai run. Output valid digunakan untuk menandai bahwa data valid atau tidak. Suatu data disebut valid, jika data tersebut non zero, merupakan koefisien DC, atau nilai run sebelumnya sudah 15 (1111b). Data akan diambil oleh unit sesudahnya hanya jika data tersebut valid. 3.3.14. Pemeta Kategori dan Generator Simbol Data-data yang masuk ke dalam penyandi entropi, selain disandikan dengan teknik RLE, juga dipetakan kategorinya. Pemetaan kategori dilakukan berdasarkan Tabel 2.3. Output unit ini adalah kategori data yang masuk ke dalam penyandi entropi dan diberi simbol cat. 51
52
Gambar 3.15 Rangkaian penyandi RLE Berdasarkan Tabel 2.3, ada 16 kategori data yang akan dikelompokkan. Implementasi pemeta kategori ini adalah suatu look up table yang di dalam VHDL berbentuk konstruksi if .. then. Karena ada 16 kategori, maka keluaran submodul ini mempunyai lebar 4 bit. cat dan run digabungkan menjadi bilangan 8 bit dan menjadi input bagi penyandi Huffman. Untuk menandai data secara lebih spesifik, terutama untuk data yang berada pada kategori yang sama, setiap data diberi simbol berukuran 16 bit. Simbol ini berbeda-beda untuk data yang berada pada kategori yang sama. Karena itu, penggunaan simbol ini harus bersama-sama dengan kategori. 3.3.15. DC differentiator Koefisien DC disandikan dengan prosedur yang berbeda dengan koefisien AC. Representasi bilangan DC yang disandikan adalah selisih antara koefisien DC pada blok yang sedang diolah dan koefisien DC pada blok sebelumnya. Khusus untuk blok 8x8 yang pertama, representasi bilangan DC adalah koefisien DC-nya. Untuk membedakan antara koefisien DC dengan yang lain, digunakan sinyal kendali DC. Berikut adalah cuplikan kode VHDL untuk implementasi DC 52
53 differentiator. diff<=din-dctemp; process(clk,rst,dc) begin if(rst='1') then dctemp<=(others=>'0'); elsif(rising_edge(clk) and dc='1')then dctemp<=din; end if; end process;
3.3.16. Penyandi Koefisien DC Representasi koefisien DC yang disandikan adalah nilai bedanya. Proses penyandian sedikit berbeda dengan koefisien AC.
Gambar 3.16 Skema penyandi koefisien DC Penyandian DC dan AC sama-sama menggunakan pemeta kategori dan simbol yang sama. Perbedaannya, penyandian DC tidak menggunakan RLE, sehingga kode Huffman untuk DC didapatkan dari penyandian kategorinya saja. Penyandian kategori untuk memperoleh sandi Huffman DC menggunakan tabel yang berbeda dari penyandian AC. Dalam implementasinya pada VHDL, pembuatan sandi Huffman dikerjakan dalam suatu look-up table. Implementasi rangkaian penyandi DC ditampilkan pada Gambar 3.16.
53
54 3.3.17. Code Multiplexer Dalam rangkaian terdapat penyandi koefisien AC dan DC. Masing-masing jenis koefisien dikeluarkan pada waktu yang berbeda. Koefisien DC hanya dikeluarkan pada saat posisi data (0,0). Selain saat itu, yang dikeluarkan adalah koefisien AC. Untuk melewatkan kode untuk koefisien AC dan DC dalam satu jalur, digunakan suatu unit multiplekser pada Gambar 3.13. MUX yang digunakan adalah 2 ke 1 jalur dengan panjang bit tiap jalur 40 bit. Untuk memilih jalur MUX, digunakan masukan select yang dihubungkan dengan masukan DC. Masukan DC ini untuk menandai koefisien yang aktif adalah koefisien DC. 3.3.18. Bit Stuffer Keluaran penyandi entropi sebenarnya bersifat variable length. Pada modul penyandi koefisien AC dan DC, keluaran dibuat fixed length 40 bit untuk mempermudah proses penyandian. Untuk membuat suatu data variable length dari data 40 bit tersebut, dibuat suatu modul yang dinamakan bit stuffer. Modul bit stuffer mengubah data paralel keluaran modul penyandi koefisien AC dan DC menjadi data serial. Data serial berasal dari data sym dan huff. Panjang data serial untuk sym ditentukan oleh cat dan untuk huff ditentukan oleh len. Gambar 3.17 menunjukkan interkoneksi penyandi koefisien dengan bit stuffer.
Rangkaian bit stuffer pada dasarnya merupakan konverter paralel ke
serial. Pada bit stuffer, panjang data yang dikeluarkan secara serial bisa diatur. Data yang akan dikeluarkan secara serial adalah huff dan sym. Keduanya memiliki panjang 16 bit. Melalui bit stuffer, panjang data serial yang dikeluarkan tidak selalu 16 bit, tetapi tergantung pada panjang yang ditentukan masukan len dan cat.
54
55 sym(16) cat (4) Penyandi AC/ DC
Controllable parallel to serial (bit stuffer)
Serial out
len (4) huff(16)
Gambar 3.17. Interkoneksi penyandi dengan bit stuffer
3.4. Metode Pengujian Sistem Sistem yang telah dirancang kemudian akan diuji unjuk kerjanya. Pengujian dilakukan pada beberapa modul secara individual dan gabungan beberapa modul. Pengujian juga dapat dilakukan secara simulasi dan secara hardware. Target pengujian adalah didapatkan parameter-parameter berikut, a. spesifikasi kecepatan dan latensi pipeline modul secara keseluruhan maupun masing-masing modul secara individual, b. ketelitian komputasi untuk keseluruhan modul secara terintegrasi maupun secara individu, c. hasil sintesis rangkaian dari VHDL yang menghasilkan informasi mengenai resource FPGA yang digunakan, d. perbandingan hasil kompresi yang dilakukan hardware dan hasil kompresi yang dilakukan oleh software komputer, e. perbandingan frame rate antara hardware yang dirancang dan IC komersial. Skema pengujian ditunjukkan pada Gambar 3.18. Objek yang digunakan 55
56 sebagai data uji adalah data citra yang sebenarnya.
Gambar 3.18 Skema pengujian simulasi dan hardware Citra yang diujikan berupa citra grayscale dengan format bitmap. Citra tersebut digunakan untuk pengujian melalui simulasi maupun hardware melalui prosedur berikut. a. Prosedur simulasi a.1. Persiapan test bench simulasi Untuk melakukan simulasi, citra objek diubah menjadi file testbench VHDL menggunakan
suatu
program Matlab.
File
testbench
berfungsi
mengeluarkan stimulus untuk rangkaian yang diuji. Karena dibentuk dari citra, data-data stimulus merupakan representasi nilai piksel dari citra. Konversi citra BMP ke kode VHDL ditunjukkan melalui skema pada Gambar 3.20. Sebagai nilai pembanding, data-data yang sama juga digunakan sebagai input program (DCT, kuantisasi, penyandi entropi) versi Matlab. Berdasarkan skema kompresi JPEG dari Wallace (1990) dan ditunjukkan pada Gambar 3.20, nilai-nilai piksel yang
56
57 dikodekan dengan bilangan tak bertanda 8 bit (0 -255) harus dikurangi dengan 128 sebelum masuk ke penyandi JPEG. Dengan begitu piksel menjadi terkodekan menggunakan bilangan 8 bit bertanda. Solomon (2004) menjelaskan tentang teknis pengelompokan data pixel pada citra yang akan dikompresi. Kompresi citra dilakukan terhadap setiap blok citra yang berukuran 8x8. Sebelum dilakukan konversi, citra dibagi menjadi beberapa blok yang berukuran 8x8. Data pada blok diurutkan pada tiap kolomnya. Setelah suatu blok diproses, dilanjutkan dengan blok yang berada di bawahnya pada kolom yang sama. Jika pemrosesan sudah sampai pada blok terakhir pada kolom tersebut, dilanjutkan pada blok pada kolom sebelah kanannya. a.2. Proses simulasi Simulasi diawali dengan pembuatan source code VHDL untuk test bench. Prosesnya ditunjukkan pada Gambar 3.19. Setelah test bench dipersiapkan, proses selanjutnya adalah melakukan simulasi. Simulasi dijalankan menggunakan software ISE simulator. a.3. Hasil Simulasi Simulasi akan menghasilkan dua macam output berikut. a.3.1 Diagram pewaktuan Diagram pewaktuan digunakan untuk menganalisis pewaktuan data output dan nilai dari beberapa sampel data. Dari diagram pewaktuan tersebut dapat diketahui bahwa output sudah muncul pada saat yang tepat atau tidak. Selain itu juga dapat diketahui besarnya nilai output sudah seperti yang diharapkan atau tidak. a.3.2. File teks yang berisi data yang sudah terkompresi 57
58 Simulator VHDL pada penelitian ini dirancang untuk menghasilkan output berupa teks file. Teks file ini berisi data hasil DCT 2D, kuantisasi, dan data hasil kompresi. Output ini berfungsi untuk menghitung tingkat akurasi komputasi yang telah dilakukan.
Gambar 3.19 Skema konversi bitmap ke VHDL b. Prosedur pengujian hardware Untuk menguji hardware diperlukan suatu antarmuka untuk mengirimkan data citra ke FPGA dan membaca data hasil kompresi dari FPGA. Antarmuka
58
59 yang digunakan pada penelitian ini adalah port serial atau UART. UART dipilih karena mudah diimplementasikan untuk koneksi PC dan FPGA. Pada PC, digunakan konverter USB ke serial untuk mendapatkan port serial. Evaluation board FPGA yang digunakan juga sudah menyediakan interface ke UART. Kerugian pengujian data menggunakan UART adalah kecepatan rangkaian menjadi turun untuk menyesuaikan dengan kecepatan UART. Oleh karena itu, metode pengujian hardware ini digunakan untuk menguji validitas data saja dan bukan kecepatan rangkaian sesungguhnya. Untuk mengetahui kecepatan rangkaian, digunakan pengujian melalui simulasi.
data_in RX Dari PC
RX register
hasil kompresi Rangkaian yang diuji
S/P
TX register
TX Ke PC
Gambar 3.20. Diagram blok pengujian rangkaian Diagram blok pengujian rangkaian menggunakan UART ditunjukkan pada Gambar 3.20. Berdasarkan gambar 3.20, terdapat 3 modul tambahan yaitu modul TX, modul RX dan S/P atau konverter serial ke paralel. Data yang akan dikompresi berasal dari file citra. Nilai piksel citra tersebut kemudian dikirim ke rangkaian kompresi. Data yang dimasukkan ke rangkaian berasal dari data yang dikirim oleh PC (komputer) lewat UART (TX). Setelah data tersebut lengkap 8 bit, data dimasukkan ke rangkaian yang akan diuji. Rangkaian yang akan diuji mempunyai keluaran serial, tetapi data yang akan dikirimkan lewat UART harus ditampung di dalam register RX dahulu. Oleh karena itu dibuat rangkaian S/P
59
60 untuk mengkonversi keluaran serial rangkaian kompresi menjadi data paralel 8 bit. Data inilah yang dimasukkan ke dalam register RX dan dikirim lewat jalur RX port serial. Data yang diterima PC melalui port serial akan disimpan di dalam sebuah file biner. File tersebut merupakan representasi hasil kompresi citra. Pada tesis ini, hasil kompresi tidak disimpan dalam format file resmi JPEG yang disebut JFIF (JPEG File Interchange Format), tetapi dalam bentuk raw data. Program Cutecom yang berjalan di atas sistem operasi Linux digunakan untuk mengirim dan menerima data melalui port serial. 3.5 Source code dan hirarkinya Implementasi rangkaian pada FPGA dilakukan dengan bahasa VHDL. Untuk memudahkan pembuatan koneksi antar komponen atau modul, masingmasing modul dibuatkan source code tersendiri, misalnya modul DCT 1D disimpan dalam file dct3_pl.vhd kemudian quantizer disimpan dalam file quantizer.vhd dan seterusnya. Kumpulan file tersebut tersusun dalam suatu hirarki rangkaian. Keterangan mengenai bentuk hirarki rangkaian dan source code yang lebih detail dijelaskan pada Lampiran B.
60
61 BAB IV HASIL PENELITIAN DAN PEMBAHASAN 4.1. Simulasi Rancangan Pengujian hasil perancangan sistem kompresi citra salah satunya dilakukan dengan simulasi menggunakan perangkat lunak Xilinx ISE simulator. Simulasi secara perangkat lunak dilakukan pada satu rangkaian kompresi secara utuh dan pada tiap-tiap modul pada rangkaian kompresi. Data input berasal dari citra grayscale dengan ukuran 160X120. Timing diagram yang dihasilkan diamati untuk melakukan verifikasi terhadap bentuk gelombang masing-masing isyarat. Data output yang dihasilkan dari simulasi disimpan di dalam suatu file dan dibandingkan dengan keluaran komputasi algoritma yang sama pada Matlab. 4.1.1. Simulasi Modul DCT-1D a. Analisis perhitungan DCT-1D Data yang menjadi input untuk menguji modul ini secara simulasi adalah data dari citra grayscale berukuran 8x8 yang disampel dari citra asal 160x120. Citra asal ditunjukkan pada Gambar 4.1.
Gambar 4.1 Citra asal untuk pengujian sistem kompresi Dari citra asal, disampel sejumlah 8 x 8 piksel untuk pengujian DCT-1D. Data input untuk DCT-1D ditampilkan pada Tabel 4.1. Label kn berarti kolom ke-
61
62 n, sedangkan bn berarti baris ke-n. Data input dari citra dikurangi dengan 128 sebelum dimasukkan ke sistem kompresi untuk mendapatkan format data bilangan 8 bit bertanda. Nilai yang sudah dikurangi 128 ditampilkan pada Tabel 4.2. Tabel 4.1 Nilai 8 x 8 piksel sebelum dikurangi 128 untuk pengujian DCT-1D b0 b1 b2 b3 b4 b5 b6 b7
k0 k1 k2 k3 k4 k5 k6 k7 170 135 87 86 86 141 160 170 166 139 82 83 84 149 165 173 157 143 77 87 118 133 178 174 161 131 87 87 116 148 185 185 156 114 87 83 113 159 183 189 144 105 84 84 124 159 184 186 146 89 82 86 122 179 177 179 142 74 69 83 154 167 179 27
Tabel 4.2 Nilai pixel sesudah dikurangi 128 untuk pengujian DCT-1D k0 b0 b1 b2 b3 b4 b5 b6 b7
k1 42 38 29 33 28 16 18 14
7 11 15 3 -14 -23 -39 -54
k2 k3 k4 k5 k6 k7 -41 -42 -42 13 32 42 -46 -45 -44 21 37 45 -51 -41 -10 5 50 46 -41 -41 -12 20 57 57 -41 -45 -15 31 55 61 -44 -44 -4 31 56 58 -46 -42 -6 51 49 51 -59 -45 26 39 51 -101
Nilai-nilai piksel pada Tabel 4.2 kemudian akan diproses oleh modul DCT1D. Modul DCT-1D melakukan komputasi untuk tiap 8 pixel. Pixel yang digunakan sebagai input adalah pixel dalam satu kolom, dari baris 0 sampai 7, kemudian dilanjutkan kolom berikutnya. Tabel 4.3 menampilkan perbandingan hasil komputasi DCT-1D dengan simulasi VHDL dan Matlab. Berdasarkan Tabel 4.3, ketelitian komputasi DCT-1D di VHDL dapat dihitung menggunakan mean square error (MSE). MSE dihitung menggunakan persamaan (4.1) berikut. MSE = Σin=1 (xi_data -xi_acuan)2 / n ..........................(4.1) Variabel xi_data adalah data yang didapat dari simulasi VHDL dan xi_acuan 62
63 adalah data acuan hasil perhitungan pada Matlab. Variabel n adalah banyaknya data. Dengan ukuran 8x8 pixel, banyaknya data adalah n=64. Berdasarkan data pada Tabel 4.3a, didapatkan tabel selisih untuk tiap titik yang ditunjukkan pada Tabel 4.3b dan mean square error untuk DCT-1D sebesar 0.069219. Tabel 4.3 Perbandingan komputasi DCT-1D pada VHDL dan Matlab: (a) Hasil komputasi dan (b) Selisih komputasi VHDL dan Matlab (a)
b0 b1 b2 b3 b4 b5 b6 b7
k0 k1 k2 k3 vhdl Matlab vhdl Matlab vhdl Matlab vhdl Matlab 218 218.00 -94 -94.00 -369 -369.00 -345 -345.00 103 102.57 247 246.82 27 27.00 6 5.68 -1 -3 -0.76 -76 -75.60 -29 -28.61 -3.12 6 -3 6.40 -10 -9.56 36 36.31 -3.47 16 16.00 -22 -22.00 5 5.00 -1 -1.00 3 2.93 7 7.11 10 9.59 9 9.47 -9 -9.24 4 3.60 -7 -7.39 1 1.12 0 0 -1 0 0.10 -0.37 -0.90 0.32
b0 b1 b2 b3 b4 b5 b6 b7
k4 k5 k6 k7 vhdl Matlab vhdl Matlab vhdl Matlab vhdl Matlab -107 -107.00 211 211.00 387 387.00 259 259.00 -198 -198.19 -131 -131.49 -62 -61.90 251 250.72 -7 -6.68 27 27.16 -64 -63.65 -308 -307.81 -75 -74.68 26 26.35 -14 -14.44 223 222.94 21 21.00 -5 3 -5.00 3.00 -141 -141.00 1 1 2 88 88.52 0.91 0.84 1.90 29 28.68 -25 -25.16 6 5.65 -46 -46.19 0 -0.03 0 0.30 -2 -1.56 10 9.82
(b) k0 b0 b1 b2 b3 b4 b5 b6 b7
k1 0 -0.43 0.24 0.4 0 -0.07 -0.24 0.1
k2 0 -0.18 0.4 0.44 0 0.11 -0.4 -0.37
k3 0 0 0.39 0.31 0 -0.41 -0.39 0.1
k4 0 -0.32 -0.12 -0.47 0 0.47 0.12 0.32
63
k5 0 -0.19 0.32 0.32 0 -0.09 -0.32 -0.03
k6 0 -0.49 0.16 0.35 0 -0.16 -0.16 0.3
k7 0 0.1 0.35 -0.44 0 -0.1 -0.35 0.44
0 -0.28 0.19 -0.06 0 0.52 -0.19 -0.18
64 b. Analisis diagram pewaktuan Simulasi rangkaian DCT-1D menghasilkan diagram pewaktuan yang berfungsi untuk verifikasi kebenaran isyarat yang dihasilkan. Parameter yang perlu diamati pada diagram pewaktuan adalah posisi pewaktuan dan nilai isyarat keluaran. Parameter tersebut digunakan untuk menilai kesesuaian hasil simulasi dengan rancangan. Masukan untuk analisis diagram pewaktuan ini adalah sampel citra dengan ukuran 16 x 16. Isyarat kendali pada DCT-1D adalah ten. Isyarat tersebut digunakan untuk meng-enable data input untuk masuk ke sistem. Isyarat status keluaran DCT-1D adalah rdy. Status tersebut adalah aktif jika bernilai logika 1. Sinyal rdy akan aktif jika ada data hasil komputasi DCT-1D yang akan dikeluarkan. Sinyal rdy harus aktif satu siklus sebelum data dikeluarkan. Kedua isyarat tersebut harus mempunyai lebar siklus pewaktuan yang sama. Diagram pewaktuan ditunjukkan pada Gambar 4.2. Tampilan semua isyarat ditunjukkan pada Gambar 4.2(a). Pada Gambar 4.2(b) ditunjukkan bahwa isyarat ten diaktifkan dari t=0 sampai t=5120 ns untuk memasukkan 256 data dengan pesat data 50 Mbyte per detik atau periode 20 ns. Data berjumlah 256 karena ada 16 x 16 piksel yang diujicobakan. Pada Gambar 4.2(c) terlihat sinyal rdy baru muncul pada saat t = 270.1 ns yang menandakan adanya latency pada sistem karena penerapan pipelining. Sinyal rdy akan berlogika 0 kembali pada t = 5410.1 ns sehingga lebar logika 1 sinyal rdy adalah 5140 ns. Lebar sinyal rdy lebih besar 20 ns (satu periode) dari ten karena sinyal tersebut diaktifkan satu periode sebelum data hasil DCT-1D dikeluarkan. Hal ini sengaja dirancang untuk memberi persiapan untai sesudah DCT-1D untuk 64
65 melakukan persiapan pengambilan sampel data keluaran DCT-1D. Gambar 4.2(d) memperlihatkan proses pengambilan data input. Data input diambil tiap transisi clock naik. Data-data input simulasi dituliskan pada source test bench VHDL. Pada test bench, data input diubah tiap transisi clock turun. Pengeluaran data output ditunjukkan pada Gambar 4.2(e). Data dikeluarkan tiap transisi clock naik.
(a)
(b)
(c) 65
66
(d)
(e) Gambar 4.2 (a – e). Diagram pewaktuan modul DCT-1D: (a) tampilan semua sinyal pada DCT-1D, (b) pengamatan lebar sinyal enable (c) pengamatan sinyal rdy (d) pengambilan data input, dan (e) pengeluaran data output Urutan pengeluaran data adalah data pada suatu kolom dikeluarkan baris per baris. Setelah semua data pada kolom tersebut sudah dikeluarkan, dilanjutkan ke kolom selanjutnya.
66
67 4.1.2. Simulasi Rangkaian DCT-2D DCT-2D dibentuk oleh dua rangkaian DCT-1D yang dihubungkan oleh suatu transpose buffer dan dikendalikan oleh suatu rangkaian controller. Dua modul DCT-1D yang diterapkan di bagian ini adalah sama, tetapi hanya berbeda pada lebar bit yang diproses saja. Untuk bagian transpose buffer dan controller, pengamatan kinerja dilakukan berdasarkan diagram pewaktuan saja. Sedangkan untuk DCT-2D pengamatan kinerja juga dilakukan dengan analisis akurasi hasil penghitungan. a. Pengujian Transpose buffer dan controller. Transpose buffer digunakan untuk menyimpan data keluaran DCT-1D stage pertama untuk dikirim sebagai input untuk DCT-1D stage kedua sehingga membentuk operasi DCT-2D. Input transpose buffer adalah data dengan urutan normal, dan keluarannya adalah data dengan urutan yang sudah ter-transpose. Untuk menjalankan transpose buffer, dibutuhkan suatu pengendali. Tugas pengendali adalah memberikan alamat tulis dan alamat baca untuk transpose buffer dengan trigger yang berasal dari sinyal status (rdy) keluaran dari DCT-1D. Berdasarkan hasil simulasi pada unit transpose dan controller, urutan data keluaran unit transpose sudah merupakan transpos dari urutan data input. Hasil simulasi pada saat awal pengisian data ditampilkan pada Gambar 4.3. Buffer di-enable akses tulisnya oleh isyarat we. Isyarat ini dihasilkan oleh unit controller, aktif satu siklus clock setelah data output DCT-1D yang pertama ready. Setelah isyarat we aktif, data akan dituliskan ke tiap alamat buffer dengan urutan alamat secara increment.
67
68
Gambar 4.3 Simulasi awal pengisian data ke transpose buffer Alamat baca unit transpos diakses dengan urutan secara transpose. Data akan dikeluarkan dari unit transpose ini setelah alamat ke-64 ditulis supaya data yang dikeluarkan adalah data yang sudah benar-benar diisikan. Inisiasi pengeluaran data ditandai dengan aktifnya isyarat en_dct2 yang dihasilkan oleh controller. Isyarat en_dct2 sekaligus untuk meng-enable modul DCT-1D yang kedua. Diagram pewaktuan pada saat awal pengeluaran data ditunjukkan pada Gambar 4.4. Gambar 4.5 memperlihatkan secara lengkap diagram pewaktuan modul transpose buffer untuk menangani 64 data keluaran DCT-1D yang pertama. Pada Gambar tersebut, terlihat bahwa alamat untuk penulisan buffer diberikan dalam urutan yang increment. Pada Gambar 4.6, terlihat bahwa alamat untuk pembacaan buffer diberikan dalam urutan yang transposed. Terlihat juga bahwa data yang tertulis dan terbaca pada buffer adalah sama, hanya urutannya yang berbeda. Transpose buffer mempunyai lebar bit 10 bit untuk tiap unit penyimpanannya. Lebar bit ini menyesuaikan dengan keluaran DCT-1D.
68
69
Gambar 4.4 Diagram pewaktuan awal pengeluaran data transpose buffer
Gambar 4.5 Diagram pewaktuan penulisan 64 data keluaran DCT-1D ke transpose buffer Unit penyimpanan yang dialokasikan adalah 128 unit penyimpan. 128 unit ini digunakan untuk menampung dua blok data yang berukuran 8x8 atau 64 unit. Kemampuan untuk menyimpan 2 blok ini, digunakan supaya proses baca dan tulis 69
70 blok dapat berjalan bersamaan. Pada waktu yang sama misalnya, 64 unit yang pertama diakses tulis sementara 64 unit yang kedua diakses baca. Pada siklus 64 clock berikutnya, giliran 64 unit pertama diakses baca dan 64 unit kedua diakses tulis secara bersamaan. Siklus baca-tulis transpose buffer tersebut akan terus berjalan secara bergantian. Metode akses ini ditunjukkan pada Gambar 4.6.
Gambar 4.6 Diagram pewaktuan pengeluaran 64 titik data output b. Pengujian rangkaian DCT-2D terskala Rangkaian DCT-2D merupakan kombinasi dua rangkaian DCT-1D yang dihubungkan oleh transpose buffer. Masukan modul DCT-1D yang kedua berasal
70
71 dari keluaran transpose buffer yaitu nilai DCT-1D yang susunannya telah ditranspos. Sama dengan analisis kinerja DCT-1D, analisis DCT-2D dilakukan melalui diagram pewaktuan dan analisis ketelitian. b.1. Pengujian ketelitian DCT-2D terskala Data input untuk menguji DCT-2D sama dengan data uji pada DCT-1D, yaitu data pada Tabel 4.1 berupa cuplikan citra grayscale pada Gambar 4.1 yang berukuran 8x8 pixel dan sudah dikurangi 128. Kemudian dibuat suatu source VHDL testbench yang berisi data dari 8x8 pixel tersebut. Testbench berfungsi untuk memberi input bagi modul DCT. Data output dari modul DCT disimpan dalam suatu file teks sehingga lebih mudah dilakukan analisis terhadap data tersebut. Untuk menguji ketelitian komputasi DCT, hasil simulasi VHDL dibandingkan dengan komputasi DCT-2D pada Matlab. Tabel 4.4 a dan b berisi 64 titik hasil komputasi DCT-2D terskala pada Matlab dan hasil simulasi VHDL. Kriteria MSE juga dipakai untuk mengukur ketelitian komputasi DCT-2D pada VHDL. Sebelum MSE, selisih antara hasil komputasi Matlab dengan simulasi VHDL perlu dihitung terlebih dahulu. Berdasarkan Tabel 4.4, maka untuk DCT-2D terskala didapatkan tabel selisih komputasi Matlab dan VHDL pada Tabel 4.5 kemudian dapat didapatkan MSEDCT-2D = 0.52796. b.2. Analisis diagram pewaktuan Gambar 4.7 menunjukkan diagram pewaktuan modul DCT-1D yang kedua. Modul ini sama dengan modul pertama, tetapi memiliki lebar bit yang lebih banyak. Input modul mempunyai lebar 11 bit dan output memiliki lebar 14 bit. Pada Gambar 4.7(a), ditunjukkan bahwa operasi DCT-1D yang kedua dienable oleh isyarat en_dct yang dikeluarkan oleh controller. 71
72 Tabel 4.4 Hasil komputasi DCT-2D terskala pada Matlab dan simulasi VHDL (a) Kolom 0 – 3
b0 b1 b2 b3 b4 b5 b6 b7
k0 k1 k2 k3 matlab vhdl matlab vhdl matlab vhdl matlab vhdl 160 160 -1586.5 -1587 1904.8 1905 1265.2 1265 241.21 243 469.24 469 1136.4 1136 -751.86 -751 -459.06 -461 511.84 512 -607.48 -608 516.11 516 189.85 189 -370.53 -372 463.64 463 -383.01 -384 -124 -124 263.75 264 -260.97 -261 229.21 229 121.26 121 -143.35 -142 137.39 137 -142.22 -141 -48.94 -47 76.55 77 -115.93 -115 48.22 48 7.68 7 -17.95 -17 15.51 16 -12.2 -13
(b) Kolom 4-7
b0 b1 b2 b3 b4 b5 b6 b7
k4 k5 k6 matlab vhdl matlab vhdl matlab vhdl -110 -110 153.27 153 -46.81 80.35 81 -205.19 -205 -44.79 -177.68 -177 193.77 194 9.93 112.54 113 -71.04 -70 151.34 -86 -86 106.01 106 -29.03 82.37 81 -48.71 -49 24.76 -2.32 -3 3.43 3 -54.52 12.74 13 -7.23 -9 3.76
k7 matlab vhdl -47 4.06 4 -44 -104.8 -105 10 6.51 6 151 -41.56 -42 -29 29.03 29 25 -8.08 -8 -55 19.57 20 4 -1.52 -2
Tabel 4.5 Selisih komputasi DCT-2D terskala pada Matlab dan VHDL k0 b0 b1 b2 b3 b4 b5 b6 b7
k1 0 -1.79 1.94 0.85 0 0.26 -1.94 0.68
k2 0.46 0.24 -0.16 1.47 -0.25 -1.35 -0.45 -0.95
k3 -0.19 0.39 0.52 0.64 0.03 0.39 -0.93 -0.49
k4 0.21 -0.86 0.11 0.99 0.21 -1.22 0.22 0.8
k5 0 -0.65 -0.68 -0.46 0 1.37 0.68 -0.26
k6 0.27 -0.19 -0.23 -1.04 0.01 0.29 0.43 1.77
k7 0.19 -0.79 -0.07 0.34 -0.03 -0.24 0.48 -0.24
0.06 0.2 0.51 0.44 0.03 -0.08 -0.43 0.48
Isyarat en_dct merupakan isyarat yang sama dengan isyarat en_dct2 yang digunakan untuk menandai data dari transpose buffer siap diakses. Berbeda dengan keluaran DCT-1D pertama yang datanya diurutkan per kolom, data keluaran DCT-1D stage ke-2 dikeluarkan per baris. Pengeluaran data DCT-2D 72
73 ditunjukkan pada Gambar 4.7(b). Data output DCT dikeluarkan satu siklus setelah isyarat en_out aktif.
(a)
(b) Gambar 4.7 Diagram pewaktuan DCT-2D, (a) Pada saat awal data dimasukkan ke modul DCT yang kedua (b)Pada saat awal data hasil komputasi DCT-2D dikeluarkan 4.1.3. Pengujian zig-zag buffer Pengujian kinerja rangkaian zig-zag dapat dilakukan dengan melihat diagram pewaktuannya. Zigzag buffer adalah rangkaian yang sama dengan transpose buffer.
73
74
Gambar 4.8 Diagram pewaktuan input data dari DCT2D ke zigzag buffer
Gambar 4.9 Diagram pewaktuan pembacaan data dari zig-zag buffer Rangkaian merupakan suatu RAM statis dengan dua pasang bus data-bus alamat. Masing-masing bus untuk baca dan tulis. Alamat baca dan tulis dihasilkan
74
75 oleh unit controller. Variabel yang perlu diperhatikan pada timing diagram adalah alamat baca dan tulis serta kesesuaian antara data yang ditulis dan dibaca. Gambar 4.8 menunjukkan keseluruhan data 64 titik dimasukkan ke dalam zig-zag buffer. Pembacaan data 64 titik dari zig-zag buffer ditunjukkan pada Gambar 4.9. Pada Gambar 4.8 dapat diamati bahwa zig-zag buffer ditulis dengan urutan alamat yang normal (increment), sedangkan pada Gambar 4.9 terlihat bahwa pembacaan dilakukan dengan urutan alamat yang zig-zag. Pembacaan buffer dimulai pada saat t=2470 ns atau 28 siklus setelah alamat ke-0 buffer ditulisi. 4.1.4. Pengujian Quantizer Analisis kinerja quantizer cukup dilakukan menggunakan analisis ketelitian komputasi dengan dibandingkan dengan data keluaran Matlab. Hasil komputasi total DCT2D - zigzag – kuantisasi pada VHDL dibandingkan dengan hasil komputasi DCT2D - zigzag – kuantisasi pada Matlab. Perbandingan hasil dan urutan komputasi versi VHDL dan Matlab diperlihatkan pada Tabel 4.6. Pada Matlab, fungsi DCT-2D yang dipakai adalah fungsi DCT yang asli, yaitu DCT tidak terskala,sehingga nilai kuantisasi yang dipakai adalah nilai-nilai kuantisasi yang asli, yang tercantum pada Tabel 2.2. Pada penerapan di FPGA, DCT-2D adalah versi terskala, sehingga nilai-nilai kuantisasinya juga harus diskala ulang untuk mendapatkan nilai output yang benar. Berdasarkan hasil simulasi VHDL pada Tabel 4.6, hasil komputasi DCT2D- zigzag - kuantisasi pada VHDL sudah seperti yang dirancang. Nilai DCT-2D terkuantisasi sama dengan nilai keluaran Matlab dengan pembulatan ke integer terdekat. Urutan data yang dikeluarkan oleh sistem yang dirancang dengan VHDL juga sama dengan urutan data hasil komputasi Matlab. 75
76 Tingkat kesalahan pada bagian ini juga diukur menggunakan MSE antara keluaran VHDL dengan keluaran komputasi Matlab yang unrounded. Nilai MSE keluaran quantizer didapatkan sebesar, MSEquantizer = 0.060552 Tabel 4.6 Hasil komputasi DCT-zigzag-kuantisasi pada VHDL dan Matlab (a). Data ke-0 sampai 23 data ke0 1 2 3 4 5 6 7
matlab data vhdl matlab rounded ke1 1.25 18 -13 -13 -13 9 2 1.81 2 10 -3 -3.14 -3 11 3 2.54 3 12 18 18.23 18 13 8 8.4 8 14 6 5.6 6 15
vhdl 3 1 -1 -2 -3 -3 -1 1
matlab data matlab rounded ke2.72 3 16 1.44 1 17 -0.86 -1 18 -1.67 -2 19 -2.78 -3 20 -3.03 -3 21 -0.57 -1 22 0.61 1 23
matlab vhdl matlab rounded 0 0.28 0 2 1.75 2 2 1.72 2 1 1.08 1 1 0.8 1 0 -0.23 0 0 -0.47 0 -1 -0.67 -1
(b) Data ke-24 sampai 47 data ke24 25 26 27 28 29 30 31
matlab data vhdl matlab rounded ke-1 -1.19 -1 32 0 -0.43 0 33 0 -0.41 0 34 0 -0.21 0 35 0 0.03 0 36 0 -0.12 0 37 0 0.41 0 38 0 0.24 0 39
vhdl 0 0 0 0 0 0 0 0
matlab data matlab rounded ke0.43 0 40 0.3 0 41 0.2 0 42 0.05 0 43 -0.06 0 44 -0.26 0 45 -0.3 0 46 -0.16 0 47
vhdl 0 0 -1 0 0 0 0 0
(c) Data ke-48 sampai 63 data ke48 49 50 51 52 53 54 55
matlab data vhdl matlab rounded ke0 0.06 0 56 0 -0.05 0 57 0 0 0 58 0 -0.1 0 59 0 -0.07 0 60 0 -0.26 0 61 0 0.17 0 62 0 0.07 0 63
76
matlab vhdl matlab rounded 0 0.01 0 0 0.05 0 0 -0.04 0 0 -0.2 0 0 -0.05 0 0 0.17 0 0 0.03 0 0 -0.03 0
matlab matlab rounded -0.11 0 0.03 0 -0.62 -1 0.04 0 0.37 0 0.15 0 0.16 0 0.11 0
77 Nilai MSEquantizer jauh lebih kecil dari MSE pada keluaran DCT-2D. Hal ini dapat disebabkan nilai pada quantizer merupakan nilai keluaran DCT-2D yang sudah dikuantisasi sehingga menjadi lebih kecil. Karena itulah maka kesalahan yang ditimbulkan juga ikut terkuantisasi. 4.1.5. Pengujian penanda nilai DC Pengujian fungsi penanda nilai DC adalah cukup dengan mengamati timing diagram keluaran pin dc pada unit gabungan DCT-2D – zigzag – kuantisasi. Isyarat dc ini dihasilkan oleh unit controller dan diaktifkan saat koefisien DC dikirimkan. Gambar 4.10 adalah diagram pewaktuan isyarat penanda nilai DC.
Gambar 4.10 Diagram pewaktuan penanda koefisien DC Berdasarkan diagram pewaktuan pada Gambar 4.10, dapat diamati bahwa penanda koefisen DC aktif ketika sinyal rdy pertama kali aktif. Sinyal rdy penanda keluaran unit ini siap untuk dibaca. Penanda koefisien DC ini hanya aktif selama 1 siklus saja, ketika koefisien DC sedang dibaca.
77
78 4.1.6 Pengujian unit penghasil nilai beda pada koefisien DC Representasi koefisien DC pada suatu blok (misalnya blok ke-n) yang disandikan adalah selisih koefisien DC pada blok ke-n dan blok ke-(n-1). Pada bagian ini akan diuji kinerja unit penghasil nilai beda tersebut dengan mengamati nilai yang terkirim pada output ketika penanda nilai DC aktif.
Gambar 4.11 Diagram pewaktuan untuk menguji penghasil selisih koefisien DC Nilai DC yang sebenarnya untuk blok ke-n dan blok ke-(n-1) juga diamati untuk verifikasi bahwa nilai yang terkirim merupakan selisih koefisien DC kedua blok. Hasil pengamatan diagram pewaktuan ditampilkan pada Gambar 4.11. Berdasarkan diagram pewaktuan pada Gambar 4.11, teramati bahwa nilai yang dikeluarkan pada blok ke-1 pada saat dc=1 adalah -12. Nilai ini adalah selisih antara nilai DC asli blok ke-1 (-11)dan nilai DC asli blok ke-0 (1).
4.1.7. Pengujian unit penyandi entropi Penyandi entropi digunakan untuk penyandian baik itu nilai DC maupun AC. Keluaran unit ini adalah sym(simbol) dengan lebar 16 bit, cat(kategori) dengan lebar 4 bit, huff(kode huffman) dengan lebar 16 bit, dan len(panjang kode huffman) 4 bit. Input bagi unit ini adalah data keluaran quantizer. Representasi koefisien DC yang jadi masukan pada unit ini sudah merupakan selisih koefisien
78
79 DC dua blok yang berdekatan. Keluaran dari unit ini diverifikasi dengan cara dibandingkan dengan Tabel 2.3 dan 2.4 yang merupakan tabel huffman untuk tiap kriteria. Unit penyandi entropi ini diawali dengan penyandi RLE. Setiap data bukan nol yang melewati penyandi RLE akan disandikan dengan format data (kategori_data, jumlah_nol_sebelum_data). Kategori data disimbolkan dengan cat dan jumlah nol disimbolkan dengan run. Pengujian unit RLE untuk jumlah nol kurang dari 16 ditunjukkan pada Gambar 4.12. Untuk jumlah nol lebih dari 16, diagram pewaktuan ditunjukkan pada Gambar 4.14. Isyarat valid menunjukkan pada saat itu data keluaran dari penyandi adalah valid untuk dibaca. Isyarat ini juga dibangkitkan oleh unit RLE.
Gambar 4.12 Diagram pewaktuan unit RLE dengan jumlah nol kurang dari 16 Suatu kondisi disebut valid jika data yang terbaca bukan nol atau suatu data nol yang didahului oleh 15 data nol atau koefisien DC. Pada Gambar 4.12 dan 4.13, teramati sistem sudah berjalan sesuai kriteria tersebut. Isyarat run dan cat akan disandikan lagi menggunakan sandi Huffman sehingga menghasilkan isyarat huff. Khusus untuk representasi koefisien DC, penyandian hanya dilakukan terhadap nilai cat saja. Hasil simulasi penyandi entropi untuk satu blok pertama untuk tiap data valid dituliskan dalam Tabel 4.7.
79
80
Gambar 4.13 Diagram pewaktuan unit RLE dengan jumlah nol 16 atau lebih Tabel 4.7 memuat hasil penyandian entropi terhadap data keluaran unit quantizer sehingga menghasilkan isyarat-isyarat sandi huff dan sym. Kedua isyarat tersebut sebenarnya panjangnya variabel, sehingga pembacaanya perlu didampingi oleh isyarat len (untuk huff) dan cat (untuk sym). Berdasarkan pengamatan pada Tabel 4.7, teramati bahwa nilai-nilai keluaran penyandi entropi sudah sama dengan nilai yang berasal dari tabel simbol (Tabel 2.3) dan tabel kode Huffman (Tabel 2.4). Meskipun demikian, panjang kode masih berbeda, karena isyarat huff dan sym sementara dikodekan menggunakan panjang maksimalnya, yaitu 16 bit. Pada baris ke-3 dari terakhir Tabel 4.7, terlihat bahwa kode sym tidak valid ketika kode huff = 11111111001. Hal itu disebabkan kode sym memang tidak punya nilai saat nilai huff-nya 11111111001. Nilai huff yang seperti itu adalah untuk mensimbolkan ada 16 nilai nol yang berurutan. Sistem dirancang untuk mengeluarkan kode EOB (end of block) yaitu huff = 1010 jika terdapat dua kali kode huff=11111111001. Artinya jika terdapat dua kali 16 nilai nol yang berurutan, sistem diprogram untuk menghentikan pemrosesan pada blok itu dan mengeluarkan kode huff =1010. Hal ini tercantum pada baris terakhir Tabel 4.7.
80
81 Tabel 4.7 Hasil penyandian entropi blok ke 1 komputasi VHDL encoder input jenis 1 DC -13 AC 2 AC -3 AC 3 AC 18 AC 8 AC 6 AC 3 AC 1 AC -1 AC -2 AC -3 AC -1 AC 1 AC 2 AC 2 AC 1 AC 1 AC -1 AC -1 AC 0 AC -1 AC 0 AC
run
cat 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 2 0 15 1 15
len 1 4 2 2 2 5 4 3 2 1 1 2 2 1 1 2 2 1 1 1 1 0 1 0
sym 2 0000000000000001 3 0000000000000010 1 0000000000000010 1 0000000000000000 1 0000000000000011 4 0000000000010010 3 0000000000001000 2 0000000000000110 1 0000000000000011 1 0000000000000001 1 0000000000000000 1 0000000000000001 1 0000000000000000 1 0000000000000000 1 0000000000000001 4 0000000000000010 1 0000000000000010 1 0000000000000001 1 0000000000000001 4 0000000000000000 1 0000000000000000 10 x 3 0000000000000000 3x
huff 0000000000000010 0000000000001011 0000000000000010 0000000000000000 0000000000000011 0000000000010010 0000000000001000 0000000000000100 0000000000000001 0000000000000000 0000000000000000 0000000000000001 0000000000000001 0000000000000000 0000000000000000 0000000000011011 0000000000000001 0000000000000000 0000000000000000 0000000000011100 0000000000000000 0000011111111001 0000000000001100 0000000000001010
menurut tabel 3 dan 4 sym 1 0010 10 00 11 10010 1000 110 11 1 0 01 00 0 1 10 10 1 1 0 0 x 0 -
huff 010 1011 10 00 11 10010 1000 100 01 00 00 01 01 00 00 11011 01 00 00 11100 00 11111111001 1100 -
4.1.8. Pengujian unit bit stuffer Hasil penyandian entropi yang berupa huff dan sym dalam format fixed length 16 bit dibuat menjadi variable length. Karena tidak memungkinkan untuk mengeluarkan suatu data dengan lebar bit yang berubah-ubah, maka bit-bit kode dikeluarkan satu persatu. Untuk mengamati data yang dikeluarkan bit stuffer, bitbit data ditampung pada register 8 bit. Keluaran bit stuffer untuk pemrosesan blok pertama ditunjukkan pada Tabel 4.8. Berdasarkan Tabel 4.8, dapat diamati bahwa data blok pertama benarbenar terkompresi. Ukuran data masukan tiap blok adalah 64 byte sebelum dikompresi. Setelah dikompresi, sesuai Tabel 2.4, data menjadi berukuran 15 byte. 81
82 Kode pada Tabel 4.8 disusun dari nilai-nilai huff dan sym yang berasal dari Tabel 4.7. Nilai-nilai tersebut didapat dari proses penyandian entropi. Kode pada Tabel 4.8 akan dicoba diuraikan untuk menunjukkan bahwa kode tersusun dari nilai huff dan sym. Misalnya pada Tabel 4.8 baris ke-1. Nilai kode stuffed = 10111010, dengan perjanjian bit paling kiri adalah bit 7 dan bit paling kanan adalah bit 0, dapat diketahui bahwa bit 0 – 3 tersusun dari kode sym dan huff dari baris ke-1 Tabel 4.7 yaitu, sym = 1, huff = 010 menghasilkan 1010 (4 bit paling belakang kode stuffed) Data pada baris ke-2 Tabel 4.8 dikodekan dengan sym =0010 dan huff = 1011. Kode ini dibagi pada sebagian byte yang ada di baris pertama dan sebagian byte baris kedua Tabel 4.8. Penjelasannya sebagai berikut. Tabel 4.8 Hasil penyandian blok ke-0 dalam paket 8 bit data valid ke- sandi terpaket 8 bit 1 10111010 2 10010010 3 11010001 4 01011010 5 00101110 6 11010010 7 01001101 8 01010100 9 00000100 10 10111000 11 01001101 12 10010010 13 01000011 14 11111110 15 10011001
Data baris pertama Tabel 4.8 = 10111010. Empat bit paling belakang sudah dipakai oleh kode sebelumnya. Pada 4 bit paling depan didapat angka 1011 yang merupakan kode huff dari data ke-2 Tabel 4.7. Kode sym dari data ke-2 Tabel 14 (0010) diletakkan pada byte baris kedua Tabel 4.8 = 10010010, yaitu pada empat 82
83 bit paling belakang. 4.1.9. Latensi sistem secara keseluruhan Latensi adalah tertundanya pengeluaran data output akibat adanya proses pipeline. Pada sistem ini, latensi diukur pada saat data output pertama dikeluarkan.
Gambar 4.14 Diagram pewaktuan latensi sistem Output yang dimaksud adalah output dari bit stuffer yang merupakan output utama dari sistem. Waktu keluarnya output itulah waktu latensi dari sistem. Berdasarkan hasil simulasi pada Gambar 4.14, output bit stuffer yang pertama keluar pada saat t = 3790 ns dengan clock 50 MHz atau periode 20 ns. Dihitung berdasarkan siklus clock-nya, pipeline latency sistem yang dirancang adalah 170 siklus clock. 4.1.10. Pengujian Dekompresi Data Hasil Simulasi Xilinx ISE Hasil simulasi kompresi menggunakan Xilinx ISE disimpan di dalam suatu file teks. Tampilan editor file teks untuk data hasil kompresi ditunjukkan pada Gambar 4.15. Data hasil kompresi pada simulasi VHDL akan didekompresi menggunakan program dalam Matlab. Proses dekompresi dilakukan dengan cara entropy decoding – inverese zigzag – dekuantisasi – IDCT-2D. Hasil dekompresi
83
84 atau pemulihan citra tersebut dibandingkan dengan data sumber yang semula. Hasil perbandingan untuk blok-0 berukuran 8x8 ditampilkan pada Tabel 4.9. Citra yang digunakan untuk analisis ini adalah citra pada Gambar 4.1. Berdasarkan Tabel 4.9, selisih pada beberapa data dekompresi dengan citra asli cukup besar. Untuk melihat pengaruhnya terhadap citra, pengamatan harus dilakukan pada citra yang sesungguhnya. Dengan ukuran citra yang besar (lebih dari 40x40), simulator Xilinx ISE sudah mengalami penurunan unjuk kerja, karena itu, pengujian harus dilakukan secara hardware menggunakan FPGA yang sudah dikonfigurasi dengan rangkaian penyandi JPEG.
Gambar 4.15 Screenshot teks file hasil simulasi kompresi 4.2. Pengujian Hardware Setelah melalui simulasi, sistem dapat diimplementasikan pada FPGA. FPGA yang digunakan adalah Xilinx Spartan 3E seri XC3S500E. Hasil sintesis rangkaian dari VHDL oleh Xilinx ISE 10 menghasilkan beberapa output. Output pertama adalah utilisasi rangkaian dalam FPGA. Utilisasi memberi informasi jumlah gerbang, slice, dan komponen FPGA lainnya. Output kedua adalah informasi pewaktuan. Informasi ini memberi ketentuan mengenai frekuensi maksimal yang dapat dipakai dan propagation delay terbesar yang didapat. 84
85 Tabel 4.9 Perbandingan data yang dipulihkan dengan citra asli (citra yang sudah dikurangi 128) k0
b0 b1 b2 b3 b4 b5 b6 b7 Dec
k1
k2
k3
k4
k5
k6
k7
dec asli dec asli dec asli dec asli dec asli dec asli dec asli dec asli 41 42 10 7 -42 -41 -33 -42 -52 -42 17 13 32 32 37 42 42 38 5 11 -49 -46 -43 -45 -53 -44 18 21 39 37 43 45 43 29 5 15 -39 -51 -36 -41 -36 -10 27 5 50 50 48 46 29 33 -2 3 -27 -41 -28 -41 -22 -12 26 20 54 57 48 57 13 28 -20 -14 -35 -41 -44 -45 -25 -15 19 31 62 55 59 61 18 16 -28 -23 -43 -44 -57 -44 -14 -4 30 31 79 56 66 58 20 18 -37 -39 -47 -46 -51 -42 15 -6 44 51 62 49 13 51 4 14 -55 -54 -55 -59 -44 -45 36 26 41 39 18 51 -70 -101 = hasil dekompresi
Setelah rangkaian berhasil disintesis dan dikompilasi, bit-code hasil kompilasi digunakan untuk mengkonfigurasi FPGA. Rangkaian yang dihasilkan diuji dengan skema sesuai Gambar 3.21. Pengujian mencakup pengukuran frame rate , rasio kompresi, dan verifikasi hasil kompresi 4.2.1. Utilisasi Komponen Berikut ini adalah laporan penggunaan komponen berupa gerbang, flipflop maupun unit aritmetika pada sistem yang dirancang. Macro Statistics # RAMs 128x14-bit dual-port RAM # ROMs 256x16-bit ROM 256x4-bit ROM 64x6-bit ROM 64x8-bit ROM # Multipliers 11x14-bit multiplier 14x14-bit multiplier 14x8-bit multiplier # Adders/Subtractors 11-bit adder 11-bit subtractor 14-bit adder 14-bit subtractor 16-bit adder 25-bit adder 25-bit subtractor 28-bit adder
: : : : : : : : : : : : : : : : : : : :
85
2 2 4 1 1 1 1 11 5 5 1 65 12 8 12 8 2 6 4 6
86 28-bit subtractor 8-bit adder 9-bit adder 9-bit subtractor # Counters 3-bit up counter 4-bit up counter 6-bit up counter 8-bit up counter # Registers 1-bit register 11-bit register 14-bit register 16-bit register 25-bit register 28-bit register 4-bit register 8-bit register 9-bit register # Latches 16-bit latch 4-bit latch # Comparators 8-bit comparator equal 8-bit comparator not equal
: : : : : : : : : : : : : : : : : : : : : : : : :
4 1 1 1 20 4 3 1 12 158 30 34 34 4 25 25 4 1 1 4 2 2 6 2 4
Utilisasi komponen FPGA seperti gerbang dan CLB ditunjukkan pada Tabel 4.10. Dari laporan utilisasi komponen, diperoleh informasi bahwa pada sistem yang dirancang, digunakan slice sebanyak 1421 unit, look up table (LUT) sebanyak 2485 unit, dan pengali sebanyak 11 unit. Tabel 4.10 Utilisasi komponen FPGA Number of Number of Number of Number Number
Slices: Slice Flip Flops: 4 input LUTs: used as logic: used as RAMs:
1421 out of 1913 out of 2485 out of 2085 400
Number of MULT18X18SIOs: Number of GCLKs:
11 1
out of out of
4656 9312 9312
30% 20% 26%
20 24
55% 4%
Laporan utilisasi ini memberikan informasi bahwa komponen yang tersisa pada FPGA Spartan-3E masih banyak walaupun setelah diberi konfigurasi sistem yang dirancang.
86
87 4.2.2. Spesifikasi Pewaktuan Spesifikasi pewaktuan untuk rangkaian yang dirancang dapat diamati dalam laporan hasil sintesis rangkaian. Laporan spesifikasi pewaktuan ditunjukkan pada Tabel 4.11. Tabel 4.11 Spesifikasi pewaktuan rangkaian yang dirancang Speed Grade: Minimum period: Maximum Frequency: Minimum input arrival time before clock: Maximum output required time after clock:
Berdasarkan Tabel 4.11, periode clock
-4 38.874ns 25.724MHz 7.038ns 4.450ns
minimal yang diperbolehkan
dipakai pada sistem yang dirancang adalah 38.874 ns dan frekuensi maksimal 25.724 MHz. Nilai-nilai tersebut didapat dari analisis delay yang terdapat pada suatu titik atau net. Rangkuman mengenai unit-unit penyumbang delay pada rangkaian ditunjukkan pada Tabel 4.12. Berdasarkan Tabel 4.11, frekuensi maksimal yang dapat dipakai untuk rangkaian cukup kecil untuk ukuran penyandi yang dioperasikan pada frekuensi tinggi. Tabel 4.12 Unit-unit penyumbang delay pada sistem unit core DCT2 quantizer AC coder compress total(ns)
gate delay(ns) net delay(ns) total gate+net 3.45 1.13 4.58 6.97 1.44 8.41 1.41 1.42 2.83 2.42 1.21 3.63 14.24
5.2
19.44
Frekuensi maksimal yang kurang tinggi disebabkan oleh delay total yang cukup besar. Delay total ini merupakan gabungan dari berbagai delay pada tiap net seperti yang ditunjukkan pada Tabel 4.12. Total delay adalah 19.44 ns. Besarnya delay dipengaruhi oleh perancangan rangkaian yang dilakukan secara
87
88 cascade dan tidak pipelined. Berdasarkan Tabel 4.12, sumber delay paling banyak berasal dari quantizer. Hal itu wajar karena komputasi pada unit itu tidak dirancang secara pipeline. 4.2.3. Perhitungan Pesat Frame Pengukuran pesat frame dilakukan secara langsung pada FPGA, karena simulasi tidak bisa berjalan untuk ukuran frame citra di atas 40x40. Skema pengujian ditunjukkan pada Gambar 3.21. Waktu yang dibutuhkan untuk mengolah satu frame citra diukur dari pertama kali isyarat masukan en diaktifkan sampai saat isyarat keluaran rdy berubah keadaan dari aktif menjadi tidak aktif. Untuk mengukur waktu pengolahan satu frame digunakan satuan siklus clock. Jumlah siklus clock yang dibutuhkan untuk mengolah satu frame bisa digunakan untuk mengukur waktu pengolahan frame. Realisasi rangkaian bisa dilakukan menggunakan counter dengan masukan enable berasal dari operasi OR isyarat en dan rdy. Jumlah clock yang dihitung selama isyarat en dan rdy aktif kemudian dikalikan dengan periode minimal yang dapat ditangani oleh sistem. Nilai yang didapat merupakan waktu pengolahan satu frame. Periode minimal diketahui berdasarkan tabel 4.11. Keluaran counter ditampilkan pada LCD untuk mengetahui jumlah siklus clock. Diagram blok rangkaian penghitung siklus clock ditampilkan pada Gambar 4.16. Pada pengukuran waktu pengolahan frame digunakan sampel citra satu.bmp, dua.bmp, tiga.bmp, dan empat.bmp. Masingmasing untuk ukuran 240x320 dan 480x640 dengan format grayscale. Tabel 4.13 menampilkan jumlah siklus clock untuk 4 citra masing-masing dengan ukuran 240x320 dan 480x640.
88
89
clock
clk counter
en OR rdy
digit-7
cnt_out 20 bit
enable
digit-6 Biner digit-5 To digit-4 8-nibble digit-3 BCD digit-2
Data (4 bit) LCD controller control (2 bit)
LCD
digit-1 digit-0 masingmasing 4 bit Gambar 4.16. Rangkaian penghitung siklus clock untuk pengolahan satu frame Tabel 4.13. Jumlah siklus clock yang dibutuhkan untuk pengolahan frame pada beberapa sampel Nama citra
ukuran
Jumlah clock per frame
satu.bmp
240x320
69.489
dua.bmp
240x320
69.377
tiga.bmp
240x320
69.550
empat.bmp
240x320
69.650
satu.bmp
480x640
277.389
dua.bmp
480x640
277.245
tiga.bmp
480x640
277.490
empat.bmp
480x640
277.510
Berdasarkan Tabel 4.13, didapatkan rerata jumlah clock untuk citra 240x320 yaitu 69.516,5 siklus clock. Rerata jumlah clock untuk citra 480x640 adalah 277.408,5. Jika digunakan clock dengan periode minimal sesuai dengan Tabel 4.11, yaitu 38,874 ns, waktu pengolahan frame dapat dihitung dengan cara mengalikan jumlah clock dengan 38,874 ns. Rerata waktu pengolahan untuk 89
90 240x320 adalah 2,7 ms sedangkan untuk 480x640 sebesar 10,78 ms. Frame rate dapat dihitung dengan cara membagi 1000 dengan waktu pengolahan dalam milidetik. Rerata frame rate untuk ukuran 240x320 adalah 370,04 fps (frame per second) sedangkan untuk ukuran 480x640 adalah 92,73 fps. Frame rate tersebut adalah untuk citra grayscale. Frame rate untuk citra berwarna juga dapat dihitung. Sebelum kompresi, citra berwarna diubah dalam format Y-Cr-Cb. Y adalah tingkat keabuan, dan CrCb adalah tingkat warna (chrominance). Citra berwarna mengalami proses downsample sebelum kompresi dengan format Y:Cr:Cb = 4 : 1 : 1. Berdasarkan informasi tersebut, frame rate berwarna dapat dihitung dengan cara frb = frg x 4/(4+1+1) = frg x 4/6 ..........................(4.1) dengan fb = frame rate citra berwarna, dan fg = frame rate citra grayscale. Rerata frame rate untuk citra berwarna 480x640 adalah 61.68 fps dan untuk citra berwarna 240x320 adalah 246.7 fps. Tabel 4.14 menunjukkan perbandingan unjuk kerja dan utilisasi komponen antara rangkaian yang dirancang dan beberapa intellectual property serta IC kompresi JPEG. Pesat frame diukur pada ukuran citra 480 x 640 dan sistem warna YCrCb = 4:1:1. Dibandingkan dengan beberapa IC kompresi JPEG yang ada di pasaran yaitu produk Zoran(1998) dan Inrevium(2005), rangkaian yang dirancang mempunyai pesat frame yang lebih tinggi. Rancangan intellectual property (IP) kompresi JPEG dari Barco (2005) dan Cast-JPEG (2008) mempunyai pesat frame yang tinggi, karena keduanya memakai FPGA high-end dengan speed grade tinggi. Walaupun demikian, rangkaian yang dirancang lebih sesuai diterapkan pada FPGA Spartan-3E karena memiliki tingkat pemakaian komponen FPGA yang lebih rendah daripada kedua 90
91 intellectual property tersebut. Informasi speed grade dan utilisasi slice hanya terdapat pada FPGA sebagai spesifikasi intellectual property. Tabel 4.14. Perbandingan frame rate dan frekuensi maksimal antara rangkaian yang dirancang dan intellectual property JPEG serta chip kompresi JPEG yang ada di pasaran untuk ukuran frame 480 x 640 dan sistem warna Y Cr Cb = 4:1:1. Pembanding Spartan-3E
BA119/ Barco(2005)
Cast-JPEG/ Cast (2008)
ZR36060/ Zoran(1998)
TE3310/ Inrevium(2005)
Jenis produk
IP
IP
IC
IC
6
6
-
-
Speed grade FPGA
4
Utilisasi FPGA
Jumlah slice Jumlah slice = 1.421 = 7.497
Jumlah slice = 15.305
-
-
Frekuensi maks
25,7 MHz
82 MHz
86 MHz
29.5 MHz
27 MHz
120 fps
162 fps
33 fps
50 fps
Frame rate 61,68 fps maks
4.2.4. Pengujian Rasio Kompresi Pengujian rasio kompresi dilakukan dengan membandingkan rasio yang dihasilkan oleh rangkaian yang dirancang dan rasio yang dihasilkan oleh software pengolah citra. Software pengolah citra yang digunakan adalah Image Analyzer karena ringan untuk dijalankan pada netbook. Citra sampel adalah citra grayscale dengan ukuran 640x480, 240x320, 80x80, dan 40x40. Rasio kompresi dihitung dengan membagi jumlah byte sesudah kompresi dengan jumlah byte sebelum dikompresi. Rasio diukur dengan satuan bit per piksel. Citra yang sama digunakan sebagai masukan software dan rangkaian. Faktor kualitas kompresi pada masingmasing alat kompresi dibuat sama, yaitu 50. Tabel 4.15 menunjukkan perbandingan ukuran data hasil kompresi antara software Image Analyzer dan FPGA. Berdasarkan Tabel 4.15, terlihat bahwa rasio kompresi yang dihasilkan
91
92 oleh FPGA cukup mendekati rasio kompresi yang dihasilkan oleh software dengan kualitas kompresi 50. Untuk citra berukuran kecil (80x80 dan 40x40), rangkaian kompresi pada FPGA bahkan menghasilkan rasio kompresi yang lebih efisien daripada software. Tabel 4.15. Perbandingan rasio kompresi antara FPGA dan Image Analyzer Citra dan Kompresi dengan FPGA ukurannya
Kompresi dengan Image Analyzer
(dalam piksel)
Ukuran (byte)
rasio
Bit per piksel
Ukuran (byte)
rasio
Bit per piksel
satu.bmp 480x640
3221
10,50%
0, 839
3215
10,50%
0, 837
dua.bmp 240x320
1147
14,90%
1, 194
1179
15,30%
1, 228
fruit.bmp 80x80
797
12,40%
0, 990
113
17,60%
1, 408
mata.bmp 40x40
326
20,40%
1, 630
654
40,80%
3, 270
Untuk mengamati citra hasil kompresi, digunakan metode dekompresi menggunakan Matlab seperti pada bagian 4.1.10. Hasil pemulihan citra yang terkompresi secara hardware menggunakan FPGA ditunjukkan pada Lampiran A. Terdapat perbedaan nilai piksel antara citra yang dipulihkan dari data hasil kompresi dan citra asli. Perbedaan tersebut menentukan kualitas citra yang dipulihkan dari data hasil kompresi. Tingkat perbedaan diukur menggunakan MSE (mean square error). Nilai MSE juga digunakan untuk mengukur perbedaan antara citra hasil kompresi rangkaian dan citra hasil kompresi software Image Analyzer dengan berbagai faktor kualitas. Tabel 4.16 menunjukkan nilai MSE antara citra hasil kompresi rangkaian yang dipulihkan dan citra asli. Tabel 4.16 juga menunjukkan MSE antara citra hasil kompresi rangkaian dan citra
92
93 terkompresi software pada faktor kualitas (Q) 10, 25, 50, 75, dan 90. Tampak pada Tabel 4.16 MSE terkecil untuk semua citra didapat pada faktor kualitas kompresi software 50. Rangkaian dirancang untuk kualitas kompresi 50. MSE terkecil tersebut menandakan bahwa ditinjau dari hasil kompresi, unjuk kerja rangkaian dapat mendekati hasil kompresi software. Tabel 4.16. MSE (Mean Square Error) antara hasil kompresi rangkaian dan citra asal serta citra hasil kompresi software dengan berbagai faktor kualitas (Q=10,25,50,75 90) File citra
ukuran
MSE1
MSE2
MSE3
MSE4
MSE5
MSE6
satu.bmp
240x320 0,0238
0,0243
0,0252
0,0033
0,0302
0,0401
dua.bmp
240x320 0,0279
0,0288
0,0290
0,0023
0,0340
0,0450
tiga.bmp
240x320 0,0180
0,0181
0,0180
0,0016
0,0235
0,0331
empat.bmp
240x320 0,0252
0,0259
0,0261
0,0020
0,0311
0,0425
satu.bmp
480x640 0,0087
0,0087
0,0086
0,00120
0,0110
0,0157
dua.bmp
480x640 0,0120
0,0122
0,0123
0,00098
0,0143
0,0191
tiga.bmp
480x640 0,0062
0,0061
0,0064
0,00076
0,0090
0,0131
empat.bmp
480x640 0,0082
0,0084
0,0085
0,00084
0,0115
0,0167
0,0166
0,0168
0,00162
0,0206
0,0201
rerata
0,01625
MSE1: MSE citra hasil dekompresi keluaran rangkaian - citra asal MSE2: MSE citra hasil dekompresi keluaran rangkaian - citra terkompresi software , Q=90 MSE3: MSE citra hasil dekompresi keluaran rangkaian - citra terkompresi software , Q=75 MSE4: MSE citra hasil dekompresi keluaran rangkaian - citra terkompresi software , Q=50 MSE5: MSE citra hasil dekompresi keluaran rangkaian - citra terkompresi software , Q=25 MSE6: MSE citra hasil dekompresi keluaran rangkaian - citra terkompresi software , Q=10
Kondisi citra hasil kompresi juga diukur secara kualitatif menggunakan penilaian subjektif yang diambil berdasarkan pendapat responden yang terhadap citra tersebut. Tabel 4.17 merangkum penilaian 10 responden terhadap citra hasil kompresi. Citra diklasifikasikan dalam lima tingkatan kualitatif, yaitu excellent, good, fair, poor, dan unsatisfactory (Jain, 1989). Tingkatan excellent dicapai jika citra hasil kompresi tidak bisa dibedakan dengan citra aslinya. Setingkat di bawah excellent, good dicapai jika citra hasil kompresi sedikit berbeda dengan citra asli, 93
94 tetapi tidak ditemukan distorsi. Jika pada citra ditemukan sedikit distorsi, tetapi tidak menggangu penampilan, citra dimasukkan dalam tingkat fair. Jika distorsi sudah mulai menggangu penampilan, citra dimasukkan dalam tingkat poor. Tingkatan unsatisfactory dicapai saat tampilan citra terkompresi sudah banyak terdistorsi dan beberapa detail sudah tidak dapat dikenali. Untuk semua citra yang diujikan, terdapat 12 atau 15% pendapat yang menyatakan excellent dan 33 atau 41% yang menyatakan good. Pendapat yang lain sebanyak 29% menyatakan fair dan sebanyak 15% menyatakan poor serta tidak ada pendapat unsatisfactory. Tabel 4.17. Penilaian secara subjektif terhadap citra hasil kompresi rangkaian dibandingkan dengan citra asal Nama file
ukuran
satu.bmp
240x320
2
2
4
2
-
dua.bmp
240x320
1
4
3
2
-
tiga.bmp
240x320
1
3
3
3
-
empat.bmp
240x320
1
2
3
4
-
satu.bmp
480x640
1
7
2
-
-
dua.bmp
480x640
3
4
3
-
-
tiga.bmp
480x640
2
5
3
-
-
empat.bmp
480x640
1
6
2
1
-
12
33
23
12
-
15.00%
41,25%
28,75%
15.00%
total %
Excellent
Good
Fair
Poor
Unsatisfactory
Penilaian subjektif dilakukan oleh 10 responden untuk setiap citra
4.3. Permasalahan dalam penelitian Permasalahan yang muncul dalam penelitian ini berasal dari metode pengujian hardware. Pengiriman data citra dari PC ke FPGA serta data terkompresi dari FPGA ke PC dilakukan melalui jalur port serial PC. Masalah timbul pada komunikasi melalui port serial tersebut, khususnya pada pengiriman
94
95 data dari FPGA ke PC. Adanya kesalahan tersebut dapat dideteksi melalui operasi eksklusif-OR (XOR) yang diterapkan pada semua data yang dikirimkan dari PC ke FPGA dan sebaliknya. Proses XOR pada pengiriman data PC-FPGA dilakukan di sisi komputer dan di sisi FPGA. Data yang akan dikirim dihitung nilai XORnya pada PC. Nilai XOR ini juga dikirimkan ke FPGA setelah semua data terkirim. FPGA akan menghitung nilai XOR data yang diterima dari PC. Jika nilai XOR pada FPGA sama dengan nilai XOR yang dikirim PC, tidak ada kesalahan pada pengiriman data PC-FPGA. Proses yang sama juga dilakukan untuk pengiriman data hasil kompresi dari FPGA ke PC. Nilai XOR data yang akan dikirimkan ke PC dihitung di FPGA dan ikut dikirimkan ke PC. Pada sisi PC, nilai XOR antara data yang diterima juga dihitung. Nilai XOR data diterima yang dihitung pada PC dibandingkan dengan nilai XOR yang dikirimkan oleh FPGA. Jika sama, tidak ada kesalahan pada pengiriman data FPGA-PC. Skema deteksi kesalahan data menggunakan XOR ditunjukkan pada gambar 4.17. PC Data citra
Jalur UART TX PC Nilai Data citra XOR
XOR (a) PC XOR XOR untuk semua data yang masuk
Jalur UART RX PC Nilai Data terkompresi XOR
FPGA XOR XOR untuk semua data yang masuk Jika XOR = 0, tidak ada kesalahan
FPGA Data terkompresi
XOR (b) Gambar 4.17. Skema deteksi kesalahan (a) untuk transmisi data citra dan (b) untuk transmisi data terkompresi
Jika XOR = 0, tidak ada kesalahan
95
96 Berdasarkan percobaan, pada pengiriman data citra dari PC ke FPGA tidak terdapat kesalahan. Kesalahan hanya muncul pada pengiriman data terkompresi dari FPGA ke PC. Tabel 4.18 menunjukkan banyaknya kejadian error pada lima kali pengiriman untuk masing-masing citra. Tabel 4.18. Banyaknya kejadian error pada lima kali pengiriman data Nama citra dan ukuran
Banyaknya error pada lima kali transmisi
satu.bmp 480x640
4
dua.bmp 240x320
2
fruit.bmp 80x80
1
mata.bmp 40x40
0
Berdasarkan Tabel 4.18, error terjadi pada citra dengan ukuran besar, yaitu lebih dari 80x80 piksel. Sistem pengujian tidak mampu menangani transmisi data dalam jumlah yang besar. Sumber clock untuk sistem kompresi diambil dari isyarat RX_rdy yang aktif ketika 8 bit data selesai diterima oleh FPGA. Frekuensi clock yang dihasilkan bisa diturunkan dengan memberi delay antar pengiriman data. Pemberian delay dapat mempengaruhi error yang dihasilkan. Percobaan pada Tabel 4.18 tidak memakai delay antar data. Berdasarkan Tabel 4.19, semakin besar delay yang ditambahkan, error akan semakin berkurang. Dengan delay yang besar, delay antar data yang dikirimkan dari FPGA ke PC juga semakin besar. Berdasarkan hal tersebut, bisa disimpulkan bahwa program yang dijalankan pada PC tidak mampu menangani pengiriman data dalam jumlah yang banyak dan frekuensi pengiriman yang tinggi. Penambahan delay dapat mengatasi error pada transmisi data terkompresi
96
97 dari FPGA ke PC, tetapi hal itu mengakibatkan proses kompresi menjadi lebih lama karena periode clock menjadi lebih besar. Periode clock efektif yang digunakan oleh sistem adalah 10 kali 1/baud rate port serial. Rumus tersebut didapat dari lebar 1 bit pada data serial yang sebesar 1/ baud rate dan transmisi 1 byte data yang terdiri dari 10 bit, yaitu 8 bit data dan 2 start-stop bit. Untuk baud rate 38.400 bps, didapatkan periode 10 / 38.400 atau 0,26 ms. Sebagai contoh, pemrosesan citra satu.bmp 240x320 membutuhkan 69.489 clock. Total waktu pemrosesan tanpa delay adalah 69.489 x 0,26 ms = 18,07 detik. Dengan penambahan delay n milidetik pada periode clock, total waktu pemrosesan adalah 69,489 n + 18,07 detik. Tabel 4.19. Hubungan antara delay dan error yang muncul pada transmisi Nama citra ukuran
dan Delay (ms)
satu.bmp 480x640
dua.bmp 240x320
fruit.bmp 80x80
Jumlah error untuk 5 kali pengiriman
0
4
1
4
2
2
3
1
4
0
0
2
1
1
2
0
0
1
1
0
97
98 BAB V KESIMPULAN DAN SARAN 5.1. Kesimpulan Berdasarkan hasil perancangan dan simulasi yang diperoleh sampai saat ini, dapat diambil kesimpulan sebagai berikut. 1.
Perangkat yang dirancang yaitu sistem kompresi citra JPEG berbasis FPGA berdasarkan hasil simulasi dan pengujian hardware, dapat melakukan kompresi citra grayscale.
2.
Berdasarkan perbandingan hasil komputasi dengan Matlab, masingmasing unit komputasi pada sistem yang dirancang mempunyai mean square error (MSE) sebagai berikut.
3.
•
MSE keluaran DCT-1D = 0.069219
•
MSE keluaran DCT-2D = 0.52796
•
MSE keluaran DCT-2D terkuantisasi = 0.060552
Implementasi rancangan pada FPGA Xilinx Spartan-3E menghasilkan utilisasi komponen sebagai berikut. •
Slice sebanyak 1421 unit
•
Look up table sebanyak 2485 unit
•
Pengali sebanyak 11 unit
4. Spesifikasi pewaktuan yang didapat dari rangkaian yang dirancang yaitu frekuensi maksimal sebesar 25.724MHz atau periode minimal clock yang diperbolehkan sebesar 38.874ns. Pesat data maksimal yang diizinkan adalah sebesar frekuensi maksimal.
98
99 5. Latensi akibat proses pipeline pada rangkaian adalah 170 siklus clock 6. Frame rate rerata maksimal yang dapat dicapai oleh rangkaian kompresi JPEG pada citra grayscale adalah 370.04 fps (frame per second) untuk ukuran 240x320 sedangkan untuk ukuran 480x640 adalah 92.73 fps. 7. Rerata frame rate maksimal untuk citra berwarna 480x640 adalah 61.68 fps dan untuk citra berwarna 240x320 adalah 246.7 fps. 8. Rasio kompresi yang dicapai oleh rangkaian kompresi JPEG dapat menyamai rasio yang dicapai oleh software pengolah citra. Untuk citra berukuran kecil (80x80 dan 40x40), rasio kompresi rangkaian bahkan lebih kecil daripada rasio kompresi software. 9. Kualitas citra hasil kompresi FPGA dapat mendekati hasil kompresi software dengan faktor kualitas 50. Rerata MSE antara keduanya sebesar 0.00162. Rerata MSE antara citra terkompresi FPGA dan citra asli 0.01625. 10. Berdasarkan pendapat 10 responden terhadap 8 kelompok citra, sebanyak 41 % menyatakan kualitas citra hasil kompresi mempunyai tingkatan good. 15 % menyatakan excellent , 29% fair, dan sisanya poor.
5.2. Saran Berdasarkan kesimpulan dan hasil penelitian yang didapatkan, diberikan saran-saran sebagai berikut. 1.
Unjuk kerja rangkaian, terutama pada bagian modul akuisisi citra, dapat ditingkatkan menggunakan SDRAM yang terpasang pada modul board FPGA. SDRAM yang berukuran besar (32 MB) dapat digunakan untuk 99
100 menampung data citra input dan data hasil kompresi. 2.
Rasio kompresi yang didapat pada FPGA sedikit berbeda dengan rasio yang didapat pada software, terutama untuk citra dengan ukuran kecil. Untuk meningkatkan kualitas kompresi, diperlukan tabel kuantisasi dan tabel Huffman yang adaptif terhadap kondisi citra. Hal itu dapat direalisasi menggunakan tambahan prosesor embedded pada FPGA.
100
101 DAFTAR PUSTAKA Agostini, L., Ivan, S., and Sergio, B., “Pipelined Fast 2-D DCT Architecture for JPEG Image Compression,” Symposium on Integrated Circuits and System Design, SBCCI Proceedings, pp.226-231, 2001. Agostini, L., Ivan S., and Sergio B., “Pipelined Entropy Coders for JPEG Compression,” Proceedings of the 15th symposium on Integrated circuits and systems design, pp.203-208, 2002. Ahmed, N., Natarajan, T., and Rao, K. “Discrete Cosine Transforms”. in IEEE Transactions on Computer., vol. C-23, pp. 90-93, 1974. Arai Y. , Agui T., Nakajima M.. “A Fast DCT-SQ Scheme for Images”. Transactions of IEICE, vol. E71, no. 11, pp. 1095-1097, 1988. Barco Corporation, “JPEG Codec : BA119JPEGCOD Factsheet”, Data Sheet, Perancis, 1998. Cast -Inc. “JPEG-C : Baseline JPEG Codec ”,Product Specification, USA, 2008 Chen, W., Smith, C., and Fralick, S., “A Fast Computation Algorithm for the Discrete
Cosine
Transform
”,
in
IEEE
Transactions
on
Communications, vol. 25, pp. 1004-1009, 1977. Inrevium, “High Performance JPEG Coder LSI : TE3310RPF”, Data Sheet, Japan, 2005. Jang, Y., Kao, J., Yang, J., and Huang, P., “A 0.8u 100-MHz 2-D DCT Core Processor”, in IEEE Transactions on Consumer Electronics, vol. 40, pp. 703-709, 1994. Jain, A. K., “Fundamental of Digital Image Processing”, Prentice-Hall
101
102 International, New Jersey, 1989. Loeffler, C., Ligtenberg, A. and Moschytz, G. S.,"Practical Fast 1-D DCT Algorithms With 11 Multipliers," Proc. of IEEE Int. Conf. on ASSP , 1989, pp. 988-991. Magli, E., “The JPEG Family Of Coding Standard”, Part of “Document and Image Compression”, Taylor and Francis, New York, 2004. Okada, S., Matsuda, Y., Watanabe, T., dan Kondo, T. ,” A Single Chip Motion JPEG CODEC LSI,” IEEE Transactions on Consumer Electronics, Vol.43, No.3, pp.418-422, 1997. Pillai, L. ,”Video Compression Using DCT”, Xilinx Application Note, XAPP610, V1.2, 2002. Solomon, D., “Data Compression : The Complete Reference”, Springer, New York, 2004. Sun, M., Ting C., and Albert M., “VLSI Implementation of a 16 X 16 Discrete Cosine Transform”, IEEE Transactions on Circuits and Systems, Vol. 36, No. 4, April 1989. Wallace, G. K. ,''The JPEG Still Picture Compression Standard'', Communications of the ACM, Vol. 34, Issue 4, pp.30-44. 1991. Xilinx, Inc., “Spartan-3E FPGA Family : Data Sheet ”, Xilinx Corporation, 2009. Zoran Corporation, “ZR36060 : Integrated JPEG Codec”, Data Sheet, USA, 1998. Zulkarnain, M., “Real Time Implementation of Baseline JPEG Decoder Using Floating Point DSP TMS320C31” Proceeding of IEEE TENCON, 2000, pp. 988-991.
102
Lampiran A. Citra Uji (resolusi 480x640) 1. Satu.bmp a. Citra Asli
A-1
b. Hasil Kompresi
rasio kompresi = 10,50%
MSE (kompresi-citra asli) = 0.0238
Hasil Penilaian Subjektif(dari 10 responden): excellent : 1, good : 7, fair : 2, poor : -
A-2
2. Dua.bmp a. Citra Asli
A-3
b. Hasil Kompresi
rasio kompresi = 13.5%
MSE (kompresi-citra asli) = 0.0120
Hasil Penilaian Subjektif(dari 10 responden): excellent : 3, good : 4, fair : 3
A-4
3. Tiga.bmp a. Citra asli
A-5
b. Hasil kompresi
rasio kompresi = 9 %
MSE (kompresi-citra asli) = 0.0062
Hasil Penilaian Subjektif(dari 10 responden): excellent : 2, good : 5, fair : 3
A-6
4. Empat.bmp a. Citra asli
A-7
b. Hasil kompresi
rasio kompresi = 12.1%
MSE (kompresi-citra asli) = 0.0082
Hasil Penilaian Subjektif(dari 10 responden): excellent : 1, good : 6, fair : 2
A-8
Lampiran B – Hirarki desain dan Source Code Hirarki desain jpeg_ram.vhd Penyandi JPEG root (keluaran serial) jpegcoder.vhd
p2s.vhd
Penyandi JPEG Keluaran paralel
Paralel ke serial
core2.vhd
fullcoder.vhd
Core 2D-DCT + quantizer +zigzag
Full entropy coder dct3_pl.vhd
dct3_st2.vhd DCT-1D #2
DCT-1D
Transpose buffer ram.vhd
Penghitung beda DC antar blok diff_pcm.vhd
rom_zigzag.vhd quantizer.vhd Zigzag ROM
quantizer zigzag buffer ram.vhd
quantizer ROM qrom.vhd DCT controller
AC coder ac_coder.vhd Counter RLE rlectr.vhd
DC coder dc_coder.vhd
Code MUX codemux.vhd Counter ROM kategori huffman
findcat.vhd
huff_rom.vhd
ctr2.vhd ROM panjang len_rom.vhd
B-1
Source code root enkoder JPEG (jpeg-ram.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_signed.all; use ieee.numeric_std.all; LIBRARY UNISIM; use UNISIM.VCOMPONENTS.ALL; entity jpeg_ram is generic( lebar_in:integer:=7; lebar_ot:integer:=8; lebar_max:integer:=13--lebar bus data memori ); port( clk: in std_logic; clk2: in std_logic; rst: in std_logic; -rst2: in std_logic; en: in std_logic; dat_in: in std_logic_vector(lebar_in downto 0); -clko: out std_logic; data_rdy: out std_logic; par_rdy: out std_logic; serial_out:out std_logic ); end jpeg_ram; architecture behav of jpeg_ram is component jpegcoder is generic( lebar_in:integer:=7; lebar_ot:integer:=8; lebar_max:integer:=13--lebar bus data memori ); port( clk: in std_logic; rst: in std_logic; en: in std_logic; dat_in: in std_logic_vector(lebar_in downto 0); cat:out std_logic_vector(3 downto 0); len:out std_logic_vector(3 downto 0); sym:out std_logic_vector(15 downto 0); huff:out std_logic_vector(15 downto 0); addr:out std_logic_vector(7 downto 0); en_out: out std_logic; --en_serial:out std_logic; valid:out std_logic ); end component; component coderam is generic(
B-2
lebar_data:integer:=39--lebar bus data memori );--pengali dikalikan 2^12 port(
addr_baca: in std_logic_vector(7 downto 0); addr_tls: in std_logic_vector(7 downto 0); data_tls: in std_logic_vector(lebar_data downto 0); data_baca: out std_logic_vector(lebar_data downto 0); we:in std_logic; clk: in std_logic ); end component; component p2s is port( clk: in std_logic; clr: in std_logic; en: in std_logic; addr_tls: in std_logic_vector(7 downto 0); addr: out std_logic_vector(7 downto 0); len:in std_logic_vector(3 downto 0); huff: in std_logic_vector(15 downto 0); cat:in std_logic_vector(3 downto 0); sym: in std_logic_vector(15 downto 0); rdy: out std_logic; ser: out std_logic); end component; signal cat: std_logic_vector(3 downto 0); signal len: std_logic_vector(3 downto 0); signal sym: std_logic_vector(15 downto 0); signal huff: std_logic_vector(15 downto 0); signal addr_bc,addr_tls:std_logic_vector(7 downto 0); signal rdy:std_logic; signal en_serial,valid:std_logic; signal data_tls,data_bc:std_logic_vector(39 downto 0); SIGNAL clk50m_dcm : std_logic; SIGNAL clk50m : std_logic; signal clk_2 : std_logic; signal end_ser:std_logic; begin clk_2<=clk2; koder_jpeg:jpegcoder port map(clk,rst,en,dat_in,cat,len,sym,huff,addr_tls,rdy,valid); data_tls(39 downto 36)<=len; data_tls(35 downto 20)<=huff; data_tls(19 downto 16)<=cat; data_tls(15 downto 0)<=sym; ram_kode: coderam port map(addr_bc,addr_tls,data_tls,data_bc,valid,clk); par2ser: p2s port map(clk_2,rst,en_serial,addr_tls,addr_bc,data_bc(39 downto 36),data_bc(35 downto 20),data_bc(19 downto 16),data_bc(15 downto 0),end_ser,serial_out); data_rdy<=end_ser; par_rdy<=rdy; process(clk,rst) begin if(rst='1')then en_serial<='0';
B-3
--addr_max<=(others=>'0'); elsif(rising_edge(clk)) then if(huff="0000000000001010" and valid='1') then en_serial<='1'; end if; if(en_serial='1' and rdy='0' and addr_bc=addr_tls-1 and end_ser='0') then en_serial<='0'; end if; end if; end process; end behav;
Source code VHDL untuk penyandi JPEG keluaran paralel (jpegcoder.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; entity jpegcoder is generic( lebar_in:integer:=7; lebar_ot:integer:=8; lebar_max:integer:=13--lebar bus data memori ); port( clk: in std_logic; rst: in std_logic; en: in std_logic; dat_in: in std_logic_vector(lebar_in downto 0); cat:out std_logic_vector(3 downto 0); len:out std_logic_vector(3 downto 0); sym:out std_logic_vector(15 downto 0); huff:out std_logic_vector(15 downto 0); addr:out std_logic_vector(7 downto 0); en_out: out std_logic; --en_serial:out std_logic; valid:out std_logic ); end entity; architecture behav of jpegcoder is component core1 is generic( lebar_ctr:integer:=15; lebar_in:integer:=7; lebar_ot:integer:=8; lebar_max:integer:=13--lebar bus data memori ); port( clk: in std_logic; rst: in std_logic; en: in std_logic; dat_in: in std_logic_vector(lebar_in downto 0);
B-4
dc: out std_logic; dat_out: out std_logic_vector(lebar_ot downto 0); dct2_rdy: out std_logic ); end component; component fullcoder is port( clk: in std_logic; clr: in std_logic; dc: in std_logic; data_in:in std_logic_vector(15 downto 0); cat:out std_logic_vector(3 downto 0); len:out std_logic_vector(3 downto 0); sym:out std_logic_vector(15 downto 0); huff:out std_logic_vector(15 downto 0); valid:out std_logic); end component; component compress is port( clk: in std_logic; clr: in std_logic; dc: in std_logic; en: in std_logic; len:in std_logic_vector(3 downto 0); huff: in std_logic_vector(15 downto 0); cat:in std_logic_vector(3 downto 0); sym: in std_logic_vector(15 downto 0); valid: in std_logic; olen:out std_logic_vector(3 downto 0); ohuff: out std_logic_vector(15 downto 0); ocat:out std_logic_vector(3 downto 0); osym: out std_logic_vector(15 downto 0); ovalid: out std_logic); end component; signal signal signal signal signal signal signal
tlen: std_logic_vector(3 downto 0); thuff: std_logic_vector(15 downto 0); tcat:std_logic_vector(3 downto 0); tsym: std_logic_vector(15 downto 0); tvalid: std_logic; ovalid:std_logic; ohuff: std_logic_vector(15 downto 0);
signal dc:std_logic; signal clr_tmp:std_logic; signal dct_rdy:std_logic; signal dct_out:std_logic_vector(8 downto 0); signal coder_in:std_logic_vector(15 downto 0); signal taddr:std_logic_vector(7 downto 0); begin valid<=ovalid; huff<=ohuff; coder_in<=dct_out(8)&dct_out(8)&dct_out(8)&dct_out(8)&dct_out(8)&dct_out(8)&dct_out (8)&dct_out;
B-5
--
clr_tmp<=dc or rst; addr<=taddr; en_out <= dct_rdy; dctcore: core1 port map(clk,rst,en,dat_in,dc,dct_out,dct_rdy); coder:fullcoder port map(clk,rst,dc,coder_in,tcat,tlen,tsym,thuff,tvalid); kompres: compress port map(clk,rst,dc,dct_rdy,tlen,thuff,tcat,tsym,tvalid,len,ohuff,cat,sym,ovalid); process(clk,rst) begin if(rst='1')then taddr<=(others=>'0'); elsif(rising_edge(clk) and ovalid='1') then taddr<=taddr+1; end if; end process; end behav;
Source code VHDL untuk core DCT-2D terkuantiasi (core2.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_signed.all; use ieee.numeric_std.all; entity core1 is generic( lebar_ctr:integer:=15; lebar_in:integer:=7; lebar_ot:integer:=8; lebar_max:integer:=13--lebar bus data memori ); port( clk: in std_logic; rst: in std_logic; en: in std_logic; dat_in: in std_logic_vector(lebar_in downto 0); dc: out std_logic; dat_out: out std_logic_vector(lebar_ot downto 0); dct2_rdy: out std_logic ); end entity; architecture struktural of core1 is component dpcm is generic( lebar_ctr:integer:=5; lebar_dat:integer:=5; lebar_ot:integer:=8; lebar_max:integer:=13--lebar bus data memori ); port( clk: in std_logic;
B-6
rst: in std_logic; dc: in std_logic; din: in std_logic_vector(lebar_ot downto 0); dout: out std_logic_vector(lebar_ot downto 0) ); end component; component myROM is generic( width: integer:=6; -- lebar bit tiap alamat depth: integer:=64; -- ada berapa byte alamat addr: integer:=6); -- lebar bus alamat port( --din: in std_logic_vector(width-1 downto 0); dout: out std_logic_vector(width-1 downto 0); address: in std_logic_vector(addr-1 downto 0) ); end component; component controller is port( clk: in std_logic; rst: in std_logic; a_in: out std_logic_vector(7 downto 0); a_out: out std_logic_vector(7 downto 0); en_dct: out std_logic; en_dct2: out std_logic; we: out std_logic; ctr_en: in std_logic; dct_rdy2: in std_logic;--penanda dct2 sudah ready datanya dct_rdy: in std_logic; rom_rdy: out std_logic; --menandai apakah rom zigzag sudah bisa diakses we2: out std_logic; dc_en: out std_logic; a2in: out std_logic_vector(7 downto 0); a2out: out std_logic_vector(7 downto 0) ); end component; component dct8a is generic(m:integer:=13;--MSB pengali n:integer:=7;--MSB data input k:integer:=10;--MSB output h:integer:=24;--MSB hasil kali p:integer:=12);--pengali dikalikan 2^12 port( clk: in std_logic; rst: in std_logic; en_dct: in std_logic; vin: in std_logic_vector(n downto 0); cnt_out: out std_logic_vector(3 downto 0); en_out: out std_logic; vout:out std_logic_vector(k downto 0) ); end component; component dct8b is generic(m:integer:=13;--MSB pengali
B-7
n:integer:=10;--MSB data input k:integer:=13;--MSB output h:integer:=27;--MSB hasil kali p:integer:=12);--pengali dikalikan 2^12 port(
clk: in std_logic; rst: in std_logic; en_dct: in std_logic; vin: in std_logic_vector(n downto 0); cnt_out: out std_logic_vector(3 downto 0); en_out: out std_logic; vout:out std_logic_vector(k downto 0) ); end component; component memori is generic( lebar_data:integer:=13--lebar bus data memori ); port( addr_baca: in std_logic_vector(7 downto 0); addr_tls: in std_logic_vector(7 downto 0); data_tls: in std_logic_vector(lebar_data downto 0); data_baca: out std_logic_vector(lebar_data downto 0); we:in std_logic; clk: in std_logic ); end component; component quantizer is generic( lebar_dct:integer:=13; lebar_rom:integer:=7;--lebar bus data rom lebar_out:integer:=8; kali:integer:=21 ); port( dct_in:in std_logic_vector(lebar_dct downto 0); rom_in:in std_logic_vector(lebar_rom downto 0); quant_out: out std_logic_vector(lebar_out downto 0) ); end component; component myqROM is generic( width: integer:=8; -- lebar bit tiap alamat depth: integer:=64; -- ada berapa byte alamat addr: integer:=6); -- lebar bus alamat port( --din: in std_logic_vector(width-1 downto 0); dout: out std_logic_vector(width-1 downto 0); address: in std_logic_vector(addr-1 downto 0) --rd: in std_logic ); end component; signal dout: std_logic_vector(lebar_max downto 0);--keluaran memori signal dct_out: std_logic_vector(10 downto 0);--keluaran dcta
B-8
signal dct_out2: std_logic_vector(lebar_max downto 0);--masukan dari dcta ke memori signal en_dct,en_dct2: std_logic; signal rdy,rdy2: std_logic; signal wen,wen2: std_logic; signal ain: std_logic_vector(7 downto 0); signal aout: std_logic_vector(7 downto 0); signal aout_ram2: std_logic_vector(7 downto 0); --signal dct2_out:std_logic_vector(lebar_max downto 0); signal romrdy:std_logic; signal ain2,aout2,alamat_bc:std_logic_vector(7 downto 0); signal dct2_out,dat2_out:std_logic_vector(lebar_max downto 0); signal alamat_ram2_lo:std_logic_vector(5 downto 0); signal dc_en: std_logic; signal qmul:std_logic_vector(7 downto 0); signal dat_out_tmp: std_logic_vector(lebar_ot downto 0); begin alamat_bc<=aout2(7 downto 6)&alamat_ram2_lo; dct_out2<=dct_out(10)&dct_out(10)&dct_out(10)&dct_out; dct2_rdy<=romrdy; dc<=dc_en; dcta: dct8a port map( clk=>clk, rst=>rst, en_dct=>en, vin=>dat_in, cnt_out=>open, en_out=>rdy, vout=>dct_out); mem: memori port map(
ctr: controller port map(
addr_baca=>aout, addr_tls=>ain, data_tls=>dct_out2, data_baca=>dout, we=>wen, clk=>clk); clk=>clk, rst=>rst, a_in=>ain, a_out=>aout, en_dct=>en_dct, en_dct2=>en_dct2, we=>wen, ctr_en=>en, dct_rdy2=>rdy2, dct_rdy=>rdy, rom_rdy=>romrdy, we2=>wen2, dc_en=>dc_en, a2in=>ain2, a2out=>aout2);--aout2=aout2_hi&lo
dctb: dct8b port map( clk=>clk,
B-9
rst=>rst, en_dct=>en_dct2, vin=>dout(10 downto 0), cnt_out=>open, en_out=>rdy2, vout=>dct2_out); rom: myROM port map( dout=>alamat_ram2_lo, address=>aout2(5 downto 0)); mem2: memori port map(
rom2: myqROM port map(
addr_baca=>alamat_bc, addr_tls=>ain2, data_tls=>dct2_out, data_baca=>dat2_out, we=>wen2, clk=>clk);
dout=>qmul, address=>alamat_ram2_lo); --dct_in:in std_logic_vector(lebar_dct downto 0); --rom_in:in std_logic_vector(lebar_rom downto 0); --quant_out: out std_logic_vector(lebar_out downto 0) qtizer: quantizer port map( dct_in=>dat2_out, rom_in=>qmul, quant_out=>dat_out_tmp); diff_pcm: dpcm port map( clk => clk, rst => rst, dc => dc_en, din =>dat_out_tmp, dout => dat_out); end struktural;
Source code VHDL untuk DCT-1D pertama (dct_pl.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_signed.all; use ieee.numeric_std.all; entity dct8a is generic(m:integer:=13;--MSB pengali n:integer:=7;--MSB data input k:integer:=10;--MSB output h:integer:=24;--MSB hasil kali p:integer:=12);--pengali dikalikan 2^12 port( clk: in std_logic; rst: in std_logic;
B - 10
en_dct: in std_logic; vin: in std_logic_vector(n downto 0); cnt_out: out std_logic_vector(3 downto 0); en_out: out std_logic; vout:out std_logic_vector(k downto 0) ); end dct8a; architecture behav of dct8a is constant constant constant constant signal signal signal signal
m1:std_logic_vector(m m2:std_logic_vector(m m3:std_logic_vector(m m4:std_logic_vector(m
downto downto downto downto
0):="00101101010000"; 0):="00011000100000"; 0):="00100010101001"; 0):="01010011101000";
--0.7071x4096 --0.3827 --0.5412 --1.3066
out_en:std_logic; cnt_in:std_logic_vector(7 downto 0); cntr_out:std_logic_vector(7 downto 0); rdy: std_logic;
signal cnt: std_logic_vector(3 downto 0); signal signal signal signal signal signal signal signal
vin_0: vin_1: vin_2: vin_3: vin_4: vin_5: vin_6: vin_7:
std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k
downto downto downto downto downto downto downto downto
signal signal signal signal signal signal signal signal
b0: b1: b2: b3: b4: b5: b6: b7:
std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k
downto downto downto downto downto downto downto downto
0); 0); 0); 0); 0); 0); 0); 0);
signal signal signal signal signal signal signal signal
c0: c1: c2: c3: c4: c5: c6: c7:
std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k
downto downto downto downto downto downto downto downto
0); 0); 0); 0); 0); 0); 0); 0);
signal signal signal signal signal signal signal signal
d0: d1: d2: d3: d4: d5: d6: d7:
std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k
downto downto downto downto downto downto downto downto
0); 0); 0); 0); 0); 0); 0); 0);
0); 0); 0); 0); 0); 0); 0); 0);
B - 11
signal d8:
std_logic_vector(k downto 0);
signal signal signal signal signal signal signal signal signal
e0: e1: e2: e3: e4: e5: e6: e7: e8:
std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h
downto downto downto downto downto downto downto downto downto
0); 0); 0); 0); 0); 0); 0); 0); 0);
signal signal signal signal signal signal signal signal
f0: f1: f2: f3: f4: f5: f6: f7:
std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h
downto downto downto downto downto downto downto downto
0); 0); 0); 0); 0); 0); 0); 0);
signal signal signal signal signal signal signal signal
s0: s1: s2: s3: s4: s5: s6: s7:
std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h
downto downto downto downto downto downto downto downto
0); 0); 0); 0); 0); 0); 0); 0);
signal ofset0: std_logic_vector(k downto 0); signal ofset1: std_logic_vector(k downto 0); signal ofset2: std_logic_vector(k downto 0); signal ofset3: std_logic_vector(k downto 0); signal ofset4: std_logic_vector(k downto 0); signal ofset5: std_logic_vector(k downto 0); signal ofset6: std_logic_vector(k downto 0); signal ofset7: std_logic_vector(k downto 0); --signal en_dct2:std_logic; begin cnt_out<=cnt; en_out<=out_en; myproc: process(clk,rst) begin
--
if(rst='1') then cnt<="0000"; --out_en<='0'; rdy<='0'; vout<=(others=>'0'); en_dct2<='0'; b0<=(others=>'0'); b1<=(others=>'0'); b2<=(others=>'0'); b3<=(others=>'0');
B - 12
b4<=(others=>'0'); b5<=(others=>'0'); b6<=(others=>'0'); b7<=(others=>'0'); c0<=(others=>'0'); c1<=(others=>'0'); c2<=(others=>'0'); c3<=(others=>'0'); c4<=(others=>'0'); c5<=(others=>'0'); c6<=(others=>'0'); c7<=(others=>'0'); d0<=(others=>'0'); d1<=(others=>'0'); d2<=(others=>'0'); d3<=(others=>'0'); d4<=(others=>'0'); d5<=(others=>'0'); d6<=(others=>'0'); d7<=(others=>'0'); d8<=(others=>'0'); e0<=(others=>'0'); e1<=(others=>'0'); e2<=(others=>'0'); e3<=(others=>'0'); e4<=(others=>'0'); e5<=(others=>'0'); e6<=(others=>'0'); e7<=(others=>'0'); e8<=(others=>'0'); f0<=(others=>'0'); f1<=(others=>'0'); f2<=(others=>'0'); f3<=(others=>'0'); f4<=(others=>'0'); f5<=(others=>'0'); f6<=(others=>'0'); f7<=(others=>'0'); s0<=(others=>'0'); s1<=(others=>'0'); s2<=(others=>'0'); s3<=(others=>'0'); s4<=(others=>'0'); s5<=(others=>'0'); s6<=(others=>'0'); s7<=(others=>'0'); ofset0<=(others=>'0'); ofset1<=(others=>'0'); ofset2<=(others=>'0'); ofset3<=(others=>'0'); ofset4<=(others=>'0');
B - 13
ofset5<=(others=>'0'); ofset6<=(others=>'0'); ofset7<=(others=>'0'); elsif(rising_edge(clk)) then if(en_dct='1' or out_en='1') then case cnt is when "0000" => vin_0<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------b0<=vin_0+vin_7; b1<=vin_1+vin_6; b2<=vin_3-vin_4; b3<=vin_1-vin_6; b4<=vin_2+vin_5; b5<=vin_3+vin_4; b6<=vin_2-vin_5; b7<=vin_0-vin_7; ---------------------------------vout<=s2(p+k downto p)+ofset2; when "0001" => vin_1<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------c0<=b0+b5; c1<=b1-b4; c2<=b2+b6; c3<=b1+b4; c4<=b0-b5; c5<=b3+b7; c6<=b3+b6; c7<=b7; ---------------------------------vout<=s3(p+k downto p)+ofset3; ---------------------------------when "0010" => vin_2<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------d0<=c0+c3; d1<=c0-c3; d2<=c2; d3<=c1+c4; d4<=c2-c5; d5<=c4; d6<=c5; d7<=c6; d8<=c7; ---------------------------------vout<=s4(p+k downto p)+ofset4; when "0011" => vin_3<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------e0<=d0(k)&d0(k)&d0&"000000000000"; e1<=d1(k)&d1(k)&d1&"000000000000"; e2<=m3*d2;
B - 14
e3<=m1*d7; e4<=m4*d6; e5<=d5(k)&d5(k)&d5&"000000000000"; e6<=m1*d3; e7<=m2*d4; e8<=d8(k)&d8(k)&d8&"000000000000"; ---------------------------------vout<=s5(p+k downto p)+ofset5; when "0100" => vin_4<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------f0<=e0; f1<=e1; f2<=e5+e6; f3<=e5-e6; f4<=e3+e8; f5<=e8-e3; f6<=e2+e7; f7<=e4+e7; ---------------------------------vout<=s6(p+k downto p)+ofset6; when "0101" => vin_5<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------s0<=f0; s1<=f4+f7; s2<=f2; s3<=f5-f6; s4<=f1; s5<=f5+f6; s6<=f3; s7<=f4-f7; ---------------------------------ofset0(k downto 1)<=(others=>'0'); ofset0(0)<=f0(p-1); ofset4(k downto 1)<=(others=>'0'); ofset4(0)<=f1(p-1); ofset2(k downto 1)<=(others=>'0'); ofset2(0)<=f2(p-1); ofset6(k downto 1)<=(others=>'0'); ofset6(0)<=f3(p-1); ---------------------------------vout<=s7(p+k downto p)+ofset7; -----------------------------------if(rdy='1')then -out_en<='1'; --end if; when "0110" => vin_6<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------vout<=s0(p+k downto p)+ofset0; ---------------------------------ofset1(k downto 1)<=(others=>'0'); ofset1(0)<=s1(p-1); ofset3(k downto 1)<=(others=>'0');
B - 15
ofset3(0)<=s3(p-1); ofset5(k downto 1)<=(others=>'0'); ofset5(0)<=s5(p-1); ofset7(k downto 1)<=(others=>'0'); ofset7(0)<=s7(p-1); when others => vin_7<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------vout<=s1(p+k downto p)+ofset1; ---------------------------------end case; if(cnt="0111") then cnt<=(others=>'0'); rdy<='1'; else cnt<=cnt+1; end if; end if; end if; end process; process(clk,rst,en_dct,cnt,rdy) begin if(rst='1') then out_en<='0'; cnt_in<=(others=>'0'); cntr_out<=(others=>'0'); elsif(rising_edge(clk)) then if(cnt="0101" and rdy='1') then out_en<='1'; end if; if(out_en='1') then if(cnt="0101") then cntr_out<=cntr_out+1; end if; end if; if(en_dct='1') then if(cnt="0111") then cnt_in<=cnt_in+1; end if; else if(cntr_out=cnt_in) then out_en<='0'; end if; end if; end if; end process; end behav;
Source code untuk DCT 1D kedua (dct_st2.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_signed.all;
B - 16
use ieee.numeric_std.all; entity dct8b is generic(m:integer:=13;--MSB pengali n:integer:=10;--MSB data input k:integer:=13;--MSB output h:integer:=27;--MSB hasil kali p:integer:=12);--pengali dikalikan 2^12 port( clk: in std_logic; rst: in std_logic; en_dct: in std_logic; vin: in std_logic_vector(n downto 0); cnt_out: out std_logic_vector(3 downto 0); en_out: out std_logic; vout:out std_logic_vector(k downto 0) ); end dct8b; architecture behav of dct8b is constant constant constant constant
m1:std_logic_vector(m m2:std_logic_vector(m m3:std_logic_vector(m m4:std_logic_vector(m
downto downto downto downto
0):="00101101010000"; 0):="00011000100000"; 0):="00100010101001"; 0):="01010011101000";
--0.7071x4096 --0.3827 --0.5412 --1.3066
signal rdy: std_logic; signal cnt: std_logic_vector(3 downto 0); signal signal signal signal signal signal signal signal
vin_0: vin_1: vin_2: vin_3: vin_4: vin_5: vin_6: vin_7:
std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k
downto downto downto downto downto downto downto downto
signal signal signal signal signal signal signal signal
b0: b1: b2: b3: b4: b5: b6: b7:
std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k
downto downto downto downto downto downto downto downto
0); 0); 0); 0); 0); 0); 0); 0);
signal signal signal signal signal signal signal signal
c0: c1: c2: c3: c4: c5: c6: c7:
std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k
downto downto downto downto downto downto downto downto
0); 0); 0); 0); 0); 0); 0); 0);
0); 0); 0); 0); 0); 0); 0); 0);
B - 17
signal signal signal signal signal signal signal signal signal
d0: d1: d2: d3: d4: d5: d6: d7: d8:
std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k std_logic_vector(k
downto downto downto downto downto downto downto downto downto
0); 0); 0); 0); 0); 0); 0); 0); 0);
signal signal signal signal signal signal signal signal signal
e0: e1: e2: e3: e4: e5: e6: e7: e8:
std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h
downto downto downto downto downto downto downto downto downto
0); 0); 0); 0); 0); 0); 0); 0); 0);
signal signal signal signal signal signal signal signal
f0: f1: f2: f3: f4: f5: f6: f7:
std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h
downto downto downto downto downto downto downto downto
0); 0); 0); 0); 0); 0); 0); 0);
signal signal signal signal signal signal signal signal
s0: s1: s2: s3: s4: s5: s6: s7:
std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h std_logic_vector(h
downto downto downto downto downto downto downto downto
0); 0); 0); 0); 0); 0); 0); 0);
signal ofset0: std_logic_vector(k downto 0); signal ofset1: std_logic_vector(k downto 0); signal ofset2: std_logic_vector(k downto 0); signal ofset3: std_logic_vector(k downto 0); signal ofset4: std_logic_vector(k downto 0); signal ofset5: std_logic_vector(k downto 0); signal ofset6: std_logic_vector(k downto 0); signal ofset7: std_logic_vector(k downto 0); signal out_en:std_logic; signal cnt_in:std_logic_vector(7 downto 0); signal cntr_out:std_logic_vector(7 downto 0);
begin cnt_out<=cnt; en_out<=out_en; myproc: process(clk,rst) begin if(rst='1') then
B - 18
cnt<="0000"; --out_en<='0'; rdy<='0'; vout<=(others=>'0'); b0<=(others=>'0'); b1<=(others=>'0'); b2<=(others=>'0'); b3<=(others=>'0'); b4<=(others=>'0'); b5<=(others=>'0'); b6<=(others=>'0'); b7<=(others=>'0'); c0<=(others=>'0'); c1<=(others=>'0'); c2<=(others=>'0'); c3<=(others=>'0'); c4<=(others=>'0'); c5<=(others=>'0'); c6<=(others=>'0'); c7<=(others=>'0'); d0<=(others=>'0'); d1<=(others=>'0'); d2<=(others=>'0'); d3<=(others=>'0'); d4<=(others=>'0'); d5<=(others=>'0'); d6<=(others=>'0'); d7<=(others=>'0'); d8<=(others=>'0'); e0<=(others=>'0'); e1<=(others=>'0'); e2<=(others=>'0'); e3<=(others=>'0'); e4<=(others=>'0'); e5<=(others=>'0'); e6<=(others=>'0'); e7<=(others=>'0'); e8<=(others=>'0'); f0<=(others=>'0'); f1<=(others=>'0'); f2<=(others=>'0'); f3<=(others=>'0'); f4<=(others=>'0'); f5<=(others=>'0'); f6<=(others=>'0'); f7<=(others=>'0'); s0<=(others=>'0'); s1<=(others=>'0'); s2<=(others=>'0'); s3<=(others=>'0'); s4<=(others=>'0');
B - 19
s5<=(others=>'0'); s6<=(others=>'0'); s7<=(others=>'0'); ofset0<=(others=>'0'); ofset1<=(others=>'0'); ofset2<=(others=>'0'); ofset3<=(others=>'0'); ofset4<=(others=>'0'); ofset5<=(others=>'0'); ofset6<=(others=>'0'); ofset7<=(others=>'0'); elsif(rising_edge(clk)) then if(en_dct='1' or out_en='1') then case cnt is when "0000" => vin_0<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------b0<=vin_0+vin_7; b1<=vin_1+vin_6; b2<=vin_3-vin_4; b3<=vin_1-vin_6; b4<=vin_2+vin_5; b5<=vin_3+vin_4; b6<=vin_2-vin_5; b7<=vin_0-vin_7; ---------------------------------vout<=s2(p+k downto p)+ofset2; when "0001" => vin_1<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------c0<=b0+b5; c1<=b1-b4; c2<=b2+b6; c3<=b1+b4; c4<=b0-b5; c5<=b3+b7; c6<=b3+b6; c7<=b7; ---------------------------------vout<=s3(p+k downto p)+ofset3; ---------------------------------when "0010" => vin_2<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------d0<=c0+c3; d1<=c0-c3; d2<=c2; d3<=c1+c4; d4<=c2-c5; d5<=c4; d6<=c5; d7<=c6; d8<=c7;
B - 20
---------------------------------vout<=s4(p+k downto p)+ofset4; when "0011" => vin_3<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------e0<=d0(k)&d0(k)&d0&"000000000000"; e1<=d1(k)&d1(k)&d1&"000000000000"; e2<=m3*d2; e3<=m1*d7; e4<=m4*d6; e5<=d5(k)&d5(k)&d5&"000000000000"; e6<=m1*d3; e7<=m2*d4; e8<=d8(k)&d8(k)&d8&"000000000000"; ---------------------------------vout<=s5(p+k downto p)+ofset5; when "0100" => vin_4<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------f0<=e0; f1<=e1; f2<=e5+e6; f3<=e5-e6; f4<=e3+e8; f5<=e8-e3; f6<=e2+e7; f7<=e4+e7; ---------------------------------vout<=s6(p+k downto p)+ofset6; when "0101" => vin_5<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------s0<=f0; s1<=f4+f7; s2<=f2; s3<=f5-f6; s4<=f1; s5<=f5+f6; s6<=f3; s7<=f4-f7; ---------------------------------ofset0(k downto 1)<=(others=>'0'); ofset0(0)<=f0(p-1); ofset4(k downto 1)<=(others=>'0'); ofset4(0)<=f1(p-1); ofset2(k downto 1)<=(others=>'0'); ofset2(0)<=f2(p-1); ofset6(k downto 1)<=(others=>'0'); ofset6(0)<=f3(p-1); ---------------------------------vout<=s7(p+k downto p)+ofset7; -----------------------------------if(rdy='1')then -en_out<='1';
B - 21
--end if; when "0110" => vin_6<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------vout<=s0(p+k downto p)+ofset0; ---------------------------------ofset1(k downto 1)<=(others=>'0'); ofset1(0)<=s1(p-1); ofset3(k downto 1)<=(others=>'0'); ofset3(0)<=s3(p-1); ofset5(k downto 1)<=(others=>'0'); ofset5(0)<=s5(p-1); ofset7(k downto 1)<=(others=>'0'); ofset7(0)<=s7(p-1); when others => vin_7<=vin(n)&vin(n)&vin(n)&vin; ---------------------------------vout<=s1(p+k downto p)+ofset1; ---------------------------------end case; if(cnt="0111") then cnt<=(others=>'0'); rdy<='1'; else cnt<=cnt+1; end if; end if; end if; end process; process(clk,rst,en_dct,cnt,rdy) begin if(rst='1') then out_en<='0'; cnt_in<=(others=>'0'); cntr_out<=(others=>'0'); elsif(rising_edge(clk)) then if(cnt="0101" and rdy='1') then out_en<='1'; end if; if(out_en='1') then if(cnt="0101") then cntr_out<=cntr_out+1; end if; end if; if(en_dct='1') then if(cnt="0111") then cnt_in<=cnt_in+1; end if; else if(cntr_out=cnt_in) then out_en<='0'; end if; end if; end if; end process; end behav;
B - 22
Source code transpose buffer dan zigzag buffer (ram.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_signed.all; use ieee.numeric_std.all; entity memori is generic( lebar_data:integer:=13--lebar bus data memori );--pengali dikalikan 2^12 port( addr_baca: in std_logic_vector(7 downto 0); addr_tls: in std_logic_vector(7 downto 0); data_tls: in std_logic_vector(lebar_data downto 0); data_baca: out std_logic_vector(lebar_data downto 0); we:in std_logic; clk: in std_logic ); end entity; architecture behav of memori is type ram is array (0 to 127) of std_logic_vector(13 downto 0); signal mem:ram; begin mem_write: process(clk) begin if(falling_edge(clk) and we='1') then mem(conv_integer(addr_tls)) <= data_tls; end if; end process; data_baca<=mem(conv_integer(addr_baca)); end;
Source code untuk quantizer (quantizer.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_signed.all; entity quantizer is generic( lebar_dct:integer:=13; lebar_rom:integer:=7;--lebar bus data rom lebar_out:integer:=8; kali:integer:=21 ); port( dct_in:in std_logic_vector(lebar_dct downto 0);
B - 23
rom_in:in std_logic_vector(lebar_rom downto 0); quant_out: out std_logic_vector(lebar_out downto 0) ); end quantizer; architecture behav of quantizer is signal hasil_kali: std_logic_vector(kali downto 0); --signal ofset:std_logic_vector(lebar_out-1 downto 0); constant ofset:std_logic_vector(lebar_out-1 downto 0):="00000000"; begin hasil_kali<=dct_in*rom_in; quant_out<=hasil_kali(20 downto 12)+(ofset&hasil_kali(11)); end;
Source code untuk ROM quantizer (qrom.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity myqROM is generic( width: integer:=8; -- lebar bit tiap alamat depth: integer:=64; -- ada berapa byte alamat addr: integer:=6); -- lebar bus alamat port( --din: in std_logic_vector(width-1 downto 0); dout: out std_logic_vector(width-1 downto 0); address: in std_logic_vector(addr-1 downto 0) --rd: in std_logic ); end myqROM; architecture behav of myqROM is -- use array to define the bunch of internal temparary signals type ROMtipe is array (0 to depth-1) of std_logic_vector(width-1 downto 0); signal tmp_rom: ROMtipe; begin tmp_rom(0)<="00100000"; tmp_rom(1)<="00100010"; tmp_rom(2)<="00100111"; tmp_rom(3)<="00011011"; tmp_rom(4)<="00010101"; tmp_rom(5)<="00010000"; tmp_rom(6)<="00010011"; tmp_rom(7)<="00011110"; tmp_rom(8)<="00011111"; tmp_rom(9)<="00010110"; tmp_rom(10)<="00010100"; tmp_rom(11)<="00010001"; tmp_rom(12)<="00001110"; tmp_rom(13)<="00001000";
B - 24
tmp_rom(14)<="00001011"; tmp_rom(15)<="00011000"; tmp_rom(16)<="00011100"; tmp_rom(17)<="00010110"; tmp_rom(18)<="00010011"; tmp_rom(19)<="00001110"; tmp_rom(20)<="00001010"; tmp_rom(21)<="00001001"; tmp_rom(22)<="00001010"; tmp_rom(23)<="00011001"; tmp_rom(24)<="00011111"; tmp_rom(25)<="00010010"; tmp_rom(26)<="00001111"; tmp_rom(27)<="00001101"; tmp_rom(28)<="00001001"; tmp_rom(29)<="00000110"; tmp_rom(30)<="00001010"; tmp_rom(31)<="00011001"; tmp_rom(32)<="00011100"; tmp_rom(33)<="00010001"; tmp_rom(34)<="00001011"; tmp_rom(35)<="00001000"; tmp_rom(36)<="00001000"; tmp_rom(37)<="00000110"; tmp_rom(38)<="00001001"; tmp_rom(39)<="00011000"; tmp_rom(40)<="00011011"; tmp_rom(41)<="00001101"; tmp_rom(42)<="00001001"; tmp_rom(43)<="00001001"; tmp_rom(44)<="00001000"; tmp_rom(45)<="00001000"; tmp_rom(46)<="00001011"; tmp_rom(47)<="00011010"; tmp_rom(48)<="00010011"; tmp_rom(49)<="00001011"; tmp_rom(50)<="00001001"; tmp_rom(51)<="00001001"; tmp_rom(52)<="00001001"; tmp_rom(53)<="00001010"; tmp_rom(54)<="00001111"; tmp_rom(55)<="00100010"; tmp_rom(56)<="00011010"; tmp_rom(57)<="00001111"; tmp_rom(58)<="00001111"; tmp_rom(59)<="00010000"; tmp_rom(60)<="00010001"; tmp_rom(61)<="00011000"; tmp_rom(62)<="00100001"; tmp_rom(63)<="01000100"; dout <= tmp_rom(conv_integer(address)); end behav;
Source code untuk ROM generator zigzag (rom_zigzag.vhd) library ieee;
B - 25
use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity myROM is generic( width: integer:=6; -- lebar bit tiap alamat depth: integer:=64; -- ada berapa byte alamat addr: integer:=6); -- lebar bus alamat port( --din: in std_logic_vector(width-1 downto 0); dout: out std_logic_vector(width-1 downto 0); address: in std_logic_vector(addr-1 downto 0) --rd: in std_logic ); end myROM; architecture behav of myROM is -- use array to define the bunch of internal temparary signals type ROMtipe is array (0 to depth-1) of std_logic_vector(width-1 downto 0); signal tmp_rom: ROMtipe; begin tmp_rom(0)<="000000"; tmp_rom(1)<="000001"; tmp_rom(2)<="001000"; tmp_rom(3)<="010000"; tmp_rom(4)<="001001"; tmp_rom(5)<="000010"; tmp_rom(6)<="000011"; tmp_rom(7)<="001010"; tmp_rom(8)<="010001"; tmp_rom(9)<="011000"; tmp_rom(10)<="100000"; tmp_rom(11)<="011001"; tmp_rom(12)<="010010"; tmp_rom(13)<="001011"; tmp_rom(14)<="000100"; tmp_rom(15)<="000101"; tmp_rom(16)<="001100"; tmp_rom(17)<="010011"; tmp_rom(18)<="011010"; tmp_rom(19)<="100001"; tmp_rom(20)<="101000"; tmp_rom(21)<="110000"; tmp_rom(22)<="101001"; tmp_rom(23)<="100010"; tmp_rom(24)<="011011"; tmp_rom(25)<="010100"; tmp_rom(26)<="001101"; tmp_rom(27)<="000110"; tmp_rom(28)<="000111"; tmp_rom(29)<="001110"; tmp_rom(30)<="010101";
B - 26
tmp_rom(31)<="011100"; tmp_rom(32)<="100011"; tmp_rom(33)<="101010"; tmp_rom(34)<="110001"; tmp_rom(35)<="111000"; tmp_rom(36)<="111001"; tmp_rom(37)<="110010"; tmp_rom(38)<="101011"; tmp_rom(39)<="100100"; tmp_rom(40)<="011101"; tmp_rom(41)<="010110"; tmp_rom(42)<="001111"; tmp_rom(43)<="010111"; tmp_rom(44)<="011110"; tmp_rom(45)<="100101"; tmp_rom(46)<="101100"; tmp_rom(47)<="110011"; tmp_rom(48)<="111010"; tmp_rom(49)<="111011"; tmp_rom(50)<="110100"; tmp_rom(51)<="101101"; tmp_rom(52)<="100110"; tmp_rom(53)<="011111"; tmp_rom(54)<="100111"; tmp_rom(55)<="101110"; tmp_rom(56)<="110101"; tmp_rom(57)<="111100"; tmp_rom(58)<="111101"; tmp_rom(59)<="110110"; tmp_rom(60)<="101111"; tmp_rom(61)<="110111"; tmp_rom(62)<="111110"; tmp_rom(63)<="111111"; dout <= tmp_rom(conv_integer(address)); end behav;
Source code untuk menghitung beda koefisien DC antar blok (dpcm.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_signed.all; use ieee.numeric_std.all; entity dpcm is generic( lebar_ctr:integer:=5; lebar_dat:integer:=5; lebar_ot:integer:=8; lebar_max:integer:=13--lebar bus data memori ); port( clk: in std_logic;
B - 27
rst: in std_logic; dc: in std_logic; din: in std_logic_vector(lebar_ot downto 0); dout: out std_logic_vector(lebar_ot downto 0) ); end dpcm; architecture behav of dpcm is component mux21 is port( a: in std_logic_vector(8 downto 0); b: in std_logic_vector(8 downto 0); sel: in std_logic; y: out std_logic_vector(8 downto 0) ); end component; signal ctr: std_logic_vector(lebar_ctr downto 0); signal dctemp: std_logic_vector(lebar_ot downto 0); signal mulai: std_logic; signal diff: std_logic_vector(lebar_ot downto 0); begin muxpcm: mux21 port map(din,diff,dc,dout); diff<=din-dctemp; process(clk,rst,dc) begin if(rst='1') then dctemp<=(others=>'0'); elsif(rising_edge(clk) and dc='1')then dctemp<=din; end if; end process; end behav;
Source code penyandi entropi DC dan AC (fullcoder.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity fullcoder is port( clk: in std_logic; clr: in std_logic; dc: in std_logic; data_in:in std_logic_vector(15 downto 0); cat:out std_logic_vector(3 downto 0); len:out std_logic_vector(3 downto 0); sym:out std_logic_vector(15 downto 0); huff:out std_logic_vector(15 downto 0); valid:out std_logic); end fullcoder; architecture behav of fullcoder is
B - 28
component ac_coder is port( clk: in std_logic; clr: in std_logic; dc: in std_logic; data_in:in std_logic_vector(15 downto 0); cat:out std_logic_vector(3 downto 0); len:out std_logic_vector(3 downto 0); sym:out std_logic_vector(15 downto 0); huff:out std_logic_vector(15 downto 0); valid:out std_logic); end component; component huff_dc is port( dc_cat: in std_logic_vector(3 downto 0); dc_code: out std_logic_vector(15 downto 0); len: out std_logic_vector(3 downto 0) ); end component; component codemux is port( alen: in std_logic_vector(3 downto 0); blen: in std_logic_vector(3 downto 0); ahuff: in std_logic_vector(15 downto 0); bhuff: in std_logic_vector(15 downto 0); sel: in std_logic; len: out std_logic_vector(3 downto 0); huff: out std_logic_vector(15 downto 0)); end component; signal tmpcat: std_logic_vector(3 downto 0); signal aclen: std_logic_vector(3 downto 0); signal dclen: std_logic_vector(3 downto 0); signal achuff: std_logic_vector(15 downto 0); signal dchuff: std_logic_vector(15 downto 0); begin cat<=tmpcat; coder_ac: ac_coder port map(clk,clr,dc,data_in,tmpcat,aclen,sym,achuff,valid); coder_dc: huff_dc port map(tmpcat,dchuff,dclen); mymux: codemux port map(aclen,dclen,achuff,dchuff,dc,len,huff); end behav;
Source code core penyandi AC (ac_coder.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;
entity ac_coder is port( clk: in std_logic; clr: in std_logic; dc: in std_logic; data_in:in std_logic_vector(15 downto 0);
B - 29
cat:out std_logic_vector(3 downto 0); len:out std_logic_vector(3 downto 0); sym:out std_logic_vector(15 downto 0); huff:out std_logic_vector(15 downto 0); valid:out std_logic); end ac_coder; architecture behav of ac_coder is component rle_ctr is port( clk: in std_logic; clr: in std_logic; dc : in std_logic; data_in:in std_logic_vector(15 downto 0); run:out std_logic_vector(3 downto 0); valid:out std_logic); end component; component findcat is port( a: in std_logic_vector(15 downto 0); cat: out std_logic_vector(3 downto 0); sym: out std_logic_vector(15 downto 0) ); end component; component dataROM is generic( width: integer:=16; -- lebar bit tiap alamat depth: integer:=256; -- ada berapa byte alamat addr: integer:=8); -- lebar bus alamat port( dout: out std_logic_vector(width-1 downto 0); address: in std_logic_vector(addr-1 downto 0) ); end component; component lenROM is generic( width: integer:=4; -- lebar bit tiap alamat depth: integer:=256; -- ada berapa byte alamat addr: integer:=8); -- lebar bus alamat port( dout: out std_logic_vector(width-1 downto 0); address: in std_logic_vector(addr-1 downto 0) ); end component; signal romadr:std_logic_vector(7 downto 0); signal run:std_logic_vector(3 downto 0); signal cat_tmp:std_logic_vector(3 downto 0); begin cat<=cat_tmp; romadr(7 downto 4)<=run; romadr(3 downto 0)<=cat_tmp; k1:rle_ctr port map(clk => clk, clr => clr, dc => dc, data_in => data_in, run => run,
B - 30
valid => valid); k2:findcat port map(a=>data_in, cat=>cat_tmp, sym=>sym); k3:dataROM port map(dout=>huff, address=>romadr); k4:lenROM port map(dout=>len, end behav;
address=>romadr);
Source code penghitung RLE (rle_ctr.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity rle_ctr is port( clk: in std_logic; clr: in std_logic; dc: in std_logic; data_in:in std_logic_vector(15 downto 0); run:out std_logic_vector(3 downto 0); valid:out std_logic); end rle_ctr; architecture behav of rle_ctr is signal ctr: std_logic_vector(3 downto 0); signal data_tmp:std_logic_vector(15 downto 0); signal tmp_val: std_logic; signal run15: std_logic; begin tmp_val<=data_tmp(15) or data_tmp(14) or data_tmp(13) or data_tmp(12) or data_tmp(11) or data_tmp(10) or data_tmp(9) or data_tmp(8) or data_tmp(7) or data_tmp(6) or data_tmp(5) or data_tmp(4) or data_tmp(3) or data_tmp(2) or data_tmp(1) or data_tmp(0) or run15 or dc; run<=ctr; valid<=tmp_val; data_tmp<=data_in; run15<=ctr(0) and ctr(1) and ctr(2) and ctr(3); process(clr,clk) begin if((clr='1') or (dc='1')) then -val<=(others=>'0'); ctr<=(others=>'0'); -tmp_val<='0'; elsif(rising_edge(clk)) then -data_tmp<=data_in; if(tmp_val='0') then ctr<=ctr+1; else ctr<=(others=>'0');
B - 31
end if; end if; end process; end behav;
Source code penghitung kategori (findcat.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_signed.all; entity findcat is port( a: in std_logic_vector(15 downto 0); cat: out std_logic_vector(3 downto 0); sym: out std_logic_vector(15 downto 0) ); end findcat; architecture behav of findcat is signal atmp: signed(15 downto 0); signal b: signed(15 downto 0); signal tmp: signed(15 downto 0); signal state: std_logic_vector(3 downto 0); constant con1: signed:="0000000000000011"; constant con2: signed:="0000000000000111"; constant con3: signed:="0000000000001111"; constant con4: signed:="0000000000011111"; constant con5: signed:="0000000000111111"; constant con6: signed:="0000000001111111"; constant con7: signed:="0000000011111111"; constant con8: signed:="0000000111111111"; constant con9: signed:= "0000001111111111"; constant con10: signed:="0000011111111111"; constant con11: signed:="0000111111111111"; constant con12: signed:="0001111111111111"; constant con13: signed:="0011111111111111"; constant con14: signed:="0111111111111111"; begin atmp<=signed(a); b<=abs(atmp); sym<=std_logic_vector(tmp); process(atmp,b) begin if(std_logic_vector(b(15 downto 0))="0000000000000000") then cat<=(others=>'0'); elsif(std_logic_vector(b(15 downto 0))="0000000000000001") then cat<="0001"; if(atmp(15)='1')then tmp<="0000000000000000"; else tmp<="0000000000000001"; end if; elsif(std_logic_vector(b(15 downto 1))="000000000000001") then cat<="0010";
B - 32
if(atmp(15)='1')then tmp<=con1-b; else tmp<=b; end if; elsif(std_logic_vector(b(15 cat<="0011"; if(atmp(15)='1')then tmp<=con2-b; else tmp<=b; end if; elsif(std_logic_vector(b(15 cat<="0100"; if(atmp(15)='1')then tmp<=con3-b; else tmp<=b; end if; elsif(std_logic_vector(b(15 cat<="0101"; if(atmp(15)='1')then tmp<=con4-b; else tmp<=b; end if; elsif(std_logic_vector(b(15 cat<="0110"; if(atmp(15)='1')then tmp<=con5-b; else tmp<=b; end if; elsif(std_logic_vector(b(15 cat<="0111"; if(atmp(15)='1')then tmp<=con6-b; else tmp<=b; end if; elsif(std_logic_vector(b(15 cat<="1000"; if(atmp(15)='1')then tmp<=con7-b; else tmp<=b; end if; elsif(std_logic_vector(b(15 cat<="1001"; if(atmp(15)='1')then tmp<=con8-b; else tmp<=b; end if; elsif(std_logic_vector(b(15 cat<="1010"; if(atmp(15)='1')then
downto 2))="00000000000001") then
downto 3))="0000000000001") then
downto 4))="000000000001") then
downto 5))="00000000001") then
downto 6))="0000000001") then
downto 7))="000000001") then
downto 8))="00000001") then
downto 9))="0000001") then
B - 33
else
tmp<=con9-b;
tmp<=b; end if; elsif(std_logic_vector(b(15 cat<="1011"; if(atmp(15)='1')then tmp<=con10-b; else tmp<=b; end if; elsif(std_logic_vector(b(15 cat<="1100"; if(atmp(15)='1')then tmp<=con11-b; else tmp<=b; end if; elsif(std_logic_vector(b(15 cat<="1101"; if(atmp(15)='1')then tmp<=con12-b; else tmp<=b; end if; elsif(std_logic_vector(b(15 cat<="1110"; if(atmp(15)='1')then tmp<=con13-b; else tmp<=b; end if; elsif(std_logic_vector(b(15 cat<="1111"; if(atmp(15)='1')then tmp<=con14-b; else tmp<=b; end if; end if; end process; end behav;
downto 10))="000001") then
downto 11))="00001") then
downto 12)) ="0001") then
downto 13)) ="001") then
downto 14)) ="01") then
Source code ROM untuk tabel huffmann (huff_rom.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity dataROM is generic( width: integer:=16; -- lebar bit tiap alamat depth: integer:=256; -- ada berapa byte alamat addr: integer:=8); -- lebar bus alamat port(
B - 34
--din: in std_logic_vector(width-1 downto 0); dout: out std_logic_vector(width-1 downto 0); address: in std_logic_vector(addr-1 downto 0) --rd: in std_logic ); end dataROM; architecture behav of dataROM is -- use array to define the bunch of internal temparary signals type ROMtipe is array (0 to depth-1) of std_logic_vector(width-1 downto 0); signal tmp_rom: ROMtipe; begin tmp_rom(0)<="0000000000001010"; tmp_rom(1)<="0000000000000000"; tmp_rom(2)<="0000000000000001"; tmp_rom(3)<="0000000000000100"; tmp_rom(4)<="0000000000001011"; tmp_rom(5)<="0000000000011010"; tmp_rom(6)<="0000000001111000"; tmp_rom(7)<="0000000011111000"; tmp_rom(8)<="0000001111110110"; tmp_rom(9)<="1111111110000010"; tmp_rom(10)<="1111111110000011"; tmp_rom(17)<="0000000000001100"; tmp_rom(18)<="0000000000011011"; tmp_rom(19)<="0000000001111001"; tmp_rom(20)<="0000000111110110"; tmp_rom(21)<="0000011111110110"; tmp_rom(22)<="1111111110000100"; tmp_rom(23)<="1111111110000101"; tmp_rom(24)<="1111111110000110"; tmp_rom(25)<="1111111110000111"; tmp_rom(26)<="1111111110001000"; tmp_rom(33)<="0000000000011100"; tmp_rom(34)<="0000000011111001"; tmp_rom(35)<="0000001111110111"; tmp_rom(36)<="0000111111110100"; tmp_rom(37)<="1111111110001001"; tmp_rom(38)<="1111111110001010"; tmp_rom(39)<="1111111110001011"; tmp_rom(40)<="1111111110001100"; tmp_rom(41)<="1111111110001101"; tmp_rom(42)<="1111111110001110"; tmp_rom(49)<="0000000000111010"; tmp_rom(50)<="0000000111110111"; tmp_rom(51)<="0000111111110101"; tmp_rom(52)<="1111111110001111"; tmp_rom(53)<="1111111110010000"; tmp_rom(54)<="1111111110010001"; tmp_rom(55)<="1111111110010010"; tmp_rom(56)<="1111111110010011"; tmp_rom(57)<="1111111110010100";
B - 35
tmp_rom(58)<="1111111110010101"; tmp_rom(65)<="0000000000111011"; tmp_rom(66)<="0000001111111000"; tmp_rom(67)<="1111111110010110"; tmp_rom(68)<="1111111110010111"; tmp_rom(69)<="1111111110011000"; tmp_rom(70)<="1111111110011001"; tmp_rom(71)<="1111111110011010"; tmp_rom(72)<="1111111110011011"; tmp_rom(73)<="1111111110011100"; tmp_rom(74)<="1111111110011101"; tmp_rom(81)<="0000000001111010"; tmp_rom(82)<="0000011111110111"; tmp_rom(83)<="1111111110011110"; tmp_rom(84)<="1111111110011111"; tmp_rom(85)<="1111111110100000"; tmp_rom(86)<="1111111110100001"; tmp_rom(87)<="1111111110100010"; tmp_rom(88)<="1111111110100011"; tmp_rom(89)<="1111111110100100"; tmp_rom(90)<="1111111110100101"; tmp_rom(97)<="0000000001111011"; tmp_rom(98)<="0000111111110110"; tmp_rom(99)<="1111111110100110"; tmp_rom(100)<="1111111110100111"; tmp_rom(101)<="1111111110101000"; tmp_rom(102)<="1111111110101001"; tmp_rom(103)<="1111111110101010"; tmp_rom(104)<="1111111110101011"; tmp_rom(105)<="1111111110101100"; tmp_rom(106)<="1111111110101101"; tmp_rom(113)<="0000000011111010"; tmp_rom(114)<="0000111111110111"; tmp_rom(115)<="1111111110101110"; tmp_rom(116)<="1111111110101111"; tmp_rom(117)<="1111111110110000"; tmp_rom(118)<="1111111110110001"; tmp_rom(119)<="1111111110110010"; tmp_rom(120)<="1111111110110011"; tmp_rom(121)<="1111111110110100"; tmp_rom(122)<="1111111110110101"; tmp_rom(129)<="0000000111111000"; tmp_rom(130)<="111111111000000"; tmp_rom(131)<="1111111110110110"; tmp_rom(132)<="1111111110110111"; tmp_rom(133)<="1111111110111000"; tmp_rom(134)<="1111111110111001"; tmp_rom(135)<="1111111110111010"; tmp_rom(136)<="1111111110111011"; tmp_rom(137)<="1111111110111100"; tmp_rom(138)<="1111111110111101"; tmp_rom(145)<="0000000111111001"; tmp_rom(146)<="1111111110111110"; tmp_rom(147)<="1111111110111111"; tmp_rom(148)<="1111111111000000"; tmp_rom(149)<="1111111111000001"; tmp_rom(150)<="1111111111000010";
B - 36
tmp_rom(151)<="1111111111000011"; tmp_rom(152)<="1111111111000100"; tmp_rom(153)<="1111111111000101"; tmp_rom(154)<="1111111111000110"; tmp_rom(161)<="0000000111111010"; tmp_rom(162)<="1111111111000111"; tmp_rom(163)<="1111111111001000"; tmp_rom(164)<="1111111111001001"; tmp_rom(165)<="1111111111001010"; tmp_rom(166)<="1111111111001011"; tmp_rom(167)<="1111111111001100"; tmp_rom(168)<="1111111111001101"; tmp_rom(169)<="1111111111001110"; tmp_rom(170)<="1111111111001111"; tmp_rom(177)<="0000001111111001"; tmp_rom(178)<="1111111111010000"; tmp_rom(179)<="1111111111010001"; tmp_rom(180)<="1111111111010010"; tmp_rom(181)<="1111111111010011"; tmp_rom(182)<="1111111111010100"; tmp_rom(183)<="1111111111010101"; tmp_rom(184)<="1111111111010110"; tmp_rom(185)<="1111111111010111"; tmp_rom(186)<="1111111111011000"; tmp_rom(193)<="0000001111111010"; tmp_rom(194)<="1111111111011001"; tmp_rom(195)<="1111111111011010"; tmp_rom(196)<="1111111111011011"; tmp_rom(197)<="1111111111011100"; tmp_rom(198)<="1111111111011101"; tmp_rom(199)<="1111111111011110"; tmp_rom(200)<="1111111111011111"; tmp_rom(201)<="1111111111100000"; tmp_rom(202)<="1111111111100001"; tmp_rom(209)<="0000011111111000"; tmp_rom(210)<="1111111111100010"; tmp_rom(211)<="1111111111100011"; tmp_rom(212)<="1111111111100100"; tmp_rom(213)<="1111111111100101"; tmp_rom(214)<="1111111111100110"; tmp_rom(215)<="1111111111100111"; tmp_rom(216)<="1111111111101000"; tmp_rom(217)<="1111111111101001"; tmp_rom(218)<="1111111111101010"; tmp_rom(225)<="1111111111101011"; tmp_rom(226)<="1111111111101100"; tmp_rom(227)<="1111111111101101"; tmp_rom(228)<="1111111111101110"; tmp_rom(229)<="1111111111101111"; tmp_rom(230)<="1111111111110000"; tmp_rom(231)<="1111111111110001"; tmp_rom(232)<="1111111111110010"; tmp_rom(233)<="1111111111110011"; tmp_rom(234)<="1111111111110100"; tmp_rom(241)<="1111111111110101"; tmp_rom(242)<="1111111111110110"; tmp_rom(243)<="1111111111110111";
B - 37
tmp_rom(244)<="1111111111111000"; tmp_rom(245)<="1111111111111001"; tmp_rom(246)<="1111111111111010"; tmp_rom(247)<="1111111111111011"; tmp_rom(248)<="1111111111111100"; tmp_rom(249)<="1111111111111101"; tmp_rom(250)<="1111111111111110"; tmp_rom(240)<="0000011111111001"; dout <= tmp_rom(conv_integer(address)); end behav;
source code ROM untuk tabel panjang kode huffman (lenrom.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity lenROM is generic( width: integer:=4; -- lebar bit tiap alamat depth: integer:=256; -- ada berapa byte alamat addr: integer:=8); -- lebar bus alamat port( --din: in std_logic_vector(width-1 downto 0); dout: out std_logic_vector(width-1 downto 0); address: in std_logic_vector(addr-1 downto 0) --rd: in std_logic ); end lenROM; architecture behav of lenROM is -- use array to define the bunch of internal temparary signals type ROMtipe is array (0 to depth-1) of std_logic_vector(width-1 downto 0); signal tmp_rom: ROMtipe; begin tmp_rom(0)<="0011"; tmp_rom(1)<="0001"; tmp_rom(2)<="0001"; tmp_rom(3)<="0010"; tmp_rom(4)<="0011"; tmp_rom(5)<="0100"; tmp_rom(6)<="0110"; tmp_rom(7)<="0111"; tmp_rom(8)<="1001"; tmp_rom(9)<="1111"; tmp_rom(10)<="1111"; tmp_rom(17)<="0011"; tmp_rom(18)<="0100";
B - 38
tmp_rom(19)<="0110"; tmp_rom(20)<="1000"; tmp_rom(21)<="1010"; tmp_rom(22)<="1111"; tmp_rom(23)<="1111"; tmp_rom(24)<="1111"; tmp_rom(25)<="1111"; tmp_rom(26)<="1111"; tmp_rom(33)<="0100"; tmp_rom(34)<="0111"; tmp_rom(35)<="1001"; tmp_rom(36)<="1011"; tmp_rom(37)<="1111"; tmp_rom(38)<="1111"; tmp_rom(39)<="1111"; tmp_rom(40)<="1111"; tmp_rom(41)<="1111"; tmp_rom(42)<="1111"; tmp_rom(49)<="0101"; tmp_rom(50)<="1000"; tmp_rom(51)<="1011"; tmp_rom(52)<="1111"; tmp_rom(53)<="1111"; tmp_rom(54)<="1111"; tmp_rom(55)<="1111"; tmp_rom(56)<="1111"; tmp_rom(57)<="1111"; tmp_rom(58)<="1111"; tmp_rom(65)<="0101"; tmp_rom(66)<="1001"; tmp_rom(67)<="1111"; tmp_rom(68)<="1111"; tmp_rom(69)<="1111"; tmp_rom(70)<="1111"; tmp_rom(71)<="1111"; tmp_rom(72)<="1111"; tmp_rom(73)<="1111"; tmp_rom(74)<="1111"; tmp_rom(81)<="0110"; tmp_rom(82)<="1010"; tmp_rom(83)<="1111"; tmp_rom(84)<="1111"; tmp_rom(85)<="1111"; tmp_rom(86)<="1111"; tmp_rom(87)<="1111"; tmp_rom(88)<="1111"; tmp_rom(89)<="1111"; tmp_rom(90)<="1111"; tmp_rom(97)<="0110"; tmp_rom(98)<="1011"; tmp_rom(99)<="1111"; tmp_rom(100)<="1111"; tmp_rom(101)<="1111"; tmp_rom(102)<="1111"; tmp_rom(103)<="1111"; tmp_rom(104)<="1111"; tmp_rom(105)<="1111";
B - 39
tmp_rom(106)<="1111"; tmp_rom(113)<="0111"; tmp_rom(114)<="1011"; tmp_rom(115)<="1111"; tmp_rom(116)<="1111"; tmp_rom(117)<="1111"; tmp_rom(118)<="1111"; tmp_rom(119)<="1111"; tmp_rom(120)<="1111"; tmp_rom(121)<="1111"; tmp_rom(122)<="1111"; tmp_rom(129)<="1000"; tmp_rom(130)<="1110"; tmp_rom(131)<="1111"; tmp_rom(132)<="1111"; tmp_rom(133)<="1111"; tmp_rom(134)<="1111"; tmp_rom(135)<="1111"; tmp_rom(136)<="1111"; tmp_rom(137)<="1111"; tmp_rom(138)<="1111"; tmp_rom(145)<="1000"; tmp_rom(146)<="1111"; tmp_rom(147)<="1111"; tmp_rom(148)<="1111"; tmp_rom(149)<="1111"; tmp_rom(150)<="1111"; tmp_rom(151)<="1111"; tmp_rom(152)<="1111"; tmp_rom(153)<="1111"; tmp_rom(154)<="1111"; tmp_rom(161)<="1000"; tmp_rom(162)<="1111"; tmp_rom(163)<="1111"; tmp_rom(164)<="1111"; tmp_rom(165)<="1111"; tmp_rom(166)<="1111"; tmp_rom(167)<="1111"; tmp_rom(168)<="1111"; tmp_rom(169)<="1111"; tmp_rom(170)<="1111"; tmp_rom(177)<="1001"; tmp_rom(178)<="1111"; tmp_rom(179)<="1111"; tmp_rom(180)<="1111"; tmp_rom(181)<="1111"; tmp_rom(182)<="1111"; tmp_rom(183)<="1111"; tmp_rom(184)<="1111"; tmp_rom(185)<="1111"; tmp_rom(186)<="1111"; tmp_rom(193)<="1001"; tmp_rom(194)<="1111"; tmp_rom(195)<="1111"; tmp_rom(196)<="1111"; tmp_rom(197)<="1111"; tmp_rom(198)<="1111";
B - 40
tmp_rom(199)<="1111"; tmp_rom(200)<="1111"; tmp_rom(201)<="1111"; tmp_rom(202)<="1111"; tmp_rom(209)<="1010"; tmp_rom(210)<="1111"; tmp_rom(211)<="1111"; tmp_rom(212)<="1111"; tmp_rom(213)<="1111"; tmp_rom(214)<="1111"; tmp_rom(215)<="1111"; tmp_rom(216)<="1111"; tmp_rom(217)<="1111"; tmp_rom(218)<="1111"; tmp_rom(225)<="1111"; tmp_rom(226)<="1111"; tmp_rom(227)<="1111"; tmp_rom(228)<="1111"; tmp_rom(229)<="1111"; tmp_rom(230)<="1111"; tmp_rom(231)<="1111"; tmp_rom(232)<="1111"; tmp_rom(233)<="1111"; tmp_rom(234)<="1111"; tmp_rom(241)<="1111"; tmp_rom(242)<="1111"; tmp_rom(243)<="1111"; tmp_rom(244)<="1111"; tmp_rom(245)<="1111"; tmp_rom(246)<="1111"; tmp_rom(247)<="1111"; tmp_rom(248)<="1111"; tmp_rom(249)<="1111"; tmp_rom(250)<="1111"; tmp_rom(240)<="1010"; dout <= tmp_rom(conv_integer(address)); end behav;
source code penyandi DC (dc_coder.vhd) library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use ieee.std_logic_signed.all; use std.textio.all; entity huff_dc is port( dc_cat: in std_logic_vector(3 downto 0); dc_code: out std_logic_vector(15 downto 0); len: out std_logic_vector(3 downto 0) ); end huff_dc; architecture behav of huff_dc is
B - 41
begin
process(dc_cat) begin if(dc_cat="0000") then dc_code<="0000000000000000"; len<="0001"; elsif(dc_cat="0001") then dc_code<="0000000000000010"; len<="0010"; elsif(dc_cat="0010") then dc_code<="0000000000000011"; len<="0010"; elsif(dc_cat="0011") then dc_code<="0000000000000100"; len<="0010"; elsif(dc_cat="0100") then dc_code<="0000000000000101"; len<="0010"; elsif(dc_cat="0101") then dc_code<="0000000000000110"; len<="0010"; elsif(dc_cat="0110") then dc_code<="0000000000001110"; len<="0011"; elsif(dc_cat="0111") then dc_code<="0000000000011110"; len<="0100"; elsif(dc_cat="1000") then dc_code<="0000000000111110"; len<="0101"; elsif(dc_cat="1001") then dc_code<="0000000001111110"; len<="0110"; elsif(dc_cat="1010") then dc_code<="0000000011111110"; len<="0111"; elsif(dc_cat="1011") then dc_code<="0000000111111110"; len<="1000"; elsif(dc_cat="1100") then dc_code<="0000001111111110"; len<="1001"; elsif(dc_cat="1101") then dc_code<="0000011111111110"; len<="1010"; elsif(dc_cat="1110") then dc_code<="0000111111111110"; len<="1011"; elsif(dc_cat="1111") then dc_code<="0001111111111110"; len<="1100"; end if; end process; end behav;
source code multiplekser kode antara DC dan AC (codemux.vhd)
B - 42
library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use ieee.std_logic_signed.all; use std.textio.all; entity codemux is port( alen: in std_logic_vector(3 downto 0); blen: in std_logic_vector(3 downto 0); ahuff: in std_logic_vector(15 downto 0); bhuff: in std_logic_vector(15 downto 0); sel: in std_logic; len: out std_logic_vector(3 downto 0); huff: out std_logic_vector(15 downto 0)); end codemux; architecture behav of codemux is signal temp_huff: std_logic_vector(15 downto 0); signal temp_len: std_logic_vector(3 downto 0); signal temp_huff_not: std_logic_vector(15 downto 0); signal temp_len_not: std_logic_vector(3 downto 0); begin temp_huff<=sel&sel&sel&sel&sel&sel&sel&sel&sel&sel&sel&sel&sel&sel&sel&sel; temp_len<=sel&sel&sel&sel; temp_huff_not<=not(temp_huff); temp_len_not<=not(temp_len); len<=(alen and temp_len_not) or (blen and temp_len); huff<=(ahuff and temp_huff_not) or (bhuff and temp_huff); end behav;
source code byte stuffer , konverter kode entropi paralel ke serial (p2s.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; entity p2s is port( clk: in std_logic; clr: in std_logic; en: in std_logic; addr_tls:in std_logic_vector(7 downto 0); addr: out std_logic_vector(7 downto 0); len:in std_logic_vector(3 downto 0); huff: in std_logic_vector(15 downto 0); cat:in std_logic_vector(3 downto 0); sym: in std_logic_vector(15 downto 0); rdy: out std_logic; ser: out std_logic); end p2s; architecture behav of p2s is signal tmpser: std_logic; signal cnt,tmplen,tmpcat: std_logic_vector(3 downto 0);
B - 43
signal tmphuff,tmpsym: std_logic_vector(15 downto 0); signal addrtmp,addr_tls_tmp: std_logic_vector(7 downto 0); signal state: std_logic_vector(3 downto 0); signal tanda_tls,rdy1: std_logic; signal tanda_bc,first:std_logic; begin ser<=tmpser; addr<=addrtmp; process(clk,clr) begin if(clr='1') then tanda_bc<='0'; tanda_tls<='0'; tmpser<='0'; cnt<=(others=>'0'); tmpcat<=(others=>'0'); -data<=(others=>'0'); tmpsym<=(others=>'0'); state<=(others=>'0'); addrtmp<=(others=>'0'); addr_tls_tmp<=(others=>'0'); rdy1<='0'; first<='0'; rdy<='0'; elsif(rising_edge(clk)) then if(first='1') then rdy<=rdy1; end if; if(en='1') then addr_tls_tmp<=addr_tls; if(addr_tls_tmp="11111111" and addr_tls="00000000" ) then tanda_tls<=not tanda_tls; end if; case state is when "0000" => --akuisisi data if(first='0')then rdy1<='1'; rdy<='1'; end if; tmplen<=len; tmphuff<=huff; if(cat="0000") then tmpcat<=cat; else tmpcat<=cat-1; end if; tmpsym<=sym; state<="0001"; tmpser<=huff(conv_integer(len)); cnt<=len-1; first<='1'; when "0001" => --keluarkan data huff tmpser<=tmphuff(conv_integer(cnt)); if(cnt="0000") then if(tmphuff="0000000000001010" or tmphuff="0000011111111001") then state<="0000";
B - 44
if(addrtmp="11111111") then tanda_bc<=not tanda_bc; end if; if((addrtmp>=(addr_tls-1) and (tanda_bc = tanda_tls)) or (addrtmp="11111111" and addr_tls="00000000")) then rdy1<='0'; else rdy1<='1'; addrtmp<=addrtmp+1; end if; else state<="0010"; cnt<=tmpcat; end if; else cnt<=cnt-1; end if; when "0010" => tmpser<=tmpsym(conv_integer(cnt)); if(cnt="0000") then state<="0000"; --cnt<="0000"; if(addrtmp="11111111") then tanda_bc<=not tanda_bc; end if; if((addrtmp>=(addr_tls-1) and (tanda_bc = tanda_tls)) or (addrtmp="11111111" and addr_tls="00000000")) then rdy1<='0'; else rdy1<='1'; addrtmp<=addrtmp+1; end if; else cnt<=cnt-1; end if; when others => state<="0000"; end case; else tmpser<=not(tmpser); rdy1<='0'; end if; end if; end process; end behav;
Source code pengendali DCT-2D (controller.vhd) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_signed.all; use ieee.numeric_std.all;
B - 45
entity controller is port( clk: in std_logic; rst: in std_logic; a_in: out std_logic_vector(7 downto 0); a_out: out std_logic_vector(7 downto 0); en_dct: out std_logic; en_dct2: out std_logic; we: out std_logic; ctr_en: in std_logic; dct_rdy2: in std_logic;--penanda dct2 sudah ready datanya dct_rdy: in std_logic; rom_rdy: out std_logic; --menandai apakah rom zigzag sudah bisa diakses we2: out std_logic; dc_en:out std_logic; a2in: out std_logic_vector(7 downto 0); a2out: out std_logic_vector(7 downto 0) ); end entity; architecture behav of controller is signal en2,rom_rd: std_logic; signal a_in1,a_out1:std_logic_vector(7 downto 0); signal a_in2a,a_out2a:std_logic_vector(7 downto 0); signal cntia,cntoa:std_logic_vector(2 downto 0); signal cntib,cntob:std_logic_vector(7 downto 0); signal cnti1a,cnto1a:std_logic_vector(2 downto 0); signal cnti1b,cnto1b:std_logic_vector(7 downto 0); signal dc:std_logic; begin dc_en<=dc; a_in<=a_in1; a2in<=a_in2a; a2out<=a_out2a; a_out(5 downto 3)<=a_out1(2 downto 0); a_out(2 downto 0)<=a_out1(5 downto 3); a_out(7 downto 6)<=a_out1(7 downto 6); rom_rdy<=rom_rd; dct_proc: process(clk,rst) begin if(rst='1')then a_in1<=(others=>'1'); en_dct<='0'; en2<='0'; we<='1'; cntia<=(others=>'0'); cntib<=(others=>'0'); cntoa<=(others=>'0'); cntob<=(others=>'0'); elsif(rising_edge(clk))then en_dct<=ctr_en; if(dct_rdy='1')then we<='1'; if(cntia="111") then cntib<=cntib+1;
B - 46
else
cntia<="000";
cntia<=cntia+1; end if; if(a_in1="00111111")then en2<='1'; a_in1<=a_in1+1; elsif(a_in1="01111111")then a_in1<="00000000"; else a_in1<=a_in1+1; end if; else
we<='0'; if(cntib=cntob) then en2<='0'; end if; end if; if(en2='1') then if(cntoa="111") then cntob<=cntob+1; cntoa<="000"; else cntoa<=cntoa+1; end if; end if; end if; end process; dct2_proc: process(clk,rst,en2) begin if(rst='1')then a_out1<="01111111"; en_dct2<='0'; elsif(rising_edge(clk))then if(en2='1') then en_dct2<='1'; if(a_out1="01111111")then a_out1<="00000000"; else a_out1<=a_out1+1; end if; else en_dct2<='0'; end if; end if; end process; isi_dct2: process(clk,rst,dct_rdy2)begin --pengisian hasil dct2 ke ram2 if(rst='1')then a_in2a<=(others=>'1'); rom_rd<='0'; we2<='1';
B - 47
dc<='0'; cnti1a<=(others=>'0'); cnti1b<=(others=>'0'); cnto1a<=(others=>'0'); cnto1b<=(others=>'0'); elsif(rising_edge(clk)) then if(dct_rdy2='1')then we2<='1'; if(cnti1a="111") then cnti1b<=cnti1b+1; cnti1a<="000"; else cnti1a<=cnti1a+1; end if; if(a_in2a(5 downto 0)="011100")then rom_rd<='1'; dc<='1'; a_in2a<=a_in2a+1; elsif(a_in2a="01111111")then a_in2a<="00000000"; dc<='0'; else a_in2a<=a_in2a+1; dc<='0'; end if; else we2<='0'; if(cnti1b=cnto1b) then rom_rd<='0'; end if; end if; if(rom_rd='1') then if(cnto1a="111") then cnto1b<=cnto1b+1; cnto1a<="000"; else cnto1a<=cnto1a+1; end if; end if; end if; end process; zigzag: process(clk,rst,rom_rd) begin if(rst='1')then a_out2a<=(others=>'0'); elsif(rising_edge(clk) and rom_rd='1')then if(a_out2a="01111111")then a_out2a<="00000000"; else a_out2a<=a_out2a+1; end if; end if; end process; end behav;
B - 48
Lampiran C. Tabel Sandi Huffman untuk koefisien AC DCT
run,cat 0,0 ( EOB) 0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 0,10 1,1 1,2 1,3 1,4 1,5 1,6 1,7 1,8 1,9 1,10 2,1 2,2 2,3 2,4 2,5 2,6 2,7 2,8 2,9 2,10 3,1
huffman code 1010 0 1 100 1011 11010 1111000 11111000 1111110110 1111111110000010 1111111110000010 1100 11011 1111001 111110110 11111110110 1111111110000100 1111111110000100 1111111110000110 1111111110000110 1111111110001000 11100 11111001 1111110111 111111110100 1111111110001000 1111111110001010 1111111110001010 1111111110001100 1111111110001100 1111111110001110 111010
run, cat 3,2 3,3 3,4 3,5 3,6 3,7 3,8 3,9 3,10 4,1 4,2 4,3 4,4 4,5 4,6 4,7 4,8 4,9 4,10 5,1 5,2 5,3 5,4 5,5 5,6 5,7 5,8 5,9 5,10 6,1 6,2 6,3
huffman code 111110111 111111110101 1111111110001110 1111111110010000 1111111110010000 1111111110010010 1111111110010010 1111111110010100 1111111110010100 111011 1111111000 1111111110010110 1111111110010110 1111111110011000 1111111110011000 1111111110011010 1111111110011010 1111111110011100 1111111110011100 1111010 11111110111 1111111110011110 1111111110011110 1111111110100000 1111111110100000 1111111110100010 1111111110100010 1111111110100100 1111111110100100 1111011 111111110110 1111111110100110
run,cat 6,4 6,5 6,6 6,7 6,8 6,9 6,10 7,1 7,2 7,3 7,4 7,5 7,6 7,7 7,8 7,9 7,10 8,1 8,2 8,3 8,4 8,5 8,6 8,7 8,8 8,9 8,10 9,1 9,2 9,3 9,4 9,5 9,6 9,7 9,8 9,9 9,10 10,1
huffman code 1111111110100110 1111111110101000 1111111110101000 1111111110101010 1111111110101010 1111111110101100 1111111110101100 11111010 111111110111 1111111110101110 1111111110101110 1111111110110000 1111111110110000 1111111110110010 1111111110110010 1111111110110100 1111111110110100 111111000 111111111000000 1111111110110110 1111111110110110 1111111110111000 1111111110111000 1111111110111010 1111111110111010 1111111110111100 1111111110111100 111111001 1111111110111110 1111111110111110 1111111111000000 1111111111000000 1111111111000010 1111111111000010 1111111111000100 1111111111000100 1111111111000110 111111010
Kuesioner usia : 21 th pekerjaan : mahasiswa aturan main 1. ekstrak file survei.zip, akan anda dapatkan folder 'kuesioner' yang berisi folder 'resolusi240x320' dan 'resolusi480x640'. Di dalam masing-masing folder tersebut terdapat folder 'satu', 'dua', 'tiga' dan 'empat'. 2. Di dalam tiap folder 'satu', 'dua' dst terdapat 2 gambar yang hampir sama yaitu 'asli.bmp' dan 'rekonstruksi.bmp' Pertanyaan : Untuk masing-masing folder 'resolusi....' , bandingkan gambar asli dan rekonstruksi pada setiap folder 'satu', 'dua', kemudian berilah tanda (tanda v atau x) pada tabel di bawah ini dengan kriteria sebagai berikut: excellent, jika menurut anda gambar asli sama persis dengan gambar rekonstruksi, tidak ada blur sedikitpun good, jika menurut anda ada perbedaan sedikit sekali gambar kanan dengan gambar kiri (misalnya sedikit blur – sekitar 10 objek yang mengalami blur), fair, jika pada gambar kanan terdapat objek yang blur (sekitar > 10 objek) dan sedikit distorsi (misalnya ada kotoran,artefak) tetapi tidak menggangu poor, jika pada gambar kanan terdapat distorsi yang menggangu penampilan unsatisfactory, jika gambar kanan terdapat banyak distorsi atau sudah sukar dikenali A. Resolusi 240x320 gambar
excellent
Satu
x
Good
dua
Fair
Poor
unsatisfactory
x
tiga
x
empat
x
B. Resolusi 480x640
gambar
excellent
Satu dua tiga empat
Good
Fair
Poor
x x x x
unsatisfactory