2017.01.22

Cosmo-KのDDR3メモリの配線を改良した

Kintex-7搭載のPCI Expressボード「Cosmo-K」のDDR3メモリの配線を修正しています。

Cosmokddr3

ぐちゃーっとした配線で何が何だかわからないと思います。

そこで、TOP層、内層1、内層2だけを表示させてみます。

今までの配線は、こうなっていました。

Old

データ線やDM、DQSなどは1対1でFPGAとDDR3が接続されているのですが、アドレス線やCAS、RASなどの制御線がT型に分岐しているのです。

DDR3の配線は等長配線のT型にするか、数珠つなぎ型にするかという選択肢はあるのですが、この基板ではT型に分岐した下側のDDR3メモリにだけ終端抵抗が付いているという間違った設計になっていました。

そのため、DDR3メモリを800MHzで動かしているうちはよかったのですが、1600MHzで動かそうとすると、2個あるDDR3メモリのうち、下側のほうだけしか動かないという現象に見舞われました。(実際には1000MHzくらいで限界になる)

高速オシロで見ると、確かにSSTL-15の信号レベルが暴れていました。

sun

そういうわけで、この配線を全面的に見直して、数珠つなぎ型の一直線の配線になるようにして、最後の部分で終端をするように変えました。

New


FPGAから出た配線が全体的に上から下へ流れていくのがわかると思います。アドレス・制御線の信号長の差も1cm以内に収まりました。

これで1600MHzアクセスができるといいのですが、どうなるでしょう。

| | コメント (0)

2017.01.21

GR-PEACHのJTAGを使ってみた

あるお客様からRZ/A1HのR7S721000VCBGというCPUでJTAGバウンダリスキャンができないか、というお問い合わせをいただいたので、試してみることにしました。

RZというのはARMのコアが乗ったルネサスのCPUで、R7S721000の評価ボードというと、GR-PEACHというのが出てきました。GR・・!?

秋月で売っているようなので、買ってみました。

Grp_1

そして、回路図を見ながらJTAGの配線を引き出します。

JTAGの信号は、下のようにCN2に出ているのですが、この回路図上のCN2のピン配置は基板を裏から見た順序になっているので注意が必要です。

Jtag_circuit_2

基板の表面から見たピン配置は下の図のようになります。

TRST ● GND
TDI  ○● GND
TDO 
● GND
TCK 
● GND
TMS 
 VCC(3.3V)

さて、ルネサスのR*系のCPUのJTAG機能はバウンダリスキャンとICE(エミュレータ)が共用されています。BSCANPという端子があって、BSCANPがLのときにはICEになって、BSCANPがHの場合にバウンダリスキャンになります。

GR-PEACHの回路図を見ると、BSCANPは22kΩの抵抗でGNDに接続されています。

Bscanp

プルダウン抵抗があってよかった。

このプルダウン抵抗がなくてBSCANPがGNDに直結されてしまっていたりすると、何もできないので、本当にこの抵抗があってよかったです。

ただ、R108がどこにあるかを探すのが大変です。この基板にはシルクがないだけでなく、仕様書に記載されている部品番号は文字が潰れて読めないからです。

R108とBSCANPの信号は、ここにありました。

R108

このBSCANPも含めて配線を引き出しました。

Grpeach_jtag

そして、MITOUJTAG(今回はLight)を起動して、自動認識させます。

おおっ! ARMのCortex-A9か何かが認識されました。このRZも例外ではなく、BSCANPがLの場合にはARMのCortex-A9として認識されてしまいます。

Detect_arm

次に、BSCANPをHにして、リセットをかけてから再度認識させてみます。

すると、何か不明なデバイスが認識されました。IDCODEを見てみると、08178447となっています。

Detect_unknown

これがRZなのですが、MITOUJTAGのデフォルトのデータベースには登録されていないようです。

そこで、ルネサスのWebサイトからRZのBSDLファイルをダウンロードします。

ダウンロードしたBSDLファイルをドラッグアンドドロップでMITOUJTAGの画面に落とします。

Dnd

すると、このBSDLファイルが登録されて、端子の形が表示されます。

Detected1

BSDLファイルの登録は最初の1回だけ行えばよく、二回目からは自動認識できるようになります。

