はじめに
RISC-V に興味があって Tang Primer を買ったのが 2020年5月頃。ADC をいじろうとするも、やりかけてお蔵入りに。記憶あいまいだけどある程度のところまで進んでました。安価な Tang Primer の ADC も使えるようになれればいいなということで、とりあえず今回は実際に動かすところまでやってみました (2021年11月末)。
そういえば当初は家にある激安電子ドラムのカスタマイズに使おうと思ったんだっけ。なんもしてない。。
Tang Primer
Anlogic の EG4S20 を搭載した Sipeed の FPGA 開発ボードです。
使い方は Tang Primer の上記 URL の Getting Started を見ていただければ。あとはググれば試されている方の情報見つかります。本もあるようですね。
EG4S20 の ADC
EG4S20 の ADC は 8-channel 12-bit 1MSPS ですが、詳細はデータシートをみてみます。
データシートは以下からダウンロードできます。
以下、Eagle_DataSheet_V2.8_english.pdf から抜粋しました。
電気的特性
ADCモジュールの端子機能
タイミングチャート
VREF は Tang Primer では 3.3V 固定です。従って 0-3.3V が 0-4095 に対応します。またADC のクロックは最大 16MHz。16 cycle で変換終了するので、ちょうど 1MSPSになります。
動作は SOC に 1パルス与えると動作開始で、EOC 1パルスでれば終了です。チャネルの選択は SOC より前に選択して EOC が立つまで保持ということかな。アナログのマルチプレクサの切り替えになると思うので早めに切り替えておくに越したことはないと思います。
Sampling Pulse と書かれている部分は多分、Sample/Hold 回路が開いている時間だと思うのですが、ここの長さは制御できないようです。まぁ、中の回路はクロック同期なんでしょうから、例えばこの期間のクロックを伸ばせば多分時間延ばせるのではないかと思います。なのでちょっとしたクロックゲーティング回路を足せば実現できるのでは?でもEG4S20に CG (Clock Gating)セルなんてあるんでしょうかね。Latch と AND または OR で作れなくはないけどタイミング合うかな。。
ADC IP Core の生成
RTL を書く前に IP core を生成します。とはいっても ADC のモジュール EG_PHY_ADC の有効にしたいチャネルを入れたラッパーをインスタンスするだけのようです。手置きしても大丈夫っぽいですが、Generator を使います。EG_PHY_ADC はパラメータで各チャネルのEnable, Disable を切り替えるようです。
EG4S20 _DataSheet_V1.5_english.pdf の 4.1 Special IP use にごく簡単に生成方法が書かれています。有効にしたいチャネルを選択するぐらいです。途中 File (ファイル名)と Component name (module 名)を指定するところがあります。adc など何でもいいとは思いますが、同じ名前にしておいてもいいでしょう。好みですが。あと Add to project ウィンドウでプロジェクトに入れる?と確認するところはチェックを入れてOKしておけばプロジェクトに取り込まれます。ファイルはデフォルトでプロジェクトのフォルダの下の al_ip フォルダ以下に置かれます。
選択したチャネルのピンアサインは固定で、IO Constraint で与えることはできません。また選択したチャネルにアサインされたピンは、IO Constraint から他の機能にアサインできなくなります。TD (Tang Dynasty) の HDLBit Flow で Optimize RTL まで実行すると IO Constraint で選択できるピンから消えます。
Tang Primer の端子アサインについては、sipeed-tang-primer-pins.pdf で確認できます。
SPI + ADC の仕様
ADCの動作を確認するため、SPI client?(今どきはなんとよべば) I/F をくっつけてみます。SPI は CPOL=0, CPHA=0 のモード0 で。ビット幅は 16bit とします。お手軽に SS が下がったら ADC を起動して、5bit 目から ADC 12bit の結果を MISO(いやこのネーミングもどうすれば。。)に出力します。ADC の結果は符号なしなので、とりあえず最初の上位 4bit は 0 出力で埋めておきます。ちなみに ADC 終了の eoc は見てません。SPI のクロックが早すぎると間に合いません。
タイミングチャートは Google のスプレッドシートでw
クロックは Tang Primer のボードには 24MHz の Xtal が載ってます。これから 16MHz 以下の ADC clock を作ればいいので 1/2 分周して 12MHz のクロックを ADC に与えることにします。この条件で SPI は 2MHz 程度で動作します。
端子アサインは以下の通りにしました。
N11: ADC0 (ADC 入力)
K14: CLK_IN (24MHz Xtal)
C15: MISO
C16: MOSI (使いません)
B16: SCLK
B15: SS
K16: XRES_IN (Tang Primer の USER スイッチ。プルアップされてます)
Simulation
回路が出来たので検証します。ADC モジュールのビヘイビアがあるのでそれを利用します。
ビヘイビアは以下の場所にあります(Windows の場合)。
C:\Anlogic\TD4.6.4\sim
TD でテストベンチのトップとか、Model Sim 用の do ファイルとか作ってくれるのですが、自前でテストベンチ用意して、Icarus verilog (iverilog) で検証してみました。
ところで ADC モジュールのビヘイビア、eg_phy_adc.v の中身を見ると、Channel select signal s に与えた値を dout に出す仕様のようです。s のチェックにはなるのですが、SPI 含めてデータがちゃんと通るかどうかを見るために、テストベンチでは ADC の出力データを決めている sample_B を外からフォースしてシミュレーションしてみます。1bit だけ立てて SPI で読み込み、を 12bit 繰り返します。
GtkWave
論理合成と書き込み
端子アサインは FPGA Flow の User Constraints -> IO Constraint から指定して、適当な名前で保存しておきます。
タイミング制約は FPGA Flow の User Constraints -> SDC Constraint で作成。途中経過出すと長くなるので、作成した制約の中身は以下のような感じ。create_clock だけやっときました。
合成は緑の丸に三角のボタンで。あっという間です。特にバイオレーションとかもないので、下矢印のアイコンをクリックして書き込みです。イレースして、Flash に書き込みます。
動かしてみる
合成結果を書き込んだ Tang Primer を実際に動かしてみます。
ADC の入力はパルジェネとか安定化電源持っていないので、M5Stack の DAC を使って生成しました。12bit の ADC に対して 8bit の DAC では役不足だし、正確な出力も作れず、校正された計測機器は持ち合わせていないので、ファンクション確認程度になります。
また Tang Primer に実装した ADC は SPI I/F を持っているのでもう一つ用意した M5Stack で SPI をポーリングで動かして ADC のデータを取り込んでみました。
DAC の出力は Faces に付けたエンコーダーパネルでグリグリすると変わるのがわかると思います。だいたい。。同じ値ということで。
ずっと前から試したかったTangPrimer の ADCようやく動かしてみました。Gray の 8bit DACでADCの入力作って、Basic は TangPrimer に実装した SPI 経由でデータの取り込み。#TangPrimer #M5Stack pic.twitter.com/AfChPzkt4X
— たつるー (@ttrsato) November 30, 2021
今回お試ししたデータ
Git に上げておきます。
RTL 検証・合成環境
RTL
src, al_ip フォルダに入っています。
adc_top.v
トップレベル階層です。adc_core と spi がインスタンスされています。
トップレベル階層です。adc_core と spi がインスタンスされています。
spi.v
SPI I/F 部分です。
adc_core.v
EG_PHY_ADC をインスタンスしています。
テストベンチ
simulation フォルダに入っています。
tb_spi_test.v
テストベンチのトップです。adc_top.v をインスタンスしています。
run_spi.bat
テストベンチ実行用バッチファイルです。実行すると iverilog でシミュレーションを走らせて検証を行います。tb_spi_test.vcd が生成されますので、GtkWave などで波形を確認できます。
実行環境
Windows10 で実行しました。
TD 4.6.4 64-Bit
Verilog simulation iverilog 11.0 (devel)
VCD 波形表示 v3.3.100
M5Stack プログラミング環境
m5stack フォルダに入っています。
ADC_SPI_IF.ino
Tang Primer と SPI 接続する側です。ポーリングした結果をディスプレイに表示します。
SCLK(G5), MISO(G17), MOSI(G16), SS(G22)
MOSI は使っていません。
DAC_Controller.ino
Tang Primer の ADC の入力信号を DAC で作ります。Faces のエンコーダーパネルを使う前提のコードです。出力中のデータを画面に表示します。
DAC1(G26)
Arduino IDE 1.8.13 で確認しています (なぜかこちらは Mac で。Windows でもきっと問題ないです)。M5Stack ディレクトリに .ino ファイルを置いています。
SPI master (MOSI はいらない) と DAC がそれぞれひとつずつ使えればいいので、M5Stack シリーズならほぼなんでもいいと思います。多少書き換えは必要とは思いますが。エンコーダーパネルを使いましたが、ボタンで値の上下でもいいですね。
0 件のコメント:
コメントを投稿