Yah, kami sudah tahu semua yang Anda butuhkan untuk memprogram UDB. Tetapi itu adalah satu hal yang perlu diketahui, dan merupakan hal lain untuk bisa. Karena itu, hari ini kita akan membahas di mana dan bagaimana menggambar inspirasi untuk meningkatkan keterampilan kita sendiri, di mana untuk mendapatkan pengalaman. Seperti yang dapat dilihat dari
terjemahan dokumentasi , ada pengetahuan kering yang tidak selalu terkait dengan praktik nyata (saya memperhatikan hal ini dalam catatan yang agak panjang, ke terjemahan terakhir hingga saat ini). Sebenarnya, statistik tampilan artikel menunjukkan bahwa semakin sedikit orang membaca terjemahan. Bahkan ada proposal untuk menghentikan siklus ini, sebagai tidak menarik, tetapi hanya dua bagian yang tersisa, oleh karena itu, pada akhirnya, hanya diputuskan untuk mengurangi kecepatan persiapan mereka. Secara umum, dokumentasi untuk pengontrol adalah hal yang perlu, tetapi tidak mencukupi. Di mana lagi mendapat inspirasi?

Pertama-tama, saya dapat merekomendasikan dokumen yang luar biasa
AN82156 Merancang Komponen Pencipta PSoC dengan UDB Datapaths . Di dalamnya Anda akan menemukan solusi khas, serta beberapa proyek standar. Selain itu, pada awal dokumen, pengembangan dilakukan menggunakan Editor UDB, dan pada akhirnya, menggunakan Datapath Config Tool, yaitu dokumen tersebut mencakup semua aspek pengembangan. Namun sayangnya, melihat harga satu chip PSoC, saya akan mengatakan bahwa jika itu hanya dapat menyelesaikan masalah yang dijelaskan dalam dokumen ini, pengontrolnya sangat berlebihan. PWM dan port serial standar dapat dilakukan tanpa PSoC. Untungnya, kisaran tugas PSoC jauh lebih luas. Karena itu, setelah selesai membaca AN82156, kami mulai mencari sumber inspirasi lainnya.
Sumber berguna berikutnya adalah contoh-contoh yang datang dengan Pencipta PSoC. Saya sudah merujuk mereka dalam catatan ke salah satu bagian dari terjemahan dokumentasi perusahaan (Anda bisa lihat di
sini ). Mereka disimpan kira-kira di sini (disk mungkin berbeda):
E: \ Program Files (x86) \ Cypress \ PSoC Creator \ 4.2 \ PSoC Creator \ psoc \ content \ CyComponentLibrary.
Anda harus mencari file * .v, yaitu, teks Verilog, atau * .vhd, karena sintaks bahasa VHDL memerlukan sedikit lebih banyak untuk dijelaskan, dan dalam bahasa ini Anda kadang-kadang dapat menemukan nuansa menarik yang tersembunyi dari mata programmer di Verilog. Masalahnya adalah ini bukan contoh, tetapi solusi siap pakai. Ini luar biasa, mereka benar-benar debugged, tetapi kami, programmer sederhana, memiliki tujuan berbeda dengan programmer Cypress. Tugas kita adalah melakukan sesuatu tambahan dalam waktu singkat, setelah itu kita mulai menggunakannya dalam proyek-proyek kita, yang akan menghabiskan sebagian besar waktu kita. Idealnya harus menyelesaikan tugas yang diberikan kepada kita hari ini, dan jika besok kita ingin memasukkan kode yang sama ke proyek lain, di mana semuanya akan sedikit berbeda, maka besok kita akan menyelesaikannya dalam situasi itu. Untuk pengembang Cypress, komponennya adalah produk akhir, sehingga mereka dapat menghabiskan sebagian besar waktunya untuk itu. Dan mereka harus menyediakan semua untuk semua. Jadi ketika saya menonton teks-teks ini, saya merasa sedih. Mereka terlalu kompleks untuk seseorang yang baru saja mulai mencari di mana menarik inspirasi untuk perkembangan pertama mereka. Tetapi sebagai referensi teks-teks ini sangat cocok. Ada banyak desain berharga yang dibutuhkan saat membuat barang-barang Anda sendiri.
Juga ada sudut yang sangat menarik. Misalnya, ada, sekarang saya akan mengatakan dalam gaya "minyak mentega", model untuk pemodelan (dahulu kala, seorang guru keras tidak menyarankan saya menerjemahkan simulasi dengan cara lain selain "pemodelan"). Mereka dapat ditemukan di katalog.
E: \ Program Files (x86) \ Cypress \ PSoC Creator \ 4.2 \ PSoC Creator \ warp \ lib \ sim.
Direktori paling menarik untuk programmer di Verilogue adalah:
E: \ Program Files (x86) \ Cypress \ PSoC Creator \ 4.2 \ PSoC Creator \ warp \ lib \ sim \ presynth \ vlg.
Deskripsi komponen dalam dokumentasi baik. Tetapi model perilaku untuk semua komponen standar dijelaskan di sini. Kadang-kadang ini lebih baik daripada dokumentasi (yang ditulis dalam bahasa yang berat, ditambah beberapa detail penting dihilangkan). Ketika perilaku komponen ini atau itu tidak jelas, ada baiknya memulai upaya untuk memahaminya secara tepat dengan melihat file dari direktori ini. Pada awalnya saya mencoba mencari di Google, tetapi sangat sering saya bertemu di forum yang ditemukan hanya alasan dan tidak ada yang spesifik. Inilah spesifikasinya.
Meskipun demikian, buku rujukannya luar biasa, tetapi dari mana mencari buku teks, dari mana belajar? Jujur saja, tidak ada yang istimewa. Tidak ada banyak contoh siap pakai untuk Editor UDB. Saya sangat beruntung ketika tiba-tiba saya memutuskan untuk memainkan LED RGB, saya menemukan contoh yang indah di bawah Editor UDB (saya menulis tentang hal itu dalam
artikel yang memulai seluruh siklus). Tetapi jika Anda banyak bekerja dengan mesin pencari, maka masih akan ada contoh untuk Datapath Config Tool, itulah sebabnya saya membuat
artikel sebelumnya sehingga semua orang akan mengerti cara menggunakan alat ini. Dan halaman indah di mana banyak contoh dikumpulkan terletak di
sini .
Di halaman ini ada perkembangan yang dibuat oleh pengembang pihak ketiga, tetapi diverifikasi oleh Cypress. Itulah yang kami butuhkan: kami juga pengembang pihak ketiga, tetapi kami ingin belajar dari sesuatu yang benar-benar diverifikasi. Mari kita lihat contoh di mana saya menemukan halaman ini - kalkulator perangkat keras akar kuadrat. Pengguna akhir memasukkannya ke jalur pemrosesan sinyal, melemparkan komponen ke sirkuit. Dalam contoh ini, kami akan melatih untuk menganalisis kode yang serupa, dan kemudian semua orang akan dapat mulai berenang secara mandiri. Jadi, contoh yang diperlukan dapat diunduh dari
tautan .
Kami memeriksanya. Ada contoh (yang semua orang akan mempertimbangkan secara independen) dan ada perpustakaan yang terletak di direktori \ CJCU_SquareRoot \ Library \ CJCU_SquareRoot.cylib.
Untuk setiap jenis (bilangan bulat atau titik tetap) dan untuk setiap bit, ada solusinya. Ini harus diperhatikan. Fleksibilitas baik ketika berkembang di Editor UDB, tetapi ketika mengembangkan menggunakan Alat Edit Datapath, seperti yang Anda lihat, orang-orang tersiksa seperti ini. Jangan takut jika Anda tidak dapat melakukannya secara universal (tetapi jika berhasil semakin baik).
Di level atas (sirkuit), saya tidak akan berhenti, kami belajar tidak bekerja dengan PSoC, tetapi bekerja dengan UDB. Mari kita lihat opsi kompleksitas sedang - 16 bit, tetapi integer. Itu terletak di direktori CJCU_B_Isqrt16_v1_0.
Hal pertama yang harus dilakukan adalah memperluas grafik transisi firmware. Tanpa itu, kami bahkan tidak akan menebak algoritma akar kuadrat apa yang telah diterapkan, karena Google menawarkan pilihan beberapa algoritma yang berbeda secara fundamental.

