« 2019年12月 | トップページ | 2020年2月 »

2020.01.28

TEC0117ボードを入荷しました

GOWINのGW1NR-9という8MByteのSDRAMを内蔵したFPGAボードがTrenzElectronic社から発売されています。

これを入荷しました!

Tec01172

箱の中身はこんな感じ。

Tec01171

下記のURLで販売しています。

https://www.trenz.jp/product/TEC0117-01

品切れの際には、次の入荷までしばらくお待ちいただくことになると思うので、お早めに!

Epwswrguyaieqnf

 

 

| | コメント (0)

2020.01.27

DACボードの動作テスト

8ch 125MHz 14bit DACボードの動作テストをしています。

Dac_build5

ねじ穴で内層が切れていたり、SPIのCLKのネットがつながっていなかったりということで多少のジャンパが飛ぶ結果となりました・・・

まぁ、急いで作った基板だし、一発ではうまく動きませんね。

軽微な修正でよかったです。

つるっつるの正弦波を出すことに成功。

Dac_wave

DACボードから1MHzの正弦波を出してADCで受けたときの歪率は-80dB。10MHzでも-60dBくらいでした。

Epsy7yqvuaea5rf

Epsyhwouuaebusz

同軸ケーブルや容量負荷でも当然ながら発振しない。望んだとおりの性能が出たと言えます。

あとは顧客の要求仕様に合うようにOPアンプの帰還抵抗を調整して出力電圧の調整を行えば完成なのですが、±5V出すとか、結構厳しいかもしれません。

出力段には、「かわかわさん」に教えていただいたTHS3491を使ったほうがいいかなと思えてきました。

 

| | コメント (0)

2020.01.25

DACボードのはんだ付け(続き)

日付が変わり、少し休んでから再開です。

下の写真は完全作動アンプの帰還抵抗。

Dac_build1

8chあるとだんだんめげてきますが、頑張って実装するしかありません。

Dac_build3

ようやく形になってきました。

Dac_build2

この基板はCosmo-Zの下側に付けるので、常に裏面が見えている形になります。

Dac_build4

そのため、ICや、オシロでプローブする必要のある部品は全部裏面に乗せました。

明け方の5時にようやく完成です。

 

| | コメント (0)

2020.01.24

DAC基板の実装開始

Digikeyから届くはずの荷物が飛行機の遅延で遅れたので今日から実装開始です。

やるぞー

Dac1_20200212110901

まずは小さな部品からということで、コンデンサを付けていきます。

Dac2_20200212110901

次にICを付けていきます。

Dac3_20200212111001

QFNなら余裕。BGAじゃなければ手で付けられます。

Dac4_20200212111001

全部で500個くらいの部品があるのでしんどいですが、やるしかありません。

 

| | コメント (0)

2020.01.23

Cosmo-Kの基板とDACボードが届く

製造を行っていたCosmo-Kの改版基板と、DACボードが届きました。

Cskdac

DACボードは1月20日に出図だから、驚きの速さです。

Dacboard2_20200212110501

Dacboard3_20200212110501

実装に出していると間に合わないので手付けでいきますよ~

 

| | コメント (0)

2020.01.22

Cosmo-Zの実装完了と動作テスト

実装中の基板が次から次へと上がってきます。

Cosmoz6pcs

あるお客様は25日締めなので、納品が1月25日を過ぎると翌月扱いになって入金が3月末になってしまうかもしれません。

(そもそも、25日締め翌月末払いだと26日から31日の間に相手方に届くと翌々月末支払いになって60日以上の支払サイトになる場合があるので、下請法のコンプライアンス的にどうなのかという問題はあります。

声を大にして言いますが、25日締め翌月末払いは下請法の支払遅延となる可能性をはらんだ条件なので、この世の中から消えてなくなったほうがよいです)

ただ、そんなことを言っても相手がわかってくれないと(もしくは、わかっていてそういう条件に設定しる場合も)揉めるだけなので、25日までに納品するのが吉です。しかも今月は25日が土曜日なので24日の金曜日には届いていないと面倒なことになりそうです。

そういうわけで、急いで製造していたのですが、何とか、今日基板が届きました。

 

今までP●.comで作っていた基板を国産メーカーに切り替えたので、ちょっと不安はあったのですが6台とも完璧に動作してくれました。P社で6層だと最速で急いでも受注日はカウントしないとか金フラッシュ+1日とかで1週間くらいはかかりますが、某国産メーカーは土曜日も営業してくれているので、本当に速く届きます。しかも安い。

それを信頼できる実装業者で特急実装し、本日届きました。

Cosmozcomplete

さあ、これを全力で検査するぞ!

Cosmozexam

 

6台のCosmo-Zの全48チャネルに1つずつ正弦波を入れていき、すべてのチャネルで波形が取れるかどうかを軽くテストしたところ、全く問題なしでした。

Cosmozwave

@100kHzでの歪率も-80db以下で、正弦波を正弦波として扱えています。

Cosmozfft

6台の検査が無事に終わりました。

