« 続・テクスチャキャッシュ | トップページ | Pythonと深層学習と »

2016年12月24日 (土)

エンコーダ回路

ISE14.7でZybo設定(XCZ010-1CLG400) でエンコーダを作る実験をして見ました。

【パターン1】
まず同時に1つしかビットが立たない前提で、よくある悪いか書き方で

[ソース]
case (data)
8'b0000_0001:   sel <= 0;
8'b0000_0010:   sel <= 1;
8'b0000_0100:   sel <= 2;
8'b0000_1000:   sel <= 3;
8'b0001_0000:   sel <= 4;
8'b0010_0000:   sel <= 5;
8'b0100_0000:   sel <= 6;
8'b1000_0000:   sel <= 7;
endcase

[結果]
Number of Slice Registers : 3
Number of LUTs            : 13


【パターン2】
これに(* full_case *)をつけたり、下記のようにdefaultをつけると

[ソース]
case (data)
8'b0000_0001:   sel <= 0;
8'b0000_0010:   sel <= 1;
8'b0000_0100:   sel <= 2;
8'b0000_1000:   sel <= 3;
8'b0001_0000:   sel <= 4;
8'b0010_0000:   sel <= 5;
8'b0100_0000:   sel <= 6;
8'b1000_0000:   sel <= 7;
default:        sel <= {SEL_WIDTH{1'bx}};
endcase

[結果]
Number of Slice Registers : 0
Number of LUTs            : 6

当然LUTが減ります。

【パターン3】
が、よく考えたらこれでいいのではないかと

[ソース]
casex (data)
8'bxxxx_xxx1:   sel <= 0;
8'bxxxx_xx1x:   sel <= 1;
8'bxxxx_x1xx:   sel <= 2;
8'bxxxx_1xxx:   sel <= 3;
8'bxxx1_xxxx:   sel <= 4;
8'bxx1x_xxxx:   sel <= 5;
8'bx1xx_xxxx:   sel <= 6;
8'b1xxx_xxxx:   sel <= 7;
default:        sel <= {SEL_WIDTH{1'bx}};
endcase

[結果]
Number of Slice Registers : 0
Number of LUTs            : 4


【パターン4】
ここで機能追加してプライオリティーエンコーダにしてみます。

[ソース]
casex (data)
8'b0000_0001:   sel <= 0;
8'b0000_001x:   sel <= 1;
8'b0000_01xx:   sel <= 2;
8'b0000_1xxx:   sel <= 3;
8'b0001_xxxx:   sel <= 4;
8'b001x_xxxx:   sel <= 5;
8'b01xx_xxxx:   sel <= 6;
8'b1xxx_xxxx:   sel <= 7;
default:        sel <= {SEL_WIDTH{1'bx}};
endcase

[結果]
Number of Slice Registers : 0
Number of LUTs            : 4

プライオリティーエンコーダにしてもロジックが変わりませんでした。


【パターン5】

ここでパターン3をもっと汎用的に for文で書いて見ます。
[ソース]
sel <= {SEL_WIDTH{1'bx}};
for ( i = 0; i < DATA_WIDTH; i = i+1 ) begin
    reg_compare    = {DATA_WIDTH{1'bx}};
    reg_compare[i] = 1'b1;
    if ( data == reg_compare ) begin
        sel <= i;
    end
end

[結果]
Number of Slice Registers : 0
Number of LUTs            : 0
Number of Block RAM/ROM   : 1

なんとメモリテーブルが生成されました!(爆死)


【パターン6】

これがプライオリティーエンコーダだと

[ソース]
sel <= {SEL_WIDTH{1'bx}};
for ( i = 0; i < DATA_WIDTH; i = i+1 ) begin
    if ( data[i] ) begin
        sel <= i;
    end
end

[結果]
Number of Slice Registers : 0
Number of LUTs            : 4

めでたしめでたし。


うーん、まさかBRAM使ったROMが出来るとは思わなかった。
casex って if 相当では書き直せないのだろうか?

ついでに言うと、プライオリティーの有無でサイズが無いのも実験として不十分なので、16bit幅に増やして追試すると

プライオリティー無し:LUTs : 10
プライオリティーあり:LUTs : 11

となっった。

やはり、プライオリティーの有無はちゃんと回路規模に影響するらしい(良かった)。

とはいえ、プライオリティー無しエンコーダは汎用的にシンプルにかくのはどうすればいいのだろうか?

各bitの立つ条件を個別に記述する手はもちろんあるが、何かもっといい手がありそうな気もする。

« 続・テクスチャキャッシュ | トップページ | Pythonと深層学習と »

FPGA」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/560384/64668023

この記事へのトラックバック一覧です: エンコーダ回路:

« 続・テクスチャキャッシュ | トップページ | Pythonと深層学習と »