はじめに
エディター宗教大戦争の一陣営でおなじみのEmacsにはverilog-modeと言う物がある。Emacs verilog-modeの機能を使うとVerilogのコーディングをいろいろ補完してくれる。中でも、下位モジュールのポート信号を上位モジュールで自動接続してくれるAUTOINPUT、AUTOOUTPUT、AUTOWIRE、AUTOINSTが昔から良く使われている。しかしそれらに関する記事が少なかったり、有ってもSystem Verilogの時代となった現在では情報が古かったり、十分でなかったりする。なのでそれらについて書こうと思う。
「Emacsか~、なら使えないや。」とか思ってしまったvi/vim教信者のそこのあなた。安心してください。確かにEmacsの機能は使うけれど、Emacsエディターの操作は一切する必要ないです。何故ならEmacsはファイルのバッチ処理ができるからです。私自身vi/vim教信者でEmacsは殆ど使った事ないです。なので以下、バッチ処理を使用したEmacs verilog-modeでの自動信号接続について説明しようと思う。
準備
当然まずEmacsがインストールされている必要がある。大概はインストールされていると思うが。なければインストールする必要がある。又、バージョンが古いとverilog-modeの対応していないオプションがあったり、不具合があったりするのでできるだけ最新バージョンにアップデートするのをお勧めする。
Emacs自体アップデートせずとも、Emacsの内蔵コンポーネントのverilog-modeのみを最新の物にして使う事もできる。バグ修正などもされているので、極力最新のverilog-modeを使用する事をおすすめする。最新版は以下よりダウンロード可能。
git clone https://github.com/veripool/verilog-mode
cd verilog-mode
make e/verilog-mode.el
とすると最新版がダウンロードされて、./verilog-mode/e/verilog-mode.el
ができるのでこれを使用する。
Emacsのバッチ実行は以下コマンドで実行できる。
emacs -batch <File Name> -f <Command Name>
Command Nameは主に
- verilog-batch-auto
- verilog-batch-delete-auto
- verilog-batch-inject-auto
の3つを使う。又、--loadオプションで使用するverilog-mode.elファイルを指定する。
なので以下の様なMakefileを用意しておくと良いであろう。
FILENAME := top.sv
EL_FILE := ./verilog-mode/e/verilog-mode.el
CMD := emacs --batch --quick --load $(EL_FILE) $(FILENAME)
auto : $(FILENAME)
$(CMD) -f verilog-batch-auto
delete : $(FILENAME)
$(CMD) -f verilog-batch-delete-auto
inject : $(FILENAME)
$(CMD) -f verilog-batch-inject-auto
--quickオプションはバッチ実行に不要な初期設定ファイルのロードをスキップして高速に実行するためのオプションである。
1. 基本
下位モジュールの入出力ポートの接続と信号宣言を自動で行うが、その際に以下のルールに従う。
- 下位モジュールの出力ポート名と同名の入力ポートが他の下位モジュールにあればwire(或いはlogic)として宣言(AUTOWIRE or AUTOLOGIC)。
- 下位モジュールの入力ポートと同名の出力ポートが他になければinputとして宣言(AUTOINPUT)。
- 下位モジュールの出力ポートと同名の入力ポートが他になければoutputとして宣言(AUTOOUTPUT)。
- 下位モジュールの入出力ポート名と同じ名前で信号を接続する(AUTOINST)。(System Verilogの
(.*)
での接続と同様。)
又、宣言の際の信号のビット幅などは
- AUTOWIREは下位モジュールの出力ポート信号
- AUTOINPUTは下位モジュールの入力ポート信号
- AUTOOUTPUTは下位モジュールの出力ポート信号
のビット幅の情報を参照する。
以下、下位モジュールにsub1とsub2がある場合の簡単な例として図を使って説明する。
以下の様にtopには下位モジュールsb1,sb2がインスタンス化されているが、入出力信号およびsb1,sb2のインスタンス接続信号は記述されておらず、それぞれ/*AUTOINPUT*/
, /*AUTOOUTPUT*/
, /*AUTOINST*/
, /*AUTOWIRE*/
がコメントとして書かれているだけである。
module top (
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
/*AUTOWIRE*/
sub1 s1 (
/*AUTOINST*/
);
sub2 s2 (
/*AUTOINST*/
);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
以下は下位モジュール。verilog-modeでは単にテキスト処理をしているだけなので、ポート宣言さえされていれば中身は無くてもO.K。
module sub1 (
input sig_a, // Single signal
input [1:0] sig_b, // Vector
input [0:2][7:0] sig_c, // 2D Packed Array
input [7:0] sig_d[0:2], // 2D Unpacked Array
output sig_e, // Single signal
output [1:0] sig_f, // Vector
output [0:2][7:0] sig_g, // 2D Packed Array
output [7:0] sig_h[0:2] // 2D Unpacked Array
);
endmodule
module sub2 (
input sig_e, // Single signal
input [1:0] sig_f, // Vector
input [0:2][7:0] sig_g, // 2D Packed Array
input [7:0] sig_h[0:2], // 2D Unpacked Array
output sig_i, // Single signal
output [1:0] sig_j, // Vector
output [0:2][7:0] sig_k, // 2D Packed Array
output [7:0] sig_l[0:2] // 2D Unpacked Array
);
endmodule
これらに対しバッチコマンドを実行してEmacs verilog-modeでtop.svの自動結線を行う。前述した様にMakefileを準備してあれば
make auto
或いは
make
と打つだけで良い。
尚、vi/vim,gvimにはmakeコマンドを受け付ける機能があるので、vi/vimおよびgvimでtop.svを開いた状態で、:make
と打つだけでvim,gvimで自動結線が実行される。なのでvi/vim信者にとっても大変便利。gvimであれば以下のボタンを押すでも良い。
実行すると以下の様に/*AUTOINPUT*/
/*AUTOOUTPUT*/
/*AUTOWIRE*/
および/*AUTOINST*/
の所に自動で記述が追加され、下位モジュールとの信号結線がされる。
module top (
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input sig_a, // To s1 of sub1.v
input [1:0] sig_b, // To s1 of sub1.v
input [0:2] [7:0] sig_c, // To s1 of sub1.v
input [7:0] sig_d [3], // To s1 of sub1.v
// End of automatics
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output sig_i, // From s2 of sub2.v
output [1:0] sig_j, // From s2 of sub2.v
output [0:2] [7:0] sig_k, // From s2 of sub2.v
output [7:0] sig_l [3] // From s2 of sub2.v
// End of automatics
);
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire sig_e; // From s1 of sub1.v
wire [1:0] sig_f; // From s1 of sub1.v
wire [0:2] [7:0] sig_g; // From s1 of sub1.v
wire [7:0] sig_h [3]; // From s1 of sub1.v
// End of automatics
sub1 s1(
/*AUTOINST*/
// Outputs
.sig_e (sig_e),
.sig_f (sig_f[1:0]),
.sig_g (sig_g/*[0:2][7:0]*/),
.sig_h (sig_h/*[7:0].[3]*/),
// Inputs
.sig_a (sig_a),
.sig_b (sig_b[1:0]),
.sig_c (sig_c/*[0:2][7:0]*/),
.sig_d (sig_d/*[7:0].[3]*/));
sub2 s2(
/*AUTOINST*/
// Outputs
.sig_i (sig_i),
.sig_j (sig_j[1:0]),
.sig_k (sig_k/*[0:2][7:0]*/),
.sig_l (sig_l/*[7:0].[3]*/),
// Inputs
.sig_e (sig_e),
.sig_f (sig_f[1:0]),
.sig_g (sig_g/*[0:2][7:0]*/),
.sig_h (sig_h/*[7:0].[3]*/));
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
top.svのendmodule
の後に何やらコメントが書かれているが、これらはEmacs verilog-modeに対する設定をいろいろ行っている。// Local Variables:
と// End:
の間に挟んで設定の記述を行う。
この例では
-
verilog-library-flags
下位モジュールのファイルがあるディレクトリを-yで指定。 -
verilog-auto-inst-column
AUTOINSTの信号名の位置の調整。(;;
以降はコメント。) -
indent-tabs-mode:nil
タブをスペースに変換。Emacsではデフォルトだとタブを勝手に入れて来るのでそれが嫌な場合に設定する。
自動で挿入された記述を消して元に戻すにはverilog-batch-delete-auto
をバッチで実行する。makeでは
make delete
と打つ。
設定や記述を変更して再度自動接続を行いたい場合にはまたmake
を打てば良いが、記述更新の度にわざわざmake delete
をする必要はなく、記述更新後に単にmake
を打つだけで良い。
1-1. input/output/wireをマニュアルで宣言
全て全自動で信号接続を行う例を紹介したが、何も全て自動接続にする必要はなく、一部を従来通りのマニュアルで接続する方法を紹介する。
ここではinstのポート接続のみを自動にして、input/output/wireの宣言の方をマニュアルで行う。
module top
(
//---- Manual Input Ports
input sig_a,
input [1:0] sig_b,
input [0:2] [7:0] sig_c,
input [7:0] sig_d [3],
//----Manual Output Ports
output sig_i,
output [1:0] sig_j,
output [0:2] [7:0] sig_k,
output [7:0] sig_l [3]
);
//---- Manual Wires
wire sig_e;
wire [1:0] sig_f;
wire [0:2] [7:0] sig_g;
wire [7:0] sig_h [3];
sub1
s1 (
/*AUTOINST*/);
sub2
s2 (
/*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// verilog-auto-inst-vector:nil
// End:
自動接続を実行すると以下のようになる。
自動接続実行結果
module top
(
//---- Manual Input Ports
input sig_a,
input [1:0] sig_b,
input [0:2] [7:0] sig_c,
input [7:0] sig_d [3],
//----Manual Output Ports
output sig_i,
output [1:0] sig_j,
output [0:2] [7:0] sig_k,
output [7:0] sig_l [3]
);
//---- Manual Wires
wire sig_e;
wire [1:0] sig_f;
wire [0:2] [7:0] sig_g;
wire [7:0] sig_h [3];
sub1
s1 (
/*AUTOINST*/
// Outputs
.sig_e (sig_e),
.sig_f (sig_f),
.sig_g (sig_g/*[0:2][7:0]*/),
.sig_h (sig_h/*[7:0].[3]*/),
// Inputs
.sig_a (sig_a),
.sig_b (sig_b),
.sig_c (sig_c/*[0:2][7:0]*/),
.sig_d (sig_d/*[7:0].[3]*/));
sub2
s2 (
/*AUTOINST*/
// Outputs
.sig_i (sig_i),
.sig_j (sig_j),
.sig_k (sig_k/*[0:2][7:0]*/),
.sig_l (sig_l/*[7:0].[3]*/),
// Inputs
.sig_e (sig_e),
.sig_f (sig_f),
.sig_g (sig_g/*[0:2][7:0]*/),
.sig_h (sig_h/*[7:0].[3]*/));
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// verilog-auto-inst-vector:nil
// End:
設定に以下を追加してみた。
// verilog-auto-inst-vector:nil
この設定で/*AUTOINST*/
でのポート接続のベクターの信号幅の記述が省略される(sig_b, _j, _f)。
s1 (
.sig_f (sig_f),
.sig_b (sig_b),
s2 (
.sig_j (sig_j),
.sig_f (sig_f),
この// verilog-auto-inst-vector:nil
はマニュアルでのinput/output/wire宣言の時にしか効かない様で/*AUTOINPUT/OUTPUT/WIRE*/
の時には設定してもベクターの信号幅が記述される。
あと、
// verilog-auto-inst-dot-name:t
を設定するとSystem Verilogの(<Signal Name>)
を省略した記述スタイルになる。
s1 (
.sig_e,
.sig_f,
.sig_a,
.sig_b,
s2 (
.sig_i,
.sig_j,
.sig_e,
.sig_f,
1-2. instポートをマニュアルで接続
同様に/*AUTOINST*/
で行っていた下位モジュールのポート接続はマニュアルで行い、input/output/wireの宣言を自動接続で行う。
module top (
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
/*AUTOWIRE*/
sub1 s1 (
// Inputs (Manual Description)
.sig_a (sig_a),
.sig_b (sig_b[1:0]),
.sig_c (sig_c/*[0:2][7:0]*/),
.sig_d (sig_d/*[7:0].[3]*/),
// Outputs (Manual Description)
.sig_e (sig_e),
.sig_f (sig_f[1:0]),
.sig_g (sig_g/*[0:2][7:0]*/),
.sig_h (sig_h/*[7:0].[3]*/)
/*AUTOINST*/);
sub2 s2 (
// Inputs (Manual Description)
.sig_e (sig_e),
.sig_f (sig_f),
.sig_g (sig_g),
.sig_h (sig_h),
// Outputs (Manual Description)
.sig_i (sig_i),
.sig_j (sig_j[1:0]),
.sig_k (sig_k/*[0:2][7:0]*/),
.sig_l (sig_l/*[7:0].[3]*/)
/*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
自動接続(および宣言)を実行すると以下のようになる。
自動接続実行結果
module top (
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input sig_a, // To s1 of sub1.v
input [1:0] sig_b, // To s1 of sub1.v
input [0:2] [7:0] sig_c, // To s1 of sub1.v
input [7:0] sig_d [3], // To s1 of sub1.v
// End of automatics
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output sig_i, // From s2 of sub2.v
output [1:0] sig_j, // From s2 of sub2.v
output [0:2] [7:0] sig_k, // From s2 of sub2.v
output [7:0] sig_l [3] // From s2 of sub2.v
// End of automatics
);
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire sig_e; // From s1 of sub1.v
wire [1:0] sig_f; // From s1 of sub1.v
wire [0:2] [7:0] sig_g; // From s1 of sub1.v
wire [7:0] sig_h [3]; // From s1 of sub1.v
// End of automatics
sub1 s1 (
// Inputs (Manual Description)
.sig_a (sig_a),
.sig_b (sig_b[1:0]),
.sig_c (sig_c/*[0:2][7:0]*/),
.sig_d (sig_d/*[7:0].[3]*/),
// Outputs (Manual Description)
.sig_e (sig_e),
.sig_f (sig_f[1:0]),
.sig_g (sig_g/*[0:2][7:0]*/),
.sig_h (sig_h/*[7:0].[3]*/)
/*AUTOINST*/);
sub2 s2 (
// Inputs (Manual Description)
.sig_e (sig_e),
.sig_f (sig_f),
.sig_g (sig_g),
.sig_h (sig_h),
// Outputs (Manual Description)
.sig_i (sig_i),
.sig_j (sig_j[1:0]),
.sig_k (sig_k/*[0:2][7:0]*/),
.sig_l (sig_l/*[7:0].[3]*/)
/*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
/*AUTOINPUT*/
/*AUTOOUTPUT*/
/*AUTOWIRE*/
の対象ポートにするには// Inputs
// Outputs
で始まるコメント行の下に書く必要がある。小文字の// inputs
// outputs
でも良い。s
が必要なので注意。これらのコメントが無かったり、あっても外にポート接続を書くと/*AUTO????*/
の対象ポートとして認識されない。逆にこのコメントがあると/*AUTO????*/
の対象ポートにしたくなくても勝手に認識されてしまったりするので注意。
又、ポート接続の際、ベクターや多次元配列の信号はそれぞれs1の入力と出力、s2の出力で
.sig_f (sig_f[1:0]),
.sig_g (sig_g/*[0:2][7:0]*/),
.sig_h (sig_h/*[7:0].[3]*/),
の様に信号幅を指定する必要がある。配列の場合はこのようにコメントで記述。これらを記述しないと1bit信号と認識されてしまう様だ。\*AUTO????*\がこれらの記述を参照している様だ。
下位モジュールの信号幅を直接参照してくれてもいいだろうにそうはしていないみたい。/*AUTOWIRE*/
でのwire宣言作成にはs1の出力ポートが参照される。なのでs2の入力ポートの信号幅の情報は記述しなくても良い。
あと、instのポート接続を完全にマニュアルで記述はしているが、/*AUTO????*/
に認識させるには/*AUTOINST*/
の記述も必要みたい。
と、以上の様にいろいろと面倒な制約があるので敢えてinstのポート接続だけをマニュアルでやる積極的理由はないであろう。どうせinput/output/wire宣言を自動でやるならinstのポート接続も自動でやれば良いと思う。
唯一マニュアルでやる理由があるのは固定値入力指定や出力の非接続の場合であろう。
sub1 s1 (
.sig_a (1'0),
.sig_e (),
/*AUTOINST*/);
1-3. マニュアルとオートの混在
当然これらマニュアルとオートそれぞれの混在が可能。
sig_a,_h,_iは完全にマニュアルでの接続。逆にsig_c,_f,_kは完全に自動接続。なのでこれら信号の情報は元のtop.svには一切記述されていない。
module top (
// Manual Input Ports
input sig_a,
input [1:0] sig_b,
// Manual Output Ports
output sig_i,
output [1:0] sig_j,
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
// Manual Wires
wire sig_e;
wire [7:0] sig_h [3];
/*AUTOWIRE*/
sub1
s1 (
.sig_a, // From Manual Input
.sig_h, // To Manual Wire
// Inputs (Manual)
.sig_d (sig_d/*[7:0].[3]*/), // From AUTOINPUT
// Outputs (Manual)
.sig_g (sig_g/*[0:2][7:0]*/), // To AUTOWIRE
/*AUTOINST*/);
sub2
s2 (
.sig_h, // From Manual Wire
.sig_i, // To Manual Output
// Inputs (Manual)
.sig_g, // From AUTOWIRE
// Outputs (Manual)
.sig_l (sig_l/*[7:0].[3]*/), // To AUTOOUTPUT
/*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// verilog-auto-inst-vector:nil
// verilog-auto-inst-dot-name:t
// End:```
自動接続を行うと以下の様になる。
自動接続実行結果
module top (
// Manual Input Ports
input sig_a,
input [1:0] sig_b,
// Manual Output Ports
output sig_i,
output [1:0] sig_j,
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input [0:2] [7:0] sig_c, // To s1 of sub1.v
input [7:0] sig_d [3], // To s1 of sub1.v
// End of automatics
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output [0:2] [7:0] sig_k, // From s2 of sub2.v
output [7:0] sig_l [3] // From s2 of sub2.v
// End of automatics
);
// Manual Wires
wire sig_e;
wire [7:0] sig_h [3];
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [1:0] sig_f; // From s1 of sub1.v
wire [0:2] [7:0] sig_g; // From s1 of sub1.v
// End of automatics
sub1
s1 (
.sig_a, // From Manual Input
.sig_h, // To Manual Wire
// Inputs (Manual)
.sig_d (sig_d/*[7:0].[3]*/), // From AUTOINPUT
// Outputs (Manual)
.sig_g (sig_g/*[0:2][7:0]*/), // To AUTOWIRE
/*AUTOINST*/
// Outputs
.sig_e,
.sig_f (sig_f[1:0]),
// Inputs
.sig_b,
.sig_c (sig_c/*[0:2][7:0]*/));
sub2
s2 (
.sig_h, // From Manual Wire
.sig_i, // To Manual Output
// Inputs (Manual)
.sig_g, // From AUTOWIRE
// Outputs (Manual)
.sig_l (sig_l/*[7:0].[3]*/), // To AUTOOUTPUT
/*AUTOINST*/
// Outputs
.sig_j,
.sig_k (sig_k/*[0:2][7:0]*/),
// Inputs
.sig_e,
.sig_f (sig_f[1:0]));
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// verilog-auto-inst-vector:nil
// verilog-auto-inst-dot-name:t
// End:
2. ポート名と接続信号名を変える場合
下位モジュールでのポート名とそれに接続される上位モジュールでの信号名が違う場合、マニュアルでやるのも一つ手だが、自動で接続をする事もできる。
以下、上位モジュールではsig_?を?_topと言う信号名で接続する場合。
以下の様にtop.svで変えたい信号名を/* <module> AUTO_TEMPLATE ()*/
の中に入れて変換ルールを指定する必要がある。top.svでは下位モジュールのポート名をこの信号名で読み替えて自動接続を行う。その際信号名の後ろにベクターであれば[]
、2次元配列であれば[][]
を付けないときちんと信号幅を抽出してくれないので注意。単一信号であれば付ける必要がない。付けないと単一信号として認識されるようだ。単一信号やベクター信号でも[][]
を付けてればきちんと認識されるので何も考えず付けておくと良いであろう。
module top
(
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
/*AUTOWIRE*/
/* sub1 AUTO_TEMPLATE (
.sig_a (a_top[]),
.sig_b (b_top[]),
.sig_c (c_top[][]),
.sig_d (d_top[][]),
.sig_e (e_top[]),
.sig_f (f_top[]),
.sig_g (g_top[][]),
.sig_h (h_top[][]),
) */
sub1 s1
( /*AUTOINST*/);
/* sub2 AUTO_TEMPLATE (
.sig_e (e_top[]),
.sig_f (f_top[]),
.sig_g (g_top[][]),
.sig_h (h_top[][]),
.sig_i (i_top[]),
.sig_j (j_top[]),
.sig_k (k_top[][]),
.sig_l (l_top[][]),
) */
sub2 s2
(
/*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
自動接続実行結果
module top
(
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input a_top, // To s1 of sub1.v
input [1:0] b_top, // To s1 of sub1.v
input [0:2] [7:0] c_top, // To s1 of sub1.v
input [7:0] d_top [3], // To s1 of sub1.v
// End of automatics
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output i_top, // From s2 of sub2.v
output [1:0] j_top, // From s2 of sub2.v
output [0:2] [7:0] k_top, // From s2 of sub2.v
output [7:0] l_top [3] // From s2 of sub2.v
// End of automatics
);
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire e_top; // From s1 of sub1.v
wire [1:0] f_top; // From s1 of sub1.v
wire [0:2] [7:0] g_top; // From s1 of sub1.v
wire [7:0] h_top [3]; // From s1 of sub1.v
// End of automatics
/* sub1 AUTO_TEMPLATE (
.sig_a (a_top[]),
.sig_b (b_top[]),
.sig_c (c_top[][]),
.sig_d (d_top[][]),
.sig_e (e_top[]),
.sig_f (f_top[]),
.sig_g (g_top[][]),
.sig_h (h_top[][]),
) */
sub1 s1
( /*AUTOINST*/
// Outputs
.sig_e (e_top), // Templated
.sig_f (f_top[1:0]), // Templated
.sig_g (g_top/*[0:2][7:0]*/), // Templated
.sig_h (h_top/*[7:0].[3]*/), // Templated
// Inputs
.sig_a (a_top), // Templated
.sig_b (b_top[1:0]), // Templated
.sig_c (c_top/*[0:2][7:0]*/), // Templated
.sig_d (d_top/*[7:0].[3]*/)); // Templated
/* sub2 AUTO_TEMPLATE (
.sig_e (e_top[]),
.sig_f (f_top[]),
.sig_g (g_top[][]),
.sig_h (h_top[][]),
.sig_i (i_top[]),
.sig_j (j_top[]),
.sig_k (k_top[][]),
.sig_l (l_top[][]),
) */
sub2 s2
(
/*AUTOINST*/
// Outputs
.sig_i (i_top), // Templated
.sig_j (j_top[1:0]), // Templated
.sig_k (k_top/*[0:2][7:0]*/), // Templated
.sig_l (l_top/*[7:0].[3]*/), // Templated
// Inputs
.sig_e (e_top), // Templated
.sig_f (f_top[1:0]), // Templated
.sig_g (g_top/*[0:2][7:0]*/), // Templated
.sig_h (h_top/*[7:0].[3]*/)); // Templated
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
2-1. 信号名の変換規則を適用して一括変換
信号名を変換する場合/* <module> AUTO_TEMPLATE ()*/
を使う事を説明したが、一つずつ信号名の変換を指定しなくてはならず、数が多くなって来ると変になる。/*AUTOWIRE*/
, /*AUTOINPUT*/
, /*AUTOOUTPUT*/
で信号の宣言は自動でされるので少しはマシだとは言え、せっかく楽をしたくて自動接続をしたいのにこれでは本末転倒。もし信号名の変換に規則がある場合には/* <module> AUTO_TEMPLATE ()*/
でその変換規則を指定するれば一括で信号名の変換ができる。
今回の例ではsig_?を?_topの様に変換したが、この規則をそのまま指定できる。
.sig_\(.*\) (\1_top[][])
の様にワイルドカード(.*)
を使って、sig_で始まる全てのポート名をそのワイルドカードの文字列(1
で指定)で始まり、_top[][]で終わる信号名に変換するように指定できる。\
はそれぞれエスケープ文字。
module top
(
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
/*AUTOWIRE*/
/* sub1 AUTO_TEMPLATE ( .sig_\(.*\) (\1_top[][]), ) */
sub1 s1
( /*AUTOINST*/);
/* sub2 AUTO_TEMPLATE ( .sig_\(.*\) (\1_top[][]), ) */
sub2 s2
(
/*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
この様に変換規則を指定すると、信号名変換があっても記述を少なくできる。
自動接続実行結果
module top
(
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input a_top, // To s1 of sub1.v
input [1:0] b_top, // To s1 of sub1.v
input [0:2] [7:0] c_top, // To s1 of sub1.v
input [7:0] d_top [3], // To s1 of sub1.v
// End of automatics
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output i_top, // From s2 of sub2.v
output [1:0] j_top, // From s2 of sub2.v
output [0:2] [7:0] k_top, // From s2 of sub2.v
output [7:0] l_top [3] // From s2 of sub2.v
// End of automatics
);
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire e_top; // From s1 of sub1.v
wire [1:0] f_top; // From s1 of sub1.v
wire [0:2] [7:0] g_top; // From s1 of sub1.v
wire [7:0] h_top [3]; // From s1 of sub1.v
// End of automatics
/* sub1 AUTO_TEMPLATE ( .sig_\(.*\) (\1_top[][]), ) */
sub1 s1
( /*AUTOINST*/
// Outputs
.sig_e (e_top), // Templated
.sig_f (f_top[1:0]), // Templated
.sig_g (g_top/*[0:2][7:0]*/), // Templated
.sig_h (h_top/*[7:0].[3]*/), // Templated
// Inputs
.sig_a (a_top), // Templated
.sig_b (b_top[1:0]), // Templated
.sig_c (c_top/*[0:2][7:0]*/), // Templated
.sig_d (d_top/*[7:0].[3]*/)); // Templated
/* sub2 AUTO_TEMPLATE ( .sig_\(.*\) (\1_top[][]), ) */
sub2 s2
(
/*AUTOINST*/
// Outputs
.sig_i (i_top), // Templated
.sig_j (j_top[1:0]), // Templated
.sig_k (k_top/*[0:2][7:0]*/), // Templated
.sig_l (l_top/*[7:0].[3]*/), // Templated
// Inputs
.sig_e (e_top), // Templated
.sig_f (f_top[1:0]), // Templated
.sig_g (g_top/*[0:2][7:0]*/), // Templated
.sig_h (h_top/*[7:0].[3]*/)); // Templated
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
2-2. マニュアル接続との混在
当然マニュアルでの信号名変換とその接続との混合も可能。
マニュアルでinstポート接続している信号は信号名の変換がすでにされているので/* <module name> AUTO_TEMPLATE ()*/
での信号名変換指定は不要。
module top (
// Manual Input Ports
input a_top,
input [1:0] b_top,
// Manual Output Ports
output i_top,
output [1:0] j_top,
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
// Manual Wires
wire e_top ;
wire [7:0] h_top[3];
/*AUTOWIRE*/
/* sub1 AUTO_TEMPLATE ( .sig_\(.*\) (\1_top[][]),) */
sub1
s1 (
.sig_a (a_top), // From Manual Input
.sig_h (h_top), // To Manual Wire
// Inputs (Manual)
.sig_d (d_top/*[7:0].[3]*/), // From AUTOINPUT
// Outputs (Manual)
.sig_g (g_top/*[0:2][7:0]*/), // To AUTOWIRE
/*AUTOINST*/);
/* sub2 AUTO_TEMPLATE ( .sig_\(.*\) (\1_top[][]),) */
sub2
s2 (
.sig_h(h_top), // From Manual Wire
.sig_i(i_top), // To Manual Output
// Inputs (Manual)
.sig_g(g_top), // From AUTOWIRE
// Outputs (Manual)
.sig_l(l_top/*[7:0].[3]*/), // To AUTOOUTPUT
/*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// verilog-auto-inst-vector:nil
// verilog-auto-inst-dot-name:t
// End:
自動接続実行結果
module top (
// Manual Input Ports
input a_top,
input [1:0] b_top,
// Manual Output Ports
output i_top,
output [1:0] j_top,
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input [0:2] [7:0] c_top, // To s1 of sub1.v
input [7:0] d_top [3], // To s1 of sub1.v
// End of automatics
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output [0:2] [7:0] k_top, // From s2 of sub2.v
output [7:0] l_top [3] // From s2 of sub2.v
// End of automatics
);
// Manual Wires
wire e_top ;
wire [7:0] h_top[3];
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [1:0] f_top; // From s1 of sub1.v
wire [0:2] [7:0] g_top; // From s1 of sub1.v
// End of automatics
/* sub1 AUTO_TEMPLATE ( .sig_\(.*\) (\1_top[][]),) */
sub1
s1 (
.sig_a (a_top), // From Manual Input
.sig_h (h_top), // To Manual Wire
// Inputs (Manual)
.sig_d (d_top/*[7:0].[3]*/), // From AUTOINPUT
// Outputs (Manual)
.sig_g (g_top/*[0:2][7:0]*/), // To AUTOWIRE
/*AUTOINST*/
// Outputs
.sig_e (e_top), // Templated
.sig_f (f_top[1:0]), // Templated
// Inputs
.sig_b (b_top[1:0]), // Templated
.sig_c (c_top/*[0:2][7:0]*/)); // Templated
/* sub2 AUTO_TEMPLATE ( .sig_\(.*\) (\1_top[][]),) */
sub2
s2 (
.sig_h(h_top), // From Manual Wire
.sig_i(i_top), // To Manual Output
// Inputs (Manual)
.sig_g(g_top), // From AUTOWIRE
// Outputs (Manual)
.sig_l(l_top/*[7:0].[3]*/), // To AUTOOUTPUT
/*AUTOINST*/
// Outputs
.sig_j (j_top[1:0]), // Templated
.sig_k (k_top/*[0:2][7:0]*/), // Templated
// Inputs
.sig_e (e_top), // Templated
.sig_f (f_top[1:0])); // Templated
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// verilog-auto-inst-vector:nil
// verilog-auto-inst-dot-name:t
// End:
2-3. ポート名の数字を信号名に使用
\(.*\)
でポート名文字列のワイルドカードを指定したが、任意の文字列であるワイルドカードではなく、@
を使うと任意の数字のみの指定をする事ができる。
ポート名に連番の数字が割当たっている場合で数字はそのままで信号名を変えたい場合等に使うと便利である。
.param_@ (reg_\1[]),
ワイルドカード\(.*\)
との同時使用する事もできる。
\1
で最初のワイルドカード\(.*\)
或いは任意の数字@
で指定した文字列を参照し、\2
で2番目の物を参照を意味する。
.param_\(.*\)_@ (reg_\1_\2[]),
module top
(
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
/*AUTOWIRE*/
/* sub1 AUTO_TEMPLATE (
.sig_\(.*\)_@ (\1_top_\2[]),
.sig_\(.*\) (\1_top[][]),
) */
sub1 s1
( /*AUTOINST*/);
/* sub2 AUTO_TEMPLATE (
.sig_\(.*\)_@ (\1_top_\2[]),
.sig_\(.*\) (\1_top[][]),
) */
sub2 s2
( /*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
module sub1 (
input sig_a, // Single signal
//input [1:0] sig_b, // Vector
input sig_b_0,
input sig_b_1,
//input [0:1][7:0] sig_c, // 2D Packed Array
input [7:0] sig_c_0,
input [7:0] sig_c_1,
input [7:0] sig_c_2,
//input [7:0] sig_d[3], // 2D Unpacked Array
input [7:0] sig_d_0,
input [7:0] sig_d_1,
input [7:0] sig_d_2,
output sig_e, // Single signal
//output [1:0] sig_f, // Vector
output sig_f_0,
output sig_f_1,
//output [0:2][7:0] sig_g, // 2D Packed Array
output [7:0] sig_g_0,
output [7:0] sig_g_1,
output [7:0] sig_g_2,
//output [7:0] sig_h[3] // 2D Unpacked Array
output [7:0] sig_h_0,
output [7:0] sig_h_1,
output [7:0] sig_h_2
);
endmodule
module sub2 (
input sig_e, // Single signal
//input [1:0] sig_f, // Vector
input sig_f_0,
input sig_f_1,
//input [0:2][7:0] sig_g, // 2D Packed Array
input [7:0] sig_g_0,
input [7:0] sig_g_1,
input [7:0] sig_g_2,
//input [7:0] sig_h[3], // 2D Unpacked Array
input [7:0] sig_h_0,
input [7:0] sig_h_1,
input [7:0] sig_h_2,
output sig_i, // Single signal
//output [1:0] sig_j, // Vector
output sig_j_0,
output sig_j_1,
//output [0:2][7:0] sig_k, // 2D Packed Array
output [7:0] sig_k_0,
output [7:0] sig_k_1,
output [7:0] sig_k_2,
//output [7:0] sig_l[3], // 2D Unpacked Array
output [7:0] sig_l_0,
output [7:0] sig_l_1,
output [7:0] sig_l_2
);
endmodule
自動接続実行結果
module top
(
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input a_top, // To s1 of sub1.v
input b_top_0, // To s1 of sub1.v
input b_top_1, // To s1 of sub1.v
input [7:0] c_top_0, // To s1 of sub1.v
input [7:0] c_top_1, // To s1 of sub1.v
input [7:0] c_top_2, // To s1 of sub1.v
input [7:0] d_top_0, // To s1 of sub1.v
input [7:0] d_top_1, // To s1 of sub1.v
input [7:0] d_top_2, // To s1 of sub1.v
// End of automatics
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output i_top, // From s2 of sub2.v
output j_top_0, // From s2 of sub2.v
output j_top_1, // From s2 of sub2.v
output [7:0] k_top_0, // From s2 of sub2.v
output [7:0] k_top_1, // From s2 of sub2.v
output [7:0] k_top_2, // From s2 of sub2.v
output [7:0] l_top_0, // From s2 of sub2.v
output [7:0] l_top_1, // From s2 of sub2.v
output [7:0] l_top_2 // From s2 of sub2.v
// End of automatics
);
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire e_top; // From s1 of sub1.v
wire f_top_0; // From s1 of sub1.v
wire f_top_1; // From s1 of sub1.v
wire [7:0] g_top_0; // From s1 of sub1.v
wire [7:0] g_top_1; // From s1 of sub1.v
wire [7:0] g_top_2; // From s1 of sub1.v
wire [7:0] h_top_0; // From s1 of sub1.v
wire [7:0] h_top_1; // From s1 of sub1.v
wire [7:0] h_top_2; // From s1 of sub1.v
// End of automatics
/* sub1 AUTO_TEMPLATE (
.sig_\(.*\)_@ (\1_top_\2[]),
.sig_\(.*\) (\1_top[][]),
) */
sub1 s1
( /*AUTOINST*/
// Outputs
.sig_e (e_top), // Templated
.sig_f_0 (f_top_0), // Templated
.sig_f_1 (f_top_1), // Templated
.sig_g_0 (g_top_0[7:0]), // Templated
.sig_g_1 (g_top_1[7:0]), // Templated
.sig_g_2 (g_top_2[7:0]), // Templated
.sig_h_0 (h_top_0[7:0]), // Templated
.sig_h_1 (h_top_1[7:0]), // Templated
.sig_h_2 (h_top_2[7:0]), // Templated
// Inputs
.sig_a (a_top), // Templated
.sig_b_0 (b_top_0), // Templated
.sig_b_1 (b_top_1), // Templated
.sig_c_0 (c_top_0[7:0]), // Templated
.sig_c_1 (c_top_1[7:0]), // Templated
.sig_c_2 (c_top_2[7:0]), // Templated
.sig_d_0 (d_top_0[7:0]), // Templated
.sig_d_1 (d_top_1[7:0]), // Templated
.sig_d_2 (d_top_2[7:0])); // Templated
/* sub2 AUTO_TEMPLATE (
.sig_\(.*\)_@ (\1_top_\2[]),
.sig_\(.*\) (\1_top[][]),
) */
sub2 s2
( /*AUTOINST*/
// Outputs
.sig_i (i_top), // Templated
.sig_j_0 (j_top_0), // Templated
.sig_j_1 (j_top_1), // Templated
.sig_k_0 (k_top_0[7:0]), // Templated
.sig_k_1 (k_top_1[7:0]), // Templated
.sig_k_2 (k_top_2[7:0]), // Templated
.sig_l_0 (l_top_0[7:0]), // Templated
.sig_l_1 (l_top_1[7:0]), // Templated
.sig_l_2 (l_top_2[7:0]), // Templated
// Inputs
.sig_e (e_top), // Templated
.sig_f_0 (f_top_0), // Templated
.sig_f_1 (f_top_1), // Templated
.sig_g_0 (g_top_0[7:0]), // Templated
.sig_g_1 (g_top_1[7:0]), // Templated
.sig_g_2 (g_top_2[7:0]), // Templated
.sig_h_0 (h_top_0[7:0]), // Templated
.sig_h_1 (h_top_1[7:0]), // Templated
.sig_h_2 (h_top_2[7:0])); // Templated
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
2-4. ポート名の数字をベクター/配列のインデックスに使用
ポート名の数字を参照できるので、当然ベクターや配列のインデックス指定にも適用もできる。
.param_@ (reg[\1][]),
但し、その場合、ベクターは/*AUTOINPUT*/, /*AUTOOUTPUT*/, /*AUTOWIRE*/での自動宣言に対応しているが、多次元配列はきちんと対応していない様なので、その部分はマニュアルで宣言する必要がある。
module top
(
/*AUTOINPUT*/
// Manual inputs
input [2:0][7:0] c_top ,
input [7:0] d_top[3],
/*AUTOOUTPUT*/
// Manual outputs
output [3] [7:0] k_top,
output [7:0] l_top[3]
);
// Manual wires
wire [3] [7:0] g_top;
wire [7:0] h_top[3];
/*AUTOWIRE*/
/* sub1 AUTO_TEMPLATE (
.sig_\(.*\)_@ (\1_top[\2][]),
.sig_\(.*\) (\1_top[][]),
) */
sub1 s1
( /*AUTOINST*/);
/* sub2 AUTO_TEMPLATE (
.sig_\(.*\)_@ (\1_top[\2][]),
.sig_\(.*\) (\1_top[][]),
) */
sub2 s2
( /*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
自動接続実行結果
module top
(
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input a_top, // To s1 of sub1.v
input [1:0] b_top, // To s1 of sub1.v, ...
// End of automatics
// Manual inputs
input [2:0][7:0] c_top ,
input [7:0] d_top[3],
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output i_top, // From s2 of sub2.v
output [1:0] j_top, // From s2 of sub2.v, ...
// End of automatics
// Manual outputs
output [3] [7:0] k_top,
output [7:0] l_top[3]
);
// Manual wires
wire [3] [7:0] g_top;
wire [7:0] h_top[3];
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire e_top; // From s1 of sub1.v
wire [1:0] f_top; // From s1 of sub1.v, ...
// End of automatics
/* sub1 AUTO_TEMPLATE (
.sig_\(.*\)_@ (\1_top[\2][]),
.sig_\(.*\) (\1_top[][]),
) */
sub1 s1
( /*AUTOINST*/
// Outputs
.sig_e (e_top), // Templated
.sig_f_0 (f_top[0]), // Templated
.sig_f_1 (f_top[1]), // Templated
.sig_g_0 (g_top[0][7:0]), // Templated
.sig_g_1 (g_top[1][7:0]), // Templated
.sig_g_2 (g_top[2][7:0]), // Templated
.sig_h_0 (h_top[0][7:0]), // Templated
.sig_h_1 (h_top[1][7:0]), // Templated
.sig_h_2 (h_top[2][7:0]), // Templated
// Inputs
.sig_a (a_top), // Templated
.sig_b_0 (b_top[0]), // Templated
.sig_b_1 (b_top[1]), // Templated
.sig_c_0 (c_top[0][7:0]), // Templated
.sig_c_1 (c_top[1][7:0]), // Templated
.sig_c_2 (c_top[2][7:0]), // Templated
.sig_d_0 (d_top[0][7:0]), // Templated
.sig_d_1 (d_top[1][7:0]), // Templated
.sig_d_2 (d_top[2][7:0])); // Templated
/* sub2 AUTO_TEMPLATE (
.sig_\(.*\)_@ (\1_top[\2][]),
.sig_\(.*\) (\1_top[][]),
) */
sub2 s2
( /*AUTOINST*/
// Outputs
.sig_i (i_top), // Templated
.sig_j_0 (j_top[0]), // Templated
.sig_j_1 (j_top[1]), // Templated
.sig_k_0 (k_top[0][7:0]), // Templated
.sig_k_1 (k_top[1][7:0]), // Templated
.sig_k_2 (k_top[2][7:0]), // Templated
.sig_l_0 (l_top[0][7:0]), // Templated
.sig_l_1 (l_top[1][7:0]), // Templated
.sig_l_2 (l_top[2][7:0]), // Templated
// Inputs
.sig_e (e_top), // Templated
.sig_f_0 (f_top[0]), // Templated
.sig_f_1 (f_top[1]), // Templated
.sig_g_0 (g_top[0][7:0]), // Templated
.sig_g_1 (g_top[1][7:0]), // Templated
.sig_g_2 (g_top[2][7:0]), // Templated
.sig_h_0 (h_top[0][7:0]), // Templated
.sig_h_1 (h_top[1][7:0]), // Templated
.sig_h_2 (h_top[2][7:0])); // Templated
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
3. インスタンス名を接続信号名に使用
インスタンスが複数ある場合など、信号名にインスタンス名を付けて識別する必要がある。その場合は@"vl-cell-name"
でインスタンス名を信号名に含める事ができる。
.\(*\) (@"vl-cell-name"_\1)
module top
(
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
/*AUTOWIRE*/
/* sub1 AUTO_TEMPLATE (
.i_sig_\(.*\) (i_\1[][]),
.o_sig_\(.*\) (w_\1_@"vl-cell-name"[][]),
) */
sub1 inst0_sub1
( /*AUTOINST*/);
sub1 inst1_sub1
( /*AUTOINST*/);
/* sub2 AUTO_TEMPLATE (
.i_sig_\(.*\) (w_\1_inst0_sub1[][]),
.o_sig_\(.*\) (o_\1_@"vl-cell-name"[][]),
) */
sub2 inst0_sub2
( /*AUTOINST*/);
/* sub2 AUTO_TEMPLATE (
.i_sig_\(.*\) (w_\1_inst1_sub1[][]),
.o_sig_\(.*\) (o_\1_@"vl-cell-name"[][]),
) */
sub2 inst1_sub2
( /*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
自動接続実行結果
module top
(
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input i_a, // To inst0_sub1 of sub1.v, ...
input [1:0] i_b, // To inst0_sub1 of sub1.v, ...
input [0:2] [7:0] i_c, // To inst0_sub1 of sub1.v, ...
input [7:0] i_d [3], // To inst0_sub1 of sub1.v, ...
// End of automatics
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output o_i_inst0_sub2, // From inst0_sub2 of sub2.v
output o_i_inst1_sub2, // From inst1_sub2 of sub2.v
output [1:0] o_j_inst0_sub2, // From inst0_sub2 of sub2.v
output [1:0] o_j_inst1_sub2, // From inst1_sub2 of sub2.v
output [0:2] [7:0] o_k_inst0_sub2, // From inst0_sub2 of sub2.v
output [0:2] [7:0] o_k_inst1_sub2, // From inst1_sub2 of sub2.v
output [7:0] o_l_inst0_sub2 [3], // From inst0_sub2 of sub2.v
output [7:0] o_l_inst1_sub2 [3] // From inst1_sub2 of sub2.v
// End of automatics
);
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire w_e_inst0_sub1; // From inst0_sub1 of sub1.v
wire w_e_inst1_sub1; // From inst1_sub1 of sub1.v
wire [1:0] w_f_inst0_sub1; // From inst0_sub1 of sub1.v
wire [1:0] w_f_inst1_sub1; // From inst1_sub1 of sub1.v
wire [0:2] [7:0] w_g_inst0_sub1; // From inst0_sub1 of sub1.v
wire [0:2] [7:0] w_g_inst1_sub1; // From inst1_sub1 of sub1.v
wire [7:0] w_h_inst0_sub1 [3]; // From inst0_sub1 of sub1.v
wire [7:0] w_h_inst1_sub1 [3]; // From inst1_sub1 of sub1.v
// End of automatics
/* sub1 AUTO_TEMPLATE (
.i_sig_\(.*\) (i_\1[][]),
.o_sig_\(.*\) (w_\1_@"vl-cell-name"[][]),
) */
sub1 inst0_sub1
( /*AUTOINST*/
// Outputs
.o_sig_e (w_e_inst0_sub1), // Templated
.o_sig_f (w_f_inst0_sub1[1:0]), // Templated
.o_sig_g (w_g_inst0_sub1/*[0:2][7:0]*/), // Templated
.o_sig_h (w_h_inst0_sub1/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_a (i_a), // Templated
.i_sig_b (i_b[1:0]), // Templated
.i_sig_c (i_c/*[0:2][7:0]*/), // Templated
.i_sig_d (i_d/*[7:0].[3]*/)); // Templated
sub1 inst1_sub1
( /*AUTOINST*/
// Outputs
.o_sig_e (w_e_inst1_sub1), // Templated
.o_sig_f (w_f_inst1_sub1[1:0]), // Templated
.o_sig_g (w_g_inst1_sub1/*[0:2][7:0]*/), // Templated
.o_sig_h (w_h_inst1_sub1/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_a (i_a), // Templated
.i_sig_b (i_b[1:0]), // Templated
.i_sig_c (i_c/*[0:2][7:0]*/), // Templated
.i_sig_d (i_d/*[7:0].[3]*/)); // Templated
/* sub2 AUTO_TEMPLATE (
.i_sig_\(.*\) (w_\1_inst0_sub1[][]),
.o_sig_\(.*\) (o_\1_@"vl-cell-name"[][]),
) */
sub2 inst0_sub2
( /*AUTOINST*/
// Outputs
.o_sig_i (o_i_inst0_sub2), // Templated
.o_sig_j (o_j_inst0_sub2[1:0]), // Templated
.o_sig_k (o_k_inst0_sub2/*[0:2][7:0]*/), // Templated
.o_sig_l (o_l_inst0_sub2/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_e (w_e_inst0_sub1), // Templated
.i_sig_f (w_f_inst0_sub1[1:0]), // Templated
.i_sig_g (w_g_inst0_sub1/*[0:2][7:0]*/), // Templated
.i_sig_h (w_h_inst0_sub1/*[7:0].[3]*/)); // Templated
/* sub2 AUTO_TEMPLATE (
.i_sig_\(.*\) (w_\1_inst1_sub1[][]),
.o_sig_\(.*\) (o_\1_@"vl-cell-name"[][]),
) */
sub2 inst1_sub2
( /*AUTOINST*/
// Outputs
.o_sig_i (o_i_inst1_sub2), // Templated
.o_sig_j (o_j_inst1_sub2[1:0]), // Templated
.o_sig_k (o_k_inst1_sub2/*[0:2][7:0]*/), // Templated
.o_sig_l (o_l_inst1_sub2/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_e (w_e_inst1_sub1), // Templated
.i_sig_f (w_f_inst1_sub1[1:0]), // Templated
.i_sig_g (w_g_inst1_sub1/*[0:2][7:0]*/), // Templated
.i_sig_h (w_h_inst1_sub1/*[7:0].[3]*/)); // Templated
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
3-1 インスタンス名の後半の文字列を使用
インスタンス名すべてではなく、インスタンス名の一部を信号名に含めたい場合がある。その場合、vl-cell-name
にsubstring
を適用する。
.\(*\) (@"(substring vl-cell-name N)"_\1)
ここでNは数字で、
Nがプラスの場合、インスタンス文字列から、 「先頭から」 数えた文字数を 「削除した」 文字列
Nがマイナスの場合、インスタンス文字列から、 「後ろから」 数えた文字数を 「取得した」 文字列
となる。
module top
(
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
/*AUTOWIRE*/
/* sub1 AUTO_TEMPLATE (
.i_sig_\(.*\) (i_\1[][]),
.o_sig_\(.*\) (w_\1_@"(substring vl-cell-name -2)"[][]),
) */
sub1 sub1_i0
( /*AUTOINST*/);
sub1 sub1_i1
( /*AUTOINST*/);
/* sub2 AUTO_TEMPLATE (
.i_sig_\(.*\) (w_\1_i0[][]),
.o_sig_\(.*\) (o_\1_@"(substring vl-cell-name 5)"[][]),
) */
sub2 sub2_i0
( /*AUTOINST*/);
/* sub2 AUTO_TEMPLATE (
.i_sig_\(.*\) (w_\1_i1[][]),
.o_sig_\(.*\) (o_\1_@"(substring vl-cell-name 5)"[][]),
) */
sub2 sub2_i1
( /*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
自動接続実行結果
module top
(
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input i_a, // To sub1_i0 of sub1.v, ...
input [1:0] i_b, // To sub1_i0 of sub1.v, ...
input [0:2] [7:0] i_c, // To sub1_i0 of sub1.v, ...
input [7:0] i_d [3], // To sub1_i0 of sub1.v, ...
// End of automatics
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output o_i_i0, // From sub2_i0 of sub2.v
output o_i_i1, // From sub2_i1 of sub2.v
output [1:0] o_j_i0, // From sub2_i0 of sub2.v
output [1:0] o_j_i1, // From sub2_i1 of sub2.v
output [0:2] [7:0] o_k_i0, // From sub2_i0 of sub2.v
output [0:2] [7:0] o_k_i1, // From sub2_i1 of sub2.v
output [7:0] o_l_i0 [3], // From sub2_i0 of sub2.v
output [7:0] o_l_i1 [3] // From sub2_i1 of sub2.v
// End of automatics
);
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire w_e_i0; // From sub1_i0 of sub1.v
wire w_e_i1; // From sub1_i1 of sub1.v
wire [1:0] w_f_i0; // From sub1_i0 of sub1.v
wire [1:0] w_f_i1; // From sub1_i1 of sub1.v
wire [0:2] [7:0] w_g_i0; // From sub1_i0 of sub1.v
wire [0:2] [7:0] w_g_i1; // From sub1_i1 of sub1.v
wire [7:0] w_h_i0 [3]; // From sub1_i0 of sub1.v
wire [7:0] w_h_i1 [3]; // From sub1_i1 of sub1.v
// End of automatics
/* sub1 AUTO_TEMPLATE (
.i_sig_\(.*\) (i_\1[][]),
.o_sig_\(.*\) (w_\1_@"(substring vl-cell-name -2)"[][]),
) */
sub1 sub1_i0
( /*AUTOINST*/
// Outputs
.o_sig_e (w_e_i0), // Templated
.o_sig_f (w_f_i0[1:0]), // Templated
.o_sig_g (w_g_i0/*[0:2][7:0]*/), // Templated
.o_sig_h (w_h_i0/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_a (i_a), // Templated
.i_sig_b (i_b[1:0]), // Templated
.i_sig_c (i_c/*[0:2][7:0]*/), // Templated
.i_sig_d (i_d/*[7:0].[3]*/)); // Templated
sub1 sub1_i1
( /*AUTOINST*/
// Outputs
.o_sig_e (w_e_i1), // Templated
.o_sig_f (w_f_i1[1:0]), // Templated
.o_sig_g (w_g_i1/*[0:2][7:0]*/), // Templated
.o_sig_h (w_h_i1/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_a (i_a), // Templated
.i_sig_b (i_b[1:0]), // Templated
.i_sig_c (i_c/*[0:2][7:0]*/), // Templated
.i_sig_d (i_d/*[7:0].[3]*/)); // Templated
/* sub2 AUTO_TEMPLATE (
.i_sig_\(.*\) (w_\1_i0[][]),
.o_sig_\(.*\) (o_\1_@"(substring vl-cell-name 5)"[][]),
) */
sub2 sub2_i0
( /*AUTOINST*/
// Outputs
.o_sig_i (o_i_i0), // Templated
.o_sig_j (o_j_i0[1:0]), // Templated
.o_sig_k (o_k_i0/*[0:2][7:0]*/), // Templated
.o_sig_l (o_l_i0/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_e (w_e_i0), // Templated
.i_sig_f (w_f_i0[1:0]), // Templated
.i_sig_g (w_g_i0/*[0:2][7:0]*/), // Templated
.i_sig_h (w_h_i0/*[7:0].[3]*/)); // Templated
/* sub2 AUTO_TEMPLATE (
.i_sig_\(.*\) (w_\1_i1[][]),
.o_sig_\(.*\) (o_\1_@"(substring vl-cell-name 5)"[][]),
) */
sub2 sub2_i1
( /*AUTOINST*/
// Outputs
.o_sig_i (o_i_i1), // Templated
.o_sig_j (o_j_i1[1:0]), // Templated
.o_sig_k (o_k_i1/*[0:2][7:0]*/), // Templated
.o_sig_l (o_l_i1/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_e (w_e_i1), // Templated
.i_sig_f (w_f_i1[1:0]), // Templated
.i_sig_g (w_g_i1/*[0:2][7:0]*/), // Templated
.i_sig_h (w_h_i1/*[7:0].[3]*/)); // Templated
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
3-2. インスタンス名中の数字を使用
インスタンス名から数字のみ取り出して信号名に含めたい場合には@
を使う。尚@
はインスタンス名中の最初の数字を参照する。
.\(*\) (@_\1)
module top
(
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
/*AUTOWIRE*/
/* sub1 AUTO_TEMPLATE (
.i_sig_\(.*\) (i_\1[][]),
.o_sig_\(.*\) (w_\1_i@[][]),
) */
sub1 inst0_sub1
( /*AUTOINST*/);
sub1 inst1_sub1
( /*AUTOINST*/);
/* sub2 AUTO_TEMPLATE (
.i_sig_\(.*\) (w_\1_i@[][]),
.o_sig_\(.*\) (o_\1_i@[][]),
) */
sub2 inst0_sub2
( /*AUTOINST*/);
sub2 inst1_sub2
( /*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
自動接続実行結果
module top
(
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input i_a, // To inst0_sub1 of sub1.v, ...
input [1:0] i_b, // To inst0_sub1 of sub1.v, ...
input [0:2] [7:0] i_c, // To inst0_sub1 of sub1.v, ...
input [7:0] i_d [3], // To inst0_sub1 of sub1.v, ...
// End of automatics
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output o_i_i0, // From inst0_sub2 of sub2.v
output o_i_i1, // From inst1_sub2 of sub2.v
output [1:0] o_j_i0, // From inst0_sub2 of sub2.v
output [1:0] o_j_i1, // From inst1_sub2 of sub2.v
output [0:2] [7:0] o_k_i0, // From inst0_sub2 of sub2.v
output [0:2] [7:0] o_k_i1, // From inst1_sub2 of sub2.v
output [7:0] o_l_i0 [3], // From inst0_sub2 of sub2.v
output [7:0] o_l_i1 [3] // From inst1_sub2 of sub2.v
// End of automatics
);
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire w_e_i0; // From inst0_sub1 of sub1.v
wire w_e_i1; // From inst1_sub1 of sub1.v
wire [1:0] w_f_i0; // From inst0_sub1 of sub1.v
wire [1:0] w_f_i1; // From inst1_sub1 of sub1.v
wire [0:2] [7:0] w_g_i0; // From inst0_sub1 of sub1.v
wire [0:2] [7:0] w_g_i1; // From inst1_sub1 of sub1.v
wire [7:0] w_h_i0 [3]; // From inst0_sub1 of sub1.v
wire [7:0] w_h_i1 [3]; // From inst1_sub1 of sub1.v
// End of automatics
/* sub1 AUTO_TEMPLATE (
.i_sig_\(.*\) (i_\1[][]),
.o_sig_\(.*\) (w_\1_i@[][]),
) */
sub1 inst0_sub1
( /*AUTOINST*/
// Outputs
.o_sig_e (w_e_i0), // Templated
.o_sig_f (w_f_i0[1:0]), // Templated
.o_sig_g (w_g_i0/*[0:2][7:0]*/), // Templated
.o_sig_h (w_h_i0/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_a (i_a), // Templated
.i_sig_b (i_b[1:0]), // Templated
.i_sig_c (i_c/*[0:2][7:0]*/), // Templated
.i_sig_d (i_d/*[7:0].[3]*/)); // Templated
sub1 inst1_sub1
( /*AUTOINST*/
// Outputs
.o_sig_e (w_e_i1), // Templated
.o_sig_f (w_f_i1[1:0]), // Templated
.o_sig_g (w_g_i1/*[0:2][7:0]*/), // Templated
.o_sig_h (w_h_i1/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_a (i_a), // Templated
.i_sig_b (i_b[1:0]), // Templated
.i_sig_c (i_c/*[0:2][7:0]*/), // Templated
.i_sig_d (i_d/*[7:0].[3]*/)); // Templated
/* sub2 AUTO_TEMPLATE (
.i_sig_\(.*\) (w_\1_i@[][]),
.o_sig_\(.*\) (o_\1_i@[][]),
) */
sub2 inst0_sub2
( /*AUTOINST*/
// Outputs
.o_sig_i (o_i_i0), // Templated
.o_sig_j (o_j_i0[1:0]), // Templated
.o_sig_k (o_k_i0/*[0:2][7:0]*/), // Templated
.o_sig_l (o_l_i0/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_e (w_e_i0), // Templated
.i_sig_f (w_f_i0[1:0]), // Templated
.i_sig_g (w_g_i0/*[0:2][7:0]*/), // Templated
.i_sig_h (w_h_i0/*[7:0].[3]*/)); // Templated
sub2 inst1_sub2
( /*AUTOINST*/
// Outputs
.o_sig_i (o_i_i1), // Templated
.o_sig_j (o_j_i1[1:0]), // Templated
.o_sig_k (o_k_i1/*[0:2][7:0]*/), // Templated
.o_sig_l (o_l_i1/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_e (w_e_i1), // Templated
.i_sig_f (w_f_i1[1:0]), // Templated
.i_sig_g (w_g_i1/*[0:2][7:0]*/), // Templated
.i_sig_h (w_h_i1/*[7:0].[3]*/)); // Templated
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
3-3. インスタンス名の最後に現れる数字を使用
最初の数字ではなくて最後の数字を参照したい場合、"\([0-9]+\)$"
を設定して@
を使う。
尚、すでに紹介したsubstring
っても同様の事ができる。
module top
(
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
/*AUTOWIRE*/
/* sub1 AUTO_TEMPLATE "\([0-9]+\)$" (
.i_sig_\(.*\) (i_\1[][]),
.o_sig_\(.*\) (w_\1_i@[][]),
) */
sub1 sub1_inst0
( /*AUTOINST*/);
sub1 sub1_inst1
( /*AUTOINST*/);
/* sub2 AUTO_TEMPLATE "\([0-9]+\)$" (
.i_sig_\(.*\) (w_\1_i@[][]),
.o_sig_\(.*\) (o_\1_i@[][]),
) */
sub2 sub2_inst0
( /*AUTOINST*/);
sub2 sub2_inst1
( /*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
自動接続実行結果
module top
(
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input i_a, // To sub1_inst0 of sub1.v, ...
input [1:0] i_b, // To sub1_inst0 of sub1.v, ...
input [0:2] [7:0] i_c, // To sub1_inst0 of sub1.v, ...
input [7:0] i_d [3], // To sub1_inst0 of sub1.v, ...
// End of automatics
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output o_i_i0, // From sub2_inst0 of sub2.v
output o_i_i1, // From sub2_inst1 of sub2.v
output [1:0] o_j_i0, // From sub2_inst0 of sub2.v
output [1:0] o_j_i1, // From sub2_inst1 of sub2.v
output [0:2] [7:0] o_k_i0, // From sub2_inst0 of sub2.v
output [0:2] [7:0] o_k_i1, // From sub2_inst1 of sub2.v
output [7:0] o_l_i0 [3], // From sub2_inst0 of sub2.v
output [7:0] o_l_i1 [3] // From sub2_inst1 of sub2.v
// End of automatics
);
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire w_e_i0; // From sub1_inst0 of sub1.v
wire w_e_i1; // From sub1_inst1 of sub1.v
wire [1:0] w_f_i0; // From sub1_inst0 of sub1.v
wire [1:0] w_f_i1; // From sub1_inst1 of sub1.v
wire [0:2] [7:0] w_g_i0; // From sub1_inst0 of sub1.v
wire [0:2] [7:0] w_g_i1; // From sub1_inst1 of sub1.v
wire [7:0] w_h_i0 [3]; // From sub1_inst0 of sub1.v
wire [7:0] w_h_i1 [3]; // From sub1_inst1 of sub1.v
// End of automatics
/* sub1 AUTO_TEMPLATE "\([0-9]+\)$" (
.i_sig_\(.*\) (i_\1[][]),
.o_sig_\(.*\) (w_\1_i@[][]),
) */
sub1 sub1_inst0
( /*AUTOINST*/
// Outputs
.o_sig_e (w_e_i0), // Templated
.o_sig_f (w_f_i0[1:0]), // Templated
.o_sig_g (w_g_i0/*[0:2][7:0]*/), // Templated
.o_sig_h (w_h_i0/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_a (i_a), // Templated
.i_sig_b (i_b[1:0]), // Templated
.i_sig_c (i_c/*[0:2][7:0]*/), // Templated
.i_sig_d (i_d/*[7:0].[3]*/)); // Templated
sub1 sub1_inst1
( /*AUTOINST*/
// Outputs
.o_sig_e (w_e_i1), // Templated
.o_sig_f (w_f_i1[1:0]), // Templated
.o_sig_g (w_g_i1/*[0:2][7:0]*/), // Templated
.o_sig_h (w_h_i1/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_a (i_a), // Templated
.i_sig_b (i_b[1:0]), // Templated
.i_sig_c (i_c/*[0:2][7:0]*/), // Templated
.i_sig_d (i_d/*[7:0].[3]*/)); // Templated
/* sub2 AUTO_TEMPLATE "\([0-9]+\)$" (
.i_sig_\(.*\) (w_\1_i@[][]),
.o_sig_\(.*\) (o_\1_i@[][]),
) */
sub2 sub2_inst0
( /*AUTOINST*/
// Outputs
.o_sig_i (o_i_i0), // Templated
.o_sig_j (o_j_i0[1:0]), // Templated
.o_sig_k (o_k_i0/*[0:2][7:0]*/), // Templated
.o_sig_l (o_l_i0/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_e (w_e_i0), // Templated
.i_sig_f (w_f_i0[1:0]), // Templated
.i_sig_g (w_g_i0/*[0:2][7:0]*/), // Templated
.i_sig_h (w_h_i0/*[7:0].[3]*/)); // Templated
sub2 sub2_inst1
( /*AUTOINST*/
// Outputs
.o_sig_i (o_i_i1), // Templated
.o_sig_j (o_j_i1[1:0]), // Templated
.o_sig_k (o_k_i1/*[0:2][7:0]*/), // Templated
.o_sig_l (o_l_i1/*[7:0].[3]*/), // Templated
// Inputs
.i_sig_e (w_e_i1), // Templated
.i_sig_f (w_f_i1[1:0]), // Templated
.i_sig_g (w_g_i1/*[0:2][7:0]*/), // Templated
.i_sig_h (w_h_i1/*[7:0].[3]*/)); // Templated
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
4. System Verilog対応
多次元配列など既にSystem Verilogで導入されたものも既に使っていたが、それ以外のSystem Verilogで導入されたtypedef, interfaceおよびlogicにも対応している。
4-1. structやunion等でtypedefを使う場合
structやunion等、信号にtypedefを適用した場合でも問題なく自動接続をする事ができる。但しその場合、verilog-typedef-regexp
で、文字列がtypedefで定義したタイプ名である事を指定する必要がある。
以下の例ではverilog-typedef-regexp:"_t$"
と、_t
で終わる文字列をtypedefで定義したタイプ名だという事をしていている。この設定はtop.svと下位モジュールファイルのsub1.svおよびsub2.svの両方に必要となる。
尚、Emacs verilog-modeで処理するにあたり、通常はpackage内にあるtypedefで定義している内容自体のファイルは必要ない。何故ならEmacs verilog-modeは単にテキスト処理を行っているに過ぎず、その内容自体には感知しないからである。
module top import my_pkg::*;
(
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
/*AUTOWIRE*/
sub1 s1
( /*AUTOINST*/);
sub2 s2
( /*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24
// verilog-typedef-regexp:"_t$"
// indent-tabs-mode:nil
// End:
module sub1 import my_pkg::*;
(
input my_t sig_a,
input lib_pkg::our_t sig_b,
input my_t [0:2] sig_c,
input my_t sig_d[3],
output my_t sig_e
output lib_pkg::our_t sig_f,
output my_t [0:2] sig_g,
output my_t sig_h[3]
);
endmodule
// Local Variables:
// verilog-typedef-regexp:"_t$"
// End:
module sub2 import my_pkg::*;
(
input my_t sig_e,
input lib_pkg::our_t sig_f,
input my_t [0:2] sig_g,
input my_t sig_h[3],
output my_t sig_i
output lib_pkg::our_t sig_j,
output my_t [0:2] sig_k,
output my_t sig_l[3]
);
endmodule
// Local Variables:
// verilog-typedef-regexp:"_t$"
// End:
自動接続実行結果
module top import my_pkg::*;
(
/*AUTOINPUT*/
// Beginning of automatic inputs (from unused autoinst inputs)
input my_t sig_a, // To s1 of sub1.v
input lib_pkg::our_t sig_b, // To s1 of sub1.v
input my_t [0:2] sig_c, // To s1 of sub1.v
input my_t sig_d [3], // To s1 of sub1.v
// End of automatics
/*AUTOOUTPUT*/
// Beginning of automatic outputs (from unused autoinst outputs)
output my_t sig_i, // From s2 of sub2.v
output lib_pkg::our_t sig_j, // From s2 of sub2.v
output my_t [0:2] sig_k, // From s2 of sub2.v
output my_t sig_l [3] // From s2 of sub2.v
// End of automatics
);
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
my_t sig_e; // From s1 of sub1.v
lib_pkg::our_t sig_f; // From s1 of sub1.v
my_t [0:2] sig_g; // From s1 of sub1.v
my_t sig_h [3]; // From s1 of sub1.v
// End of automatics
sub1 s1
( /*AUTOINST*/
// Outputs
.sig_e (sig_e),
.sig_f (sig_f),
.sig_g (sig_g[0:2]),
.sig_h (sig_h/*.[3]*/),
// Inputs
.sig_a (sig_a),
.sig_b (sig_b),
.sig_c (sig_c[0:2]),
.sig_d (sig_d/*.[3]*/));
sub2 s2
( /*AUTOINST*/
// Outputs
.sig_i (sig_i),
.sig_j (sig_j),
.sig_k (sig_k[0:2]),
.sig_l (sig_l/*.[3]*/),
// Inputs
.sig_e (sig_e),
.sig_f (sig_f),
.sig_g (sig_g[0:2]),
.sig_h (sig_h/*.[3]*/));
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24
// verilog-typedef-regexp:"_t$"
// indent-tabs-mode:nil
// End:
正規表現では、$
は“~で終わる”文字列、^
は“~で始まる”文字列を表す。(<AAA>|<BBB>)
はAAAまたはBBBを表す。なので例えば
// verilog-typedef-regexp:"\\(_t$\\|_st$\\|_e$\\|^t_\\)"
とすると、???_t
, ???_st
, ???_e
, t_???
の文字列がtypedefである事を指定する。この様に(
, |
, )
には\\
のエスケープ文字が必要。
注意が必要なのはこの文字列が信号名等に含まれているとそれらをtypedefだと誤認識してしまう。なのでこの例ではsig_e
をタイプ名と誤認する。また、^t_
はt_
で始まる文字列なので、lib_pkg::t_our
の様に前にpackage名を明示的に指定していた入りするとt_our
をtypedefだと正しく認識しない。
4-2. interfaceを使う場合
interface
を取り扱う事も可能。但し対応しているのは/*AUTOINST*/
でのインスタンスポートの接続部分のみ/*AUTOINPUT*/
, /*AUTOOUTPUT*/
および/*AUTOWIRE*/
に対応した/*AUTOINTERFACE*/
の様なものはない。なのでtopでのinterfaceポート宣言およびインスタンス宣言はマニュアルでやる必要がある。
typedefと違い、何か特定の文字列を認識させる必要はなく自動でinterfaceとして認識する。逆に、typedefで定義したタイプとし認識させたいのにうまく行っていないと、interfaceとして認識される。
以下の様にsub1.svではmodport指定無しの場合と有りの場合、sub2.svではgeneric interfaceの場合にしてある。modport指定がされていればtopでそのmodport名を指定して接続される。指定がなければ指定無しで接続される。generic portはinterfaceがインスタンス化されているtopでのmodportを指定しての接続は必須だが、そのままではmodport指定無しで接続されてしまう。なので/* sub2 AUTO_TEMPLATE ( .if_int (if_int.slv), ) */
でmodport名を指定するようにAUTO_TEMPLATEで指定している。或いはどうせinterfaceのインスタンス化自体マニュアルでしかできないので、AUTO_TEMPLATEで指定せずとも、接続もマニュアルでやってしまっても良いかもしれない。どちらの手間もほぼ同じだ。
尚、interfaceもtypedefと同様に、その内容自体は感知する必要ないのでinterfaceの定義自体のファイルは不要である。
module top
(
// Manual
in_if if_i,
out_if if_o
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
/*AUTOWIRE*/
// Manual Instantiation
int_if if_int();
sub1 s1
( /*AUTOINST*/);
/* sub2 AUTO_TEMPLATE ( .if_int (if_int.slv), ) */
sub2 s2
( /*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
module sub1 (
in_if if_i , // Without modport
int_if.mst if_int // With modport
);
endmodule
module sub2 (
interface if_int, // Generic Interface
interface if_o // Generic Interface
);
endmodule
自動接続実行結果
module top
(
// Manual
in_if if_i,
out_if if_o
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
/*AUTOWIRE*/
// Manual Instantiation
int_if if_int();
sub1 s1
( /*AUTOINST*/
// Interfaces
.if_i (if_i),
.if_int (if_int.mst));
/* sub2 AUTO_TEMPLATE ( .if_int (if_int.slv), ) */
sub2 s2
( /*AUTOINST*/
// Interfaces
.if_int (if_int.slv), // Templated
.if_o (if_o));
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
4-3. wireに代わってlogicを使用
SystemVerilogでは結線信号の宣言にwireの代わりにlogicも使えるようになった。Emacs verilog-modeではそれにも対応している。logicを使いたい場合には以下2通りの方法がある。
a) verilog-auto-wire-type:"logic"を使用
module top (
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
/*AUTOWIRE*/
sub1 s1(
/*AUTOINST*/);
sub2 s2(
/*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// verilog-auto-wire-type:"logic"
// indent-tabs-mode:nil
// End:
自動結線(/*AUTOWIRE*/の部分のみ抜粋)
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
logic sig_e; // From s1 of sub1.v
logic [1:0] sig_f; // From s1 of sub1.v
logic [0:2] [7:0] sig_g; // From s1 of sub1.v
logic [7:0] sig_h [3]; // From s1 of sub1.v
// End of automatics
b) /*AUTOLOGIC*/を使用
module top (
/*AUTOINPUT*/
/*AUTOOUTPUT*/
);
/*AUTOLOGIC*/
sub1 s1(
/*AUTOINST*/);
sub2 s2(
/*AUTOINST*/);
endmodule
// Local Variables:
// verilog-library-flags:("-y ./sub")
// verilog-auto-inst-column:24 ;; Min. 24?
// indent-tabs-mode:nil
// End:
自動結線(/*AUTOLOGIC*/の部分のみ抜粋)
/*AUTOLOGIC*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
logic sig_e; // From s1 of sub1.v
logic [1:0] sig_f; // From s1 of sub1.v
logic [0:2] [7:0] sig_g; // From s1 of sub1.v
logic [7:0] sig_h [3]; // From s1 of sub1.v
// End of automatics
良く使う設定
既にいくつか設定を紹介したが、それらを含めてその他以下が良く使うであろう設定を紹介しておく。:nilで設定を無効化、:t等他の文字列で設定を有効化。
-
verilog-library-flags
下位モジュールのファイルがあるディレクトリを-yで指定。(-y dir1 -y dir2 ...)の様に指定。 -
verilog-library-directories
同じく下位モジュールのディレクトを指定。("." "dir1" "dir2" ...)の様に指定。 -
verilog-library-files
これも別の下位モジュールの指定方法。ディレクトリではなくファイルパスで直接指定。("/path/technology.v" "/path2/tech2.v")の様に指定。 -
verilog-typedef-regexp
説明した通りtypedefを使う場合に使用。 -
verilog-auto-inst-column
AUTOINSTでインデント位置の調整。何故か24が最小値っぽい。 -
verilog-auto-inst-vector
AUTOINSTの際の信号の接続に信号幅[X:Y]を含めるか含めないかの指定。nilで含めない設定。但しマニュアルでinput, ouput, wire宣言した信号に対してしか効かないみたい。 -
verilog-auto-inst-dot-name
AUTOINSTで、System Verilogの.port name
スタイルで接続。ベクター信号や多次元配列信号に対しては効かないみたい。マニュアルでinput, output, wireを宣言して上記verilog-auto-inst-vector:nilを設定した場合にはきちんと効く。 -
verilog-auto-inst-param-value
AUTOINSTでparameterで指定されている信号幅を数字に展開。 -
verilog-auto-wire-type
"logic"の指定でAUTOWIREでwireの代わりにlogicを使う。 -
indent-tabs-mode
タブをスペースに変換。Emacsではデフォルトだとタブを勝手に入れて来るのでそれが嫌な場合にnilを設定する。
その他の設定項目は公式のHelpページを参照。
実行サンプル環境
git clone https://github.com/AlphaLyrae0/Emacs_Verilog_Mode_Examples.git
でダウンロードの後
cd Emacs_Verilog_Mode_Examples
でダウンロードしたディレクトリに入る。
各サンプルの実行は以下。尚、最新のverilog-modeが自動でダウンロードされるようにしてある。
make auto_<Dir Name>
自動接続での接続を削除する場合には以下。
make delete_<Dir Name>
全てのサンプルの自動結線を一括で削除する場合は以下。
make delete
全てのサンプルの自動結線の削除に加えて、ダウンロードしたverilog-modeの削除も行い初期化する場合は以下。
make clean
参考サイト
https://www.veripool.org/verilog-mode/help/
https://www.veripool.org/verilog-mode-faq/
https://github.com/veripool/verilog-mode/blob/master/FAQ.rst
https://veripool.org/papers/verilog-mode_veritedium_20161211.pdf