Cosmozcomplete2

すべてのチャネルは完璧に動作しました。

明日さらに正確に測定して、無事に出荷できそうです。

| | コメント (0)

2020.01.21

Cosmo-Kの基板が届いた

1月の14日ごろに実装に出していたCosmo-Kの基板が届きました。

Cosmok

Cosmo-Kシリーズには、SFP(10Gbps)×3個のCosmo-K-と、SFP×3個とユニバーサルエリアの付いたCosmo-K0と、QSFP(40Gbps)が1個のCosmo-K+がありますが、上の写真のように1枚の基板に面付して製造しています。そのため、K+とK-とK0の製造台数が変わると使われなかった基板が無駄になってしまいます。

K0はほとんど受注がないので無視していいのですが、K+はK-より少し少ないのがもったいなく感じるところです。

出来上がってきた基板にファームウェアを書き込んで、USB3.0のテストを行ったところ、IN/OUTともに300MByte/sec出ていて、かつ256Mバイトまでのメモリの検査を行って異常なしでした。

ひとまず安心です。

 

| | コメント (0)

2020.01.20

新しいDAC基板を設計します(2)

機能の設計の続きを行います。

AM 0:30

基板のパターンを8個コピペしただけだったのを、回路図を複製して部品番号を振りなおしネット名を付け替えます。この作業が一番大変でした。

AM 5:00

8ch分の回路が正しく出来上がります。

AM 5:58

このDACチップは250MHz 14bitのパラレルインタフェースなのでメザニンコネクタまで一対一で配線を引けます。

クロックは大事にしようとガードリングを付けたり別の層にしたら、SPIの配線が引きにくくなることに気が付いて、1時間の手戻りが発生です。

Dac5

AM 8:01

家族の食事を作ったり、子供を学校に送り出したりして、仕事の再開です。

この基板は0.1mm/0.1mmのルールにしなくても0.125mmでいけるかと思ったり、6層にしなくても4層でいけると思い、デザインルールを緩くすることにしました。そのため、自分に無駄に厳しい労働を強いることになりました。

Dac4

AM 10:12

アナログアンプに供給する±2.5Vの電源をチャネルごとに用意したり、電源の層のスプリットプレーンを置いて、左半分は完成です。

Dac6

AM 11:04

アナログ回路が必要とする±5Vの電源を生成するDC-DCモジュールを、基板の右側に2chごとに配置しました。スイッチング電源なので気休めのLCフィルタでノイズを落とします。DCDCの後には±2.5Vを出すLDOを配置しています。

Dac7

きっと重い基板になるのでしょう。

まだ完成じゃありません。

Dac8

Dac9

AM 11:52

1.0Vを出す基準電圧回路を乗せます。

Dac10

なかなか完成しません。

PM 1:01

あとはポリゴン貼ったり、部品番号を順番になるように付けなおしたり、シルクの位置を調整したりします。

内層に通した電源がViaの壁で分断されていたりといった致命的なミスを見つけ、手直ししたりします。

これでようやく完成です。

Dac11

Dac12

PM 1:23

出図完了です。

今日は完徹してしまいました。

設計を開始してから延べ16時間くらいでできました。

生基板が到着するのは23日の木曜日です。

 

| | コメント (0)

2020.01.19

新しいDAC基板を設計します

Cosmo-Z用の拡張DACボードを設計します。

スペックは、14bit、125MHz、8chです。出力振幅は1Vppが標準ですが、OPアンプ回路の改良で5Vppくらいまで出せるようにしたいと考えています。

2:06設計開始です。

Dac1_20200123012701

4:35 8ch分の回路ができました。

Dac2_20200123012701

だいたいの形ができました。

・・・

実は、8ch分の回路はコピペしただけなので部品番号が同じです。

Dac3_20200123012701

とりあえず今日はここまで。

 

| | コメント (0)

2020.01.18

Cosmo-K-の基板を修正

特電の製品でCosmo-Kというのがあります。

Kintex-7を中心にDDR3メモリ、USB3.0、GPIO、SATA、10Gbpsの光ファイバを何個か備えたボードです。

なぜか今月に入って注文がぽぽぽぽーんと入ってきたので、生基板の在庫が切れてしまいました。

そこで、新しく生基板から作ることにしたのですが、せっかくなので基板の改版を行うことにしました。

Cosmok1

 

直したいところは「VCCAUX_IOを2.0Vにする」ということと「SFPケージの穴を大きくする」ということの2つです。

 

Kintex-7にはVCCAUX_IOという謎の電源ピンがあります。VCCAUXは通常は1.8Vですが、VCCAUX_IOはI/Oの出力バッファに割り当てられている電源のようで、DDR3メモリを最高速度でアクセスするには2.0Vにする必要があります。

Cosmok2

現在の基板がこんな状態で、ほとんどあまりのピンがない状態です。

それでも何とかVCCAUX_IOの端子を切り分けて、コンデンサを内側に1個追加し、配線を引き出すことができました。

Cosmok3

