目次次へ番外編 Chap.6 命令語インタプリタを改造する(1)

「今回からラダー図でメモリを作るんじゃなかったけ?」と思った人には申し訳ありません。

予定を変更して、先に命令語インタプリタを改造することにします。
具体的には、命令語インタプリタにスタックを設けて「回路ブロックの結合」構造のあるラダー図を実行できるようにします。

話は変わりますが、1970年代後半、アメリカのある有名な半導体メーカが1ビットマイコンを出していました。
このマイコン、扱うデータが1ビットですから、算術演算はできません。(できるのは、論理演算だけです。)
それに、取り込んだデータをビット反転してからレジスタと論理演算する、奇妙な命令があります。
これって、どこかで聞いたことがあるような気がしませんか?
(聞いたことかないという人は、番外編Chap1の表1.1を見てください。)
1970年代後半に、シーケンス制御を想定したマイコンが存在していた!という話でした。

6.1 今までの命令語インタプリタの問題点
さて、本題です。
これまで使ってきた命令語インタプリタには、回路ブロックの結合をおこなう命令語がありませんでした。
このため、ラダー図に回路ブロックの結合構造がある場合、このラダー図を命令語に変換する前に、ラダー図を変形する必要がありました。
しかし、この変形は回路ブロックをいったんコイルに置き換えるため、どうしても冗長になってしまいます。

そこで、今回から命令語インタプリタを改造し、回路ブロックの結合構造をそのまま実行できるようにすることにします。
理屈はともかく、図6.1のラダー図を見てください。

図6.1 回路ブロックのOR結合(ORSTACK命令を使用)

この図は「回路ブロックの結合」構造のあるラダー図です。(青色の枠内と水色の枠内をOR結合しています。)
このラダー図は、従来の「命令語インタプリタ」の命令語には変換できませんでしたが、図のように、改造後の「命令語インタプリタ」の命令語には変換することができます。
これは、回路ブロックのOR結合をおこなうORSTACKという命令語があるためです。

6.2 改造後の命令語インタプリタの仕組み
次に、この改造後の「命令語インタプリタ」の仕組みを考えてみましょう。

(1)導通状態スタックを設ける
「命令語インタプリタ」には、導通状態を記憶するレジスタは1個しかありません。(以下、導通状態レジスタと呼びます。)
したがって、図6.1のように回路ブロックの結合のあるラダー図を命令語に展開した場合、2回目に(ここではBのとき)出現したLD命令、またはLDNOT命令で、導通状態レジスタの内容は上書きされて消失してしまいます。

そこで対策として、LD命令、またはLDNOT命令で、「現在の導通状態レジスタの内容をスタックに退避する」ことにします。
このためのスタックを、導通状態スタックと呼ぶことにします。
ここでは、1ビット×8段の深さの導通状態スタックを、命令語インタプリタの内部に設けることにします。

(2)LD命令、LDNOT命令の動作を変更する
(1)で説明したように、LD命令とLDNOT命令の動作仕様を表6.1のように変更します。(Regは、導通状態レジスタのことです。)

表6.1 LD命令とLDNOT命令の動作
命令語 従来の命令語インタプリタでの動作 改造後の命令語インタプリタでの動作
LD n (1)Reg ← (n)
(1) 現在のRegの内容を、導通状態スタックに退避する(PUSH動作)
(2) Reg ← (n)

LDNOT n (1)Reg ← not(n)
(1) 現在のRegの内容を、導通状態スタックに退避する(PUSH動作)
(2) Reg ← not(n)

LD命令またはLDNOT命令の直前までで1つの回路ブロックと扱いますから、導通状態スタックには回路ブロックの演算結果が積まれてゆくことになります。

(3)ANDSTACK命令、ORSTACK命令を新設する
次に、導通状態スタックに積まれた回路ブロックの演算結果をどうやって使うかを考えます。
導通状態スタックに積まれた回路ブロックの演算結果と、現在の回路ブロックの演算結果を表す導通状態レジスタとを、AND演算すれば2つの回路ブロックのAND結合になります。
同様に、OR演算すれば2つの回路ブロックのOR結合になります。
そこで、このような動作をおこなう命令語を新設することにし、それぞれANDSTACK、ORSTACK命令と呼ぶことにします。

表6.2に、ANDSTACK命令とORSTACK命令の動作を示します。

表6.2 ANDSTACK命令とORSTACK命令の動作
命令語 動作
ANDSTACK (1)導通状態スタックからデータを復帰する(PULL動作)
(2)Reg ← Reg and PULLした内容
ORSTACK (1)導通状態スタックからデータを復帰する(PULL動作)
(2)Reg ← Reg or PULLした内容

以上、(1)〜(3)の改造によって、回路ブロックの結合をおこなうことができるようになります。

ところで、図6.1で展開された命令語(@〜E)を注意深く見ていた人は、LD命令2個に対して、ORSTACK命令が1個しかないことに気がついたのではないでしょうか?
通常、スタックへのデータのPUSH動作、PULL動作は、同じ数だけおこなわなければならないはずです。

しかし、今回の場合は、最初のLD命令(@)の実行直前の導通状態レジスタの値は意味がありませんから、捨ててもかまいません。
すると、残った問題は、スタックポインタの「ずれ」を、どう解決するかだけです。
これには、表6.3のような解決方法があります。

表6.3 スタックポインタの「ずれ」の解決方法
方法1 回路先頭のLD命令、またはLDNOT命令に限り、PUSH動作をおこなわせないようにする。
方法2 OUT命令で、導通状態スタックからダミーのPULL動作をおこなう。
方法3 スタックの代りに、シフトレジスタを使う。

方法3は、シフトレジスタが「スタックポインタが固定されて、代りにデータが移動するスタック」と見なせることを利用しています。
今回の改造では、方法3を採用する予定です。

6.3 複雑なラダー図を命令語に変換
最後に、複雑なラダー図を命令語に変換した例を示します。
(図6.2は、ラダー図開発ツールLD Cv!でラダー図を作成して、これをLD Cv!自身で命令語に変換させた画面です。)
命令語インタプリタを改造して使用する場合、この変換作業を、手作業でおこなわなければなりません。

この変換結果を、納得できるでしょうか?
(なお、変換結果は一通りでないため、これ以外の変換結果でも正解の場合があります。)

図6.2 複雑なラダー図を命令語に変換した例
(ラダー図開発ツールLDCv!で変換)


さて、次回はVisual Basicで書かれた命令語インタプリタを、実際に改造してみることにします。

目次次へ