LoginSignup
5
4

More than 5 years have passed since last update.

Verilog HDLでの数値リテラル(定数)の書き方

Last updated at Posted at 2013-12-03

ブログ記事の焼き直しですみませんが、私が Verilog HDL を書き始めて一番ハマった(バグった)部分です。
Veritakのたっくさんに教えて頂いたバグでした。わからなかったので、とっても助かりました。ありがとうございました。
(書き方が全くわからないので、平文で書きます。ご容赦を。。。)

Spartan-3E Starter Kit (http://japan.xilinx.com/products/boards-and-kits/HW-SPAR3E-SK-US-G.htm) のDDR SDRAMのコントローラを作った時の話です。フロムスクラッチで練習のために書いてまして、FIFOも自分で書きました。その時に、Xilinx社のプリミティブの中で、Dual Port RAMライブラリのRAM16XDをメモリとして使用しています。Write Pointer(wp) と Read Pointer(rp) を定義し、wp と rp のポインタを使ったリングバッファとして、FIFOを構成していました。
なお、wp, rp 共に4ビットとして定義していました。FIFOのFULLを判定する式はrp-1 == wp となるのはお分かりかと思います。それで、FIFOのFULLを判定する式を下に示すように書いていました。
assign fifo_full = (rp-1==wp) ? 1'b1: 1'b0;

これでバグりました。fifo_full が 1 になりませんでした。判定条件が真になりませんでした。
この記述がなぜダメかというと、rp-1 の -1 はビット幅を指定していないので、32ビット幅に拡張されてしまうそうです。つまり符号が拡張されるので、32'hFFFF_FFFFになります。左辺は当然32ビット符号拡張されますが、== の比較のときに右辺も32ビットに拡張されてしまいます。
これでも通常の場合はOKなのですが、rp が 0、wp が F の時(ポインタは4ビットに定義してあるので)当然ながらFIFOはFULLなのですが、左辺は32'hFFFF_FFFF、右辺は32'h0000_000Fとなってイコールになりませんでした。当然式は真にならず、fifo_full が 1 になることはありませんでした。
これを避けるためには rp-1 の -1 のビット幅を制限する必要があるそうです。ここではポインタは4ビットなので、4ビットに制限します。つまり 1 は 4'b0001 か 4'h1 と書く必要があります。
よって、下のように、上式を書き換えると、fifo_full が正常に 1 になるようになりました。
assign fifo_full = (rp-4'h1==wp) ? 1'b1: 1'b0;

これは、皆さんには常識かもしれませんが、知らなかった人のために書いておきます。コレにハマるとしばらく原因がわかりません。。。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4