Bench worksheets · transcribed from the lab notebook實驗桌工作單 · 由實驗筆記本謄寫ベンチ用ワークシート · 研究ノートからの書き起こしLembar kerja meja praktik · disalin dari buku catatan lab

Digital System Training數位系統訓練デジタルシステム訓練Pelatihan Sistem Digital

Radio Frequency & Microwave Lab, NSYSU國立中山大學 射頻與微波實驗室国立中山大学 高周波・マイクロ波研究室Laboratorium Frekuensi Radio & Gelombang Mikro, NSYSU

A bench-first path through digital system design: Verilog on the FPGA fabric, C and C++ on the host, and the toolchain that joins them — Git, the lab VPN, the operating system, and AI-assisted coding. Every section is a ladder of builds, each one standing on the last, so nothing you get working is ever thrown away.一條從實驗桌出發的數位系統設計學習路線:FPGA 上的 Verilog、主機端的 C 與 C++,以及把兩者串起來的工具鏈——Git、實驗室 VPN、作業系統與 AI 輔助開發。每個章節都是一層層往上疊的實作,後面的題目站在前面的成果上,已經做出來的東西不會被丟掉。実験台から始めるデジタルシステム設計の道筋。FPGA 上の Verilog、ホスト側の C と C++、そして両者をつなぐツールチェーン——Git、研究室 VPN、オペレーティングシステム、AI 支援開発。各セクションは積み上がる課題の連なりで、後の課題は前の成果の上に立ち、動かせたものが捨てられることはない。Jalur belajar desain sistem digital yang dimulai dari meja praktik: Verilog di atas fabric FPGA, C dan C++ di sisi host, serta rantai alat yang menyatukan keduanya — Git, VPN laboratorium, sistem operasi, dan pemrograman berbantuan AI. Setiap bagian adalah rangkaian pekerjaan yang saling menumpuk, masing-masing berdiri di atas yang sebelumnya, sehingga tidak ada hasil kerja yang terbuang.

Before you start · hardware · cable driver · parts · hand-in開始之前 · 硬體 · 下載線驅動 · 材料 · 繳交始める前に · ハードウェア · ケーブルドライバ · 部品 · 提出Sebelum mulai · perangkat keras · driver kabel · komponen · pengumpulan

Pre-request事前準備事前準備Prasyarat

Everything that has to be settled before the first build: the boards and the adapter you are lent, the oscillator check that decides every divisor on the worksheets, the USB-JTAG cable driver, where to buy the rest of the parts and how the invoice has to be made out, and the three things every hand-in carries. 在第一個設計開始之前必須先處理好的事:借給你的板子和轉接器、決定工作單上每一個除數的振盪器確認、USB-JTAG 下載線驅動、其餘材料去哪裡買、發票要怎麼開,以及每一次繳交都要帶的三樣東西。最初のビルドに入る前に片付けておくこと:貸し出すボードとアダプタ、ワークシートのすべての分周値を左右する発振器の確認、USB-JTAG ケーブルドライバ、残りの部品をどこで買い發票をどう切ってもらうか、そして提出物に必ず付く 3 点。Semua yang harus beres sebelum build pertama: papan dan adapter yang dipinjamkan, pemeriksaan osilator yang menentukan setiap pembagi di lembar kerja, driver kabel USB-JTAG, di mana membeli sisa komponennya dan bagaimana fakturnya harus dibuat, serta tiga hal yang dibawa setiap pengumpulan.

Hardware — what you are given硬體 —— 你會拿到的東西ハードウェア — 貸し出すものPerangkat keras — apa yang kamu terima

There should be three Digilent Artix-7 dev boards — the white ones — in the lab. If they are not on the bench, ask Tony, or anyone who can reach Yiya; between them they know where the boards ended up. 實驗室裡應該有三片 Digilent Artix-7 開發板——白色那款。如果桌上找不到,去問 Tony,或任何聯絡得到 Yiya 的人;板子最後跑到哪去,他們之間會知道。研究室にはDigilent Artix-7 開発ボードが 3 枚——白いボード——あるはず。机の上に無ければ Tony に、あるいは Yiya に連絡が取れる人に聞くこと。どこへ行ったかは彼らが知っている。Seharusnya ada tiga papan pengembangan Digilent Artix-7 — yang berwarna putih — di lab. Kalau tidak ada di meja, tanyakan kepada Tony, atau siapa saja yang bisa menghubungi Yiya; di antara mereka pasti ada yang tahu papan itu berakhir di mana.

I will hand each of you a USB-to-TTL adapter — that is how the FPGA talks to your PC or laptop, and every task from 3 onward assumes one is plugged in. Three rules before it touches the board: cross TX and RX, tie the grounds together, and leave the adapter's VCC pin unconnected — the board powers itself, and 5 V from an adapter into a 3.3 V I/O bank is the standard way to lose a bank. If the adapter has a 3.3 V / 5 V jumper, set it to 3.3 V first. It appears as a COM port on Windows (CH340 or CP2102 driver) and as /dev/ttyUSB0 on Linux.我會發給每個人一條 USB 轉 TTL 轉接器——FPGA 就是靠它跟你的桌機或筆電溝通,第 3 題之後每一題都預設你手上有一條插著。接到板子之前先記三件事:TX 與 RX 要交叉、地要共接、轉接器的 VCC 腳不要接——板子自己有電源,把 5 V 從轉接器灌進 3.3 V 的 I/O bank,就是燒掉一整個 bank 的標準做法。如果轉接器上有 3.3 V/5 V 跳線,先切到 3.3 V。它在 Windows 上會出現成一個 COM 埠(CH340 或 CP2102 驅動),在 Linux 上是 /dev/ttyUSB0。USB-TTL 変換アダプタは全員に一本ずつ渡す——FPGA が PC やノートと話すのはこれ経由で、課題 3 以降はすべて手元にある前提だ。ボードにつなぐ前に三つ:TX と RX をクロスする、グラウンドを共通にする、アダプタの VCC ピンはつながない——ボードは自前で給電しており、アダプタの 5 V を 3.3 V の I/O バンクに入れるのはバンクを一つ壊す典型的な方法だ。3.3 V/5 V のジャンパがあるなら、先に 3.3 V にしておくこと。Windows では COM ポート(CH340 か CP2102 のドライバ)、Linux では /dev/ttyUSB0 として見える。Saya akan membagikan satu adapter USB-ke-TTL kepada setiap orang — lewat itulah FPGA berbicara dengan PC atau laptopmu, dan setiap tugas mulai dari nomor 3 mengandaikan ada satu yang tercolok. Tiga aturan sebelum benda itu menyentuh papan: silangkan TX dan RX, satukan ground, dan biarkan pin VCC adapter tidak tersambung — papan itu punya catu daya sendiri, dan 5 V dari adapter yang masuk ke bank I/O 3.3 V adalah cara baku untuk kehilangan satu bank. Kalau adapter punya jumper 3.3 V / 5 V, setel dulu ke 3.3 V. Ia muncul sebagai port COM di Windows (driver CH340 atau CP2102) dan sebagai /dev/ttyUSB0 di Linux.

CH340 · USB-to-TTL / UART adapter boardCH340 · USB 轉 TTL/UART 轉接板CH340 · USB-TTL/UART 変換ボードCH340 · papan adapter USB-ke-TTL / UARTshopee.tw ↗樂意創客官方店 · the same part I hand out — buy one here if you want a spare, or a second bench setup at home.樂意創客官方店 · 就是我發的那一款——想要備品,或在家再擺一套,可以自己買。樂意創客官方店 · 配っているのと同じ部品——予備が欲しいときや、自宅にもう一式組みたいときはここで買える。樂意創客官方店 · komponen yang sama dengan yang saya bagikan — beli di sini kalau mau cadangan, atau ingin menyiapkan satu set kedua di rumah.

Check the oscillator before you build anything. Every divisor on this sheet assumes a 50 MHz clock. The common Digilent Artix-7 boards ship a 100 MHz oscillator — read your board's reference manual, and if it says 100 MHz, double all of these: 動手做之前先確認振盪器頻率。本工作單上所有除數都假設 50 MHz 時脈。常見的 Digilent Artix-7 板子出廠是 100 MHz——請查你手上板子的 reference manual,如果是 100 MHz,下列數字全部乘二:作り始める前に発振器を確認すること。このシートの分周値はすべて 50 MHz クロック前提。一般的な Digilent Artix-7 ボードは 100 MHz 発振器を積んでいる——ボードのリファレンスマニュアルを読み、100 MHz なら以下をすべて 2 倍にする:Periksa osilatornya sebelum membangun apa pun. Semua pembagi pada lembar ini mengandaikan clock 50 MHz. Papan Digilent Artix-7 yang umum dikirim dengan osilator 100 MHz — baca reference manual papanmu, dan kalau tertulis 100 MHz, gandakan semua angka berikut:

0.5 Hz tick (task 1)0.5 Hz tick(第 1 題)0.5 Hz tick(課題 1)tick 0.5 Hz (tugas 1)
100e6 → 200e6, 28-bit
115200 baud divisor115200 baud 除數115200 baud 分周値pembagi baud 115200
434 → 868
16× RX tick16 倍取樣 tick16 倍サンプリング ticktick RX 16×
27 → 54
20 kHz PWM period20 kHz PWM 週期20 kHz PWM 周期periode PWM 20 kHz
2500 → 5000
20 ms servo frame20 ms 伺服框架20 ms サーボフレームframe servo 20 ms
1e6 → 2e6 counts
1.5 ms servo centre1.5 ms 伺服中位1.5 ms サーボ中立titik tengah servo 1.5 ms
75,000 → 150,000

Before you program the board — install the USB-JTAG cable driver燒錄之前 —— 先裝好 USB-JTAG 下載線驅動ボードに書き込む前に — USB-JTAG ケーブルドライバを入れるSebelum memprogram papan — pasang driver kabel USB-JTAG

Use Vivado 2019.2 — not the newest release. This sheet is written against Vivado 2019.2: the project layout and the .xdc constraints assume that version. Vivado upgrades a project the first time a newer release opens it, and the upgraded project will not open in 2019.2 again, so a classmate's newer install is not interchangeable with yours. Install 2019.2 (the free WebPACK edition covers the Artix-7) before you start.請使用 Vivado 2019.2,不要用最新版。這份工作單是以 Vivado 2019.2 為準寫的:專案結構與 .xdc 腳位約束都假設是這個版本。專案一旦被較新版的 Vivado 打開就會被升級,升級後的專案再也回不到 2019.2,所以同學那台較新的安裝並不能跟你的互換。開始之前請先裝 2019.2(免費的 WebPACK 版就涵蓋 Artix-7)。Vivado は 2019.2 を使うこと — 最新リリースではない。このシートは Vivado 2019.2 を前提に書かれている:プロジェクト構成と .xdc の制約は このバージョンを想定している。プロジェクトは新しいリリースで開いた時点で自動的に アップグレードされ、アップグレード後は 2019.2 では開けなくなるので、同級生の新しい環境と入れ替えて使うことはできない。 始める前に 2019.2(無償の WebPACK 版で Artix-7 は足りる)を入れること。Pakai Vivado 2019.2 — bukan rilis terbaru. Lembar ini ditulis untuk Vivado 2019.2: tata letak proyek dan constraint .xdc mengasumsikan versi itu. Vivado meng-upgrade proyek begitu dibuka oleh rilis yang lebih baru, dan proyek hasil upgrade tidak bisa dibuka lagi di 2019.2, jadi instalasi teman yang lebih baru tidak bisa dipertukarkan dengan punyamu. Pasang 2019.2 (edisi WebPACK gratis sudah mencakup Artix-7) sebelum mulai.

There is no separate "Artix-7 FPGA driver", so stop looking for one. The FPGA die is configured over JTAG and Windows never sees it. What Windows has to recognise is the USB-to-JTAG bridge chip on the Arty A7 — an FTDI part — and until that chip is bound to a driver, neither Vivado's Hardware Manager nor Digilent's djtgcfg can reach the board. "Installing the FPGA driver" means installing this cable driver, nothing else. 沒有一個叫「Artix-7 FPGA 驅動」的東西,不用再找了。FPGA 晶片本身是透過 JTAG 燒錄,Windows 從頭到尾看不到它。Windows 真正要認得的是 Arty A7 板上的 USB 轉 JTAG 橋接晶片——一顆 FTDI 的 IC——在這顆晶片綁好驅動之前,Vivado 的 Hardware Manager 和 Digilent 的 djtgcfg 都碰不到板子。所謂「裝 FPGA 驅動」,就是裝這條下載線的驅動,沒有別的。「Artix-7 FPGA ドライバ」という別物は存在しないので探すのはやめること。FPGA のダイは JTAG で書き込まれ、Windows からは一切見えない。Windows が認識しなければならないのは Arty A7 に載っている USB-JTAG ブリッジチップ——FTDI 製——で、これにドライバが結び付くまでは Vivado の Hardware Manager も Digilent の djtgcfg もボードに届かない。「FPGA ドライバを入れる」とはこのケーブルドライバを入れることであり、それ以外ではない。Tidak ada "driver FPGA Artix-7" yang terpisah, jadi berhenti mencarinya. Die FPGA dikonfigurasi lewat JTAG dan Windows tidak pernah melihatnya. Yang harus dikenali Windows adalah chip jembatan USB-ke-JTAG di Arty A7 — sebuah komponen FTDI — dan sampai chip itu terikat ke driver, baik Hardware Manager Vivado maupun djtgcfg dari Digilent tidak bisa menjangkau papan. "Memasang driver FPGA" berarti memasang driver kabel ini, tidak lebih.

Two ways to get there. Pick by what you need, not by which is shorter:有兩條路。依你需要什麼來選,不是選比較短的那條:方法は二つ。短い方ではなく、必要なものに合わせて選ぶこと:Ada dua jalan. Pilih berdasarkan apa yang kamu butuhkan, bukan mana yang lebih pendek:

A · Vivado cable driversA · Vivado 下載線驅動A · Vivado ケーブルドライバA · driver kabel Vivado
driver + synthesis + Hardware Manager驅動 + 合成 + Hardware Managerドライバ + 合成 + Hardware Managerdriver + sintesis + Hardware Manager
B · Digilent Adept 2 RuntimeB · Digilent Adept 2 RuntimeB · Digilent Adept 2 RuntimeB · Digilent Adept 2 Runtime
driver + djtgcfg only, no Vivado只有驅動 + djtgcfg,沒有 Vivadoドライバ + djtgcfg のみ、Vivado 無しhanya driver + djtgcfg, tanpa Vivado

Path B is not a substitute for Path A. It gives you the transport and a command-line programmer, and nothing that can turn Verilog into a bitstream. If you are going to build the tasks on this sheet you need Vivado, so you need Path A. 路線 B 不能取代路線 A。它只給你傳輸層和一個命令列燒錄工具,沒有任何東西能把 Verilog 變成 bitstream。既然你要做這份工作單上的題目,就需要 Vivado,也就需要路線 A。B は A の代わりにはならない。B が与えるのは通信路とコマンドラインの書き込みツールだけで、Verilog をビットストリームにするものは何も無い。このシートの課題を作るなら Vivado が要るので、A が要る。Jalur B bukan pengganti Jalur A. Ia memberimu transport dan pemrogram baris perintah, tetapi tidak ada apa pun yang bisa mengubah Verilog menjadi bitstream. Kalau kamu akan membangun tugas-tugas di lembar ini kamu butuh Vivado, jadi kamu butuh Jalur A.

Path A — Vivado cable drivers (Windows)路線 A —— Vivado 下載線驅動(Windows)A — Vivado ケーブルドライバ(Windows)Jalur A — driver kabel Vivado (Windows)

  1. Get the installer. Download the Vivado 2019.2 installer or install image from AMD's downloads page — that exact release, not the newest one on the page. The free WebPACK edition covers the Artix-7.拿到安裝程式。從 AMD 的下載頁抓 Vivado 2019.2 的安裝程式或安裝映像——就是這個版本,不是頁面上最新的那個。免費的 WebPACK 版就涵蓋 Artix-7。インストーラを入手する。AMD のダウンロードページから Vivado 2019.2 のインストーラまたはインストールイメージを取る——ページ上の最新版ではなく、このリリースを。無償の WebPACK 版で Artix-7 は足りる。Ambil installer-nya. Unduh installer atau image instalasi Vivado 2019.2 dari halaman unduhan AMD — rilis itu persis, bukan yang terbaru di halaman. Edisi WebPACK gratis sudah mencakup Artix-7.
  2. The installer's checkbox is a shortcut, not a guarantee. During installation Vivado offers an "install cable drivers" option. Take it, but do not trust it: for years it has silently failed for some people — the box shows unchecked again, or the driver never binds. Step 3 is the reliable method and works whether or not you ticked the box.安裝程式裡的勾選框是捷徑,不是保證。安裝過程中 Vivado 會提供「install cable drivers」的選項。勾起來,但不要信它:多年來它對某些人會默默失敗——勾選框又變回沒勾,或驅動根本沒綁上。第 3 步才是可靠的方法,不管你有沒有勾那個框都適用。インストーラのチェックボックスは近道であって保証ではない。インストール中に Vivado は「install cable drivers」の選択肢を出す。チェックはするが信用しないこと:何年も前から一部の環境で黙って失敗する——チェックが外れて表示される、あるいはドライバが結び付かない。手順 3 が確実な方法で、チェックの有無に関係なく使える。Kotak centang di installer adalah jalan pintas, bukan jaminan. Selama instalasi Vivado menawarkan opsi "install cable drivers". Centang, tetapi jangan percaya begitu saja: selama bertahun-tahun ia gagal diam-diam pada sebagian orang — kotaknya tampil tidak tercentang lagi, atau driver-nya tidak pernah terikat. Langkah 3 adalah cara yang andal dan bekerja terlepas dari apakah kamu mencentang kotak itu.
  3. Run the driver script yourself, as Administrator. Open Command Prompt or PowerShell with Run as administrator, then:自己以系統管理員身分跑驅動安裝腳本。用以系統管理員身分執行開啟命令提示字元或 PowerShell,然後:ドライバスクリプトを自分で、管理者として実行する。コマンドプロンプトか PowerShell を管理者として実行で開き、次を実行:Jalankan skrip driver sendiri, sebagai Administrator. Buka Command Prompt atau PowerShell dengan Run as administrator, lalu:
    :: replace the two paths with your own install directory
    cd C:\Xilinx\Vivado\2019.2\data\xicom\cable_drivers\nt64
    install_drivers_wrapper.bat C:\Xilinx\Vivado\2019.2\install_log
    The single argument is the folder for the install log; leave it out and the script writes install_drivers_wrapper.log into the Vivado install directory instead. Old forum posts show a three-argument form from legacy releases — ignore them, current releases take only the log directory. The script installs both the Digilent components and the generic Xilinx Platform Cable (pcusb) driver.唯一的參數是安裝紀錄要寫到哪個資料夾;不給的話,腳本會把 install_drivers_wrapper.log 寫進 Vivado 的安裝目錄。舊的論壇文章會出現三個參數的寫法,那是舊版的——不用理,現行版本只吃紀錄資料夾這一個參數。這支腳本會同時裝 Digilent 元件和通用的 Xilinx Platform Cable(pcusb)驅動。唯一の引数はインストールログを書き出すフォルダで、省略するとスクリプトは install_drivers_wrapper.log を Vivado のインストールディレクトリに書く。古いフォーラム投稿には旧リリース由来の三引数形式が出てくるが無視すること。現行リリースはログディレクトリだけを取る。このスクリプトは Digilent のコンポーネントと汎用の Xilinx Platform Cable(pcusb)ドライバの両方を入れる。Satu-satunya argumen adalah folder untuk log instalasi; kalau dihilangkan, skrip menulis install_drivers_wrapper.log ke direktori instalasi Vivado. Postingan forum lama menunjukkan bentuk tiga argumen dari rilis lawas — abaikan, rilis terkini hanya menerima direktori log. Skrip ini memasang komponen Digilent sekaligus driver generik Xilinx Platform Cable (pcusb).
  4. Replug and look in Device Manager. Unplug the Arty A7's USB cable, plug it back in, and open Device Manager. The board should now appear as a JTAG/USB device — no "Unknown device", no yellow warning icon.重插一次,看裝置管理員。把 Arty A7 的 USB 線拔掉再插回去,打開裝置管理員。板子現在應該以 JTAG/USB 裝置出現——沒有「未知的裝置」,沒有黃色驚嘆號。抜き差ししてデバイスマネージャーを見る。Arty A7 の USB ケーブルを抜いて挿し直し、デバイスマネージャーを開く。ボードが JTAG/USB デバイスとして見えているはず——「不明なデバイス」も黄色い警告アイコンも無いこと。Colok ulang dan lihat Device Manager. Cabut kabel USB Arty A7, colok kembali, dan buka Device Manager. Papan kini seharusnya muncul sebagai perangkat JTAG/USB — tidak ada "Unknown device", tidak ada ikon peringatan kuning.
  5. Confirm the tool sees it. In Vivado: Open Hardware Manager → Open Target → Auto Connect, and the Arty A7 should be listed under the local server. Or from a prompt run djtgcfg enum — the Vivado driver install normally brings the Adept components with it; if the command is missing, Path B installs it.確認工具看得到它。在 Vivado 裡:Open Hardware Manager → Open Target → Auto Connect,Arty A7 應該會列在本機伺服器底下。或者在命令列跑 djtgcfg enum——Vivado 的驅動安裝通常會連 Adept 元件一起帶進來;如果找不到這個指令,走路線 B 就會裝到。ツールから見えることを確認する。Vivado で Open Hardware Manager → Open Target → Auto Connect を実行すると、ローカルサーバの下に Arty A7 が並ぶはず。あるいはプロンプトから djtgcfg enum を実行する——Vivado のドライバインストールは通常 Adept のコンポーネントも一緒に入れる。コマンドが見つからなければ B の手順で入る。Pastikan alatnya melihat papan. Di Vivado: Open Hardware Manager → Open Target → Auto Connect, dan Arty A7 seharusnya tercantum di bawah server lokal. Atau dari prompt jalankan djtgcfg enum — instalasi driver Vivado biasanya membawa komponen Adept bersamanya; kalau perintahnya tidak ada, Jalur B memasangnya.

Path B — Digilent Adept 2 Runtime only (no Vivado)路線 B —— 只裝 Digilent Adept 2 Runtime(不裝 Vivado)B — Digilent Adept 2 Runtime のみ(Vivado 無し)Jalur B — hanya Digilent Adept 2 Runtime (tanpa Vivado)

For a laptop that only has to detect the board or load a .bit file someone else built — bring-up checks, a demo machine — you can skip Vivado entirely.如果某台筆電只需要認得板子,或載入別人做好的 .bit 檔——例如做開機檢查、當展示機——可以完全不裝 Vivado。ボードの検出か、他人が作った .bit の書き込みだけが目的のノート——立ち上げ確認やデモ機——なら、Vivado は丸ごと省ける。Untuk laptop yang hanya perlu mendeteksi papan atau memuat berkas .bit buatan orang lain — pemeriksaan bring-up, mesin demo — kamu bisa melewatkan Vivado sepenuhnya.

  1. Download the Adept 2 Runtime from Digilent, not from AMD — the link is below.下載 Adept 2 Runtime,從 Digilent 拿,不是 AMD——連結在下面。Adept 2 Runtime を AMD ではなく Digilent からダウンロードする——リンクは下にある。Unduh Adept 2 Runtime dari Digilent, bukan dari AMD — tautannya di bawah.
  2. Install the Windows package. It brings the USB/JTAG driver for Digilent boards, the Adept runtime libraries and the command-line utilities, djtgcfg among them.安裝 Windows 版套件。它會裝上 Digilent 板子用的 USB/JTAG 驅動、Adept 執行期函式庫,以及包含 djtgcfg 在內的命令列工具。Windows 用パッケージをインストールする。Digilent ボード用の USB/JTAG ドライバ、Adept ランタイムライブラリ、そして djtgcfg を含むコマンドラインツールが入る。Pasang paket Windows-nya. Ia membawa driver USB/JTAG untuk papan Digilent, pustaka runtime Adept, dan utilitas baris perintah, termasuk djtgcfg.
  3. Verify from a command prompt. A working install answers like this:在命令提示字元裡驗證。裝好的話會這樣回你:コマンドプロンプトから確認する。正しく入っていればこう返ってくる:Verifikasi dari command prompt. Instalasi yang bekerja menjawab seperti ini:
    > djtgcfg enum
    Found 1 device(s)
    Device: ArtyA7
      Product Name:   Digilent Arty A7 - 35T
      User Name:      ArtyA7
      Serial Number:  <serial>