Detect_rz

そうしたら、端子の可視化も自由自在です。

Sample_2

Detected

デフォルトで動いているLEDチカチカ(7色のグラデーション)をさせているときの、LEDの端子の様子を波形で見てみました。

途中、何度かリセットスイッチを押していますが、リセット中にはLEDの端子が入力状態に切り替わっているのも見えます。

Grpeach_logana_2

sun

端子を見るだけではつまらないので、EXTESTをしてみましょう。

Extest_3
メニューバーの「端子操作」ボタンを押します。

すると、CPUの動作が停止するので、

例えば、H2を押して、ポップアップが出たら「自動トグル出力」を選びます。


Toggle

すると、H2端子から自動的にHLHLHL・・・のパルスが出るので、LEDがチカチカ光ります。

これはプログラムを書きこんで操作しているのではなく、端子の状態だけをJTAGバウンダリスキャンで操作しています。なので、JTAG-ICEとは根本的に動作原理が異なります。

sun

GR-PEACHを使っていて気になったのは、JTAGのTRST信号がデフォルトではコネクタに出ていないことです。TRSTはR29の抵抗を介して端子に出ているのですが、回路図を見るとシステムのリセット(nRZRST)にもつながっています。TRSTはJTAGのリセットなので、本来ならばシステムのリセットと一緒にすべきではありません。TRSTとRESは分けるのが正解です。

Trst


このR29はどこにあるか探したら、はここにありました。

R29

私はこれをジャンパしましたが、TRSTとシステムのリセットがつながってしまうので、つなぐべきかどうかは一概には言えません。これだとリセット時の動作の振る舞いのデバッグができなくなります。

| | コメント (0)

2017.01.14

ZYNQに接続したRTCが動いた!

Cosmo-Zの新バージョンはRTCを搭載しています。

ZYNQからI2C経由でRTC(Microchip MCP79411)を操作することができました。その手順を示します。

まず、EDK(最近の人はVivadoですね)で、PSの設定を開き、I2Cの0番を有効にします。

Zynq_i2c_1

そして、Export Hardware SDKを行い、fsblを再生成し、boot.binを再生成します。

新しいboot.binで起動したら何かキーを押してブートを止め、u-bootのコンソールに入ります。

u-bootにはi2cという便利なコマンドがあります。i2c probeと打つと、I2Cのバスに様々なアドレス(1,3,5,7,9,11,13…)を順番に出力して、どんなデバイスがつながっているかを調べてくれます。

Zynq_i2c_2

上の画面はi2c probeを行ったときの表示で、57と6Fのデバイスが見つかっています。57がMCP79411内のEEPROMで、6FがMCP79411内のRTCとSRAMです。

i2cコマンドを通じたメモリの読み書きは、以下のコマンドで行えます。

メモリリード:i2c md デバイスアドレス サブアドレス 長さ
メモリライト:i2c mw デバイスアドレス サブアドレス 値

これでひととおりMCP79411の動作が確かめられたら、Linuxで使えるようにしたいのですが、そのためにはデバイスツリーというのを書かなければなりません。

デバイスツリーの正しい書き方はよくわかりませんが、

