rx_pipe.vモジュールにCANの受信フレームをパターンマッチングで、どのレジスタ宛かを検出する部分があるのだが、そこの拡張ID部のビット幅を1bit短く記述していた。拡張ID部は18bit長なので、この部分は[17:0]でなければならない。パターンマッチングは基本ID部と拡張ID部その他IDのモードやマッチングをする/しないの情報を連結して行っていたので、それらの情報が1bit右にズレてしまっていた。そのため、今回の実装ではパターンマッチングを行わないという風に合成エンジンが解釈し、その信号が伝搬する下流の回路の生成がされないかあるいは変な状態になってしまっていたようだ。。。
修正前
修正後
修正後はLSEでもSynplifyでもトライステート部の回路は生成されるようになった。
RTL記述
LSEでの合成結果
Synplifyでの合成結果
これで両方の回路とも正常動作を期待したのだが、どうもまだ挙動が怪しい。
Zynq-CANの代わりにOpenCoresのCAN-IPを使い、ターゲットとしてうちの子(fpga_top)のRTL、合成後のゲートネットリスト、及び can-ip 単体を接続したテストベンチを作成して、OpenCoresのIPからPWMのdutyを設定するフレームを送信してちゃんと受信されるかを見てみた。
ベクタ ... pwmのdutyを0x40 (25%)に設定するフレームを5回連続して送信してみた。
結果
ref_modelはOpenCoresのCAN-IPの送受信信号で、rtl部はfpga_topのRTL、core部はcan_ip単体、gateは合成して生成されたネットリストによるものである。
Synpliftyで合成したネットの場合
RTL, gate, core 全てが同じ動作をしており、ちゃんとACK応答をしている。また、dutyも設定されている。
LSEで合成したネットの場合
gateは全く反応していない。。。 なんか変だなぁ−、まだ何かあるんだろうか?
試しに、Synplify版のビットデータを実デバイスに書いて、Zynqとの間で同様の通信をさせてみた。
Zynq側のプログラム
観測点はCANトランシーバとFPGA間の信号で、黄色は送信信号(FPGA➔Zynq)、紫は受信信号(Zynq➔FPGA)だ。
この分解能だと見辛いのでロジアナても見てみた。
採取した波形 ... 応答しない場合と応答する場合があるようだ。
上述のSynplify版ネットリストでのシミュレーション波形と比較してみた。
上がシミュレーションの波形、下がロジアナで採取した波形で、1発目の通信の部分だ。
FPGA側がACKやCRCエラー等で一切応答しないために、タイムアウトエラーとなっているようだ。Zynq((及びref_model)から送信されるフレームはどちらも同じなのでそこは問題なさそうだ。
何かしらの応答をしている箇所を見てみた。 FPGAから応答がないのでZynqからのエラーフレームに反応する形でこちらのFPGAもエラーフレームを出している。。。ということはエラーの検出はしているようなのだが???
と、言うわけでまだまだ先は長そうだ。 うーむ・・・でも、楽しい。