What this path cannot do: synthesise, implement or generate a bitstream — you still need Vivado, or a pre-built .bit, for that — and there is no Hardware Manager GUI. Programming is the command line only:這條路做不到的事:合成、實作、產生 bitstream——這些還是要 Vivado,或是一個做好的 .bit——而且沒有 Hardware Manager 的圖形介面。燒錄只能靠命令列:この方法でできないこと:合成・配置配線・ビットストリーム生成——これには依然 Vivado か、出来合いの .bit が要る——そして Hardware Manager の GUI も無い。書き込みはコマンドラインだけ:Yang tidak bisa dilakukan jalur ini: sintesis, implementasi, atau membangkitkan bitstream — untuk itu kamu tetap butuh Vivado, atau .bit yang sudah jadi — dan tidak ada GUI Hardware Manager. Pemrograman hanya lewat baris perintah:

djtgcfg prog -d ArtyA7 -i 0 -f design.bit
Digilent · Adept 2 Runtime downloadDigilent · Adept 2 Runtime 下載Digilent · Adept 2 Runtime ダウンロードDigilent · unduhan Adept 2 Runtimedigilent.com ↗Runtime and utilities for Windows. Install only the Runtime — the Adept "System" GUI package is not needed for the Arty A7.Windows 用的執行期與工具程式。只裝 Runtime 就好——Adept 的「System」圖形介面套件對 Arty A7 用不到。Windows 用のランタイムとユーティリティ。Runtime だけ入れればよい——Adept の「System」GUI パッケージは Arty A7 には不要。Runtime dan utilitas untuk Windows. Pasang Runtime saja — paket GUI "System" Adept tidak diperlukan untuk Arty A7.

When it does not work不成功的時候うまくいかないときSaat tidak berhasil

  • "Unknown device" in Device Manager after plugging in. The cable driver is not bound. Re-run step 3 of Path A as Administrator, then unplug and replug.插上去之後裝置管理員顯示「未知的裝置」。下載線驅動沒綁上。以系統管理員身分重跑路線 A 的第 3 步,然後拔掉重插。接続後にデバイスマネージャーで「不明なデバイス」。ケーブルドライバが結び付いていない。A の手順 3 を管理者として再実行し、抜き差しする。"Unknown device" di Device Manager setelah dicolok. Driver kabel belum terikat. Jalankan ulang langkah 3 Jalur A sebagai Administrator, lalu cabut dan colok kembali.
  • Vivado shows "localhost Connected" but no hardware target. Almost always a driver-binding problem, not a bad cable or a dead board. Re-running the driver installer as Administrator clears most cases.Vivado 顯示「localhost Connected」,但底下沒有硬體目標。幾乎都是驅動沒綁好,不是線壞了或板子掛了。以系統管理員身分重跑一次驅動安裝程式,大多數情況就解決了。Vivado に「localhost Connected」と出るがハードウェアターゲットが無い。ほぼ確実にドライバの結び付きの問題で、ケーブルやボードの故障ではない。ドライバインストーラを管理者として再実行すればたいてい直る。Vivado menampilkan "localhost Connected" tetapi tidak ada target perangkat keras. Hampir selalu masalah pengikatan driver, bukan kabel rusak atau papan mati. Menjalankan ulang installer driver sebagai Administrator menyelesaikan sebagian besar kasus.
  • djtgcfg enum finds nothing. Make sure the USB cable carries data — many phone cables are charge-only — and try another port. USB 3.0 hubs have occasionally broken enumeration with older Adept versions; a port on the machine itself is the safer test.djtgcfg enum 什麼都找不到。確認 USB 線能傳資料——很多手機線只能充電——並換一個埠試試。USB 3.0 集線器偶爾會讓舊版 Adept 列舉失敗;直接插機器本體的埠比較保險。djtgcfg enum が何も見つけない。USB ケーブルがデータ対応か確認する——スマホ用ケーブルには充電専用が多い——別のポートも試すこと。USB 3.0 ハブは古い Adept で列挙に失敗することがあるので、本体のポートで試すのが確実。djtgcfg enum tidak menemukan apa pun. Pastikan kabel USB-nya membawa data — banyak kabel ponsel hanya untuk pengisian — dan coba port lain. Hub USB 3.0 kadang merusak enumerasi pada versi Adept yang lebih lama; port di mesin itu sendiri adalah uji yang lebih aman.
  • The log says windrvr6 is "not installed". Normal on Windows 10 and 11. Current Vivado packages install a pcusb-based driver; windrvr6 belongs to Windows 7-era installs and is expected to be absent.紀錄檔寫 windrvr6「not installed」。在 Windows 10、11 上這是正常的。現行 Vivado 套件裝的是以 pcusb 為基礎的驅動;windrvr6 是 Windows 7 時代的東西,本來就該不存在。ログに windrvr6 が「not installed」と出る。Windows 10/11 では正常。現行の Vivado パッケージは pcusb ベースのドライバを入れる。windrvr6 は Windows 7 時代のもので、無いのが当然。Log mengatakan windrvr6 "not installed". Normal di Windows 10 dan 11. Paket Vivado terkini memasang driver berbasis pcusb; windrvr6 milik instalasi era Windows 7 dan memang diharapkan tidak ada.
Install Vivado cable drivers (admin shell)裝 Vivado 下載線驅動(管理員 shell)Vivado ケーブルドライバ導入(管理者 shell)Pasang driver kabel Vivado (shell admin)
install_drivers_wrapper.bat <log_dir>
Run it from在哪個目錄執行実行するディレクトリJalankan dari
…\data\xicom\cable_drivers\nt64
Check the board is seen確認板子被偵測到ボード検出の確認Periksa papan terdeteksi
djtgcfg enum
Program a bitstream from the CLI用命令列燒 bitstreamCLI からビットストリーム書き込みProgram bitstream dari CLI
djtgcfg prog -d ArtyA7 -i 0 -f x.bit

How to buy the materials you need要用的材料怎麼買必要な材料の買い方Cara membeli bahan yang kamu butuhkan

The boards and the adapter are lent to you, not given. Everything else on this sheet you buy yourself, and it is worth doing: one breadboard, a handful of jumper wires and a spare adapter is the difference between debugging only at the bench and debugging at home at 1 a.m. In Kaohsiung the place to buy them is 中將電子. 板子和轉接器是借你的,不是給你的。這份工作單上其他東西都要自己買,而且值得買:一塊麵包板、一把杜邦線、一條備用轉接器,決定了你只能在實驗桌上除錯,還是凌晨一點在家也能除錯。在高雄,要買這些就去中將電子。ボードとアダプタは貸与で、譲渡ではない。このシートに出てくるそれ以外のものは自分で買う——買う価値がある。ブレッドボード一枚、ジャンパ線ひと束、予備のアダプタ一本があるかどうかで、研究室の机でしかデバッグできないか、深夜一時に自宅でもできるかが変わる。高雄でそれを買う場所は中將電子だ。Papan dan adapternya dipinjamkan kepadamu, bukan diberikan. Semua yang lain di lembar ini kamu beli sendiri, dan itu sepadan: satu breadboard, segenggam kabel jumper, dan satu adapter cadangan adalah pembeda antara hanya bisa men-debug di meja lab dan bisa men-debug di rumah pada pukul satu pagi. Di Kaohsiung, tempat membelinya adalah 中將電子.

中將電子實業有限公司 has been on 長明街 since August 1977, and in 1993 it pulled out the service counters and reopened as an open warehouse floor — the largest electronic-parts store in southern Taiwan. You walk the aisles, take the parts off the shelf yourself, and pay at the front. It is a short walk from 高雄車站, so from the lab it is 西子灣 → 美麗島 → red line → 高雄車站. 中將電子實業有限公司從 1977 年 8 月就在長明街,1993 年拆掉櫃台,改成開放式大賣場——南台灣最大的電子零件專賣場。你自己走走道、自己從架上拿零件、到前面結帳。它離高雄車站走路就到,所以從實驗室出發是:西子灣 → 美麗島 → 轉紅線 → 高雄車站。中將電子實業有限公司は 1977 年 8 月から長明街にあり、1993 年にカウンターを撤去して開放型の大型売場として開き直した——南台湾で最大の電子部品売場である。自分で通路を歩き、自分で棚から部品を取り、前のレジで払う。高雄車站から歩いてすぐなので、研究室からは 西子灣 → 美麗島 → 紅線 → 高雄車站。中將電子實業有限公司 sudah berada di 長明街 sejak Agustus 1977, dan pada 1993 mereka membongkar meja layanannya lalu dibuka kembali sebagai lantai gudang terbuka — toko komponen elektronik terbesar di Taiwan selatan. Kamu berjalan sendiri di antara rak, mengambil komponennya sendiri, lalu membayar di depan. Jaraknya dekat dengan jalan kaki dari 高雄車站, jadi dari lab: 西子灣 → 美麗島 → jalur merah → 高雄車站.

Read this before you plan a trip around their website. 中將電子 has a web presence but no web store: no catalogue, no stock levels, no cart. What exists is a Facebook page and a LINE official account, plus a web66 詢價 page at 1207833627324.web66.tw — that is a contact form, not a shop. Its trade listing reads 電子器材、電子設備批發 and gives the company address on 建國二路, one street over from the shop floor, so the address you find online is not always the door you want. The working method is: message the LINE account with a photo of the part or its part number, ask 有現貨嗎?多少錢?, and go in once they answer. Never conclude from the website that they do or do not carry something. 在你照著他們的網站安排行程之前,先看這一段。中將電子有網路門面,但沒有網路商店:沒有型錄、沒有庫存數量、沒有購物車。實際存在的是一個 Facebook 粉絲頁、一個 LINE 官方帳號,加上一頁 web66 詢價官網 1207833627324.web66.tw——那是聯絡表單,不是商店。上面的營業項目寫「電子器材、電子設備批發」,登記地址在建國二路,跟賣場只隔一條街,所以你在網路上查到的地址不一定是你要走進去的那個門。正確做法是:用 LINE 傳零件照片或料號過去,問有現貨嗎?多少錢?,等回覆再跑一趟。絕對不要從網站去推論他們有沒有賣某樣東西。サイトを見て予定を立てる前に、ここを読むこと。中將電子はウェブ上の窓口はあるが、ウェブストアは無い:カタログも在庫数も買い物カゴも無い。あるのは Facebook ページと LINE 公式アカウント、それに web66 の見積依頼ページ 1207833627324.web66.tw ——これは問い合わせフォームであって店ではない。営業項目は「電子器材、電子設備批發」、登記住所は売場から一本隣の建國二路になっているので、ネットで出てくる住所が入りたい入口とは限らない。正しい手順はこうだ:LINE に部品の写真か型番を送り、有現貨嗎?多少錢?(在庫はありますか、いくらですか)と聞き、返事が来てから行く。サイトを根拠に取扱いの有無を判断してはいけない。Baca ini sebelum kamu menyusun rencana berdasarkan situs mereka. 中將電子 punya kehadiran di web, tetapi tidak punya toko online: tidak ada katalog, tidak ada jumlah stok, tidak ada keranjang. Yang ada adalah halaman Facebook dan akun resmi LINE, ditambah satu halaman permintaan harga (詢價) di web66, 1207833627324.web66.tw — itu formulir kontak, bukan toko. Kategori usahanya tertulis 電子器材、電子設備批發 dan alamat terdaftarnya di 建國二路, satu jalan dari lantai tokonya, jadi alamat yang kamu temukan online belum tentu pintu yang kamu tuju. Cara kerjanya: kirim foto komponen atau nomor partnya ke akun LINE, tanyakan 有現貨嗎?多少錢? ("ada stok? berapa harganya?"), dan datang setelah mereka menjawab. Jangan pernah menyimpulkan dari situsnya bahwa mereka menjual atau tidak menjual sesuatu.

LINE official account · @alo0446zLINE 官方帳號 · @alo0446zLINE 公式アカウント · @alo0446zAkun resmi LINE · @alo0446zpage.line.me ↗中將電子實業有限公司 · the fast channel. Send a photo or a part number and ask for stock and price before you spend an hour on the MRT.中將電子實業有限公司 · 最快的管道。傳張照片或料號過去,先問有沒有貨、多少錢,再決定要不要花一小時搭捷運。中將電子實業有限公司 · 一番速い窓口。写真か型番を送って在庫と値段を先に聞けば、MRT に一時間かけずに済む。中將電子實業有限公司 · saluran tercepat. Kirim foto atau nomor part dan tanyakan stok serta harganya sebelum kamu habiskan sejam di MRT. Facebook · 中將電子Facebook · 中將電子Facebook · 中將電子Facebook · 中將電子facebook.com ↗Where the store notices go. Published hours are 09:00–21:30 daily, but national-holiday hours are announced only here and on LINE — check before a long-weekend trip.店家公告都發在這裡。公布的營業時間是每天 09:00–21:30,但國定假日的時間只在這裡和 LINE 上公告——連假要去之前先看一下。店の告知はここに出る。公表の営業時間は毎日 09:00–21:30 だが、祝日の時間はここと LINE でしか告知されない——連休に行く前に確認すること。Pengumuman toko dimuat di sini. Jam yang dipublikasikan 09:00–21:30 setiap hari, tetapi jam pada hari libur nasional hanya diumumkan di sini dan di LINE — periksa sebelum pergi di akhir pekan panjang.

Ask at the counter in Mandarin or Taiwanese — asking in English will slow you down. The names that get you the parts on this sheet: 麵包板 (breadboard), 杜邦線 母對母/公對母 (jumper wires, F–F / M–F), 排針 2.54mm (headers), 電阻 220Ω/1kΩ (resistors), LED, 直流減速馬達 (geared DC motor), 馬達驅動模組 L298N/TB6612 (motor driver), SG90 伺服馬達 (servo). 在櫃台用國語或台語問——用英文只會拖慢你。能換到這份工作單上零件的名字:麵包板、杜邦線 母對母/公對母、排針 2.54mm、電阻 220Ω/1kΩ、LED、直流減速馬達、馬達驅動模組 L298N/TB6612、SG90 伺服馬達。レジでは中国語(華語)か台湾語で聞くこと——英語で聞くと話が遅くなる。このシートの部品にたどり着く名前:麵包板(ブレッドボード)、杜邦線 母對母/公對母(ジャンパ線 メス–メス/オス–メス)、排針 2.54mm(ピンヘッダ)、電阻 220Ω/1kΩ(抵抗)、LED、直流減速馬達(ギヤード DC モータ)、馬達驅動模組 L298N/TB6612(モータドライバ)、SG90 伺服馬達(サーボ)。Tanyakan di kasir dalam bahasa Mandarin atau Hokkien Taiwan — bertanya dalam bahasa Inggris hanya memperlambatmu. Nama-nama yang akan membawamu ke komponen di lembar ini: 麵包板 (breadboard), 杜邦線 母對母/公對母 (kabel jumper F–F / M–F), 排針 2.54mm (pin header), 電阻 220Ω/1kΩ (resistor), LED, 直流減速馬達 (motor DC bergigi), 馬達驅動模組 L298N/TB6612 (driver motor), SG90 伺服馬達 (servo).

What the invoice is actually for. You are not meant to end up carrying the cost of lab materials yourself — it is paid back to you out of the lab's research budget at the university, and the invoice is the one document that lets that happen. The accounting office reimburses against a 三聯式 uniform invoice made out to the university itself — 國立中山大學, 統一編號 76211194 — because only that can be entered in the books as a university purchase. A 二聯式 invoice or a plain 收據 is issued to you, so there is nothing for the school to reimburse and the cost stays yours. So at the counter, before they ring it up, say 要開三聯式發票 and give that 統編; a swap afterwards is a favour, not a right. Hand the invoice to me together with the part — a lost invoice is an unreimbursed purchase — and clear the purchase with me before you spend, not after, because the budget has to have room for it first. 發票到底是拿來做什麼的。實驗室材料費不該由你自己吸收——這筆錢會從學校的實驗室研究經費核銷回來給你,而發票就是唯一能讓這件事成立的憑證。會計室是憑三聯式統一發票報帳,而且發票要開給學校本身——國立中山大學,統一編號 76211194——因為只有這樣,帳上才記得成一筆學校的採購。二聯式發票或收據是開給你的,學校沒有東西可以核銷,這筆錢就變成你自己出。所以在櫃台結帳之前就要說「要開三聯式發票」,並把統編給他;事後想換是人情,不是你的權利。發票請跟零件一起交給我——發票掉了,這筆就報不了——而且要在花錢之前跟我說,不是花完才說,因為經費要先有空間。發票は何のためにあるのか。研究室の材料費を最後まで自分で負担する筋合いはない——この費用は大学にある研究室の研究費から精算されて戻ってくるし、發票はそれを成立させる唯一の証憑だ。会計課が精算に使うのは三聯式の統一發票で、宛先は大学そのもの——國立中山大學、統一編號 76211194——でなければならない。そう書かれて初めて、帳簿上「大学の購入」として記録できるからだ。二聯式の發票や收據はあなた宛なので、大学には精算する対象が無く、費用はあなたの負担のままになる。だからレジを通す前に「要開三聯式發票」と言い、その統一編號を伝えること。後から差し替えてもらうのは好意であって権利ではない。發票は部品と一緒に私に渡すこと——發票を失くせば、その分は精算できない——そして使った後ではなく、使う前に私に確認すること。先に予算の枠が必要だからだ。Untuk apa sebenarnya fakturnya. Kamu tidak seharusnya akhirnya menanggung sendiri biaya bahan lab — biaya itu dibayarkan kembali kepadamu dari anggaran riset lab di universitas, dan faktur adalah satu-satunya dokumen yang memungkinkan hal itu. Bagian keuangan mengganti biaya berdasarkan faktur resmi 三聯式 yang dibuat atas nama universitas itu sendiri — 國立中山大學, 統一編號 76211194 — karena hanya itu yang bisa dicatat dalam pembukuan sebagai pembelian universitas. Faktur 二聯式 atau 收據 biasa diterbitkan atas nama kamu, jadi tidak ada yang bisa diganti oleh kampus dan biayanya tetap menjadi bebanmu. Maka di kasir, sebelum mereka menghitung, katakan 要開三聯式發票 dan berikan 統一編號 itu; menukarnya belakangan adalah kebaikan hati mereka, bukan hakmu. Serahkan fakturnya kepada saya bersama komponennya — faktur yang hilang berarti pembelian yang tidak diganti — dan bicarakan dulu dengan saya sebelum belanja, bukan sesudahnya, karena anggarannya harus punya ruang lebih dahulu.

Shop floor賣場売場Lantai toko
高雄市三民區長明街 247 號
Phone電話電話Telepon
07-235-4786
Hours營業時間営業時間Jam buka
09:00 – 21:30
From the lab從實驗室出發研究室からDari lab
西子灣 → 美麗島 → 高雄車站
Online cart線上購物車オンラインカートKeranjang online
none — LINE, or walk in沒有 —— 用 LINE,或直接走進去無し — LINE か店頭tidak ada — LINE, atau datang langsung
Invoice to發票開給發票の宛先Faktur atas nama
三聯式 · 國立中山大學 · 統編 76211194
Seller, registered as賣方登記名稱売主の登記名Penjual, terdaftar sebagai
中將電子實業有限公司 · 統編 86900206

How to hand it in — all three parts, every task怎麼交 —— 每一題都要三樣提出方法 — 各課題につき 3 点すべてCara mengumpulkannya — ketiga bagian, untuk setiap tugas

  1. A testbench. Simulate the module and show the waveform that proves the behaviour — the exact signals and the exact moment named in that task's Done when list, not a screenshot of the whole run. 一個 testbench。模擬你的模組,並秀出能證明行為的波形——要正好是該題完成條件裡點名的訊號與時間點,不是整段模擬的截圖。testbench。モジュールをシミュレーションし、動作を証明する波形を示すこと——その課題の完了条件で名指しされた信号とその瞬間であって、実行全体のスクリーンショットではない。Sebuah testbench. Simulasikan modulnya dan tunjukkan bentuk gelombang yang membuktikan perilakunya — sinyal yang tepat dan saat yang tepat seperti disebut pada daftar Selesai bila tugas itu, bukan tangkapan layar seluruh simulasi.
  2. A video on YouTube. Record the hardware doing it, upload it (unlisted is fine) and hand in the link. A simulation that passes while the board does nothing is not a finished task. 一支 YouTube 影片。拍下硬體實際運作,上傳(設不公開即可),把連結交上來。模擬過了但板子沒動,不算做完。YouTube の動画。ハードウェアが実際に動いている様子を撮影してアップロードし(限定公開で可)、リンクを提出する。シミュレーションが通ってもボードが動かなければ課題は完了ではない。Sebuah video di YouTube. Rekam perangkat kerasnya saat bekerja, unggah (unlisted tidak masalah) dan kumpulkan tautannya. Simulasi yang lolos sementara papannya diam bukanlah tugas yang selesai.
  3. A live demo. If I am in the lab, run it on your own host and walk me through it there. If I am not, make an appointment and demo it over Google Meet with your screen shared — same thing, same questions. 一次現場展示。我人在實驗室的話,就用你自己的電腦跑給我看,當場講解。我不在的話,跟我約時間,用 Google Meet 分享螢幕展示——一樣的流程,一樣會問問題。ライブデモ。私が研究室にいるときは、自分のホストで動かして目の前で説明すること。いないときはアポイントを取り、Google Meet で画面共有してデモする——内容も質問も同じ。Demo langsung. Kalau saya ada di lab, jalankan di host-mu sendiri dan jelaskan langsung di sana. Kalau saya tidak ada, buat janji dan demokan lewat Google Meet dengan layar dibagikan — sama saja, pertanyaannya juga sama.

Section 01 · 10 tasks · 51 checkpoints · 161 points第 01 章 · 10 題 · 51 個檢查點 · 共 161 分セクション 01 · 10 課題 · 51 チェックポイント · 合計 161 点Bagian 01 · 10 tugas · 51 checkpoint · 161 poin

FPGA Starter HomeworkFPGA 入門作業FPGA 入門課題Tugas Awal FPGA

Warm-up builds that walk from a counter blinking on the board's LEDs up to a motor turning under duty-cycle control, then hand the host side to Python. Each one adds a single new idea to the thing you built before it. 從板子上 LED 閃爍的計數器一路做到用工作週期控制轉動的馬達,最後把主機端交給 Python。每一題都只在前一題的基礎上加入一個新觀念。ボードの LED を光らせるカウンタからデューティ比で回るモータまで進み、最後にホスト側を Python へ渡す。各課題は前の課題に新しい考え方を一つだけ足していく。Latihan pemanasan yang berjalan dari pencacah yang mengedipkan LED di papan sampai motor yang berputar di bawah kendali duty cycle, lalu menyerahkan sisi host kepada Python. Masing-masing hanya menambahkan satu gagasan baru pada apa yang sudah kamu bangun sebelumnya.

FabricFPGA 端FPGA 側Sisi FPGA
Verilog · Quartus or Vivado
Host主機端ホスト側Sisi host
LabVIEW or Python
System clock系統時脈システムクロックClock sistem
50 MHz
Serial link串列連線シリアル接続Sambungan serial
115200 8N1

Before the first build, read the Pre-request section above: the boards and the USB-to-TTL adapter you are lent, the oscillator check that decides every divisor below, the USB-JTAG cable driver, where to buy the rest of the parts, and the three things every hand-in has to carry.動手做第一題之前,先讀上方的事前準備一節:借給你的板子和 USB 轉 TTL 轉接器、決定下面每一個除數的振盪器確認、USB-JTAG 下載線驅動、其餘材料去哪裡買,以及每一次繳交都必須有的三樣東西。最初のビルドに入る前に上の事前準備の節を読むこと:貸し出すボードと USB-TTL 変換アダプタ、以下のすべての分周値を左右する発振器の確認、USB-JTAG ケーブルドライバ、残りの部品をどこで買うか、そして提出物に必ず要る 3 点。Sebelum build pertama, baca bagian Prasyarat di atas: papan dan adapter USB-ke-TTL yang dipinjamkan, pemeriksaan osilator yang menentukan setiap pembagi di bawah, driver kabel USB-JTAG, di mana membeli sisa komponennya, dan tiga hal yang harus ada pada setiap pengumpulan.

8 pts分点poin1FIRST LIGHT

