(57)【要約】【課題】設計作業の煩雑化を招くことなく必要最小限の規模で並列信号処理論理を構成することを可能とする。【解決手段】配置される機能ブロックには出力信号の数値型決定機能をもつ関数が対応付けられており、数値型には当該数値が誤差を含む数値であるか否かを識別する指標と浮動小数点型を表す指数部ビット幅が含まれており、数値型決定機能は入力信号の数値型から予想される誤差が出力信号に一定値以上含まれないように型決定をおこなうものであり、同機能はあらかじめ与えられた外部入力信号の数値型から信号の流れに従って順次内部の信号線の型を決定することで機能ブロックを並列処理論理記述に変換する。【選択図】図１
2011232963.tif 000002
【特許請求の範囲】
【請求項１】
演算機能を有する複数の機能ブロックを相互に接続した形で与えられる並列論理回路記述を、レジスタを介して接続された単位論理記述（RTLレベルの記述）へと変換する機能を含む論理設計支援装置もしくはソフトウエアであって、前記機能ブロックのそれぞれには入力信号の数値型に応じて出力信号の数値型を決定する機能（以下「型決定機能」と記す）を有する関数が対応付けられていること、数値型には少なくとも浮動小数点型が含まれており、前記型決定機能の出力信号の数値型の決定が、演算結果に含まれると予想される誤差の幅の最小値の１／Ｎを下回る桁部分を出力信号に含めず、かつ演算結果のとり得る値の全範囲にわたって表現可能であること判断基準として行われること、前記型決定機能はあらかじめ数値型の与えられた外部入力信号から順次信号の流れに従って内部信号線の型を決定すること、を特徴とする論理設計支援装置もしくはソフトウエア。ここで、Ｎは２の冪、すなわち１、２、４、８、……であるものとする。
【請求項２】
請求項１記載の論理設計支援装置もしくはソフトウエアであって、数値型にはその属性値として（１）当該数値が誤差を含む数値であるか否かを識別する指標、（２）その数値のとりえる値の最大値および最小値、（３）その数値は符号を反転したものであるか否かを識別する指標、（４）その数値に加算すべき定数、の少なくともいずれか一つ、好ましくはこれらのすべてを含むことを特徴とする論理設計支援装置もしくはソフトウエア。
【請求項３】
請求項１または請求項２記載の論理設計支援装置もしくはソフトウエアであって、機能ブロックが出力する信号に演算結果に含まれると予想される誤差の幅の最小値の１／Ｎを下回る桁部分を含めない論理構成を形成することを特徴とする論理設計支援装置もしくはソフトウエア。ここで、Ｎは２の冪、すなわち１、２、４、８、……であるものとする。
【請求項４】
請求項３記載の論理設計支援装置もしくはソフトウエアであって、前記Ｎの値を一時的に増加させることによりアルゴリズムの妥当性を検証する手段を有することを特徴とする論理設計支援装置もしくはソフトウエア。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、数値演算をおこなう並列論理回路の設計支援装置およびこのためのソフトウエアに関わる。
【背景技術】
【０００２】
デジタル化された数値情報を処理する目的で、FPGAやASICなどを用いた並列論理回路が広く工業的に使用されている。並列論理回路の設計は、Verilog
HDLなどのハードウエア記述言語を用いてなされる例が多い。これらのハードウエア記述言語は、演算処理の入出力となる信号線のビット幅を１ビット単位で設定することで必要最小限の論理構成で目的とする機能を実現することが可能である。しかし、設計者が個々の信号のビット幅を管理することから設計作業が煩雑となるという問題がある。また、数値を固定小数点として扱う際には、その小数点位置を設計者が管理しなければならず、設計作業はさらに煩雑になる。
【０００３】
並列論理回路は、高速処理が可能である半面、論理規模が複雑になるという問題がある。そのため、マイクロプロセッサやDSPで行われている浮動小数点処理を並列論理回路で使用することは一般に困難とされ、たとえば非特許文献１では浮動小数点数を固定小数点数に変換して処理している。同様な事情は非特許文献２にも解説されている。しかしながら、これらの文献でも言及されているように、固定小数点数は扱える数値の範囲が狭く、精度が悪化するという問題がある。
【０００４】
少数ではあるが、並列論理回路で浮動小数点演算を行う試みも報告されている。たとえば、非特許文献３には、浮動小数点表現を使用することで論理構成を簡素化した例が紹介されている。固定小数点数に代えて浮動小数点数を用いる場合は、小数点位置は自動的に設定されるが、指数部と仮数部のビット幅は設計者が設定する必要があり、設計作業が煩雑であることに変わりはない。
【先行技術文献】
【非特許文献】
【０００５】
【非特許文献１】http://japan.xilinx.com/japan/events/dsp_seminar_2007/pdf/Cybernet.pdf
【非特許文献２】http://zone.ni.com/devzone/cda/pub/p/id/784
【非特許文献３】Dido, J.他, “A Flexible Floating-point Format forOptimizing Data-Paths and Operators in FPGA Based DSPs”, ACM SIG FPGA, FPGA’02, Monterey, California, USA, Feb.24-26(2002)
【発明の概要】
【発明が解決しようとする課題】
【０００６】
本発明はこのような事情に鑑みてなされたものであって、設計作業の煩雑さを招くことなく必要最小限の規模で論理を構成することを課題とする。また、浮動小数点数演算を含む論理を経済的に構成することを可能とし、固定小数点化による精度の悪化を避けることを課題とする。
【課題を解決するための手段】
【０００７】
並列処理論理の設計に際しては種々の方法が用いられているが、いずれの手法においても目的とする論理仕様を四則演算などの基本的な演算機能を有する機能ブロックを互いに信号線で接続した形で記述する段階を経る。この段階を「機能ブロック線図（FBD：ファンクション・ブロック・ダイアグラム）レベルの表現」とこの明細書では記述するが、必ずしも線図の形をとるものではなく、表形式、ないし電子的なデータ構造の形で装置内部に保持される場合が多い。また“FBD”という用語はIEC61131-3規格でも用いられているが、本明細書ではこの規格とは無関係にこの用語を使用する。
【０００８】
本発明になる装置もしくはソフトウエアはFBDレベルで記述された論理仕様の段階で数値型を自動決定するものであり、具体的には、機能ブロックのそれぞれに入力信号の数値型に応じて出力信号の数値型を決定する機能（以下「型決定機能」と記す）を有する関数を対応付け、各機能ブロックの入力信号の数値型が決定された時点でこの型決定機能により出力信号の数値型を自動的に決定することを特徴とする。
【０００９】
装置に外部から入力される信号の型はあらかじめ与えておく。また、装置内部に後段から前段へと信号が戻されるフィードバックループが存在する場合は、フィードバックされた信号の型を他の信号の型に対する相対定義として与えておく。こうすれば、入力段より順次、前記型決定機能を作動させることで、その他の信号の型はすべて自動的に決定することが可能である。前記型決定機能は、演算結果に最低でも含まれると予想される誤差の大きさに対する所定割合を下回る桁部分を出力信号に含めないことを基準として出力信号の型を決定することが好ましい。このようにすることで、必要最小限の規模で論理が形成される。乗算結果から誤差を含む桁部分を排除するためにはシフト処理が必要であり、これを可能とするためには浮動小数点形式を数値型に含めなければならない。
【００１０】
目的とする論理によっては、個々の信号線が伝達する数値が、ある信号線では誤差を含み、他の信号線では誤差を含まない場合もある。このような場合には、信号線上を伝達される数値が誤差を含む数値であるか否かを識別する指標（以下「不確定性指標」と記す）を数値型に含め、この指標に応じて型の決定を行えばよい。また、個々の信号線が表現する値の最大値と最小値、信号線が表現する値は符号を反転したものであるか否かを表す指標、信号線が表現する値に加算すべき定数、などを信号線が表す数値型の属性に含めることで、信号線のビット幅をさらに縮小できる場合が多い。
【発明の効果】
【００１１】
本発明の装置もしくはソフトウエアを用いれば、システムを構成する各機能ブロックが扱う数値情報が最小のビット幅で表現されるため、必要最小限の規模で論理を構成することができる。このためには、多種多様な数値型で信号の数値表現を行う必要があるが、内部で扱われる信号の数値型はすべて自動的に決定されるため、設計作業の煩雑さを招くこともない。
【００１２】
本発明はFPGAやASIC向けの論理設計支援装置への応用を目的としてなされたものであるが、論理設計支援装置は並列型計算機に用いるコンパイラもしくはオペレーティング・システムとしての機能を有することから、本発明をFPGAに類似したハードウエア構成をもつ並列型演算装置のためのコンパイラもしくはオペレーティング・システムとして用いることも可能であり、この場合にも上記と同様の効果が得られる。
【図面の簡単な説明】
【００１３】
【図１】本発明の処理の流れを示すフロー図である。
【図２】加算機能ブロックの内部処理を示すブロック図である。
【図３】乗算機能ブロックの内部処理を示すブロック図である。
【図４】本発明の第一の実施例になる論理設計支援システムにおいて機能ブロック選択作業の画面を示す図である。
【図５】本発明の第一の実施例になる論理設計支援システムにおいて加算機能ブロックが選択された直後の画面を示す図である。
【図６】本発明の第一の実施例になる論理設計支援システムにおいて加算機能ブロックに入出力ポートが接続された直後の画面を示す図である。
【図７】本発明の第一の実施例になる論理設計支援システムにおいて入力ポートの数値型決定作業のための画面を示す図である。
【図８】本発明の第一の実施例になる論理設計支援システムにおいて加算機能ブロックの出力数値型が自動決定された直後の画面を示す図である。
【発明を実施するための形態】
【００１４】
論理設計支援装置は、このためのソフトウエアをインストールしたパーソナル・コンピュータ（以下「PC」と略記する）もしくはエンジニアリング・ワークステーションの形で提供される。また、同等の機能を有する製品は、客先のPCにインストールして動作させるためのパッケージ・ソフトウエアの形でも供給される。この発明を論理設計支援装置として提供する装置で使用する場合も、発明の本質はこれにインストールされたソフトウエアの部分にあり、ハードウエア部分は通常のPCと何ら変わらないため、以下の説明はソフトウエア部分についてのみ行う。
【００１５】
目標とする並列演算論理の仕様は、論理ブロックを表すオブジェクトのリストとして与えられる。（注記：「オブジェクト」という用語は、抽象データ型である「クラス」と同じ意味で扱われる場合もあるが、ここでは特定の型属性をもつ個々の「具体的対象」という意味でこの用語を用いており、「実体：インスタンス」に近い概念を意味する。）C++言語でソフトウエアを記述する場合には、論理ブロックオブジェクトのデータ型をたとえば“Func”クラスとして定義しておく。マイクロソフト社の提供するVisualStudio開発環境下で.NET
Frameworkのサービス関数を利用する場合、“Func”クラスは次のように定義される。
1:    typedef
bool (*Coder)
2:        (List<Module^>^
modules, Func^ func);
3:    public
ref class Func
4:    {
5:    public:
6:        Func()
7:        {
8:            inports
= gcnew List<Port^>;
9:            outports
= gcnew List<Link^>;
10:        }
11:    private:
12:        String^ name;
13:        int id;
14:        List<Port^>^ inports;
15:        List<Link^>^ outports;
16:            bool done;
17:    public:
18:        Coder coder;
19:    };
【００１６】
上記リストにおいて、行１および行２は関数ポインタ型“Coder”の定義であり、クラスFuncに付随する、型決定機能を有するコード化関数へのポインタ、“coder”の型の記述を簡素化するために型名を定義している。クラス“Func”の定義本体は行３から行１９の間に記述されている。なお、上記リストは説明のため簡略化して記述したものであって、実際に用いられるクラス定義には、演算の際に使用される作業用の変数定義が含まれている（この事情は以下のリストでも同様である）。
【００１７】
行６から１０はクラス“Func”のオブジェクトが形成される際に実行される文であり、コンストラクタと呼ばれる。この部分では、リスト型オブジェクトの領域確保を行っている。
【００１８】
行１２から行１６の間にこのクラスの内部変数がおかれる。これらは必要に応じてproperty定義を行うことで外部から参照できるようにしているが、property定義に関しては記載を省略している。それぞれの変数の意味は次のとおりである。
name：機能の名称であり、加算を行う機能ブロックであれば“Add”などの作業者に理解容易な名前が与えられる。
id：個々の“Func”オブジェクトを識別するための番号であり、機能ブロックを配置する際にそれぞれの機能ブロックにユニークな番号が与えられる。
inports：入力ポートのリストであり、それぞれのポートはクラス“Port”のオブジェクトへのポインタとして定義されている。
outports：出力ポートのリストであり、それぞれのポートはクラス“Link”のオブジェクトへのポインタとして定義されている。
done：この“Func”オブジェクトのコード化が完了したことを表すフラグである。
【００１９】
クラス“Port”は、ポート名を表す文字列“name”とこれに接続された信号線を表すクラス“Link”オブジェクトへのポインタを含む。出力ポートのリスト要素には、入力ポートと異なりポート名を表す文字列は与えず、“Link”クラスをそのまま用いている。これは、出力ポートには必ず単一の信号線が接続されるため、出力ポート名を出力信号線の名称で代用しているためである。
【００２０】
クラス“Link”は次のように定義される。
1:    public
ref class Link
2:    {
3:    public:
4:        Link()
5:        {
6:            man
= gcnew Wire;
7:            dests
= gcnew List<Func^>;
8:        }
9:    private:
10:        Func^ src;
11:        List<Func^>^ dests;
12:        bool certain;
13:        Wire^ man;
14:        Wire^ exp;
15:        String^ over;
16:        String^ under;
17:    };
【００２１】
上記リストにおいて、４行目から８行目までは“Link”オブジェクトが形成される際に実行される文が記述されたコンストラクタであり、仮数部に対応する整数値の信号線である“Wire”オブジェクト“man”の領域を確保するとともに、信号線の行き先となる論理ブロック（クラス“Func”）のリスト“dests”の領域を確保している。 “Link” オブジェクトの名称は、これに必ず伴う“Wire”オブジェクト“man”の名称で代用する。“Link”オブジェクトには、信号の供給源となる機能ブロックへのポインタ“src”と、信号の行き先となる機能ブロックへのポインタのリスト“dests”が定義されており、これにより機能ブロックの接続関係を順にたどることが可能である。“Link”オブジェクトの数値型を表すものとして、誤差を含まない数値であることを示すフラグ“certain”、および信号値を浮動小数点表現するために必要な仮数部“man”と指数部“exp”という二つの “Wire”オブジェクトへのポインタがおかれている。指数部を表現する整数がおかれた領域へのポインタ“exp”は、必要がある場合にのみこのために確保された領域を指し示し、指数部が不要な場合にはヌルポインタとされる。一方、仮数部を表すための領域は必ず確保され“man”がその領域を指し示す。また、信号の異常を表す二つのフラグ信号線名“over”と“under”が含まれている。
【００２２】
ここで提案している手法は、オーバーフロー、アンダーフローが生じないように出力信号線の数値型が自動的に決定され、一般的にはこれらの異常を表すためのフラグ信号線は必要ない。しかしながら、実際の論理回路設計にあたっては、資源の制約から信号線を削減する必要が生じる場合もある。このような場合には、出力信号型を与える変換機能ブロックを用い、信号線の数値型を強制的に設計者が指定した数値型とする。この際、出力の信号線が不足すれば、オーバーフローやアンダーフローが起こり得る。
【００２３】
オーバーフローおよびアンダーフローが生じた場合の処理の仕方として、二通りの方法をとりえる。一つは、オーバーフローした際には信号線の値を表現可能な最大値に保ち、アンダーフローが生じた際には信号線の値を表現可能な最小値とする手法であり（これをクリッピング処理と以下記す）、もう一つの方法は異常が発生した際には異常を表示するフラグを立て、フラグが立っている際には信号線の値は不定であるとみなす手法である。クリッピング処理は、オーバーフローやアンダーフローが軽微であることが予想される場合に有効であり、また画像や音声出力のように異常な値の出力がさほど悪影響を与えない場合にも使用することができる。一方、精密な計測や制御のための複雑な演算処理の中間過程などにあっては、これらの異常が生じた際にはこれを表示し、あるいは制御を停止するなどの処置が要請される場合もある。後者の場合は、異常フラグを出力し、これらの値により必要な処理を行うように論理を構成する。なお、後者の場合でもクリッピング処理を併用することが便利な場合もあるが、クリッピング処理の実装にはセレクタが必要となり、論理資源を消費して遅延時間も増加するため、通常はいずれか一方の処理のみとする。
【００２４】
整数値を表現する“Wire”クラスの定義の一部を以下に示す。なお、以下に記した以外に、“Wire”クラスのオブジェクトにはコード化の際に用いられる作業領域が含まれている。これらに関してはコード化に関する説明の際に追記して説明する。
1:    public
ref class Wire
2:    {
3:    public:
4:        Wire(void){}
5:    private:
6:        String^
name;
7:        bool
neg;
8:        int
bias, min, max;
9:    };
【００２５】
上記リスト６行目に定義されている“name”はこの“Wire”オブジェクトの名称である。先に述べたように、“Link”オブジェクトのメンバー“man”に割り当てられた“Wire”オブジェクトの名称が“Link”オブジェクトの名称およびこれに信号を供給する“Func”オブジェクトの出力ポートの名称としても用いられる。
【００２６】
行７から９は、“Wire”オブジェクトの属性を決定するもので、“bias”は定数値、“min”および“max”は信号線のビットパターン部分が表す値の最小値と最大値を規定する。“Wire”オブジェクトの値は、定数値“bias”とビットパターン部分が表す値の和で与えられる。“min”および“max”がともに０である場合は、この“Wire”オブジェクトは“bias”部分の値に相当する定数を表すものと解釈される。行７に定義されたブール型の変数“neg”はビットパターン部分が示す値が符号反転されたものであることを示すフラグであり、負の値のみをとりえる数を表現する際や、単項演算子“−”を作用した際の信号線のビット幅拡大を防ぐために設けられている。
【００２７】
整数の型を表す属性は、ビット幅と符号の有無で指定するのが一般的である。しかしながら、並列演算においては異なるビット幅の数値間での演算がしばしば行われるため、入力される値の範囲から出力される値の範囲を規定し、この情報を次段の型決定に反映させることで信号線のビット幅縮小が可能となる場合が多い。符号の有無と信号線のビット幅は、最大値と最小値から一意に定まる。したがって“Wire”オブジェクトのビット幅や符号の有無は、これを演算する汎用の関数を準備するか、もしくは “Wire”クラスのプロパティとしてこれらの値を返す手続きを準備しておくことで容易に参照することが可能である。
【００２８】
クラス“Link”のオブジェクトには、仮数部を表す“man”および指数部を表す“exp”の二つの“Wire”オブジェクトが付随している。指数部を表す“exp”がヌルポインタである場合は、この“Link”オブジェクトが整数値であることを意味する。“exp”が定数である場合（“exp”の最大値と最小値がともにゼロである場合）には“Link”オブジェクトは固定小数点数となる。“exp”が定数でない “Link”オブジェクトは浮動小数点数となる。
【００２９】
クラス“Link”には、また、オーバーフローなどの異常を表す信号線を付随させることができる。行１５に規定された“over”はオーバーフローフラグ名、行１６の“under”はアンダーフローフラグ名である。信号線の異常状態として、このほかにゼロによる除算などの「数値化不能異常」があり、上記例ではこの異常を“over”と“under”の双方のフラグを立てることで表現しているが、数値化不能異常を独立した信号線で表示してもよい。これらの信号線は、ブール値を表す１本の信号線のみで配設され型情報を伴わないため信号線の属性情報は不要であり、信号線の名称のみが与えられる。異常フラグが存在しない場合は信号線の名称をヌルポインタとする（文字列を表す変数は文字列のおかれた領域を指し示すポインタであるため、文字列が存在しない場合はヌルポインタとされる）。名称が指定された異常フラグに対しては、該当する異常フラグ信号線が形成される。
【００３０】
クラス“Link”定義の１２行目に記述されたブール変数“certain”は、この信号線の示す値が誤差を含むか否かを識別する不確定性指標であり、この値がtrueである場合、信号線の示す値は誤差を含まないものとみなされる。誤差は、仮数部を表す整数（“man”）にのみ含まれ、指数部は誤差を含まない。なお、ここで紹介する例においては、誤差を含まない数値表現に対しては指数部を用いることを認めず、誤差を含まない数値の表現形式として整数型のみを許容している。この制約は生成される論理規模の拡大を防止するためのものであるが、この制約は絶対的制約ではなく、誤差を含まない固定小数点数あるいは誤差を含まない浮動小数点数の取り扱いを可能としてもよい。また、ここに示した例では数値型の類型分けをせずにブール値をとる変数として不確定性指標を与えることで誤差含有の有無を識別しているが、誤差を含む数値型と誤差を含まない数値型の二類型に分類して扱うことも可能である。すなわち、整数型は誤差を有さないものとして扱い、実数型は誤差を有するものとして扱うことも可能である。このような場合には、不確定性指標は型の類型に含まれている。
【００３１】
不確定性指標は少々複雑な概念であるため、以下詳細に説明する。デジタル化された数値情報には、個体の計数値のように誤差をもたない数値と、長さや電圧の計測値のように誤差を含む数値の二通りのものがある。デジタル化された数値情報の整数部分について考えれば、前者の場合の真値との差が常に０であり誤差の範囲も０であるのに対し、後者の場合の真値との差は、切り捨てが行われた場合には−１〜０、四捨五入が行われた場合には−０．５〜＋０．５となり、いずれも誤差の範囲（以後「誤差」と記す）は１となる。
【００３２】
オーバーフローを生じることなく、かつ有効な情報を失うことなく演算を遂行するためには、誤差をもたない数値に対しては演算の結果得られるすべてのビットを後段に伝達する必要がある。たとえば、ｎビットの符号なし整数どうしの乗算であれば、最大の値が入力された際の２ｎビットの結果を後段に伝達しなければならない。
【００３３】
一方、これらが誤差を含む数値であれば、入力値の有効数字はｎビットであるため、演算結果の有効数字もｎビットとなる（実際に後段に伝達しているビット幅はｎ＋１である。これに関しては後述する）。ただし、有効数字以下の桁には不確定ではあるが、入力に含まれている情報を幾分か反映している。これらの情報を有効に後段に伝達するため、有効数字以下の桁を後段に伝達することで演算精度が改善される。このような余分なビットは「保護ビット（ガード・ビット）」と呼ばれ、１ビットもしくは２ビットの保護ビットを追加することが一般に行われる。1ビットの保護ビットを与える場合には誤差を有効桁の１／２、２ビットの保護ビットを与える場合には誤差が有効桁の１／４となるように下位を省略（切り捨てもしくは四捨五入）すればよい。
【００３４】
保護ビットは、丸めにより有効な情報が失われることを防止するためには２ビットで十分であるが、アルゴリズムをテストするために、より多い保護ビットを用いる追加機能も準備しておくことが好ましい。有効桁数の異なる信号を複数回用いる演算においては、演算の順序によっては誤差が相殺される可能性もある。誤差の相殺は、相殺されるべき誤差を含む桁部分が後段に伝達されてはじめて可能となる。単純な例で説明すれば、第一の信号値に有効桁数の少ない第二の信号値を乗算し、次に同じ第二の信号値で除算する一連の演算を想定すれば、第二の信号値に含まれる誤差は同じ値を用いて乗算と減算が行われるため互いに打ち消し合うこととなる。しかしながら、誤差を後段に伝達しない構成では、最初の演算で第二の信号値の有効桁数に見合う情報のみを後段に伝達することとなり、誤差のキャンセルは機能しなくなる。
【００３５】
誤差のキャンセルは精度が改善されるという意味では有益であるが、この現象は不適切なアルゴリズムによって生じると考えられ、アルゴリズムを改善することにより、少ないビット幅でも精度を悪化することなく演算が可能となる。保護ビットを一時的に増加する機能を設けておけば、この機能を働かせたときに出力信号の安定性が改善したかどうかを検査することにより、内部で誤差のキャンセルが働いているかどうかを判定することができる。誤差のキャンセルが働いている場合は、アルゴリズムを見直すことで、単純な回路構成でも精度の悪化を招かずに演算することが可能となる。
【００３６】
つぎに、誤差を含む数値の演算について説明する。
【００３７】
誤差を含む数値は、その値がman×2expとなるように、仮数部manと指数部expを用いて表現される。manおよびexpは共に整数であり、数値自体が整数である場合にはexpは省略される。また、誤差はman部にのみ含まれるものとみなし、exp部は誤差を含まないものとする。
【００３８】
誤差を含む数値を二倍にするとこれに含まれる誤差も二倍となり、１／２にすると誤差も１／２となる。かかる演算において、後段に伝達される誤差を入力と同等にするためには、仮数部には手を加えず、二倍する演算は指数部に１を加え、１／２倍する演算は指数部から１を差し引けばよい。一般に、誤差を含む数値に対するシフト演算は、指数部の値を増減することによって行えばよい。
【００３９】
定数乗算は、必ずしも２の冪を乗じるとは限らない。２の冪以外の定数を乗算する際は、演算自体は有用な情報を失わない形で行い、同様な演算が繰り返し行われた後に、有効数字を減少させる演算を行うのがよい。たとえば、３を乗じる演算は、指数部に１を加えて２倍すると同時に、仮数部を１．５倍にする。誤差を含む数値にこの演算が２回行われた場合には、誤差の増加は９倍となる一方で、各演算での最下位桁の示す値は２倍となるため、仮数部最下位桁の９／４倍の誤差が後段の出力部に残っている。このような場合は、２回の３倍演算の後に、有効数字を１ビット減少させる操作を行う。有効数字を１ビット減少させる操作は、仮数部を２で割り（ビットパターン部を１ビット右シフトし仮数部の定数値が０でない場合はこれも１／２とし）、指数部に定数１を加算することで実現される。
【００４０】
誤差を含む数値の加算に際しては、誤差の一部が相殺されるため、加算結果に含まれる誤差は入力に含まれる誤差の和とはならない。同等な誤差を有する数値をＮ個加算した場合の誤差は、誤差が互いに無相関である場合にはＮの平方根に比例して増加することが期待される。このため、加算演算においては２倍の定数乗算とは異なる扱いが必要になる。すなわち、加算結果の誤差は入力された数値に含まれる誤差の最大値（誤差の大きい側の入力値に含まれる誤差の値）であるものとして出力の調整を行う。具体的には、指数部の異なる二つの誤差を含む数値を加算する場合、指数部の値の大きい側に双方の指数部をあわせるように、指数部の小さい側の数値の仮数部を右シフトして仮数部どうしを足し合わせればよい。この結果加算結果に含まれる誤差は各入力値に含まれる誤差よりも大きくなため、適宜有効数字を減少させる上述した操作を行うことでビット幅を縮小することができる。なお、多数の値を加算する累積演算に際しては、誤差部分を含む形で累積演算を遂行し最後に誤差部分を除去する、累積演算専用の型決定アルゴリズムを用いることが好ましい。
【００４１】
乗算は、指数部を加算し、仮数部を乗算することで行われる。誤差を含む数値の乗算に際しては、双方の入力値の最上位ビットが他方の誤差に乗じられるものとして誤差の値を推定し、無効桁部分の切り捨て（もしくは四捨五入）を行えばよい。これを具体例で示せば、仮数部がｎビットの二つの数値を乗算した場合、２n-1の大きさをもつ一方の数値の最上位がもう一方の数値に乗算されて、誤差も２n-1倍される。双方の入力値のビット長が等しい場合には双方の誤差が加算されるが、誤差の一部はキャンセルされ、誤差は２倍以下となることが期待される。したがって、情報の棄損を防止するために、乗算の結果得られる２ｎビットの積をｎ−１ビット右シフトし、指数部にｎ−１を加算したものを結果とすることが好ましい。すなわちｎビットの二つの数値の乗算結果はｎ＋１ビットで表される。有効数字ｎビットの乗算結果の有効数字はｎビットとすることが一般的であるが、情報の棄損防止を第一として加算と同等に扱うこととすれば、通常の手法に比べて１ビット多く後段に伝達することとなる。なお、この手法は加算による誤差の増加を無視していることに加え、最上位のビットのみが立っている場合の誤差を判断基準としており、下位のビットが立っている場合の誤差はこれより大きい。したがって、加減算の場合と同様、適宜ビット幅縮小操作を行うことが好ましい。
【００４２】
信号線の型属性は、論理ブロックごとに準備されたコード化関数によって与えられる。コード化関数へのポインタは、“Func”クラスのオブジェクト毎に準備された関数ポインタ“coder”に、論理ブロックを配置する際に設定される。コード化関数は、引数としてコード出力領域であるクラス“Module”のリストへのポインタと、親である“Func”クラスのオブジェクト自身へのポインタ“func”をもって呼び出され、コード化を行ったか否かを表すブール値を返す。コード化関数の動作は以下のとおりである。
【００４３】
まず、“func”のすべての入力ポートの信号源である機能ブロックのコード化が完了しているか否かがチェックされる。前述したクラス定義にしたがえば、このチェックはリスト“func->inports”のすべての要素“inport”に対して“inport->link->src->done”がtrueであるかどうかを確認すればよい。いずれかの入力ポートが未接続であるか、あるいは入力ポートの信号源となる機能ブロックのコード化が完了していない場合は、コード化関数はコード化を行わず、falseを返して終了する。
【００４４】
機能ブロックの入力ポートに接続された信号線の信号源のコード化がすべて完了していれば、これらの信号線の型も定義済みである。この場合、コード化関数は出力信号の型設定を行い、機能ブロックを中間形式に変換して出力し、“done”フラグをtrueとしてtrueを返して終了する。なお、コード化関数が呼ばれた時点で既に“done”フラグがtrueである場合は、既にこの機能ブロックのコード化は完了しているため、コード化関数はなにも行わずfalseを返して終了する。
【００４５】
変換対象全体を表す機能ブロックリスト“func_list”の処理フローを図１（ａ）に、コード化関数の処理フローを図１（ｂ）にそれぞれ示す。図１には図示されていないが、処理に先立って“func_list”のすべての要素のコード化完了フラグ（done）をリセットしておく。次に、“func_list”のいずれかの要素に対して“coder”の処理が行われている限り、“func_list”のすべての要素に対してコード化関数を呼び出す。コード化処理はコードの形成と出力ポートに接続された信号線の型を決定するため、コード化処理が行われたことは新たな信号線の型が決定されたことを意味し、これを入力ポートに接続する新たな機能ブロックのコード化処理が可能となるためである。
【００４６】
コード化関数内部の処理フローを図１（ｂ）に示す。この関数は、コード化の対象となる機能ブロックに対して既に処理が完了していたら何もせずにfalseを値として呼び出し元に帰る。また、機能ブロックのすべての入力ポートをチェックし、接続されているいずれかの信号線の信号源である機能ブロックのコード化処理が完了していない場合も、同じようにfalseを値として処理を終了する。これらいずれでもない場合は、コード化処理を行い、出力ポートに接続された信号線の型を決定し、値trueをもって呼び出し元に帰る。
【００４７】
つぎに、コード化関数のコード化処理の内容について説明する。
【００４８】
並列論理回路の記述は、いくつかの階層に分けて考えることができ、抽象度の高い階層で記述された論理仕様を抽象度の低い階層の使用記述に変換することが論理設計支援システムの機能である。この発明は、機能ブロックを信号線（リンク）で接続するFBD（ファンクション・ブロック・ダイアグラム）レベルの論理仕様記述をRTL（レジスタ・トランスファー・レベルまたはレジスタ・トゥ・ロジック）レベルの論理記述に変換することを目的としている。RTLレベルは、比較的単純な論理をクロック信号で同期駆動されるレジスタを介して接続した形式で表現される。RTLレベルの回路記述はVerilog
HDLなどのハードウエア記述言語により表現することができる。さらにこの下の階層に、半導体チップ内部の具体的な配線を規定するネット・リストのレベルがある。
【００４９】
FBDレベルの記述を入力とする論理設計支援システムは、FBDレベルの記述から直接ネット・リストを形成しているように外部からは見えるが、その内部処理は一般的にいくつかの中間段階を経由して行われる。本発明の趣旨は、FBDレベルの記述からRTLレベルの論理記述に変換する部分にあるため、以下の説明はこの部分に絞っておこなう。また、本発明の処理の出力となるRTLレベルの論理記述としてVerilog
HDLによる記述を例に説明するが、ハードウエア記述言語による表示は本発明を構成する必須要件ではなく、装置内部の適切なデータ構造を用いて後段の処理に処理結果を引き渡すことも可能であることは言うまでもない。
【００５０】
Verilog HDLでは、論理をいくつかのモジュールに分割して記述する。そこで論理記述をモジュールのリストとして出力することとする。なお、Verilog
HDLでは、一つのモジュール記述を利用して複数のエンティティ（デバイス内に配置される論理ブロック）を配置することができるが、今回説明している例ではタイミング制約を個々のモジュール記述内部で解決するため、配置されるエンティティごとにモジュール記述を行うようにしている。これは、同一の処理を行うモジュールであってもエンティティ毎に異なるタイミングの信号源に接続されるため、異なる箇所にパイプライン・レジスタが挿入される可能性があるためである。
【００５１】
“Module”クラスは以下のように定義されている。
1:    public
ref class Module
2:    {
3:    public:
4:        Module()
5:        {
6:            inports
= gcnew List<WirePair^>;
7:            outports
= gcnew List<WirePair^>;
8:            nodes
= gcnew List<Node^>;
9        }
10:    private:
11:        String^ name;
12:        int id;
13:        List<WirePair^>^ inports;
14:        List<WirePair^>^ outports;
15:        List<Node^>^ nodes;
16:    };
【００５２】
上記リストにおいて、１１行目はモジュールの名称であり、１２行目はモジュールを管理するためのユニークな番号である。出力されるVerilog
HDLコードを記述する際には、モジュール名として上記モジュールの名称と番号を組み合わせた名前を使用し、それぞれのモジュールに異なる名称が与えられるようにする。行１３および行１４には、モジュールの入出力ポートとなる“WirePair”オブジェクトのリストが格納される。これらのリストの要素であるクラス“WirePair”は、二つの“Wire”クラスオブジェクトの対であり、モジュール内部の信号線である“Wire”オブジェクトと、配置されたモジュールのポートに接続される上位モジュールの信号線である“Wire”オブジェクトが、それぞれ格納される。
【００５３】
上記リストの行１５に記述されている“Node”クラスオブジェクトのリスト“nodes”の各要素は、Verilog HDLで記述した際のそれぞれの行に対応する論理単位であり、パイプライン化の単位として出力側にレジスタが挿入される可能性がある、具体的な処理内容を規定するものである。
【００５４】
クラス“Node”の定義は次のようになされている。
1:    public
ref class Node
2:    {
3:    public:
4:        Node(){}
5:    private:
6:        Wire^
left_wire;
7:        String^
code_str;
8:        List<ModWire^>^
right_wires;
9:        double
delay;
10:    };
【００５５】
上記リストにおいて、６行目に定義される“left_wire”はこの論理単位の出力線であり、最終的なVerilogコードに展開される際に、クロック非同期処理に展開される場合にはVerilog
HDLのキーワード“wire”で定義される信号線に、クロック同期処理に展開される場合にはVerilog
HDLのキーワード“reg”で定義されるレジスタとなる。
【００５６】
上記リスト７行目の“code_str”は、Verilogコードに展開される際に右辺におかれる式をフォーマット文字列の形で記述するものである。フォーマット文字列は.NET
Frameworkにおいて“{0}
+ {1}”のような文字列で表現され、“String::Format(“{0} + {1}”, a, b)”等とすることにより“{0}”、“
{1}”の部分に変数aおよびbに格納された文字列が代入される。上記リストでは、これに代入される文字列は８行目に記述されている“ModWire”クラスオブジェクトのリストの要素から形成される。
【００５７】
“ModWire”クラスは次のように定義されている。
1:    public
ref class ModWire
2:    {
3:    public:
4:        ModWire(){}
5:    private:
6:        Wire^
wire;
7:        String^
ope;
8:        int
ex_left, ex_right;
9:        Node^
parent;
10:    public:
11:        virtual String^ ToString() override;
12:    };
【００５８】
“ModWire”クラスは“Wire”クラスに修飾を加えるクラスである。Verilog
HDLの右辺式に現れる変数は、Wire名が単独で使用される場合もあるが、これを上位側あるいは下位側にビット拡張したり、一部のビットのみを取り出したりして用いられる場合も多い。“ModWire”クラスはこのような記述を単純化するためのものであり、上記リスト６行目に書かれた“Wire”オブジェクトを、８行目に指定された二つの整数により左右にビット拡張し（これらの整数値が負なら縮小し）、７行目に示された単項演算子“ope”を作用させることを指定する。これをVerilog
HDLの右辺式に記述する際の文字列形式は、１１行目に示されるオーバーライドされた文字化関数“ToString”を作用させることによって与えられる。９行目に格納されている親である“Node”オブジェクトへのポインタは、ワイヤを入力側にたどって“Node”オブジェクトにアクセスする際に用いられる。
【００５９】
次に、コード化関数の処理内容について、加算機能ブロックに対応付けられるコード化関数を例に説明する。
【００６０】
加算機能ブロックのコード化は、入力信号線の型によって３つの異なる方式で行われる。図２は加算機能ブロックをコード化する際のブロック内部の構造を示すもので、（ａ）は入力信号がいずれも指数部をもたない場合のコード化を、（ｂ）は一方の入力信号が誤差を含まず他方が指数部をもつ場合のコード化を、（ｃ）はその他の場合のコード化を示している。なお、ここでは誤差を含まない信号線は指数部をもたないことを前提としており、（ｂ）における誤差を含まない側の信号は仮数部（m2）のみからなることを前提としている。また、双方の入力信号が指数部をもたない場合は（ａ）に示す形でコード化が行われるため、（ｃ）の形でコード化が行われるのは、入力信号の少なくとも一方が指数部をもち、かつ双方が誤差をもつ場合に限定される。
【００６１】
図２の矩形で表示された部分は“Wire”クラスのオブジェクト（これを「ワイヤ」と呼ぶ）に対する演算を表す。ワイヤに対する演算は、様々な機能ブロックのコード化で共通して使用されるため、あらかじめワイヤに対する演算をコード化する関数（「ワイヤレベルのコード化関数」と呼ぶ）の標準的なものを準備しておく。たとえば、ワイヤの加算コードを形成するための関数のヘッダは次のように定義されている。
static Wire^ wire_add(List<Node^>^ nodes, Wire^ in1, Wire^
in2);
入力信号が供給されるワイヤへのポインタを引数“in1”および“in2”に与えてこの関数を呼び出すと、演算を行うための中間コードが引数にポインタを与えた“Node”クラスのリストに追加され、関数内部で確保・定義された出力ワイヤへのポインタが関数値として返される。
【００６２】
ワイヤの加算コードを出力する関数の内部処理は比較的単純である。まず、出力ワイヤの領域を確保し、型属性値を設定する。出力ワイヤの最大値は二つの入力ワイヤの最大値の和で与えられ、最小値も同様に入力の最小値の和で与えられる。出力の定数部は二つの入力ワイヤの定数部の和で与えられる。つぎに、それぞれの入力の実装ビット幅（最大値と最小値がともにゼロの場合、実装ビット幅は０となる）の組合せにより、それぞれ次の形で符号反転フラグの設定と中間コードの形成が行われる。
・  双方の実装ビット幅が０の場合：コードは形成されない。また、符号反転フラグは意味をもたない。
・  一方の実装ビット幅のみが０の場合：実装ビット幅が０でない側の入力を出力にコピーするコードを形成する。符号反転フラグも同じものがコピーされる。
・  双方の実装ビット幅が０でない場合：出力の符号反転フラグには第一の入力のものがコピーされる。入力の符号反転フラグが双方同じ場合は加算コードが出力され、異なる場合は減算コードが出力される。
【００６３】
図２および図３で用いられているワイヤレベルのコード化関数は以下のとおりである。
add：加算
shift：シフト
sub：減算
mux：マルチプレクサ（信号線の選択）
sgn：符号のとりだし
abs：絶対値化
or：ビットごとの論理和
mul：乗算
encode：コード化（最上位ビットのとりだし）
【００６４】
機能ブロックに対するコード化関数は、入力信号の型情報からこれを構成するワイヤの型を得、入力側より順にワイヤレベルのコード化関数を呼び出す。ワイヤレベルのコード化関数の引数としてコードを書き込むために与えるクラス“Node”のオブジェクトのリストへのポインタには、全体のコード化結果を格納するクラス“Module”オブジェクトのリスト（これを“module_list”とする）の要素のなかの適切な“Module”オブジェクトの“Node”リストが設定される。たとえば、トップモジュールに結果を格納するためには、“module_list[0]->nodes”をワイヤレベルのコード化関数の引数に指定すればよい。機能ブロックの出力信号線の仮数部と指数部に値を代入する形で呼ばれたワイヤレベルのコード化関数は、機能ブロックの出力信号線の型を決定する。こうして、出力の信号型が自動的に決定され、かつ機能ブロックは与えられた入力信号線の型に対応する中間コード（ノードリスト）に変換される。
【００６５】
次に、ワイヤレベルのコード化関数を用いて機能ブロックをコード化する手順について、図２に示した加算機能ブロックのコード化を例に説明する。図２（ａ）は、入力信号の数値型がいずれも指数部をもたない場合のコード化方法を示すものであって、双方の入力信号の仮数部に対応するワイヤm1およびm2を入力としてワイヤレベルで加算コードを形成する手続き“add”を呼び出すことでコード化が行われることを示している。ワイヤレベルのコード化関数addが形成する出力ワイヤオブジェクトは加算機能ブロック出力信号の仮数部m3となる。出力信号の指数部は存在しないためヌルポインタが与えられる。また、不確定指標“certain”は、入力のいずれか一方が誤差を含む場合に出力も誤差を含むものとして設定される。ワイヤレベルのコード化関数“add”は演算に必要な中間コードを形成するので、これをモジュールリストの適切な部分に与えればよい。
【００６６】
図２（ｂ）は、第一の入力信号が誤差を含まず、第二の入力信号が誤差を含みかつ指数部を有する場合の加算機能ブロックのコード化手順を示したものである。誤差を含まない数値型は指数部をもたないため、第二の入力信号が指数部をもたない場合は双方の入力信号とも指数部をもたないことを意味し、（ａ）の手順が用いられる。また、双方が誤差を含み、少なくとも一方が指数部を有する場合には（ｃ）の手順が使用される。
【００６７】
一方の入力信号のみが誤差を含む場合は、誤差を含まない側の信号を適宜シフトして誤差を含む信号と桁合わせする。このコード化を行うのが第２図（ｂ）に示された左側のワイヤレベルのコード化関数“shift”であり、第一の信号の仮数部m1を第二の信号の指数部e2の示す桁数だけ逆方向へのシフトを行う。これに第一の信号の仮数部m2を加算した信号が出力信号の仮数部m3となる。出力信号の指数部e3には第二の入力信号の指数部e2がコピーされる。
【００６８】
双方の入力信号が誤差を含み少なくとも一方が指数部を伴う場合には、図２（ｃ）のフローに従って加算機能ブロックのコード化が行われる。この場合は、指数部が等しくなるように仮数部のシフトを行った後に加算する必要がある。シフトは指数部の値の小さな側の入力信号の仮数部に対して行い、双方の指数部の値の差だけ仮数部の右シフトを行う。
【００６９】
図２（ｃ）では、まずシフト数を決定するため双方の入力信号の指数部e1とe2の差を演算するワイヤレベルのコード化関数“sub”を呼び出す。差の符号が同じく“sgn”によってとりだされ、セレクタ（マルチプレクサ）に相当するワイヤレベルのコード化関数“mux”を３つ用いることで、入力信号の仮数部（m1、m2）のシフトを行う側とシフトを行う側をそれぞれ選択し、出力信号の指数部e3を値の大きな側の入力信号の指数部（e1またはe2）をコピーすることで形成する。シフトは常に右シフトであるため、絶対値を形成するワイヤレベルのコード化関数“abs”を呼び出して絶対値を表す信号線を形成し、これをシフトのコード化関数“shift”に与える。最後にシフトを行った結果とシフトを行わない側の入力信号の仮数部を加算するコードを“add”により形成し、これを出力信号の仮数部m3とする。
【００７０】
セレクタによる信号選択を行う際には、出力信号線の属性を一つに決めるため、入力信号の型を定数部も含めて一致させておく必要がある。また、符号のとりだしや絶対値化に際しては定数部と変数部を合計した値に対して処理する必要がある。これらの処理を行うコードは、それぞれのワイヤレベルのコード化関数の内部でも必要に応じて形成されるが、複数のワイヤレベルのコード化関数内部で同じ処理コードを個別に形成することは非効率的であるため、複数のワイヤレベルのコード化関数で共通に行われる処理は事前に行っておくことが好ましい。図２（ｃ）には記載していないが、双方の入力信号線の指数部（e1およびe2）に対しては定数部を取り除く処理を事前に行っておくことが好ましく、双方の入力信号の仮数部（m1およびm2）に対しては双方の入力型を包含する（必要かつ十分な大きさの）型に変換する処理を事前に行っておくことが好ましい。
【００７１】
また、図２には示されていないが、入力信号が異常フラグを含む場合、コード化関数は出力信号にも異常フラグを形成し、入力信号の異常フラグの状態に基づいて出力信号の異常フラグを演算するコードを出力する。加算機能ブロックの場合、この処理は次のようになる。
・  双方の入力信号に異常フラグがない場合は出力の異常フラグは形成されない。
・  一方の入力信号のみが異常フラグをもつ場合には、この値を出力の異常フラグに代入するコードを出力する。
・  双方の入力信号に異常フラグがある場合には、出力の異常フラグには入力の異常フラグの論理和が出力される。
このシステムは、オーバーフロー異常フラグとアンダーフロー異常フラグの双方がセットされている場合、数値化不能異常であるとしている。上記の演算によれば、入力信号の一方がオーバーフローし他方がアンダーフローしている場合の出力は双方のフラグがセットされるため数値化不能異常を意味することとなる。オーバーフローした数値とアンダーフローした数値の和をゼロとする定義もあり得ようが、オーバーフローおよびアンダーフローがどの程度の幅で生じているかを知る手だてはなく、これらの和がいかなる値ともなりえるため、この演算結果を数値化不能異常とする上記手法はより安全であるといえる。
【００７２】
図２に例示した加算器は、出力信号の型を演算結果に含まれる誤差に基づいて決定しているが、さらに、あらかじめ定められたレベルを超える誤差を後段に伝達しないように右シフトされた形で演算結果を出力するよう構成している。後段に伝達される誤差を規制することは、出力信号の精度が保証されるという長所があるが、信号線のビット幅に余裕がある場合にも規定量以上の誤差を含むと判断される桁はシフトアウトされて後段には伝達されない。こうして失われる桁は、原理的にはノイズのみを含み有効な情報を含まないが、アルゴリズムによっては後段で誤差のキャンセルが期待される場合もある。このような効果を利用する際には、出力信号の型は演算結果に含まれる誤差に基づいて決定する一方で、信号線の幅が許す限りの信号を後段に伝達するようにすればよい。この場合の具体的処理内容は、出力信号の上位桁のゼロを除去するようにシフト演算を行う形で出力信号を形成する構成となる。
【００７３】
図３は第二の例として、誤差を含む信号線が入力される乗算機能ブロックをコード化する際に使用されるフローを概念的に示したものである。仮数部m1およびm2は乗算器“mul”に与えられるとともに、双方の入力信号を通して最上位となる有効ビットの位置がビットごとの論理和“or”および符号化器“encode”によって求められる。最上位の有効ビットは他方の誤差に乗じられてこれを拡大するため、乗算結果を有効ビット最上位の位置に応じて右シフトしたものを結果の仮数部m3とする。また、このときシフトされる数は双方の入力信号の指数部e1とe2の和に加算され、乗算結果の指数部e3を形成する。図３は概要を説明するために付随的処理が省略されている。たとえば、乗算および論理和に先立って定数部とビットパターン部は一体化される必要があり、m1もしくはm2が０でない定数部と１以上の幅のビットパターン部の双方を含む場合には加算のためのコードを出力しなければならない。また、最上位ビットを求めるための論理和に先立ち、それぞれの値を絶対値化する処理も必要である。図３の例で、前節に述べた信号線の幅が許す限りの信号を後段に伝達するようにコード化する際は、最上位ビットの検出を乗算器“mul”の出力で行い、オーバーフローが生じない最低の幅だけ右シフトを行うようにすればよい。
【００７４】
ワイヤレベルのコード化関数が形成するコードは引数にポインタを与えた“Node”オブジェクトのリストに追加される。機能ブロックのコード化関数は、コードを格納すべき領域へのポインタを引数に与えて所望のワイヤレベルのコード化関数を順次呼び出すことで、処理に必要なコードのリストが得られる。“Node”オブジェクトのリストはRTLレベルの論理記述に相当し、本発明の目的とする形式である。したがって、この形式からVerilog HDLのソースコードを形成する部分は本特許の趣旨ではないが、本特許の実施にあたって必要な部分ではあるため、以下その概要を説明する。
【００７５】
ここで解説している論理設計支援装置の出力形式であるVerilog HDLのソースコードはモジュール定義として記述される。モジュール内部には他のモジュールを配置することが可能であり、配置されるモジュールの本体定義は上位のモジュール定義の外側（モジュール定義の終了を示すendmodule文の後）で定義される。最上位のモジュールをトップモジュールと呼び、その内部に配置されるモジュールをサブモジュールと呼ぶ。Verilog
HDLによるコード記述は、サブモジュールを使用しなくても可能であるが、個々の機能ごとにサブモジュールとして記述したほうがソースコードの可読性が高く、設計者による検証が容易になるという利点がある。しかし、ソースコードを人が読むことが期待されていないシステムであれば、強いてサブモジュールに分割して記述する必要はない。以下は、機能ブロックごとにサブモジュールに分割する手法を例として説明を続ける。
【００７６】
システムが複数のモジュールで記述されることから、出力する中間コードもモジュールのリストの形に形成する。入力は機能ブロックのリストであり、それぞれ次のように宣言されている。
List<Func^>^ func_list;
List<Module^>^ module_list;
論理設計支援装置の主要な機能は、“func_list”を“module_list”に変換することであるともいえる。前述したように、“Module”クラスのオブジェクトには、モジュールの入出力ポートに対応する“Wire”クラスオブジェクトの対（ペア）のリスト“inports”および“outports”と、モジュール内部の論理要素の記述に対応する“Node”クラスのオブジェクトのリストが含まれている。後者は、“Node”クラスのオブジェクトのリストへのポインタを与えてワイヤレベルのコード化関数を呼び出すことで、呼び出された関数内で必要なコードがリストに追加される。入出力ポートに対応する“Wire”クラスのオブジェクトのペアのリストは、機能ブロックに接続される信号線に含まれる個々のワイヤ名称を外部名とし、これに対応する内部名（図２の加算器の例では第一の入力信号線の仮数部ワイヤ名をm1、指数部ワイヤ名をe1、第二の入力信号線のそれぞれをm2、e2、出力信号線のそれぞれをm3，e3としている）として、外部名と内部名を組み合わせたペアを入出力ポートリスト“inports”および“outports”に追加すればよい。
【００７７】
“Node”クラスのオブジェクトは、Verilog
HDLに展開した際にソースリストの行を形成する情報を含んでいる。Verilog HDLの主要な文は定義分と代入文であり、前者はポートの定義、ワイヤの定義、レジスタの定義のいずれかであり、後者はクロック信号に同期する代入文および常時値が代入される非同期代入文に分けることができる。これらは“Wire”クラスオブジェクトの属性によって使い分けがなされる。
【００７８】
“Wire”クラスの定義は前述したが、その際にはコード形成に関わる部分を省略したので、これらを以下に掲げる。
1:    bool
done, ext_in, ext_out;
2:    Node^
src;
3:    List<ModWire^>^
dests;
4:    bool
registered;
5:    int
clock_delay;
6:    double
logic_delay;
１行目のブール値のうち、“done”は処理完了を示すフラグ、“ext_in”は入力ポートに接続されるワイヤであることを示すフラグ、“ext_out”は出力ポートに接続されたワイヤであることを示すフラグである。また、行２の“src”と行３の“dests”は、ワイヤへの信号の供給源と出力先を表すポインタで、信号源が一つに限られることから“src”はノードへのポインタとして与え、出力先は複数許容されることから、このワイヤを参照している“ModWire”オブジェクトへのポインタのリストとして保持されている。“ModWire”オブジェクトには親のノードへのポインタが含まれているため、これをたどることで信号出力先のノードに到達することが可能である。
【００７９】
各ワイヤ上の信号が有効になるタイミングは、上記リスト５行目のクロックディレイと６行目のロジックディレイの二つで規定される。ロジックディレイは論理演算を含むノードを経由する毎にノードに設定された値が加算される。また、クロックに同期して値がセットされるレジスタを経由する毎にクロックディレイがインクリメントされ、レジスタの出力信号線に相当するワイヤのロジックディレイはゼロにリセットされる。
【００８０】
モジュールリストが形成されたのち、トップモジュール（モジュールリストの先頭の要素に割り当てられている）の外部入力ポートに接続されたワイヤのタイミングがまずセットされる。通常はこれらの値はいずれもゼロにセットされるが、入力信号のタイミングが異なる場合は適切な値を与える。タイミングの設定が完了したら、そのワイヤオブジェクトの “done”フラグをセットする（以後も同様である）。
【００８１】
つぎに、中間コードとして出力されたすべての“Module”オブジェクトのリストであるmodule_listのすべての要素に対して、これに含まれる“Node”リストであるnodesと入出力ポートを表す“WirePair”オブジェクトのリストであるinportsとoutportsのすべての要素がサーチされる。nodesの各ノードについて、すべての入力ワイヤの“done”フラグがセットされていたら、右辺の“ModWire”リストに指定された入力ワイヤの最も遅いロジックディレイと、ノードごとに与えられるロジックディレイとを加算して左辺ワイヤのロジックディレイとする。この値がタイミング制約を満足しない場合（論理を駆動するクロック周波数から要請される規定値を上回る場合）は、それぞれの入力ワイヤの信号源側にレジスタを挿入し（registeredフラグを立て）、クロックディレイをインクリメントしてロジックディレイをリセットする。なお、ノードのすべての入力ワイヤのクロックディレイは等しいことが要請され、これが異なる場合には、クロックディレイの小さな側の入力ワイヤに必要な数のレジスタを挿入してクロックディレイを一致させる。入出力ポートに対しては、信号の流れに従って、ペアを構成するワイヤのディレイ情報がコピーされる。
【００８２】
フィードバックループの出力信号に関しては、ループの信号源よりも若いクロックディレイ信号と共にノードに入力されることが期待されるため、フィードバックループ機能ブロックを経由した際には機能ブロックに対して設定された所定量だけクロックディレイが減算される。“Module”クラスオブジェクトのポートリストに関しては、信号源に相当する側のワイヤのタイミングが設定されていたら、これと対であるワイヤのタイミングも同じ値に設定する。この操作を変化が生じなくなるまで繰り返し行うことで、すべての“Wire”オブジェクトのタイミングが設定され、必要な個所へのレジスタ挿入が完了する。
【００８３】
最後に、モジュールリストおよびその内部のノードリストがVerilog HDLに変換され、テキストファイルに出力される。この工程は、概ね次の手順によって遂行される。
・  トップモジュールのノードリストより、順に以下の操作を繰り返す。
・  それぞれのモジュールの入出力ポートリストより、モジュール定義の先頭部分および入出力ポート定義部分が形成される。
・  出力ワイヤのregisteredフラグが立っているものについてはレジスタ宣言が行われる。
・  registeredフラグがセットされていない場合には、外部出力ポートでないものについてはワイヤ宣言が、外部出力ポートについてはアサイン文が記述され、等号の右辺にcode_strに従ってコードが記述される。
・  サブモジュールの名称と識別番号およびと入出力ポートリストからモジュール配置コードが形成される。
・  ノードリストの出力ワイヤのregisteredが立っているものがある場合には、クロック同期コードが形成される。具体的には、共通のクロック同期文が形成され、その内部にレジスタへのノンブロッキング代入文（演算子“<=”を用いたクロック同期代入文）が記述される。
・  それぞれのモジュールに対する記述が終了したら、モジュールの終了コード（endmodule文）を出力した後、次のモジュールに関して同様のコード展開を繰り返す。
【００８４】
以上解説した手順により、基本的な演算機能を有する論理ブロックを互いに接続した機能ブロック線図（FBD）を、内部の信号線表現形式を最適化した形でRTLレベルの中間形式に変換し、タイミング制約を満足するようにパイプライン化を行って、Verilog
HDLコードに変換する処理が行われる。内部信号線の型属性は、オーバーフローを生じずかつ有効な情報を失うことなく、実装される信号線のビット幅が最小となるよう、自動的に最適化される。このため、設計者の手を煩わせることなく、最小規模の論理回路で所望の論理演算機能を実現することが可能である。
【実施例１】
【００８５】
図４〜８は、本発明を応用した並列論理回路設計支援システムの一例を示すものである。このソフトウエアはグラフィック・ユーザ・インターフェースにより簡単な操作で機能ブロックを表形式に配置してこれらの間を接続することを可能としている。
【００８６】
図４は機能ブロックを選択する機能を示したもので、“add
func”と表示されたボックスの右側をクリックすることで機能ブロックの一覧が表示され、必要なものをマウスでクリックすることで選択された機能ブロックが表中に配置される。ここでは、加算機能ブロックを選択した例について説明する。
【００８７】
図５は、加算機能ブロック（“Add”）が配置された状態を示すもので、下の広いウィンドウ（メイン・ウィンドウと呼ぶ）のそれぞれの行に、配置された加算機能ブロックの名称と、入出力ポートの状態が表示されている。ここで、配置された加算機能ブロック（“Func: Add U1”）の入出力ポートは未接続状態であるため、“*** NC ***”という表示がなされ、接続をすべき状態であることを示している。未接続の入力ポートは左上の窓に表示されており、このウィンドウでいずれかの行を選択した状態で、メイン・ウィンドウの出力ポートをダブルクリックすることで双方を接続することができる。また、メイン・ウィンドウで未接続のポートをダブルクリックすると、自動的に外部入出力ポートが生成されてこれに接続が行われる。
【００８８】
図６は、メイン・ウィンドウでそれぞれの未接続ポートの表示された行をダブルクリックすることにより、加算機能ブロックのそれぞれの入出力ポートに外部入出力ポートを接続した状態を示す。外部入力ポートの数値型は設計者が与える必要があり、この設定が完了していないことを示すため、型定義（“Typedef”）行に“***
TBD ***”が表示される。
【００８９】
メイン・ウィンドウの型定義行をマウスでダブルクリックすると、図７に示された型編集窓が開く。この窓で、誤差の有無（“uc”チェックボックス）、仮数部（“man”）と指数部（“exp”）の定数項、最小値、最大値等を設定し、設定が完了したら“close”ボタンをクリックする。
【００９０】
図８は、型の設定が完了した状態を示している。このソフトウエアは、何らかの操作が行われるごとに可能な限りコード化関数を呼び出し、その結果を表示するようにしている。このため、図８には設定が完了したすべての接続の型が表示されている。ここでは、設計者が設定したのは入力ポートの型だけであるが、型決定機能により加算機能ブロックの出力ポートの数値型も決定されていることに注目されたい。多数の機能ブロックを配置した場合も同様の手順が繰り返され、すべての接続に対して型が自動決定される。
【実施例２】
【００９１】
論理仕様はまた、言語を用いて表現することも可能である。以下は、言語形式で論理仕様を入力する一例を示す。ここでは信号処理に特化した特殊な言語仕様で表現した例について説明するが、他の言語仕様を用いた場合も同様な処理が可能である。
1:    func1.(
2:        out1,
3:        out2
4:        )
(
5:        in1,
6:        in2)
7:        a
= in1 * in2 + in1 / in2
8:        b
= 1 / a
9:        out1
= a + b
10:        out2 = func2(a, b)
11:        func2(in3, in4)
12:            func = in3 - in4
13:    (EOF)
【００９２】
上記リストの構成要素は次のようになっている。
・  関数の定義：１行目および１１行目。定義範囲はこの文よりもレベル（行頭の空白の数）の大きい文が続く限りとされる。したがってfunc1の定義範囲は１行目から１２行目までであり、func2の範囲は１１行目から１２行目（ファイルの終わり）までとなる。func2の定義はfunc1の定義範囲に含まれるため、func2はfunc1によってのみ参照される。なお、関数内部の名前の有効範囲はその関数の内部のみであり、func2の内部で定義された名前（ここではin3およびin4）はfunc2の外部からは参照することができない。
・  出力ポート：関数名そのもの、または関数名の後の“.”に続けておかれたリストに記述される。リストは“()”で囲まれた中に“,”で区切って要素を並べる形で記述される。
・  入力ポート：関数名、ないし出力ポートリストがある場合はそのあとに記述される。複数の入力ポートがある場合はリスト形式で記述する。
・  継続行：閉じかっこ以外で終わる行は次行に継続する。行２〜６は行1の継続行である。
・  代入文：代入文は左辺と右辺を“=”で接続したものであり、左辺には信号線名が、右辺には式がおかれる。右辺の式は演算記号で区切られた信号線名、定数、関数呼び出しであり、コンパイラの式解析機能により、機能ブロックに対応する単純な式に変換される。すなわち、行行7は以下の代入文に分割される
7.1:        a1 = in1 * in2
7.2:        a2 = in1 / in2
7.3:        a = a1 + a2
これらの代入文は、左辺を出力ポートとし、右辺を入力ポートとする機能ブロックに変換され、それぞれの機能ブロック間が信号線 “a1”および“a2”で接続される。
・  内部関数の定義：11行目は内部関数の定義 であり、この部分はそれ自体が一つの機能ブロックとして形成される。
・  ファイルの終わり：上記リストでは13行目に(EOF)と記したが、この文字列がソースファイルに記述されるわけではなく、オペレーティング・システムによってファイルの終わりが検出される。
【００９３】
上記言語仕様の一つの規約として、右辺に用いられる変数名（信号線の名称）は、これが現れる以前に（ソースリストでは上部に）記述された行の左辺もしくは入力ポート記述部分に現れていなければならないことを要請する。言語を用いて記述された論理仕様は行ごとに機能ブロックとその接続（FBD）に変換され、型の自動決定に際しても信号線の接続状態がトレースされるため、この要請は機械処理をするうえでは不要である。しかしながらこの要請をおくことにより、信号は常に上の行から下の行へと流れることが保障されるため、設計者がソースコードを理解しやすいという利点がある。なお、フィードバックループに対しては、以下に示すようなダミーの代入文を記述し、数値型を決定するための基準となる信号線と上位および下位へのビット拡張、およびクロックディレイを与えるようにする。
c = forward(4, a, 0, 0)
ここで、forwardは前方参照のためのダミー代入文であることを示すためのキーワードであり、引数リストの最初の要素（4）はクロックディレイ、二番目の要素（a）は型決定の基準となる信号線名、その後の要素は信号線の上位および下位へのビット拡張幅を指定している。型決定の基準となる信号線名がこの行以前に左辺もしくは入力ポート定義部分に現れていることが要請されることは、前述した要請と同様である。
【００９４】
この例で示された論理仕様の言語記述において注目すべき点は、通常のコンピュータ用高級言語と異なり、扱われている変数（信号線）の型指定が全く行われていない点である。この記述を実装する論理に変換する際には数値型は指定されなければならないが、この指定は変換操作（コンパイル）の際に入力信号の数値型を指定する形で行えばよい。このように構成することの利点は、論理仕様を作成する際に信号の数値型に気を配る必要がなく設計作業が簡素化されることに加え、作成された論理仕様をそのままの形で信号形式の異なる種々の用途に使用できる点があげられる。
【００９５】
設計者が記述した論理仕様は、コンパイラによって最終的には実装形式まで変換される。コンパイルの開始にあたって入力信号の数値型指定が必要であるが、これはソースファイル中にコンパイラ指示行として含めてもよいし、コンパイラを起動した後に設計者との対話形式で指定するようにしてもよい。コンパイラは、構文解析として知られている公知の技法により言語記述に含まれる式を単純な演算要素に分解し、機能ブロックを信号線で接続したFBD形式に変換する。ついで、本発明の手法を用いてそれぞれの信号線の数値型を決定し、機能ブロックを単純な論理要素と信号線に分解し、これをRTL形式に変換した後、チップ内部の配線に対応するネット・リストに変換する。
【産業上の利用可能性】
【００９６】
以上詳細に説明したように、本発明の手法を用いれば、並列論理回路の設計に際して、設計の煩雑化を招くことなく最小の論理構成で回路を実装することが可能であり、精度・安全性に優れる浮動小数点形式の数値型を含む論理回路も容易に形成することが可能である。並列論理回路は、今日ASICやFPGAなどの大規模集積回路を用いた信号処理に数多く使用されており、これらを用いた計測・制御や画像処理も幅広い分野で使用されている。これらの分野では多くの用途で精度・安全性に対する要求が高まっており、本発明の幅広い分野での応用が期待される。
【図１】
2011232963.tif 000003
【図２】
2011232963.tif 000004
【図３】
2011232963.tif 000005
【図４】
2011232963.tif 000006
【図５】
2011232963.tif 000007
【図６】
2011232963.tif 000008
【図７】
2011232963.tif 000009
【図８】
2011232963.tif 000010