« 2016年12月 | トップページ | 2017年2月 »

2017.01.26

VHDLのgenericとconstantとfunction

VHDLでgenericのパラメータを使うことはよくあると思いますが、与えられたパラメータを加工してバスのビット幅にしたりする際に、条件判断が必要な式が必要になることがあります。

例えば、ADコンバータのAD9633(12bit)、AD9253(14bit)、AD9653(16bit)を使い分けるようなデザインを作りたい場合です。

データ出力のビット幅は、genericを使って、

entity adcblock is
    Generic ( ADC_BITS : integer range 0 to 16 := 12);
    Port ( adc_data_o : std_logic_vector(ADC_BITS-1 downto 0);
        ・・・・

と、可変長にできます。

もちろん、信号の宣言のところでは

signal adc_data : std_logic_vector(ADC_BITS-1 downto 0);

と、Genericで与えられたADC_BITSは自由に使えます。

問題は、このパラメータを、加減乗除だけではなく複雑な演算に使ったりしたい場合です。

AD9633などのADCはシリアルでデータを送ってくるので、ISERDESを使ってパラレルに変換しなければなりません。AD9633は6bitのシリアル2本で、AD9653は8bitのシリアル2本でデータを送ってきます。しかし、困ったことにAD9253は14bitのデータに"00"を詰めて8bit 2本に拡張して送ってきます。

ISERDESのビット幅は6,8,8なので、ADC_BITS/2とするわけにもいきません。

こんなときには、functionを使います。

VHDLのfunctionの文法はなかなか覚えにくいので、ここに例を書いておきます。

architecture Behavioral of adcblock is
    function GET_SERDEC_WIDTH (BITS : in integer ) return integer is 
    variable temp : integer range 0 to 16;
begin
    temp := 12;
    if(BITS = 12) then temp := 12; end if;
    if(BITS = 14) then temp := 16; end if;
    if(BITS = 16) then temp := 16; end if;
    return temp;	
end GET_SERDEC_WIDTH;
constant SERDEC_WIDTH : integer range 0 to 18 := GET_SERDEC_WIDTH(ADC_BITS);

つまり、SERDEC_WIDTHという変数を作りたいのですが、この変数をGET_SERDEC_WIDTHというfunctionで計算しているわけです。

functionはbeginの前、つまり、定数やsignalを定義する場所でも使えますので、こういう使い方ができます。

他に、ISERDESのためのクロック倍率を作るところでは、

function GET_MULT (BITS : in integer ) return real is 
    variable temp : real range 0.0 to 16.0;
begin
    temp := 6.0;
    if(ADC_BITS = 14) then temp := 8.0; end if;
    if(ADC_BITS = 16) then temp := 8.0; end if;
    return temp;
end GET_MULT;
constant BAIRITSU : real range 0.0 to 16.0 := GET_MULT(ADC_BITS);

としています。こうしてintegerからrealを作って、

mmcm_adv_inst : MMCME2_ADV
generic map
(BANDWIDTH            => "OPTIMIZED",
  CLKOUT4_CASCADE      => FALSE,
  COMPENSATION         => "ZHOLD",
  STARTUP_WAIT         => FALSE,
  DIVCLK_DIVIDE        => 1,
  CLKFBOUT_MULT_F      => BAIRITSU,
  CLKFBOUT_PHASE       => 0.000,
  CLKFBOUT_USE_FINE_PS => FALSE,
  CLKOUT0_DIVIDE_F     => BAIRITSU,
  CLKOUT0_PHASE        => 0.000,
  CLKOUT0_DUTY_CYCLE   => 0.500,
  CLKOUT0_USE_FINE_PS  => FALSE,
  CLKOUT1_DIVIDE       => 1,
  CLKOUT1_PHASE        => 0.000,
  CLKOUT1_DUTY_CYCLE   => 0.500,
  CLKOUT1_USE_FINE_PS  => FALSE,
  CLKIN1_PERIOD        => 10.000,
  REF_JITTER1          => 0.010)
port map
・・・

このようにして使っています。

※VHDLでのrealは必ず小数点を付けなければならないようで、0.0のように書きます。

実際に、Cosmo-Zでやってみました。

AD9633(12bit)のADCのときのヒストグラム(AD変換結果のばらつき)は、

Csz12bit_hist

このように1LSB程度です。12bitの変換値は、ピタッと止まっていると言えます。

緑のところが太いのはアナログフロントエンドの違いです。

AD9253(14bit)にすると、若干、広がりがでてきます。

Csz14bit_hist

拡大すると、

Csz14bit_hist_mag

ADCの分解能が4倍になったので、3LSBくらいの広がりが出ても不思議ではありません。事実、高速・高分解能ADCの変換値は常に揺れ動いています。

| | コメント (0)

2017.01.25

Cosmo-Zのデータ形式

Cosmo-Zで保存した計測データがファイル形式なのか、と問い合わせをいただくことがあります。

基本的には、こういう波形が入ったときに、Event_wave

Event_struct

パケットにしてヘッダを付けて、それを複数個束ねてファイルに保存しているのですが、しっかりと文章に書いて、Webサイトに掲載しました。

こちらをご覧ください。

http://www.tokudenkairo.co.jp/cosmoz/fileformat.html

Windowsで動くデコードソフトもダウンロードできます。

| | コメント (0)

2017.01.24

Cosmo-ZのVivadoデザイン

昨年の9月27日にCosmo-ZのデザインをVivado 2016.2用に作ったものがあったのですが、Vivado 2016.3に移行しようと思っていたら「IPを全部作り直さなければならない」という噂を聞いて躊躇していました。

そしたらあっという間にVivado 2016.4が出て、完全に取り残されてしまいました。

今週、優秀なアルバイトさんが、Cosmo-ZのVivadoデザインを2016.4に対応してくれました。どうやら、メモリとかクロックジェネレータに至るまで、IPは全部作り直したそうです。

Cosmozvivado

さて、2016.2から2016.4に移行した際、リソース使用量が変わっていないかどうか気になります。

下の図は、Vivado2016.2で合成したときのものです。

Utilization_2016_2

出ているCritical Warningは、CoreGen FIFOのバグによるものです。(クロックがないというやつ)

次の図は、Vivado 2016.4によるものです。

Utilization_2016_4

リソースの使用率は全く変わっていません。

Critical Warningは同じくCoreGen FIFOが出しています。

| | コメント (0)

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の信号レベルが暴れていました。

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

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

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

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

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

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


Toggle

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

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

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

Trst


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

R29

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

| | コメント (1)

2017.01.20

Cosmo-Z Type Cの出荷開始

Cosmo-Z Type Cの出荷を開始しました。

Cosmozc

Cosmo-Z Type Cの特長としては、

  • RTC(リアルタイムクロック)搭載
  • GPS用コネクタを増設
  • メザニン拡張コネクタへの配線が3本増えている
  • 電源を強化
  • 12Vの電源を加えても大丈夫(なはず。テストはしていない)
  • リセットスイッチを少し下にずらし、ネジ穴と干渉しないようにした

などです。

この新しいCosmo-Zが、皆様の実験やご研究の役に立つことを願っています。

| | コメント (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バイト書き込み

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

今回使っているのは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アドレスが与えられるようになりました。

また、基板表面の拡張コネクタの部分にシルクを入れ、何番のポートかわかるようにしたのと、拡張コネクタの上のほうに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)

2017.01.07

LinuxでのCombined Write

PCI Expressにおけるメモリ書き込みは、Combined Writeを使うと高速に行えます。

Write Combinedを使わないと、PCI Expressは長さ1(4ワード)のトランザクションを発行してしまうので、極めて遅くなります。

Combined Writeというのは、CPUの書き込み機構をうまく利用した方法で、複数のメモリ書き込みを1つに結合して長いパケットにして発行するやり方です。

LinuxでCombined Writeを使う方法はよくわからないのですが、デバイスドライバの中でBARの物理アドレスを仮想アドレスにマップするときに、

ioremap_wc(BARx_BaseAddr,BARx_Length);

という関数を使うと良いようです。

ioremap(BARx_BaseAddr,BARx_Length);

ioremap_nocache(BARx_BaseAddr,BARx_Length);

という関数を使うと通常のWriteとなってしまうようなのですが、正直なところよくわかりません。うまく切り替わってくれないことが多々あります。

では、実際に波形をみてみましょう。MITOUJTAGのロジアナ機能を使って、PCI Expressの書き込みトランザクションを見てみます。

書き込みは、

memcpy_toio(Mapped_BAR1_BaseAddr , WriteBuffer , count);

を使いました。

まずは、普通のWriteの場合です。128バイトのデータ転送を行ってみたところ、32回のトランザクションが発生して、5.45μ秒かかっています。したがって、転送速度は23MB/secとなります。

Single_write

拡大してみると、先頭のワードが40000001なので、1ワードの書き込みトランザクションになっていることがわかります。これでは遅いですね。

Single_write2



次は、Combined Writeにした場合の波形です。先頭のワードが40000010なので64バイトの書き込みトランザクションが2回になっています。128バイトを752nsで書き込んでいるので、速度は170MB/sとなります。

Wc

圧倒的に速くなりました。

切り替えは、ioremapを使うか、ioremap_wcを使うかといった違いだけなのですが、どうやらLinuxの起動時にはWriteCombiedを使うようになっていて、関数を変えるだけでは切り替わらないようです。

rescanを行う際に、

sudo chmod 666 /sys/bus/pci/devices/0000\:04\:00.0/rescan
sudo echo 1 > /sys/bus/pci/devices/0000\:04\:00.0/rescan

のように、バスの中までrescanをすると、この機能が切り替わるようなのですが、切り替わらないときもあります。

何がトリガーとなって、ioremapとioremap_wcが切り替わるのかは、正直、よくわかりません。OSごと再起動すると切り替わることが多いように見えます。

| | コメント (0)

2017.01.06

PCI ExpressのFPGAを効率的に開発する方法(Linux版)

PCI ExpressをFPGAで実装すると、新しいデザインが出来たら当然、書き換えることになります。

FPGAを書き換えると内部のレジスタがすべて0にクリアされてしまいます。BARなどの設定値が全部消えてしまうので、アクセスできなくなってしまいます。

普通はFPGAを書き換えるたびにOSを再起動しなければなりません。再起動を待つ時間がもったいないだけでなく、アプリの起動やディレクトリの移動など面倒な手間が増えます。

PCI ExpressのFPGAを書き換えても、OSの再起動なしに続行したいわけです。

Windowsの場合ならばデバイスマネージャから無効/有効を行えばBARの再設定が行われるので再起動する手間を省けますが、Linuxでやる方法を調べました。

ここではScientific Linux CERN 6 (SLC6)というディストリビューションを使用しています。

基本的なやり方は、rescanというドライバを使って、

sudo echo "1" > /sys/bus/pci/rescan

のようにします。一瞬、??となる書き方なのですが、rescanというのは、

--w--w---- 1 root root 4096  1月  6 16:09 2017 /sys/bus/pci/rescan

というスペシャルファイルで、このファイルに1を書き込むと再スキャンが行われるという代物のようです。

ただ、私が使っているSLC6というディストリビューションではrescanに書くだけではうまく行かず、sudoを付けていても許可がありませんと出てしまいます。

そこでchmod 666でドライバrescanに読み書き属性を付与してから行っています。また、なぜかrescanだけではうまくいかないので、removeというドライバにも同様に1を書き込んでから行います。

結局のところ、以下のようなスクリプトを書いて実行しています。

#!/bin/sh
sudo chmod 666 /sys/bus/pci/devices/0000\:0$1\:00.0/remove
sudo echo 1 > /sys/bus/pci/devices/0000\:0$1\:00.0/remove
sudo chmod 666 /sys/bus/pci/rescan
sudo echo "1" > /sys/bus/pci/rescan

使い方は、./rescan 4 のようにrescanの後にバス番号を指定します。

バス番号というのは、lspciで表示される一覧の一番左の数字です。

Lspci

上のDPIO moduleというのがFPGAで作ったPCI Expressのファンクションです。この数字が4なので、rescan 4とすると、上のスクリプトが起動して、PCI Expressデバイスが削除されてから再スキャンされて、BARが再設定されるというわけです。

これで、OSを再起動することなく、FPGAのみ書き換えて動作を続行することができるようになります。

実際にやってみてわかった注意点がいくつかあります。

  1. BARのサイズを増やすと、再設定が行われない場合がある。
    つまり、最初は16kB程度の領域を確保していて、再スキャン後に64MBに増えているような場合は、うまくいかない。FPGAを書き換えてもリクエストするメモリ空間のサイズは変えない方が良い。
  2. BARサイズを減らすのは大丈夫なようだ。
  3. VIDやDIDが変わるのはOK。

以下に、実際の実行結果を示します。

まずは、起動したLinuxを直後にlspciでデバイスのコンフィギュレーション情報を見たところです。1bc8:1080のデバイスが見えています。Region 0..2の表示にも注目してください。

[user@px ~]$ lspci -d 1bc8:* -vvvx
04:00.0 DPIO module: Device 1bc8:1080
        Subsystem: Device 1bc8:1080
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 0, Cache Line Size: 256 bytes
        Interrupt: pin A routed to IRQ 11
        Region 0: Memory at dbfec000 (32-bit, non-prefetchable) [size=16K]
        Region 1: Memory at dbff0000 (32-bit, non-prefetchable) [size=64K]
        Region 2: Memory at dc000000 (32-bit, non-prefetchable) [size=64M]
        Capabilities: <access denied>
00: c8 1b 80 10 07 00 10 00 00 00 00 11 40 00 00 00
10: 00 c0 fe db 00 00 ff db 00 00 00 dc 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 c8 1b 80 10
30: 00 00 00 00 40 00 00 00 00 00 00 00 0b 01 00 00

FPGAを書き換え中にlsmodしてみました。すべてのレジスタがffになって見えないことがわかります。

[user@px ~]$ lspci -d 1bc8:* -vvvx
04:00.0 DPIO module: Device 1bc8:1080 (rev ff) (prog-if ff)
        !!! Unknown header type 7f
00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
30: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

下の表示はFPGAの書き換えが完了した直後の状態です。Region 0,1,2がvirtualと出ています。

[user@px ~]$ lspci -d 1bc8:* -vvvx
04:00.0 DPIO module: Device 1bc8:1080
        Subsystem: Device 1bc8:1080
        Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Interrupt: pin A routed to IRQ 255
        Region 0: [virtual] Memory at fb310000 (32-bit, non-prefetchable) [size=16K]
        Region 1: [virtual] Memory at fb300000 (32-bit, non-prefetchable) [size=64K]
        Region 2: [virtual] Memory at fb400000 (32-bit, non-prefetchable) [size=4M]
        Capabilities: <access denied>
00: c8 1b 80 10 00 00 10 00 00 00 00 11 00 00 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 c8 1b 80 10
30: 00 00 00 00 40 00 00 00 00 00 00 00 ff 01 00 00

ここでrescanすると、

[user@px ~]$ lspci -d 1bc8:* -vvvx
04:00.0 DPIO module: Device 1bc8:1080
        Subsystem: Device 1bc8:1080
        Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Interrupt: pin A routed to IRQ 255
        Region 0: Memory at fb310000 (32-bit, non-prefetchable) [disabled] [size=16K]
        Region 1: Memory at fb300000 (32-bit, non-prefetchable) [disabled] [size=64K]
        Region 2: Memory at fb400000 (32-bit, non-prefetchable) [disabled] [size=4M]
        Capabilities: <access denied>
00: c8 1b 80 10 00 00 10 00 00 00 00 11 00 00 00 00
10: 00 00 31 fb 00 00 30 fb 00 00 40 fb 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 c8 1b 80 10
30: 00 00 00 00 40 00 00 00 00 00 00 00 ff 01 00 00

virtualと表示されていたregionが設定され、使用できるようになります。

この情報が、Linux上で動くPCI Expressのアドインカードを開発する人の助けになれば幸いです。

| | コメント (3)

2017.01.03

年末年始の発送

今年は年末年始にもご注文があって嬉しい悲鳴です。

12月30日夜に1件注文があったので、31日に発送しようとしたのですが文京区の佐川急便集配所が早くに閉まっていたため、自宅のある墨田区へ持ち帰り。墨田区の佐川急便が奇跡的に開いていたのでそこから出しました。1月1日に到着したようです。

12月31日の夜に3件の注文がありました。年末年始は墨田区から発送しよう思ったのですが、代引き(e飛電)のプリンタが会社にしかないので、結局、元日に会社に行って発送しました。しかし、佐川急便の集配所が閉まっていたので、近所の佐川急便の集配所を調べてみると、なんと、東京駅にあることが判明。

http://www.sagawa-exp.co.jp/ttk/servicecenter/70150142.html

Tokyosagawa

1月1日には、この東京駅の佐川急便から2件発送。もちろんe飛電の伝票でも受け付けてくれました。また、クロネコヤマトで墨田区からも発送。

1月3日は、佐川急便の東京駅から発送。

と、年末年始も即日発送にこだわってみました。

1月以降の発送は、初詣の帰りに会社によってから発送しているので、御神気のパワーが宿っているかも。

・・・・・

電話すれば集荷に来てくれると思うのですが、時間がいつになるかわからないので、集配所に持ち込もうとしたのですが、いつもの集配所も早く閉まっているので、意外と大変でした。

東京駅の佐川急便さん、ありがとうございます。

集荷に来てくれるというサービスのありがたさを改めて知った年末年始でした。

| | コメント (0)

2017.01.01

基板年賀状2017

今年も基板年賀状を作りました。

銀河へはばたくフェニックスをイメージしています。

Nenga2017

LEDや抵抗、コンデンサなどの部品を実装して、電源を入れると、光ります。

Nenga_light



宛名面は2パターンあって、HyperFADCとCosmo-Kの広告になっています。

Nenga2017_atena

貴方のところには、どちらの年賀状が届きましたか?

回路図や部品実装、郵送料、デザインの詳細などについては下記のページをご覧ください。

↓↓↓↓↓↓↓↓↓↓↓↓↓↑↓↓↓↓

http://www.tokudenkairo.co.jp/nenga2017.html

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

それでは、今年も1年間よろしくお願いします。

| | コメント (0)

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

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

今年の目標を書きます。

■■カメラを開発する

特電始まって以来、初めての技術系正社員を入れる

秋葉原にリアル店舗を出す

----------------------

いままでの延長でできることではなく、どれも実現がとても難しいことをあえて書きました。20%でも達成できるように頑張ります。

1番目の■というのは伏字です。これは特電が2015年度から取り組んでいる壮大な計画です。うまくいけば日本の建設業界や防災が変わるというほど大きな目標です。

2番目の正社員も悲願の目標です。いままで特電には技術系の社員を採用したことがなかった(アルバイトとインターンのみ)ので、週5/8時間で働いてくれる初めての正社員を入れたいと思っています。

3番目の秋葉原にリアル店舗という件ですが、コンセプトは「プロ専門のFPGAショップ(素人さんお断り)」です。特電製品やTrenzElectronic製品をはじめ、ハイエンドなFPGAのボードを売ったり、FPGAを単体で売ったり、FPGAやJTAGの使い方のレクチャーを有料で行ったりするようなお店です。計画が具体的になったら、店長候補も募集したいと思います。

どこまでできるか分かりませんが、頑張ります。

| | コメント (2)

« 2016年12月 | トップページ | 2017年2月 »