Count on the LEDs, and watch it wrap用 LED 數數,並看著它繞回 0LED でカウントし、ラップするのを見るMencacah di LED, dan mengamati saat ia berputar kembali

  • Verilog
  • Counter
  • Clock enable
  • Pin constraints

“use the led on dev. board to show the output of counter and wrap” ↳ added as the warm-up

The first thing that has to work: a bitstream on the board, pins assigned correctly, and something moving. Run a free counter, put it on the LEDs, and make the wrap from 255 back to 0 visible as its own event rather than something you infer. 第一件必須成功的事:bitstream 燒進板子、腳位指定正確、而且看得到東西在動。跑一個自由計數器,把它接到 LED 上,並讓 255 繞回 0 這件事本身變成看得見的事件,而不是用推的。最初に動かなければならないもの:ボードに書き込まれたビットストリーム、正しく割り当てられたピン、そして何かが動いていること。フリーランのカウンタを走らせて LED に出し、255 から 0 へのラップを推測ではなく目に見えるイベントにする。Hal pertama yang harus jalan: bitstream di papan, pin yang ditetapkan dengan benar, dan sesuatu yang bergerak. Jalankan pencacah bebas, tampilkan di LED, dan buat perputaran dari 255 kembali ke 0 terlihat sebagai kejadian tersendiri, bukan sesuatu yang hanya kamu simpulkan.

50 MHz is far too fast to watch, so the counter does not run on every clock — it runs on a tick. One clock, one enable: that habit is the reason this task comes before everything else. 50 MHz 快到根本看不見,所以計數器不是每個時脈都走——它是靠 tick 走。單一時脈、單一 enable:這個習慣就是這題排在最前面的理由。50 MHz は速すぎて見えないので、カウンタは毎クロックではなく tick で進む。クロックは一つ、イネーブルは一つ——この習慣こそ、この課題が最初に来る理由だ。50 MHz jauh terlalu cepat untuk diamati, jadi pencacahnya tidak berjalan pada setiap clock — ia berjalan pada sebuah tick. Satu clock, satu enable: kebiasaan itulah alasan tugas ini datang sebelum yang lain.

// one clock, one enable — never a counter bit as a clock
wire tick = (pre == DIV-1);   // 0.5 Hz
if (tick) cnt <= cnt + 1'b1;  // 8-bit, wraps by itself

Target numbers目標數字目標値Angka target

Tick ratetick 頻率tick レートLaju tick
0.5 Hz → 1 count / 2 s
Prescale divisor前置除數プリスケール分周値Pembagi prescale
50e6 / 0.5 = 100,000,000
Prescaler width前置計數器位寬プリスケーラ幅Lebar prescaler
27 bits (2^27 > 1e8)
Counter
8 bits → 256 states
Wrap period繞回週期ラップ周期Periode perputaran
512 s = 8 min 32 s
Wrap flash繞回閃燈ラップ点灯Kedip saat berputar
1 tick = 2 s

Traps陷阱落とし穴Jebakan

  • Never write always @(posedge cnt[24]). A counter bit used as a clock is a ripple clock: it works on the bench, and it makes every timing report after it meaningless. Use a clock enable.絕對不要寫 always @(posedge cnt[24])。把計數器的某個位元拿來當時脈就是 ripple clock:在桌上會動,但之後每一份 timing report 都失去意義。請改用 clock enable。always @(posedge cnt[24]) と書いてはいけない。カウンタのビットをクロックに使うのはリップルクロックで、机の上では動くがそれ以降のタイミングレポートをすべて無意味にする。クロックイネーブルを使うこと。Jangan pernah menulis always @(posedge cnt[24]). Bit pencacah yang dipakai sebagai clock adalah ripple clock: ia jalan di meja praktik, dan membuat setiap laporan timing setelahnya tidak bermakna. Pakai clock enable.
  • Most boards wire LEDs active low. All eight stuck on usually means a missing ~, not a dead board.多數板子的 LED 是低電位點亮。八顆全亮通常是少了一個 ~,不是板子壞了。多くのボードで LED はアクティブロー配線。8 個とも点きっぱなしなら、たいていはボードの故障ではなく ~ の書き忘れ。Kebanyakan papan memasang LED secara active low. Kedelapan LED yang menyala terus biasanya berarti ada ~ yang hilang, bukan papan yang mati.
  • The carry-out is one clock wide — 20 ns. Stretch it to a full tick or you will never see the wrap.進位輸出只有一個時脈寬——20 ns。把它拉長成一整個 tick,否則你永遠看不到繞回。キャリーアウトは 1 クロック幅、つまり 20 ns。1 tick 分に伸ばさなければラップは絶対に見えない。Carry-out hanya selebar satu clock — 20 ns. Regangkan menjadi satu tick penuh atau kamu tidak akan pernah melihat perputarannya.
  • No pin assignment, no light. Quartus wants a .qsf location and I/O standard per pin; Vivado wants the same pair in an .xdc.沒有指定腳位就沒有燈。Quartus 需要在 .qsf 裡給每支腳位置與 I/O standard;Vivado 則是在 .xdc 裡寫同樣兩項。ピン割り当てが無ければ光らない。Quartus は .qsf にピンごとの位置と I/O 規格を要求し、Vivado は同じ二つを .xdc に要求する。Tanpa penetapan pin, tidak ada cahaya. Quartus meminta lokasi .qsf dan standar I/O per pin; Vivado meminta pasangan yang sama di dalam .xdc.
  • Give it a reset and use it. An uninitialised counter starts wherever the fabric powers up, which makes "it starts at a weird number" your first wasted afternoon.給它一個 reset,而且真的要用。沒初始化的計數器會從上電當下的任意值開始,「怎麼從奇怪的數字開始」會是你第一個浪費掉的下午。リセットを用意し、実際に使うこと。初期化されていないカウンタは電源投入時の値から始まり、「変な数字から始まる」で最初の午後を丸ごと潰すことになる。Beri ia reset dan gunakan. Pencacah yang tidak diinisialisasi mulai dari nilai apa pun yang muncul saat fabric menyala, dan itulah yang membuat "kok mulainya dari angka aneh" menjadi sore pertama yang kamu buang percuma.

Done when完成條件完了条件Selesai bila

Reference answer — not released yet參考解答 —— 尚未開放参考解答 — まだ公開されていませんJawaban acuan — belum dirilis

12 pts分点poin2CONCURRENCY

Two FSMs, one clock, no stalls兩個 FSM、同一時脈、不停頓二つの FSM、一つのクロック、停滞なしDua FSM, satu clock, tanpa macet

  • Verilog
  • FSM
  • Handshake
  • Testbench

“multi-fsm running at same time (e.g. uart serialize & uart buffer allocater)”

Write the transmitter as two independent state machines that run every clock edge and talk only through a handshake — never through a shared variable. The serializer owns the bit timing; the allocator owns which byte comes next. Both live in their own always block; neither one waits for the other to finish a whole byte. 把發送端寫成兩個各自獨立、每個時脈邊緣都在跑的狀態機,彼此只透過 handshake 溝通——絕不共用變數。serializer 負責位元時序,allocator 負責決定下一個 byte。兩者各自待在自己的 always 區塊裡;誰都不必等對方把一整個 byte 做完。送信側は二つの独立したステートマシンとして書く。どちらも毎クロックエッジで動き、やり取りはハンドシェイクのみ——共有変数は使わない。シリアライザはビットタイミングを、アロケータは次のバイトを担当する。それぞれ自分の always ブロックに置き、相手が 1 バイトを終えるのを待たない。Tulis pemancarnya sebagai dua mesin keadaan mandiri yang berjalan pada setiap tepi clock dan hanya berbicara lewat handshake — jangan pernah lewat variabel bersama. Serializer memegang pewaktuan bit; alokator memegang byte mana yang menyusul. Keduanya hidup di blok always masing-masing; tidak satu pun menunggu yang lain menyelesaikan satu byte penuh.

// allocator → serializer, one byte per handshake
tx_valid  // allocator: this byte is real
tx_ready  // serializer: I latched it, give me the next
tx_data[7:0]
// transfer happens on the edge where both are high

Target numbers目標數字目標値Angka target

Baud divisorbaud 除數baud 分周値Pembagi baud
50e6 / 115200 = 434
Serializer statesserializer 狀態シリアライザの状態Keadaan serializer
IDLE·START·DATA·STOP
Bits per frame每個 frame 的位元數1 フレームのビット数Bit per frame
10 (1+8+1)
Ring buffer環形緩衝區リングバッファRing buffer
16 B, wrapping wr/rd ptr

Traps陷阱落とし穴Jebakan

  • One always @(posedge clk) block per FSM. Two blocks driving the same reg is a compile error waiting for you.每個 FSM 一個 always @(posedge clk) 區塊。兩個區塊去驅動同一個 reg,等著吃編譯錯誤。FSM ごとに always @(posedge clk) ブロックを一つ。二つのブロックで同じ reg を駆動すればコンパイルエラーが待っている。Satu blok always @(posedge clk) untuk tiap FSM. Dua blok yang menggerakkan reg yang sama adalah galat kompilasi yang sedang menunggumu.
  • The allocator must handle full and empty as distinct states — an equal read and write pointer means both unless you keep a count.allocator 必須把滿和空當成兩種不同狀態——讀寫指標相等時兩者都成立,除非你另外記一個計數。アロケータはフルとエンプティを別の状態として扱う必要がある——読み書きポインタが等しいだけでは両方を意味するので、カウントを別に持つこと。Alokator harus memperlakukan penuh dan kosong sebagai keadaan yang berbeda — pointer baca dan tulis yang sama nilainya berarti keduanya, kecuali kamu menyimpan pencacah.
  • Register the outputs. Combinational tx straight off the state decoder will glitch.輸出要打一級暫存器。直接從狀態解碼拉出來的組合邏輯 tx 會有毛刺。出力はレジスタで受けること。ステートデコーダから直接出した組み合わせ論理の tx はグリッチする。Registerkan keluarannya. tx kombinasional langsung dari dekoder keadaan akan menghasilkan glitch.

Done when完成條件完了条件Selesai bila

Reference answer — not released yet參考解答 —— 尚未開放参考解答 — まだ公開されていませんJawaban acuan — belum dirilis

15 pts分点poin3LOOPBACK

LabVIEW writes, the FPGA echoes it backLabVIEW 送出,FPGA 原封回傳LabVIEW が送り、FPGA がそのまま返すLabVIEW menulis, FPGA menggemakannya kembali

  • UART RX
  • Synchronizer
  • VISA

“Use labview to send data to rx of uart on FPGA and FPGA echo the data back to labview”

Now build the receiver and wire it straight into the transmitter from task 2. The whole design is a wire with a clock in the middle: whatever the host writes, it should read back byte-identical. This is the test rig you will reuse for everything after it. 現在做接收端,並直接接到第 2 題的發送端。整個設計就是一條中間夾了時脈的線:主機寫什麼,就該原樣讀回什麼。這是你後面每一題都會重複用到的測試平台。次に受信側を作り、課題 2 の送信側へ直結する。設計全体は真ん中にクロックが入った一本の線で、ホストが書いた内容がそのまま読み戻せるはず。これ以降ずっと使い回すテスト治具になる。Sekarang bangun penerimanya dan sambungkan langsung ke pemancar dari tugas 2. Seluruh rancangannya adalah sehelai kabel dengan clock di tengahnya: apa pun yang ditulis host, harus terbaca kembali identik byte demi byte. Inilah perangkat uji yang akan kamu pakai lagi untuk semua yang berikutnya.

On the LabVIEW side: VISA Configure Serial Port → VISA Write → VISA Read → VISA Close, with the read byte count wired from Bytes at Port rather than a guess. LabVIEW 這邊:VISA Configure Serial Port → VISA Write → VISA Read → VISA Close,讀取的 byte 數要從 Bytes at Port 接過來,不要用猜的。LabVIEW 側は VISA Configure Serial Port → VISA Write → VISA Read → VISA Close。読み取りバイト数は当て推量ではなく Bytes at Port から配線する。Di sisi LabVIEW: VISA Configure Serial Port → VISA Write → VISA Read → VISA Close, dengan jumlah byte yang dibaca disambungkan dari Bytes at Port, bukan dari tebakan.

Target numbers目標數字目標値Angka target

Oversampling過取樣オーバーサンプリングOversampling
16× per bit
Tick divisortick 除數tick 分周値Pembagi tick
50e6/(115200·16) ≈ 27
Sample point取樣點サンプリング点Titik pencuplikan
tick 8 of 16 (mid-bit)
Input sync輸入同步入力同期Sinkronisasi masukan
2 flip-flops on rx
Soak test長時間測試ソークテストUji rendam
1000 random bytes, 0 mismatches

Traps陷阱落とし穴Jebakan

  • The rx pin is asynchronous. Two flip-flops before it touches any FSM, or you will chase a bug that only appears once an hour.rx 腳是非同步訊號。在它碰到任何 FSM 之前先過兩級正反器,否則你會去追一個一小時才出現一次的 bug。rx ピンは非同期。FSM に触れる前にフリップフロップ 2 段を通すこと。さもないと 1 時間に 1 度しか出ないバグを追うことになる。Pin rx bersifat asinkron. Dua flip-flop sebelum ia menyentuh FSM mana pun, atau kamu akan mengejar bug yang hanya muncul sekali sejam.
  • Re-check the start bit at mid-bit and abort if it went high — that is your noise rejection.在位元中央再確認一次 start bit,如果變成高電位就中止——這就是你的雜訊排除。ビット中央でスタートビットを再確認し、ハイになっていれば中止する——これがノイズ除去になる。Periksa ulang start bit di tengah bit dan batalkan kalau ternyata sudah naik — itulah penolakan derau milikmu.
  • Flow control off, and confirm both ends agree on 8N1. Half the "corrupted echo" reports are a parity mismatch.關掉流量控制,並確認兩端都設 8N1。所謂「回傳資料壞掉」有一半是 parity 設定不一致。フロー制御はオフ、両端が 8N1 で一致していることを確認する。「エコーが壊れる」という報告の半分はパリティの不一致。Flow control mati, dan pastikan kedua ujung sepakat pada 8N1. Separuh laporan "gema rusak" sebenarnya adalah ketidakcocokan paritas.
  • Echoing at the same baud you receive means zero headroom. Keep the FIFO from task 2 in the path.用跟接收相同的 baud 回傳等於毫無餘裕。把第 2 題的 FIFO 留在路徑上。受信と同じ baud で返すと余裕がゼロになる。課題 2 の FIFO を経路に残しておくこと。Menggemakan pada baud yang sama dengan yang kamu terima berarti nol ruang lega. Pertahankan FIFO dari tugas 2 tetap di jalurnya.

Done when完成條件完了条件Selesai bila

Reference answer — not released yet參考解答 —— 尚未開放参考解答 — まだ公開されていませんJawaban acuan — belum dirilis

18 pts分点poin4FIXED POINT

A single-pole low-pass filter in Q format用 Q format 做單極點低通濾波器Q フォーマットによる 1 次ローパスフィルタTapis lolos-rendah kutub tunggal dalam format Q

  • IIR
  • Q format
  • Saturation
  • Host主機端ホスト側Sisi host

“fast low pass filter (for fixed point operation practice) with labview”

Integers only — no float, no double, anywhere in the loop. Every value is a Q-format number: a plain integer whose binary point you track in your head, not in the machine. The point is not the filter, it is knowing where that point sits after every multiply and what happens at the edges of the word. 整數,只有整數——迴圈裡不准有 float、不准有 double。每個值都是 Q format 數字:本質上就是整數,小數點位置由你自己記在腦子裡,而不是交給機器。重點不是濾波器,而是每次乘法之後那個小數點跑到哪裡,以及字組邊界會發生什麼事。整数のみ——ループ内に float も double も置かない。すべての値は Q フォーマットの数、つまり小数点の位置を機械ではなく自分の頭で管理する普通の整数だ。要点はフィルタではなく、掛け算のたびに小数点がどこへ動くか、そしてワードの端で何が起きるかを知ることにある。Bilangan bulat saja — tanpa float, tanpa double, di mana pun dalam loop. Setiap nilai adalah bilangan format Q: bilangan bulat biasa yang titik binernya kamu lacak di kepalamu, bukan di mesin. Intinya bukan tapisnya, melainkan mengetahui di mana titik itu berada setelah setiap perkalian dan apa yang terjadi di tepi word.

// y[n] = y[n-1] + a·(x[n] - y[n-1]),  15 fraction bits
err  = x - y            // I16, may overflow → saturate
acc  = a * err          // I32, 30 fraction bits
y    = y + (acc >> 15)  // shift back to 15

The coefficient is picked once, away from the bench, and enters the code as the integer 3869 — that is a 20 Hz corner at 1 kHz, scaled by 215. Nothing in the running loop ever sees a fraction. 係數只在離開實驗桌時算一次,進到程式裡就是整數 3869——那是 1 kHz 取樣下 20 Hz 轉角頻率乘以 215 的結果。執行中的迴圈從頭到尾看不到任何分數。係数は机の外で一度だけ決め、コードには整数 3869 として入る——1 kHz サンプリングでの 20 Hz カットオフを 215 倍した値だ。実行中のループが小数を見ることは一度もない。Koefisiennya dipilih sekali, jauh dari meja praktik, dan masuk ke kode sebagai bilangan bulat 3869 — itu adalah sudut 20 Hz pada 1 kHz, diskalakan dengan 215. Tidak ada satu pun bagian loop berjalan yang pernah melihat pecahan.

Target numbers目標數字目標値Angka target

Sample rate取樣率サンプリングレートLaju cuplik
1 kHz
Cutoff截止頻率カットオフFrekuensi potong
20 Hz
Format格式フォーマットFormat
16-bit Q, 15 frac bits
α as an integerα 的整數值整数としての αα sebagai bilangan bulat
3869 / 2^15 (0x0F1D)
Word字組ワードWord
I16 state, I32 accumulator
Settling (step, 95%)步階響應建立時間(95%)整定時間(ステップ、95%)Waktu tunak (step, 95%)
≈ 24 samples

Traps陷阱落とし穴Jebakan

  • >> 15 on a negative number truncates toward −∞. Add the rounding term (1<<14) before shifting, or your output drifts down.對負數做 >> 15 會往 −∞ truncate。移位前先加上四捨五入項 (1<<14),否則輸出會一路往下漂。負数に対する >> 15 は −∞ 方向に切り捨てられる。シフト前に丸め項 (1<<14) を足さないと出力が下へドリフトする。>> 15 pada bilangan negatif memotong ke arah −∞. Tambahkan suku pembulatan (1<<14) sebelum menggeser, atau keluaranmu akan melorot turun.
  • Saturate x − y; do not let it wrap. A wrap turns a smooth step into a spike.把 x − y 做飽和處理,不要讓它 wrap。一旦 wrap,平滑的步階就會變成尖刺。x − y は飽和させ、ラップさせないこと。ラップすると滑らかなステップがスパイクに化ける。Jenuhkan x − y; jangan biarkan ia berputar. Perputaran mengubah step yang mulus menjadi lonjakan.
  • With a small α the increment can round to zero — the output parks a few LSB short of the input and stays there. That limit cycle is expected; measure it, do not patch it away with a float.α 很小時,增量會被四捨五入成零——輸出會停在離輸入差幾個 LSB 的地方不動。這個極限環是預期中的現象;把它量出來,不要用浮點數把它蓋掉。α が小さいと増分がゼロに丸められ、出力は入力より数 LSB 手前で止まったままになる。このリミットサイクルは想定内であり、測定すべきもので、float で誤魔化すものではない。Dengan α yang kecil, penambahnya bisa membulat menjadi nol — keluarannya berhenti beberapa LSB di bawah masukan dan diam di situ. Siklus batas itu memang diharapkan; ukurlah, jangan ditambal dengan float.
  • Force the wire/array types (I16, I32) explicitly. Leave it to coercion and you get doubles without noticing.明確指定接線/陣列型別(I16、I32)。放著讓它自動轉型,你會在不知不覺中拿到 double。配線や配列の型(I16、I32)は明示的に指定する。暗黙変換に任せると、気づかないうちに double になる。Paksakan tipe wire/array (I16, I32) secara eksplisit. Serahkan pada koersi dan kamu akan mendapat double tanpa menyadarinya.

Done when完成條件完了条件Selesai bila

Reference answer — not released yet參考解答 —— 尚未開放参考解答 — まだ公開されていませんJawaban acuan — belum dirilis

23 pts分点poin5ACTUATOR

PWM a positional servo to a commanded angle用 PWM 把位置型伺服機轉到指定角度PWM で位置制御サーボを指定角度へ回すMem-PWM servo posisional ke sudut yang diperintahkan

  • PWM
  • Pulse width
  • Angle mapping
  • Closed loop
  • Bench supply

“pwm control the easy servo motor” ↳ positional, angle-commanded

A servo's PWM is not a throttle. The 50 Hz frame you send carries exactly one number — the width of the high pulse — and that width is an angle setpoint: 1.0 ms is one end of the travel, 2.0 ms the other, 1.5 ms the middle. Nothing in that signal tells the motor how fast to turn. Inside the case a potentiometer reads the actual shaft angle, a PI controller works on the error between it and your setpoint, and that loop decides the motor's speed and direction through the servo's own H-bridge. You command where; the servo decides how fast. Your job is the counter and the compare that turn an angle into that pulse width, with the angle read straight off the FPGA's GPIO pins.伺服機的 PWM 不是油門。你送出去的 50 Hz 框架只帶一個數字——高電位脈波的寬度——而那個寬度是角度設定值:1.0 ms 是行程的一端,2.0 ms 是另一端,1.5 ms 是中間。這個訊號裡沒有任何一處在告訴馬達要轉多快。殼子裡面有一顆電位器在讀實際的軸角度,一個 PI 控制器處理它與你的設定值之間的誤差,而決定馬達轉速與方向的是那個迴路,透過伺服機自己的 H 橋去驅動。你命令的是「到哪裡」,「轉多快」由伺服機自己決定。你要做的是把角度換成那個脈波寬度的計數器與比較器,而角度直接從 FPGA 的 GPIO 腳位讀進來。サーボの PWM はスロットルではない。送り出す 50 Hz のフレームが運ぶ数値はただ一つ——ハイパルスの幅——で、その幅は角度の設定値だ:1.0 ms が可動範囲の一端、2.0 ms がもう一端、1.5 ms が中央。この信号のどこにも、モータをどれだけ速く回すかという情報はない。ケースの中ではポテンショメータが実際の軸角度を読み、PI 制御器が設定値との誤差を処理し、モータの速度と方向を決めるのはそのループで、サーボ自身の H ブリッジを通して駆動する。指令するのは「どこへ」であり、「どれだけ速く」はサーボが決める。あなたの仕事は、角度をそのパルス幅に変換するカウンタと比較器で、角度は FPGA の GPIO ピンから直接読む。PWM sebuah servo bukanlah pengatur tenaga. Frame 50 Hz yang kamu kirim membawa tepat satu angka — lebar pulsa tingginya — dan lebar itu adalah setpoint sudut: 1.0 ms adalah salah satu ujung lintasan, 2.0 ms ujung yang lain, 1.5 ms bagian tengahnya. Tidak ada apa pun dalam sinyal itu yang memberi tahu motor seberapa cepat harus berputar. Di dalam casing-nya, sebuah potensiometer membaca sudut poros yang sebenarnya, sebuah kendali PI bekerja atas selisih antara nilai itu dan setpoint-mu, dan loop itulah yang menentukan kecepatan serta arah motor melalui H-bridge milik servo sendiri. Kamu memerintahkan ke mana; servo yang memutuskan secepat apa. Tugasmu adalah pencacah dan pembanding yang mengubah sudut menjadi lebar pulsa itu, dengan sudutnya dibaca langsung dari pin GPIO FPGA.

Those GPIO pins are asynchronous to your clock, so double-flop them before use and latch the whole word at the frame edge — sampling a multi-bit angle mid-transition hands you a value that was never on the pins at all, and the servo will faithfully drive to it.那些 GPIO 腳位跟你的時鐘不同步,所以要先過兩級正反器同步,再在框架邊界上把整個字一次鎖住——在多位元角度值跳變的中途取樣,拿到的會是一個從來沒出現在腳位上的值,而伺服機會忠實地轉到那個角度去。その GPIO ピンはクロックに非同期なので、使う前に二段フリップフロップで同期し、ワード全体をフレームのエッジでラッチすること——多ビットの角度値を遷移の途中でサンプルすると、ピン上に一度も存在しなかった値を拾い、サーボは忠実にその角度へ動いてしまう。Pin GPIO itu asinkron terhadap clock-mu, jadi lewatkan lebih dulu melalui dua flip-flop dan kunci seluruh word pada tepi frame — mencuplik sudut multi-bit di tengah transisi memberimu nilai yang sebenarnya tidak pernah ada di pin, dan servo akan dengan patuh bergerak ke sana.