Sejauh ini, tidak ada yang jelas, tetapi dapat diprediksi. Perlu menambahkan informasi lebih lanjut. Kami melihat pengkodean negara. Sangat mengejutkan bahwa mereka tidak dikodekan dalam kode biner incremental yang biasa.

Saya telah menyebutkan pendekatan ini dalam artikel saya, tetapi saya tidak pernah bisa menggunakannya dalam contoh spesifik. Biarkan saya mengingatkan Anda bahwa konfigurasi dinamis ALU RAM hanya memiliki tiga input alamat. Artinya, ALU dapat melakukan salah satu dari delapan operasi. Jika automaton memiliki lebih banyak status, maka aturan "setiap negara memiliki operasi sendiri" menjadi tidak mungkin. Oleh karena itu, negara dipilih di mana operasi untuk ALU identik, mereka memiliki tiga bit dipasok ke alamat RAM dari konfigurasi dinamis (biasanya yang low-order), mereka dikodekan dengan cara yang sama, dan sisanya dengan cara yang berbeda. Cara menjumlahkan solitaire seperti itu sudah menjadi masalah pengembang. Pengembang kode yang dipelajari terlipat persis seperti yang ditunjukkan di atas.
Tambahkan informasi ini ke grafik, plus warna negara yang melakukan fungsi yang sama di ALU dalam warna yang sama.

