Anda di sini

Elektronika

Menggunakan Xilinx VIVADO untuk Memprogram dan Mensimulasikan FPGA

Kusuma Wardana - 14 November 2019 18:38:13 0

Pendahuluan

Vivado adalah software yang diproduksi oleh Xilinx untuk melakukan sintesis serta analisis terhadap HDL (Hardware Description Language) yang nantikan akan kita tanamkan pada FPGA (Field Programmable Gate Array). Tentu disini FPGA yang akan kita pakai merupakan keluaran dari Xilinx. Sebelum Vivado, terdapat software pendahulunya yang dikenal sebagai Xilix ISE.

Tutorial ini merupakan tahapan paling awal dalam menggunakan Vivado untuk memprogram FPGA kita. Vivado merupakan software yang akaya akan fitur. Mulai dari pemrograman dasar blok-blok logika dalam FPGA, simulasi, hingga pemrograman SoC (System on Chip). Untuk saat ini, kita hanya akan membahas langkah dasar untuk memprogram FPGA. Seiring dengan waktu dan ketekunan, tahap demi tahap kita akan semakin paham menggunakan software ini.

Membuat Project Vivado

Asumsi kalian sudah menginstal Vivado. Jika belum, ikuti petunjuknya di sini. Jika sudah terinstal, jalankanlah program Vivado tersebut. Tampilan awal akan diperlihatkan seperti gambar berikut:

Pada gambar di atas, pilih Create Project. Selanjutnya, akan muncul jendela Create a New Vivado Project, lalu klik NEXT. Nanti akan muncul jendela Project Name seperti gambar berikut:

Beri nama project kita. Misal, saya kasih nama project_adder. Hindari menggunakan spasi ya.
Untuk Project Location, kalian bisa tempatkan di tempat tertentu. Misal saat ini saya taruh di drive E, dan saya buatkan satu folder khusus yaitu VIVADOBASIC. Jangan lupa dicentang Create project Subdirectory. Kemudian klik NEXT, dan akan muncul jendela berikut:

Pada jendela Project Type, pilih RTL Project, dan centang Do not specify resources at this time. Kemudia klik NEXT, dan akan muncul jendela berikut:

Pada jendela Default Part, kita akan menentukan jenis board apa yang akan kita gunakan. Pastikan kalian tahu jenis board apa yang digunakan, sebab bagian ini akan menentukan konfigurasi yang tepat saat melakukan proses sintesis dan implementasi dari program kita selanjutnya. Mungkin board yang kalian pakai berbeda dengan board yang saya pakai. Namun, hal ini tidak menjadi masalah.

Ada dua cara yang dapat dilakukan, yaitu menentukan secara spesifik part yang digunakan, atau dengan cara memilih langsung berdasarkan board yang digunakan.

1. Berdasarkan Parts
Jika ingin menentukan berdasarkan Parts, kita harus mengetahui kode dari IC yang kita gunakan. Caranya, bisa kalian lihat pada kotak dari board yang kalian punya atau baca di Reference Manual-nya. Misal, sebagai contoh saya menggunakan board Basys 3. Karena pilihannya cukup banyak, saya bisa lakukan filter. Basys 3 merupakan keluarga Artix-7, dan package-nya cpg236. Speed-nya -1. Dan saya pilih xc735tcpg236-1. Kalau kalian memiliki board yang berbeda dan kebingungan, cukup googling saja. Misal saya punya board NEXYS 4 DDR, saya cukup googling dengan kata kunci "NEXYS 4 DDR Reference Manual". Baca dengan perlahan dan didapatkan bahwa part yang digunakan adalah XC7A100T-1CSG324C.

2. Berdasarkan Board
Ada cara yang lebih mudah, yaitu berdasarkan board. Klik board (Nomer 2 pada Gambar di atas). Kemudian ketik nama board yang kita gunakan. Jika tidak muncul, maka kita harus unduh referensi alatnya terlebih dahulu secara online (masih ada proses selanjutnya).

Jika sudah, maka klik NEXT. Kemudian muncul jendela New Project Summary. Baca dahulu secara perlahan rangkuman yang diberikan. Jika sudah yakin benar, maka klik FINISH. Tunggu sampai Vivado melakukan inisialisasi. Jika sudah selesai, maka akan muncul Jendela kerja kita.