次に、光ファイバのモジュールであるSFPを収めている箱「ケージ」のピンの穴が狭かったので、これを太くしました。

使用している部品は、Anphenolの10127103-101LFとTE Connectivityの2007198-1です。

これらの部品には、たくさんの卵型の突起が生えていて、この突起を基板にはんだ付けすることで固定します。


Cage1

データシートには穴の直径は1.05mmと書かれているのですが、絶対に1.05mmの穴には入りません。

Cage2

今まではラジオペンチでこの卵型の突起をつぶして細くして基板に差し込んでいたのですが、「このデータシート、ゼッタイ変だよな~」と思いつつ、穴を限界まで太くすることにしました。

これで完成です。

Cosmok4_20200119003901

今回の修正は主にこの2か所なのですが、いままでの基板とパターンやステンシル、レジストなどに予期せぬ相違が発生していないかを念入りにチェックしなければなりません。

ガーバのDIFFっていうのがあれば便利なのですが、そういうのはなさそうなのでGCPrevieを使って念入りに見比べて、ようやく出図です。軽微な修正のはずだったのに5時間くらいかかってしまいました。

来週の木曜日には生基板が出来上がってくる予定です。

| | コメント (1)

2020.01.15

Cosmo-Zの生基板が届きました

1/10に入稿したCosmo-Zの新基板が届きました。

Np1068c3_1

Np1068c3_2

早速実装屋さんに送ります。

 

| | コメント (0)

2020.01.12

Spartan-6の起動タイミング

あるデバッグで、Spartan-6 FPGAがSPI ROMから起動するときの波形を見てみました。

Spi_config

Spartan-6は、電源電圧がある値まで立ち上がるとSPI ROMのコンフィグが開始するようです。

電源の立ち上がりに時間がかかると、完全に上がりきっていないときからコンフィグが開始してしまいます。この写真のケースではそれは問題にはなっていませんが、ちょっと気にはなります。

電源電圧がある程度まで立ち上がったら、遅延時間を待ってからPROGをL→Hにするようなリセット回路が必要ではないかと思います。

 

| | コメント (0)

2020.01.11

HSMS-282Pの代替部品

GHz帯で使えるショットキバリアダイオードで、HSMS-2xxxというのがありました。

ダイオードの接続にいろいろなバリエーションがあるので、検波回路や保護回路にいろいろと使えます。

私がCosmo-Zのアナログの保護回路に使っていたのはHSMS-282Pというもので、下の図のような接続だったのですが、このHSMSシリーズが2年ほど前からディスコンになってしまっていたのです。

Hsms

流通在庫を探すなどして何とかしのいできましたが、

このたび、Skywork Solutions Inc.という会社がSMS3923-081LFというのを出してくれました。Digikeyでも買えます!

Sms3923

性能もほぼHSMS-282Pに匹敵するもので、代替可能と判断しました。

Sms39232

 

 

 

| | コメント (0)

実装用部品の受け入れ作業

深夜に会社に来て、実装用部品の受け入れ作業を行っています。

特電ではほぼすべての部品はDigikeyで買っていますが、購入した部品に4桁の数字のラベルを貼ります。

Buhin

このラベルは自作のWebアプリで管理するためのもので、いつ、何を、何個買って、何に使って、どこに保存しているかをかかを管理するものです。

Kanri

昨年からの方針転換で「部品の在庫は極力もたない」という方針で、原則1回の実装で購入した部品は使い切る方針なのですが、どうしても残ってしまって次回にも使うという部品はあるものです。

今日届いたのはCosmo-Kの部品だったようです。

 

さて、Cosmo-Kの部品が揃ったら、次にCosmo-ZとCosmo-Z ADC拡張ボードの部品をDigikeyに発注です。

一晩で50万円分くらい買います。実装失敗したらどうなっちゃうんだろう・・

Cosmo-Zは200種類くらいの部品があるので、発注していたら朝になってしまいました。

Zynq

子供たちの朝ごはんを作って、寝ます。

 

| | コメント (0)

2020.01.07

内層クリアランス

ある基板が在庫が切れてしまったので、再生産することになりました。

以前はP〇.comで作っていたのですが、P社の内層クリアランスは0.5mm必要で、Viaが0.3mm径の場合のみ0.4mmでよいとのことでした。

製造基準書には丁寧に内層クリアランス径は1.1mmと書かれているので、下の図のようなイメージで間違っていないのでしょう。

Naisou_clear1

内層クリアランスというのはViaの端から何mm開けなければならないかということです。

そもそも、なぜこれが必要なのかというと、Viaを作るためのメッキ液が染み込むとかいう化学的な理由なのかもしれません。そのあたりは詳しくありません。

まぁいずれにせよ、1.0mmピッチという比較的端子幅の広いBGAに対しても1.1mmの内層クリアランス径となると、下の図のようにベタパターンの分離が起きてしまいます。

Beta_bundan

GNDは内挿のベタのプレーンを作って、ベタパターンで配線するのが普通ですが、内層クリアランスが大きいと分断されてしまうのです。