This task needs no driver stage at all. The servo's signal wire is a logic input on its internal control board — a few hundred microamps, happy with 3.3 V — so it goes straight to an FPGA pin with nothing in between. No MOSFET, no H-bridge, no flyback diode: the bridge is already in there, one centimetre from the PI loop driving it, and a bridge of your own in front of a logic input would only destroy the signal. What the servo does need is power it can actually draw: its own 4.8–6 V rail, never the board's 5 V pin, with the two grounds tied at a single point so your pulse has a reference.這題完全不需要任何驅動級。伺服機的訊號線是它內部控制板上的一個邏輯輸入——幾百微安培,3.3 V 就吃得下——所以直接接到 FPGA 腳位,中間什麼都不用加。不用 MOSFET、不用 H 橋、不用續流二極體:橋本來就在裡面,離驅動它的 PI 迴路一公分遠,你自己在邏輯輸入前面再加一座橋,只會把訊號毀掉。伺服機真正需要的是它拉得動的電源:自己一條 4.8–6 V 的電源軌,絕對不要用板子的 5 V 腳,並且兩邊的地要在單一點接在一起,你的脈波才有參考點。この課題にドライバ段は一切不要だ。サーボの信号線は内部制御基板のロジック入力——数百マイクロアンペアで、3.3 V でも問題ない——なので、間に何も挟まず FPGA のピンへ直結する。MOSFET も H ブリッジもフライバックダイオードも要らない:ブリッジはすでに中にあり、それを駆動する PI ループから 1 cm の距離にある。ロジック入力の手前に自前のブリッジを置いても信号を壊すだけだ。サーボが本当に必要とするのは実際に引ける電力だ:専用の 4.8–6 V レールを用意し、ボードの 5 V ピンは使わない。そして両方の GND を一点で接続し、パルスに基準を与えること。Tugas ini sama sekali tidak memerlukan tingkat penggerak. Kabel sinyal servo adalah masukan logika pada papan kendali internalnya — beberapa ratus mikroampere, senang dengan 3.3 V — jadi ia langsung ke pin FPGA tanpa apa pun di antaranya. Tanpa MOSFET, tanpa H-bridge, tanpa dioda flyback: jembatannya sudah ada di dalam sana, satu sentimeter dari loop PI yang menggerakkannya, dan jembatan buatanmu sendiri di depan masukan logika hanya akan merusak sinyalnya. Yang justru dibutuhkan servo adalah daya yang benar-benar bisa ia tarik: rel 4.8–6 V miliknya sendiri, jangan pernah pin 5 V papan, dengan kedua ground disatukan di satu titik agar pulsamu punya acuan.

// 50 Hz servo frame from a 50 MHz clock
scnt  <= (scnt == 999999) ? 0 : scnt + 1;
servo <= (scnt < pulse);  // pulse 50000..100000 = 1.0..2.0 ms = 0..180°

Target numbers目標數字目標値Angka target

Frame框架週期フレーム周期Frame
50 Hz → 20 ms
Period counts週期計數值周期カウント数Hitungan periode
50e6 / 50 = 1,000,000
0° (one end)0°(一端)0°(一端)0° (satu ujung)
1.0 ms → 50,000
90° (centre)90°(中位)90°(中央)90° (tengah)
1.5 ms → 75,000
180° (other end)180°(另一端)180°(もう一端)180° (ujung lainnya)
2.0 ms → 100,000
Counts per degree每度計數值1 度あたりのカウントHitungan per derajat
≈ 278
Angle command角度命令角度指令Perintah sudut
GPIO, latched at frame edge
Driver驅動器ドライバPenggerak
none — the servo has its own
Supply供電電源Catu daya
4.8–6 V, own rail
Slew limit迴轉率限制スルーレート制限Batas laju
0 → 180° over >= 500 ms

Where to get one去哪裡買入手先Di mana membelinya

MG90S · metal-gear micro servo, 14 gMG90S · 金屬齒輪微型伺服機,14 gMG90S · 金属ギア マイクロサーボ、14 gMG90S · micro servo roda gigi logam, 14 g shopee.tw ↗ 樂意創客官方店 · pick the 180° or the 360° version at checkout樂意創客官方店 · 結帳時選 180° 或 360° 版本樂意創客官方店 · 決済時に 180° 版か 360° 版を選ぶ樂意創客官方店 · pilih versi 180° atau 360° saat checkout

Read what that package actually is before wiring it: an MG90S is a brushed motor, a gearbox, a feedback potentiometer and the PI loop with its own H-bridge, all sealed in one case. That is why three wires are enough — power, ground, and one signal line carrying nothing but your angle.接線之前先搞清楚那顆東西是什麼:MG90S 是有刷馬達、齒輪箱、回饋電位器,加上那個帶自己 H 橋的 PI 迴路,全部封在同一個殼裡。這就是為什麼三條線就夠了——電源、地,以及一條只送角度的訊號線。配線する前にそれが何なのかを把握すること:MG90S はブラシモータ、ギアボックス、フィードバック用ポテンショメータ、そして自前の H ブリッジを備えた PI ループが、すべて一つのケースに封じられている。だから線は三本で足りる——電源、GND、そして角度だけを運ぶ信号線 1 本だ。Pahami dulu apa isi paket itu sebelum menyambungnya: sebuah MG90S adalah motor brushed, gearbox, potensiometer umpan balik dan loop PI dengan H-bridge-nya sendiri, semuanya tersegel dalam satu casing. Itulah sebabnya tiga kabel sudah cukup — daya, ground, dan satu jalur sinyal yang tidak membawa apa pun selain sudutmu.

Buy the 180° version. That is the positional servo this task is about: pulse width commands an angle and the internal loop holds it there against a load. The 360° version looks identical and is a different device — its potentiometer is decoupled from the output shaft, so there is no angle to hold, and the same pulse width becomes a speed and direction command with 1.5 ms meaning stop. With that part the angle checkpoints below are not reachable; it is an open-loop motor with a driver attached.請買 180° 的版本。那顆才是這題要的位置型伺服:脈波寬度命令角度,內部迴路會頂著負載把它維持在那裡。360° 那顆外觀一樣,但是另一種裝置——它的電位器已經和輸出軸脫開,所以沒有角度可以維持,同一個脈波寬度變成命令速度與方向,1.5 ms 代表停止。用那顆的話,下面的角度檢查點做不到;它只是一顆接了驅動器的開迴路馬達。180° 版を買うこと。それがこの課題で使う位置制御サーボだ:パルス幅が角度を指令し、内部ループが負荷に抗してそこを保持する。360° 版は見た目が同じでも別の装置で——ポテンショメータが出力軸から切り離されているため保持すべき角度が存在せず、同じパルス幅が速度と方向の指令になり、1.5 ms が停止を意味する。その部品では下の角度チェックポイントに到達できない。ドライバの付いた開ループのモータにすぎない。Belilah versi 180°. Itulah servo posisional yang menjadi pokok tugas ini: lebar pulsa memerintahkan sudut dan loop internal menahannya di sana melawan beban. Versi 360° terlihat identik tetapi merupakan perangkat yang berbeda — potensiometernya dilepas dari poros keluaran, sehingga tidak ada sudut untuk ditahan, dan lebar pulsa yang sama berubah menjadi perintah kecepatan dan arah dengan 1.5 ms berarti berhenti. Dengan komponen itu, checkpoint sudut di bawah tidak bisa dicapai; ia adalah motor loop-terbuka dengan penggerak yang menempel.

Do not write a new angle to the compare register the instant the GPIO pins change. A servo commanded from 0° to 180° in a single frame goes there as fast as its internal loop can manage — full current, full torque, and a supply sag that resets the FPGA if the two share a rail. Move the setpoint one degree per frame instead: full travel then takes 180 × 20 ms = 3.6 s, comfortably outside the 500 ms floor, and the mechanism never sees a step. This is the same ramp the brushed-motor extension needs, applied to a position instead of a duty.不要在 GPIO 腳位一變就把新角度寫進比較暫存器。一個在單一框架內從 0° 被命令到 180° 的伺服機,會用它內部迴路能給的最快速度衝過去——滿電流、滿扭矩,如果它和 FPGA 共用一條電源軌,電壓會塌到讓 FPGA 重置。改成每個框架只移動一度:跑完全行程要 180 × 20 ms = 3.6 s,穩穩地落在 500 ms 的下限之外,而機構永遠不會看到階躍。這和有刷馬達那一節需要的斜升是同一件事,只是作用在位置而不是 duty 上。GPIO ピンが変わった瞬間に新しい角度を比較レジスタへ書いてはいけない。1 フレームで 0° から 180° へ指令されたサーボは、内部ループが出せる限りの速さでそこへ飛ぶ——全電流、全トルク、そして FPGA と電源レールを共有していれば電圧が落ちて FPGA がリセットする。代わりに設定値をフレームごとに 1 度ずつ動かすこと:全行程は 180 × 20 ms = 3.6 s となり、500 ms の下限には余裕で収まり、機構がステップを見ることはない。これはブラシモータの発展課題で必要になるランプと同じ話を、デューティではなく位置に適用したものだ。Jangan menulis sudut baru ke register pembanding begitu pin GPIO berubah. Servo yang diperintahkan dari 0° ke 180° dalam satu frame akan ke sana secepat yang bisa dilakukan loop internalnya — arus penuh, torsi penuh, dan tegangan yang anjlok sehingga FPGA ter-reset kalau keduanya berbagi rel. Geser setpoint-nya satu derajat per frame saja: lintasan penuh lalu memakan 180 × 20 ms = 3.6 s, jauh di atas batas bawah 500 ms, dan mekanismenya tidak pernah menerima step. Ini adalah ramp yang sama dengan yang dibutuhkan perluasan motor brushed, hanya diterapkan pada posisi alih-alih duty.

Reference designs參考設計参考設計Rancangan acuan

Extension — a bare brushed motor延伸:換成裸的有刷馬達発展——剥き出しのブラシモータPerluasan — motor brushed telanjang

Everything above stops at the servo's signal pin, because the loop that turns your angle into motor current is already inside the case. Build that inner half yourself — a bare brushed motor, no feedback — and this is what you have to add: a carrier fast enough to be inaudible, a compare value that now means speed, a bridge if you want reversal, and a buffer stage between the FPGA pin and the winding. Note that only reversal needs a bridge; one low-side transistor is enough for one direction.上面所有東西都停在伺服機的訊號腳,因為把你的角度變成馬達電流的那個迴路,已經在殼子裡了。自己把裡面那一半做出來——一顆裸的有刷馬達,沒有回饋——要加的就是這些:一個快到聽不見的載波、一個現在代表轉速的比較值、想換向的話再加一座橋,以及 FPGA 腳位與線圈之間的緩衝級。注意只有換向才需要橋;單一方向用一顆低邊電晶體就夠了。ここまでの内容はサーボの信号ピンで終わる。角度をモータ電流に変えるループは、すでにケースの中にあるからだ。その内側の半分を自分で作るなら——剥き出しのブラシモータ、フィードバックなし——追加が必要なのは次のものだ:可聴域を超えたキャリア、いまや速度を意味する比較値、反転させたいならブリッジ、そして FPGA のピンと巻線の間のバッファ段。ブリッジが必要なのは反転のときだけで、片方向なら低電位側のトランジスタ 1 個で足りる。Semua di atas berhenti pada pin sinyal servo, karena loop yang mengubah sudutmu menjadi arus motor sudah ada di dalam casing. Bangun sendiri separuh bagian dalam itu — motor brushed telanjang, tanpa umpan balik — dan inilah yang harus kamu tambahkan: pembawa yang cukup cepat sehingga tak terdengar, nilai pembanding yang sekarang berarti kecepatan, sebuah jembatan kalau kamu ingin pembalikan arah, dan tingkat penyangga antara pin FPGA dan lilitannya. Perhatikan bahwa hanya pembalikan arah yang butuh jembatan; satu transistor sisi-bawah sudah cukup untuk satu arah.

The FPGA pin is a control signal, not a power source. An I/O pin drives a few milliamps — 24 mA at the very most, and only if the bank is configured for it — while a small brushed motor pulls several hundred milliamps running and close to an amp stalled. Between the PWM output and the motor you have to design a buffer stage of your own. Wiring a motor straight to an I/O pin kills the pin, and often takes the whole bank with it.FPGA 的腳位是控制訊號,不是電源。一支 I/O 腳只能推幾毫安培——最多 24 mA,而且還要 bank 有這樣設定——但一顆小型有刷馬達運轉時要幾百毫安培,堵轉時接近一安培。PWM 輸出和馬達之間,你必須自己設計一級緩衝電路。把馬達直接接到 I/O 腳,那支腳會死,而且常常整個 bank 一起陪葬。FPGA のピンは制御信号であって電源ではない。I/O ピンが流せるのは数ミリアンペア——バンクの設定次第で最大 24 mA——に対し、小型のブラシモータは回転中で数百ミリアンペア、ストール時には 1 A 近くを引く。PWM 出力とモータの間には、自分で設計したバッファ段が必要だ。モータを I/O ピンに直結すればそのピンは壊れ、多くの場合バンクごと道連れになる。Pin FPGA adalah sinyal kendali, bukan sumber daya. Sebuah pin I/O menggerakkan beberapa miliampere — paling banter 24 mA, dan hanya kalau bank-nya dikonfigurasi untuk itu — sementara motor brushed kecil menarik beberapa ratus miliampere saat berjalan dan mendekati satu ampere saat macet. Di antara keluaran PWM dan motor, kamu harus merancang sendiri tingkat penyangga. Menyambungkan motor langsung ke pin I/O akan membunuh pin itu, dan sering kali membawa serta seluruh bank-nya.

That buffer can be a single transistor. One logic-level N-MOSFET as a low-side switch — source to ground, drain to the motor's negative terminal, motor positive to its own supply — gives you full PWM speed control in one direction, and an NPN BJT with a base resistor does the same job at lower current. Three details decide whether it works: the MOSFET must be logic-level, because a plain IRF540 never fully turns on at 3.3 V; a flyback diode across the motor catches the inductive kick; and a 10 kΩ pull-down on the gate keeps the motor still while the FPGA is still configuring and the pin is high-Z. For a BJT, size the base resistor from the current you need — at β ≈ 100 and 500 mA that is 5 mA of base current, so (3.3 − 0.7) / 5 mA ≈ 470 Ω. Only the reversal checkpoint needs more than one transistor; that is what the H-bridge is for.這個緩衝電路可以只有一顆電晶體。一顆邏輯準位 N-MOSFET 當低邊開關——source 接地、drain 接馬達負端、馬達正端接它自己的電源——就能在單一方向上做完整的 PWM 調速;電流不大時,一顆 NPN BJT 加上基極電阻也能做同樣的事。成敗取決於三個細節:MOSFET 必須是邏輯準位的,因為一般的 IRF540 在 3.3 V 下根本不會完全導通;馬達要並一顆續流二極體吸收電感回衝;閘極要接一顆 10 kΩ 下拉電阻,讓 FPGA 還在組態、腳位還是高阻抗時馬達不會亂動。用 BJT 的話,基極電阻要照需要的電流算——β ≈ 100、負載 500 mA 時基極要 5 mA,所以 (3.3 − 0.7) / 5 mA ≈ 470 Ω。只有「換向」那個檢查點需要一顆以上的電晶體,那正是 H 橋存在的理由。このバッファはトランジスタ 1 個でも構わない。ロジックレベルの N-MOSFET をローサイドスイッチとして使えば——ソースを GND、ドレインをモータのマイナス端子、モータのプラス端子は専用電源へ——片方向で完全な PWM 速度制御ができる。電流が小さければ、ベース抵抗付きの NPN BJT でも同じ役目を果たす。成否を決めるのは三点:MOSFET はロジックレベル品であること(普通の IRF540 は 3.3 V では完全にオンしない)、モータと並列のフライバックダイオードで誘導性のキックを逃がすこと、そしてゲートの 10 kΩ プルダウンで、FPGA がまだコンフィグ中でピンがハイインピーダンスの間にモータが動かないようにすること。BJT ならベース抵抗は必要な電流から決める——β ≈ 100 で 500 mA ならベース電流 5 mA、つまり (3.3 − 0.7) / 5 mA ≈ 470 Ω。トランジスタが 1 個で足りないのは反転のチェックポイントだけで、そのために H ブリッジがある。Penyangga itu bisa berupa satu transistor. Satu N-MOSFET logic-level sebagai sakelar sisi-bawah — source ke ground, drain ke terminal negatif motor, positif motor ke catu dayanya sendiri — sudah memberimu kendali kecepatan PWM penuh dalam satu arah, dan BJT NPN dengan resistor basis melakukan pekerjaan yang sama pada arus yang lebih rendah. Tiga hal menentukan apakah ini berhasil: MOSFET-nya harus logic-level, karena IRF540 biasa tidak pernah benar-benar menyala penuh pada 3.3 V; dioda flyback melintang pada motor menangkap tendangan induktifnya; dan pull-down 10 kΩ pada gate menjaga motor tetap diam selagi FPGA masih dikonfigurasi dan pin-nya masih high-Z. Untuk BJT, hitung resistor basis dari arus yang kamu butuhkan — pada β ≈ 100 dan 500 mA itu berarti arus basis 5 mA, jadi (3.3 − 0.7) / 5 mA ≈ 470 Ω. Hanya checkpoint pembalikan arah yang butuh lebih dari satu transistor; untuk itulah H-bridge ada.

If you want the motor's noise to stay out of the FPGA altogether, put a photocoupler between the two: the PWM pin drives the coupler's LED through a series resistor, the phototransistor on the far side drives the gate, and the only thing crossing between the two grounds is light. Watch the speed — a common PC817 takes a few microseconds to switch, which is a visible slice of a 50 µs PWM period and distorts the duty; at 20 kHz reach for a fast logic coupler (6N137) or a gate-driver coupler (TLP250) instead. Size the LED resistor from the coupler's forward voltage — (3.3 − 1.2) / 5 mA ≈ 470 Ω — and remember the transistor side needs its own supply and pull-up, or the isolation buys you nothing.如果你希望馬達的雜訊完全進不了 FPGA,就在兩者之間放一顆光耦合器:PWM 腳透過一顆串聯電阻去推光耦裡的 LED,另一端的光電晶體再去驅動閘極,兩邊的地之間就只剩下光在傳遞。要注意速度——常見的 PC817 切換要好幾微秒,在 50 µs 的 PWM 週期裡是看得出來的一塊,會讓 duty 失真;20 kHz 請改用高速邏輯型光耦(6N137)或閘極驅動型光耦(TLP250)。LED 的限流電阻依它的順向電壓計算——(3.3 − 1.2) / 5 mA ≈ 470 Ω——另外別忘了電晶體那一側要有自己的電源與上拉電阻,否則這層隔離等於白做。モータのノイズを FPGA に一切入れたくないなら、両者の間にフォトカプラを置く:PWM ピンが直列抵抗を介してカプラの LED を駆動し、反対側のフォトトランジスタがゲートを駆動する。二つのグラウンドの間を渡るのは光だけになる。速度には注意——よくある PC817 はスイッチングに数マイクロ秒かかり、50 µs の PWM 周期では無視できない割合を占めてデューティを歪ませる。20 kHz なら高速ロジック用(6N137)かゲートドライバ用(TLP250)のフォトカプラを使うこと。LED の抵抗は順方向電圧から決める——(3.3 − 1.2) / 5 mA ≈ 470 Ω——そしてトランジスタ側には独自の電源とプルアップが要る。でなければ絶縁した意味がない。Kalau kamu ingin derau motor sama sekali tidak masuk ke FPGA, pasang photocoupler di antara keduanya: pin PWM menggerakkan LED coupler lewat resistor seri, fototransistor di seberangnya menggerakkan gate, dan satu-satunya yang menyeberang di antara kedua ground adalah cahaya. Perhatikan kecepatannya — PC817 yang umum butuh beberapa mikrodetik untuk beralih, dan itu potongan yang kelihatan dari periode PWM 50 µs sehingga merusak duty-nya; pada 20 kHz, pilihlah coupler logika cepat (6N137) atau coupler gate-driver (TLP250). Hitung resistor LED dari tegangan maju coupler-nya — (3.3 − 1.2) / 5 mA ≈ 470 Ω — dan ingat sisi transistornya butuh catu daya dan pull-up sendiri, kalau tidak isolasinya tidak memberimu apa-apa.

// 20 kHz carrier from a 50 MHz clock
cnt <= (cnt == 2499) ? 0 : cnt + 1;
pwm <= (cnt < duty);   // duty 0..2500 = 0..100%
Carrier載波キャリアPembawa
20 kHz (above audible)
Period counts週期計數值周期カウント数Hitungan periode
50e6 / 20e3 = 2500
Duty resolutionduty 解析度デューティ分解能Resolusi duty
≈ 11.3 bits
Driver驅動器ドライバPenggerak
H-bridge, not a bare FET
Dead time死區時間デッドタイムDead time
>= 1 µs between high/low side
Ramp斜升ランプRamp
0 → 100% over >= 200 ms

Traps陷阱落とし穴Jebakan

  • Putting a MOSFET or an H-bridge in front of the servo's signal wire. It is a logic input, not a winding — drive it directly.在伺服機訊號線前面加 MOSFET 或 H 橋。那是邏輯輸入,不是線圈——直接推它就好。サーボの信号線の手前に MOSFET や H ブリッジを置くこと。あれは巻線ではなくロジック入力だ——直結して駆動する。Memasang MOSFET atau H-bridge di depan kabel sinyal servo. Itu masukan logika, bukan lilitan — gerakkan langsung.
  • A frame that is only approximately 20 ms, or a pulse that jitters by a microsecond, makes the horn buzz and hunt — that is your counter, not the servo.框架只是「大約」20 ms,或脈波抖動個一微秒,舵臂就會嗡嗡叫並來回找位——那是你的計數器的問題,不是伺服機的。フレームが「およそ」20 ms しかない、あるいはパルスが 1 マイクロ秒ジッタするだけで、ホーンは唸って位置を探し続ける——それはサーボではなく自分のカウンタの問題だ。Frame yang hanya kira-kira 20 ms, atau pulsa yang bergetar sebesar satu mikrodetik, membuat horn berdengung dan mencari-cari — itu pencacahmu, bukan servonya.
  • Commanding past the mechanical end stop. Below 1.0 ms or above 2.0 ms the loop keeps pushing against the stop, draws stall current and cooks the gearbox — clamp the angle in hardware, not in the host that feeds the pins.命令超過機械極限。低於 1.0 ms 或高於 2.0 ms 時,迴路會一直頂著限位推,吃堵轉電流並把齒輪箱燒掉——角度要在硬體裡夾住,不要靠餵腳位的那一端自律。機械的なエンドストップを越えて指令すること。1.0 ms 未満または 2.0 ms 超では、ループはストッパを押し続けてストール電流を引き、ギアボックスを焼く——角度はハードウェアでクランプする。ピンに値を送る側の良心に任せてはいけない。Memerintahkan melewati batas mekanis. Di bawah 1.0 ms atau di atas 2.0 ms, loop-nya terus mendorong melawan batas itu, menarik arus macet dan memanggang gearbox — kunci sudutnya di perangkat keras, bukan di host yang memberi umpan ke pin.
  • An MG90S takes 3.3 V logic on the signal pin happily, but never power it from the board's 5 V pin — a stalled servo pulls close to an amp and the FPGA resets with it.MG90S 的訊號腳吃 3.3 V 邏輯沒問題,但絕對不要用板子的 5 V 腳供電——伺服機堵轉時電流接近一安培,FPGA 會跟著重置。MG90S の信号ピンは 3.3 V ロジックで問題なく動くが、ボードの 5 V ピンから電源を取ってはいけない——ストール時に 1 A 近く流れ、FPGA も一緒にリセットする。MG90S menerima logika 3.3 V pada pin sinyal dengan senang hati, tetapi jangan pernah memberinya daya dari pin 5 V papan — servo yang macet menarik mendekati satu ampere dan FPGA ikut ter-reset.
  • Separate motor supply, grounds tied at one point. Powering the motor off the board rail browns out the FPGA the moment it stalls.馬達要獨立供電,接地只在一點共接。用板子的電源軌去推馬達,堵轉那一瞬間 FPGA 就會掉電。モータ電源は別系統にし、グラウンドは一点で接続する。ボードの電源レールからモータを回すと、ストールした瞬間に FPGA が電圧降下で落ちる。Catu daya motor terpisah, ground disatukan di satu titik. Memberi daya motor dari rel papan akan membuat FPGA brownout begitu motornya macet.
  • Step the duty from 0 to full and the inrush trips the supply. Ramp the compare register.把 duty 從 0 一步跳到滿,突入電流會讓電源跳掉。比較暫存器要用斜升的。デューティを 0 から一気に全開にすると突入電流で電源が落ちる。比較レジスタはランプさせること。Naikkan duty dari 0 ke penuh sekaligus dan arus inrush-nya akan menjatuhkan catu daya. Ramp-kan register pembandingnya.
  • Never drive both sides of a bridge leg on at once. Insert the dead time in the FSM, not in your head.絕不要讓橋臂的上下兩側同時導通。死區時間要寫進 FSM 裡,不是放在你腦子裡。ブリッジの上下アームを同時にオンにしてはいけない。デッドタイムは頭の中ではなく FSM に入れること。Jangan pernah menyalakan kedua sisi satu kaki jembatan sekaligus. Sisipkan dead time-nya di dalam FSM, bukan di kepalamu.
  • Below a few percent duty the motor buzzes and does not turn — that is the deadband, not a bug.duty 低於百分之幾時馬達只會嗡嗡叫而不轉——那是死區,不是 bug。デューティが数パーセントを下回るとモータは唸るだけで回らない——それはデッドバンドであってバグではない。Di bawah beberapa persen duty, motor berdengung dan tidak berputar — itu deadband, bukan bug.

