Namuru-Nanoでは、IF信号をサンプリングするクロックを6逓倍して
システムクロックとし、サンプリングクロックはenable信号にするという
少しトリッキーな実装をしています。
これは、オリジナルのNamaruのコードをできるだけ変更しないための
苦肉の策ですが、とりあえずこのままポートします。
Namuru-Nanoでは、システムクロックの生成にNios IIのPLLを使っていましたが、
ZynqではClocking Wizardを使って、MMCMを追加します。
![](https://blogimg.goo.ne.jp/user_image/1c/c6/71ab0de682654fd2023a67f8ba4e3657.png)
クロック入力の周波数は、とりあえずNamuru-Nanoと同じ16.368MHzとし、
それを6逓倍した90.208MHzのシステムクロックと、そのままのenable信号を
出力します。
![](https://blogimg.goo.ne.jp/user_image/0f/c2/326d0bb4dc0c10bc45d47cdd49034685.png)
![](https://blogimg.goo.ne.jp/user_image/04/d3/43f7117d2a4adc2d30df3ba586a10295.png)
![](https://blogimg.goo.ne.jp/user_image/04/64/68676cad45a0715b8b6af59dc84ebdef.png)
生成されたIPコアは、トップモジュールに組み込みます。
フロントエンドから供給されるサンプリング信号s_clkを入力とし、
システムクロックのclkと、enable信号のsample_clkを出力します。
MMCMのlocked信号も、basebandモジュールのリセット信号に追加しています。
![](https://blogimg.goo.ne.jp/user_image/43/6e/9827d784b6adf972997f6345dda4d533.png)
次は、basebandモジュールをIP化して、AXIバスに繋げよう。
システムクロックとし、サンプリングクロックはenable信号にするという
少しトリッキーな実装をしています。
これは、オリジナルのNamaruのコードをできるだけ変更しないための
苦肉の策ですが、とりあえずこのままポートします。
Namuru-Nanoでは、システムクロックの生成にNios IIのPLLを使っていましたが、
ZynqではClocking Wizardを使って、MMCMを追加します。
![](https://blogimg.goo.ne.jp/user_image/1c/c6/71ab0de682654fd2023a67f8ba4e3657.png)
クロック入力の周波数は、とりあえずNamuru-Nanoと同じ16.368MHzとし、
それを6逓倍した90.208MHzのシステムクロックと、そのままのenable信号を
出力します。
![](https://blogimg.goo.ne.jp/user_image/0f/c2/326d0bb4dc0c10bc45d47cdd49034685.png)
![](https://blogimg.goo.ne.jp/user_image/04/d3/43f7117d2a4adc2d30df3ba586a10295.png)
![](https://blogimg.goo.ne.jp/user_image/04/64/68676cad45a0715b8b6af59dc84ebdef.png)
生成されたIPコアは、トップモジュールに組み込みます。
フロントエンドから供給されるサンプリング信号s_clkを入力とし、
システムクロックのclkと、enable信号のsample_clkを出力します。
MMCMのlocked信号も、basebandモジュールのリセット信号に追加しています。
![](https://blogimg.goo.ne.jp/user_image/43/6e/9827d784b6adf972997f6345dda4d533.png)
次は、basebandモジュールをIP化して、AXIバスに繋げよう。
Namuru-NanoのbasebandのHDLをVivadoで合成してみると、当然、
AlteraのIPであるlpm_counterとlpm_shiftregが未定義とエラーが出ます。
![](https://blogimg.goo.ne.jp/user_image/51/a8/f2a21e995ac6dd6d7ec2c69b5888ca4a.png)
lpm_counterは、Xilinx LogiCORE IPのbinary counterに置き換えられそうでしたので、
VivadoのIPカタログからbinary counterを開き、各種パラメータを設定します。
VivadoでのIPコアの使いかたは、こちらを参考にしました。
ACRi:FPGA をもっと活用するために IP コアを使ってみよう (2)
Binary CounterのComponent Nameは、Altera IPと同じlpm_counterにします。
Output Widthは24ビット、Loadableを有効にし、Count ModeはDOWNです。
Synchronous Clearも有効にします。
![](https://blogimg.goo.ne.jp/user_image/61/6f/2b9bd59e8d19bd26a53e50a59dd04fa5.png)
![](https://blogimg.goo.ne.jp/user_image/5a/0f/cb42de256c7442c8a8c87359e80deceb.png)
設定ダイアログのOKをクリックして閉じると、Generate Output Productsの
ダイアログが開きます。GenerateをクリックしてIPコアを合成します。
![](https://blogimg.goo.ne.jp/user_image/2e/b7/9875d73e0a3e7e1d02193f3903506ef9.png)
IPコアのモジュールが準備できたら、SourcesペインのIP Sourcesタブから、
テンプレートファイル(.veo)を開きます。
![](https://blogimg.goo.ne.jp/user_image/19/9f/6c2c9d10e8d898f6bab1cfaad79726ec.png)
このインスタンス生成のテンプレートを、もとのソースコードにコピーして、
入出力ポートの信号を接続します。
![](https://blogimg.goo.ne.jp/user_image/40/de/416abe11a953016a403178651ffb281f.png)
一方、lpm_shiftregは、ちょうど置き換えれるようなIPが見当たりません。
そのため、こちらはモジュールのHDLコードを追加します。
![](https://blogimg.goo.ne.jp/user_image/4b/dc/742fc154d3f34a9f39149478db42c59c.png)
これで、Run Synthesisを実行すると、errorもwarningもなしで、合成が完了します。
![](https://blogimg.goo.ne.jp/user_image/50/ab/18c72f891b0bf379bb861339b28002cf.png)
P.S. Binary Counterの設定画面を見ると、Final Count Valueが1からFFFFFEまでしか選べません。
0までカウントダウンしてくれないのでしょうか?それとも、Restrict Countを有効にしなければ、
0またはFFFFFFがFinal Count Valueになるのでしょうか?別途、テストベンチを組んで確かめよう。
P.P.S. 8ビットのBinary Counterを作成して、テストベンチで動作を確認してみました。
lpm_counterと同様に、loadされた値から0までカウントダウンしてくれるようです。
![](https://blogimg.goo.ne.jp/user_image/3f/72/299d1d9b6becab3bd04b9992f1249be2.png)
![](https://blogimg.goo.ne.jp/user_image/58/c8/1602967aa5590674cf10b4e8e46fa6c9.png)
AlteraのIPであるlpm_counterとlpm_shiftregが未定義とエラーが出ます。
![](https://blogimg.goo.ne.jp/user_image/51/a8/f2a21e995ac6dd6d7ec2c69b5888ca4a.png)
lpm_counterは、Xilinx LogiCORE IPのbinary counterに置き換えられそうでしたので、
VivadoのIPカタログからbinary counterを開き、各種パラメータを設定します。
VivadoでのIPコアの使いかたは、こちらを参考にしました。
ACRi:FPGA をもっと活用するために IP コアを使ってみよう (2)
Binary CounterのComponent Nameは、Altera IPと同じlpm_counterにします。
Output Widthは24ビット、Loadableを有効にし、Count ModeはDOWNです。
Synchronous Clearも有効にします。
![](https://blogimg.goo.ne.jp/user_image/61/6f/2b9bd59e8d19bd26a53e50a59dd04fa5.png)
![](https://blogimg.goo.ne.jp/user_image/5a/0f/cb42de256c7442c8a8c87359e80deceb.png)
設定ダイアログのOKをクリックして閉じると、Generate Output Productsの
ダイアログが開きます。GenerateをクリックしてIPコアを合成します。
![](https://blogimg.goo.ne.jp/user_image/2e/b7/9875d73e0a3e7e1d02193f3903506ef9.png)
IPコアのモジュールが準備できたら、SourcesペインのIP Sourcesタブから、
テンプレートファイル(.veo)を開きます。
![](https://blogimg.goo.ne.jp/user_image/19/9f/6c2c9d10e8d898f6bab1cfaad79726ec.png)
このインスタンス生成のテンプレートを、もとのソースコードにコピーして、
入出力ポートの信号を接続します。
![](https://blogimg.goo.ne.jp/user_image/40/de/416abe11a953016a403178651ffb281f.png)
一方、lpm_shiftregは、ちょうど置き換えれるようなIPが見当たりません。
そのため、こちらはモジュールのHDLコードを追加します。
![](https://blogimg.goo.ne.jp/user_image/4b/dc/742fc154d3f34a9f39149478db42c59c.png)
これで、Run Synthesisを実行すると、errorもwarningもなしで、合成が完了します。
![](https://blogimg.goo.ne.jp/user_image/50/ab/18c72f891b0bf379bb861339b28002cf.png)
P.S. Binary Counterの設定画面を見ると、Final Count Valueが1からFFFFFEまでしか選べません。
0までカウントダウンしてくれないのでしょうか?それとも、Restrict Countを有効にしなければ、
0またはFFFFFFがFinal Count Valueになるのでしょうか?別途、テストベンチを組んで確かめよう。
P.P.S. 8ビットのBinary Counterを作成して、テストベンチで動作を確認してみました。
lpm_counterと同様に、loadされた値から0までカウントダウンしてくれるようです。
![](https://blogimg.goo.ne.jp/user_image/3f/72/299d1d9b6becab3bd04b9992f1249be2.png)
![](https://blogimg.goo.ne.jp/user_image/58/c8/1602967aa5590674cf10b4e8e46fa6c9.png)
![](https://blogimg.goo.ne.jp/user_image/62/51/553b4afdd78fc6cb0632185cb9378c5a.png)
10年以上も前に、NamuruのHDLコードをAlteraのDE0-Nano+MAX2771の
組み合わせに移植しています。
https://blog.goo.ne.jp/osqzss/e/e088b635bc33084117b7e9606316a569
すっかり放置しており、細かなところを忘れていますが、HDLに関しては
ほぼこのままZynqベースのPocketGNSSに移植できるかと思います。
CPUがソフトコアのNios IIから、Zynq内蔵のARMに変わりますので、
バス回りは調整が必要です。FPGAに実装される相関器が汎用的に使えるよう、
相関器とCPUとのインターフェイスはSPIなどにした方が良いかもしれません。
オリジナルのNamuru-NanoのソースコードをGoogle Driveにソースコードを
アップしましたので、興味のある方は開発に参加してもらえると嬉しいです。
https://drive.google.com/drive/folders/141BSfAa7lHga43nRK0nXX9STol0DK0OE?usp=sharing
組み合わせに移植しています。
https://blog.goo.ne.jp/osqzss/e/e088b635bc33084117b7e9606316a569
すっかり放置しており、細かなところを忘れていますが、HDLに関しては
ほぼこのままZynqベースのPocketGNSSに移植できるかと思います。
CPUがソフトコアのNios IIから、Zynq内蔵のARMに変わりますので、
バス回りは調整が必要です。FPGAに実装される相関器が汎用的に使えるよう、
相関器とCPUとのインターフェイスはSPIなどにした方が良いかもしれません。
オリジナルのNamuru-NanoのソースコードをGoogle Driveにソースコードを
アップしましたので、興味のある方は開発に参加してもらえると嬉しいです。
https://drive.google.com/drive/folders/141BSfAa7lHga43nRK0nXX9STol0DK0OE?usp=sharing
PocketGNSSに実装予定の相関器の構成を示します。
まずは、スタンダードにGPS L1 C/Aコードの相関器を組んで行きます。
![](https://blogimg.goo.ne.jp/user_image/3e/d4/b10d6d65ef1dda7db0f15c9f2c65cada.png)
ひとつの衛星の信号処理には、この相関器が2つ必要になります。
一方の相関器では、搬送波NCOによって同位相の搬送波レプリカが、
もう一方の相関器では直交位相の搬送波レプリカが生成されます。
P.S. 相関器は、オープンソースのNAMURUをベースに開発します。
DE0-Nanoに移植したのが10年以上前なのね。すっかり忘れている。
https://blog.goo.ne.jp/osqzss/e/e088b635bc33084117b7e9606316a569
まずは、スタンダードにGPS L1 C/Aコードの相関器を組んで行きます。
![](https://blogimg.goo.ne.jp/user_image/3e/d4/b10d6d65ef1dda7db0f15c9f2c65cada.png)
ひとつの衛星の信号処理には、この相関器が2つ必要になります。
一方の相関器では、搬送波NCOによって同位相の搬送波レプリカが、
もう一方の相関器では直交位相の搬送波レプリカが生成されます。
P.S. 相関器は、オープンソースのNAMURUをベースに開発します。
DE0-Nanoに移植したのが10年以上前なのね。すっかり忘れている。
https://blog.goo.ne.jp/osqzss/e/e088b635bc33084117b7e9606316a569
PocketSDR+FPGAの開発環境を整えるべく、まずは2つのMAX2771の中心周波数や
サンプリング周波数を設定できるようにします。基本的には↓と同じ。
https://blog.goo.ne.jp/osqzss/e/9beea46afd397912bbcebe5a57c8a14e
![](https://blogimg.goo.ne.jp/user_image/02/cf/4ab201190c819688959c1291fca8128a.jpg)
デフォルトのレジスタ値は、PocketSDRと同じにしています。
![](https://blogimg.goo.ne.jp/user_image/30/60/c392e9ba4dadd09d76c11075eaae622d.png)
問題なくレジスタが設定できているようです。
![](https://blogimg.goo.ne.jp/user_image/27/77/2c8cd45580aeedd4b85868c21a62b2aa.png)
開発のベースとなる環境は整ったので、次は相関器を実装して信号捕捉を目指します。
MATLAB/SimulinkのHDL Coderも試してみたい。
https://blog.goo.ne.jp/osqzss/e/8f2b39bbacd19d9d08f037cce23fd5de
P.S. ソースコードをGitHubで公開して行きたいのだけれども、Vivadoのプロジェクトや
Block Design、Vitisのプロジェクトをそれぞれバージョン管理する良い方法が分からない。
P.P.S. なひたふJTAG日記:Vivadoのプロジェクトをgitで管理する最小限は何か
http://nahitafu.cocolog-nifty.com/nahitafu/2019/05/post-60422b.html
サンプリング周波数を設定できるようにします。基本的には↓と同じ。
https://blog.goo.ne.jp/osqzss/e/9beea46afd397912bbcebe5a57c8a14e
![](https://blogimg.goo.ne.jp/user_image/02/cf/4ab201190c819688959c1291fca8128a.jpg)
デフォルトのレジスタ値は、PocketSDRと同じにしています。
![](https://blogimg.goo.ne.jp/user_image/30/60/c392e9ba4dadd09d76c11075eaae622d.png)
問題なくレジスタが設定できているようです。
![](https://blogimg.goo.ne.jp/user_image/27/77/2c8cd45580aeedd4b85868c21a62b2aa.png)
開発のベースとなる環境は整ったので、次は相関器を実装して信号捕捉を目指します。
MATLAB/SimulinkのHDL Coderも試してみたい。
https://blog.goo.ne.jp/osqzss/e/8f2b39bbacd19d9d08f037cce23fd5de
P.S. ソースコードをGitHubで公開して行きたいのだけれども、Vivadoのプロジェクトや
Block Design、Vitisのプロジェクトをそれぞれバージョン管理する良い方法が分からない。
P.P.S. なひたふJTAG日記:Vivadoのプロジェクトをgitで管理する最小限は何か
http://nahitafu.cocolog-nifty.com/nahitafu/2019/05/post-60422b.html
今度はVitisを起動してworkspaceを選んでも、「Vits IDE 応答なし」のまま
Vitis IDEが立ち上がらない。
![](https://blogimg.goo.ne.jp/user_image/54/7e/32e05fb7b79c8f2291d5c4b253f50711.png)
原因不明だけれども、「eclipse.exe -clean」で解決するらしい。
https://marsee101.blog.fc2.com/blog-entry-5551.html
魔法の言葉、「vitis -eclipseargs -clean」でVitisを起動してworkspaceを選ぶと、
無事にVitis IDEが起動しました
Vitis IDEが立ち上がらない。
![](https://blogimg.goo.ne.jp/user_image/54/7e/32e05fb7b79c8f2291d5c4b253f50711.png)
原因不明だけれども、「eclipse.exe -clean」で解決するらしい。
https://marsee101.blog.fc2.com/blog-entry-5551.html
魔法の言葉、「vitis -eclipseargs -clean」でVitisを起動してworkspaceを選ぶと、
無事にVitis IDEが起動しました
![](https://blogimg.goo.ne.jp/user_image/64/83/0a3aa94a6fa4e7a633875c50869ba52d.png)
久しぶりにZybo Z7にbitstreamを書き込もうとしたら、ターゲットを認識してくれない。
![](https://blogimg.goo.ne.jp/user_image/6d/56/ca11b618906631b728a73f470bf472f0.png)
原因が不明なので、Digilentのcable driverを再インストール。インストーラは↓で見つかります。
vivadoインストールフォルダ\data\xicom\cable_drivers\nt64\digilent\install_digilent.exe
![](https://blogimg.goo.ne.jp/user_image/6d/56/ca11b618906631b728a73f470bf472f0.png)
原因が不明なので、Digilentのcable driverを再インストール。インストーラは↓で見つかります。
vivadoインストールフォルダ\data\xicom\cable_drivers\nt64\digilent\install_digilent.exe
「新しいフェーズに入った衛星測位技術を加速させる人材育成」の教材に
ソフトウェア受信機を活用していますが、FPGAでスタンドアローンの
GNSS受信機を開発したいという要望も多いです。
そこで、PocketSDRのフロントエンド部だけを取り出し、ZYBO-Z7など
DIGILENT社のFPGA評価ボードに接続できる基板を作製しました。
![](https://blogimg.goo.ne.jp/user_image/69/80/00bd8f3906251d4a37ca34b4bec45d35.jpg)
オリジナルのPocketSDRからは、基板を4層にしたり、RF分配器に
100オームのアイソレーション抵抗を追加したり、RF性能の改善を
試みています。
![](https://blogimg.goo.ne.jp/user_image/5e/a2/954439a1622b7df3923bda18350862d3.jpg)
ZYBO-Z7とセットで、5台ほど準備する予定です。開発に興味があり
協力していただける方は、ぜひ人材育成プロジェクトまでご連絡ください。
P.S. まずはEZ-USB FX2LP Discoveryに接続して、PocketSDRとして動作を確認。
問題なくGNSS信号の捕捉が確認できました。
![](https://blogimg.goo.ne.jp/user_image/22/57/5e83d78362932c38c75bca65f69e32b1.jpg)
ソフトウェア受信機を活用していますが、FPGAでスタンドアローンの
GNSS受信機を開発したいという要望も多いです。
そこで、PocketSDRのフロントエンド部だけを取り出し、ZYBO-Z7など
DIGILENT社のFPGA評価ボードに接続できる基板を作製しました。
![](https://blogimg.goo.ne.jp/user_image/69/80/00bd8f3906251d4a37ca34b4bec45d35.jpg)
オリジナルのPocketSDRからは、基板を4層にしたり、RF分配器に
100オームのアイソレーション抵抗を追加したり、RF性能の改善を
試みています。
![](https://blogimg.goo.ne.jp/user_image/5e/a2/954439a1622b7df3923bda18350862d3.jpg)
ZYBO-Z7とセットで、5台ほど準備する予定です。開発に興味があり
協力していただける方は、ぜひ人材育成プロジェクトまでご連絡ください。
P.S. まずはEZ-USB FX2LP Discoveryに接続して、PocketSDRとして動作を確認。
問題なくGNSS信号の捕捉が確認できました。
![](https://blogimg.goo.ne.jp/user_image/22/57/5e83d78362932c38c75bca65f69e32b1.jpg)
![](https://blogimg.goo.ne.jp/user_image/46/cf/aeec8dd857f8f30075c64f1fc1f68dd3.png)
一年以上放置していたMAX2771の基板をZYBOに接続して、GNSS受信機開発を再開。
https://blog.goo.ne.jp/osqzss/e/72ac9b6eca3813b12310b58b70e4dddc
![](https://blogimg.goo.ne.jp/user_image/4b/00/39d553115cfd6c72c2d1075e4c5941bf.jpg)
まずは、MAX2771のレジスタにアクセスして、中心周波数やサンプリング周波数を設定できるようにします。
インターフェイスには、PocketSDRで動作が確認できているGPIOによるbit bangingを採用。
データの読み書きは、同じピンをinoutで使うため、AXIO GPIOのAll InputsとAll Outputsの
どちらもチェックせずにBlock Designに組み込みます。
![](https://blogimg.goo.ne.jp/user_image/3c/7c/539a2627862a63af266c59c49e426a32.png)
こうすることで、Wrapperの生成で自動的にIOBUFのプリミティブが挿入され、inoutのピンになります。
![](https://blogimg.goo.ne.jp/user_image/5c/9e/027c055380e241589a444bcfbb931250.png)
GPIOの制御は、PocketSDRのコードをほぼそのまま流用。
大きな違いは入出力の方向が0で出力、1で入力ということくらい。
![](https://blogimg.goo.ne.jp/user_image/77/7e/77a2b7e3f075a55795f90c7cb1aaca03.png)
問題なくMAX2771のレジスタにアクセスできました。
https://blog.goo.ne.jp/osqzss/e/72ac9b6eca3813b12310b58b70e4dddc
![](https://blogimg.goo.ne.jp/user_image/4b/00/39d553115cfd6c72c2d1075e4c5941bf.jpg)
まずは、MAX2771のレジスタにアクセスして、中心周波数やサンプリング周波数を設定できるようにします。
インターフェイスには、PocketSDRで動作が確認できているGPIOによるbit bangingを採用。
データの読み書きは、同じピンをinoutで使うため、AXIO GPIOのAll InputsとAll Outputsの
どちらもチェックせずにBlock Designに組み込みます。
![](https://blogimg.goo.ne.jp/user_image/3c/7c/539a2627862a63af266c59c49e426a32.png)
こうすることで、Wrapperの生成で自動的にIOBUFのプリミティブが挿入され、inoutのピンになります。
![](https://blogimg.goo.ne.jp/user_image/5c/9e/027c055380e241589a444bcfbb931250.png)
GPIOの制御は、PocketSDRのコードをほぼそのまま流用。
大きな違いは入出力の方向が0で出力、1で入力ということくらい。
![](https://blogimg.goo.ne.jp/user_image/77/7e/77a2b7e3f075a55795f90c7cb1aaca03.png)
問題なくMAX2771のレジスタにアクセスできました。
![](https://blogimg.goo.ne.jp/user_image/42/41/3268d4bcbfa1832273fb291d75fbf129.png)