Powered by SmartDoc

チュートリアル

本章では,簡単な例を用いて, 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と演算の種類との関係
funcの値 cの出力値
0 a+b
1 a-b
2 a&b
3 a|b
alu.v
`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ファイルの作成

最初からSTファイルの書くのは面倒なので,すでに準備してあるalu.stを使う.

テストベンチ全体

以上にテストベンチalu.stは下記の通りとなる.このファイルは,配布ファイルのexample/alu/alu.stである.

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サブルーチンの引数で,変数を使ったり演算を行ったりすることができる.ここでは,期待値は,演算結果ではなく,入力式そのものを使用している.

Verilogテストベンチの作成

次に,作成したSTファイルalu.stを用いてverilog用のテストベンチを作成する. UNIXのコマンドラインで,下記を実行する.

# examples/alu/に移動する.
% chmod +x alu.st
% ./alu.st > alutest.v

これで, verilog用のalutest.vというテストベンチが作成される.

Verilogシミュレーションの実行

次にverilogシミュレータを用いてシミュレーションを行う.ここでは, GPLライセンスにより,無償で利用可能なiverilog (http://iverilog.icarus.com/)を用いる.STは, Verilogの標準的な文法しか用いていないため, Cadence社のxmverilogや,Synopsys社のvcs等の商用のVerilogシミュレータでも問題なく動作する.

HDLでのシミュレーション

下記を実行する.

% 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

SDFを使ったシミュレーション

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)で変化するのに時間がかかっているのがわかる.

SDF付きシミュレーションの結果

HSPICEでのシミュレーション

STは汎用のテストベンチ作成ツールである.さきほどはVerilogを用いた論理レベルのシミュレーションだが,同じテストベンチを用いて, SPICE用のテストベンチも作成することができる.

ALUのSPICEネットリスト

上記ALUのSPICE用ネットリストをリスト6.1.5.1.1[aluのSPICEネットリスト]に示す.

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用記述

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用テストベンチの生成

では, HSPICE用のテストベンチを生成する.

% ./alu.st -t hspice > alu_vec_hspice.sp

とする.

HSPICEの実行

それでは,作成したHSPICE用のテストベンチとネットリストを用いて,シミュレーションを行う.シミュレーションを行うために,これらのファイルを読み込んだり,トランジスタモデルファイルの指定を行うトップレベルのファイルalutop_hspice.sp:を用いる. HSPICEのネットリストとして,alunet.vをSPICE形式に変換したalunet.cirを用いている.

alutop_hspice.sp
*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!

finesimでのシミュレーション

高速なSPICEシミュレータであるfinesimを使ったシミュレーションも可能である.下記のとおり実行する.

% finesim -out alutop_finesim alutop_hspice.sp

alutop_finesim.logにlogファイル,alutop_finesim.fsdbに波形ファイルが出力される.波形ファイルはcxにより表示可能である.

STの便利なところ

SPICE用のテストベンチは, Verilog用のテストベンチに数行のSPICE用のサブルーチンを加えて作成する.しかしvcdやmoduleといったサブルーチンはそのままにしている.特定のターゲット用のサブルーチンは,そのターゲット以外では何もしない.従って,SPICE用のサブルーチンを加えたSTのテストベンチもtargetを変更するだけで,そのままVerilog用のテストベンチを作成することができる.

順序回路による例

ここでは,順序回路による例として, 4ビット累算器を用いる.用意されたVerilog記述から, v2st.plを用いてSTのテンプレートを出力し,それを利用してSTの入力ファイルを作成する.

Verilog記述の用意

図6.2.1.1[4ビット累算器]に示す4ビット累算器のVerilog-HDL記述を用意している.この図に対応するVerilog記述はリスト6.2.1.1[fourbitaccum.v]の通りである.

4ビット累算器
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記述/VHDL記述からのST記述自動生成

既存の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]に示す.

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

HSPICEによるシミュレーションの実行

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を使って説明する.

  1. 既存のテストベンチを使ってシミュレーションを行う.その際,vcdファイルを出力しておく.テストベンチでは,非同期リセットのエッジ(Active lowの場合は立ち上がり)とクロックのエッジ(ポジティブエッジトリガの場合は立ち上がり)が重ならないようにする.重なった場合は,RTLの場合,テストベンチの書き方によりリセットが有効なクロックサイクルが異なるため.fourbitaccumtest.v(リスト6.3.1[fourbitaccumtest.v])では,RSTのエッジをクロックとずらしている.

    fourbitaccumtest.v
    `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が生成される.

  2. 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)がサイクルタイム
      
    
  3. 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";
      
    
  4. 抽出したテストベンチをSTのテストベンチに追記する.fourbitaccum_vcd.stのbeginvectorとendvectorの間に,下記のとおり記述する.
    beginvector;
    #vector 0,0,"X"; 
    # 再度,fourbitaccum_vec.stを生成する場合は,下記の
    # requireをコメントにする.
    require "カレントディレクトリ名/fourbitaccum_vec.st";
    ## 小林研のフローのディレクトリ構成で実行する場合は,下記でも良い.
    }
    endvector;
        
    
  5. テストベンチを生成してシミュレーションを実行する.

    % 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";