Done when完成條件完了条件Selesai bila

Reference answer — not released yet參考解答 —— 尚未開放参考解答 — まだ公開されていませんJawaban acuan — belum dirilis

24 pts分点poin6HOST SIDE

Retire LabVIEW: the same panel in Python讓 LabVIEW 退休:用 Python 做同一個控制面板LabVIEW を引退させる:同じパネルを Python でPensiunkan LabVIEW: panel yang sama dalam Python

  • pyserial
  • Tkinter
  • Threads
  • Python 3

“better use python to code gui program to replace labview” ↳ added after the notebook page

Rebuild tasks 3–5 as one Python window: a port selector, an echo self-test, a live plot of the filtered stream, and a duty slider. Same FPGA bitstream, same 115200 8N1 link — only the desk side changes. pyserial plus stdlib tkinter is the whole dependency list, which is the argument for doing it this way. 把第 3 到第 5 題重做成一個 Python 視窗:串列埠選單、回傳自我測試、濾波資料的即時繪圖,以及一根 duty 滑桿。FPGA 的 bitstream 一樣、115200 8N1 的連線一樣——只有桌上這端換掉。相依套件就只有 pyserial 加上標準函式庫的 tkinter,這就是這樣做的理由。課題 3〜5 を一つの Python ウィンドウとして作り直す:ポート選択、エコーの自己テスト、フィルタ済みデータのライブプロット、そしてデューティのスライダ。FPGA のビットストリームも 115200 8N1 のリンクも同じで、変わるのは机の上だけだ。依存は pyserial と標準ライブラリの tkinter だけ——それがこのやり方を選ぶ理由になる。Bangun ulang tugas 3–5 sebagai satu jendela Python: pemilih port, uji-mandiri gema, plot langsung aliran hasil tapis, dan penggeser duty. Bitstream FPGA yang sama, sambungan 115200 8N1 yang sama — hanya sisi mejanya yang berubah. pyserial ditambah tkinter dari stdlib adalah seluruh daftar dependensinya, dan itulah alasan melakukannya dengan cara ini.

One byte stream now carries three different things, so give it a frame: A5 | cmd | len | payload… | xor. Sync on A5, drop the frame if the checksum disagrees, and never assume one read() returns one frame. 同一條位元組串流現在要載三種東西,所以給它一個框架:A5 | cmd | len | payload… | xor。用 A5 同步,checksum 不合就丟掉整個 frame,而且永遠不要假設一次 read() 剛好回來一個 frame。一本のバイトストリームが三種類のものを運ぶことになるので、フレームを与える:A5 | cmd | len | payload… | xor。A5 で同期し、チェックサムが合わなければそのフレームを捨てる。1 回の read() が 1 フレームを返すとは決して仮定しないこと。Satu aliran byte sekarang membawa tiga hal berbeda, jadi berilah ia frame: A5 | cmd | len | payload… | xor. Sinkronkan pada A5, buang frame-nya kalau checksum tidak cocok, dan jangan pernah mengandaikan satu read() mengembalikan satu frame.

Target numbers目標數字目標値Angka target

Port串列埠ポートPort
serial.Serial(port, 115200)
Defaults預設值デフォルトNilai bawaan
8N1, no flow control
Reader讀取執行緒リーダPembaca
1 daemon thread → queue
UI drainUI 取用UI の取り出しPengurasan UI
root.after(30 ms)
Frame框架フレームFrame
A5 · cmd · len · data · xor
Windows port >= 10Windows 埠號 >= 10Windows のポート番号 >= 10Port Windows >= 10
\\.\COM10

Traps陷阱落とし穴Jebakan

  • Never touch a Tk widget from the reader thread. Push bytes into a queue.Queue and drain it from after() on the main thread — this is the single most common way these panels hang.絕對不要從讀取執行緒去碰 Tk 元件。把位元組丟進 queue.Queue,再由主執行緒的 after() 取出——這類面板當掉,最常見的原因就是這個。リーダスレッドから Tk のウィジェットに触れてはいけない。バイト列は queue.Queue に入れ、メインスレッドの after() で取り出す——この種のパネルがフリーズする原因の第一位がこれだ。Jangan pernah menyentuh widget Tk dari thread pembaca. Dorong byte-nya ke dalam queue.Queue dan kuras dari after() di thread utama — inilah cara paling umum panel semacam ini menggantung.
  • ser.read(n) returns up to n bytes when the timeout expires. Accumulate into a buffer and parse frames out of it; do not treat one read as one message.ser.read(n) 在逾時的時候回傳的是最多 n 個位元組。請累積到緩衝區裡再從中解析 frame;不要把一次讀取當成一則訊息。ser.read(n) はタイムアウト時に最大 n バイトを返す。バッファに貯めてからフレームを切り出すこと。1 回の read を 1 メッセージとして扱ってはいけない。ser.read(n) mengembalikan paling banyak n byte ketika timeout-nya habis. Kumpulkan ke dalam buffer dan parse frame-nya dari sana; jangan perlakukan satu read sebagai satu pesan.
  • A Tk Scale fires its callback on every pixel of drag. Throttle it, or send only on release, or you queue hundreds of duty writes into a 115200 pipe.Tk 的 Scale 每拖動一個像素就觸發一次回呼。要節流,或只在放開時送出,否則你會把幾百筆 duty 寫入塞進 115200 的管線裡。Tk の Scale はドラッグ 1 ピクセルごとにコールバックを呼ぶ。スロットリングするか、離した時だけ送ること。さもないと 115200 の細い管に数百回の書き込みを詰め込むことになる。Scale pada Tk memicu callback-nya pada setiap piksel gerakan. Batasi lajunya, atau kirim hanya saat dilepas, kalau tidak kamu menumpuk ratusan penulisan duty ke dalam pipa 115200.
  • Close the port on WM_DELETE_WINDOW. On Windows the handle stays locked and the next run fails with "Access is denied" until you replug.在 WM_DELETE_WINDOW 時關閉串列埠。在 Windows 上那個 handle 會一直被鎖住,下次執行會出現「Access is denied」,直到你把線拔掉重插。WM_DELETE_WINDOW でポートを閉じること。Windows ではハンドルがロックされたままになり、挿し直すまで次回の実行が「Access is denied」で失敗する。Tutup port-nya pada WM_DELETE_WINDOW. Di Windows, handle-nya tetap terkunci dan jalan berikutnya gagal dengan "Access is denied" sampai kamu mencabut dan memasangnya lagi.
  • Plot decimated data. Redrawing 1000 points at 1 kHz starves the event loop; keep a ring of the last ~500 samples and redraw at 30 Hz.繪圖前先抽取。以 1 kHz 重畫 1000 個點會把事件迴圈餓死;保留最近約 500 筆的環形緩衝,用 30 Hz 重畫就好。プロットは間引くこと。1 kHz で 1000 点を再描画するとイベントループが飽和する。直近 500 サンプル程度のリングを持ち、30 Hz で描き直す。Plot data yang sudah didesimasi. Menggambar ulang 1000 titik pada 1 kHz membuat event loop kelaparan; simpan ring berisi ~500 cuplikan terakhir dan gambar ulang pada 30 Hz.

Done when完成條件完了条件Selesai bila

Reference answer — not released yet參考解答 —— 尚未開放参考解答 — まだ公開されていませんJawaban acuan — belum dirilis

10 pts分点poin7THE REPO

Get on the VPN, make the repo, push all of it連上 VPN、開好 repo、把全部推上去VPN に入り、リポジトリを作り、全部を push するMasuk ke VPN, buat repo-nya, push semuanya

  • VPN
  • Gitea
  • Commit history
  • .gitignore
  • git

“apply vpn account, create repo on gitea.rflab.lan and push all your homework” ↳ added after the notebook page

Three steps, in this order, and none of them is optional. Get a VPN account — the steps are in the RF&MW Lab VPN tab: pick an id and a password, send them to me, wait for my email, then set the client up from the deck. Connect, open gitea.rflab.lan and register your own account. Then make one repository and push every task on this sheet into it. Nothing here is reachable from the open internet, so the VPN is not a convenience — it is the only door. 三個步驟,照這個順序,一個都不能跳。先申請 VPN 帳號——步驟在 RF&MW Lab VPN 分頁:想好帳號密碼、傳給我、等我的信,然後照投影片設定 client。連上之後,打開 gitea.rflab.lan 註冊自己的帳號。接著開一個 repository,把這份工作單上的每一題都推進去。這裡的東西從外網一律連不到,所以 VPN 不是方便與否的問題——它是唯一的門。三つの手順を、この順で。どれも省略不可だ。まず VPN アカウントを申請する——手順は RF&MW Lab VPN タブにある:ID とパスワードを決めて私に送り、返信のメールを待ち、スライドに従ってクライアントを設定する。接続したら gitea.rflab.lan を開いて自分のアカウントを登録する。そのうえでリポジトリを一つ作り、このシートの全課題をそこへ push する。ここにあるものは外部インターネットからは一切届かないので、VPN は便利さの話ではなく、唯一の入口だ。Tiga langkah, dalam urutan ini, dan tidak satu pun opsional. Dapatkan akun VPN — langkahnya ada di tab VPN RF&MW Lab: pilih id dan kata sandi, kirimkan ke saya, tunggu email saya, lalu siapkan klien-nya mengikuti dek slide. Sambungkan, buka gitea.rflab.lan dan daftarkan akunmu sendiri. Kemudian buat satu repositori dan push setiap tugas di lembar ini ke sana. Tidak ada satu pun di sini yang bisa dijangkau dari internet terbuka, jadi VPN bukan soal kenyamanan — ia satu-satunya pintu.

Why this is a task and not a formality. Git is the lab's memory. Every build on this worksheet goes through a version that works and a version that does not, and the only cheap way to get back to the one that worked is to have committed it. Without that you keep a folder called task5_final_v3_ok and you still cannot say what changed between it and task5_final_v2. With it, git diff answers in one line, git bisect finds the commit that broke the servo in a few steps, and a branch lets you try the risky rewrite without putting the working bitstream at risk. It is also how anyone else reads your work: I review what you pushed, not what is on your laptop, and the student who picks this up after you graduate gets the history or gets nothing. Every job you will apply to assumes you already have this — nobody teaches it twice, and a repository with a real history is the most portable evidence you own that you did the work yourself. 為什麼這是一題,而不是一個形式。Git 是實驗室的記憶。這份工作單上的每一個設計,都會經過「會動的版本」和「不會動的版本」,而要回到會動的那一個,唯一便宜的方法就是當初有 commit 起來。沒有它,你手上只會有一個叫 task5_final_v3_ok 的資料夾,而且你還是說不出它和 task5_final_v2 之間到底差在哪。有了它,git diff 一行就回答你,git bisect 幾步就找出把伺服機弄壞的那個 commit,而開一條 branch 就能讓你去試那個有風險的改寫,同時不賠上已經會動的 bitstream。它也是別人讀你作品的方式:我 review 的是你推上去的東西,不是你筆電裡的東西;而在你畢業之後接手的人,拿到的要嘛是歷史,要嘛什麼都沒有。你之後要應徵的每一份工作都預設你已經會了——沒有人會教第二次,而一個有真實歷史的 repository,是你手上最好帶著走、也最能證明這些東西是你自己做的證據。なぜこれが形式ではなく課題なのか。Git は研究室の記憶だ。このワークシートのどのビルドも、動いた版と動かなかった版を通り抜ける。そして動いた版へ安く戻る唯一の方法は、その時点で commit してあることだ。それが無ければ手元に残るのは task5_final_v3_ok というフォルダだけで、task5_final_v2 との違いは結局言えない。あれば git diff が一行で答え、git bisect が数手でサーボを壊した commit を見つけ、ブランチを切れば動くビットストリームを危険に晒さずに大胆な書き直しを試せる。他人が君の成果を読む方法でもある:私がレビューするのは push されたものであって、君のノート PC の中身ではない。君の卒業後にこれを引き継ぐ学生は、履歴を受け取るか、何も受け取らないかのどちらかだ。これから応募するどの職場も、これはもう出来る前提で話す——二度は教えられない。そして実際の履歴を持つリポジトリは、この作業を自分でやったという、最も持ち運びやすい証拠になる。Mengapa ini sebuah tugas dan bukan formalitas. Git adalah ingatan lab ini. Setiap build di lembar kerja ini melewati sebuah versi yang jalan dan sebuah versi yang tidak, dan satu-satunya cara murah untuk kembali ke yang jalan adalah pernah meng-commit-nya. Tanpa itu kamu menyimpan folder bernama task5_final_v3_ok dan tetap tidak bisa menyebut apa yang berubah antara folder itu dan task5_final_v2. Dengan itu, git diff menjawab dalam satu baris, git bisect menemukan commit yang merusak servonya dalam beberapa langkah, dan sebuah branch membiarkanmu mencoba penulisan ulang yang berisiko tanpa mempertaruhkan bitstream yang sudah jalan. Itu juga cara orang lain membaca karyamu: saya meninjau apa yang kamu push, bukan apa yang ada di laptopmu, dan mahasiswa yang meneruskan ini setelah kamu lulus mendapat riwayatnya atau tidak mendapat apa-apa. Setiap pekerjaan yang akan kamu lamar mengandaikan kamu sudah menguasai ini — tidak ada yang mengajarkannya dua kali, dan sebuah repositori dengan riwayat yang sungguhan adalah bukti paling mudah dibawa yang kamu punya bahwa pekerjaan itu kamu kerjakan sendiri.

One repository for the whole sheet, private, with me added as a collaborator so it can be reviewed. The layout is fixed so that eight repositories can be read the same way: 整份工作單一個 repository,設為 private,並把我加為協作者,這樣才能 review。目錄結構是固定的,這樣八個人的 repo 才能用同一種方式讀:シート全体でリポジトリは一つ、private にして、レビューできるよう私を collaborator に追加すること。構成は固定する。そうすれば八人分のリポジトリを同じ読み方で読める:Satu repositori untuk seluruh lembar ini, private, dengan saya ditambahkan sebagai kolaborator agar bisa ditinjau. Tata letaknya dibakukan supaya delapan repositori bisa dibaca dengan cara yang sama:

dst-<your-id>/
  README.md          # one table: task, folder, top module, YouTube link
  .gitignore         # Vivado build output never enters the repo
  rtl/               # the Verilog, one folder per task
  tb/                # the testbenches that produced the waveforms
  xdc/               # pin constraints
  doc/               # the state diagrams: .dot and .svg
  host/              # the task-6 Python panel

The history is part of the hand-in. One commit per task at least, written when you finished that task, with a message that says what changed — and a tag task1 … task10 on the commit where each one worked. A repository whose entire history is a single commit called "final" tells me you did the work somewhere else and copied it in, which is exactly what this task exists to stop. 歷史紀錄本身就是繳交內容的一部分。每一題至少一個 commit,在你做完那一題的當下提交,訊息要寫清楚改了什麼——並在每一題成功的那個 commit 上打標籤 task1 … task10。一個整段歷史只有一個叫 "final" 的 commit 的 repo,等於告訴我你在別的地方做完才複製進來,而這一題存在的目的就是要擋掉這件事。履歴も提出物のうちだ。最低でも課題ごとに一つの commit を、その課題を終えたその時に、何を変えたか分かるメッセージで。そして各課題が動いた commit に task1 … task10 のタグを付ける。履歴全体が "final" という一つの commit だけのリポジトリは、別の場所で作ってコピーしたと私に告げているのと同じで、この課題はまさにそれを防ぐためにある。Riwayatnya adalah bagian dari pengumpulan. Minimal satu commit per tugas, ditulis saat kamu menyelesaikan tugas itu, dengan pesan yang menyebut apa yang berubah — dan sebuah tag task1 … task10 pada commit tempat masing-masing berhasil. Repositori yang seluruh riwayatnya satu commit bernama "final" memberi tahu saya bahwa kamu mengerjakannya di tempat lain lalu menyalinnya masuk, dan justru itulah yang hendak dicegah tugas ini.

What belongs in the repository哪些東西該進 repositoryリポジトリに入れてよいものApa yang masuk ke repositori

Source only: the Verilog, the testbenches, the constraints, the state diagrams, the host scripts, the README — and the .gitignore itself, which is source too and is the one file about generated files that has to be committed. Everything Vivado writes stays out: .runs/ .cache/ .Xil/ *.jou *.log, the bitstreams, the editor backups. Write the ignore file before the first git add, then make the tool prove it: git status --short should name nothing you did not write yourself, and git check-ignore -v <path> tells you which line of .gitignore is keeping a file out. 只有原始碼:Verilog、testbench、腳位約束、狀態圖、主機端腳本、README——還有 .gitignore 本身,它也是原始碼,而且是唯一一個「關於產生檔案」卻必須 commit 進去的檔案。Vivado 寫出來的東西一律不進去:.runs/ .cache/ .Xil/ *.jou *.log、bitstream、編輯器的備份檔。ignore 檔要在第一次 git add 之前就寫好,然後讓工具證明給你看:git status --short 不該列出任何不是你自己寫的檔案,而 git check-ignore -v <path> 會告訴你是 .gitignore 的哪一行把某個檔案擋在外面。入れるのはソースだけだ:Verilog、テストベンチ、ピン制約、状態遷移図、ホスト側のスクリプト、README——そして .gitignore 自身。これもソースであり、生成物について書かれた唯一のコミットすべきファイルだ。Vivado が書き出すものは入れない:.runs/ .cache/ .Xil/ *.jou *.log、ビットストリーム、エディタのバックアップ。ignore ファイルは最初の git add の前に書き、あとはツールに証明させる:git status --short に自分が書いていないファイルが出てはいけないし、git check-ignore -v <path> はどの行がそのファイルを弾いているのかを教えてくれる。Hanya sumber: Verilog, testbench, constraint pin, diagram state, skrip sisi host, README — dan .gitignore itu sendiri, yang juga sumber dan merupakan satu-satunya berkas tentang berkas hasil yang wajib di-commit. Semua yang ditulis Vivado tetap di luar: .runs/ .cache/ .Xil/ *.jou *.log, bitstream, berkas cadangan editor. Tulis berkas ignore sebelum git add yang pertama, lalu biarkan alatnya membuktikan: git status --short tidak boleh menyebut berkas yang bukan tulisanmu, dan git check-ignore -v <path> memberi tahu baris .gitignore mana yang menahan sebuah berkas.

An ignore rule only applies to files git is not already tracking. If the build output is in the index — on the first try it usually is — adding a rule changes nothing, and you have to untrack it by hand. git rm --cached takes a file out of the index and leaves it on your disk; -r does the same for a directory. Two things to remember: without --cached, git rm deletes the file from your disk as well, and untracking does not make the clone any smaller, because the blob stays in the history — which is why this is done early rather than at the end. ignore 規則只對 git 還沒開始追蹤的檔案有效。如果編譯產物已經在 index 裡——第一次做幾乎都是這樣——再補規則也沒有用,必須自己把它取消追蹤。git rm --cached 只把檔案從 index 拿掉,檔案還留在你的磁碟上;加上 -r 就是對整個目錄做同樣的事。有兩件事要記得:少了 --cached,git rm 會連磁碟上的檔案一起刪掉;而且取消追蹤不會讓 clone 變小,因為那個 blob 還留在歷史裡——所以這件事要趁早做,不要留到最後。ignore の規則は、git がまだ追跡していないファイルにしか効かない。ビルド生成物がすでに index に入っているなら——最初はたいていそうなる——規則を足しても何も変わらず、自分で追跡から外すしかない。git rm --cached はファイルを index から外すだけで、ディスクには残す。-r を付ければディレクトリでも同じことができる。覚えておくことが二つ:--cached を落とすと git rm はディスクのファイルごと消す。そして追跡を外してもクローンは小さくならない。blob は履歴に残るからだ——だからこれは最後ではなく、早いうちにやる。Aturan ignore hanya berlaku untuk berkas yang belum dilacak git. Kalau keluaran build sudah ada di index — pada percobaan pertama biasanya memang begitu — menambah aturan tidak mengubah apa pun, dan kamu harus melepas pelacakannya sendiri. git rm --cached mengeluarkan berkas dari index dan membiarkannya di diskmu; -r melakukan hal yang sama untuk sebuah direktori. Dua hal yang perlu diingat: tanpa --cached, git rm ikut menghapus berkas dari disk, dan melepas pelacakan tidak mengecilkan clone karena blob-nya tetap ada di riwayat — itulah sebabnya ini dikerjakan sedini mungkin, bukan di akhir.

git check-ignore -v .runs/impl_1/top.rpt   # which rule catches it, if any
git rm -r --cached .runs/ .cache/ .Xil/    # untrack, keep on disk
git rm --cached vivado.jou vivado.log      # untrack single files
git commit -m "stop tracking Vivado build output"
git status --short                         # only your own files are left

SSH key for GiteaGitea 的 SSH 金鑰Gitea 用の SSH 鍵Kunci SSH untuk Gitea