ps7-i2c@e0004000 {
    compatible = "cdns,i2c-r1p10";
    status = "okay";
    clocks = <0x2 0x26>;
    interrupt-parent = <0x3>;
    interrupts = <0x0 0x19 0x4>;
    reg = <0xe0004000 0x1000>;
    #address-cells = <0x1>;
    #size-cells = <0x0>;
    clock-frequency = <0x9c40>;

という記述を追加しました。clocksなどの設定の意味はよくわかりませんが、これでうまくいきました。clock-frequencyは40kHzにしています。ZYNQではI2C_0のレジスタは0xe0004000にあるようで、これはデザインによらず固定です。

これでLinuxを起動すると、(dmesgの部分に)

cdns-i2c e0004000.ps7-i2c: 40 kHz mmio e0004000 irq 57

と表示されます。

そして、/dev/i2c-0というデバイスが出来ています。

Zynq_i2c_3_2

i2c-0というのは、ZYNQのI2C_0に相当します。これは汎用のI2Cデバイスのマスタなので、ユーザがプログラムを組めば自由に操作できます。

このデバイスを使うには、まず

#include <sys/ioctl.h>
#include <linux/i2c-dev.h> 

をincludeし、open("/dev/i2c-0",O_RDWR)でオープンします。

int i2c = open("/dev/i2c-0",O_RDWR);
if(i2c < 0) {
  printf("I2C Open error");
  return -1;
}

デバイスのスレーブアドレスを指定するには、

ioctl(i2c, I2C_SLAVE, 0x6f); 

とします。そうしたら、read()やwrite()を使って読み書きします。

char val = 0x00;
char data[32];
write(i2c, &val, 1);
read(i2c, &data, 32); 

とすれば、サブアドレス0から、32バイトのデータが読み出されます。

実際に作ったプログラムを載せます。

#include <stdio.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
int main() {
    int i2c = open("/dev/i2c-0",O_RDWR);
    if(i2c >= 0) {
        unsigned char dat[256];
        unsigned char addr;
        ioctl(i2c, I2C_SLAVE, 0x6f);
        printf("RTC\n");
        addr = 0x0;
        write(i2c, &addr, 1);
        read(i2c, &dat, 32);
        for(i=0;i<32;i++) {
            if((i & 15) == 0) printf("%04X ",i);
            printf("%02x ",dat[i]);
            if((i & 15) == 15) printf("\n");
        }
        printf("\n");
   
        printf("SRAM\n");
        addr = 0x20;
        write(i2c, &addr, 1);
        read(i2c, &dat, 64);
        for(i=0;i<64;i++) {
            if((i & 15) == 0) printf("%04X ",i+0x20);
            printf("%02x ",dat[i]);
            if((i & 15) == 15) printf("\n");
        }
        printf("\n");
   
        printf("EEPROM\n");
        addr = 0x00;
        ioctl(i2c, I2C_SLAVE, 0x57);
        write(i2c, &addr, 1);
        read(i2c, &dat, 128);
        for(i=0;i<128;i++) {
            if((i & 15) == 0) printf("%04X ",i);
            printf("%02x ",dat[i]);
            if((i & 15) == 15) printf("\n");
        }
        printf("\n");
   
        printf("Unique ID\n");
        addr = 0xf0;
        ioctl(i2c, I2C_SLAVE, 0x57);
        write(i2c, &addr, 1);
        read(i2c, &dat, 8);
        for(i=0;i<8;i++) {
            if((i & 15) == 0) printf("%04X ",i);
            printf("%02x ",dat[i]);
            if((i & 15) == 15) printf("\n");
        }
        printf("\n");
    }
    else {
        printf("no i2c\n");
    }
    return 0;
}

これで実行すると、

Zynq_i2c_4


これでMCP79411のすべてのレジスタが表示されています。
(最後のUnique IDの部分はMACアドレスに使われる部分なので、モザイクをかけています。)

ICの購入時点ではRTCは止まっています。RTCをスタートするには、アドレス0にbit7(STビット)に'1'を書き込みます。また、初期状態ではVBATの端子にバックアップ電源をつないでいても、電源OFFで消えてしまいます。VBATを使えるようにするには、アドレス3のbit3(VBATENビット)を'1'にします。

RTCの複数のバイトに書き込むには、

dat[0] = 0;    // アドレス0から
dat[1] = 0x80; // スタート 0秒
dat[2] = 0x18; // 18分
dat[3] = 0x15; // 15時
dat[4] = 0x08; // VBATEN 曜日は無視 
dat[5] = 0x14; // 14日
dat[6] = 0x01; // 1月
dat[7] = 0x17; // 2017年
dat[8] = 0x80;
write(i2c, &dat, 9); // 8バイト書き込み

のようにすればよいようです。

sun

今回使っているのはMCP79411ですが、MCP79410とMCP79412でも同じようにできると思います。

本当は、デバイスドライバを作ってデバイスツリーに組み込むか、どこかからMPC7941x用のデバイスドライバを探してくれば、OS起動時に自動的に時刻をセットしたりもできるのだとは思いますが、ユーザモードアプリでいいんじゃないかという気になってきました。

| | コメント (0)

2017.01.13

Cosmo-Zの新バージョンが出来上がってきた

Cosmo-Zの新しいバージョンの実装があがってきました。

Cosmozc

今回は7台製造しました。

お客様によって、LEMOコネクタだったり、アナログフロントエンドの特性が異なっていたりするので、7台ともすべて異なる構成です。

今回の基板の改版点は、

  • ZYNQからI2Cを出し、RTCを実装した
  • RTCと一緒にMACアドレス用にIDを搭載
  • 拡張コネクタに3本の汎用I/O信号を追加
  • GPS用のコネクタを搭載
  • 電源の強化と、12Vを入れても壊れないようにした

などです。

まず、第一の改良点ですが、基板裏のこの部分。

Cosmozrtc

ここに、RTC用のIC(Microchip MCP79411)とバックアップ用の電気二重層コンデンサを実装しました。

バックアップといったらバッテリではないの?と思うかもしれませんが、バッテリが入っていると航空機に乗せるのが面倒になったりするので、輸出とかで困ることになるかもしれません。

そこで、バックアップは電気二重層コンデンサにしました。この大きさでも70mFあるので、27時間程度のバックアップはできるのではないかと思います。

さて、MCP79411というRTCのチップは、なかなか面白いICです。内部に1024bitのEEPROMと、64byteのSRAM、それから48bitのUnique IDを持っています。

Unique IDというのはMACアドレスに使えるIDのようで、調べてみると確かにMicrochip社のMac IDのベンダコードになっていました。これでCosmo-Zも正式なMACアドレスが与えられるようになりました。

sun

また、基板表面の拡張コネクタの部分にシルクを入れ、何番のポートかわかるようにしたのと、拡張コネクタの上のほうにGPS用の6ピンのコネクタを設けました。

Cosmozctop


1mmピッチのピンヘッダ端子に、「GND、1.8V、TX、RX、1PPS、3.3V」の順に端子が並んでいます。ここにGPSモジュールをつなぐのですが、ZYNQのI/O電圧を1.8Vにしているので、1.8V対応のGPSでなければなりません。候補として、LYNX TECHNOLOGIES社の「RXM-GPS-F4-T」が挙げれます。Digikeyでモジュールを購入して、試してみようと思います。

また、右側にある電源部はTIのTPS54620RGYRというICに置き換えました。いままではTPS62065を使っていたのですが、TPS62065は2Aまでしか出せないのと、12Vを加えたときに壊れるという問題がありました。

思い起こせば、ET2015の当日。先に会場に着いたアルバイトさんがCosmo-Zをセットアップしてくれたのですが、ちゃんと説明しておかなかったため、12VのACアダプタをつないでしまいました。このときの教訓から、12V耐性のない機械は危険だということを思い知りました。

また、最近、Cosmo-ZのFPGAが進化した結果、消費電流が増えて電源が足りなくなって落ちてしまうということが発生していました。そのため、4Aの電源モジュールを別途搭載して出荷していたのですが、TPS54620RGYRと表面実装インダクタ「CDRH8D28NP-3R3NC」のおかげでオンボードで4A電源を乗せることができました。

そういうわけで、この電源回路にはかなり思い入れがあります。

これから動作テストをして、出荷開始です。

| | コメント (0)

2017.01.12

JESD204Bのはじめてのデータ受信

昨年11月に作ったJESD204B出力のADCボードと、データ取り込み用ボードで、ようやくデータが受信できるようになりました。

使用しているADCは、TI社のADS54J60です。

2つのボードをこのように40Gbの光ファイバでつなぎます。

Jesd204b

2つのボードの間は10Gbpsのリンク(現在は半分の5Gbpsで運用)が4本でつながっています。ADCのSYNCという端子をLにすると、K28.5のCOMが送られてきます。

K28.5は16進数で1BCなので、最初は4つのチャネルにBCBCBCBCというデータが来ます。

SYNCをHにすると、COM以外の何かが送られてきます。

K28.5 キタ━━━(゚∀゚).━━━!!!

Jesd204b_1_2

K28.5以外のものが来るパターンが上の波形には2回見えていて、最初のは

GTX0  1BC 11C 00 F0 E5 FF FE 00・・
GTX1  1BC 11C 05 FF FF 00 04 00・・
GTX2  1BC 11C 10 FF FA 00 04 FF・・
GTX3  1BC 11C F5 00 0A FF F5 FF・・

と読めます。1BCはK28.5で/K/という記号で表します。11CはK28.0で/R/という記号で表します。/R/は「マルチフレーム先頭文字」の意味だそうです。

2回目のK符号は

GTX0  17C 11C 19C 00 00 01 1C 1C・・
GTX1  17C 11C 19C 00 00 00 03 03・・
GTX2  17C 11C 19C 00 00 03 03 03・・
GTX3  17C 11C 19C 00 00 02 00 00・・

と読めます。17CはK28.3で/A/で、「レーンアラインメント文字」だそうです。19Cは/Q/の「リンクコンフィグ先頭文字」だそうです。なので、/A/ /R/ /Q/ ・・・

その続きの波形を見てみると、

Jesd204b_2

1個目が

GTX0  17C 11C E3 FF FE FF FF 00
GTX1  17C 11C FD 00 02 FF FC 00
GTX2  17C 11C 00 FF FF 00 FF 00
GTX3  17C 11C ED FF F8 FF F5 FF

と読めます。/A/ /R/ ・・です。

2個目は

GTX0  17C 11C 00 00 01 FF FB 00
GTX1  17C 11C FD 00 00 00 FA 00
GTX2  17C 11C 10 FF FA 00 00 FF
GTX3  17C 11C F1 FF FE FF F9 00

これもまた/A/ /R/ ・・です。

3個目は

GTX0  17C 00 02 00 15 FF FE FF
GTX1  17C 00 01 00 08 FF FD FF
GTX2  17C 00 0F FF F7 00 06 FF
GTX3  17C FF F5 00 09 00 01 FF

で、/A/です。

このような感じで、SYNCをONにしたときに5回のK符号のフレームが来るのですが、トラ技2016年9月号を読んで、意味がわかりました。

最初の/R/から/A/までが1セット目のフレームでILAS(Initial Lane Alignment Sequence)というそうです。

/R//Q/・・・/A/が2つ目のセットでマルチフレーム。この中にはコンフィギュレーションコードというのが入っています。

3個目、4個目は/R/・・/A/で、マルチフレーム1と同じ内容でデータに意味はないということでした。

大事なのは/R/ /Q/の続きの14オクテットで、ここにコンフィギュレーションレジスタという情報が書かれているそうです。本当かいな。

GTX0 00 00 01 1C 1C 16 01 12 CF DC 00 00 00 CD
GTX1 00 00 00 03 03 09 01 0D 2F 23 00 00 00 31
GTX2 00 00 03 03 03 09 01 0D 2F 23 00 00 00 34
GTX3 00 00 02 03 03 09 01 0D 2F 23 00 00 00 03

解読した値を書いていてい気が付いたのですが、おそらくGTX0のチャネルはRXPとRXNが反転していますね。GTX1~GTX3は同じような感じのデータなので、そちらはたぶん正解なのでしょう。

解読すると、

L=3、F=3、K=9、M=1、N=13、SUBCLASSV=1、N'=15、JESDV=1、S=3、HD=0、CF=0、RES1=0、RES2=0、FCHK=xx

となりました。

+1する補正を考慮すると、

L=4、F=4、K=10、M=2、N=14、SUBCLASSV=1、N'=16、JESDV=1、S=3、HD=0、CF=0、RES1=0、RES2=0、FCHK=xx

読める、読めるぞ・・

解読したところ

  • L:4 リンク数は4
  • M:2 デバイスには2つのコンバータ
  • F:4 1フレームあたり4オクテット
  • S:4 コンバータあたりフレームあたりのサンプル数
  • K:10 1マルチフレームあたり10フレーム
  • N:14bitでサンプリング
  • N':1サンプルあたり16bit
  • JESD204B

となりました。ADCの分解能が14bitというのが納得いきませんが、概ね良い感じだと思います。

| | コメント (0)

2017.01.11

JESD204B 1G ADCの動作確認

昨年から開発を続けているJESD204B対応の1Gs/s ADC「HyperFADC」ですが、高速シリアルのデータをデコードしようと頑張っています。使用しているADCのADS54J60にはSYNCという端子があるのですが、これをLにすると、1BC 1BC 1BC 1BC、つまりK28.5のCOMが送られてきます。

Cosmokp_jesd204_adc_2lane_5gbps

SYNCをHにすると、K28.5ではなく、D0.0に変わったかと思ったのですが・・

Cosmokp_jesd204_adc_2lane_5gbps_3

rxnotintableという信号が立ちあがっているので、D0.0が送られてきているわけでもなさそうです。

いまいち使い方がよくわかりません。


| | コメント (0)

2017.01.10

MITOUJTAG Lightの販売が間もなく終了となります

特殊電子回路では、FPGAを使うハイレベルな個人エンジニア向けに、JTAGツールMITOUJTAG Lightを提供しています。

2016年12月末から限定30個で販売しておりましたが、ご好評により、在庫があとわずかとなってきました。

Mjl_zaiko


「12月中は49,800円の特別価格」と申し上げておりましたが、やはり1月に入っても同じ特別価格49,800円で提供しております。

1月から価格を変えるというのは、やはり会計上大変なので・・!

MITOUJTAG Lightを使うと、いままで苦しかったFPGAやCPUのハードウェア・デバッグがとても楽になります。

今までオシロやChip●copeで頑張ってデバッグをされていた方からは、「なんでいままでこんなことで苦労していたんだろう・・」という声が良く聞かれます。それほど強力なデバッグツールです。

JTAGバウンダリスキャンでデバッグを楽にして、FPGAの中身にエネルギーをつぎ込みたいという方は、ぜひお使いください。MITOUJTAG Lightをお持ちの方は、MITOUJTAG BASICへの優待バージョンアップもできます。

個人向けのMITOUJTAG Lightは在庫限りで販売終了となりますので、どうぞお早目に。

↓ご注文はこちら

https://shop.tokudenkairo.co.jp/shopping/detail.php?shpdi=MJLIGHT

◆PR◆

今年も基板チョコを作ります。

基板チョコというのは、下の写真(2012年のもの)のようなホワイトチョコレートに食用インクで印刷したものです。

Kibanchoco3

今年の絵柄はまだ未定ですが、2月中旬にはお得意様各位に発送したいと思います。

もちろん、1月以降にMITOUJTAG Lightをお買い上げいただいた方には、もれなく基板チョコを差し上げます。

| | コメント (0)

2017.01.08

Kintex-7のPCI Expressのバーストライト

Kintex-7のPCI Expressでバーストライトをさせて、その速度を見てみました。

使ったのは、Cosmo-K+というボード。

1478579823_cosmok

PCI Express Gen2でx4という構成です。理論的には2GByte/sec出るはずです。

しかし、実際にやってみると514MBくらいしか出ません。

Cmbwr512mb

原因の1つは、デバイスドライバの問題で、ユーザ空間とカーネル空間を行き来するときにバッファの内容がコピーされるのですが、そのコピーの時間が無駄にかかっているためです。

もう一つの理由は、WriteCombinedで書き込んでいるのですが、AXIから読み出すときに、m_axis_tx_ready_intという信号がパタパタと遷移していて、1つのデータの読み出しに2クロックかかっているためです。

Wr64png

Gen1 x1のときには250MB/secしか出ないので、XILINXのCore Gen IPが作るユーザ側インタフェースは64bit 62.5MHz(最低速度)でも十分に間に合いました。

最低速度の半分のレートしか出ないので、AXバスをパタパタさせてもオーバーヘッドはなかったのですが、Gen2 x8だと64bit 250MHzになるので、もはやReadyをパタパタさせてはなりません。

Gen1のx1では、WriteCombinedで200MBくらい出るので、DMAよりも手軽で速く、速度的にも満足だったのですが、Gen2x4ではそうはいかなくなってきました。

毎クロックできびきび動作するよう、ステートマシンの作り直しが必要なのと、バッファのコピーを避けるためドライバがユーザ空間のメモリ領域のアドレスを見つけて、直接DMAする必要なのでしょう。

| | コメント (0)

«LinuxでのCombined Write