Membuat File pada Vivado

Pada jendela kerja Vivado, klik File --> Add Sources. Alternatifnya, bisa buka melalui jendela PROJECT MANAGER --> Add Sources. Maka, akan muncul seperti gambar di bawah ini.

Nah, sekarang kita akan buat dulu file kodingan kita. Maka kita pilih Add or Create design sources. Kemudian klik NEXT, dan akan muncul jendela di bawah ini:

Pilih Create File, dan akan muncul jendela berikut:

Nah, pada jendela ini, kita akan menentukan tipe dan nama file kita. Saat ini saya menggunakan bahasa Verilog. Jika kalian menggunakan VHDL atau System Verilog, silahkan pilih opsi yang sesuai. Saya beri nama adder sebagai nama file saya. Kemudian klik OK. Selanjutnya klik NEXT. Maka, akan muncul jendela berikut:

Kita diminta untuk mendefinisikan Input-Ouput dari port yang akan kita gunakan. Sementara kita biarkan saja dulu dengan mengklik OK. Nanti akan ada warning. Kalian cukup abaikan saja dengan klik YES. Setelah selesai, kita klik Finish, dan akan kembali menuju jendela kerja kita.

Memprogram File Vivado

Sampai saat ini, kita sudah membuat file dan siap untuk dikoding. Amati dibagian Sources, dan expand Design Sources. Akan terlihat file adder.v, seperti pada gambar berikut:

Klik dua kali adder,v, maka akan muncul jendela editor. Kita akan memprogram half-adder pada FPGA. Rangkaian gerbang logika untuk half-adder beserta tabel kebenarannya diperlihatkan seperti pada gambar dibawah ini.

absumc_out
0000
0110
1010
1101

