
Saat men-debug program reguler, breakpoints dapat diatur hampir di mana-mana dan dalam jumlah yang cukup besar. Sayang Ketika suatu program dieksekusi pada controller, aturan ini tidak berlaku. Jika ada bagian di mana diagram waktu terbentuk, maka berhenti akan merusak segalanya. Dan bagian pada frekuensi rendah dan tinggi bukanlah hal yang sama. Kondisi batas adalah momok bagi pengembang. Atau, katakanlah, bus USB. Di NIOS II, saya tidak bekerja dengannya, tetapi pada STM32 itu mengerikan. Dan saya ingin melihat sesuatu, dan ketika Anda berhenti, Anda menangkap batas waktu. Secara umum, sangat sering, meskipun ada debugging JTAG tingkat lanjut, perilaku program di area kritis waktu dikaburkan. Akan bagus untuk melihat, setidaknya setelah eksekusi, rantai apa yang dilalui program, cabang mana yang bekerja, dan mana yang tidak!
Lebih penting untuk mengetahui sejarah pengecualian. Pada NIOS II, saya tidak melakukan ini, tetapi pada Cyclone V SoC di inti ARM - sepenuhnya. Saat debugging, semuanya berfungsi, dan jika Anda memulai program dari ROM, Anda mendapatkan pengecualian. Jelas bagaimana mereka memasukinya, dan perkembangan seperti apa yang menyebabkan hal ini tidak terjadi. Menelusuri juga merusak semua penutup.
Artikel sebelumnya dalam seri:
- Pengembangan "firmware" paling sederhana untuk FPGA yang dipasang di Redd, dan debugging menggunakan tes memori sebagai contoh
- Pengembangan "firmware" paling sederhana untuk FPGA yang dipasang di Redd. Bagian 2. Kode program
- Pengembangan intinya sendiri untuk ditanamkan dalam sistem prosesor berbasis FPGA
- Pengembangan program untuk prosesor pusat Redd pada contoh akses ke FPGA
- Eksperimen pertama menggunakan protokol streaming pada contoh CPU dan komunikasi prosesor di Redd FPGA
Pendahuluan
Merupakan kebiasaan untuk menulis artikel pendidikan dengan wajah serius, mengedepankan materi dengan tenang dan tidak memihak. Namun sayang, ini tidak selalu berhasil. Sekarang, sesuai dengan rencana, harus ada artikel tentang optimalisasi prosesor yang disintesis di kompleks Redd, di mana kita perlu berbicara tentang fitur-fitur bekerja dengan cache. Berikutnya adalah artikel tentang keterlambatan saat mengakses bus. Secara umum, semua ini dapat ditampilkan pada osiloskop. Saya sudah melakukan ini dalam sebuah artikel tentang DMA ("
DMA: Myths and Reality "). Tapi saya ingin menunjukkan semuanya menggunakan prosesor itu sendiri, saya melakukan pemeriksaan untuk inti ARM di FPGA Cyclone V SoC. Sangat nyaman (meskipun hasilnya tidak dipublikasikan). Untuk alasan ini, saya memutuskan untuk berurusan dengan mekanisme penelusuran yang melekat pada blok JTAG. Sangat disayangkan bahwa sejauh ini saya belum dapat menampilkan dengan sumber daya yang dapat diunduh gratis berapa banyak ketukan yang dimainkan perintah ini, tetapi ada materi yang dengannya program selalu dapat ditanya bagaimana itu bisa sampai pada kehidupan seperti itu. Yah, dan di samping itu, sementara ingatan akan badai malam masih segar di ingatanku, aku akan membuangnya dengan cara yang agak emosional. Jadi hari ini akan ada banyak memoar dan sedikit teori yang berguna.
Perangkat keras
Jadi, sangat sering ketika men-debug suatu program untuk mikrokontroler, diinginkan untuk mengetahui jalur yang telah dilalui, dan ia harus melewatinya dengan kecepatan penuh. Untuk kasus NIOS II, mekanisme ini tersedia dan disertakan di sini pada tab ini dari properti inti prosesor:

Jenis Jejak mengatur jenis informasi yang akan disimpan. Anda tidak dapat menyimpan apa pun (ini akan menghemat memori chip), Anda hanya dapat menyimpan riwayat perintah (paling sering ini sudah cukup), baik, atau menyimpan riwayat baik perintah maupun data. Perlu dicatat bahwa dokumentasi mengatakan bahwa dalam mode terakhir, menyimpan informasi entah bagaimana sulit, sementara overlay dengan riwayat perintah dimungkinkan, dan lebih banyak memori dikonsumsi. Jadi gunakan mode ini hanya ketika itu benar-benar diperlukan.
Parameter Trace Storage menetapkan jenis memori yang akan disimpan jejaknya. Dokumentasi mengatakan bahwa memori eksternal tidak didukung oleh lingkungan pengembangan standar. Karena itu, lebih baik memilih bagian dalam saja.

Nah, Onchip Trace Frame Size menentukan ukuran buffer. Semakin besar penyangga, semakin banyak peristiwa dapat ditempatkan di dalamnya, semakin besar sejarah dapat dipertimbangkan. Tetapi semakin sedikit akan menjadi memori kristal untuk kebutuhan lain.

Tidak perlu mengaktifkan kotak centang membuat port JTAG terpisah. Biarkan semuanya taksi secara teratur.
Dukungan perangkat lunak
Bagus Jadi kami mengatur inti prosesor, bagaimana selanjutnya? Ohhhh! Kemudian kisah detektif dimulai. Jika angka-angka di atas harus ditafsirkan sebagai panduan untuk bertindak, maka ilustrasi yang menunjukkan kekacauan dan penyumbatan akan mengikuti. Sejumlah dokumen mengatakan bahwa untuk bekerja dengan pelacakan, Anda harus menggunakan program mahal pihak ketiga dan bahkan peralatan JTAG khusus. Tetapi dalam beberapa dokumen tergelincir bahwa Anda dapat mengambil sesuatu penuh waktu.
Eksperimen Gerhana
Bagus Mari kita melihat-lihat Eclipse. Saya mengingatkan Anda bahwa saya menggunakan lingkungan pengembangan Quartus Prime 17.1. Yah, itu terjadi. Kami memulai program untuk debugging dan pergi ke item menu yang memungkinkan Anda untuk membuka berbagai jendela:

Di sana kami memilih Debug-> Trace Control window:

Dan kita mendapatkan boneka seperti itu:

Tetapi sesi debug dimulai. Selain itu, item menu Mulai Tracing dan Stop Tracing bahkan muncul di dalamnya (sebelum membuka jendela ini, mereka tidak). Tetapi mereka diblokir. Dan saya tidak bisa mengaktifkannya.

Sia-sia saya mengisi Google dengan berbagai permintaan. Dalam dokumen-dokumen lama, barang-barang ini digambarkan berfungsi dengan baik, tetapi dalam dokumen modern tidak disebutkan. Tidak ada yang menyebut mereka di forum. Mungkin seseorang di komentar akan memberi tahu Anda sesuatu?
Masalah dengan versi terbaru Eclipse
Bagus Bagaimana dengan versi terbaru dari lingkungan pengembangan? Mungkin semuanya bekerja di sana? Yyyyyy! Ini adalah topik untuk bab terpisah. Versi terbaru untuk Siklon keempat dan kelima adalah 18.1.1. Artinya, Anda harus mengunduh versi 18.1 terlebih dahulu, dan kemudian menginstal pembaruan 18.1.1. Jika seseorang memutuskan bahwa saya memiliki terlalu banyak waktu luang, bahwa saya mengatur ulang perangkat lunak demi setiap hal kecil, maka semuanya baik-baik saja. Pemeriksaan utama adalah tentang masalah cache. Mereka lebih serius, saya ingin memeriksanya di versi baru, saya hanya tidak menulis tentang mereka di sini.
Jadi, saya mengunduhnya. Diinstal Pertama, versi 18.1 di bawah Win7 diluncurkan, tetapi 18.1.1 tidak menemukan DLL. Bagus Saya mengetahui bahwa saya perlu mengunduh Redist dari Visual Studio 2015. Saya menginstalnya. Itu mulai berjalan. Membuat proyek dengan sistem prosesor. Dia bahkan bersiap-siap. Saya akan ke Eclipse, membuat program dengan BSP berdasarkan itu, semuanya, seperti yang telah kami lakukan berkali-kali ... Dan saya mendapatkan hal semacam ini ...

Proyek ini tidak akan. Jika Anda keluar dan masuk, itu hanya terbuka sebagian.

Lihat folder ditutup? Itu dia. Mengapa Ohhhh! Tiga file memiliki:

Ini adalah atribut perlindungan yang luar biasa:

Jadi mereka tidak dapat dibuka atau diubah ... Jika Anda memberi lebih banyak hak, proyek akan terbuka, tetapi file tidak sepenuhnya dibuat, sehingga tidak akan berfungsi untuk mengumpulkannya. Mencoba memberi hak sampai Eclipse ditutup, dan kemudian menyimpan proyek. Hasilnya sama.
Mungkinkah Windows 7 yang cepat menua menjadi penyebabnya? Tidak heran saya kekurangan perpustakaan! Saya menaruh Quartus baru pada WIN10, saya mendapatkan hasil yang sama persis dengan membuat proyek! Saya punya teman. Berdasarkan tempat kerjanya, ia terkadang menemukan produk-produk dari produsen dalam negeri. Dan dia mengungkapkan serangkaian pemikiran tentang diri mereka sendiri dan tentang kerabat mereka. Nah, tentang fakta bahwa "siapa yang membangun ini?" Anda tahu, melihat kegembiraan dalam perangkat lunak Intel, saya mulai berpikir bahwa itu jauh dari negara asal ... Sebenarnya, ini tidak terjadi di bawah Alter ... Apa pun telah terjadi, tetapi saya tidak ingat itu.
Saya baru saja keluar. Saya menyalin proyek ke USB flash drive dengan sistem file FAT32. Tidak ada atribut keamanan. Saya membuka proyek dari sana, masuk ke Eclipse dan membuat kode. Tidak ada atribut keamanan - tidak ada masalah. Lalu saya menyalinnya kembali ke hard drive dan ... Yah, tentu saja, saya mendapat masalah dalam menghasilkan BSP. Karena file * .bsp berisi banyak path relatif dan satu absolut. Ada baiknya saya mengeluarkan flash drive. Kalau tidak, saya tidak akan memperhatikan bahwa BSP turun di atasnya (karena ini adalah tempat kelahiran proyek), dan proyek dikumpulkan pada hard drive. Berikut adalah contoh dari jalur seperti itu (sudah diperbaiki):

Baiklah, baiklah ... Semuanya dihasilkan, dirakit ... Dan berfungsi persis sama seperti pada versi 17.1 ... Dan untuk pengontrol SoC di lingkungan baru, Anda juga harus membuat ulang rantai JTAG setiap kali di pemrogram. Dalam versi 17.1, itu sudah cukup untuk melakukan ini sekali dan menyelamatkan ... Eeeeeh. Baiklah oh baiklah ...
Altera Monitor dan masalahnya
Dengan satu atau lain cara, pencarian jaringan untuk kata Mulai Tracing dan Stop Tracing menuntun saya ke dokumen yang menarik. Mereka menggambarkan berbagai versi program lucu yang disebut
Altera Monitor hari ini (namanya berbeda dalam dokumen lama). Menemukannya relatif mudah. Anda perlu mengunduh paket
Program Universitas untuk versi lingkungan pengembangan Anda. Perhatikan batasan lisensi. Tetapi karena kita belajar sekarang, kita tidak takut akan itu. Tetapi untuk pekerjaan komersial - semuanya buruk di sana. Detail di sini:
www.intel.com/content/www/id/id/programmable/support/training/university/materials-software.htmlUnduh, masukkan ... Ada dokumen yang dilampirkan ke versi saat ini (karena versi yang tersebar di Internet sangat bervariasi). Saya bahkan mencoba menjalankan contoh untuk papan tempat memotong roti DE0-Nano-SoC saya. Dia sedang bekerja. Tetapi ketika saya mencoba membuat proyek saya, itu tidak berhasil. File * .sof dimuat ke dalam FPGA, setelah itu, setelah beberapa saat, sebuah pesan ditampilkan:

Hanya tidak ada informasi di jendela yang ditentukan. Jika Anda mencoba mengunduh lagi: well, teks akan muncul tepat di jendela itu:
Tidak dapat meminta ID Instansi JTAG.
Harap pastikan FPGA telah dikonfigurasi menggunakan file .sof yang benar.Masalah apa ini? Saya mencari di Google. Menemukan beberapa forum dengan masalah yang sama. Pada satu kesempatan, seorang karyawan Intel menanyakan frekuensi penulis di JTAG dan menyarankan untuk menetapkan yang standar. Meskipun, pada saat itu saya sudah mengerti bahwa itu bukan masalah frekuensi: contoh perusahaan berhasil, dan bagaimana mengaturnya? Di satu forum, penulis menulis bahwa entah bagaimana itu telah berlalu. Dia tidak mengerti caranya. Dan dia mengatakan bahwa jika Anda melakukan semuanya dengan hati-hati sesuai instruksi, semuanya akan berhasil. Sisa gambar itu sama. Pria itu bertanya. Mereka tidak menjawabnya. Setelah enam bulan atau satu tahun, seseorang menulis bahwa ia memiliki situasi yang sama, adakah solusi? Dan diam aaaaaaaa ...
Upaya solusi berpengalaman
Bagus Apa yang bisa menjadi alasannya? Pada awalnya saya memutuskan untuk melihat-lihat dalam contoh kerja. ID JTAG misterius apa? Mungkinkah ini disebabkan oleh keberadaan sistem ID Sistem yang berfungsi?

Ditambahkan pada dirinya sendiri, tidak membantu. Mungkin JTAG ke jembatan Avalon, yang semua perangkat periferal terhubung, yang harus disalahkan?

Ditambahkan - tidak membantu. Saya mencoba beberapa hipotesis lagi, tetapi saya menyadari bahwa Anda dapat menebak selamanya. Dengan sedih, saya bahkan bertanya pada Yandex, Bing, dan bahkan BaiDu. Mereka semua tahu kurang dari Google. Menjadi jelas bahwa kami harus berurusan dengan dekompilasi untuk mengekstrak dari program itu sendiri apa yang diperlukan. Diperiksa dalam bahasa apa program ditulis. Ternyata di Jawa. Bytecode disimpan dalam file Altera_Monitor_Program.jar. Yah, ini aneh. Kecuali fakta bahwa saya tidak tahu Jawa ini sama sekali. Pada Java Script, ada sebuah kasus, mencoba-coba Internet of Things, tetapi saya tidak menemukan Jawa yang sebenarnya. Tapi di mana milik kita tidak hilang!
Analisis bytecode JAVA untuk menemukan masalah
Bagaimana cara membuka kode byte? Google menghasilkan sebuah artikel tentang Habré, yang mengatakan bahwa untuk ini Anda perlu menggunakan JD-GUI. Ditemukan di github, unduh. Saya mengidentifikasi area masalah dengan cukup cepat, karena JD-GUI memiliki navigasi interaktif yang luar biasa. Dari pesan ke situs, saya keluar dalam 10 menit. Bagian ini memanggil program pihak ketiga, setelah itu menganalisis responsnya. Panggilannya terlihat seperti ini:
systemConsoleCommand[index] = "system-console"; systemConsoleCommand[var24++] = "--script=" + Globals.gHost.getMonitorProgramRootDir("bin/jtag_instance_check.tcl", true); systemConsoleCommand[var24++] = cable; systemConsoleCommand[var24++] = Globals.gProject.system.sofFilename; try { Process sysConsoleProc = NiosIIShell.executeCommand(systemConsoleCommand).start(); BufferedReader gdbIn = new BufferedReader(new InputStreamReader(sysConsoleProc.getInputStream()));
Nah, dan selanjutnya - analisis jawaban yang belum kita pertimbangkan.
Dengan kode ini, saya mencoba membuka konsol NIOS II:

Di sana saya pergi ke direktori tempat file sof berada dan mengarahkan baris perintah:
system-console --script = jtag_instance_check.tcl USB-0 test.sofBenar, untuk ini saya harus menyalin file C: \ intelFPGALite \ 17.1 \ University_Program \ Monitor_Program \ bin \ jtag_instance_check.tcl ke tempat yang sama dengan sof, agar tidak menderita dengan path. Pada akhirnya, saya mendapat respons yang lumayan:
TYPE_NAME altera_avalon_jtag_uart.jtag FULL_HPATH jtag_uart_0 (INSTANCE_ID: 0)
TYPE_NAME altera_nios2_gen2.data_master FULL_HPATH nios2_gen2_0 (INSTANCE_ID: 0)
Segalanya tampak indah ...
Pelacakan Bytecode JAVA
Jika kasus ini terjadi hari ini, bagian ini tidak akan ada. Tapi itu terjadi kemarin. Saya masih mengerti Java dengan sangat buruk. Apa yang ditulis di sana sambil menguraikan teks adalah hutan yang gelap bagiku. Benar, selama dua tahun anak saya menghadiri kursus pemrograman olimpiade di 1 franchisee Soviet (sertifikat dan handout adalah 1 Soviet). Uang gila diberikan untuk kursus-kursus ini. Dan mereka mengajar mereka di sana hanya di Jawa. Jadi, dia juga tidak mengerti apa yang ditulis lebih lanjut dalam kode (menjaga intrik, saya akan mempublikasikan kode sedikit lebih rendah, tidak sekarang). Secara umum, ada perasaan gigih bahwa sudah waktunya untuk dilacak. Saya tahu bagian yang buruk, saya melihat bahwa garis diterima di sana dan program tidak menyukai mereka dengan sesuatu. Jadi apa
Anak itu menemukan saya artikel yang sangat bagus
www.crowdstrike.com/blog/native-java-bytecode-debugging-without-source-codeIni berbicara tentang plugin yang sangat berguna untuk Eclipse, yang memungkinkan Anda untuk bekerja dengan JAR, mengatur breakpoint di dalamnya. Tempat pengunduhan, saya temukan di sini:
marketplace.eclipse.org/content/bytecode-visualizer/helpSaya mengunduh Eclipse, mengunduh plug-in untuk instalasi offline dengan setengah sedih ... Saya mulai menginstal - tidak ada cukup perpustakaan. Saya mulai membaca. Ternyata ada tiga versi plugin. Di bawah Eslipse 4.5 (Mars), 4.4 (Luna) dan 4.3 (Saya tidak ingat namanya). Yah, semuanya sederhana. Kami pergi ke situs web Eclipse, kami melihat tautan untuk mengunduh versi Mars untuk Java ... Dan ... Sudah mati. Tidak masalah! Ada sekitar selusin cermin! .. Dan semua tautan ke sana sudah mati. Kami mencoba Luna untuk Java, ada tautan ke x64 sudah mati, ke x86 ada satu yang hidup ... Seperti yang dikatakan salah seorang teman saya: "Wasir, itu komprehensif." Secara umum, Google mengalami kesulitan, tetapi menemukan saya perakitan Java 64-bit versi Mars di beberapa server tidak resmi. Saya mengunduhnya selama setengah jam, tetapi mengunduhnya.
Menerapkan plugin, membuat proyek ... Horor! Di sana, jejaknya tidak pada tingkat kode sumber, tetapi pada tingkat ala assembler. Singkatnya, kode byte yang didekode dilacak. Namun faktanya, itu tidak masalah! Setelah semua, Anda selalu dapat memeriksa dengan sumber yang telah dikompilasi dibuka di jendela lain, ditambah bahwa plugin menunjukkan komentar yang sangat bagus ... Juga ternyata breakpoint dapat diatur tidak di sembarang tempat, tetapi hanya di pintu masuk ke fungsi. Tapi saya tidak bisa berhenti! Tidak ada banyak di sana dan Anda harus berjalan dari pintu masuk ke area masalah.
Biarkan saya mengingatkan Anda bahwa baris yang diproses terlihat seperti ini:
TYPE_NAME altera_avalon_jtag_uart.jtag FULL_HPATH jtag_uart_0 (INSTANCE_ID: 0)
TYPE_NAME altera_nios2_gen2.data_master FULL_HPATH nios2_gen2_0 (INSTANCE_ID: 0)Dan di sini adalah kode Java:
if (str.contains("(INSTANCE_ID:")) { Pattern getInstance = Pattern.compile("\\(INSTANCE_ID:(\\d+)\\)"); Matcher idMatcher = getInstance.matcher(str); if (idMatcher.find()) { String foundstr = idMatcher.group(1); instance = Integer.parseInt(foundstr); }
mengisolasi ID Instance dengan sempurna. Dan ini kodenya:
Pattern getHPath = Pattern.compile("FULL_HPATH (.+?)\\|(.+?) \\("); Matcher hpathMatcher = getHPath.matcher(str); if (hpathMatcher.find()) { hpath = hpathMatcher.group(2).replace("|", "."); }
variabel hpath tidak mengisi. Hari ini saya sudah tahu bahwa ungkapan biasa:
"FULL_HPATH (.+?)\\|(.+?) \\("
membutuhkan dua kata yang dipisahkan oleh bilah vertikal. Nah, maka hanya apa yang setelah garis diambil. Saya tidak tahu kemarin. Lebih menarik adalah hal lain. Anak itu belajar pekerjaan di Jawa selama dua tahun dan tidak belajar ekspresi reguler! Tidak, jelas bahwa mereka diajarkan bukan bahasa, tetapi pemrograman Olimpiade melalui bahasa, tetapi seperti yang saya pahami, ekspresi reguler di Jawa berada di urutan hal. Mereka mengambil uang seperti itu, mereka mengocok sertifikat dari perusahaan terkemuka, tetapi mereka tidak mengajarkan hal-hal penting ... Tapi saya ngelantur.
Cahaya di ujung terowongan
Apa itu garis vertikal? Kami mengambil proyek yang berhasil, memberikannya tim yang sama dan mendapatkan jawaban ini:
TYPE_NAME altera_avalon_jtag_uart.jtag FULL_HPATH Computer_System: The_System | JTAG_UART (INSTANCE_ID: 0)
TYPE_NAME altera_avalon_jtag_uart.jtag FULL_HPATH Computer_System: The_System | JTAG_UART_2nd_Core (INSTANCE_ID: 1)
TYPE_NAME altera_avalon_jtag_uart.jtag FULL_HPATH Computer_System: The_System | JTAG_UART_for_ARM_0 (INSTANCE_ID: 2)
TYPE_NAME altera_avalon_jtag_uart.jtag FULL_HPATH Computer_System: The_System | JTAG_UART_for_ARM_1 (INSTANCE_ID: 3)
TYPE_NAME altera_nios2_gen2.data_master FULL_HPATH Computer_System: The_System | Nios2 (INSTANCE_ID: 0)
TYPE_NAME altera_nios2_gen2.data_master FULL_HPATH Computer_System: The_System | Nios2_2nd_Core (INSTANCE_ID: 1)Apa itu Computer_System: The_System? Semuanya sederhana di sini. Dalam seri artikel ini saya mempromosikan ide lanjutan di mana sistem komputer berada di tingkat atas hierarki.
Dan contoh ini memiliki lapisan Verilog ini: module DE0_Nano_SoC_Computer ( //////////////////////////////////// // FPGA Pins //////////////////////////////////// // Clock pins input CLOCK_50, input CLOCK2_50, input CLOCK3_50, // ADC output ADC_CONVST, output ADC_SCLK, output ADC_SDI, input ADC_SDO, // ARDUINO inout [15:0] ARDUINO_IO, inout ARDUINO_RESET_N, // GPIO inout [35:0] GPIO_0, inout [35:0] GPIO_1, // KEY input [1:0] KEY, // LED output [7:0] LED, // SW input [3:0] SW, //////////////////////////////////// // HPS Pins //////////////////////////////////// // DDR3 SDRAM output [14:0] HPS_DDR3_ADDR, output [2:0] HPS_DDR3_BA, output HPS_DDR3_CAS_N, output HPS_DDR3_CKE, output HPS_DDR3_CK_N, output HPS_DDR3_CK_P, output HPS_DDR3_CS_N, output [3:0] HPS_DDR3_DM, inout [31:0] HPS_DDR3_DQ, inout [3:0] HPS_DDR3_DQS_N, inout [3:0] HPS_DDR3_DQS_P, output HPS_DDR3_ODT, output HPS_DDR3_RAS_N, output HPS_DDR3_RESET_N, input HPS_DDR3_RZQ, output HPS_DDR3_WE_N, // Ethernet output HPS_ENET_GTX_CLK, inout HPS_ENET_INT_N, output HPS_ENET_MDC, inout HPS_ENET_MDIO, input HPS_ENET_RX_CLK, input [3:0] HPS_ENET_RX_DATA, input HPS_ENET_RX_DV, output [3:0] HPS_ENET_TX_DATA, output HPS_ENET_TX_EN, // Accelerometer inout HPS_GSENSOR_INT, // I2C inout HPS_I2C0_SCLK, inout HPS_I2C0_SDAT, inout HPS_I2C1_SCLK, inout HPS_I2C1_SDAT, // Pushbutton inout HPS_KEY, // LED inout HPS_LED, // LTC inout HPS_LTC_GPIO, // SD Card output HPS_SD_CLK, inout HPS_SD_CMD, inout [3:0] HPS_SD_DATA, // SPI output HPS_SPIM_CLK, input HPS_SPIM_MISO, output HPS_SPIM_MOSI, inout HPS_SPIM_SS, // UART input HPS_UART_RX, output HPS_UART_TX, // USB inout HPS_CONV_USB_N, input HPS_USB_CLKOUT, inout [7:0] HPS_USB_DATA, input HPS_USB_DIR, input HPS_USB_NXT, output HPS_USB_STP ); //======================================================= // REG/WIRE declarations //======================================================= wire hps_fpga_reset_n; //======================================================= // Structural coding //======================================================= Computer_System The_System ( //////////////////////////////////// // FPGA Side //////////////////////////////////// // Global signals .system_pll_ref_clk_clk (CLOCK_50), .system_pll_ref_reset_reset (1'b0), // ADC .adc_sclk (ADC_SCLK), .adc_cs_n (ADC_CONVST), .adc_dout (ADC_SDO), .adc_din (ADC_SDI), // Arduino GPIO .arduino_gpio_export (ARDUINO_IO), // Arduino Reset_n .arduino_reset_n_export (ARDUINO_RESET_N), // Slider Switches .slider_switches_export (SW), // Pushbuttons .pushbuttons_export (~KEY), // Expansion JP1 .expansion_jp1_export ({GPIO_0[35:19], GPIO_0[17], GPIO_0[15:3], GPIO_0[1]}), // Expansion JP7 .expansion_jp7_export ({GPIO_1[35:19], GPIO_1[17], GPIO_1[15:3], GPIO_1[1]}), // LEDs .leds_export (LED), //////////////////////////////////// // HPS Side //////////////////////////////////// // DDR3 SDRAM .memory_mem_a (HPS_DDR3_ADDR), .memory_mem_ba (HPS_DDR3_BA), .memory_mem_ck (HPS_DDR3_CK_P), .memory_mem_ck_n (HPS_DDR3_CK_N), .memory_mem_cke (HPS_DDR3_CKE), .memory_mem_cs_n (HPS_DDR3_CS_N), .memory_mem_ras_n (HPS_DDR3_RAS_N), .memory_mem_cas_n (HPS_DDR3_CAS_N), .memory_mem_we_n (HPS_DDR3_WE_N), .memory_mem_reset_n (HPS_DDR3_RESET_N), .memory_mem_dq (HPS_DDR3_DQ), .memory_mem_dqs (HPS_DDR3_DQS_P), .memory_mem_dqs_n (HPS_DDR3_DQS_N), .memory_mem_odt (HPS_DDR3_ODT), .memory_mem_dm (HPS_DDR3_DM), .memory_oct_rzqin (HPS_DDR3_RZQ), // Accelerometer .hps_io_hps_io_gpio_inst_GPIO61 (HPS_GSENSOR_INT), // Ethernet .hps_io_hps_io_gpio_inst_GPIO35 (HPS_ENET_INT_N), .hps_io_hps_io_emac1_inst_TX_CLK (HPS_ENET_GTX_CLK), .hps_io_hps_io_emac1_inst_TXD0 (HPS_ENET_TX_DATA[0]), .hps_io_hps_io_emac1_inst_TXD1 (HPS_ENET_TX_DATA[1]), .hps_io_hps_io_emac1_inst_TXD2 (HPS_ENET_TX_DATA[2]), .hps_io_hps_io_emac1_inst_TXD3 (HPS_ENET_TX_DATA[3]), .hps_io_hps_io_emac1_inst_RXD0 (HPS_ENET_RX_DATA[0]), .hps_io_hps_io_emac1_inst_MDIO (HPS_ENET_MDIO), .hps_io_hps_io_emac1_inst_MDC (HPS_ENET_MDC), .hps_io_hps_io_emac1_inst_RX_CTL (HPS_ENET_RX_DV), .hps_io_hps_io_emac1_inst_TX_CTL (HPS_ENET_TX_EN), .hps_io_hps_io_emac1_inst_RX_CLK (HPS_ENET_RX_CLK), .hps_io_hps_io_emac1_inst_RXD1 (HPS_ENET_RX_DATA[1]), .hps_io_hps_io_emac1_inst_RXD2 (HPS_ENET_RX_DATA[2]), .hps_io_hps_io_emac1_inst_RXD3 (HPS_ENET_RX_DATA[3]), // I2C .hps_io_hps_io_i2c0_inst_SDA (HPS_I2C0_SDAT), .hps_io_hps_io_i2c0_inst_SCL (HPS_I2C0_SCLK), .hps_io_hps_io_i2c1_inst_SDA (HPS_I2C1_SDAT), .hps_io_hps_io_i2c1_inst_SCL (HPS_I2C1_SCLK), // Pushbutton .hps_io_hps_io_gpio_inst_GPIO54 (HPS_KEY), // LED .hps_io_hps_io_gpio_inst_GPIO53 (HPS_LED), // LTC .hps_io_hps_io_gpio_inst_GPIO40 (HPS_LTC_GPIO), // SD Card .hps_io_hps_io_sdio_inst_CMD (HPS_SD_CMD), .hps_io_hps_io_sdio_inst_D0 (HPS_SD_DATA[0]), .hps_io_hps_io_sdio_inst_D1 (HPS_SD_DATA[1]), .hps_io_hps_io_sdio_inst_CLK (HPS_SD_CLK), .hps_io_hps_io_sdio_inst_D2 (HPS_SD_DATA[2]), .hps_io_hps_io_sdio_inst_D3 (HPS_SD_DATA[3]), // SPI .hps_io_hps_io_spim1_inst_CLK (HPS_SPIM_CLK), .hps_io_hps_io_spim1_inst_MOSI (HPS_SPIM_MOSI), .hps_io_hps_io_spim1_inst_MISO (HPS_SPIM_MISO), .hps_io_hps_io_spim1_inst_SS0 (HPS_SPIM_SS), // UART .hps_io_hps_io_uart0_inst_RX (HPS_UART_RX), .hps_io_hps_io_uart0_inst_TX (HPS_UART_TX), // USB .hps_io_hps_io_gpio_inst_GPIO09 (HPS_CONV_USB_N), .hps_io_hps_io_usb1_inst_D0 (HPS_USB_DATA[0]), .hps_io_hps_io_usb1_inst_D1 (HPS_USB_DATA[1]), .hps_io_hps_io_usb1_inst_D2 (HPS_USB_DATA[2]), .hps_io_hps_io_usb1_inst_D3 (HPS_USB_DATA[3]), .hps_io_hps_io_usb1_inst_D4 (HPS_USB_DATA[4]), .hps_io_hps_io_usb1_inst_D5 (HPS_USB_DATA[5]), .hps_io_hps_io_usb1_inst_D6 (HPS_USB_DATA[6]), .hps_io_hps_io_usb1_inst_D7 (HPS_USB_DATA[7]), .hps_io_hps_io_usb1_inst_CLK (HPS_USB_CLKOUT), .hps_io_hps_io_usb1_inst_STP (HPS_USB_STP), .hps_io_hps_io_usb1_inst_DIR (HPS_USB_DIR), .hps_io_hps_io_usb1_inst_NXT (HPS_USB_NXT) ); endmodule
Saya secara khusus membawanya secara penuh untuk menekankan berapa banyak kode yang sama sekali tidak perlu Anda harus tulis dalam kasus ini. Dan jika kaki ditambahkan atau dihapus, kode ini juga harus diedit. Sebenarnya, garis

Teks yang sama: ... Computer_System The_System ( //////////////////////////////////// // FPGA Side //////////////////////////////////// // Global signals .system_pll_ref_clk_clk (CLOCK_50), ...
dan berikan awalan ini. Para penulis percaya bahwa hierarki harus seperti itu, hanya ini dan bukan yang lain. Sistem prosesor tidak dapat dilepas lebih dalam dan tidak dapat dijalankan.
Kita seharusnya tidak menunggu belas kasihan dari alam, ambillah - tugas kita!
Apakah kita benar-benar melakukan pekerjaan seperti itu murni untuk menghadapi masalah ini? Seperti yang seorang teman saya suka mengatakan: "pekerjaan yang tidak perlu lebih buruk daripada mabuk," dan penciptaan lapisan seperti itu adalah kasus khas dari pekerjaan yang tidak perlu. Oleh karena itu, kami akan berusaha menghindari batasan ini. Ingat, ketika memanggil program JAVA pihak ketiga, kode tersebut menggantikan beberapa skrip tcl, saya juga menyalinnya ke direktori di sebelah file sof? Itu adalah keselamatan kita! Dialah yang memberi tahu konsol sistem tindakan apa yang harus diambil dan dialah yang memformat respons. pemformatan berjalan seperti ini:

Teks yang sama: # PRINT OUT INSTANCE ID INFO FOR EVERYTHING: set i 0 foreach path [lsort -command compare_node_number [get_service_paths bytestream]] { # If this path corresponds to a JTAG UART, incr i if {[string match *$cable_name* $path ] && [string match *jtag_uart* [marker_get_type $path] ]} { puts "[marker_get_info $path] (INSTANCE_ID:$i)" incr i } } set i 0 foreach path [lsort -command compare_node_number [get_service_paths processor]] { # If this path corresponds to a NiosII, incr i if {[string match *$cable_name* $path ] && [string match *nios2* [marker_get_type $path] ]} { puts "[marker_get_info $path] (INSTANCE_ID:$i)" incr i } }
Blok pertama memformat informasi tentang JTAG_UART blok, yang kedua - tentang inti prosesor. Sekarang, jika di sini kita tambahkan garis vertikal ke aliran output! Rekan saya memperbaiki bagian ini sebagai berikut:
# PRINT OUT INSTANCE ID INFO FOR EVERYTHING: set i 0 foreach path [lsort -command compare_node_number [get_service_paths bytestream]] { # If this path corresponds to a JTAG UART, incr i if {[string match *$cable_name* $path ] && [string match *jtag_uart* [marker_get_type $path] ]} { set info [marker_get_info $path] if {[string first "|" $info] == -1} { set info [string map {"FULL_HPATH " "FULL_HPATH a:b|"} $info] } puts "$info (INSTANCE_ID:$i)" incr i } } set i 0 foreach path [lsort -command compare_node_number [get_service_paths processor]] { # If this path corresponds to a NiosII, incr i if {[string match *$cable_name* $path ] && [string match *nios2* [marker_get_type $path] ]} { set info [marker_get_info $path] if {[string first "|" $info] == -1} { set info [string map {"FULL_HPATH " "FULL_HPATH a:b|"} $info] } puts "$info (INSTANCE_ID:$i)" incr i } }
Sekarang, jika tidak ada tanda hubung, mereka akan ditambahkan. Dan akhirnya, program ini akan bekerja tidak hanya dengan yang mengerikan, tetapi juga dengan sistem prosesor yang ditulis secara optimal!
Menyiapkan proyek di Monitor Altera
Uffff. Itu saja. Akhir untuk mencungkil, off-road dan kecerobohan (meskipun, tentang off-road - ini tidak akurat). Sekarang lagi, gambar-gambar dalam artikel mencerminkan instruksi untuk bekerja! Kami memiliki proyek untuk FPGA, serta program yang membangun dan berjalan di Eclipse. Sekarang luncurkan Altera Monitor dan buat proyek.

Kami membuat katalog dengan proyek (saya meletakkannya secara terpisah dari proyek untuk FPGA) dan memberikan nama proyek. Juga pilih arsitektur prosesor

Sistem yang saya pilih adalah Sistem Kustom. Anda harus menentukan file * .sof dan * .sopcinfo saya. Saya memilih mereka di direktori kerja. Sistem kami tidak membutuhkan preloader.

Pilih jenis program Program dengan Dukungan Driver Perangkat, maka pustaka BSP akan dibangun:

Hanya ada satu file yang berfungsi sejauh ini (dibuat di Eclipse). Di sini saya tambahkan:

Di jendela terakhir, saya tidak mengubah apa pun:

Kami setuju untuk mengunduh file sof:

Jika kami baru saja menginstal perangkat lunak, kami beralih ke mode sumber. Maka itu sudah akan dihidupkan (saya akan menunjukkan kepada Anda seperti apa menu itu ketika semuanya sudah dihidupkan, juga akan ada item untuk dimasukkan).

Saya memiliki program C paling sederhana:
#include "sys/alt_stdio.h" int main() { alt_putstr("Hello from Nios II!\n"); volatile int i=0; i += 1; i += 2; i += 3; i += 4; i += 5; i += 6; i += 7; i += 8; i += 9; i += 10; i += 11; i += 12; /* Event loop never exits. */ while (1); return 0; }
Saya mencoba untuk mengumpulkannya:

Saya mendapatkan kesalahan:
c: /intelfpga/17.1/nios2eds/bin/gnu/h-x86_64-mingw32/bin /../ lib / gcc / nios2-elf / 5.3.0 /../../../../../ .. /H-x86_64-mingw32/nios2-elf/bin/ld.exe: region `Code 'dilampaui oleh 15888 bytesIni karena saya tidak menambahkan SDRAM ke sistem, saya membatasinya pada memori FPGA internal. Tapi mengapa semuanya cocok di Eclipse, tetapi tidak di sini? Karena saya memilih BSP di sana dengan akhiran Small, tetapi di sini saya secara otomatis membuat paket reguler. Oleh karena itu, buka file: C: \ Work \ Play2 \ BSP \ settings.bsp
Dan kami mulai penyetelan manual.


Membangun kembali BSP:

Dan lagi kami mengumpulkan proyek. Kali ini berhasil. Sekarang muat:

Akhirnya, jejak yang sebenarnya
Anda belum lupa mengapa saya melakukan semua ini? Saya melakukan ini untuk melacak. Itu harus diaktifkan. Untuk melakukannya, buka tab Lacak dan pilih Aktifkan Lacak di menu konteks:

Saya akan meletakkan breakpoint di akhir fungsi main () pada tab Disassembly (alangkah bagusnya assembler RISC setelah assembler stack yang mengerikan di mana kode Java dikonversi!)
Inilah awal dari fungsi utama:

Gulirkan sedikit ke bawah dan letakkan breakpoint di sini:

Kami mulai, menunggu berhenti dan pergi ke tab Jejak.
Secara umum, semuanya tidak terlalu baik. Pada awalnya, jelas ada semacam harapan (kami memiliki kesimpulan di JTAG di sana, jadi itu adalah hal yang sah):

Pada akhirnya - beberapa kode lain ... Tapi saya tidak melihat kode fungsi utama! Inilah akhirnya:

Saya bahkan tidak tahu harus berkata apa. Tapi bagaimanapun, jika Anda tidak menempatkan satu, tetapi dua breakpoints (di awal dan akhir fungsi utama), maka setelah menjalankan dari yang pertama ke yang kedua, gambar akan layak:

Kesimpulan singkat
Jadi, kami mengetahui bahwa sangat mungkin untuk mengetahui cara kerja situs tertentu. Jadi, topik artikel ("... bagaimana prosesor telah sampai pada kehidupan seperti itu") diungkapkan. Lebih menarik bagaimana semua orang yang masalah-masalahnya harus diselesaikan untuk mendapatkan hasil telah datang ke kehidupan seperti itu? Dan sangat disayangkan bahwa sejauh ini saya belum dapat menentukan berapa banyak bar yang diselesaikan oleh tim tertentu. Dari potongan dokumentasi jelas bahwa ini tampaknya secara teknis memungkinkan, tetapi perangkat lunak apa yang memungkinkan ini dilakukan tidak jelas. Ada pendapat bahwa dokumen
Menganalisis dan Desain Debugging dengan System Console , yang harus saya baca ketika menganalisis skrip tcl, akan membantu kami. Ini memiliki tablet yang menarik
Tabel 10-15: Trace System Commands , tetapi secara pribadi, saya hanya tidak punya waktu untuk studi rinci tentang masalah ini. Tapi mungkin itu akan sangat penting bagi seseorang sehingga dia mengimplementasikan semuanya. Perintah-perintah ini termasuk dalam skrip tcl.
Nah, dalam artikel berikut, pengukuran harus dilakukan dengan cara lama, dengan osiloskop.