gm300の日記: ring buffer式の非同期FIFO
久しぶりに大きな問題に。
まだエンジニアレベルに留まっているが、実のところ本当には、どう制約するのがいいのかコンセンサスが取れていない。skewが小さくないといけないのは、当たり前。どんなに小さくしても毎サイクル確実に取り込むのは無理。gray codeを使えば遷移状態を確実につかめるのはまあいい。000->001->011->111みたいな遷移の時に、受け取るほうが早いときは、000->011に見える。今は、そうじゃなくて、x1xの信号が早すぎて000->010->011みたいな遷移に見えることが話題になっている。そんなことって本当にあるのか?
001を飛ばすのを防ぐには、flow制御しかない。っていうか、このコード自身がflow制御なわけだ。「000」見たぜ!->001に変更->「001」みたぜ!で交換するなら、gray codeのbit間遷移のx1xの信号がどんなに早くてxx1がどんなに遅くても000->010が見えることはない。というわけでハンドシェークしていればgraycode部のskewは、問題無い。
で、話は戻ってdata転送のhand shakeをgray codeで行う時の話だ。いろいろやりかたがあるが、今の実装は、gray codeは、addressとみなして、気が付いたときにaddressを調べ、over runしないことを確かめる という方式だ。この方式では折角の先の議論が台無しだが、gray code部は、ダラダラ流れるだけで、間違って値にならないことが重要だ。あーあ。つまり追い抜いてはいけない。src/dstの両方のskewが0であれば、追い抜くというのは、datapath遅延が、1cycle以上の遅延差があるとき。skewが0でないなら、合わせて1 cycle以下。今のやり方は、datapathの遅延を1cycle以下にする方法だ。FPGAの場合、clock skewはせいぜい0.5nsec。うーん。ダメじゃない。でも確実でもない。src clock skewが0.5n. dst clock skewが 0.5, datapath遅延がcycle - 1n以下ならだめだ。どうすりゃいい? 非同期ということで、もともとclock skewは適当についているので、skewを考慮してmax_delayとmin_delayで挟み込む。 そんな面倒な話、嫌われそうだ。思い切ってclock cycle - 1nにするか。次は、それってread / writeって話だ。
ring buffer式の非同期FIFO More ログイン