本章では,簡単な例を用いて, ST記述の作成の仕方を説明する.
STでは,サイクルを単位として入力ベクタ,期待値を与えて行く.まず,同期クロックのない組み合わせ論理回路のテストベクタ作成の方法を学ぶ.次に同期クロックのある8ビットカウンタのテストベクタを作成する.最後に,与えられたVerilog記述からv2st.plを用いてSTのテンプレートを作成し,それを元にテストベクタを記述する方法を学ぶ.
最初に,組み合わせ論理回路の例として,簡単なALUを取り扱う.最初は, Verilog記述をシミュレーションする.次に,同じ回路をHSPICEでシミュレーションする.
取り扱うALUは4ビットのa, bを入力として,演算結果を5ビットのcに出力する.演算の種類は2ビットのfunc入力により切り替える.対応するVerilog-HDL記述はリスト6.1.1.1[alu.v]の通りとなる.このファイルは,配布パッケージのexample/alu/alu.vと同じである. funcの値と演算結果との対応は下記の通りとなる.
| funcの値 | cの出力値 |
| 0 | a+b |
| 1 | a-b |
| 2 | a&b |
| 3 | a|b |
`define ADD 0
`define SUB 1
`define AND 2
`define OR 3
module alu(c,a,b,func);
input [3:0] a,b;
output [4:0] c;
reg [4:0] c;
input [1:0] func;
always @(a or b or func)
begin
case(func)
`ADD:
c=a+b;
`SUB:
c=a-b;
`AND:
c=a&b;
`OR:
c=a|b;
endcase // case(func)
end // always @ (a or b or func)
endmodule
最初からSTファイルの書くのは面倒なので,すでに準備してあるalu.stを使う.
以上にテストベンチalu.stは下記の通りとなる.このファイルは,配布ファイルのexample/alu/alu.stである.
#!/usr/bin/perl use ST; target "verilog"; module "alu"; #shm "alu","AC"; vcd "alu",0; level 0,5,2,3; source "vdd","vh=5"; source "vss","vh=0"; pin "a[3:0]","input", "defval=0"; pin "b[3:0]","input", "defval=0"; pin "c[4:0]","output","defval=X"; pin "func[1:0]","input","defval=0"; timing 1e-09,100e-09,10; waveform "input","dnrz", "%.........","a","b","func"; waveform "output","edge","..........%","c"; pinorder "a","b","func","c"; beginvector; vector 7,3,0,10; # func=0なので加算 vector 7,2,0,9; # func=0なので加算 vector 5,3,1,5-3; # func=1なので, 減算 vector 6,2,2,6&2; # func=2なので, 論理積 vector 7,3,3,7|3; # func=3なので, 論理和 vector 7,2,0,10; # func=0なので加算.わざと間違い svector "a=7","b=3","c=7+3"; # svectorは"ピン名=値"で指定. # 記述してないピンはpinコマンドのdefvalの値が使われる. endvector;
#!/usr/bin/perl use ST; target "verilog"; module "alu"; vcd "alu",0;
先頭の5行は,上記の通りである.最初の行は, UNIXではお馴染の記述である.このように書くことで,このファイルに実効属性をつけて,このファイルを直接実行することができる. 2行目は, STのperlモジュールを呼び出すために必要となる. 3行目でターゲットとするシミュレータを指定する.ここでは, verilogを指定している. 4行目は, verilog固有の記述である.前節のverilog記述のmodule名はaluなので,ここではその名前を指定している.5行目は,verilogシミュレーション実行時の波形ファイルの出力形式と,ファイル名などを指定している.詳細は,節[vcdサブルーチン]を参照する.
その次に,HSPICEでシミュレーションするための3行が次のように記載されているが,これはHSPICEシミュレーションで詳しく説明する.
level 0,5,2,3; source "vdd","vh=5"; source "vss","vh=0";
次に, pinサブルーチンを用いて,ピンの名前と属性を指定する.最初の引数は,ピン名である.すべての入出力ピンは,多ビットのバスとなっている.多ビットのバスは, Verilog等で良く使われている"ピン名[MSB:LSB]"という書式で表す. 2番目の引数は,入出力の種類を表す.入力は, input,出力はoutput,双方向ピンはinoutとなる. 3番目の引数以降はオプションの定義を記述する."defval=値"はピンの入力値と期待値のデフォルト値を指定する.svectorサブルーチン出品の値が指定されないときにはこの値が用いられる.
pin "a[3:0]","input", "defval=0"; pin "b[3:0]","input", "defval=0"; pin "c[4:0]","output","defval=X"; pin "func[1:0]","input","defval=0";
次に,シミュレーションを行う周期等をtimingサブルーチ ンを用いて指定する. timingサブルーチンは次の3つの引数をとる.
timing 最小時間単位,シミュレーション周期,タイミング分割数;
最小時間単位とは, Verilogでは,シミュレーションの結果が出力されるさいの最小時間となる.具体的には, Verilogでの`timescale文の2番目の引数となる.詳しくはVerilogの文法の解説を参照せよ.ここでは, 1e-9(1ns)を指定する.後述するテストベクタは周期毎に記述する.シミュレーション周期は,このテストベクタを投入する周期を記述する.タイミング分割数とは,後述する周期内の波形記述で,周期内をいくつに分割してタイミングを記述するかを指定する.ここでは,下記の通り記述している.
timing 1e-9,100e-9,10
これで,周期は100ns(100e-9),この周期を10分割して, 10ns毎に周期内の波形を記述することを表す.このように記述すると, Verilog用のテストベンチの先頭行には,下記のように`timescaleコマンドが出力される.
`timescale 10ns / 1ns
次に, 1周期内でどのように入力波形を与えるかと,どこで出力値を見るかをwaveformサブルーチンを用いて記述する.ここでは下記の通り指定する.
waveform "input","dnrz", "%.........","a","b","func"; waveform "output","edge","..........%","c";
この指定により,入力ピンは, 1周期の最初に0, 1が変化する.また,出力ピンcは,最初に"."が10個並び,その後に"%"が続いている.100nsの周期のうち10分割目である100nsのところで,出力値と期待値の比較を行う.詳しくは, waveformサブルーチンのところを参照せよ.
次に, pinorderサブルーチンにより,テストベクタを記述する順番を指定する.
pinorder "a","b","func","c";
上記のように指定することで, a, b, func, cの順にテストベクタを記述していくこととなる.
次に, 1周期毎にテストベクタを記述する.テストベクタは, beginvector, endvectorサブルーチンの間にvectorサブルーチンを用いて記述する.もちろん,出力ピンに対する値は,期待値となる. svectorサブルーチンを用いると,"ピン名=値"でpinorderの定義順と関係なくピンの入力値と期待値値を設定できる.設定していないピンはpinコマンドのdefvalで指定した値となる.
beginvector; vector 7,3,0,10; # func=0なので加算 vector 7,2,0,9; # func=0なので加算 vector 5,3,1,5-3; # func=1なので, 減算 vector 6,2,2,6&2; # func=2なので, 論理積 vector 7,3,3,7|3; # func=3なので, 論理和 svector "a=7","b=3","c=7+3"; # svectorは"ピン名=値"で指定. # 記述してないピンはpinコマンドのdefvalの値が使われる. endvector;
vectorコマンド1行で,1サイクルの入力ベクタと期待値となる.さきほどのpinorderサブルーチンで指定した順に, vectorサブルーチンの引数に入力値と期待値を記述していく. vectorサブルーチンの引数で,変数を使ったり演算を行ったりすることができる.ここでは,期待値は,演算結果ではなく,入力式そのものを使用している.
次に,作成したSTファイルalu.stを用いてverilog用のテストベンチを作成する. UNIXのコマンドラインで,下記を実行する.
# examples/alu/に移動する. % chmod +x alu.st % ./alu.st > alutest.v
これで, verilog用のalutest.vというテストベンチが作成される.
次にverilogシミュレータを用いてシミュレーションを行う.ここでは, GPLライセンスにより,無償で利用可能なiverilog (http://iverilog.icarus.com/)を用いる.STは, Verilogの標準的な文法しか用いていないため, Cadence社のxmverilogや,Synopsys社のvcs等の商用のVerilogシミュレータでも問題なく動作する.
下記を実行する.
% iverilog -o alutestrtl alutest.v alu.v # -oで実行ファイル名を指定. % ./alutestrtl
Cadence社のxmverilogを使う場合は,下記のとおり実行する.
% xmverilog -l alutestrtl.log +access+r alutest.v alu.v
すると, iverilogでは次のような結果が返ってくる.
VCD info: dumpfile alu.vcd opened for output. Some simulation mismatches are detected!
上記のメッセージのうち
Some simulation mismatches are detected!
というメッセージは,期待値とシミュレーション結果がどこかで一致していないことを表す.その具体的な結果はalu_st.logに下記のとおりに出力される.デフォルトでは, "module名_st.log"もしくはverilog_logfileで指定したファイルに出力される.
cycle(time): pin: sim. result != exp val
6(600): c: 0x9!=0xa
上記の通り,6サイクル目(最初は0サイクル)の"vector 7,2,0,10;"で指定した期待値が誤っていることが分かる.
試しに,期待値を変更して,テストベンチを作り直し,再びシミュレーションしてみよ.今度は,
No simulation mismatches is detected!
というメッセージが返ってくるはずである.
ST記述のうち,
vcd "alu",0;
という記述により,シミュレーション時の各ノードの波形がalu.vcdというファイルに格納される. gtkwave (http://gtkwave.sourceforge.net/)という波形表示プログラムを用いて,このファイルを参照する.
% gtkwave alu.vcd
なお,Cadence社のxmverilogを用いる場合は,vcdサブルーチンよりもshmサブルーチンを用いてshm形式で出力し,simvisionで波形ファイルを表示したほうが高速に波形表示ができる.
次にネットリストでのシミュレーションを行う.配布パッケージに, alunet.v(ALUのネットリスト)と, subcircuit.v(Verilogライブラリ)が格納されている.これらを用いて,ネットリストでのシミュレーションを行う.
% iverilog -o alutestnet alutest.v alunet.v -v \
../verilog/subcircuit.v
% ./alutestnet > alutestnet.log
STは, SDF(Standard Delay Format)ファイルを使ったシミュレーションも簡単に行えるようにサブルーチンを用意している.配布パッケージに, examples/alu/alunet.sdfという, alunet.vのSDFが用意されている.このファイルを用いて,遅延を考慮したシミュレーションを行うために,
sdf "alunet.sdf";
という記述を加えたalusdf.stを用意している.これを用いてテストベンチを作り,シミュレーションを実行し,波形を表示してみよう.ただし,iverilogはsdfに対応していないため,Cadence社のxmverilogを用いる.
% xmverilog -l alutest_net_sdf.log +define+SDF +access+r \
alutestsdf.v alunet.v ../verilog/subcircuit.v
+define+SDFを付加しないと,SDFは有効とならない.テストベンチを変更せずに,SDFなしとSDFありのシミュレーションを可能とするために,このような仕様としている.
alusdf.stでは,vcdコマンドを"vcd "alu",0;"としており,波形はalu.vcdに出力される.先ほどと同様に,gtkwaveを用いて,alu.vcdの波形を表示してみよう.図6.1.4.3.1[SDF付きシミュレーションの結果]の通り,出力Cがシミュレーション冒頭では不定値(X)で変化するのに時間がかかっているのがわかる.
STは汎用のテストベンチ作成ツールである.さきほどはVerilogを用いた論理レベルのシミュレーションだが,同じテストベンチを用いて, SPICE用のテストベンチも作成することができる.
上記ALUのSPICE用ネットリストをリスト6.1.5.1.1[aluのSPICEネットリスト]に示す.
$ Spice netlist generated by v2lvs
$ v2012.3_31.26 Wed Oct 3 10:56:20 PDT 2012
.INCLUDE "../spice/subcircuit.cir"
.SUBCKT alu c[4] c[3] c[2] c[1] c[0] a[3] a[2] a[1] a[0] b[3] b[2] b[1] \
b[0]
+ func[1] func[0]
XU33 a[0] net726 n217 and2
XU34 n175 func[0] func[1] cell215net482 and3
XU35 n194 n177 n170 or2
XU36 func[1] func[0] n174 n189 n129 aoi31
XU37 n129 c[2] inv1
XU38 func[1] func[0] n173 n187 n130 aoi31
XU39 n130 c[1] inv1
XU40 b[0] func[1] func[0] n186 n131 aoi31
XU41 n131 c[0] inv1
XU42 a[0] cell215net510 inv1
XU43 n210 n218 buf1
XU44 func[0] net686 inv1
XU45 func[0] cell215net515 inv1
XU46 func[0] b[1] n195 xnor2
XU47 n133 n141 buf2
XU48 net643 n207 n206 nand2
XU49 n149 n150 func[1] n148 sel21
XU50 cell215net482 cell215net483 c[3] or2
XU51 n148 cell215net483 inv1
XU52 a[3] b[3] n149 nand2
XU53 n153 n138 n150 xnor2
XU54 n134 n138 buf1
XU55 n154 n139 n134 and2
XU56 n135 n139 buf2
XU57 cell215net559 net590 net594 n139 cell215net565 oai23
XU58 n137 n136 n135 nand2
XU59 a[3] n136 inv4
XU60 n144 n143 n137 xnor2
XU61 b[3] n143 inv4
XU62 func[0] n144 inv4
XU63 n145 n147 n154 or2
XU64 n146 n147 buf4
XU65 n145 n147 cell215net498 or2
XU66 n142 n152 n146 xnor2
XU67 b[3] n152 inv4
XU68 func[0] n142 inv4
XU69 n142 net615 cell215net509 xnor2
XU70 a[3] n145 inv1
XU71 n151 n153 buf1
XU72 n132 n151 inv1
XU73 net602 net594 n140 n141 n132 aoi31
XU74 net632 n133 inv1
XU75 cell215net495 n140 buf1
XU76 net754 net646 net643 cell215net547 cell215net495 oai23
XU77 func[1] cell215net488 inv1
XU78 n211 n155 buf1
XU79 n168 n156 buf1
XU80 net646 cell215net509 n157 or2
XU81 net789 n158 n184 xnor2
XU82 b[1] n158 inv4
XU83 func[0] net789 inv4
XU84 a[0] net646 inv2
XU85 cell215net509 net754 buf4
XU86 net686 n160 n159 xor2
XU87 n165 n160 inv1
XU88 a[2] n177 inv1
XU89 cell215net493 net750 inv1
XU90 n197 n195 cell215net493 nand2
XU91 n201 n161 inv1
XU92 n161 n162 inv1
XU93 net742 n163 n207 or2
XU94 func[0] net742 inv1
XU95 net754 cell215net510 n163 and2
XU96 n169 n164 inv1
XU97 n164 n165 inv1
XU98 a[0] net647 inv1
XU99 net726 a[0] n209 or2
XU100 net754 net726 inv1
XU101 n162 n166 inv1
XU102 n166 n167 inv1
XU103 func[0] b[2] n168 xnor2
XU104 n214 n169 inv1
XU105 n199 n214 buf2
XU106 n179 n171 inv1
XU107 n171 n172 inv1
XU108 b[1] a[1] n173 or2
XU109 b[2] a[2] n174 or2
XU110 b[3] a[3] n175 or2
XU111 n172 n176 inv1
XU112 n182 n208 n178 and2
XU113 net590 cell215net559 n179 nor2
XU114 net596 cell215net559 inv4
XU115 cell215net525 net590 buf2
XU116 net647 net754 n180 or2
XU117 n157 n193 inv1
XU118 cell215net527 net643 buf2
XU119 cell215net557 net596 buf2
XU120 n192 n215 buf2
XU121 n216 n181 buf4
XU122 n209 n216 buf2
XU123 n177 n156 net632 or2
XU124 a[2] n196 inv2
XU125 func[0] n181 n182 nand2
XU126 n190 n183 buf2
XU127 func[0] b[1] n185 xnor2
XU128 b[0] net615 inv4
XU129 n188 cell215net488 c[4] and2
XU130 n192 cell215net506 n191 and2
XU131 func[0] b[2] n194 xnor2
XU132 func[0] func[1] n190 nand2
XU133 n196 n156 cell215net494 nand2
XU134 net632 net643 cell215net525 nand2
XU135 n184 a[1] n198 xnor2
XU136 a[2] b[2] n200 and2
XU137 n176 n215 n191 n201 aoi21
XU138 n200 n167 func[1] n189 sel21
XU139 net750 cell215net539 n202 or2
XU140 n198 n202 n178 n203 sel21
XU141 a[1] b[1] n204 and2
XU142 n204 n203 func[1] n187 sel21
XU143 n183 cell215net504 net647 n205 aoi21
XU144 n205 n159 func[1] n186 sel21
XU145 net594 cell215net506 inv1
XU146 n197 n185 cell215net527 or2
XU147 net643 cell215net539 inv1
XU148 net646 cell215net509 n208 or2
XU149 func[0] n181 cell215net547 nand2
XU150 n218 n193 net602 cell215net557 oai21
XU151 n170 net594 n211 nand2
XU152 n217 n206 n155 net602 n192 oai23
XU153 cell215net498 cell215net565 n212 nand2
XU154 n216 n180 n199 nand2
XU155 n207 n210 inv1
XU156 n213 cell215net515 n188 xnor2
XU157 b[0] cell215net504 inv4
XU158 n212 n213 buf4
XU159 cell215net494 net594 buf4
XU160 cell215net493 net602 buf4
XU161 a[1] n197 inv4
.ENDS
なおこのファイルは配布パッケージのexamples/alu/alunet.cirである.また,このネットリストには各ゲートのサブサーキットの中身は含まれていない.サブサーキットファイルは, examples/spice/subcircuit.cirに, SPICE用のトランジスタパラメータは, examples/spice/spice3.paraである.なお,電源電圧は5Vとする.
SPICEシミュレーションを行うためのサブルーチン記述は下記の3行である.
level 0,5,2,3; source "vdd","vh=5"; source "vss","vh=0";
levelサブルーチンにより電源電圧のローレベル(0V)とハイレベル(5V),ローレベルと認識する最高電圧(2V),ハイレベルと認識する最低電圧(3V)を指定する. sourceサブルーチンにより, vddというノードが5V電源, vssが0V電源(グラウンド)であることを指定している.
では, HSPICE用のテストベンチを生成する.
% ./alu.st -t hspice > alu_vec_hspice.sp
とする.
それでは,作成したHSPICE用のテストベンチとネットリストを用いて,シミュレーションを行う.シミュレーションを行うために,これらのファイルを読み込んだり,トランジスタモデルファイルの指定を行うトップレベルのファイルalutop_hspice.sp:を用いる. HSPICEのネットリストとして,alunet.vをSPICE形式に変換したalunet.cirを用いている.
*ALU spicefile
.options post
.include ../spice/spice3.para
X0 c[4] c[3] c[2] c[1] c[0] a[3] a[2] a[1] a[0] b[3] b[2] b[1] b[0] func[1] \
func[0] alu
.include alunet.cir
.include alu_vec_hspice.sp
.end
このalutop_hspice.spをHSPICEでシミュレーションする.
% hspice alutop_hspice.sp -o
正しくシミュレーションが実行された場合には, alutop_hspice.tr0という波形ファイルが作成される.このalutop_hspice.tr0をCustomExplorer(cx)で見て,結果を確認する.
% cx -w alutop_hspice.tr0
STは, HSPICEの持つディジタル信号向けの期待値比較(.dout)をサポートしている. alutop_hspice.lisを見ると,下記の通り, "verified with no error"となっている.なお,.doutはHSPICEの2016.06-1もしくは,2019.06-SP2-2での正常動作を確認している.2017.03ではバグのため正常動作しないので注意すること.
*****Output vector error report*****
output signal at node v(c[0])
verified with no error.
*****Output vector error report*****
output signal at node v(c[1])
verified with no error.
*****Output vector error report*****
output signal at node v(c[2])
verified with no error.
*****Output vector error report*****
output signal at node v(c[3])
verified with no error.
*****Output vector error report*****
output signal at node v(c[4])
verified with no error.
期待値が間違っている場合は,下記の通り,warningが表示される.
output signal at node[(c1 ]:
**warning**:incorrect logic state at node[(c1 ] time= 0.4900E-06, low \
expected!
高速なSPICEシミュレータであるfinesimを使ったシミュレーションも可能である.下記のとおり実行する.
% finesim -out alutop_finesim alutop_hspice.sp
alutop_finesim.logにlogファイル,alutop_finesim.fsdbに波形ファイルが出力される.波形ファイルはcxにより表示可能である.
SPICE用のテストベンチは, Verilog用のテストベンチに数行のSPICE用のサブルーチンを加えて作成する.しかしvcdやmoduleといったサブルーチンはそのままにしている.特定のターゲット用のサブルーチンは,そのターゲット以外では何もしない.従って,SPICE用のサブルーチンを加えたSTのテストベンチもtargetを変更するだけで,そのままVerilog用のテストベンチを作成することができる.
ここでは,順序回路による例として, 4ビット累算器を用いる.用意されたVerilog記述から, v2st.plを用いてSTのテンプレートを出力し,それを利用してSTの入力ファイルを作成する.
図6.2.1.1[4ビット累算器]に示す4ビット累算器のVerilog-HDL記述を用意している.この図に対応するVerilog記述はリスト6.2.1.1[fourbitaccum.v]の通りである.
module fourbitaccum (inp,outp,CLK,RST); input [3:0] inp; input CLK,RST; output [7:0] outp; reg [7:0] outp; always @(posedge CLK or negedge RST) if(!RST) outp <=0; else outp <= outp + inp; endmodule
このファイルは,配布パッケージに, examples/accumulator/fourbitaccum.vとして格納されている.
既存のVerilog-HDL記述から節[既存のVerilog moduleからのSTテンプレートの生成]に記載されているv2st.plを用いて, STのテンプレートを作成する.
% v2st.pl -c CLK fourbitaccum.v > fourbitaccum.st % chmod +x fourbitaccum.st
-cオプションにより,クロックピンの指定を行っている.生成されるfourbitaccum.stをリスト6.2.2.1[fourbitaccumskel.st]に示す.
#!/usr/local/bin/perl use ST; #level 0,3.3,1.0,2.0; target "verilog"; module "fourbitaccum"; #channelfile "mot23-chip-dut.csv"; #source_vdec; #source "VDD","channel=1","vh=1.2"; #source "VSS","vh=0.0"; vcd "fourbitaccum.vcd",0; #If you do not specify clock pins with a command argument, #Modify clock pins such as "CLK" like # pin "CLK",clock; # Default signal value is spcified with "defval" option # Pin location for LSI testers with "loc" option # pin "test","input","defal=0","loc=101"; pin "inp[3:0]","input","defval=0"; pin "CLK","clock",; pin "RST","input","defval=0"; pin "outp[7:0]","output","defval=X"; timing 1e-09,1e-07,10; # default clock cycle is 100ns # waveform of clock must be specified with the clock command like slope 1e-9,1e-9; # rise time and fall time for spice and epic clock "CLK","1111100000"; waveform "input","dnrz","%.........","inp","RST"; waveform "output","edge",".........%","outp"; pinorder "inp","RST","outp"; beginvector; vector 0,0,"X"; endvector;
VHDL記述からは,vhdl2st.plを使って同様のことが可能である.詳しくは節[既存のVHDL記述からのSTテンプレートの生成]を参照する.
Verilogに必要な設定は,すべて自動的に得られている.あとは, vectorサブルーチンを用いて,入力値と期待値を記述していくだけである.
vector 0,1,0; vector 0,0,0; # RSTを0に vector 1,1,0; # inに1を入力 vector 5,1,1; # inに5を入力 累算結果は 1 vector 0,1,6; # 累算結果は 6
次に,このファイルを実行して,テストベンチを作成する.
%./fourbitaccum.st > fourbitaccumtest.v
テストベンチが出力されたら,もとのVerilog-HDLファイルとともにシミュレーションを実行する.
# xmverilogの場合,
% xmverilog -l fourbitaccumtest.log +access+r fourbitaccumtest.v \
fourbitaccum.v
# iverilogの場合
% iverilog -o fourbitaccumtest fourbitaccumtest.v fourbitaccum.v
% ./fourbitaccumtest > fourbitaccumtest.log
SPICEでのシミュレーションに必要なfourbitaccumnet.cir, subcircuit.cirも用意してある. aluの例を元に,必要な記述を加え,fourbitaccum_vec_hspice.spを作成せよ.追加する記述は,fourbitaccum_save.stを参照する.
作成後は,fourbitaccumtop_hspice.spをhspiceでシミュレーションして,波形ファイルを確認せよ.
通常のテストベンチ(VerilogやVHDLで記載されたテストベンチ)とシミュレーション結果(vcdファイル)を使って,STのテストベンチを作成することができる.example/accumulatorのfourbitaccumtest.v fourbitaccum.v, fourbitaccum.vhdを使って説明する.
既存のテストベンチを使ってシミュレーションを行う.その際,vcdファイルを出力しておく.テストベンチでは,非同期リセットのエッジ(Active lowの場合は立ち上がり)とクロックのエッジ(ポジティブエッジトリガの場合は立ち上がり)が重ならないようにする.重なった場合は,RTLの場合,テストベンチの書き方によりリセットが有効なクロックサイクルが異なるため.fourbitaccumtest.v(リスト6.3.1[fourbitaccumtest.v])では,RSTのエッジをクロックとずらしている.
`timescale 1ns / 100ps
module fourbitaccumtest;
reg CLK,RST;
reg [3:0] inp;
wire [7:0] outp;
fourbitaccum fourbitaccum(
.inp(inp),
.CLK(CLK),
.RST(RST),
.outp(outp)
);
always #50 begin
CLK<=~CLK; // 100ns clock
end
initial begin
CLK<=1;
RST<=1;
inp<=1;
#10 RST<=0; // RSTとCLKのエッジはずらす.RST=1とCLK=1が同時の場合,
#100 RST<=1; // シミュレーション結果がテストベンチの書き方により
// 変わってしまうため.
#(100*10) $finish;
end
initial begin
$dumpfile("fourbitaccumtest.vcd");
$dumpvars(0,
fourbitaccumtest.fourbitaccum
);
end
endmodule
% xmverilog +access+r -l fourbitaccutest.log fourbitaccumtest.v \
fourbitaccum.v
または
% make fourbitaccumtest.log
これにより,fourbitaccumtest.vcdが生成される.
v2st.pl, vhdl2st.plを使って,テストベンチの雛形を作成する.
% v2st.pl -c CLK fourbitaccum.v > fourbitaccum_vcd.st % vhdl2st.pl -c CLK fourbitaccum.vhd > fourbitaccum_vcd.st
fourbitaccum_vcd.stのtimingサブルーチンの2個目の引数(シミュレーションのサイクルタイム)をfourbitaccumtest.vのサイクルタイムに合わせて書き換える.なお,デフォルトは100nsとなっているため,fourbitaccum_vcd.stでは書き換え不要である.
timing 1e-09,1e-07,10; # 1e-07 (100ns)がサイクルタイム
vcdから,ベクタを生成する.ST記述より,-tオプションによりターゲットをvcdとし,-wオプションでベクタ生成に使うvcdファイルを指定する.
% perl fourbitaccum_vcd.st -t vcd -w fourbitaccumtest.vcd > \
fourbitaccum_vec.st
fourbitaccum_vec.stは,下記の通り,vcdから抽出したピンの信号値をvectorサブルーチンで出力する.
vector "1","1","x"; vector "1","0","0"; vector "1","1","1"; vector "1","1","2"; vector "1","1","3"; vector "1","1","4"; vector "1","1","5";
beginvector;
#vector 0,0,"X";
# 再度,fourbitaccum_vec.stを生成する場合は,下記の
# requireをコメントにする.
require "カレントディレクトリ名/fourbitaccum_vec.st";
## 小林研のフローのディレクトリ構成で実行する場合は,下記でも良い.
}
endvector;
テストベンチを生成してシミュレーションを実行する.
% perl fourbitaccum_vcd.st -t verilog > \
fourbitaccum_test_from_vcd.v
% xmverilog +access+r -l fourbitaccum_test_from_vcd.log \
fourbitaccum_test_from_vcd.v fourbitaccum.v
fourbitaccum_test_from_vcd.logに下記の通り表示されていれば,期待値とシミュレーション結果が一致している.このST記述を用いることにより,他のシミュレータやテスタへのベクタ変換ができるようになる.
No simulation mismatch is detected!
SPICE系のシミュレータを使う場合には,下記の$voltageを電源電圧に合わせること.
$voltage=5.0; $vdelta=$voltage/10;
これにより,下記のlevelコマンドにより入力ピンの電圧レベルと,出力のHI/LOを判断する電圧レベルが設定される.
level 0,$voltage,$voltage/2-$vdelta,$voltage/2+$vdelta;
また,下記の通り,電源とグラウンドのノードに接続する電圧源の設定を行う.vh=で電圧を指定するため,VDDは$voltage V, VSSは0 Vに設定される.
source "VDD","channel=1","vh=$voltage","io"; source "VSS","vh=0.0";