いままでは、島ができてしまった部分には、自分ではんだ面や他の内層ら接続したりしていたのですが、前回作っていた基板ではそれを忘れていてP社の人が気づいて向こうで修正してくれていました。

Naisou_clear3

今回の製造からは、日本の国産基板メーカーに変えることにしたのですが、製造会社に修正されたことをすっかりわすれていて、ガーバを出してから1分後に気が付き、あわてて基板キャンセルを行いました。

今回の基板メーカーに「内層クリアランスはどのくらいですか」と聞いてみたところ、0.15mmという回答でした。

つまり、図にするとこうなります。

Naisou_clear2

ホント大丈夫か?

ちょっと不安になってしまう。

特急コースなら6層基板が2日で仕上がってP社の5日コース(実働10日くらいのイメージ)より安いという。

マジ神!

内層クリアランスが少なくてもよいと言われても経験的に広く取ってきた身としてはやはり怖いので、基本的に1.1mm径のルールで作って、最小限のGND島の部分だけ狭くして通り道を作ることにします。

 

 

| | コメント (0)

2020.01.06

「Cosmo-Z」にユーザ回路を追加する方法(後編)

ZYNQ搭載高速ADCボード「Cosmo-Z」にユーザ回路を追加する方法の続きです。

フィルタの追加

FilterブロックにはADCで計測された生データが流れているので、ここに適当なフィルタを追加します。

適当なフィルタということでCICフィルタを選びました。

CICフィルタとは

CICフィルタというのは足し算とデシメーションだけでできている単純なローパスフィルタで、特性は急峻ではありませんが、構造は簡単です。

詳しいことは当ブログの過去記事

http://nahitafu.cocolog-nifty.com/nahitafu/2015/08/cosmo-z18bit-ec.html

の記事をご覧ください。

SLICEモジュールの改造

VivadoでIPコアとして使えるCICフィルタは、AXI Streamを前提としていて、生のデータは入れられないようです。

そこで、前回作ったSLICEモジュールを改造して、8chのデータが詰まった96bitのAXI Streamを、16bitのAXI Stream 8chに分解するようにしました。

元のADCデータは12bit×8chなのですが、これを12bitのAXI Stream 8本に分けたところ、VivadoがWarningを出してきました。

どうやら、AXI Streamはビット幅が8の倍数でないと正しく動作しないかもしれないそうなのです。

CICフィルタに入れるデータは2の補数表現であろうから、リニア→2の補数表現に変換しなければなりません。

せっかくなので、CH1をCH1,2,3,4にコピーして、CH2をCH5,6,7,8にコピーする機能もSliceモジュールに持たせましょう。


architecture Behavioral of cosmoz_data_slice is
ATTRIBUTE X_INTERFACE_INFO : STRING;
ATTRIBUTE X_INTERFACE_INFO of tdata_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata0_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT0 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid0_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT0 TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata1_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT1 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid1_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT1 TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata2_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT2 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid2_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT2 TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata3_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT3 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid3_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT3 TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata4_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT4 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid4_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT4 TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata5_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT5 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid5_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT5 TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata6_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT6 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid6_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT6 TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata7_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT7 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid7_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT7 TVALID";
begin
tvalid0_o <= tvalid_i;
tvalid1_o <= tvalid_i;
tvalid2_o <= tvalid_i;
tvalid3_o <= tvalid_i;
tvalid4_o <= tvalid_i;
tvalid5_o <= tvalid_i;
tvalid6_o <= tvalid_i;
tvalid7_o <= tvalid_i;
tdata0_o <= (tdata_i(ADC_BITS * (0 + 1) - 1 downto ADC_BITS * 0) - x"800") & "0000";
tdata1_o <= (tdata_i(ADC_BITS * (0 + 1) - 1 downto ADC_BITS * 0) - x"800") & "0000";
tdata2_o <= (tdata_i(ADC_BITS * (0 + 1) - 1 downto ADC_BITS * 0) - x"800") & "0000";
tdata3_o <= (tdata_i(ADC_BITS * (0 + 1) - 1 downto ADC_BITS * 0) - x"800") & "0000";
tdata4_o <= (tdata_i(ADC_BITS * (1 + 1) - 1 downto ADC_BITS * 1) - x"800") & "0000";
tdata5_o <= (tdata_i(ADC_BITS * (1 + 1) - 1 downto ADC_BITS * 1) - x"800") & "0000";
tdata6_o <= (tdata_i(ADC_BITS * (1 + 1) - 1 downto ADC_BITS * 1) - x"800") & "0000";
tdata7_o <= (tdata_i(ADC_BITS * (1 + 1) - 1 downto ADC_BITS * 1) - x"800") & "0000";

こんなふうになりました。

Combineモジュールの改良

Combineモジュールでは逆にこれらのデータを束ねます。


  ATTRIBUTE X_INTERFACE_INFO : STRING;
