この記事は、NetBSD Advent Calendar 2025の24日目の記事です。
はじめに
21日目から23日目にかけて、安価に購入したFPGA基板であるTang Nano 9Kのための開発環境をNetBSD上に整え、基本的にはNetBSDだけで開発できることを確認しました。 でも、合成や配置配線にもベンダー特有の最適化が必要であるかもしれません。 また、GOWIN FPGA Designerでは、A/Dコンバーターなどの各種ロジックやArm Cortex-M0やRISC-Vなどのアーキテクチャーのマイクロコントローラーを選択するメニューがありました。 どこまで無料で使えるのか分かっていませんが、そういうものはNetBSD上では使いようがなさそうです。
とは言え、私がVerilogを学んだり、Tang Nano 9Kを購入したのは、PyRTLという教育用のHDLを使ってみたかったためでした。 なので、そういう便利なものは使えなくても困りません。 PyRTLはVerilogのソースコードを出力してくれるので、21日目のように作業できれば、最適化は別として、それで良いとも言えます。
ですが、マイナーなものを使うと、世界で最初に困る人になってしまいがちです。 PyRTLにはJupyer Notebook/JupyeterLabで学べるような教材が用意されているのですが、少なくとも2025年12月28日現在lpkgsrc経由で利用できるJupyter Notebook/JupyterLabではエラーになりウェーブフォームをウェブブラウザー上では見ることができません。 せっかくPyRTLにはシミュレーション機能が内蔵されているのに、それを活用することができません。
おそらくNetBSDで作業しているから発生する問題ではないと思われるものの、pkgsrc/cad/py-PyRTL-0.12が壊れているのは困りますので、直すことにしました。
エラーの内容
まず、私は以下のようなJupyter NotebookとJupyterLabのパッケージをインストールしています。 これ以外にも関連するものはありますが、そこまで厳密である必要はないでしょう。
py314-jupyter-lsp-2.3.0 py314-jupyter_server_terminals-0.5.3 py314-jupyter_client-8.7.0 py314-jupyterlab-4.4.10 py314-jupyter_core-5.9.1 py314-jupyterlab-pygments-0.3.0 py314-jupyter_events-0.12.0 py314-jupyterlab-server-2.28.0 py314-jupyter_server-2.17.0
エラーの内容は非常に簡単です。ipynb-examples/example1-combologic.ipynbと言う教材のStep 2の3個目のセルのsim.tracer.render_trace(symbol_len=2)が失敗します。
エラーメッセージはJavascript Error: $ is not definedです。
FirefoxのDevelopert toolのconsoleには何も出ていませんが、Jupyter Notebook/JupyterLabの画面上に表示されるエラーです。
実を言うと、ipynb-examples/example1-combologic.ipynbは、examples/example1-combologic.pyから自動生成されています。 と言うことで、examples/example1-combologic.pyの内容をそのままJupyter Notebook/JupyterLabの1つのセルで実行して、どこがいけないのか調査することにしました。
エラーを調査する
ipynbファイルを保存すると、以下のような内容が含まれています。 この内容は元々のipynbにはありません。 どこかで自動的に挿入されているはずです。
(snip)
$.getScript("https://cdnjs.cloudflare.com/ajax/libs/wavedrom/1.6.2/skins/default.js"),
$.getScript("https://cdnjs.cloudflare.com/ajax/libs/wavedrom/1.6.2/wavedrom.min.js"),
(snip)
ここまで特徴的であれば、/usr/pkg/lib以下を探しても迷うことはありません。
pyrtl/simulation.pyというファイルに含まれていることが分かりました。
そして、この$は、jQueryが提供されることが期待されているようです。
ですが、私のインストールしているJupyter NotebookもJupyterLabも、ウェブブラウザー上でjQueryの$は提供していないようです。
少なくとも$.getScript関数は使えません。
どこかでjQueryのgetScript関数は使うなと言われたような記憶もありますが、最新版では使えるのかもしれません。 いずれにしても、PyRTLの教材を動かすのには十分なはずです。 と言うことで、jQueryを読み込んだ後に、問題の箇所を実行するようにすれば良さそうです。
エラーを修正する
オリジナルのPyRTL-0.12のソースコードで関連する箇所を以下に示します。 この中の1775行目からのjs_code変数の中身を書き換えれば良さそうです。 改めて見ると、問題の箇所は、当然ですがJupyter Notebook/JupyterLabで実行した場合のみ呼び出されるようになっています。
1760 if _currently_in_jupyter_notebook():
1761 from IPython.display import (
1762 HTML,
1763 Javascript,
1764 display,
1765 )
1766
1767 from pyrtl.visualization import trace_to_html
1768
1769 htmlstring = trace_to_html(
1770 self, trace_list=trace_list, sortkey=_trace_sort_key
1771 )
1772 html_elem = HTML(htmlstring)
1773 display(html_elem)
1774 # print(htmlstring)
1775 js_stuff = """
1776 $.when(
1777 $.getScript("https://cdnjs.cloudflare.com/ajax/libs/wavedrom/1.6.2/skins/default.js"),
1778 $.getScript("https://cdnjs.cloudflare.com/ajax/libs/wavedrom/1.6.2/wavedrom.min.js"),
1779 $.Deferred(function( deferred ){
1780 $( deferred.resolve );
1781 })).done(function(){
1782 WaveDrom.ProcessAll();
1783 });"""
1784 display(Javascript(js_stuff))
Jupyter NotebookやJupyterLabを実行できるウェブブラウザーであれば、fetch関数やpromiseのサポートは持っているはずな気がします。 と言うことで、安直ですがfetchして実行する関数を用意し、jQueryを読み込んだ後に、promiseを使って、既存のロジックを実行させることにしました。
以下のようなパッチを作成して適用しました。
@@ -1773,6 +1773,16 @@ class SimulationTrace:
display(html_elem)
# print(htmlstring)
js_stuff = """
+ function fetchAndRunScript(uri) {
+ return fetch(uri)
+ .then(resp => resp.text())
+ .then(scrtext => {
+ const scrfunc = new Function(scrtext);
+ scrfunc();
+ })
+ .catch(err => console.error('Cannot load script:', err));
+ }
+ fetchAndRunScript("https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js").then(() => {
$.when(
$.getScript("https://cdnjs.cloudflare.com/ajax/libs/wavedrom/1.6.2/skins/default.js"),
$.getScript("https://cdnjs.cloudflare.com/ajax/libs/wavedrom/1.6.2/wavedrom.min.js"),
@@ -1780,7 +1790,7 @@ class SimulationTrace:
$( deferred.resolve );
})).done(function(){
WaveDrom.ProcessAll();
- });"""
+ });});"""
display(Javascript(js_stuff))
else:
self.render_trace_to_text(
こうすることで、ウェブブラウザー上でウェーブフォームを表示させることができるようになりました。 これで、FPGAに実装する前のチェックが簡単になります。
pkgsrc/cad/py-PyRTL-0.12nb1としてcommitしておこうと思います。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。