OpenCoresではWISHBONEバスが奨励されているので、IPコアの外部バスをオリジナルの仕様からWISHNBONEバスに変更しました。
リセット信号
OpenCoresのデザインガイドライン「OpenCores HDL modeling guidelines」には次のような記載があります。
- リセットは、非同期アクティブHighにしてください。(Recommendation)
一方、
WISHBONEバスの仕様書「Wishbone B4」には次のような記載があります。
- すべてのWISHBONEインターフェースはRST_Iのアサーションに続くCLK_Iの立ち上がりエッジで初期化されなければならない。
デザインガイドラインでは「非同期リセット」、WISHBONEバスの仕様書では「同期リセット」と読めます。どちらにすれば良いか決めかねるので、とりあえずdefineで選択できるようにコードを書き換えました。
`define D3D_SYNC_RESET 1 // Positive: 1 // Negative: 0 `define D3D_RESET_POL 1'b1 `ifdef D3D_SYNC_RESET always @(posedge clk_core) begin `else always @(posedge clk_core or posedge rst) begin `endif if (rst == `D3D_RESET_POL) begin r_state <= P_IDLE; end else begin : end end
WISHBONEバスのバースト指定
今回のIPコアは、マスタ・アクセス時にメモリからデータをバーストでリードする仕様なのですが、WISHBONEバスはどうもバーストの仕様がないようです(コマンド出力と同時にバースト長を指定できない)。DRAM系のメモリに対してバーストでアクセスできないのは、かなり心苦しいのですが、どうしようもありません。バーストアクセスをシングルアクセスに変更しました。
実機(DE0)でメモリをSDRAMとしてバスアクセスを比較した結果が次のタイミングチャートです。
IPコアのバスアクセスは、DE0ではブリッジ回路でAVALONバスに変換しています。この波形は3ワードのバーストリードで頂点データをメモリからフェッチした時のものです。コマンド出力から17サイクル後に最初のデータが有効になり、3ワードの読み出し完了まで22サイクルです。
WISHBONEバスに変更した回路のバスアクセスでは、シングルアクセスx3で3ワードのリードを行っています。コマンド出力から、3ワードの読み出し完了まで62サイクルです。
WISHBONEバスに変更したことで、完全にパフォーマンスが1/3になってしまいました。複雑な気持ちになりますが、仕方ありません。
その4に続く。