ATTRIBUTE X_INTERFACE_INFO of tdata_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid_o : SIGNAL is "xilinx.com:interface:axis:1.0 DOUT TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata0_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN0 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid0_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN0 TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata1_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN1 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid1_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN1 TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata2_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN2 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid2_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN2 TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata3_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN3 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid3_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN3 TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata4_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN4 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid4_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN4 TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata5_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN5 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid5_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN5 TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata6_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN6 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid6_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN6 TVALID";
ATTRIBUTE X_INTERFACE_INFO of tdata7_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN7 TDATA";
ATTRIBUTE X_INTERFACE_INFO of tvalid7_i : SIGNAL is "xilinx.com:interface:axis:1.0 DIN7 TVALID";
begin
tvalid_o <= tvalid0_i;
tdata_o(ADC_BITS * (0 + 1) - 1 downto ADC_BITS * 0) <= tdata0_i(15 downto 4) - x"800";
tdata_o(ADC_BITS * (1 + 1) - 1 downto ADC_BITS * 1) <= tdata1_i(15 downto 4) - x"800";
tdata_o(ADC_BITS * (2 + 1) - 1 downto ADC_BITS * 2) <= tdata2_i(15 downto 4) - x"800";
tdata_o(ADC_BITS * (3 + 1) - 1 downto ADC_BITS * 3) <= tdata3_i(15 downto 4) - x"800";
tdata_o(ADC_BITS * (4 + 1) - 1 downto ADC_BITS * 4) <= tdata4_i(15 downto 4) - x"800";
tdata_o(ADC_BITS * (5 + 1) - 1 downto ADC_BITS * 5) <= tdata5_i(15 downto 4) - x"800";
tdata_o(ADC_BITS * (6 + 1) - 1 downto ADC_BITS * 6) <= tdata6_i(15 downto 4) - x"800";
tdata_o(ADC_BITS * (7 + 1) - 1 downto ADC_BITS * 7) <= tdata7_i(15 downto 4) - x"800";

Block Designを配線する

SliceモジュールとCombineモジュールをRTLモジュールとして作り、間にCICフィルタを挟みます。

1_20200109041201

ADCに入ってくる信号はCH1(正弦波)とCH2(矩形波:トリガ信号)で、それを以下のような方針で8chに振り分けます。

  • ADC CH1→そのまま→CH1
  • ADC CH1→CICフィルタ(め)→CH2
  • ADC CH1→CICフィルタ(ふつう)→CH3
  • ADC CH1→CICフィルタ(きつめ)→CH4
  • ADC CH2→そのまま→CH5
  • ADC CH2→CICフィルタ(ゆるめ)→CH6
  • ADC CH2→CICフィルタ(ふつう)→CH7
  • ADC CH2→CICフィルタ(きつめ)→CH8

VivadoのIPのCICフィルタの設定は以下のとおりです。

ゆるめ フィルタ

2_20200109041201

ふつう フィルタ

3_20200109041301

きつめ フィルタ

4_20200109041301

入出力ビット幅

フィルタの設定がきつくなると力バスのビット幅も増えてきます。

同じ条件で評価したいので、いずれのフィルタも、入出力データは16bit幅でTruncationの設定にしています。

5_20200109041301

ちょっと失敗したこと

SliceとCombineをRTLモジュールにしたことが失敗でした。

なぜなら、RTLモジュールでAXI Streamを作ると、Varidateをしたときにバスの速度が自動的に推定されないようで、全部手作業で設定しなければいけないようでした。ポートをクリックして、Block Interface PropertyをつっついてCONFIGの中のFREQ_HZを全部設定しなおさなければなりません。

IPとして作れば、おそらく自動で設定されます。

RTLモジュールはIPコアと違い、ツールがラッパを作ってアトリビュートを設定することができないのでしょう。

論理合成して実行

これを論理合成して、計測を行ってみました。

結果は次の図の波形のとおり。

7_20200109041301

フィルタがきつくなるにつれ、遅延が増えていくのがわかります。

時間軸的に拡大してみると、フィルタを通したほうはすべてカクカクしています。

これはCICフィルタがデシメーションをしているためで、4回に1回しかデータを出力しないからです。

8_20200109041301

灰色の線(CH8)は矩形波の反射による鋭いヒゲを除去できているのでLPFとしての効果はありそうです。

CICフィルタの周波数特性とノイズ除去性能

LPFなので、どのくらいノイズが除去できるか気になるところです。

今回使っている正弦波の発振器は、安物なので、波形が歪んでいます。

9_20200109041301

そのため、FFTをすると結構な高調波が乗ってしまうのですが・・・

10_20200109041301

CICフィルタを通すと、

(ゆるめ)

11_20200109041301

(ふつう)

12_20200109041301

(きつめ)

13_20200109041301

全体的にノイズは減っているのでしょうが、CICフィルタ自体が緩すぎて、あまり効果は感じられません。

サンプリング周波数の1/8付近(10MHz付近)のノイズは落ちていますが、20MHz付近ではかえってノイズが増えているように見えます。

矩形波もフィルタした結果のFFT

トリガの矩形波もCICフィルタに掛けているので、そのFFTでスペクトラムを見てみます。