The repository is reached over SSH, not HTTPS, so before the first push each machine you work on needs a key pair, and Gitea needs the public half. Once per machine, not per repository: Repository 走 SSH,不走 HTTPS,所以在第一次 push 之前,你用的每一台機器都要有一組金鑰,而 Gitea 要有其中的公鑰。每台機器做一次,不是每個 repo 做一次:リポジトリには HTTPS ではなく SSH で接続する。だから最初の push の前に、作業する各マシンに鍵ペアが必要で、Gitea にはその公開鍵が要る。リポジトリごとではなく、マシンごとに一度:Repositorinya diakses lewat SSH, bukan HTTPS, jadi sebelum push pertama setiap mesin yang kamu pakai butuh sepasang kunci, dan Gitea butuh bagian publiknya. Sekali per mesin, bukan per repositori:

  1. Generate the pair. Accept the default path; a passphrase is optional but recommended. This writes id_ed25519 (private — never share it, never commit it) and id_ed25519.pub (public).產生金鑰對。路徑用預設的;passphrase 可以不設,但建議設。這會寫出 id_ed25519(私鑰——絕不外流、絕不 commit)和 id_ed25519.pub(公鑰)。鍵ペアを生成する。パスは既定のままで。パスフレーズは任意だが推奨。id_ed25519(秘密鍵——決して共有せず、commit もしない)と id_ed25519.pub(公開鍵)が書き出される。Buat pasangan kuncinya. Terima path bawaan; passphrase opsional tapi dianjurkan. Ini menulis id_ed25519 (privat — jangan pernah dibagikan, jangan pernah di-commit) dan id_ed25519.pub (publik).
    ssh-keygen -t ed25519 -C "you@example.edu.tw"
  2. Print the public key and copy the whole single line — it starts with ssh-ed25519 and ends with your comment.把公鑰印出來,整行複製——它以 ssh-ed25519 開頭、以你的註解結尾。公開鍵を表示し、その一行を丸ごとコピーする——ssh-ed25519 で始まり、コメントで終わる。Tampilkan kunci publiknya dan salin satu baris itu seluruhnya — dimulai dengan ssh-ed25519 dan diakhiri dengan komentarmu.
    cat ~/.ssh/id_ed25519.pub
  3. With the VPN connected, open gitea.rflab.lan: your avatar → Settings → SSH / GPG Keys → Add Key. Paste the line into Content, name it after the machine (laptop, lab-pc), save.連著 VPN 打開 gitea.rflab.lan:你的頭像 → Settings → SSH / GPG Keys → Add Key。把那一行貼進 Content,名稱用機器的名字(laptop、lab-pc),存檔。VPN に接続した状態で gitea.rflab.lan を開く:アバター → Settings → SSH / GPG Keys → Add Key。その一行を Content に貼り、マシン名(laptop、lab-pc)を付けて保存する。Dengan VPN tersambung, buka gitea.rflab.lan: avatarmu → Settings → SSH / GPG Keys → Add Key. Tempel baris itu ke Content, beri nama sesuai mesinnya (laptop, lab-pc), simpan.
  4. Test it. The first time, ssh asks whether to trust the host fingerprint — answer yes. Gitea must reply with Hi there, <you>! You've successfully authenticated. Permission denied (publickey) means the key in Gitea is not the one on this machine, or ssh picked a different key file.測試。第一次 ssh 會問要不要信任主機指紋——回答 yes。Gitea 必須回 Hi there, <you>! You've successfully authenticated。出現 Permission denied (publickey) 表示 Gitea 裡的金鑰不是這台機器的,或 ssh 用了別的金鑰檔。テストする。初回はホストのフィンガープリントを信頼するか聞かれる——yes と答える。Gitea が Hi there, <you>! You've successfully authenticated と返さなければならない。Permission denied (publickey) なら、Gitea に登録した鍵がこのマシンのものではないか、ssh が別の鍵ファイルを使っている。Uji. Pertama kali, ssh bertanya apakah sidik jari host dipercaya — jawab yes. Gitea harus membalas Hi there, <you>! You've successfully authenticated. Permission denied (publickey) berarti kunci di Gitea bukan yang ada di mesin ini, atau ssh memakai berkas kunci lain.
    ssh -T git@gitea.rflab.lan
  5. Use the SSH URL as the remote. If a remote with the https:// URL already exists, switch it rather than adding a second one.remote 用 SSH 的網址。如果已經有一個 https:// 的 remote,直接改掉它,不要再加第二個。remote には SSH の URL を使う。すでに https:// の remote があるなら、二つ目を足すのではなく差し替える。Pakai URL SSH sebagai remote. Kalau sudah ada remote dengan URL https://, ganti saja alih-alih menambah yang kedua.
    git remote add origin git@gitea.rflab.lan:<you>/dst-<your-id>.git
    git remote set-url origin git@gitea.rflab.lan:<you>/dst-<your-id>.git   # if origin already exists

On Windows the same commands work in Git Bash, MSYS2 or PowerShell with the built-in OpenSSH. If you set a passphrase and do not want to retype it, start ssh-agent and run ssh-add once per session. 在 Windows 上,Git Bash、MSYS2 或用內建 OpenSSH 的 PowerShell 都跑同樣的指令。如果設了 passphrase 又不想每次重打,每次開機後啟動 ssh-agent 並執行一次 ssh-add。Windows でも Git Bash、MSYS2、または内蔵 OpenSSH の PowerShell で同じコマンドが使える。パスフレーズを設定して毎回打ちたくないなら、セッションごとに ssh-agent を起動して ssh-add を一度実行する。Di Windows perintah yang sama berjalan di Git Bash, MSYS2, atau PowerShell dengan OpenSSH bawaan. Kalau kamu memasang passphrase dan tidak mau mengetiknya ulang, jalankan ssh-agent lalu ssh-add sekali per sesi.

Target numbers目標數字目標値Angka target

Server伺服器サーバーServer
gitea.rflab.lan · VPN only
RepositoryRepositoryリポジトリRepositori
dst-<your-id>, private
Collaborator協作者コラボレータKolaborator
me, with read access
Default branch預設分支既定ブランチBranch bawaan
main
CommitsCommit 數コミット数Commit
>= 1 per task, dated as you went
Tags標籤タグTag
task1 … task10
Clone sizeClone 大小クローンのサイズUkuran clone
< 20 MB, no build output
Ignored被忽略的無視するものDiabaikan
*.jou *.log .Xil/ *.runs/ *.cache/

Traps陷阱落とし穴Jebakan

  • gitea.rflab.lan does not resolve when the VPN is down, and git reports that as a confusing clone failure. Check the name first — ping gitea.rflab.lan — before you go looking for a git problem that is not there.VPN 沒連上的時候 gitea.rflab.lan 根本解析不出來,而 git 會把這件事報成一個看起來很莫名其妙的 clone 失敗。先確認名字解得出來——ping gitea.rflab.lan——再去找那個根本不存在的 git 問題。VPN が落ちていると gitea.rflab.lan は名前解決できず、git はそれを紛らわしい clone の失敗として報告する。まず名前を確認すること——ping gitea.rflab.lan——存在しない git の問題を探しに行く前に。gitea.rflab.lan tidak bisa di-resolve saat VPN mati, dan git melaporkannya sebagai kegagalan clone yang membingungkan. Periksa namanya dulu — ping gitea.rflab.lan — sebelum kamu mencari masalah git yang sebenarnya tidak ada.
  • Use the SSH remote — git@gitea.rflab.lan:<you>/dst-<your-id>.git — not the https:// one. Over HTTPS the lab certificate makes git complain, and the tempting fix, git config --global http.sslVerify false, turns verification off for every server you will ever talk to. An SSH key needs no certificate and no password prompt: add your public key under Gitea → Settings → SSH Keys, and ssh -T git@gitea.rflab.lan must greet you by name before the first push.用 SSH 的 remote——git@gitea.rflab.lan:<you>/dst-<your-id>.git——不要用 https:// 的。走 HTTPS 時實驗室的憑證會讓 git 抱怨,而那個很誘人的解法 git config --global http.sslVerify false 會把你以後連到的每一台伺服器的驗證都關掉。SSH 金鑰不需要憑證、也不會問密碼:把你的公鑰加到 Gitea → Settings → SSH Keys,然後在第一次 push 之前 ssh -T git@gitea.rflab.lan 必須能叫出你的名字。remote は SSH の git@gitea.rflab.lan:<you>/dst-<your-id>.git を使い、https:// は使わない。HTTPS では研究室の証明書で git が文句を言い、つい手を出したくなる git config --global http.sslVerify false は今後接続するあらゆるサーバーの検証を切ってしまう。SSH 鍵なら証明書もパスワード入力も要らない:公開鍵を Gitea → Settings → SSH Keys に登録し、最初の push の前に ssh -T git@gitea.rflab.lan が自分の名前で挨拶してくることを確認する。Pakai remote SSH — git@gitea.rflab.lan:<you>/dst-<your-id>.git — bukan yang https://. Lewat HTTPS sertifikat lab membuat git mengeluh, dan perbaikan yang menggoda, git config --global http.sslVerify false, mematikan verifikasi untuk setiap server yang akan pernah kamu hubungi. Kunci SSH tidak butuh sertifikat maupun prompt kata sandi: tambahkan kunci publikmu di Gitea → Settings → SSH Keys, dan ssh -T git@gitea.rflab.lan harus menyapamu dengan nama sebelum push pertama.
  • A Vivado project directory is mostly build output. Write the .gitignore before the first commit; once .runs/ is in the history, deleting it in a later commit does not make the clone any smaller.Vivado 的專案目錄大部分都是編譯產物。.gitignore 要在第一個 commit 之前就寫好;一旦 .runs/ 進了歷史,之後再 commit 刪掉它,clone 也不會變小。Vivado のプロジェクトディレクトリはほとんどがビルド生成物だ。.gitignore は最初の commit の前に書くこと。.runs/ が一度履歴に入ってしまえば、後の commit で消してもクローンは小さくならない。Direktori proyek Vivado sebagian besar adalah keluaran build. Tulis .gitignore sebelum commit pertama; begitu .runs/ masuk riwayat, menghapusnya di commit berikutnya tidak membuat clone-nya mengecil.
  • Never commit a password, and never put one in a remote URL — https://user:pass@gitea… is stored in .git/config in clear text and travels with the repository. With the SSH remote there is nothing to store — the key authenticates you.絕對不要把密碼 commit 進去,也不要把密碼寫進 remote 的網址——https://user:pass@gitea… 會以明文存在 .git/config 裡,而且會跟著 repo 一起走。用 SSH 的 remote 就沒有東西需要存——金鑰就是你的身分。パスワードを commit してはいけないし、remote の URL に埋め込んでもいけない——https://user:pass@gitea… は .git/config に平文で残り、リポジトリと一緒に持ち歩かれる。SSH の remote なら保存すべきものは何もない——鍵が認証を担う。Jangan pernah meng-commit kata sandi, dan jangan menaruhnya di URL remote — https://user:pass@gitea… tersimpan di .git/config dalam teks polos dan ikut berpindah bersama repositorinya. Dengan remote SSH tidak ada yang perlu disimpan — kuncinya yang mengautentikasi kamu.
  • On Windows, CRLF makes every line of every file look changed on the first commit from another machine. Set core.autocrlf or commit a .gitattributes with * text=auto before anyone else clones it.在 Windows 上,CRLF 會讓別台機器第一次 commit 的時候,每個檔案的每一行看起來都被改過。先設定 core.autocrlf,或先 commit 一個寫著 * text=auto 的 .gitattributes,再讓別人 clone。Windows では CRLF のせいで、別のマシンからの最初の commit ですべてのファイルの全行が変更扱いになる。誰かが clone する前に core.autocrlf を設定するか、* text=auto と書いた .gitattributes を commit しておくこと。Di Windows, CRLF membuat setiap baris di setiap berkas tampak berubah pada commit pertama dari mesin lain. Setel core.autocrlf atau commit sebuah .gitattributes berisi * text=auto sebelum orang lain meng-clone-nya.

Done when完成條件完了条件Selesai bila

Reference answer — not released yet參考解答 —— 尚未開放参考解答 — まだ公開されていませんJawaban acuan — belum dirilis

15 pts分点poin8SEQUENCE

Find 1011 in 1011011: once Mealy, once Moore在 1011011 裡找出 1011:一次 Mealy,一次 Moore1011011 の中から 1011 を見つける:Mealy で一度、Moore で一度Temukan 1011 dalam 1011011: sekali Mealy, sekali Moore

  • Verilog
  • FSM
  • Mealy
  • Moore
  • Overlap
  • Testbench

“change homework9 to detect 1011 sequence from input sequence of 1011011 with mealy and moore type” ↳ replaces the state-diagram task

A serial input x delivers one bit per tick. Build two detectors that raise z whenever the last four bits were 1011 — one written as a Mealy machine, one as a Moore machine — and feed both the same stream, 1011011, first bit first. Detection overlaps: the last 1 of one match may be the first 1 of the next. So 1011011 holds two matches, bits 1–4 and bits 4–7, and each detector must fire twice. 一條序列輸入 x,每個 tick 送進一個位元。做兩個偵測器,只要最近四個位元是 1011 就把 z 拉高——一個寫成 Mealy 機,一個寫成 Moore 機——並把同一串輸入 1011011(從第一個位元開始送)同時餵給兩者。偵測是可重疊的:一次比對的最後一個 1,可以是下一次比對的第一個 1。所以 1011011 裡有兩次比對成功,第 1–4 位元和第 4–7 位元,兩個偵測器都必須觸發兩次。シリアル入力 x は tick ごとに 1 ビットを届ける。直近 4 ビットが 1011 になるたびに z を上げる検出器を二つ作る——一つは Mealy 機械、一つは Moore 機械として——そして両方に同じ系列 1011011 を先頭ビットから流す。検出は重なりあり:ある一致の最後の 1 が、次の一致の最初の 1 になってよい。したがって 1011011 には一致が二つ、1–4 ビット目と 4–7 ビット目にあり、どちらの検出器も二回発火しなければならない。Sebuah masukan serial x mengirim satu bit per tick. Bangun dua detektor yang menaikkan z setiap kali empat bit terakhir adalah 1011 — satu ditulis sebagai mesin Mealy, satu sebagai mesin Moore — dan beri keduanya aliran yang sama, 1011011, bit pertama lebih dulu. Deteksinya tumpang-tindih: angka 1 terakhir dari satu kecocokan boleh menjadi angka 1 pertama dari kecocokan berikutnya. Jadi 1011011 memuat dua kecocokan, bit 1–4 dan bit 4–7, dan setiap detektor harus menyala dua kali.

Draw the state diagram first; here the drawing is the design. The Mealy machine needs four states, named for how much of the pattern has been seen: S0 (nothing), S1 (1), S2 (10), S3 (101), and the output rides on one arc, S3 —1/1→ S1. The Moore machine needs a fifth state, S4 (1011), with z=1 written in the bubble. The arcs worth thinking about are the ones after a mismatch or a hit. From S3 a 0 goes to S2, not S0, because 1010 still ends in 10; after a hit the machine goes to S1, because 1011 ends in 1. Those two arcs are what make overlap work. 先畫狀態圖;這一題裡,圖就是設計。Mealy 機需要四個狀態,依照已經看到多少樣式來命名:S0(什麼都沒有)、S1(1)、S2(10)、S3(101),而輸出掛在一支箭頭上:S3 —1/1→ S1。Moore 機需要第五個狀態 S4(1011),z=1 寫在圓圈裡。值得想清楚的是比對失敗或比對成功之後的箭頭。從 S3 收到 0 要去 S2 而不是 S0,因為 1010 的結尾仍然是 10;比對成功後要去 S1,因為 1011 的結尾是 1。可重疊偵測就靠這兩支箭頭。まず状態遷移図を描くこと。この課題では図こそが設計だ。Mealy 機械には、パターンをどこまで見たかで名付けた四つの状態が要る:S0(何もなし)、S1(1)、S2(10)、S3(101)。出力は一本の矢印 S3 —1/1→ S1 に乗る。Moore 機械には五つ目の状態 S4(1011)が要り、z=1 を丸の中に書く。考えるべきは、不一致の後と一致の後の矢印だ。S3 で 0 が来たら S0 ではなく S2 へ行く——1010 はまだ 10 で終わっているから。一致の後は S1 へ行く——1011 は 1 で終わっているから。重なりありの検出を成り立たせているのは、この二本の矢印である。Gambar diagram state lebih dulu; di sini gambarnya adalah desainnya. Mesin Mealy butuh empat state, dinamai menurut seberapa banyak pola yang sudah terlihat: S0 (belum ada), S1 (1), S2 (10), S3 (101), dan keluarannya menumpang di satu busur, S3 —1/1→ S1. Mesin Moore butuh state kelima, S4 (1011), dengan z=1 ditulis di dalam gelembung. Busur yang perlu dipikirkan adalah busur setelah ketidakcocokan atau setelah kecocokan. Dari S3, angka 0 menuju S2, bukan S0, karena 1010 masih berakhir dengan 10; setelah kecocokan mesin menuju S1, karena 1011 berakhir dengan 1. Dua busur itulah yang membuat tumpang-tindih bekerja.

Then put the two outputs on one waveform. The Mealy z is high during bits 4 and 7 — while the fourth bit of the match is still on the input. The Moore z is high during bits 5 and 8, one tick later, because it has to wait for the clock edge that moves the machine into S4. Same bits, same answer, one tick apart: the Mealy–Moore offset, on a machine small enough to see whole. 接著把兩個輸出放在同一張波形上。Mealy 的 z 在第 4 和第 7 個位元期間為高——此時比對的第四個位元還在輸入端上。Moore 的 z 在第 5 和第 8 個位元期間為高,晚了一個 tick,因為它得等到把機器送進 S4 的那個時脈邊緣。同樣的位元、同樣的答案,相差一個 tick:這就是 Mealy 與 Moore 的時差,只是這次機器小到可以一眼看完。次に、二つの出力を一枚の波形に並べる。Mealy の z は 4 ビット目と 7 ビット目の間 High になる——一致の 4 ビット目がまだ入力に乗っている間だ。Moore の z は 5 ビット目と 8 ビット目の間 High になり、1 tick 遅れる。機械を S4 へ移すクロックエッジを待たなければならないからだ。同じビット、同じ答え、1 tick のずれ:これが Mealy と Moore のずれで、今度は全体が一目で見渡せるほど小さな機械の上にある。Lalu letakkan kedua keluaran di satu gelombang. z Mealy tinggi selama bit 4 dan 7 — saat bit keempat dari kecocokan masih ada di masukan. z Moore tinggi selama bit 5 dan 8, satu tick kemudian, karena ia harus menunggu tepi clock yang memindahkan mesin ke S4. Bit yang sama, jawaban yang sama, berselisih satu tick: selisih Mealy–Moore, pada mesin yang cukup kecil untuk dilihat utuh.

Compare the two比較兩者二つを比べるBandingkan keduanya

Answer each in one or two sentences in your README, using your own waveform and diagrams as the evidence:在你的 README 裡每題用一到兩句回答,並以你自己的波形和狀態圖作為證據:README に各問一〜二文で答えること。根拠には自分の波形と状態遷移図を使う:Jawab masing-masing dalam satu atau dua kalimat di README-mu, dengan gelombang dan diagrammu sendiri sebagai bukti:

  1. States. How many states does each machine need, and why does the Moore machine need exactly one more?狀態數。兩台機器各需要幾個狀態?為什麼 Moore 機剛好多一個?状態数。それぞれの機械にいくつの状態が要るか。Moore 機械がちょうど一つ多いのはなぜか。State. Berapa state yang dibutuhkan tiap mesin, dan mengapa mesin Moore butuh tepat satu lebih banyak?
  2. Timing. In which bits does each z go high, and what makes the Moore output one tick later?時序。兩個 z 各在哪幾個位元為高?是什麼讓 Moore 的輸出晚一個 tick?タイミング。それぞれの z は何ビット目で High になるか。Moore の出力が 1 tick 遅れるのはなぜか。Pewaktuan. Di bit mana tiap z menjadi tinggi, dan apa yang membuat keluaran Moore terlambat satu tick?
  3. What z depends on. Write each output as a function (state only, or state and x). If x changed in the middle of a bit, which z would change with it, and which would stay put until the next edge?z 取決於什麼。把兩個輸出各寫成一個函數(只有狀態,或狀態加上 x)。如果 x 在位元中途改變,哪一個 z 會跟著變,哪一個會維持到下一個邊緣?z は何に依存するか。それぞれの出力を関数として書くこと(状態のみ、または状態と x)。x がビットの途中で変わったら、どちらの z が追従し、どちらが次のエッジまで保たれるか。Apa yang memengaruhi z. Tulis tiap keluaran sebagai fungsi (hanya state, atau state dan x). Kalau x berubah di tengah bit, z mana yang ikut berubah, dan mana yang tetap sampai tepi berikutnya?
  4. Cost. From the Quartus fitter report, how many registers and ALMs does each detector use? Does the extra state cost anything you can measure?成本。從 Quartus 的 fitter 報告看,兩個偵測器各用了多少暫存器和 ALM?多出來的那個狀態,有沒有造成可以量得到的成本?コスト。Quartus の fitter レポートで、それぞれの検出器はレジスタと ALM をいくつ使っているか。一つ多い状態に、測れるほどのコストはあるか。Biaya. Dari laporan fitter Quartus, berapa register dan ALM yang dipakai tiap detektor? Apakah state tambahan itu menimbulkan biaya yang bisa diukur?
  5. Choice. Name one situation where you would pick the Mealy machine and one where you would pick the Moore machine, and say why.選擇。各舉一個你會選 Mealy 機、以及會選 Moore 機的情況,並說明理由。選択。Mealy 機械を選ぶ場面と Moore 機械を選ぶ場面を一つずつ挙げ、理由を述べること。Pilihan. Sebutkan satu situasi di mana kamu akan memilih mesin Mealy dan satu di mana kamu akan memilih mesin Moore, dan jelaskan alasannya.

Target numbers目標數字目標値Angka target

Input stream輸入序列入力系列Aliran masukan
1011011 · first bit first, then 0
Bit rate位元速率ビットレートLaju bit
1 bit per tick · 1 Hz on the board
Matches比對成功次數一致の数Kecocokan
2 · bits 1–4 and 4–7 (overlapping)
MealyMealyMealyMealy
4 states · 2-bit register · z on the arc
MooreMooreMooreMoore
5 states · 3-bit register · z in the bubble
Mealy z highMealy z 為高Mealy z が HighMealy z tinggi
during bits 4 and 7
Moore z highMoore z 為高Moore z が HighMoore z tinggi
during bits 5 and 8
Start啟動開始Mulai
KEY3 sends the stream once
Display顯示表示Tampilan
x · Mealy z · Moore z on LEDR0–2

Traps陷阱落とし穴Jebakan

  • Send the machine back to S0 after a hit and it becomes a non-overlapping detector: it finds bits 1–4, throws away the 1 at bit 4, and misses bits 4–7. The input 1011011 was chosen to catch exactly this. Two hits means overlapping; one hit means you reset after a match.比對成功後把機器送回 S0,它就變成不可重疊的偵測器:它找到第 1–4 位元,丟掉第 4 位元那個 1,於是漏掉第 4–7 位元。輸入 1011011 就是專門為了抓這個錯而選的。兩次命中代表可重疊;一次命中代表你在比對成功後重置了。一致の後に機械を S0 へ戻すと、重なりなしの検出器になる:1–4 ビット目を見つけ、4 ビット目の 1 を捨ててしまい、4–7 ビット目を取りこぼす。入力 1011011 はまさにこれを捕まえるために選んである。二回なら重なりあり、一回なら一致の後にリセットしている。Kirim mesin kembali ke S0 setelah kecocokan dan ia menjadi detektor tanpa tumpang-tindih: ia menemukan bit 1–4, membuang angka 1 di bit 4, lalu melewatkan bit 4–7. Masukan 1011011 dipilih tepat untuk menangkap ini. Dua kecocokan berarti tumpang-tindih; satu kecocokan berarti kamu mereset setelah cocok.
  • 1011011 does not test the mismatch arc from S3. Send S3 on a 0 to S0 instead of S2 and this stream still passes, but 101011 fails: the match at bits 3–6 is lost. Put both streams in the testbench.1011011 測不到從 S3 出去的失敗箭頭。把 S3 收到 0 時送到 S0 而不是 S2,這串輸入照樣會過,但 101011 會失敗:第 3–6 位元的那次比對會漏掉。兩串輸入都要放進 testbench。1011011 では S3 からの不一致の矢印を試せない。S3 で 0 が来たとき S2 ではなく S0 へ送っても、この系列は通ってしまうが、101011 では失敗する:3–6 ビット目の一致を取りこぼすのだ。testbench には両方の系列を入れること。1011011 tidak menguji busur ketidakcocokan dari S3. Kirim S3 saat menerima 0 ke S0 alih-alih S2 dan aliran ini tetap lolos, tetapi 101011 gagal: kecocokan di bit 3–6 hilang. Masukkan kedua aliran ke testbench.
  • The Mealy output is combinational from x, so it follows every wiggle of the input. x has to come from a register that changes just after the clock edge; drive it straight from a switch or an unsynchronised key and z glitches in the middle of a bit.Mealy 的輸出是由 x 組合出來的,所以輸入的每一次抖動它都會跟著動。x 必須來自一個在時脈邊緣之後才改變的暫存器;如果直接接開關或未同步的按鍵,z 就會在位元中途出現突波。Mealy の出力は x からの組合せ回路なので、入力の揺れにいちいち追従する。x はクロックエッジの直後に変わるレジスタから来なければならない。スイッチや同期していないキーから直接駆動すると、z はビットの途中でグリッチを起こす。Keluaran Mealy bersifat kombinasional dari x, jadi ia mengikuti setiap goyangan masukan. x harus berasal dari register yang berubah tepat setelah tepi clock; kalau digerakkan langsung dari sakelar atau tombol yang belum disinkronkan, z mengalami glitch di tengah bit.
  • Do not register the Mealy output. Write z <= … inside the clocked block and it arrives one tick late, which is Moore timing: the two waveforms then look identical and the point of the task is gone. Keep it as an assign.不要把 Mealy 的輸出打進暫存器。在時脈區塊裡寫 z <= …,它就會晚一個 tick 才出來,那就是 Moore 的時序:兩張波形看起來一模一樣,這一題的重點就不見了。讓它保持為 assign。Mealy の出力をレジスタに入れないこと。クロック付きブロックの中で z <= … と書くと 1 tick 遅れて出てくる——それは Moore のタイミングだ。二つの波形は同じに見え、この課題の要点は消えてしまう。assign のままにしておくこと。Jangan meregister keluaran Mealy. Tulis z <= … di dalam blok ber-clock dan ia tiba satu tick terlambat, yang merupakan pewaktuan Moore: kedua gelombang lalu tampak sama dan inti tugas ini hilang. Biarkan sebagai assign.
  • Five Moore states in a 3-bit register leave three encodings unused. Give the case a default: that goes to S0, and draw those three codes in the diagram with an arc back to S0.3 bit 暫存器放 5 個 Moore 狀態,會空出 3 個編碼。給 case 一個回到 S0 的 default:,並在狀態圖上把這三個編碼畫出來,各加一支回到 S0 的箭頭。3 ビットのレジスタに Moore の 5 状態なら、未使用のエンコードが三つ残る。case に S0 へ戻る default: を付け、その三つのコードも図に描いて S0 へ戻る矢印を付けること。Lima state Moore dalam register 3 bit menyisakan tiga pengodean tak terpakai. Beri case-nya default: yang menuju S0, dan gambar ketiga kode itu di diagram dengan busur kembali ke S0.
  • The 1 Hz tick is an enable, not a clock, as in task 6. Clock both detectors and the pattern shifter from CLOCK2_50 and advance them with if (tick), so x and the state change on the same edge.和第 6 題一樣,1 Hz 的 tick 是 enable,不是時脈。兩個偵測器和送出樣式的移位暫存器都用 CLOCK2_50 當時脈、用 if (tick) 往前推,讓 x 和狀態在同一個邊緣改變。課題 6 と同じく、1 Hz の tick はイネーブルであってクロックではない。二つの検出器もパターンを送るシフトレジスタも CLOCK2_50 で動かし、if (tick) で進めること。そうすれば x と状態が同じエッジで変わる。Tick 1 Hz adalah enable, bukan clock, seperti di tugas 6. Jalankan kedua detektor dan penggeser pola dari CLOCK2_50 dan majukan dengan if (tick), sehingga x dan state berubah pada tepi yang sama.

