'+コーディング1H+syntax check2H+debug4H+blog0.5H=28.5H
予定よりも早くデバグに入れたのは嬉しいけど、症状は重い。
やっとステートマシンが回り始めたんだけど、なぜか1ステート飛ばして止まっちゃう。
ステートマシンで書かずに、普通にカウンタで書けばよかったかな?
ステートマシン推定の弊害
quartusは、ステートマシン推定ってのをしてくれる。
例えば
localparam S_0 = 0 ; localparam S_1 = 1 ; localparam S_2 = 2 ; reg [3:0] STATE ; always @(posedge CK ) if (start) STATE <= S_0 ; else case ( STATE ) S_0: STATE <= S_1 ; S_1 : if ( carry ) STATE <= S_2 ; S_2 : begin if ( ~carry) STATE <= S_0 ;
の様に書くと、STATEのbit数を揃えてくれたり、レジスタをワンホットに変えて
ハザードを減らしてくれたりする。
また、ミーリーで書いてもワンホットに変換すれば、デコード値がDFF出力になるので、体外の場合、ムーアーの様に早い。
orつなぎなどでも、それに良いように書き換えてくれるので、ミーリーの記述でDFF出しの様な回路が記述できるすげえやつ。なのですよ。
そのかわり、ステートとSTATEの値がparameterで指定した値と異なる値が再配置されるで、
xilinxなど他のデバイスに異色した時に、回路構成が全く変わってしまう。
それ以上にシミュレーションツールごとに振る舞いが変わるので、結構つかれる。
ステートとSTATEの値の対応は、レポートに出てくるので、メモすればいいちゃいいんだが。
(あ、Verilog1995モードでは推定しないっぽいです。)
で、今回ヘマしたのは、ステートを使うときに
always @(posedge CK) if ( STATE == S_1) JUDGE <= 1'b1 ;
の様に書くと、STATEとステートの対応が変わっているため、意図した分岐をする時も
しないときもある。のがこまる。
(S_0の様なリセットなシーケンスでは0がアサインされることが多そうではあるけど)
こうかかなきゃいけない。時がある。
always @(posedge CK) case( STATE) S_1: JUDGE <= 1'b1 ; endcase
endcaseがなければ、我慢できるが、コード量が多いのが気になるなぁ。
してやられた感じ。気づくのに1時間かかった。
(仕事でも引っかかった覚えが)
ただ、ステートマシンの外でも値の書き換えをしてくれてた時もあった気がするので、
切り分けがよくわかりません。が、こちらで書いとけば、どこにでもセーフポータブルかと。