矩形波のスペクトラムはくし型になります。

14_20200109041301

まずは「ゆるめ」のフィルタ。fs/4の20MHzで急峻に切れています。

15_20200109041401

次は「ふつう」のフィルタ。10MHz付近の減衰が少しだけ大きくなっています。

16_20200109041401

最後は「きつめ」のフィルタ。

10MHzと30MHz付近で大きくカットできました。

17_20200109041401

元が幅が広がったスペクトラムのほうがフィルタの特性は把握しやすいですね。

きっと、10MHz、20MHz、30MHz、40MHzのすべての部分で急峻に切れているのでしょう。

まとめ

いかがでしたでしょうか。

Cosmo-ZのFilterブロックでAXI Streamをほどいて再結合させ、その間にリアルタイムな信号処理を追加することができました。

 

| | コメント (2)

2020.01.05

「Cosmo-Z」にユーザ回路を追加する方法(前編)

ZYNQ搭載の高速ADCボード「Cosmo-Z」(コスモゼット)は、FPGAをユーザがカスタマイズすることができる高速データ収集装置です。

Cosmo-Zをカスタマイズしてユーザ回路でデータを処理するやり方の例を紹介します。

1_20200109035401

ダウンロードとプロジェクトの生成

まずは「Cosmo-ZのFPGAソース公開とビルド方法」の記事を読み、ダウンロードとプロジェクトの生成を行ってください。

Vivadoのプロジェクトを起動すると、以下のようなBlockDesignが現れます。

2_20200109035401

Signal Processブロック

上の図で左下にあるSignalProcessをクリックして開きます。

SignalProcessは階層構造になっていて、様々なモジュールが中に入っています。

SignalProcessブロックでは、ADCBlock→Filter→UPP(汎用パルス処理)→TRIGGER→trigdelay(トリガディレイ)→captureという順に信号が流れていきます。

ユーザがカスタマイズできるのは、FilterとTRIGGERの2種類です。

Filterをカスタマイズすることで、

  • ADCで計測された信号をFPGAでリアルタイム処理するために取り出す
  • 独自のリアルタイム処理するフィルタを追加

することができます。

3

信号の規格

各ブロックを接続している信号はAXI Streamという標準的なバス規格ですが、バスのビット幅はADC_MAXCH × ADC_BITSでパラメタライズできるようになっています。

ADC_MAXCHはADCのチャネル数、ADC_BITSはADCのビット数で、デフォルトではADC_MAXCH=8、ADC_BITS=12となっています。

この値を変更するには、BlockDesignのトップにあるコメントを書き換え、

4

Tcl窓にNahiConfigByCommentと入力します。

5

Tclスクリプトが走り、プロジェクト内のすべてのモジュールのADC_BITSとMAX_ADCCHが一斉に書き換えられます。

それに伴い、AXI Streamのビット幅も自動的に調整されます。

Filterブロックをカスタマイズしよう

BlockDesignにあるFilterブロックを開けてみると、実は、中身は空っぽです。
6

このFilterは、BlockDesignの階層になっていて、ユーザが自分で回路を作りこむようになっています。

モジュールの追加

まず、FilterブロックをIPインテグレータで開いたら、 

7

VivadoのSourcesにある+ボタンをクリックし、

8

Add or Create Designを行います。

9

プロジェクトのsrcの中にあるdata_combine.vhdとdata_slice.vhdを追加します。

10

追加したら、BlockDesignの何もないところで右クリックし、Add moduleを行ってRTLソースを追加します。

11

 

以下のような2つのモジュールが追加されます。

12

SliceとCombine

SLICEはCosmo-Zの計測データが流れているAXI Streamを1つ1つのチャネルのデータに分解してくれるものです。

※XILINXのコアにも似たようなのはあるのですが、SLICEが12bit単位とか14bit単位とかできなさそうです。

Sliceの中身

Sliceモジュールの中身は


    tvalid_o   <= tvalid_i;
tdata0_o <= tdata_i(ADC_BITS * (0 + 1) - 1 downto ADC_BITS * 0);
tdata1_o <= tdata_i(ADC_BITS * (1 + 1) - 1 downto ADC_BITS * 1);
tdata2_o <= tdata_i(ADC_BITS * (2 + 1) - 1 downto ADC_BITS * 2);
tdata3_o <= tdata_i(ADC_BITS * (3 + 1) - 1 downto ADC_BITS * 3);
tdata4_o <= tdata_i(ADC_BITS * (4 + 1) - 1 downto ADC_BITS * 4);
tdata5_o <= tdata_i(ADC_BITS * (5 + 1) - 1 downto ADC_BITS * 5);
tdata6_o <= tdata_i(ADC_BITS * (6 + 1) - 1 downto ADC_BITS * 6);
tdata7_o <= tdata_i(ADC_BITS * (7 + 1) - 1 downto ADC_BITS * 7);

Combineモジュールの中身は


    tvalid_o   <= tvalid_i;
