2011年6月26日日曜日

CAN IPのDEBUG 3

自作CAN IPのDebugを続けている。
この土日はあまり時間がとれなかったので、Standard FormatとExtend FormatのArbitration、Standard Format同士のArbitration、DLC(Data Length Code)を見た。
(Extend Fromat同士のArbitrationは既に検証済み)

Arbitrationに関しては何れも問題なく動作したが、波形的には従来見ているものと大差ないので、
今回はDLCについて書く。

CAN では1 Frame当たり0~8 Byte迄のDataを転送できるが、その転送長はCONTROL FIELD内
の4bitのDLC(Data Length Code)で表す。




転送長とDLC各bitとの対応は上記のとおりである(Dを0、Rを1と見れば普通のBinary表現)が、
転送長が0~8の9種であるのに対してDLCは2^15 = 16通りある。
CAN では8以上は8と解釈することになっている。(CAN Specification 2.0 Addendum page 1)


上図はDLCを0~15迄振ってNode1から送信をした場合であるが、DLCが8以上では転送長は8に丸められている。


上図はRemote frameでDLCを0~15にした場合だ。
Remote frameはData転送を要求するFrameなのでRemote Frame自体にはData転送は無い。
従って、DLC0~15の各Frameの長さは同一になっているのが判る。

2011年6月19日日曜日

CAN IPのDEBUG 2

・・・という訳でtest benchが出来上がった。
directory構造は下のようになっている。
simulation環境はsim以下だ。



ref_model にOpenCoresのCAN IPのRTL、
tbench下はtest bench関係、vect下にはtest vectorが収容される。
test vectorはverilogで記述する。これはsimulation時にtest benchに
include される。


こうすることで、共通のframeworkを使いながら最大の自由度が得られる。
・・・んじゃないかなと思う。

標準的なtest vectorは以下のような感じで記述するが、verilogでtest benchの一部として
記述するので基本的には何でも有りだ。
冒頭で start_tb を待っているが、このstart_tbはresetやReference Modelの初期化終了後に
1になる信号だ。 また、最後のsim_endはsimulation終了を通知するeventだ。



simulationの実行はsim_exec下でdo_simというshell scriptで行う。
do_simのusageは以下の通りだ。



今回のIPのsimulationはassertion向きな気がしているので、
Coveredによるcoverage計測もできるようにしている。
使用するverilog simulatorはIcarus VerilogとGPL Cverの何れかを指定可能で、
環境変数SIMULATORにiverilogまたはcverを設定する。
環境変数が設定されていない場合はiverilogが使用される。
波形はvcd形式とfst形式の何方かを指定できる。何方かを指定しないと生成されない。
fstはGTKWaveがsupportしているfile formatで、vcdに比べfile sizeが小さくなる。
cverは元々fst形式のdump機能を持っていないが、GTKWaveの作者が機能拡張した版を
公開している。
http://gtkwave.sourceforge.net/gplcver-2.12a_fst.src.tar.gz

-cln はsim_exec下をdo_simのみを残して全て削除する。
何もかもを消して全てを忘れたい時に実行する・・・じゃ無くて、simulationを続けていると
sim_exec下にlogやら波形fileやらcoverage fileやらが溜まっていくのでこれらを消して、
初期状態に戻したいときに実行する。



このtest benchはReference ModelのNodeを1つと自作IPのNode 3つで構成している。

この環境でsimulationを実行して得た波形を表示したのが以下だ。

また、coverage計測を実行して得られた結果をcoveredで表示している様子が以下だ。

2011年6月12日日曜日

CAN IPのDEBUG

OpenCoresのCAN IPをReference Modelにして自作 CAN IPのdebugを行っている。
OpenCoresのCAN IPに付属しているtest benchではCAN IPが2つinstanceされているが、
この他にsimulation の項目に応じてCAN busのtransaction patternを発生させるtaskがある。
このtaskは全部で17個程ある。


従って実質的には3つのnodeが存在する。先日はこの環境に自作のIPを追加して、
simulationを実行して自作IPがReference Modelと同じ動作をするかを見れるようにした。
最終的にはtest benchを作成してReference Modelをそのbenchにinstanceするつもりだが、
その前に上記のtest benchの全taskでの検証を実施してみることにした。
その結果、自作IPにerror 処理の部分にbugが見つかった。
具体的にはError Frame送出後のError Delimiter Frame時にDominantを検出する場合が
想定されていなかった。これはOverload Delimiter Frameも同様だった。
CAN I/F規約ではbusに繋がっている全てのError ActiveなnodeがError Frameを送出した後、
Error Frame Delimiter Frameに移行するので、Error Frame Delimiter Frameの期間
Recessive状態が続くものと考えてしまったが、甘かった。異常状態を想定しなければならないので、
Dominantも想定する必要があった。 これ以外にもphy部でhard synchronous処理にbugが見つかったりした。
これらを修正していった結果Reference Modelと同じ結果を得られるようになった。



