可変アドレスデコーダ(Verilog)
概要
入力ビット数と出力ビット数が可変できるアドレスデコーダ。出力ビット数は2^入力ビット数とする。
アドレスデコーダを可変にする状況で使いまわせると思い作成。
テクノロジーマッピングで意図したLUTの個数になっているかみてみた。(Cyclone3デバイス 4入力-LUTを条件として確認)
ソースコード
decode_var.v
// decode_var.v // author:manaka // date:19/01/04 // Description:First // History // v0.1 create new // module decode_var #( parameter DATA_BITS = 4 // decoder inout bits ,parameter DCD_BITS = 16 // decoder output bits(2^DATA_BITS) ) ( input [DATA_BITS-1:0] data_in // decode_input ,output[DCD_BITS-1:0] decode_out // decode_output ); genvar dcd_lp ; // decode loop variable /* decoder */ generate for( dcd_lp = 0; dcd_lp < DCD_BITS; dcd_lp = dcd_lp + 1) begin : gen_dcd_lp assign decode_out[dcd_lp] = (data_in == dcd_lp )? 1'b1: 1'b0; end endgenerate endmodule
検証環境
- decode_var_tb.v
- decode_var_top.v TOPから入力データ幅と出力データ幅を定義
- D1.decode_var.v width:12 cycle数: 5
- D2.decode_var.v width:32 cycle数:11
- decode_var_top.v TOPから入力データ幅と出力データ幅を定義
decode_var_top.v
// decode_var_top.v // author:manaka // date:19/01/05 // Description:First // History // v0.1 create new // module decode_var_top( input [3:0] DATA_1_IN ,output [15:0] DECODE_1_OUT ,input [4:0] DATA_2_IN ,output [31:0] DECODE_2_OUT ); //------------------------------------ // decoder_var module //------------------------------------ defparam D1.DATA_BITS = 4 ; defparam D1.DCD_BITS = 16 ; decode_var D1( .data_in (DATA_1_IN) ,.decode_out (DECODE_1_OUT) ); defparam D2.DATA_BITS = 5 ; defparam D2.DCD_BITS = 32 ; decode_var D2( .data_in (DATA_2_IN) ,.decode_out (DECODE_2_OUT) ); endmodule
shift_reg_tb.v
// decode_var_tb.v // author:manaka // date:19/01/04 // Description:First // History // v0.1 create new // `timescale 1ps/1ps module decode_var_tb(); reg CLK ; reg RST ; reg [3:0] DATA_1_IN ; wire [15:0] DECODE_1_OUT ; reg [4:0] DATA_2_IN ; wire [31:0] DECODE_2_OUT ; integer i ; //------------------------------------ // decoder_var module //------------------------------------ decode_var_top top_inst( .DATA_1_IN ( DATA_1_IN ) ,.DECODE_1_OUT ( DECODE_1_OUT ) ,.DATA_2_IN ( DATA_2_IN ) ,.DECODE_2_OUT ( DECODE_2_OUT ) ); //------------------------------------ // Clock generator //------------------------------------ parameter CLK_PERIOD = 20000; // ps 20ns initial begin CLK = 1'b0; end always #(CLK_PERIOD/2) begin CLK <= ~CLK; end //------------------------------------ // Reset generator //------------------------------------ initial begin RST = 1 ; repeat(20) @(negedge CLK); RST = 0 ; end //------------------------------------ // Test //------------------------------------ initial begin DATA_1_IN= {4{1'b0}}; DATA_2_IN= {5{1'b0}}; @(negedge CLK); while(RST==0) @(negedge CLK); repeat(50) @(negedge CLK); // count up decoder // count up decoder for( i = 0; i < 16; i = i + 1) begin DATA_1_IN= DATA_1_IN + 1 ; repeat(10) @(negedge CLK); end for( i = 0; i < 32; i = i + 1) begin DATA_2_IN= DATA_2_IN + 1 ; repeat(10) @(negedge CLK); end $stop; end endmodule
検証結果
シミュレーション検証
TOPで宣言したモジュールがパラメーターにより各bit幅でデコードされることを確認。
- 4bit 24=16bit幅でデコード
- 5bit 25=32bit幅でデコード
ツール合成(Quartus13.1)
RTL viewer
Quartusで合成し、RTLViewerを確認。比較器で表現されている。
テクノロジーマップ viewer
全体図
4bit→16bitのデコーダー
4bit→16bitのデコーダーは4入力LUT1段で済んでいる。
合成プロジェクトはCycloneIIIのため、4入力LUT。
5bit→32bitのデコーダー
5bit→32bitのデコーダーは4入力LUT1段では足りず、2段構成となる。
合成プロジェクトはCycloneIIIのため4入力LUTであるが、上位デバイスで6入力や8入力LUTであれば1段で済むと思われる。
RTLViewerは比較器で表現されてしまっているが、テクノロジーマップでのLUT段数は入力数に依存することは期待通りだった。
LUTの入力数を考えながらデコーダーを設計するとリソースを無駄にしなくて済みそうだ。(4入力LUT,6入力LUT,8入力LUTに合わせて設計するとか)
ただツールは頭がいいので、そんなこと意識しなくても最適化してくれるのかな。