tdata_o(ADC_BITS * (0 + 1) - 1 downto ADC_BITS * 0) <= tdata0_i;
tdata_o(ADC_BITS * (1 + 1) - 1 downto ADC_BITS * 1) <= tdata1_i;
tdata_o(ADC_BITS * (2 + 1) - 1 downto ADC_BITS * 2) <= tdata2_i;
tdata_o(ADC_BITS * (3 + 1) - 1 downto ADC_BITS * 3) <= tdata3_i;
tdata_o(ADC_BITS * (4 + 1) - 1 downto ADC_BITS * 4) <= tdata4_i;
tdata_o(ADC_BITS * (5 + 1) - 1 downto ADC_BITS * 5) <= tdata5_i;
tdata_o(ADC_BITS * (6 + 1) - 1 downto ADC_BITS * 6) <= tdata6_i;
tdata_o(ADC_BITS * (7 + 1) - 1 downto ADC_BITS * 7) <= tdata7_i;

です。

本当に単純にばらしたりくっつけたりしているだけです。

デフォルトの直結で動作させた場合

まずは分解したデータをそのままつないで結合するデザインを作ります。

13  

いきなりですがこれを論理合成してFPGAに書き込んで動かしてみます。

論理合成の途中経過は省略します。

Cosmo-ZのCH1にはファンクションジェネレータから100kHzの正弦波を、CH2にはTTLレベルのトリガ信号を入れます。

CH3~CH8はオープンにしています。

14

Webオシロで見てみると、茶色の線(CH1)には正弦波が、赤色の線(CH2)には矩形波が映っています。

CH3~CH8には何も入力していないのでノイズが見えています。

15

CH3~CH8に、FPGA内部の配線をつなぐ

CH3~CH8はコネクタには何もつながっていないので、ノイズしか入ってきませんでした。

ノイズを見てもしようがないので、FPGAの中でCH1とCH2の信号をコピーしてつないでみましょう。

16  

結果は下の図のとおり。CH3,4,5にはCH1のコピーが、CH6,7,8にはCH2のコピーが入りました。

17

まとめ

Filterブロックの中から信号を取り出すことで、計測したままのデータをそのまま扱うことができるようになりました。

 

| | コメント (0)

2020.01.04

Trenz製品紹介サイトのよくある質問とその答えをまとめたった

特殊電子回路㈱が運営するTrenz製品販売サイトでは、購入前のボード選定に関するご質問や、購入後の使い方の質問をよくいただきます。

いつも調べてメールで返答しているのですが、そういったお問い合わせや無償サポートの内容をまとめて公開したら、今後、ご購入いただく方や今悩んでいる方たちのためになるかと思い、2年分くらいをまとめました。

こちらのページです。

https://www.trenz.jp/qanda/index.html

Qanda

納期や価格の問い合わせは省き、他の人にも有益となるようなお問い合わせだけをまとめました。

質問の内容や回答にお客様の秘密が含まれるような場合はその部分を削除し、一部加筆訂正しています。

今のところ、

という記事があります。

記事の全文は検索可能ですので、Trenz製品に興味を持ってみたらぜひとも読んで検索してみてください。

 

| | コメント (0)

2020.01.03

風水プログラミング

今日は趣向を変えて風水のプログラミングをしてみます。

オカルトな世界にもいろいろあるのですが、(玄空飛星)風水、九星気学、四柱推命は計算のアルゴリズムがしっかりと確立していて、入力が同じならば出力は同じになるという特徴を持っています。

例えば、(玄空飛星)風水ならば、竣工年と建物の向きが決まれば、結果は一意に定まります。

四柱推命ならば誕生の年月日と時間で結果は一意に決まります。

そのアルゴリズムは、ちゃんとした本を読めば書いてあります。(ドクター〇パとか李〇●竹とかを読んでも書いていません)

 

作ったプログラムの一部を示しましょう。

PHPで書いてあります。