上は主にerror処理を見るためのtaskを実行した時の波形だ。
一方、下は正常処理を見るためのtaskを実行した時の波形だ。



CAN I/Fは仕様が複雑で、serial dataを受信(または送信)しながら、同時処理していかなくてはならない。そのため、自作IPのstate machine記述は複雑なものとなってしまった。



ただし、伝送速度は最高でも1Mbpsなので最近のFPGAなら楽勝で実装できてしまうだろう。

というわけで、これまでのdebug作業で主に受信部の検証は出来た。次は送信部の検証を行う必要があるのだが、これは上記のbenchだとやりにくいため、新しくtest benchを作成して進めていこうと
考えている。

2011年6月4日土曜日

CAN IPの作成

「カン」という言葉を聞くと何故か、し~んぱ~いないからね…という歌が反射的に頭の中に湧いてきてしまうが、そのカンでは無くて(そっちはKANだし)、CANとはController Area Networkのことで、Controller Area Networkは、耐ノイズ性の強化を考慮して設計され、相互接続された機器間のデータ転送に使われる規格。機器の制御情報の転送用として普及しており、輸送用機械、工場工作機械等のロボット分野においても利用されている。自動車においては、速度、エンジンの回転数、ブレーキの状態、故障診断の情報などの転送に使用されている。(出典 Wikipedia)  CANはBosch社によって開発され、その後、国際標準化機構(ISO)が ISO 11898およびISO 11519として標準化している。(同)  CANの規格書はBosch版をここから入手することができる(日本語の資料としてはこれが解りやすい)が、Patentの関係でCANのプロトコルを使用する場合はBosch社からLicenseを受ける必要があるらしい。2年ほど前にCANについて調べたみたことがあり、上記の仕様書を入手して読んでみたりしていた。
物理層はI2C busを差動にした様な印象で、へんてこな仕様だなぁーという印象だったが、DataLink層の仕様も読んでみてそれまでの私の知識にはない変わった仕様だった。でも、仕様書を読んでいるうちに自分でもIPを作れそうな気がしてきて作成してみた。 出来上がったRTLの公開も考えていたのだが、上記のLicenseの件が気になったりしている内に興味もなくなり、作業を中断していた。
因みに、CAN プロトコルを実デバイスで私用する場合はLicenseを受ける必要があるが、自分で作成したソースコードの公開自体は問題ないみたいだ。実際、OpenCoresではIgor, Mohorという方が作成されたCAN IPがLGPLで公開されている。(Copyright文にはLGPLの他に、このIPをシリコンに実装する場合はBoschからLicenseを受ける必要がある旨がしっかりと記載されている。) 日本でも、FPGAインフォメーションがVHDL版のCAN IPを公開している。
という訳で暫く放置していたCAN IPだが、Core部のRTLはほぼ完成していたこともあり、作業を再開した。
以下は3つのNodeでの調停と負けたNodeのRetryをSimulationしている様子だ。



上記Simulationは正常に動作しているのだが、全てが自作であり、仕様の解釈を間違えて実装している可能性は排除出来ないため、本当に正しい動作なのかは何とも言えない。
そこで、OpenCoresのCAN IPを入手してこのIPをReference modelとして使うことにした。
このIPのREADME.txtによると、BoschのVHDL Reference Modelでtestしていて全ての項目をpassしているそうなので、Referenceとしては申し分ないだろう。
以下はOpenCores版CAN IPに付属しているTest Benchに自作IPを組み込んでSimulationした様子だ。



動作的には受信部しか見れていないが正しく動作している。
自作IPの組み込みはしたのだが、このTest Benchの構造やどこまでのことが出来るのかまでは、まだ、解析できていないが、一応自作IPの検証項目としては以下を考えているので、これらを見れるようにぼちぼちやっていこうと思う。



順番が逆になってしまったが、私のCAN IPの構造(RTL構成)は以下の様になっている。



図にするとこんな感じだ。





実用の為にはFIFOや受信パケットの取捨選択をするためのIDのマッチング用回路も必要になるが、この部分はcan_coreには含めていない。 これは、その部分の難易度が高いからではなく、自分の設計スタイルでいつも、必要最小限の部分をcoreとしてまとめるようにしているからだ。

2011年6月3日金曜日

zumi32はAtlysだと100MHzでもOK?

以前、zumi32の性能を見るために各FPGA用に合成して、Metする上限の周波数を調べた。
その時はSpartan6 (XC6SLX9-2)では89MHzが上限だったのだが、今回Atlys (に搭載されているXC6SLX45-2)用に合成してみたところ、109MHzまでMetした。 




おぉ ー!!
なんかうれしい。

TE0720 No.4 (BNN-PYNQを動かしてみる 2)

TE0720でBNN-PYNQを動かすことが出来た。 以下は前回に続いてBNN-PYNQが動くまでの記録。 gdb (GNU debugger)で例外が出る原因を調べてみた。 例外が発生しているのはシェアードライブラリ(python_hw-cnv-pynq.so)の中であ...