[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6. ポート

ポートはユニット間の結合の仲介、パケット転送の仲介を行う。ポートには、 複数の入出力を共用するような結線に相当するportクラスと、仮想チャ ネルに相当するvirtual_channel_inputクラス、 virtual_channel_outputクラスがある。

6.1 portクラス  
6.2 bus_port_baseクラス  
6.3 bus_portクラス  
6.4 virtual_channel_inputクラス  
6.5 virtual_channel_outputクラス  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.1 portクラス

ハードウェアを表すクラス同士の接続に使われる、入出力端子(ポート)を表す クラスである。複数ポート同士を接続すると、接続された全てのポートで共有 される1つの経路が確保される。あるポートからパケットを入力すると、接続 されたポート全てから入力したパケットの参照および取得を行うことができる。

ポートが結合路を占有する状況をシミュレートするために、相互接続されたポー トにはそれぞれ経路内で固有のID番号が自動的に割り振られている。経路の占 有を行いたい場合は、ポートがオーナシップ要求を経路に対して発行する。要 求が衝突した場合、ポートのID番号を元に指定したアルゴリズムに従ってアー ビトレーションを行い、オーナを選定する。経路を使用し終わったオーナは占 有権を放棄することで経路を解放する。

ポート上の一連のパケット転送には、結合路内で一意なトランザクションIDが 自動的に割り付けられる。このトランザクションIDは、オーナが交代するごと に更新される。また、任意の値を設定することもできる。この値はスプリット トランザクションを行う場合に使用する。

結合路は、内部に複数のアービタを格納することができる。無指定では単一の アービタのみが使用できる。複数アービタを使用することで、複数のオーナシッ プを独立に扱うことが可能である。

6.1.1 portクラスの定義  
6.1.2 パケットの送信  
6.1.3 ポートのオーナシップ  
6.1.4 portクラスの使用方法  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.1.1 portクラスの定義

bool is_connected(void) const
ポートが結合済みであれば真を返す。

bool is_connected(const port&) const
ポートが引数で指示されたポートに結合済みであれば真を返す。

bool have_packet(void) const
結線上にパケットが存在すれば真を返す。

void connect(port&)
引数で示されるポートに結合する。

void disconnect(port&)
引数で示されたポートとの結合を切り離す。結合されていない場合は何も起こ らない。

void disconnect(void)
結合を切り離す。結合されていない場合は何も起こらない。

void put(packet*)
パケットを送る。結線上に既にパケットが存在する場合は、新しいパケットで 上書きする。

packet* get(void)
結線上のパケットを受け取り、結線上のパケットを消去する。パケットが受け 取れない(結合相手がいない、もしくはまだパケットが送られてきていない)場 合、NULLが返される。

void clear(void)
結線上のパケットを消去する。

const packet* look(void) const
パケットを参照する。パケットが受け参照できない(結合相手がいない、もし くはまだパケットが送られてきていない)場合、NULLが返される。

bool is_connected_to_asynchronous_unit(void) const
ポートが非同期ユニットに結合済みであれば真を返す。

bool is_connected_to_asynchronous_unit(const asynchronous_unit&) const
ポートが引数で指示された非同期ユニットに結合済みであれば真を返す。

void connect_to_asynchronous_unit(asynchronous_unit&)
引数で示される非同期ユニットに結合する。

void disconnect_asynchronous_unit(void)
非同期ユニットを切り離す。

int id(void) const
ポートのID番号を返す。

void set_id(int)
ポートのID番号を変更する。

bool is_owned(int = 0) const
引数で示されたアービタのポートがどこかのポートに占有されていれば真を返 す。

bool is_owner(int = 0) const
引数で示されたアービタのポートを自分自身が占有していれば真を返す。

void request_ownership(int = 0)
引数で示されたアービタのオーナシップを要求する。

void release_ownership(int = 0)
引数で示されたアービタのオーナシップを放棄する。

int transaction_id(void) const
現在のトランザクションIDを返す。

void set_transaction_id(int)
トランザクションIDを設定する。

void set_number_of_arbitor(int)
アービタ数を設定する。

virtual bool compete(int, int) const
アービトレーションアルゴリズム機能を提供する関数。第一引数に前回オーナ だったポートのID番号、第二引数に競争相手のID番号が示されている。自分の ID番号、引数の情報を元にアービトレーションを行い、競争相手と自分のどち らが勝つのかを決定し、自分が勝った場合は真、相手が勝った場合は偽を返す。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.1.2 パケットの送信

パケットを送る場合、以下の手順で行う。なお、ここでは経路の排他制御は行っ ていない。排他制御を行う場合は、パケットの送受信を行う前後にポートの占 有処理を行わなければならない。See section 6.1.3 ポートのオーナシップ.

  1. パケットを生成する。パケットはnew演算子で生成する。

  2. 入力側のポートにパケットを入力する。生成したパケットへのポインタを入力 側ポートに渡す。putメンバ関数を使う。以後のパケットの実体の扱い はポートに任されるので、ユーザが勝手に開放してはいけない。

  3. 出力側のポートからパケットを取り出せるかどうか確認する。 have_packet関数でポートからパケットを出力できるかどうか確認して おく。

  4. 出力側のポートからパケットを参照する。出力側ポートのlookメンバ 関数を使い、パケットの内容を参照する。パケットが送られていれば、パケッ トを参照することができる。この時点で必要がないと判断されたパケットにつ いては、実際の受け取りを必ずしも行う必要はない。受け取らずに放置された パケットは後続パケットによって上書きされる。なお、放置されたパケットは 後続パケットが到着するまでポート内に残る可能性があるので注意すること。

  5. 出力側のポートからパケットを受け取る。出力側ポートのgetメンバ関 数を使い、パケットの実体を受け取る。パケットが送られていれば、パケット を受け取ることができる。実際の受取りはポインタの受渡しである。使い終わっ たパケットは受け取ったユーザが開放する責任を持つ。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.1.3 ポートのオーナシップ

例えば、複数のプロセッサが共有バスに接続されているようなシステムでは、 複数プロセッサが同時に共有バスに対して書き込みを行おうとする。このアク セスの衝突は排他制御によって回避する必要がある。この排他制御処理を行う ために、ポートには経路の占有処理を行う機能が設けてある。

相互接続されたポートにはそれぞれ経路内で固有のID番号が自動的に割り振ら れている。経路の占有を行いたい場合は、ポートがオーナシップ要求を経路に 対して発行する。要求が衝突した場合、ポートのID番号を元に指定したアルゴ リズムに従ってアービトレーションを行い、オーナを選定する。経路を使用し 終わったオーナは占有権を放棄することで経路を解放する。アービトレーショ ンアルゴリズムはcompete仮想関数によって実装されており、ユーザが 自由にアルゴリズムを変更することができる。デフォルトのアルゴリズムはラ ウンドロビンである。

実際に通信路の占有を行う場合は、例えば以下のような手順を踏む。オーナシッ プの要求や開放は出力フェーズ、状態の問い合わせは入力フェーズでのみ行わ なければならない。

  1. 出力フェーズにて、request_ownership関数でオーナシップを要求する。

  2. 次の入力フェーズにて、is_owner関数でオーナになったかどうか確認 する。オーナになれなかった場合には、再び出力フェーズでオーナシップを要 求し直す。

  3. オーナになっていれば、通信路の占有が行われた。占有した状態で排他的に行 うべき処理を行う。

  4. 処理が終了したら、出力フェーズでrelease_ownership関数を用いオー ナシップを開放する。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.1.4 portクラスの使用方法

portクラスの使用例として、2つのポート間でbus_packetをや り取りするプログラムを紹介する。

 
#include <isis/isis.h>

int main(void)
{
    port a, b;
    a.connect(b);
    packet* pkt = new bus_packet<int>;
    ((bus_packet<int>*)(pkt))->address() = 100;
    a.put(pkt);
    pkt = b.get();
    ((bus_packet<int>*)(pkt))->address()++;
    b.put(pkt);
    pkt = a.get();
    cout << *pkt << endl;
    delete pkt;
    return 0;
}

  1. 結合。まずポートa, bを用意し、両者を結合させる。結合は一方 のポートのconnect関数にもう一方のポートを与えることによって行わ れる。

  2. パケットの送信。アドレス100を表すパケット(pkt)を生成する。

  3. パケットの受信。パケットをポートaに入力し、ポートbから取り 出す。

  4. ackの返送。受け取ったパケットのアドレスを1増加させ、再びポートb に入力する。

  5. ackの確認。ポートaからパケットを取り出し、値を表示する。

  6. 通信終了。使い終わったパケットを開放する。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.2 bus_port_baseクラス

バスに対するインタフェースの役割を果たすクラス。ISIS上でのバスは portクラスとbus_packet_baseクラスの派生クラスにより実装 されているが、これらのクラスを直接アクセスするのは繁雑な作業を要するた め、その複雑さを隠蔽するために用意されている。bus_port_baseクラ スの機能だけを使用してバスにアクセスする様にすることにより、 portクラスとbus_packet_baseクラスに依存しない実装が可能 である。See section 5.2 bus_packet_baseクラス.

このクラスが用意するのは抽象クラスであるbus_packet_baseへのイン タフェースであるため、パケットを生成するような関数は用意されていない。 See section 6.3 bus_portクラス.

const packet_type* look(void) const
バス上のパケットを直接参照する。

address_type address(void) const
アドレスを参照する。

data_type data(void) const
データを参照する。

int total_packet_count(void) const
バースト転送時のデータパケット数を参照する。例えば4ワードの連続転送を 行っている場合、返り値は4である。

int packet_number(void) const
バースト転送時のデータパケットの番号を参照する。4ワードの連続転送で2ワー ド目を転送している場合、返り値は1(パケット番号は0から)である。

bool is_single(void) const
単一ワード転送であれば真を返す。

bool is_multi(void) const
複数ワード転送であれば真を返す。

bool is_ready(void) const
バス上に有効なパケットが存在しなければ真を返す。

bool is_read(void) const
バス上にreadパケットが存在すれば真を返す。

bool is_write(void) const
バス上にwriteパケットが存在すれば真を返す。

bool is_request(void) const
バス上にrequestパケットが存在すれば真を返す。

bool is_grant(void) const
バス上にgrantパケットが存在すれば真を返す。

bool is_ack(void) const
バス上にackパケットが存在すれば真を返す。

bool is_nack(void) const
バス上にnackパケットが存在すれば真を返す。

bool is_data(void) const
バス上にdataパケットが存在すれば真を返す。

bool is_read_request(void)
バス上にread_requestパケットが存在すれば真を返す。

bool is_read_grant(void) const
バス上にread_grantパケットが存在すれば真を返す。

bool is_read_ack(void) const
バス上にread_ackパケットが存在すれば真を返す。

bool is_read_nack(void) const
バス上にread_nackパケットが存在すれば真を返す。

bool is_read_data(void) const
バス上にread_dataパケットが存在すれば真を返す。

bool is_write_request(void)
バス上にwrite_requestパケットが存在すれば真を返す。

bool is_write_grant(void) const
バス上にwrite_grantパケットが存在すれば真を返す。

bool is_write_ack(void) const
バス上にwrite_ackパケットが存在すれば真を返す。

bool is_write_nack(void) const
バス上にwrite_nackパケットが存在すれば真を返す。

bool is_write_data(void) const
バス上にwrite_dataパケットが存在すれば真を返す。

bool is_single_read_request(void) const
バス上に単一ワードのread_requestパケットが存在すれば真を返す。

bool is_single_read_grant(void) const
バス上に単一ワードのread_grantパケットが存在すれば真を返す。

bool is_single_read_ack(void) const
バス上に単一ワードのread_ackパケットが存在すれば真を返す。

bool is_single_read_nack(void) const
バス上に単一ワードのread_nackパケットが存在すれば真を返す。

bool is_single_read_data(void) const
バス上に単一ワードのread_dataパケットが存在すれば真を返す。

bool is_single_write_request(void) const
バス上に単一ワードのwrite_requestパケットが存在すれば真を返す。

bool is_single_write_grant(void) const
バス上に単一ワードのwrite_grantパケットが存在すれば真を返す。

bool is_single_write_ack(void) const
バス上に単一ワードのwrite_ackパケットが存在すれば真を返す。

bool is_single_write_nack(void) const
バス上に単一ワードのwrite_nackパケットが存在すれば真を返す。

bool is_single_write_data(void) const
バス上に単一ワードのwrite_dataパケットが存在すれば真を返す。

bool is_multi_read_request(void) const
バス上に複数ワードのread_requestパケットが存在すれば真を返す。

bool is_multi_read_grant(void) const
バス上に複数ワードのread_grantパケットが存在すれば真を返す。

bool is_multi_read_ack(void) const
バス上に複数ワードのread_ackパケットが存在すれば真を返す。

bool is_multi_read_nack(void) const
バス上に複数ワードのread_nackパケットが存在すれば真を返す。

bool is_multi_read_data(void) const
バス上に複数ワードのread_dataパケットが存在すれば真を返す。

bool is_multi_write_request(void) const
バス上に複数ワードのwrite_requestパケットが存在すれば真を返す。

bool is_multi_write_grant(void) const
バス上に複数ワードのwrite_grantパケットが存在すれば真を返す。

bool is_multi_write_ack(void) const
バス上に複数ワードのwrite_ackパケットが存在すれば真を返す。

bool is_multi_write_nack(void) const
バス上に複数ワードのwrite_nackパケットが存在すれば真を返す。

bool is_multi_write_data(void) const
バス上に複数ワードのwrite_dataパケットが存在すれば真を返す。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.3 bus_portクラス

bus_packetによるバスに対するインタフェースの役割を果たすクラス。 bus_port_baseクラスの派生クラスで、パケットの送信機能が追加され ている。See section 6.2 bus_port_baseクラス.

void send_single_read_request(address_type)
単一ワードのread_requestを発行する。引数はアドレスである。

void send_single_read_grant(void)
単一ワードのread_grantを発行する。

void send_single_read_ack(void)
単一ワードのread_ackを発行する。

void send_single_read_nack(void)
単一ワードのread_nackを発行する。

void send_single_read_data(data_type)
単一ワードのread_dataを発行する。引数はデータである。

void send_single_write_request(address_type)
単一ワードのwrite_requestを発行する。引数はアドレスである。

void send_single_write_grant(void)
単一ワードのwrite_grantを発行する。

void send_single_write_ack(void)
単一ワードのwrite_ackを発行する。

void send_single_write_nack(void)
単一ワードのwrite_nackを発行する。

void send_single_write_data(data_type)
単一ワードのwrite_dataを発行する。引数はデータである。

void send_multi_read_request(address_type, unsigned int)
複数ワードのread_requestを発行する。第一引数はアドレス、第二引 数は転送するワード数である。

void send_multi_read_grant(void)
複数ワードのread_grantを発行する。

void send_multi_read_ack(void)
複数ワードのread_ackを発行する。

void send_multi_read_nack(void)
複数ワードのread_nackを発行する。

void send_multi_read_data(data_type, unsigned int, unsigned int)
複数ワードのread_dataを発行する。第一引数はデータ、第二引数は転 送するワード数、第3引数はデータの通し番号である。

void send_multi_write_request(address_type, unsigned int)
複数ワードのwrite_requestを発行する。第一引数はアドレス、第二引 数は転送するワード数である。

void send_multi_write_grant(void)
複数ワードのwrite_grantを発行する。

void send_multi_write_ack(void)
複数ワードのwrite_ackを発行する。

void send_multi_write_nack(void)
複数ワードのwrite_nackを発行する。

void send_multi_write_data(data_type, unsigned int, unsigned int)
複数ワードのwrite_dataを発行する。第一引数はデータ、第二引数は 転送するワード数、第3引数はデータの通し番号である。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.4 virtual_channel_inputクラス

仮想チャネルへの入力ポートを表すクラス。出力ポートを表す virtual_channel_outputクラスのオブジェクトと組で使用することにより、仮 想チャネルを実現する。仮想チャネル間には指定された個数の仮想的なパケッ トの経路が確保される。それぞれの仮想的なチャネルには指定されたサイズの 待ち行列が付加されており、パケットを一定数格納しておくことができる。ま た、ハンドシェーク機能などもサポートする。See section 6.5 virtual_channel_outputクラス.

6.4.1 virtual_channel_inputクラスの定義  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.4.1 virtual_channel_inputクラスの定義

virtual_channel_input(void)
チャネル数0, 内部バッファサイズ0の入力仮想チャネルを構築する。

virtual_channel_input(size_t a, size_t b)
チャネル数a, 内部バッファサイズbの入力仮想チャネルを構築す る。

bool is_connected(void)
出力仮想チャネルに接続されていれば真を返す。

bool is_connected(const virtual_channel_output&)
引数で示された出力仮想チャネルに接続されていれば真を返す。

void connect(virtual_channel_output&)
引数で示された出力仮想チャネルに接続する。

void disconnect(void)
出力仮想チャネルを切り離す。

size_t channel_size(void) const
仮想チャネル数を返す。

size_t buffer_size(void) const
内部バッファサイズを返す。

void channel_resize(size_t)
仮想チャネル数を変更する。

void buffer_resize(size_t)
内部バッファサイズを変更する。

bool empty(size_t)
引数で示された内部バッファに空かどうか調べる。

bool full(size_t)
引数で示された内部バッファに空きがあるかどうか調べる。

size_t length(size_t)
引数で示された内部バッファ内のパケット数を得る。

packet* get(size_t)
引数で示された内部バッファからパケットを取り出す。

const packet* look(size_t)
引数で示された内部バッファの先頭パケットを参照する。

void del(size_t)
引数で示された内部バッファの先頭パケットを廃棄する。

void clear(size_t)
引数で示された内部バッファを空にする。

void clear(void)
全ての内部バッファを空にする。


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.5 virtual_channel_outputクラス

仮想チャネルへの出力ポートを表すクラス。入力ポートを表す virtual_channel_inputクラスのオブジェクトと組で使用することにより、仮 想チャネルを実現する。See section 6.4 virtual_channel_inputクラス.

6.5.1 virtual_channel_outputクラスの定義  


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.5.1 virtual_channel_outputクラスの定義

virtual_channel_output(void)
出力仮想チャネルを構築する。

bool is_connected(void)
入力仮想チャネルに接続されていれば真を返す。

bool is_connected(const virtual_channel_input&)
引数で示された入力仮想チャネルに接続されていれば真を返す。

void connect(virtual_channel_input&)
引数で示された入力仮想チャネルに接続する。

void disconnect(void)
入力仮想チャネルを切り離す。

size_t channel_size(void) const
仮想チャネル数を返す。

size_t buffer_size(void) const
内部バッファサイズを返す。

void channel_resize(size_t)
仮想チャネル数を変更する。

void buffer_resize(size_t)
内部バッファサイズを変更する。

bool empty(size_t)
引数で示された内部バッファに空かどうか調べる。

bool full(size_t)
引数で示された内部バッファに空きがあるかどうか調べる。

size_t length(size_t)
引数で示された内部バッファ内のパケット数を得る。

void put(size_t, packet*)
第一引数で示された内部バッファへ第二引数で示されたパケットを送出する。

const packet* look(size_t) const
引数で示された内部バッファの先頭パケットを参照する。

void clear(size_t)
引数で示された内部バッファを空にする。

void clear(void)
全ての内部バッファを空にする。


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Masaki WAKABAYASHI on September, 3 2003 using texi2html