$運星 = array(); // 
$運星["東南"] = 剰余($era + 8); //
$運星["南" ] = 剰余($era + 4); //
$運星["南西"] = 剰余($era + 6); //
$運星["東" ] = 剰余($era + 7); //
$運星["中央"] = 剰余($era + 0); //
$運星["西"] = 剰余($era + 2); //
$運星["北東"] = 剰余($era + 3); //
$運星["北"] = 剰余($era + 5); //
$運星["北西"] = 剰余($era + 1); //
switch($向) {
case "N1": case "N2": case "N3":
$中央水星 = $運星["北"];
$中央山星 = $運星["南"];
break;
case "NE1": case "NE2": case "NE3":
$中央水星 = $運星["北東"];
$中央山星 = $運星["南西"];
break;
case "E1": case "E2": case "E3":
$中央水星 = $運星["西"];
$中央山星 = $運星["東"];

とか、

	if($中央山星 == 5) {
if( (preg_match("/[23]/",$向) && !($era % 2)) // 偶数で区分2か3
|| (preg_match("/[1]/",$向) && ($era % 2))) { // 奇数で区分1
$山星順行 = true;
}
else {
$山星順行 = false;
}
}
if($中央水星 == 5) {
if( (preg_match("/[23]/",$向) && !($era % 2)) // 偶数で区分2か3
|| (preg_match("/[1]/",$向) && ($era % 2))) { // 奇数で区分1
$水星順行 = true;
}

なんだかとても怪しげなプログラムですね。

PHPは変数名に普通に漢字が使えるし、連想配列が使えるのでわかりやすく書けました。

もし、英数字しか使えないとどうやって英語に訳せばよいかわからなくて困るでしょう。

 

さて、これは何を計算するプログラムなのかというと、風水のチャートを作るプログラムなのです。

Chart

この数字がわかると、建物の部屋の吉方向や凶方向、場所の運勢や適した用途がわかります。

計算で求められるのはこの数字までで、その数字をどうやって解釈するかは風水師の経験にゆだねるところが多いのです。

このツールの良いところは、年飛星も表示できることと、北を上にして表示できること。

 

下の図は、卯山酉向(西向き)で第7運(1984~2003年)に建てられた物件のチャート。

7_w2_20200104223801

だいたいどの風水本も風水サイトも南が上で表示されているので、北が上にするというオプションも付けました。

北が上のほうがわかりやすいですよね。

| | コメント (0)

2020.01.02

Trenzサイトの本文を検索できるようにしました

Trenz製品販売日本語サイトの見えないところをリニューアルしました。

見えない部分だけど大事な仕事。

 

まず、今までTrenzサイトでは検索窓にカーソルを合わせることが困難でした。

どうやら2018年にスライダーを起動するJavascriptが追加された際に、スライダーの枠のdivが、実際の画像のサイズよりも大きいheightで定義されていて、その枠の見えない部分にバリアされて検索窓にカーソルが合わせられなかったようです。

そのため、スクロールする一瞬だけ検索ができるということになっていました。

この不具合を1年4か月くらい放置していました。いけないですね。

Search_blocked

 

せっかく検索ができるようになったので、本文を全文検索できるようにしました。

Trenz製品販売日本語サイトをはじめ、特電の作るWebページはtkcmsというCMS(コンテンツマネージメントシステム)で作られていますが、そのデータは以下のような感じでデータベースに入っています。(実際には1つのレコードには30個くらいの項目があるのですが簡単にしています。)

Contents_array

そして、過去のページ内容をいつでも復元できように、すべてのページのすべての時点のデータを全保存しています。

だから、元になるテーブルを全検索しては、すでに無効になっている記事や更新される前のデータもひっかかってしまいます。

 

このようなテーブルに対して全検索を行うには、まず、アクティブな記事のリストを作り(ここでSELECTを1回)、各記事のURLやタイトルをキーとして内容を取り出すためのSELECT文を記事の数だけforeachで回すことになります。

合計、ページ数+1回のSELECT文を回さなければならなくなり、重くなります。

 

そこで考えたのが、検索用のキャッシュテーブルを作ること。

全記事のデータの中から現在アクティブかつ最新のものを取り出し、HTMLのタグを外し、全角英数字を半角英数字に変換したテーブルを作ります。

Search_cache

そして、この検索用キャッシュテーブルに対して検索を行います。

全角半角で揺れても大丈夫になるし、1回のSELECT文で済むし、各ページの検索スコアを設定することもできるようになりました。

例えばZynqberryで検索したときの結果は以下のとおり。

Search_result

商品情報だけではなく、記事全文からテキスト検索できるようになりました。

 

| | コメント (0)

2020.01.01

あけましておめでとうございます

あけましておめでとうございます!

今年もよろしくお願いします。

 

今年の抱負は、「Facebookをがんばる」「レスポンシブデザインをがんばる」にしたいと思います。

かなえられない高い目標よりも、まずは現実的な目標を。。

 

さて、

HyperFDACとか、Cosmo-K DVIとか、JTAGチャレンジ基板とか、一昨年までにやっていて完成させていなかった製品を、やっぱり完成させたいですね。

 

それから、Web版MITOUJTAGの開発も再開したいと思っています。

Web版MITOUJTAGは、Webブラウザ経由でJTAGが使えるというクラウドアプリで、サーバ上でJTAGの複雑な処理をするというものなのですが、今までに2回作りました。

1回目は「MITOUJTAG Air」の名前で出したのですが、ソースコードがぐちゃぐちゃになって失敗。2回目はMITOUJTAGオンラインの名前で出して、ユーザ間のコミュニケーションができるようにしたもので、キャラクタが出てきてオンラインゲーム風でした。やはりソースコードがぐちゃぐちゃになったのと、ブラウザからUSB-JTAGにアクセスするためにActiveXを使っていたことで崩壊。

3度目を今年はやりたい。FPGAのデバッグではなく、CPUのデバッグにも広げたい。その方策は考えてある。

 

手を付けていて完成していなかったものをすべて片づけて、それから組み込みとかIoTとかFPGAではない、次の世界にいきたい。

それが今年の目標です。

| | コメント (0)

« 2019年12月 | トップページ | 2020年2月 »