Mari kita koding mulai dari sintaks module adder ( dst... . Mari kita buat programnya dalam bahasa Verilog, yaitu sebagai berikut:

module adder(input a, b,
             output sum, c_out);
    xor g1(sum, a, b);
    and g2(c_out, a, b);
endmodule

Ingat, Verilog adalah case-sensitive. Jadi pastikan penggunaan huruf kecil dan huruf kapital yang konsisten. Jika sudah selesai mengetik program tersebut di atas, maka simpan file kita baik dengan mengklik lambang Save File atau dengan menekan tombol Ctrl+S.

Sintesis Program

Setelah koding kita simpan, mari kita lakukan sintesis. Sintesis adalah proses menterjemahkan HDL (Hardware Description Language) , baik dalam bahasa VHDL atau Verilog ke bentuk level-gate netlist. Setelah sintesis dijalankan, kita akan mendapatkan report apa saja resource yang telah kita pakai, misal berapa cell, berapa I/O Port dan berapa net yang kita pakai. Nah, coba kita langsung lakukan sintesis saat ini. Di bagian Jendela Flow Navigator, pilih bagian SYNTHESIS, kemudian klik Run Synthesis kemudian klik OK. Proses ini diperlihatkan seperti pada gambar berikut:

Tunggulah prosesnya sampai selesai. Proses ini dapat tergantung dari kompleks tidaknya desain yang kita buat. Setelah selesai, kita akan diberikan pilihan. Apakah akan melanjutkan ke proses implementasi atau tidak. Sementara kita klik Cancel, seperti gambar berikut:

Kemudian expand Open Synthesized Design, dan klik Schematic. Amatilah skematik yang terbentuk dari proses sintesis tadi. Diperoleh bahwa desain kita menghabiskan 6 Cells, 4 I/O ports, dan 8 nets.

Melakukan Simulasi

Proses ini sifatnya opsional. Namun, akan sangat berguna jika kalian tidak memiliki board FGPA secara fisik atau ingin meyakinkan dulu logika yang kita bangun telah sesuai. Untuk melakukan simulasi, kita harus membuat file yang dikenal sebagai testbench. Mari kita buat tesbench-nya terlebih dahulu.

Sama seperti membuat file baru sebelumnya, kita akan lakukan langkah yang sama juga untuk proses simulasi, hanya berbeda di jenis file-nya saja. Pilih File --> Add Sources. Nah, sekarang kita pilih Add or Create simulation sources.

Selanjutnya pilih Create File, dan beri nama file kta dengan adder_tb. Pastikan tipe file Verilog. Kemudian klik OK. Amati Gambar berikut ini.

Kemudian pilih Finish. Kemudian akan muncul lagi jendela Define Module. Sementara kita tidak menambahkan apa-apa. Cukup klik OK, dan warning kita abaikan saja dengan klik YES. Selanjutnya akan muncul file untuk Simulation Sources, dengan nama adder_tb.v. Klik 2 kali file adder_tb.v tersebut, dan akan muncul jendela editor, seperti pada gambar berikut:

Pada bagian editor, ketiklah file testbench berikut:

module adder_tb();
reg a, b;
wire sum, c_out;

adder dut(.a(a), .b(b), .sum(sum), .c_out(c_out));

initial
    begin
        a = 1'b0;
        b = 1'b0;
        #50;
        a = 1'b0;
        b = 1'b1;
        #50;
        a = 1'b1;
        b = 1'b0;
        #50;
        a = 1'b1;
        b = 1'b1;
    end
endmodule

Kemudian pada jendela Flow Navigator, pilih SIMULATION, kemudia pilih Run Simulation, seperti gambar di bawah ini.

Kemudian akan muncul jendela hasil simulasi. Zoom agar bentuk gelombang input dan output dapat terlihat dengan baik, kemudian bandingkan hasilnya dengan Tabel Kebenaran untuk half-adder di atas. Sudah sesuai bukan?

Menambahkan Constraints

Sampai saat ini kita sudah membuat file desain kita dalam bahasa Verilog (kalian bisa gunakan bahasa VHDL atau SystemVerilog). Kita juga sudah melakukan simulasi. Saat ini, kita yakin bahwa koding HDL kita untuk half-adder kita telah benar.

Nah, langkah selanjutnya adalah memprogram file tersebut ke FPGA. Namun demikian masih ada hal yang harus dikerjakan. Kita harus memetakan bagian mana dari FPGA kita yang akan menghandle input/output tersebut. Nah, kita akan membuat file constraint-nya. Asumsi saat ini saya akan menggunakan input berupa dua buat Switch untuk mewakili input a dan b, serta dua buah LED untuk mewakili input sum dan c_out.

Langkahnya sama seperti membuat file utama dan simulasi sebelumnya. Kita buka File --> Add Sources, kemudian kali ini pilih Add or Create Constraints. Klik NEXT, pilih Create File. Isilah nama file kita, misalnya adder_constraint. seperti gambar dibawah ini. Kemudian akhiri dengan FINISH.

Selanjutnya, mari kita cek lagi file yang sudah kita buat di bagian jendela Sources. Pada bagian Constraints klik 2 kali adder_tb.xdc, maka akan muncul editor untuk file constraint kita. Salin koding berikut, kemudian tempel pada editor adder.constraint.xdc kita.

## This file is a general .xdc for the Basys3 rev B board
## To use it in a project:
## - uncomment the lines corresponding to used pins
## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project

## Clock signal
#set_property PACKAGE_PIN W5 [get_ports clk]                            
    #set_property IOSTANDARD LVCMOS33 [get_ports clk]
    #create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk]
 
## Switches
#set_property PACKAGE_PIN V17 [get_ports {sw[0]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[0]}]
#set_property PACKAGE_PIN V16 [get_ports {sw[1]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[1]}]
#set_property PACKAGE_PIN W16 [get_ports {sw[2]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[2]}]
#set_property PACKAGE_PIN W17 [get_ports {sw[3]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[3]}]
#set_property PACKAGE_PIN W15 [get_ports {sw[4]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[4]}]
#set_property PACKAGE_PIN V15 [get_ports {sw[5]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[5]}]
#set_property PACKAGE_PIN W14 [get_ports {sw[6]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[6]}]
#set_property PACKAGE_PIN W13 [get_ports {sw[7]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[7]}]
#set_property PACKAGE_PIN V2 [get_ports {sw[8]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[8]}]
#set_property PACKAGE_PIN T3 [get_ports {sw[9]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[9]}]
#set_property PACKAGE_PIN T2 [get_ports {sw[10]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[10]}]
#set_property PACKAGE_PIN R3 [get_ports {sw[11]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[11]}]
#set_property PACKAGE_PIN W2 [get_ports {sw[12]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[12]}]
#set_property PACKAGE_PIN U1 [get_ports {sw[13]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[13]}]
#set_property PACKAGE_PIN T1 [get_ports {sw[14]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[14]}]
#set_property PACKAGE_PIN R2 [get_ports {sw[15]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {sw[15]}]
 

## LEDs
#set_property PACKAGE_PIN U16 [get_ports {led[0]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
#set_property PACKAGE_PIN E19 [get_ports {led[1]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
#set_property PACKAGE_PIN U19 [get_ports {led[2]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
#set_property PACKAGE_PIN V19 [get_ports {led[3]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
#set_property PACKAGE_PIN W18 [get_ports {led[4]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[4]}]
#set_property PACKAGE_PIN U15 [get_ports {led[5]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[5]}]
#set_property PACKAGE_PIN U14 [get_ports {led[6]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[6]}]
#set_property PACKAGE_PIN V14 [get_ports {led[7]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[7]}]
#set_property PACKAGE_PIN V13 [get_ports {led[8]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[8]}]
#set_property PACKAGE_PIN V3 [get_ports {led[9]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[9]}]
#set_property PACKAGE_PIN W3 [get_ports {led[10]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[10]}]
#set_property PACKAGE_PIN U3 [get_ports {led[11]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[11]}]
#set_property PACKAGE_PIN P3 [get_ports {led[12]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[12]}]
#set_property PACKAGE_PIN N3 [get_ports {led[13]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[13]}]
#set_property PACKAGE_PIN P1 [get_ports {led[14]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[14]}]
#set_property PACKAGE_PIN L1 [get_ports {led[15]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {led[15]}]
    
    
##7 segment display
#set_property PACKAGE_PIN W7 [get_ports {seg[0]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {seg[0]}]
#set_property PACKAGE_PIN W6 [get_ports {seg[1]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {seg[1]}]
#set_property PACKAGE_PIN U8 [get_ports {seg[2]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {seg[2]}]
#set_property PACKAGE_PIN V8 [get_ports {seg[3]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {seg[3]}]
#set_property PACKAGE_PIN U5 [get_ports {seg[4]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {seg[4]}]
#set_property PACKAGE_PIN V5 [get_ports {seg[5]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {seg[5]}]
#set_property PACKAGE_PIN U7 [get_ports {seg[6]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {seg[6]}]

#set_property PACKAGE_PIN V7 [get_ports dp]                            
    #set_property IOSTANDARD LVCMOS33 [get_ports dp]

#set_property PACKAGE_PIN U2 [get_ports {an[0]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {an[0]}]
#set_property PACKAGE_PIN U4 [get_ports {an[1]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {an[1]}]
#set_property PACKAGE_PIN V4 [get_ports {an[2]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {an[2]}]
#set_property PACKAGE_PIN W4 [get_ports {an[3]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {an[3]}]


##Buttons
#set_property PACKAGE_PIN U18 [get_ports btnC]                        
    #set_property IOSTANDARD LVCMOS33 [get_ports btnC]
#set_property PACKAGE_PIN T18 [get_ports btnU]                        
    #set_property IOSTANDARD LVCMOS33 [get_ports btnU]
#set_property PACKAGE_PIN W19 [get_ports btnL]                        
    #set_property IOSTANDARD LVCMOS33 [get_ports btnL]
#set_property PACKAGE_PIN T17 [get_ports btnR]                        
    #set_property IOSTANDARD LVCMOS33 [get_ports btnR]
#set_property PACKAGE_PIN U17 [get_ports btnD]                        
    #set_property IOSTANDARD LVCMOS33 [get_ports btnD]
 


##Pmod Header JA
##Sch name = JA1
#set_property PACKAGE_PIN J1 [get_ports {JA[0]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JA[0]}]
##Sch name = JA2
#set_property PACKAGE_PIN L2 [get_ports {JA[1]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JA[1]}]
##Sch name = JA3
#set_property PACKAGE_PIN J2 [get_ports {JA[2]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JA[2]}]
##Sch name = JA4
#set_property PACKAGE_PIN G2 [get_ports {JA[3]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JA[3]}]
##Sch name = JA7
#set_property PACKAGE_PIN H1 [get_ports {JA[4]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JA[4]}]
##Sch name = JA8
#set_property PACKAGE_PIN K2 [get_ports {JA[5]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JA[5]}]
##Sch name = JA9
#set_property PACKAGE_PIN H2 [get_ports {JA[6]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JA[6]}]
##Sch name = JA10
#set_property PACKAGE_PIN G3 [get_ports {JA[7]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JA[7]}]



##Pmod Header JB
##Sch name = JB1
#set_property PACKAGE_PIN A14 [get_ports {JB[0]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JB[0]}]
##Sch name = JB2
#set_property PACKAGE_PIN A16 [get_ports {JB[1]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JB[1]}]
##Sch name = JB3
#set_property PACKAGE_PIN B15 [get_ports {JB[2]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JB[2]}]
##Sch name = JB4
#set_property PACKAGE_PIN B16 [get_ports {JB[3]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JB[3]}]
##Sch name = JB7
#set_property PACKAGE_PIN A15 [get_ports {JB[4]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JB[4]}]
##Sch name = JB8
#set_property PACKAGE_PIN A17 [get_ports {JB[5]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JB[5]}]
##Sch name = JB9
#set_property PACKAGE_PIN C15 [get_ports {JB[6]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JB[6]}]
##Sch name = JB10 
#set_property PACKAGE_PIN C16 [get_ports {JB[7]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JB[7]}]
 


##Pmod Header JC
##Sch name = JC1
#set_property PACKAGE_PIN K17 [get_ports {JC[0]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JC[0]}]
##Sch name = JC2
#set_property PACKAGE_PIN M18 [get_ports {JC[1]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JC[1]}]
##Sch name = JC3
#set_property PACKAGE_PIN N17 [get_ports {JC[2]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JC[2]}]
##Sch name = JC4
#set_property PACKAGE_PIN P18 [get_ports {JC[3]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JC[3]}]
##Sch name = JC7
#set_property PACKAGE_PIN L17 [get_ports {JC[4]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JC[4]}]
##Sch name = JC8
#set_property PACKAGE_PIN M19 [get_ports {JC[5]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JC[5]}]
##Sch name = JC9
#set_property PACKAGE_PIN P17 [get_ports {JC[6]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JC[6]}]
##Sch name = JC10
#set_property PACKAGE_PIN R18 [get_ports {JC[7]}]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports {JC[7]}]


##Pmod Header JXADC
##Sch name = XA1_P
#set_property PACKAGE_PIN J3 [get_ports {JXADC[0]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {JXADC[0]}]
##Sch name = XA2_P
#set_property PACKAGE_PIN L3 [get_ports {JXADC[1]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {JXADC[1]}]
##Sch name = XA3_P
#set_property PACKAGE_PIN M2 [get_ports {JXADC[2]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {JXADC[2]}]
##Sch name = XA4_P
#set_property PACKAGE_PIN N2 [get_ports {JXADC[3]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {JXADC[3]}]
##Sch name = XA1_N
#set_property PACKAGE_PIN K3 [get_ports {JXADC[4]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {JXADC[4]}]
##Sch name = XA2_N
#set_property PACKAGE_PIN M3 [get_ports {JXADC[5]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {JXADC[5]}]
##Sch name = XA3_N
#set_property PACKAGE_PIN M1 [get_ports {JXADC[6]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {JXADC[6]}]
##Sch name = XA4_N
#set_property PACKAGE_PIN N1 [get_ports {JXADC[7]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {JXADC[7]}]



##VGA Connector
#set_property PACKAGE_PIN G19 [get_ports {vgaRed[0]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {vgaRed[0]}]
#set_property PACKAGE_PIN H19 [get_ports {vgaRed[1]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {vgaRed[1]}]
#set_property PACKAGE_PIN J19 [get_ports {vgaRed[2]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {vgaRed[2]}]
#set_property PACKAGE_PIN N19 [get_ports {vgaRed[3]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {vgaRed[3]}]
#set_property PACKAGE_PIN N18 [get_ports {vgaBlue[0]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {vgaBlue[0]}]
#set_property PACKAGE_PIN L18 [get_ports {vgaBlue[1]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {vgaBlue[1]}]
#set_property PACKAGE_PIN K18 [get_ports {vgaBlue[2]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {vgaBlue[2]}]
#set_property PACKAGE_PIN J18 [get_ports {vgaBlue[3]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {vgaBlue[3]}]
#set_property PACKAGE_PIN J17 [get_ports {vgaGreen[0]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {vgaGreen[0]}]
#set_property PACKAGE_PIN H17 [get_ports {vgaGreen[1]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {vgaGreen[1]}]
#set_property PACKAGE_PIN G17 [get_ports {vgaGreen[2]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {vgaGreen[2]}]
#set_property PACKAGE_PIN D17 [get_ports {vgaGreen[3]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {vgaGreen[3]}]
#set_property PACKAGE_PIN P19 [get_ports Hsync]                        
    #set_property IOSTANDARD LVCMOS33 [get_ports Hsync]
#set_property PACKAGE_PIN R19 [get_ports Vsync]                        
    #set_property IOSTANDARD LVCMOS33 [get_ports Vsync]


##USB-RS232 Interface
#set_property PACKAGE_PIN B18 [get_ports RsRx]                        
    #set_property IOSTANDARD LVCMOS33 [get_ports RsRx]
#set_property PACKAGE_PIN A18 [get_ports RsTx]                        
    #set_property IOSTANDARD LVCMOS33 [get_ports RsTx]


##USB HID (PS/2)
#set_property PACKAGE_PIN C17 [get_ports PS2Clk]                        
    #set_property IOSTANDARD LVCMOS33 [get_ports PS2Clk]
    #set_property PULLUP true [get_ports PS2Clk]
#set_property PACKAGE_PIN B17 [get_ports PS2Data]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports PS2Data]    
    #set_property PULLUP true [get_ports PS2Data]


##Quad SPI Flash
##Note that CCLK_0 cannot be placed in 7 series devices. You can access it using the
##STARTUPE2 primitive.
#set_property PACKAGE_PIN D18 [get_ports {QspiDB[0]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {QspiDB[0]}]
#set_property PACKAGE_PIN D19 [get_ports {QspiDB[1]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {QspiDB[1]}]
#set_property PACKAGE_PIN G18 [get_ports {QspiDB[2]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {QspiDB[2]}]
#set_property PACKAGE_PIN F18 [get_ports {QspiDB[3]}]                
    #set_property IOSTANDARD LVCMOS33 [get_ports {QspiDB[3]}]
#set_property PACKAGE_PIN K19 [get_ports QspiCSn]                    
    #set_property IOSTANDARD LVCMOS33 [get_ports QspiCSn]

Ingat, saya menggunakan Basys 3 sebagai board FPGA. Kalian harus sesuaikan dengan jenis board kalian. File constraint ini SPESIFIK dengan board tertentu. Kalau kalian memiliki board yang berbeda, cukup di Googling saja dengan kata kunci "nama board constraint". Misal, saya ingin mencari file xdc untuk board nesys 4, maka saya cukup ketikkan "nexys 4 constraint".

Alternatif lain membuat file constraint adalah dengan menambahkan file dari luar. Silahkan ekstrak file basys3_constraint.zip yang saya sertakan di bagian bawah dari tutorial ini (atau cari di internet untuk jenis board yang lain) . Sama prosedurnya dengan sebelumnya. Pilih File --> Add Sources. Pilih Add or create constraints kemudian pilih Add Files. Carilah dimana kalian mengekstrak file basys3_constraint.zip tadi.

Edit Constraints

Nah, sampai saat ini kalian sudah memiliki file constraint. Namun, semua masih di-comment-kan (belum diaktifkan). Kita harus uncoment-kan bagian-bagian yang ingin kita pakai (tidak perlu memakai semua fasilitas dari board tersebut).

Amati kembali rangkaian gerbang logika untuk half-adder di atas. Misal, pada board Basys 3 saya akan gunakan sw0 untuk input a, sw1 untuk input b, led LD0 untuk sum dan LD1 untuk c_out, maka saya aktifkan bagian tersebut saja, yaitu dengan menghilangkan tanda pagar (#). Jangan lupa untuk mengubah nama port default-nya dengan nama port yang kita gunakan dalam pemrograman, yaitu sw[0] diedit menjadi a, sw[1] menjadi b, led[0] menjadi sum, dan led[1] menjadi c_out.

Amati bagian berikut (sisa baris yang lain tidak diperlihatkan):

## Switches
#set_property PACKAGE_PIN V17 [get_ports {sw[0]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {sw[0]}]
#set_property PACKAGE_PIN V16 [get_ports {sw[1]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {sw[1]}]

## LEDs
#set_property PACKAGE_PIN U16 [get_ports {led[0]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
#set_property PACKAGE_PIN E19 [get_ports {led[1]}]
#set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]

KITA UBAH MENJADI:

## Switches
set_property PACKAGE_PIN V17 [get_ports {a}]
set_property IOSTANDARD LVCMOS33 [get_ports {a}]
set_property PACKAGE_PIN V16 [get_ports {b}]
set_property IOSTANDARD LVCMOS33 [get_ports {b}]

## LEDs
set_property PACKAGE_PIN U16 [get_ports {sum}]
set_property IOSTANDARD LVCMOS33 [get_ports {sum}]
set_property PACKAGE_PIN E19 [get_ports {c_out}]
set_property IOSTANDARD LVCMOS33 [get_ports {c_out}]

Setelah selesai, kita simpan dengan klik logo simpan, atau tekan tombol Ctrl + S.

Sampai saat ini kita sudah melakukan banyak perubahan. Oleh karena itu, kita akan melakukan Sintesis ulang. Klik kembali RUN SYNTHESIS seperti langkah sebelumnya. Tunggu beberapa saat sampai muncul jendela berikut.

Melakukan Implementasi

Nah, ketika sudah muncul jendela di atas, kita sekarang pilih Run Implementation, kemudian klik OK. Tunggu sampai proses selesai. Implementasi adalah proses mengambil netlist, melakukan optimasi, penempatan dan routing.

Ketika proses implementasi selesai, kita bisa buka hasil implementasi kita. Akan muncul jendela ketika sudah selesai implementasi. Pada jendela tersebut, pilih Open Implemented Design, kemudian pilih OK. Hasil implementasi bisa di-zoom dan terlihat bagaian mana dari FPGA tersebut yang akan digunakan.

Program dan Debug

Nah, sekarang pastikan board FPGA kita terkoneksi dengan komputer kita. Hubungkan dengan kabel USB, dan hidupkan Power-nya.

Agar bisa diprogram, sekarang kita akan membuat bitstream. Bitstream ini yang selanjutnya akan diunggah ke FPGA kita. Pada jendela Flow Navigator, pilih PROGRAM AND DEBUG. Kemudian pilih Generate Bitstream.

Tunggu beberapa saat. Setelah selesai, maka akan muncul jendela seperti di bawah ini. Pastikan TIDAK ADA yang error. Jika ada error, silahkan review lagi tahapan sebelumnya.

Jika sudah selesai proses generate bitstream, maka pilihlah Open Hardware Manager. Kemudian di bagian atas dari jendela HARDWARE MANAGER, pilih Open Target, kemudian Auto Connect. Amati gambar berikut.

etelah selesai, Pilih Program Device, kemudian pilih Program. Tunggulah sampai proses mengunggah bitstream selesai.

Upload dan Mainkan

Tunggu proses upload selesai. Kemudian cari SW0 dan SW1. Mainkan sesuai dengan tabel kebenaran, dan lihat hasilnya melalui LED. Yeeeeee...... selamat! kalian sudah berhasil mengkoding FPGA!

Demikain tutorial yang mungkin (sangat) melelahkan ini. Semoga bermanfaat Smile

103
Image

Kusuma Wardana

I Nyoman Kusuma Wardana, yang akrab dipanggil Kusuma, lahir dan besar di Bali. Ia tinggal di Desa Wisata Ubud, dan lebih banyak melaksanakan aktivitasnya di Denpasar. Profesinya adalah sebagai staf pengajar di Jurusan Teknik Elektro, Politeknik Negeri Bali. Saat ini Ia menjadi salah satu penulis di tutorkeren.com.

Mari Gabung

Halo Emo 51 , Ada yang ingin disampaikan? Jangan sungkan untuk gabung diskusi ini. Silahkan Login dulu atau Daftar baru.