Belum ada pola yang dimanifestasikan, tetapi kami terus membuka grafik. Kami membuka Alat Edit Datapath dan kami sudah mempelajari logika di dalamnya.
Harap dicatat bahwa kami memiliki dua blok Datapath yang terhubung dalam sebuah rantai. Ketika kita melakukan sesuatu sendiri, kita juga mungkin memerlukan ini (meskipun, Alat Edit Datapath dapat membuat blok yang sudah ditautkan dalam rantai, jadi ini tidak menakutkan):

Saat membaca (dan mengisi) grafik yang berhubungan dengan ALU, kami selalu membuka dokumen dengan gambar berikut:

Benar, para pengembang contoh ini merawat kami dan mengisi kolom komentar. Sekarang kita dapat menggunakannya untuk memahami untuk apa konfigurasi. Pada saat yang sama, kami mencatat bagi diri kami sendiri bahwa menulis komentar selalu bermanfaat baik bagi mereka yang akan menemani kode, dan bagi kami, ketika dalam enam bulan kami akan melupakan semuanya tentang itu.
Kami melihat kode X000 yang sesuai dengan status 0 dan 12:

Dari komentar, sudah jelas apa yang terjadi di sana (isi register D0 disalin untuk mendaftar A0, dan konten D1 disalin untuk mendaftar A1. Mengetahui hal ini, kami melatih intuisi kami untuk masa depan dan menemukan entri serupa di bidang pengaturan:

Di sana kita melihat bahwa ALU beroperasi dalam mode
PASS , register geser juga
PASS , sehingga tidak ada tindakan lain yang benar-benar dilakukan.
Sepanjang jalan, kita melihat teks di Verilog dan melihat di mana nilai register D0 dan D1 sama dengan:

Jika diinginkan, hal yang sama dapat dilihat di Alat Konfigurasi Datapath, dengan memilih View-> Nilai Registrasi Awal:


Untuk melihat, lebih mudah untuk secara langsung menganalisis kode Verilog, untuk membuat versi Anda sendiri - bekerja melalui editor agar tidak mengingat sintaks.
Demikian pula, kami menganalisis (pertama, mengintip di komentar) semua fungsi ALU lainnya:

Kami mengulang grafik transisi otomat dengan mempertimbangkan pengetahuan baru:

Sesuatu sudah menjulang, tetapi sejauh ini saya tidak bisa memastikan dengan pasti algoritma apa pun yang ditemukan oleh Google pada grafik ini. Sebaliknya, tentang beberapa orang, Anda dapat dengan yakin mengatakan bahwa itu bukan mereka, tetapi bahkan bagi orang yang dapat dipercaya saya masih tidak dapat memberikan jawaban yang yakin bahwa itu adalah mereka. Membingungkan penggunaan register FIFO F0 dan F1 yang aktif. Umumnya dalam file
\ CJCU_SquareRoot \ Library \ CJCU_SquareRoot.cylib \ CJCU_Isqrt_v1_0 \ API \ CJCU_Isqrt.c
dapat dilihat bahwa F1 digunakan untuk meneruskan argumen dan mengembalikan hasilnya:

Teks yang sama:void `$INSTANCE_NAME`_ComputeIsqrtAsync(uint`$regWidth` square) { /* Set up FIFOs, start the computation. */ CY_SET_REG`$dpWidth`(`$INSTANCE_NAME`_F1, square); CY_SET_REG8(`$INSTANCE_NAME`_CTL, 0x01); } … uint`$resultWidth` `$INSTANCE_NAME`_ReadIsqrtAsync() { /* Read back result. */ return CY_GET_REG`$dpWidth`(`$INSTANCE_NAME`_F1); }
Tapi satu argumen dan satu hasil. Dan mengapa ada begitu banyak panggilan ke FIFO selama bekerja? Dan apa hubungannya dengan FIFO0? Potong saya berkeping-keping, tetapi tampaknya penulis mengambil keuntungan dari mode yang ditemui dalam terjemahan dokumentasi, ketika alih-alih FIFO lengkap, blok ini bertindak sebagai register tunggal. Misalkan penulis memutuskan untuk memperluas set register. Jika demikian, maka metodologi mereka akan berguna bagi kita dalam pekerjaan praktis kita, mari kita pelajari detailnya. Bahkan, dokumentasi berbicara tentang berbagai pendekatan untuk bekerja dengan FIFO. Anda bisa - jadi, Anda bisa - begitu, tetapi Anda bisa - semacam itu. Dan tidak ada yang spesifik. Sekali lagi kami memiliki kesempatan untuk belajar tentang praktik internasional terbaik. Apa yang penulis lakukan dengan FIFO?
Pertama, ini adalah tugas sinyal:
wire f0_load = (state == B_SQRT_STATE_1 || state == B_SQRT_STATE_4); wire f1_load = (state == B_SQRT_STATE_1 || state == B_SQRT_STATE_3 || state == B_SQRT_STATE_9 || state == B_SQRT_STATE_11); wire fifo_dyn = (state == B_SQRT_STATE_0 || state == B_SQRT_STATE_12);
Kedua, ini koneksi ke Datapath:
/* input */ .f0_load(f0_load), /* input */ .f1_load(f1_load), /* input */ .d0_load(1'b0), /* input */ .d1_load(fifo_dyn),
Dari deskripsi pengontrol tidak terlalu jelas apa artinya semua ini. Tetapi dari Application Note, saya menemukan bahwa pengaturan ini yang harus disalahkan untuk semuanya:

Ngomong-ngomong, justru karena pengaturan ini, blok ini tidak dapat dijelaskan menggunakan Editor UDB. Ketika bit kontrol ini dalam keadaan
ON , FIFO dapat bekerja pada sumber dan penerima yang berbeda. Jika
Dx_LOAD sama dengan satu, maka
Fx bertukar dengan bus sistem, jika nol, maka dengan register yang dipilih di sini:

Ternyata F0 selalu bertukar dengan register A0, dan F1 di negara 12 dan 0 - dengan bus sistem (untuk mengunggah hasil dan memuat argumen), di negara-negara lain - dengan A1.
Selanjutnya, dari kode Verilog, kami menemukan bahwa di F0 data akan dimuat di negara bagian 1 dan 4, dan di F1 - di negara bagian 1, 3, 9, 11.
Tambahkan pengetahuan yang diperoleh ke grafik. Untuk menghindari kebingungan selama urutan operasi, tibalah saatnya untuk mengganti tanda penugasan "a la UDB Editor" dengan panah Verilogov untuk menekankan bahwa sumber adalah nilai dari sinyal yang dimilikinya sebelum memasuki blok.

Dari sudut pandang analisis algoritma, semuanya sudah jelas. Di depan kami adalah modifikasi dari algoritma seperti itu:
uint32_t SquareRoot(uint32_t a_nInput) { uint32_t op = a_nInput; uint32_t res = 0; uint32_t one = 1uL << 30; // The second-to-top bit is set: use 1u << 14 for uint16_t type; use 1uL<<30 for uint32_t type // "one" starts at the highest power of four <= than the argument. while (one > op) { one >>= 2; } while (one != 0) { if (op >= res + one) { op -= res + one; res += one << 1; } res >>= 1; one >>= 2; } return res; }
Hanya terkait dengan sistem kami akan terlihat seperti ini:
uint32_t SquareRoot(uint32_t a_nInput) { uint32_t op = a_nInput; uint32_t res = 0; uint32_t one = 1uL << 14; // The second-to-top bit is set while (one != 0) { if (op >= res + one) { op -= res + one; res += one << 1; } res >>= 1; one >>= 2; } return res; }
Negara 4 dan 10 secara eksplisit menyandikan string:
res >>= 1;
untuk cabang yang berbeda.
Garisnya adalah:
one >>= 2;
itu secara eksplisit dikodekan oleh sepasang negara 6 dan 7, atau sepasang negara 9 dan 7. Untuk saat ini, saya ingin berseru: "Ya, penemu adalah penulis yang sama!", tetapi segera akan menjadi jelas mengapa ada kesulitan dengan dua cabang (dalam kode C ada cabang dan solusi).
Negara 2 mengkodekan cabang bersyarat. Negara 7 mengkodekan pernyataan loop. Operasi perbandingan pada langkah 2 sangat mahal. Secara umum, dalam sebagian besar langkah, register A0 berisi variabel satu. Tetapi pada langkah 1, variabel satu diturunkan ke F0, dan alih-alih nilai
res + satu dimuat, maka pada langkah 2 pengurangan dilakukan untuk tujuan perbandingan, dan pada langkah 3 dan 8, nilai
satu dikembalikan. Mengapa, pada langkah 4, A0 disalin ke F0 lagi, saya tidak mengerti. Mungkin ini semacam kelainan.
Masih mencari tahu siapa yang
res dan siapa yang
op . Kita tahu bahwa kondisinya membandingkan op dan res + satu. Dalam kondisi 1, A0 (
satu ) dan A1 ditambahkan. Jadi ada A1
res . Ternyata di negara bagian 11 A1 juga
res , dan dialah yang masuk ke F1, yang diumpankan ke output fungsi. F1 di negara bagian 1 jelas
op . Saya mengusulkan untuk memperkenalkan diferensiasi warna
celana variabel. Kami menunjukkan
res sebagai merah,
op sebagai hijau, dan
satu sebagai coklat (tidak cukup kontras, tetapi warna lain bahkan kurang kontras).

Sebenarnya, seluruh kebenaran terungkap. Kita melihat bagaimana A1 secara terkenal berubah sementara dari F1 untuk perbandingan dan perhitungan, bagaimana perbedaan yang sama digunakan baik untuk perbandingan (sebenarnya, menghasilkan bit C), dan untuk berpartisipasi dalam formula. Kami bahkan melihat mengapa ruang kosong (memotong) dalam algoritma C dikodekan oleh cabang panjang dari grafik transisi dari otomat (dalam cabang ini, register dipertukarkan identik dengan pertukaran yang terjadi pada cabang kode utama). Kami melihat semuanya.
Satu-satunya pertanyaan yang tidak pernah berhenti menyiksaku adalah bagaimana penulis mengubah FIFO ke mode byte tunggal? Dokumentasi mengatakan bahwa untuk ini Anda perlu menaikkan bit CLR dalam register Kontrol Bantu menjadi sebuah unit, tetapi saya tidak melihat bahwa API memiliki catatan seperti itu. Mungkin seseorang akan memahami ini dan menulis di komentar.
Nah, dan untuk mengembangkan sesuatu sendiri - dalam urutan terbalik, menggunakan keterampilan yang didapat.
Kesimpulan
Untuk mengembangkan keterampilan mengembangkan "firmware" berdasarkan UDB, akan bermanfaat tidak hanya untuk membaca dokumentasi, tetapi juga untuk mendapatkan inspirasi dari desain orang lain. Kode yang disertakan dengan Pencipta PSoC dapat berguna sebagai referensi, dan model perilaku yang disertakan dengan kompiler akan membantu Anda lebih memahami apa yang dimaksud dalam dokumentasi. Artikel ini juga menyediakan tautan ke serangkaian contoh dari pabrikan pihak ketiga dan menunjukkan proses penguraian salah satu contoh tersebut.
Mengenai hal ini, siklus artikel hak cipta tentang bekerja dengan UDB dapat dianggap selesai. Saya akan senang jika dia membantu seseorang untuk mendapatkan pengetahuan yang berguna dalam latihan. Ada beberapa terjemahan dokumentasi di depan, tetapi statistik menunjukkan bahwa hampir tidak ada yang membacanya. Mereka direncanakan dengan rapi agar tidak menjatuhkan topik secara singkat.