Done when完成條件完了条件Selesai bila

Reference answer — not released yet參考解答 —— 尚未開放参考解答 — まだ公開されていませんJawaban acuan — belum dirilis

12 pts分点poin9TRAFFIC LIGHT

A traffic light that waits for the side road會等側道的紅綠燈脇道を待つ信号機Lampu lalu lintas yang menunggu jalan samping

  • Verilog
  • FSM
  • Timer
  • Push button
  • Testbench

“insert the traffic light as the homework 8” ↳ added after the Python-panel task

A crossing where the main road has priority. The main road stays green for as long as nobody is waiting. Someone on the side road presses KEY3, and the light runs one fixed cycle: the main road keeps its green a little longer, goes yellow, then every direction is red for a moment, then the side road gets its green, and finally the main road is green again and the light goes back to waiting. No press, no cycle: the light does not run on a timer by itself. 一個主幹道優先的路口。只要沒有人在等,主幹道就一直是綠燈。側道有人按下 KEY3,燈號就跑一個固定的週期:主幹道的綠燈再撐一下、轉黃燈、接著所有方向短暫全紅、然後側道綠燈,最後主幹道回到綠燈,燈號回去等待。沒有人按,就沒有週期:這個燈不會自己按時間輪替。幹線道路が優先の交差点。誰も待っていない限り、幹線は青のままだ。脇道の誰かが KEY3 を押すと、信号は決まった 1 サイクルを走る:幹線の青を少しだけ延ばし、黄になり、全方向が一瞬赤になり、脇道が青になり、最後に幹線が青に戻って信号は再び待機に戻る。押されなければサイクルは無い:この信号は時間だけで勝手に切り替わらない。Sebuah persimpangan di mana jalan utama punya prioritas. Jalan utama tetap hijau selama tidak ada yang menunggu. Seseorang di jalan samping menekan KEY3, dan lampu menjalankan satu siklus tetap: jalan utama mempertahankan hijaunya sebentar lagi, menjadi kuning, lalu semua arah merah sesaat, lalu jalan samping mendapat hijau, dan akhirnya jalan utama hijau lagi dan lampu kembali menunggu. Tanpa tekanan, tanpa siklus: lampu ini tidak berganti hanya karena waktu.

The idea is two machines instead of one. The light FSM decides which phase the crossing is in — GREEN, YELLOW, ALL_RED, REDnSIDEWAYGREEN — and never counts a second itself. A separate timer FSM, IDLE / COUNTING, decides how long. On each phase change the light loads a duration and raises a start strobe; the timer counts ticks up to that duration and drops back to IDLE, and that return is the light's signal to move on. It is the task-2 handshake again, applied to time instead of bytes, and the count on HEX1:HEX0 lets you watch the timer do its half of the work. 核心想法是用兩台機器,而不是一台。燈號 FSM 決定路口現在在哪一個階段——GREEN、YELLOW、ALL_RED、REDnSIDEWAYGREEN——而它自己從來不數秒。另一台計時 FSM,IDLE/COUNTING,決定多久。每次換階段,燈號就載入一個時長、拉起一個 start 脈衝;計時器把 tick 數到那個時長,然後回到 IDLE,而這個「回到 IDLE」就是燈號往下走的訊號。這就是第 2 題的交握,只是交換的東西從 byte 換成了時間;HEX1:HEX0 上的計數讓你看得到計時器做它那一半的工作。考え方の中心は一つではなく二つの機械だ。信号 FSM は交差点がどのフェーズにあるか——GREEN、YELLOW、ALL_RED、REDnSIDEWAYGREEN——を決め、自分では一秒も数えない。別のタイマー FSM、IDLE/COUNTING がどれだけ長くを決める。フェーズが変わるたびに信号は時間を読み込み、start ストローブを上げる。タイマーはその時間まで tick を数えて IDLE に戻り、その戻りが信号にとって次へ進む合図になる。課題 2 のハンドシェイクを、バイトではなく時間に当てはめたものだ。HEX1:HEX0 のカウントで、タイマーが自分の役目を果たす様子が見える。Gagasannya adalah dua mesin, bukan satu. FSM lampu memutuskan fase mana yang sedang berlaku di persimpangan — GREEN, YELLOW, ALL_RED, REDnSIDEWAYGREEN — dan tidak pernah menghitung detik sendiri. FSM timer yang terpisah, IDLE / COUNTING, memutuskan berapa lama. Pada setiap pergantian fase, lampu memuat sebuah durasi dan menaikkan strobe start; timer menghitung tick sampai durasi itu lalu kembali ke IDLE, dan kepulangan itu adalah sinyal bagi lampu untuk lanjut. Ini handshake tugas 2 lagi, diterapkan pada waktu alih-alih byte, dan hitungan di HEX1:HEX0 membuatmu bisa melihat timer mengerjakan bagiannya.

Look at the encodings: 000 → 001 → 011 → 010 → 000. Every step of the cycle flips exactly one bit — a Gray-code sequence — so a phase decoded from the state register can never glitch through a wrong phase on its way to the next one. Put the phase on four LEDs (main green, main yellow, main red, side green) so the board looks like the crossing it is modelling. 看一下編碼:000 → 001 → 011 → 010 → 000。週期裡每一步都只翻轉一個位元——這是 Gray code 序列——所以從狀態暫存器解碼出來的階段,在換到下一個階段的途中不會閃過一個錯的階段。把階段接到四顆 LED 上(主幹道綠、主幹道黃、主幹道紅、側道綠),讓板子看起來就像它在模擬的那個路口。エンコードを見てほしい:000 → 001 → 011 → 010 → 000。サイクルの各ステップでちょうど 1 ビットだけが変わる——Gray コードの系列だ——ので、状態レジスタからデコードしたフェーズが、次のフェーズへ移る途中で誤ったフェーズを一瞬通ることが無い。フェーズを 4 個の LED(幹線青・幹線黄・幹線赤・脇道青)に出し、ボードがモデル化している交差点そのものに見えるようにすること。Perhatikan pengodeannya: 000 → 001 → 011 → 010 → 000. Setiap langkah siklus membalik tepat satu bit — sebuah urutan kode Gray — sehingga fase yang didekode dari register state tidak pernah sekilas melewati fase yang salah dalam perjalanannya ke fase berikutnya. Tampilkan fasenya di empat LED (hijau utama, kuning utama, merah utama, hijau samping) supaya papan terlihat seperti persimpangan yang sedang dimodelkannya.

Target numbers目標數字目標値Angka target

TickticktickTick
1 Hz · 50,000,000 clocks
Request請求要求Permintaan
KEY3, active low
Green hold after a press按下後綠燈延長押下後の青の延長Hijau ditahan setelah ditekan
10 s
Yellow黃燈黄Kuning
3 s
All red全紅全赤Semua merah
2 s
Side road green側道綠燈脇道の青Hijau jalan samping
16 s
Phase encoding階段編碼フェーズのエンコードPengodean fase
000 · 001 · 011 · 010 (Gray)
Timer計時器タイマーTimer
counts 0 → N · N + 1 ticks
Display顯示表示Tampilan
timer on HEX1:HEX0 · phase on 4 LEDs

Traps陷阱落とし穴Jebakan

  • The 1 Hz tick is an enable, not a clock. always @(posedge tick) is the task-1 ripple clock again; clock both machines from CLOCK2_50 and gate them with if (tick).1 Hz 的 tick 是 enable,不是時脈。always @(posedge tick) 又是第 1 題的 ripple clock;兩台機器都用 CLOCK2_50 當時脈,再用 if (tick) 控制。1 Hz の tick はイネーブルであってクロックではない。always @(posedge tick) は課題 1 のリップルクロックの再来だ。二つの機械とも CLOCK2_50 で動かし、if (tick) でゲートすること。Tick 1 Hz adalah enable, bukan clock. always @(posedge tick) adalah ripple clock tugas 1 lagi; jalankan kedua mesin dari CLOCK2_50 dan kendalikan dengan if (tick).
  • Only the clock and the reset belong in an edge list. Adding posedge side_alarm or posedge set_counter makes Quartus give up on flip-flops and build latches — the simulation can still pass while the board misbehaves.邊緣觸發清單裡只能有時脈和 reset。加上 posedge side_alarm 或 posedge set_counter,Quartus 就放棄用正反器,改做 latch——模擬照樣會過,板子卻不照規矩走。エッジリストに入れてよいのはクロックとリセットだけ。posedge side_alarm や posedge set_counter を足すと Quartus はフリップフロップを諦めてラッチを作る——シミュレーションは通っても、ボードはおかしな動きをする。Hanya clock dan reset yang boleh ada di daftar tepi. Menambahkan posedge side_alarm atau posedge set_counter membuat Quartus menyerah pada flip-flop dan membangun latch — simulasinya tetap bisa lolos sementara papannya berperilaku aneh.
  • A push button is asynchronous and it bounces. Two flip-flops to synchronise it, then an edge detect, so that one press is one request — and a press while the light is not in main green is ignored, not queued.按鍵是非同步的,而且會彈跳。先用兩級正反器同步,再做邊緣偵測,讓按一次就是一次請求——而燈號不在主幹道綠燈時按下,是被忽略,不是排隊。押しボタンは非同期で、しかもチャタリングする。2 段のフリップフロップで同期させてからエッジ検出し、1 回押せば 1 回の要求になるようにする——そして幹線が青でないときの押下は、待ち行列に入れず無視する。Tombol tekan itu asinkron dan memantul. Dua flip-flop untuk menyinkronkannya, lalu deteksi tepi, supaya satu tekanan menjadi satu permintaan — dan tekanan saat lampu tidak sedang hijau utama diabaikan, bukan diantrekan.
  • The handshake costs ticks. The timer sees the start strobe one tick after the light raises it, and the light sees the timer go idle one tick after it finishes. Measure each phase on the waveform instead of assuming it is exactly N + 1 ticks.交握是要花 tick 的。計時器在燈號拉起 start 的下一個 tick 才看到它,而燈號在計時器數完的下一個 tick 才看到它回到 idle。每個階段的長度要在波形上量,不要假設它剛好是 N + 1 個 tick。ハンドシェイクには tick がかかる。タイマーは信号が start を上げた次の tick でそれを見、信号はタイマーが数え終えた次の tick でアイドルに戻ったことを見る。各フェーズの長さはちょうど N + 1 tick だと決めつけず、波形で測ること。Handshake itu memakan tick. Timer melihat strobe start satu tick setelah lampu menaikkannya, dan lampu melihat timer menjadi idle satu tick setelah ia selesai. Ukur setiap fase di gelombang alih-alih menganggap panjangnya tepat N + 1 tick.
  • Whoever loads a duration must start the timer in the same tick. Load one without the other and the light sits in a phase waiting for a timer that never runs.誰載入時長,誰就要在同一個 tick 啟動計時器。只做其中一件,燈號就會卡在某個階段,等一個永遠不會跑的計時器。時間を読み込む側は、同じ tick でタイマーを起動しなければならない。片方だけだと、信号は決して動かないタイマーを待ってそのフェーズに居座る。Siapa pun yang memuat durasi harus memulai timer pada tick yang sama. Muat satu tanpa yang lain dan lampu akan diam di sebuah fase menunggu timer yang tidak pernah berjalan.
  • Four phases in a 3-bit register leave four encodings unused. Give the case a default: that goes to main green, and draw those codes in its state diagram.3 bit 的暫存器放 4 個階段,會空出 4 個編碼沒用到。給 case 一個回到主幹道綠燈的 default:,並在狀態圖上把這些編碼畫出來。3 ビットのレジスタに 4 フェーズなら、未使用のエンコードが 4 つ残る。case に幹線の青へ戻る default: を付け、状態遷移図にそれらのコードも描くこと。Empat fase dalam register 3 bit menyisakan empat pengodean tak terpakai. Beri case-nya default: yang menuju hijau utama, dan gambar kode-kode itu di diagram state-nya.

Done when完成條件完了条件Selesai bila

Reference answer — not released yet參考解答 —— 尚未開放参考解答 — まだ公開されていませんJawaban acuan — belum dirilis

24 pts分点poin10ELEVATOR

Drive a nine-floor elevator from a Tk panel over the UART用 Tk 面板透過 UART 驅動一台九層樓的電梯Tk パネルから UART 越しに九階建てのエレベータを動かすKendalikan lift sembilan lantai dari panel Tk lewat UART

  • Verilog
  • FSM
  • UART
  • Protocol
  • Python
  • Tkinter

“use python tk and uart to pass the floor button signal to fpga board and display how the elevator moving in tk, to replace the gen of random input” ↳ replaces the random-stimulus simulation

Nine floors, one car, sixteen hall buttons — up on floors 1–8, down on floors 2–9. The controller lives on the FPGA and the policy does not change. What changes is where the presses come from and where you watch the result: there is no stimulus generator and no random seed any more. A Python panel on your desk is the building's call panel, and the same panel is the shaft you watch the car move in. 九層樓,一台轎廂,十六顆樓層按鈕——1–8 樓有上,2–9 樓有下。控制器住在 FPGA 上,排程策略不變。改變的是:按鍵從哪裡來,以及你在哪裡看結果——不再有激勵產生器,也不再有亂數種子。你桌上的那個 Python 面板,就是這棟樓的召喚面板;而同一個面板,也是你看著轎廂上下移動的那座井道。九階、かご一台、十六個のホールボタン——1–8 階に上、2–9 階に下。コントローラは FPGA に住み、方針は変わらない。変わるのは、押下がどこから来るか、そして結果をどこで見るかだ:もう刺激ジェネレータも乱数シードも無い。机の上の Python のパネルがこの建物の呼び出しパネルであり、同じパネルが、かごの動きを見るための昇降路でもある。Sembilan lantai, satu kereta, enam belas tombol hall — naik di lantai 1–8, turun di lantai 2–9. Pengendalinya tinggal di FPGA dan kebijakannya tidak berubah. Yang berubah adalah dari mana tekanannya datang dan di mana kamu menonton hasilnya: tidak ada lagi pembangkit stimulus dan tidak ada lagi seed acak. Sebuah panel Python di mejamu adalah panel panggilan gedung itu, dan panel yang sama adalah lorong tempat kamu menonton keretanya bergerak.

The policy is still the elevator algorithm, LOOK. While the car is going up it keeps going up for as long as any call is waiting above it, and it opens its doors at a floor only when that floor wants to go up too — or when it is the last call left in that direction. When nothing is left above, it reverses. With no calls at all it stands still, doors shut, on whatever floor it served last: it does not drive back to floor 1, and it never turns around mid-run because a nearer call appeared behind it. 排程策略仍然是電梯演算法,LOOK。轎廂往上走的時候,只要上方還有召喚在等,它就繼續往上;而它在某一層開門,只有在那一層也想往上、或那是這個方向上最後一個召喚的時候。上方沒有東西了,它就轉向。完全沒有召喚時,它關著門停在最後服務的那一層:它不會自己開回 1 樓,也絕不會因為後方出現比較近的召喚就半路掉頭。方針は引き続きエレベータアルゴリズム、LOOK だ。かごが上昇中は、自分より上に呼びが残っている限り上昇を続け、ある階で扉を開くのは、その階も上へ行きたい時か、その方向で最後に残った呼びである時だけだ。上に何も残らなければ反転する。呼びが一つも無ければ、最後に扱った階で扉を閉じたまま停まる:1 階へ戻ることはなく、後方に近い呼びが現れたからといって途中で向きを変えることもない。Kebijakannya tetap algoritma lift, LOOK. Selama kereta naik, ia terus naik selama masih ada panggilan menunggu di atasnya, dan ia membuka pintu di sebuah lantai hanya bila lantai itu juga hendak naik — atau bila itu panggilan terakhir yang tersisa pada arah tersebut. Ketika tak ada lagi di atas, ia berbalik. Tanpa panggilan sama sekali ia diam, pintu tertutup, di lantai mana pun yang terakhir dilayaninya: ia tidak kembali ke lantai 1, dan tidak pernah berbalik di tengah jalan karena ada panggilan lebih dekat di belakangnya.

Two directions over the one 115200 8N1 line you built in task 3. Downward, one byte per press. Upward, a seven-byte status frame every time the floor, the direction, the door or the set of pending calls changes, plus a heartbeat twice a second so the panel can tell a quiet lift from a dead cable. The panel draws what the frame says, and that one sentence is the whole discipline of this task: the lamp under a button is lit because the FPGA says that call is pending, never because you just clicked it. A panel that lights its own buttons will go on telling you the lift is working long after the cable has fallen out. 在你第 3 題做出來的那一條 115200 8N1 線上,資料往兩個方向走。往下,每按一次送一個 byte。往上,只要樓層、方向、門或待處理召喚集合有任何改變,就送出一個七個 byte 的狀態框,再加上每秒兩次的心跳,好讓面板分得出「電梯很閒」和「線斷了」。面板畫的是框裡說的東西,而這一句話就是這一題全部的紀律:按鈕下面的燈會亮,是因為 FPGA 說那個召喚還在等,不是因為你剛剛點了它。一個自己把自己按鈕點亮的面板,會在纜線早就掉了之後,還一直告訴你電梯運作正常。課題 3 で作った 115200 8N1 の一本の線を、データが双方向に流れる。下りは押下ごとに 1 バイト。上りは、階・方向・扉・保留中の呼びの集合のいずれかが変わるたびに 7 バイトのステータスフレーム、加えて毎秒二回のハートビート。パネルが「静かなエレベータ」と「死んだケーブル」を区別できるようにするためだ。パネルはフレームが言うことを描く。この一文がこの課題の規律のすべてだ:ボタンの下のランプが点くのは、その呼びが保留中だと FPGA が言っているからであって、今クリックしたからではない。自分のボタンを自分で点けるパネルは、ケーブルが抜けたあともずっと、エレベータは動いていると言い続ける。Dua arah di atas satu jalur 115200 8N1 yang kamu bangun di tugas 3. Ke bawah, satu byte per tekanan. Ke atas, sebuah frame status tujuh byte setiap kali lantai, arah, pintu atau himpunan panggilan tertunda berubah, ditambah detak jantung dua kali sedetik agar panelnya bisa membedakan lift yang sepi dari kabel yang mati. Panelnya menggambar apa yang dikatakan frame-nya, dan satu kalimat itulah seluruh disiplin tugas ini: lampu di bawah sebuah tombol menyala karena FPGA mengatakan panggilan itu tertunda, bukan karena kamu baru saja mengekliknya. Panel yang menyalakan tombolnya sendiri akan terus memberitahumu liftnya bekerja lama setelah kabelnya terlepas.

A random stream was good at finding the passenger nobody picked up. A person clicking buttons finds something else: the moments where the lift is correct and still feels wrong — the call you place one tick after the doors shut, the wait while the car runs to the far end of the building away from you. You will press those on purpose, and your own panel will show you whether what you are watching is a bug in the controller or the elevator algorithm behaving exactly as specified. Keep the log of the session; it is the evidence. 隨機輸入很擅長找出那位沒有人去載的乘客。一個人用手點按鈕,找到的是另一種東西:電梯完全正確、但你就是覺得不對勁的那些時刻——你在門關上後一個 tick 才按下的那次召喚、轎廂往反方向跑到大樓另一端時你站著等的那段時間。你會刻意去按出這些情況,而你自己的面板會讓你看出:眼前這件事到底是控制器的 bug,還是電梯演算法完全照規格在跑。把這一次操作的紀錄留下來;那就是證據。ランダムな入力列は、誰にも拾われない乗客を見つけるのが得意だった。人がボタンを押すと、見つかるのは別のものだ:エレベータが正しいのに、それでも違和感のある瞬間——扉が閉じた 1 tick 後に入れてしまった呼び、かごが自分とは反対側の端まで走っていく間の待ち時間。君はそれを意図的に押すことになり、自分のパネルが、見ているものがコントローラのバグなのか、エレベータアルゴリズムが仕様どおりに振る舞っているだけなのかを示してくれる。そのセッションのログを残すこと。それが証拠だ。Aliran acak pandai menemukan penumpang yang tidak dijemput siapa pun. Orang yang mengeklik tombol menemukan hal lain: saat-saat ketika liftnya benar dan tetap terasa salah — panggilan yang kamu buat satu tick setelah pintunya menutup, waktu menunggu selagi keretanya berlari ke ujung gedung yang jauh darimu. Kamu akan menekan itu dengan sengaja, dan panelmu sendiri akan menunjukkan apakah yang kamu tonton adalah bug di pengendalinya atau algoritma liftnya berperilaku persis seperti ditentukan. Simpan log sesinya; itulah buktinya.

