Verilogで犯しがちな記述ミス のバックアップ(No.4)

更新


公開メモ

意図

インプリメント時のワーニングをうまく見る方法が分からず、 簡単な記述ミスのせいで2,3時間を無駄にすることがしばしばなので、 ありがちなミスやそれへの対処法をここに記述して、日頃から注意しようという算段です。

宣言されていない信号線が幅1の wire として解釈される

Verilog ではこれは言語仕様なので、警告も出ないのですよね。

このせいで、クロックが正しく繋がれていなかったり、 幅の広いバス線のはずが1ビット目しか繋がれていなかったり、 常に泣かされています。

宣言されていない信号線が使われたらエラーにするか、 最低でも警告を出すオプションがあればかなり開発が 順調に進むと思うのですが・・・

見つけられていないだけかもしれません?

対処法

(2010/06/03 追記)

marsee さんに対処法を教えていただきました。

ソースコードの最初に

LANG:verilog
`default_nettype none

を記述すれば良いそうで、定義していない信号をエラーにできます。 Verilog 2001 以降で使えるそうです。

以下の注意も一緒にいただきました。

Xilinxのライブラリなどでは、1ビットのwireは定義していないこともあるので、

コンパイルの順番によっては、そこでエラーになることがあります。

そこで、最後に`default_nettype wireを書いておくと良いと思います。

つまり、

LANG:verilog

`default_nettype none

(Verilogの回路本体)

`default_nettype wire

です。

演算子の優先順位

参考:http://homepage3.nifty.com/hdl_design/verilog_hdl2.htm

ビット演算子と等号

ビット論理演算子の & や | よりも等号・不等号の方が優先順位が 高いことをすぐに忘れてしまい、痛い目を見ます。

LANG:verilog
assign a = b == c & d;

これは、

LANG:verilog
assign a = ( b == c ) & d;

と解釈されますので、

LANG:verilog
assign a = b == ( c & d );

としたければ、括弧は必須です。

Pascal や Ruby ではビット論理演算が等号よりも強かったので、 今でも勘違いして原因が分からず途方に暮れます。

C++ や C#, Java もビット論理演算が等号より弱いので、 そちらでも間違えまくりです(泣

等号と3項演算子

LANG:verilog
assign a = b == c ? d : e

は、

LANG:verilog
assign a = ( b == c ) ? d : e

と解釈されるので、

LANG:verilog
assign a = b == ( c ? d : e )

としたければ括弧は必須です。

これも結構やらかします。

3項演算子 ? : はすべての演算子の中で最も優先順位が低い、と覚えておけばいいのですね。

コメント




()は必須です

[アプロ] (2010-06-03 (木) 07:57:45)

assign文による組み合わせ回路で、条件判定する場合は、() でくくる癖をつけた方がいいですよ

また、あとあと論理がわかるように
(c == 1'b1) ?
とか明示するとよいでしょう

  • 書き込みありがとうございます。予防のために括弧を付ける癖を付けるというのが正しい姿勢なのでしょうね。 -- [武内(管理人)]
  • 条件判定で c == 1'b1 と書くのは個人的にはまだ受け入れにくいです。C を始めとするプログラミング言語では c != 0 とか c != false は冗長であるというのが常識で、この書き方もそれに似ているように思えてしまいます。特にビット幅まで指定した場合に c == 1'b1 と c == 1'b0 を瞬時に判別できないため、c と !c で書き分けるのに比べてかえって視認性が悪くなってしまうのではと感じています。c == 1'b1 という書き方のメリットはどのあたりにあるのでしょう? -- [武内(管理人)]

宣言されていない信号線が幅1の wire として解釈されるの解決法

[marsee] (2010-06-03 (木) 07:09:46)

宣言されていない信号線が幅1の wire として解釈されるの解決法としては、`default_nettype noneを最初に記述するという方法があります。こうすると定義していない信号があるとエラーになります。ただ、これはVerilog2001の構文です。Xilinxのライブラリなどでは、1ビットのwireは定義していないこともあるので、コンパイルの順番によっては、そこでエラーになることがあります。そこで、最後に`default_nettype wireを書いておくと良いと思います。つまり、
`default_nettype none
Verilogの回路本体
`default_nettype wire
です。

  • 大変有用な情報をありがとうございます。昨日からどこが悪いか全く分からず苦労している回路にこれを付けたらバグが見つかりそうな予感です(汗 -- [武内(管理人)]

Counter: 268472 (from 2010/06/03), today: 3, yesterday: 0