それでは,2.1節においてSFLで記述したクロック・タイマの動作を, SFLシミュレータSECONS (Sfl Extended CONversational Design System) を使って設計者の意図に沿うものになってるかどうかを検証してみましょう.
これまでの論理設計で使われてきた論理シミュレータと呼ばれるツールは,
(1) 設計が機能的に正しいか?
(2) タイミング制約を満たすか?
を検証するためのものですが,SFLには,単相の同期クロック以外の タイミング情報は存在しせん. したがって,SECONDSで 上記の(2)を検証することはできません. というよりも,PARTHNONではシミュレーションで (2)をたしかめる必要 はないのです.その理由は,PARTHENONでタイミングの制約は, 同期クロックにデータ転送が間に合うかどうか, クロック・スキューにるデータの筒抜けが起こらないかどうかだけで, これらは合成ツールにより静的に検証されるらです. このようにSECONDSは,論理シミュレータというより 「プログラム言語SFLのデバガ」といえます.
とにかくSECONDSを動かしてみましょう. 2.1節で記述したタイマ・モジュールがTIMER.SFL, デクリメンタ・モジュールがDECR8.SFLというファイルに納められている とします(以下,このデクリメンタの実現法は,機能記述でも キャリ・ルック・アヘッドでもキャリ伝搬方式でもかわない). なお,PARTHENONをインストールしたディレクトリの example.dir\chapter2内には,2.1節の リスト2.1と リスト2.9 に相当するSFL記述があらかじめ用意されていますので, そこをカレント・ディレクトリにすれば, 以下の使い方をすぐに試してみることができます.
SECONDSの起動
SFLの読み込み
シミュレ−ションイメ−ジの作成
シミュレ−ションデ−タの設定と結果表示
スクリプトの使用
SECONDSの終了
SFLシミュレータSECONDSの基本をマスタするために, デクリメンタだけをシミュレーションしてみましょう.
まずは,SECONDSを立ち上げます.
A>seconds
***************************************************************
* SECONDS Version 2.3.0 1994/07/05 *
* This program is a part of the PARTHENON system. *
* Copyright (C) 1989-1994 NTT *
***************************************************************
!!Type 'help' if you need help messages!!
SECONDS>
SECONDSの起動画面に続いてに"SECONDS> " と表示してきました.これがSECONDSの出すコマンド・プロンプトです. SECONDSは会話型のツールで,すべてをコマンドで制御します.
シミュレーションでまずやらなくてはいけないことは, SFLでの設計記述をSECONDS内に読み込むことです. SFLを読み込むには,sflreadというコマンドを使います. 2.1節で示した8ビットのデクリメンタDECR8を読み込んでみましょう.
SECONDS> sflread DECR8.SFL
sflreadコマンドは,SFLの誤りを見つけると,エディタを起動して利用者 に修正を促します.詳しくは,第6章(SFLEXP)2節(エラーへの対処)を参照 してください.
では,SFLにきちんと読み込まれたがどうかを確認してみます.
SECONDS> lmc
DECR8 (module )
さて,これでシミュレーションにかかれるでしょうか? じつは,もう1ステップ必要です.
SECONDSでのシミュレーションは,ブレッド・ボードに回路を構成し, そこでテストするイメージに似ています.そのたとえでいうと, いままでのステップは使える部品を部品箱に集めてきたところまでです. シミュレータではいくらでも部品をコピーできるので,部品点数ではなく 部品の種別だけが問題となります.
(1) ブレッド・ボードを作る
ブレッド・ボードで回路をテストするには,部品を集めただけではだめで, ボード上に回路を構築しなければなりません.SECONDSでは, この回路をシミュレーション・イメージと呼びます. シミュレーション・イメージは,トップ・モジュールのインスタンス を作ること(ブレッド・ボード上に部品を置くことに相当)により作成されます.
では,DECR8のシミュレーション・イメージを作ってみましょう.
SECONDS> install DECR8 /
これは,DECR8という部品をトップ・モジュール("/")として,インスタンスを作ることを指示しています.DECR8にはサブモジュールがありませんから,これだけでシミュレーション・イメージは完成です(複数のモジュールがある場合については後述する).
(2) シミュレーション・タイム
いったん,シミュレーション・イメージが作られると 「シミュレーション・タイム」が定義されます.確認してみましょう.
SECONDS> time
0
timeコマンドは,現在のシミュレーション・タイム(サイクル)を表示します. シミュレーション・イメージが作られる前に,timeコマンドを発行すると 何が出るかはやってみてのお楽しみです.
シミュレーション・イメージがどうなっているかは,lcコマンドを使って 見ることができます.
SECONDS> lc
/ (module )
C (term internal )
ENABLE (instr input )
IN (term input )
OUT (term output )
これは,「現在,トップ・モジュール(ルート)にいて, その下に四つのオブジェクトがある」ことを示しています.
(1) 初期時のINとOUT端子にテスタをあてる
さて,いよいよシミュレーションを開始しましょう. DECR8のブレッド・ボード上の入力端子IN(8ビット)とOUTにテスタ をあててみます.
SECONDS> print "IN=%B OUT=%B\n" IN OUT
IN=zzzzzzzz OUT=zzzzzzzz
printコマンドの第1パラメータは,テスタをあてたオブジェクトの値を どのように表示するかという書式の指定です.ここでは2進数による表示 を指定しています.INもOUTも全ビットが'z'と出力されました. "z"はドライブされていないということ(ハイ・インピーダンス) を表してます.
(2) 制御端子ENABLEをアサートするとINとOUT端子は・・・
制御端子ENABLEをアサートしてみましょう. SFLでは,制御端子に"1"や"0"を代入することは できませんが,SECONDSのコマンドでは可能です(コマンドでの設定は SFLの記述に優先する).
SECONDS> set ENABLE 1
SECONDS> print "IN=%B OUT=%B\n" IN OUT
Error :(forward) on 0 in /
(W)Referred terminal /IN is not driven.
End of Errors
IN=zzzzzzzz OUT=uuuuuuuu
ENABLEをアサートすると,SECONDSに怒られてしまいました. これは,ENABLEがアサートされたにもかかわらず, 入力端子INに当然与えられているべきデータがないからです. もっともこれは警告"(W)"で, 「以後,シミュレーションの作業が続けられなくなる」という類 ではありません.
OUTの値は'u'と表示されました."u"は 「不定値で,"0"とも"1"ともいえない」 という意味であり,"z"との違いはその端子系オブジェクト がドライブされているということです.
(3) IN端子に値をセットする
では,INに1をセットしてみましょう.OUTには0が出力されるはずです (今度は16進表示).
SECONDS> set IN X01 ; print "IN=%X OUT=%X\n" IN OUT
IN=01 OUT=00
たしかに,0が出力されました.あとはいろいろな入力を与えて結果が正しい かを調べればよいのです.
その前に,いちいち
set IN ?? ; print "IN=%X OUT=%X\n" IN OUT
と打ち込むのはめんどうなので,次のようなファイルを用意しておきましょう. これには,SECONDSのコマンド列が入っています.これをスクリプトと呼びます.
<TRY.SEC>
set IN $1
print "IN=%X OUT=%X\n" IN OUT
(1) speakコマンドでスクリプトを作る
ここで,マルチウィンドウのシステムなら,横でエディタを開けばよいのですが, それができない場合は,
SECONDS> speak TRY.SEC
SECONDS> echo 'set IN $1'
SECONDS> echo 'print "IN=%X OUT=%X\n" IN OUT'
SECONDS> speak
とすれば,ファイルTRY.SECを作ることができます.
speakは,コマンドの出力を切り替えるコマンドで,パラメータなしの場合は, 標準出力に戻すと同時にTRY.SECをクローズすることを意味しています. また,"$1"というのは,このスクリプトに与えられる第1パラメータ を意味します.
(2) listenコマンドを使ってスクリプトを使う
つぎは,スクリプトの使い方です.
SECONDS> listen TRY.SEC X01
IN=01 OUT=00
listenコマンドは,コマンドの入力を切り替えるコマンドで, 第1パラメータで指定されたスクリプト・ファイルからコマンドを読み込みます. 第2パラメータ以降は,このスクリプト・ファイルへのパラメータとなります。 なお、SECONDSは自分の知らないコマンドが与えられると, コマンド名listenの入力が省略されているものとみなすので, listenは省略することができます.
(3) シミュレーション結果は?
さて,シミュレーション結果はつぎのようになります.
SECONDS> TRY.SEC X02
IN=02 OUT=01
SECONDS> TRY.SEC X03
IN=03 OUT=02
SECONDS> TRY.SEC X04
IN=04 OUT=03
SECONDS> TRY.SEC X08
IN=08 OUT=07
SECONDS> TRY.SEC X10
IN=10 OUT=0f
SECONDS> TRY.SEC X20
IN=20 OUT=1f
SECONDS> TRY.SEC X40
IN=40 OUT=3f
SECONDS> TRY.SEC X80
IN=80 OUT=7f
SECONDS> TRY.SEC X00
IN=00 OUT=ff
このシミュレーション結果をみると,デクリメンタ・モジュールは 正しく動作しているようです.
setコマンドは,この例のような外部入力だけではなく, レジスタやステージの状態,メモリ(メモリにはmemset,memclrコマンド を使うが,本質的には同じ)など,任意のオブジェクトの値を設定できるので, 原理的にはこれだけのコマンドで任意のパターンをシミュレートすることが できます.
以上が,SECONDSを使うための必要最小限の知識です.いいえもう一つ, (リセット・ボタン以外で)SECONDSを終了させる必要があります.
SECONDS> bye
******************************
* Good bye, see you later. *
******************************
複数モジュールのインストール
レポ−ト機能
時刻の更新
スケジュ−ル機能
リクエスト機能
他のアプリケーションとの協調
組み合わせ回路やごく簡単な順序回路のシミュレーションであれば, ブレッド・ボードとテスタ(基本的な使い方)だけで十分ですが, 少し大きな順序回路となると,これではたまりません. もう少しお金に余裕のある人は,ロジック・アナライザを使おうと思うでしょう. もちろんSECONDSもロジック・アナライザとして利用できます.
順序回路のシミュレーションをクロック・タイマ全体を例にしてやってみましょう.
(1) sflreadコマンドで複数のファイルを読み込む
さて,TIMERとDECR8のモジュールは別々のファイルに作られています. sflreadはファイル単位ですから,ファイルごとに読み込みが必要です.
A>seconds
SECONDS> sflread TIMER.SFL
SECONDS> sflread DECR8.SFL
SECONDS> lmc
TIMER (module )
DECR8 (module )
(2) autoinstallコマンドで指定した部品をトップ・モジュールにする
SECONDS> autoinstall TIMER
autoinstallコマンドは,指定した部品をトップ・モジュールとして インストールし,すべてのサブモジュール位置に(この場合DECRのみ), 親モジュールの指示する部品(DECR8)を置きます.この例の場合は,
SECONDS> install TIMER /
SECONDS> install DECR8 DECR
と等価です.部品間の結線は,端子(ポート)の名前により,自動的に行われます.
今度は,printコマンドの代わりにレポート機能を使います.
SECONDS> rpt_add ext "%4T: START=%B RESET=%B INIT=%X EXPIRE=%B" START RESET INIT EXPIRE
SECONDS> rpt_add int " REMAINED=%X TASK=%B STATE=%S\n" REMAINED MAIN.RUN MAIN
ここで,第1パラメータのextやintは,後で消したり順序を変えたりするための 識別子です.第2パラメータ以降はprintコマンドのパラメータと同じです.
rpt_addコマンドは,printコマンドのようにすぐには値を表示してくれません. レポート機能は,forwardコマンドにより時刻が進んでいくときに値の表示を 行う機能だからです.しかし,思ったとおりの形式で表示されるかどうかは ぜひ知りたいものです.
SECONDS> report do
とすると,レポート内容を強制的に表示させることができます.いまの場合は,
0 : START=0 RESET=0 INIT=zz EXPIRE=0 REMAINED=uu TASK=0 STATE=DOWN
と表示され,書式を確認することができます.
START端子をアサートしなければ,クロック・タイマは動きだしません. そこでまず,INITを3にセットして,STARTをアサートしてみます.
SECONDS> set INIT X3 ; set START 1
SECONDS> report do
0 : START=1 RESET=0 INIT=03 EXPIRE=0 REMAINED=uu TASK=0 STATE=DOWN
まだ,REMAINEDやTASKの値が変わっていません.これらは,レジスタ系の オブジェクトですから,クロックが入らないと値が変化しないわけです.
それでは,クロックを入れてみましょう.
SECONDS> forward +1
1 : START=0 RESET=0 INIT=zz EXPIRE=0 REMAINED=03 TASK=1 STATE=DOWN
レポート機能により,新しい時刻での結果が表示されました.続けてクロック を入れてみます.
SECONDS> forward +1
2 : START=0 RESET=0 INIT=zz EXPIRE=0 REMAINED=02 TASK=1 STATE=DOWN
SECONDS> forward +1
3 : START=0 RESET=0 INIT=zz EXPIRE=0 REMAINED=01 TASK=1 STATE=DOWN
SECONDS> forward +1
4 : START=0 RESET=0 INIT=zz EXPIRE=1 REMAINED=00 TASK=1 STATE=ASSERT
いまのところ,正しく動いているようです. しかし,他の場合も考えなくては なりません.
1サイクルごとに,forwardコマンドを入れるのはまどろっこしいので, 一気に飛ばしましょう.その前におまじないをしておきます. 次のようなスクリプト・ファイルを作っておきます.
<reset.sec>
sch_add +100 reset 'set RESET 1 ; reset.sec'
<start.sec>
sch_add %e 30 100 50 start 'set START 1 ; start.sec'
ファイルreset.secは,100サイクルごとにRESETをアサートするスクリプト, start.secは,平均50サイクルの指数分布に従う乱数(ただし,30以上100以下)で, STARTをアサートする間隔を決めるスクリプトです.
スケジュール機能は,コマンドの実行を,指定した時刻まで遅らせる機能です. 上のスクリプトを実行してその機能を確認してみましょう.
SECONDS> start.sec
SECONDS> reset.sec
SECONDS> schedule
<Schedule on 37>
start 'set START 1 ; start.sec'
<Schedule on 104>
reset 'set RESET 1 ; reset.sec'
ところで,STARTをアサートするときには,INITに初期値を入れる必要があります. そうしないとまたSECONDSに怒られてしまいます. start.secファイルに,INITを設定するsetコマンドを追加してもよいのですが, ここでは必要に応じてそのつど入れることにしましょう. SECONDSはシミュレーション中に値が必要になったオブジェクト (端子系のデータ・オブジェクトにかぎる)の値を利用者に要求してくる 機能(リクエスト機能)をもっています.
SECONDS> req_add INIT
SECONDS> request on
これで準備完了です.300サイクルほど回してみますが,画面だと流れてしまう ので,結果を,ファイルtimer.chtに出すことにしましょう.
SECONDS> speak timer.cht
SECONDS> forward +300
Request for 'INIT' on 41 : X40
Request for 'INIT' on 77 : X80
Request for 'INIT' on 120 : Xff
Request for 'INIT' on 155 : X90
Request for 'INIT' on 212 : X80
Request for 'INIT' on 250 : X20
なお,SECONDSの乱数発生器は再現可能でないため,実行するごとにINITの値 を要求してくる時刻は異なります.したがって,ここでのコマンド・シーケンス を繰り返しても同じ結果は得られません.
ファイルに出した結果を眺めるには,以下のようにするのがよいでしょう. execコマンドは,第1パラメータの文字列をDOSのコマンドとして実行します.
SECONDS> speak
SECONDS> exec "type timer.cht | more"
5 : START=0 RESET=0 INIT=zz EXPIRE=1 REMAINED=00 TASK=1 STATE=ASSERT
6 : START=0 RESET=0 INIT=zz EXPIRE=1 REMAINED=00 TASK=1 STATE=ASSERT
......................................
40 : START=0 RESET=0 INIT=zz EXPIRE=1 REMAINED=00 TASK=1 STATE=ASSERT
41 : START=1 RESET=0 INIT=40 EXPIRE=0 REMAINED=00 TASK=1 STATE=ASSERT
42 : START=0 RESET=0 INIT=zz EXPIRE=0 REMAINED=40 TASK=1 STATE=DOWN
......................................
76 : START=0 RESET=0 INIT=zz EXPIRE=0 REMAINED=1e TASK=1 STATE=DOWN
77 : START=1 RESET=0 INIT=80 EXPIRE=0 REMAINED=1d TASK=1 STATE=DOWN
78 : START=0 RESET=0 INIT=zz EXPIRE=0 REMAINED=80 TASK=1 STATE=DOWN
......................................
103 : START=0 RESET=0 INIT=zz EXPIRE=0 REMAINED=67 TASK=1 STATE=DOWN
104 : START=0 RESET=1 INIT=zz EXPIRE=0 REMAINED=66 TASK=1 STATE=DOWN
105 : START=0 RESET=0 INIT=zz EXPIRE=0 REMAINED=66 TASK=0 STATE=DOWN
......................................
281 : START=0 RESET=0 INIT=zz EXPIRE=0 REMAINED=02 TASK=1 STATE=DOWN
282 : START=0 RESET=0 INIT=zz EXPIRE=0 REMAINED=01 TASK=1 STATE=DOWN
283 : START=0 RESET=0 INIT=zz EXPIRE=1 REMAINED=00 TASK=1 STATE=ASSERT
......................................
303 : START=0 RESET=0 INIT=zz EXPIRE=1 REMAINED=00 TASK=1 STATE=ASSERT
304 : START=0 RESET=1 INIT=zz EXPIRE=0 REMAINED=00 TASK=1 STATE=ASSERT
本来,シミュレーションでは,注意深く設定されたテスト・パターンを与えるべき ですが,今回は,仕様の許す範囲で,でたらめに与えたデータでシミュレーション を行いました.このやり方では,逆にシミュレーションの結果を注意深く解析して, 十分にシミュレーションができたかどうかを確認する必要があります.
SECONDSは,シミュレーション結果に対してグラフィック表示をするとか, 特定のパターンを探すとかいった機能を提供していません. そのかわり,書式付きのprintコマンドやレポート機能, および補助的なechoコマンドを備えており,シミュレーション結果を適当な形式 でファイル(またはパイプ)に出しておいて,ポスト・プロセスとして利用者の側 でこれを処理することができるようになっています. これは,本来SECONDSが,sh,grep,awk,sed,perlなどのテキスト処理 プログラムのそろっているUNIX系OSでの実行を前提として設計されているからです.
MS-DOSで使う場合もこれらと同様のプログラムがあると,SECONDSをより上手に 使うことができます.あまり長くないシミュレーションでは,Lotus 1-2-3を使う という方法もあります.上の例で,
SECONDS> echo '"TIME" "START" "RESET" "INIT" "EXPIRE" "REMAINED" "TASK" "STATE"'
SECONDS> rpt_add ext '"%4T" "%B" "%B" "%X" "%B" ' START RESET INIT EXPIRE
SECONDS> rpt_add int '"%X" "%B" "%S"\n' REMAINED MAIN MAIN.RUN
としてやると,出力をそのままLotus 1-2-3で読み込むことができます.
以上,SECONDSの大まかな機能を使ってみました.上に出てきたコマンド以外にも, SECONDSにはデバッグに便利な多くのコマンドが用意されています. 詳細は,第5章のSECONDSリファレンスを参照してください.
注: 現在,ワークステーション版では,2SECONDSというさらに高機能な シミュレータが搭載されている.これは名前からもわかるようにSECONDS の後継プログラムで,
▲