What to do要做的事やることYang harus dilakukan

  1. Write the protocol down before either side exists. Downward: 0x80 | dir<<4 | floor, so the whole command set is 0x81–0x89 for down and 0x91–0x99 for up, with 0xFF as reset. Upward: 0xA5 and then six payload bytes. Put it in the README now, because the first bug you will have is the two sides disagreeing about it.在兩邊都還不存在之前,先把協定寫下來。往下:0x80 | dir<<4 | floor,所以整個指令集就是下行的 0x81–0x89 和上行的 0x91–0x99,另外 0xFF 是 reset。往上:0xA5 後面接六個 payload byte。現在就寫進 README,因為你會遇到的第一個 bug,就是兩邊對它的認知不一致。どちらの側も存在しないうちにプロトコルを書き下す。下り:0x80 | dir<<4 | floor。したがってコマンド集合は下り方向が 0x81–0x89、上り方向が 0x91–0x99 で、0xFF がリセット。上り:0xA5 に続いて 6 バイトのペイロード。今すぐ README に書くこと。最初に出会うバグは、両側の認識が食い違っていることだからだ。Tulis protokolnya sebelum kedua sisinya ada. Ke bawah: 0x80 | dir<<4 | floor, sehingga seluruh himpunan perintahnya adalah 0x81–0x89 untuk turun dan 0x91–0x99 untuk naik, dengan 0xFF sebagai reset. Ke atas: 0xA5 lalu enam byte muatan. Taruh di README sekarang, karena bug pertama yang akan kamu temui adalah kedua sisinya tidak sepakat soal itu.
  2. Make the board talk before you make it move. Reuse the UART from task 3. Have the FPGA answer every command byte with a status frame carrying whatever state it currently holds, and watch that in a plain terminal first. Until a press on your desk reaches the board and a frame comes back, the elevator is not what is broken.先讓板子會講話,再讓它會動。把第 3 題的 UART 拿來用。讓 FPGA 對每一個收到的指令 byte 都回一個狀態框,內容就是它當下的狀態,然後先用一個單純的終端機去看它。在「桌上按一下、訊息到板子、框回來」這條路通之前,壞掉的都不是電梯。動かす前に、まず喋らせる。課題 3 の UART を再利用する。FPGA が受け取ったコマンドバイトごとに、その時点の状態を載せたステータスフレームを返すようにし、まずは素のターミナルでそれを見る。机の上の押下がボードに届き、フレームが返ってくるまでは、壊れているのはエレベータではない。Buat papannya bicara sebelum membuatnya bergerak. Pakai lagi UART dari tugas 3. Buat FPGA menjawab setiap byte perintah dengan sebuah frame status yang membawa keadaan yang sedang dipegangnya, dan tonton itu di terminal biasa dulu. Sampai sebuah tekanan di mejamu sampai ke papan dan sebuah frame kembali, liftnya bukan yang rusak.
  3. Wire the calls in. A received command byte sets one bit in the call register — the same register the controller already reads. The controller neither knows nor cares that the press arrived down a cable, and that is the sign you have put the seam in the right place.把召喚接進去。收到的指令 byte 就是去設定召喚暫存器裡的某一個位元——而那就是控制器本來就在讀的那個暫存器。控制器不知道、也不需要知道這次按鍵是從一條線上來的;而這正是你把接縫切在正確位置的證明。呼びを配線する。受信したコマンドバイトは呼びレジスタのビットを一つ立てる——コントローラが元から読んでいる、まさにそのレジスタだ。コントローラは押下がケーブル越しに来たことを知らないし、気にもしない。それが、継ぎ目を正しい位置に置けたという印だ。Sambungkan panggilannya. Byte perintah yang diterima menyalakan satu bit di register panggilan — register yang sama yang sudah dibaca pengendalinya. Pengendalinya tidak tahu dan tidak peduli bahwa tekanannya tiba lewat kabel, dan itulah tandanya kamu meletakkan sambungannya di tempat yang benar.
  4. Draw the shaft, and the call panel beside it. A Tk canvas with nine floors and the car as a rectangle. Beside every floor put its own pair of hall buttons, ▲ and ▼ — floor 1 gets only ▲ and floor 9 only ▼, which is how sixteen is the right number. Clicking one sends that floor's command byte, and the button carries its own lamp. Interpolate the car's position over the two seconds the board takes to cross a floor, so the motion is continuous even though the truth underneath arrives one frame at a time.把井道畫出來,旁邊再畫召喚面板。一個 Tk canvas:九層樓,轎廂是一個矩形。每一層樓旁邊都要有自己的一對樓層按鈕,▲ 和 ▼——1 樓只有 ▲,9 樓只有 ▼,這就是為什麼是十六顆。點下其中一顆就送出那一層的指令 byte,而按鈕本身帶著自己的燈。在板子跨越一層樓所需的兩秒之間,把轎廂的位置內插出來,讓動作是連續的——即使底下的真相是一框一框來的。昇降路と、その横に呼び出しパネルを描く。九階ぶんの Tk キャンバス、かごは矩形。各階の横にその階専用のホールボタンを一対、▲ と ▼ を置く——1 階は ▲ だけ、9 階は ▼ だけで、だから十六個になる。どれかをクリックすればその階のコマンドバイトが送られ、ボタン自身がランプを持つ。ボードが一階ぶんを渡る二秒のあいだ、かごの位置を補間して動きを連続にすること。下にある真実は一フレームずつしか届かないとしても。Gambar lorongnya, dan panel panggilan di sebelahnya. Sebuah kanvas Tk dengan sembilan lantai dan keretanya sebagai persegi panjang. Di samping setiap lantai, letakkan sepasang tombol hall miliknya sendiri, ▲ dan ▼ — lantai 1 hanya mendapat ▲ dan lantai 9 hanya ▼, dan begitulah enam belas menjadi angka yang benar. Mengeklik salah satunya mengirim byte perintah lantai itu, dan tombolnya membawa lampunya sendiri. Interpolasikan posisi keretanya sepanjang dua detik yang dibutuhkan papan untuk melewati satu lantai, supaya geraknya kontinu meski kebenaran di bawahnya tiba satu frame pada satu waktu.
  5. Prove the panel is a mirror and not a model. Pull the USB cable in the middle of a run. Within a second the panel must say the link is dead and stop pretending: no car movement, no lamp changes. Plug it back in and it must recover from the next frame without being restarted.證明這個面板是一面鏡子,不是一個模型。在跑到一半的時候把 USB 線拔掉。一秒之內,面板必須說連線斷了,並且停止假裝:轎廂不動、燈不變。再插回去,它必須能從下一個框恢復,而且不用重開。パネルが鏡であってモデルでないことを証明する。動作中に USB ケーブルを抜く。一秒以内にパネルはリンクが死んだと言い、取り繕うのをやめなければならない:かごは動かず、ランプも変わらない。挿し直せば、再起動せずに次のフレームから復帰しなければならない。Buktikan panelnya adalah cermin, bukan model. Cabut kabel USB di tengah jalan. Dalam satu detik panelnya harus mengatakan tautannya mati dan berhenti berpura-pura: tidak ada gerakan kereta, tidak ada perubahan lampu. Pasang kembali dan ia harus pulih dari frame berikutnya tanpa dimulai ulang.

Target numbers目標數字目標値Angka target

Floors樓層階数Lantai
9 · 1 bottom, 9 top
Hall buttons樓層按鈕ホールボタンTombol hall
16 · ▲ 1–8 · ▼ 2–9 · drawn and clicked on the Tk panel16 顆 · ▲ 1–8 · ▼ 2–9 · 畫在 Tk 面板上並在上面點擊16 個 · ▲ 1–8 · ▼ 2–9 · Tk パネル上に描かれ、そこでクリックする16 · ▲ 1–8 · ▼ 2–9 · digambar dan diklik di panel Tk
Link連線リンクTautan
115200 8N1 · the task-3 UART115200 8N1 · 第 3 題的 UART115200 8N1 · 課題 3 の UART115200 8N1 · UART tugas 3
Press command按鍵指令押下コマンドPerintah tekan
0x80 | dir<<4 | floor · down 0x81–0x89 · up 0x91–0x99
Reset commandreset 指令リセットコマンドPerintah reset
0xFF
Status frame狀態框ステータスフレームFrame status
0xA5 · floor · state · up×2 · down×2 · 7 bytes
Payload rulepayload 規則ペイロード規則Aturan muatan
every byte after the sync has bit 7 clearsync 之後每個 byte 的 bit 7 都是 0同期バイト以降は全バイトの bit 7 が 0setiap byte setelah sync, bit 7-nya nol
Frame when何時送框送信契機Kapan mengirim frame
on every change · plus a 2 Hz heartbeat每次狀態改變 · 外加 2 Hz 心跳変化のたび · 加えて 2 Hz のハートビートpada tiap perubahan · plus detak 2 Hz
TickticktickTick
1 Hz · 50,000,000 clocks
Travel行進走行Perjalanan
2 ticks per floor
Door open開門扉の開放Pintu terbuka
4 ticks
Policy排程策略方針Kebijakan
LOOK · no call behind interrupts a run
Link loss斷線リンク喪失Tautan putus
shown within 1 s · recovers without a restart1 秒內顯示 · 不用重開即可恢復1 秒以内に表示 · 再起動せず復帰tampil dalam 1 s · pulih tanpa restart
Board display板上顯示ボード表示Tampilan papan
floor on HEX0 · direction on 2 LEDs · KEY0 reset樓層在 HEX0 · 方向用 2 顆 LED · KEY0 reset階は HEX0 · 方向は LED 2 個 · KEY0 でリセットlantai di HEX0 · arah di 2 LED · KEY0 reset

Traps陷阱落とし穴Jebakan

  • The lamp belongs to the FPGA, not to the click. Lighting a button the instant it is pressed gives you a panel that works beautifully with the cable unplugged. Light it from the call mask in the status frame instead, and the round trip becomes something you can see: you click, and a moment later it lights. That delay is real, and noticing it is the point.燈是 FPGA 的,不是那一下點擊的。按下去就立刻亮,你會得到一個就算線拔掉也運作得很漂亮的面板。改成用狀態框裡的召喚遮罩去點亮它,那趟來回就變成你看得見的東西:你點了一下,過一會兒它才亮。那個延遲是真的,而注意到它正是重點。ランプは FPGA のものであって、クリックのものではない。押した瞬間に点灯させれば、ケーブルを抜いても見事に動くパネルができあがる。代わりにステータスフレームの呼びマスクから点灯させれば、往復が目に見えるようになる:クリックし、少し遅れて点く。その遅延は本物であり、それに気づくことがここの要点だ。Lampu itu milik FPGA, bukan milik klik. Menyalakan tombol begitu ia ditekan memberimu panel yang bekerja indah dengan kabel tercabut. Nyalakan dari mask panggilan di frame status, dan perjalanan bolak-baliknya menjadi sesuatu yang bisa kamu lihat: kamu mengeklik, dan sesaat kemudian ia menyala. Jeda itu nyata, dan menyadarinya adalah intinya.
  • A sync byte you can also send as data is not a sync byte. Keep every payload byte below 0x80 — which is why the two call masks go out as four nibble-sized bytes — so that 0xA5 can only ever mean “a frame starts here”. The alternative is a resynchroniser. Choose one deliberately; drifting one byte out of alignment and never recovering is the classic symptom of having chosen neither.一個你也可能把它當資料送出去的 sync byte,不是 sync byte。讓 sync 之後每個 payload byte 都小於 0x80——這正是兩個召喚遮罩要拆成四個半位元組大小的 byte 送出去的原因——這樣 0xA5 就只可能代表「一個框從這裡開始」。另一條路是寫一個重新同步器。要刻意選一個;錯開一個 byte 之後再也回不來,就是兩個都沒選的典型症狀。データとしても送りうる同期バイトは、同期バイトではない。ペイロードの全バイトを 0x80 未満に保つこと——二つの呼びマスクをニブル大の 4 バイトに分けて送る理由がこれだ——そうすれば 0xA5 は「ここからフレーム」以外を意味しえない。もう一つの道は再同期器を書くことだ。どちらかを意図して選ぶこと。1 バイトずれたまま二度と戻らないのは、どちらも選ばなかった時の典型的な症状だ。Byte sync yang juga bisa kamu kirim sebagai data bukanlah byte sync. Jaga setiap byte muatan di bawah 0x80 — itulah sebabnya kedua mask panggilan dikirim sebagai empat byte seukuran nibble — sehingga 0xA5 hanya bisa berarti “sebuah frame dimulai di sini”. Alternatifnya adalah sebuah penyinkron ulang. Pilih satu dengan sengaja; melenceng satu byte dan tidak pernah pulih adalah gejala klasik dari tidak memilih keduanya.
  • tkinter is single-threaded and a blocking read on the serial port will freeze it. Call read() on the GUI thread and the window stops repainting exactly when the lift is busiest. Put the serial side in its own thread and hand frames over with a queue and after(), or poll non-blocking from an after loop — but never block the main loop.tkinter 是單執行緒的,而在序列埠上做阻塞式 read 會把它凍住。在 GUI 執行緒上呼叫 read(),視窗就會剛好在電梯最忙的時候停止重繪。把序列那一側放進自己的執行緒,用 queue 搭配 after() 把框交過去;或者用 after 迴圈做非阻塞輪詢——但絕對不要擋住 main loop。tkinter はシングルスレッドで、シリアルポートに対するブロッキング read はそれを凍らせる。GUI スレッドで read() を呼べば、エレベータが最も忙しいまさにその時にウィンドウの再描画が止まる。シリアル側は専用スレッドに置き、キューと after() でフレームを渡すか、after ループからノンブロッキングでポーリングすること——ただしメインループを決してブロックしない。tkinter itu berulir tunggal dan read yang memblokir pada port serial akan membekukannya. Panggil read() di utas GUI dan jendelanya berhenti menggambar ulang tepat ketika liftnya paling sibuk. Taruh sisi serialnya di utasnya sendiri dan serahkan frame-nya lewat antrean dan after(), atau polling tanpa blokir dari sebuah loop after — tapi jangan pernah memblokir loop utamanya.
  • Up at 5 and down at 5 are two different calls. A stop at floor 5 on the way up clears the up bit only. Clear both and the passenger waiting to go down watches the doors close, their lamp goes out on your own panel, and you will have watched the bug happen without recognising it.5 樓的「上」和 5 樓的「下」是兩個不同的召喚。上行途中停在 5 樓,只能清掉「上」那一個位元。兩個都清掉,等著要下樓的乘客就看著門關上、他的燈在你自己的面板上熄掉——而你會親眼看著這個 bug 發生,卻沒認出它來。5 階の「上」と 5 階の「下」は別々の呼びだ。上昇中に 5 階で停まったら、消してよいのは「上」のビットだけ。両方消すと、下りたい乗客は扉が閉まるのを見ることになり、そのランプは自分のパネル上で消える——バグが起きるのを見ていながら、それと気づかないことになる。Naik di lantai 5 dan turun di lantai 5 adalah dua panggilan berbeda. Berhenti di lantai 5 saat naik hanya menghapus bit naiknya. Hapus keduanya dan penumpang yang menunggu turun melihat pintunya menutup, lampunya padam di panelmu sendiri, dan kamu akan telah menonton bug itu terjadi tanpa mengenalinya.
  • The byte arrives when it arrives. Latch a received command into the call register on the 50 MHz clock, not on the 1 Hz tick: a press that lands between two ticks is otherwise dropped, and you will spend the evening blaming the serial port for something your own clock enable did.byte 什麼時候到就是什麼時候到。收到的指令要用 50 MHz 時脈鎖進召喚暫存器,不是用 1 Hz 的 tick:否則落在兩個 tick 之間的那次按鍵就被丟掉了,而你會花一整個晚上去怪序列埠——實際上那是你自己的 clock enable 幹的。バイトは届く時に届く。受信したコマンドは 1 Hz の tick ではなく 50 MHz のクロックで呼びレジスタにラッチすること。さもないと tick と tick の間に来た押下は落ち、君は自分のクロックイネーブルがやったことでシリアルポートを一晩責めることになる。Byte-nya tiba saat ia tiba. Kunci perintah yang diterima ke dalam register panggilan pada clock 50 MHz, bukan pada tick 1 Hz: tekanan yang mendarat di antara dua tick jika tidak akan hilang, dan kamu akan menghabiskan malam menyalahkan port serial atas sesuatu yang dilakukan clock enable-mu sendiri.
  • Floors 1 and 9 each have a button that does not exist. The panel must not draw down-at-1 or up-at-9, and the board must reject those two command bytes rather than set a bit that nothing will ever clear. Two defences, because either one alone fails the moment someone sends bytes by hand.1 樓和 9 樓各有一顆不存在的按鈕。面板不能畫出「1 樓下」或「9 樓上」,而板子也必須拒絕那兩個指令 byte,而不是去設一個永遠不會有人清掉的位元。要有兩道防線,因為只要有人用手送 byte,任何單獨一道都會失守。1 階と 9 階には、それぞれ存在しないボタンがある。パネルは「1 階の下」と「9 階の上」を描いてはならず、ボードもその二つのコマンドバイトを拒否しなければならない。誰も消さないビットを立てるのではなく。防御は二重に——どちらか一方だけでは、誰かが手でバイトを送った瞬間に破れる。Lantai 1 dan 9 masing-masing punya tombol yang tidak ada. Panelnya tidak boleh menggambar turun-di-1 atau naik-di-9, dan papannya harus menolak kedua byte perintah itu alih-alih menyalakan bit yang tidak akan pernah dihapus apa pun. Dua pertahanan, karena salah satunya saja akan jebol begitu ada orang mengirim byte dengan tangan.
  • A heartbeat is not a nicety. Without it the panel cannot tell “the lift is idle and nothing has changed” from “the cable fell out ten minutes ago”. Two frames a second costs fourteen bytes and removes an entire class of wrong conclusion.心跳不是裝飾。沒有它,面板就分不出「電梯閒著、什麼都沒變」和「線在十分鐘前就掉了」。每秒兩個框只花十四個 byte,卻消掉了一整類的錯誤結論。ハートビートは飾りではない。それが無ければパネルは「エレベータは暇で何も変わっていない」と「十分前にケーブルが抜けた」を区別できない。毎秒 2 フレームは 14 バイトの費用で、誤った結論を丸ごと一種類取り除く。Detak jantung bukan hiasan. Tanpanya panelnya tidak bisa membedakan “liftnya diam dan tak ada yang berubah” dari “kabelnya terlepas sepuluh menit lalu”. Dua frame sedetik berbiaya empat belas byte dan menyingkirkan satu kelas kesimpulan keliru seluruhnya.
  • Interpolating the car is drawing, not state. Animate between floors by all means, but when a frame arrives the drawing snaps to what the frame says. An animation that keeps its own idea of where the car is will drift away from the board, and the first time you notice will be when your doors open on the wrong floor.把轎廂的位置內插出來是「畫圖」,不是「狀態」。樓層之間當然可以做動畫,但只要有框進來,畫面就要跳到框裡說的位置。一個自己記著轎廂在哪裡的動畫,會慢慢和板子脫節,而你第一次發現的時候,會是你的門在錯的樓層打開。かごの補間は描画であって状態ではない。階と階の間でアニメーションさせるのは構わないが、フレームが届いたら描画はフレームの言う位置へ即座に合わせる。かごの位置について自前の考えを持ち続けるアニメーションはボードから少しずつ離れていき、最初に気づくのは、扉が間違った階で開く時だ。Menginterpolasi keretanya adalah penggambaran, bukan keadaan. Silakan menganimasikan antar lantai, tetapi begitu sebuah frame tiba gambarnya harus menempel pada apa yang dikatakan frame itu. Animasi yang menyimpan gagasannya sendiri tentang di mana keretanya berada akan menyimpang dari papannya, dan pertama kali kamu menyadarinya adalah ketika pintumu terbuka di lantai yang salah.

Done when完成條件完了条件Selesai bila

Reference answer — not released yet參考解答 —— 尚未開放参考解答 — まだ公開されていませんJawaban acuan — belum dirilis

Why this order為什麼是這個順序なぜこの順番かMengapa urutannya begini

1 → the LEDs prove the toolchain, the pin constraints and the clock-enable habit while nothing else can be blamed. 2 → two FSMs teach you handshakes, which is the only way the later blocks talk to each other. 3 → the echo turns the host into a test instrument you trust. 4 → fixed point is arithmetic practice on a link that already works, so a wrong answer is a math bug and nothing else. 5 → the motor is the first block where a bug has torque. 6 → once the fabric has settled, the host side is the easy thing to replace. 7 → the repository is where the work stops being yours alone: VPN, Gitea, and a history someone else can read. 8 → the sequence detector puts Mealy and Moore side by side on a machine small enough to see whole, so the one-clock offset between them becomes something you can point at. 9 → and the traffic light is two FSMs handing time back and forth — the task-2 handshake applied to seconds. 1 → LED 驗證的是工具鏈、腳位約束,以及 clock enable 的習慣,此時還沒有別的東西可以怪。2 → 兩個 FSM 教你 handshake,那是後面所有模組彼此溝通的唯一方式。3 → 回傳測試把主機端變成一台你信得過的量測儀器。4 → 定點數是在一條已經會動的連線上練算術,所以答案錯了就純粹是數學 bug。5 → 馬達是第一個「bug 帶有扭力」的模組。6 → FPGA 這端安定之後,主機端反而是最容易換掉的部分。7 → repository 是這些工作不再只屬於你一個人的地方:VPN、Gitea,以及一段別人讀得懂的歷史。8 → 序列偵測器把 Mealy 和 Moore 放在一台小到能一眼看完的機器上並排比較,那一個時脈的時差變成你指得出來的東西。9 → 而紅綠燈是兩台 FSM 互相交棒時間——把第 2 題的交握用在秒數上。1 → LED はツールチェーン、ピン制約、クロックイネーブルの習慣を検証する——他に責任を押しつけられるものが無い段階で。2 → 二つの FSM がハンドシェイクを教える。以降のブロックが互いに話す唯一の方法だ。3 → エコーはホストを信頼できる測定器に変える。4 → 固定小数点は、既に動くリンクの上での算術の練習だから、答えが違えばそれは純粋に数学のバグだ。5 → モータは、バグにトルクが伴う最初のブロック。6 → ファブリック側が固まってしまえば、ホスト側は取り替えるのが最も簡単な部分になる。7 → リポジトリは、この仕事が君ひとりのものでなくなる場所だ:VPN、Gitea、そして他人が読める履歴。8 → 系列検出器は、全体が一目で見渡せる小さな機械の上で Mealy と Moore を並べ、1 クロックのずれを指差せるものにする。9 → そして信号機は二つの FSM が時間を受け渡し合う——課題 2 のハンドシェイクを秒に当てはめたものだ。1 → LED membuktikan toolchain, batasan pin dan kebiasaan clock-enable selagi belum ada hal lain yang bisa disalahkan. 2 → dua FSM mengajarimu handshake, satu-satunya cara blok-blok berikutnya berbicara satu sama lain. 3 → gema mengubah host menjadi alat ukur yang kamu percayai. 4 → fixed point adalah latihan aritmetika di atas sambungan yang sudah bekerja, jadi jawaban yang salah pasti bug matematika dan bukan yang lain. 5 → motor adalah blok pertama yang bug-nya punya torsi. 6 → begitu sisi fabric-nya mapan, sisi host adalah bagian yang paling mudah diganti. 7 → repositori adalah tempat pekerjaan ini berhenti menjadi milikmu sendiri: VPN, Gitea, dan sebuah riwayat yang bisa dibaca orang lain. 8 → detektor urutan menjajarkan Mealy dan Moore pada mesin yang cukup kecil untuk dilihat utuh, sehingga selisih satu clock di antara keduanya menjadi sesuatu yang bisa kamu tunjuk. 9 → dan lampu lalu lintas adalah dua FSM yang saling mengoper waktu — handshake tugas 2 yang diterapkan pada detik.

Reuse, do not restart. The FIFO from task 2, the RX path from task 3 and the filter from task 4 should all still be in the project when the Python panel replaces the LabVIEW one. Nothing later throws anything earlier away: task 7 is the same tree with a history on it, and task 8 is a small new machine that sits beside the others. If a later task makes you delete an earlier one, you have misread the task. 重複使用,不要重來。當 Python 面板取代 LabVIEW 那一版時,第 2 題的 FIFO、第 3 題的 RX 路徑、第 4 題的濾波器,都應該還留在專案裡。後面的題目不會丟掉前面的任何東西:第 7 題是同一棵檔案樹,只是多了一段歷史;第 8 題則是放在其他模組旁邊的一台小新機器。如果某一題讓你想刪掉前面某一題,那是你把題目讀錯了。作り直さず、使い回す。Python のパネルが LabVIEW 版を置き換える時点でも、課題 2 の FIFO、課題 3 の RX 経路、課題 4 のフィルタはプロジェクトに残っているはずだ。後の課題が前の課題を捨てることはない:課題 7 は同じツリーに履歴が付いただけ、課題 8 は他のモジュールの隣に置く小さな新しい機械だ。後の課題のために前の課題を消したくなったなら、課題の読み方を誤っている。Pakai lagi, jangan mulai dari nol. FIFO dari tugas 2, jalur RX dari tugas 3 dan tapis dari tugas 4 semuanya harus masih ada di dalam proyek ketika panel Python menggantikan panel LabVIEW. Tidak ada tugas belakangan yang membuang tugas sebelumnya: tugas 7 adalah pohon berkas yang sama dengan riwayat di atasnya, dan tugas 8 adalah mesin kecil baru yang duduk di samping yang lain. Kalau sebuah tugas belakangan membuatmu menghapus tugas sebelumnya, kamu salah membaca tugasnya.

Checkmarks and released answers are stored in this browser only.打勾狀態與已開放的解答只存在這個瀏覽器裡。チェックと公開済みの解答は、このブラウザ内にのみ保存される。Tanda centang dan jawaban yang dirilis hanya disimpan di peramban ini.