[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ここではバスの実装方法と使用方法について述べる。
10.1 バスの実装 10.2 バスの使用方法
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バスは、バス上を流れる情報を表すパケットとパケットの転送路となるバスそ のものの入出力ポートの2つから構成される。
bus_packet_base
クラスで表される。このクラスは抽
象クラスであり、アドレスとデータ以外の状態を内包せず、状態の問い合わせ
関数のみを純粋仮想関数および定義済み仮想関数として提供する。実際の状態
まで含めたパケットを実装するためには、状態を追加した具体派生クラスを使
用する必要がある。純粋仮想関数のみを定義すれば具体派生クラスを実装でき
るが、実行時の関数呼び出しのコストを低減させるためにその他の仮想関数に
ついても再定義した方が良い。See section 5.2 bus_packet_baseクラス.
bus_packet
クラスは、bus_packet_base
の具体派生クラスであ
る。bus_packet_base
クラスで用意されている機能のみを実体化したも
のである。通常のバストランザクションであれば、このbus_packet
ク
ラスで実装可能である。See section 5.3 bus_packetクラス.
port
クラスとbus_packet_base
クラスの派生クラスにより実装されているが、
これらのクラスを直接アクセスするのは繁雑な作業を要するため、その複雑さ
を隠蔽するために用意されている。bus_port_base
クラスの機能だけを
使用してバスにアクセスするようにすることにより、port
クラスと
bus_packet_base
クラスに依存しない実装が可能である。
See section 6.2 bus_port_baseクラス.
bus_port_base
が用意するのは抽象クラスである
bus_packet_base
へのインタフェースであるため、パケットを生成す
るような関数は用意されていない。bus_port
クラスが
bus_packet
によるバスに対するインタフェースの役割を果たす
bus_port_base
クラスの具体派生クラスで、パケットの送信機能が追加
されている。See section 6.3 bus_portクラス.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
bus_packet_base
では、パケットの状態としてrequest、grant、ack、
nack、dataの5つの基本型を設定している。1つのバストランザクションはこれ
らのうちのいくつかのパケットを要求側と応答側で送受信することで行われる。
10.2.1 単独バスマスタ 10.2.2 複数バスマスタ 10.2.3 スプリットトランザクション
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
バスマスタが単独である場合のリードトランザクションとライトトランザクショ
ンの例を示す。パケットの参照はすべてclock_in
フェーズ、パケット
の送信やバスの開放はすべてclock_out
フェーズで行う。
read_request
パケットを発行する。
read_request
パケットを受け取る。
データを送出可能なクロックの1つ前以降のクロックでread_ack
パケッ
トを返す。
read_ack
パケットを受け取る。このパケットを受け取ったら、要求側
は次のクロック以降でデータを受け取れるようにする。
read_data
パケットを送出する。
read_data
パケットを受け取る。
バス上のパケットを消去する。そのまま次の動作に移る場合、このフェーズで 次のパケットを送出してもよい。
write_request
パケットを発行する。
write_request
パケットを受け取る。
データを受け取り可能なクロックの2つ前以降のクロックでwrite_ack
パケットを返す。
write_ack
パケットを受け取る。このパケットを受け取ったら、要求側
は次のクロック以降で書き込むデータを送ることができる。
write_data
パケットを送出する。
write_data
パケットを受け取る。
バス上のパケットを消去する。応答側ではなく要求側に消去させる理由は、要 求側がバスを開放することなく次の動作を行うことを可能にするためである。 そのまま次の動作に移る場合、このフェーズで次のパケットを送出してもよい。
read_request
パケットを発行する。
read_request
パケットを受け取る。
データの送出可能なクロックの1つ前以降のクロックでread_ack
パケッ
トを返す。
read_ack
パケットを受け取る。このパケットを受け取ったら、要求側
は次のクロックからデータを受け取れるようにする。
応答側が最初のread_data
パケットを送出する。
要求側が最初のread_data
パケットを受け取る。
上記のデータの受渡しをデータ数分だけ繰り返す。
データ転送が終わったら、バス上のパケットを消去する。そのまま次の動作に 移る場合、このフェーズで次のパケットを送出してもよい。
write_request
パケットを発行する。
write_request
パケットを受け取る。
データを受け取り可能なクロックの2つ前以降のclock_out
サイクルで
write_ack
パケットを返す。
write_ack
パケットを受け取る。このパケットを受け取ったら、要求側
は次のクロック以降で書き込むデータを送れるようにする。
最初のwrite_data
パケットを送出する。
最初のwrite_data
パケットを受け取る。
上記のデータの受渡しをデータ数分だけ繰り返す。
データ転送が終わったら、要求側がバス上のパケットを消去する。応答側では なく要求側に消去させる理由は、要求側がバスを開放することなく次の動作を 行うことを可能にするためである。そのまま次の動作に移る場合は、このフェー ズで次のパケットを送出してもよい。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
複数のバスマスタが存在する場合は、実際のパケットの送受信を行う前に転送
路のオーナになり、バスを占有して通信を行う必要がある。また、通信終了時
にはバスを開放し、他のバスマスタが次の通信を行えるようにしなければなら
ない。バスの占有処理はport_base
クラスによって実装されている。
See section Port Ownership.
以下にシングルリードトランザクションとシングルライトトランザクションの 例を示す。
オーナシップを要求する。
自分がオーナになれたかどうかを確認する。オーナになれなかった場合は次以 降のクロックで再びオーナシップを要求する。
read_request
パケットを発行する。
read_request
パケットを受け取る。
データを送出可能なクロックの1つ前以降のクロックでread_ack
パケッ
トを返す。
read_ack
パケットを受け取る。このパケットを受け取ったら、要求側
は次のクロック以降でデータを受け取れるようにする。
read_data
パケットを送出する。
read_data
パケットを受け取る。
バス上のパケットを消去し、オーナシップを放棄する。そのまま次の動作に移 る場合、このフェーズでオーナシップを放棄せずに次のパケットを送出しても よい。
オーナシップを要求する。
自分がオーナになれたかどうかを確認する。オーナになれなかった場合は次以 降のクロックで再びオーナシップを要求する。
write_request
パケットを発行する。
write_request
パケットを受け取る。
データを受け取り可能なクロックの2つ前以降のクロックでwrite_ack
パケットを返す。
write_ack
パケットを受け取る。このパケットを受け取ったら、要求側
は次のクロック以降で書き込むデータを送ることができる。
write_data
パケットを送出する。
write_data
パケットを受け取る。
バス上のパケットを消去し、オーナシップを放棄する。そのまま次の動作に移 る場合、このフェーズでオーナシップを放棄せずに次のパケットを送出しても よい。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
スプリットトランザクションを行う場合は、複数バスマスタの場合に行う転送
路のオーナシップの取り扱いに加え、トランザクション途中でバスを開放する
処理が追加される。この処理を行うために、ポートの持つトランザクションID
機能を使用する。この機能はport
クラスで用意されているもので、そ
れぞれのバストランザクションに個別にID番号を割り当てる機能である。
要求側はまずバスのオーナになる。オーナになったら、自分に割り当てられた トランザクションIDを記憶しておいてから要求パケットを送信する。応答側は、 要求を受理したらその時のトランザクションIDを記憶し、即座にgrantパケッ ト(要求を受理可能だが、まだ受理できる状態にないことを示す)を返す。要求 側はgrantパケットを受け取った時点でバス上のパケットを消去し、バスのオー ナシップを一旦開放し、トランザクションIDをチェックしつつackを待つ。応 答側は応答準備が整ったらバスのオーナになり、記憶しておいたトランザクショ ンIDを設定してackを返す。要求側は自分に割り当てられたトランザクション IDであることを確認してからackを受信する。その後の処理は複数バスマスタ の場合と同一である。
以下にシングルリードトランザクションとシングルライトトランザクションの 例を示す。
オーナシップを要求する。
自分がオーナになれたかどうかを確認する。オーナになれなかった場合は、次 以降のクロックで再びオーナシップを要求する。オーナになれた場合は、この トランザクションに割り当てられたトランザクションIDを記憶しておく。
read_request
パケットを発行する。
read_request
パケットを受け取る。この時のトランザクションIDを記
憶しておく。
read_grant
パケットを送信し、一旦バスを開放するよう指示する。
read_grant
パケットを受け取る。
バス上のパケットを消去し、オーナシップを放棄する。トランザクションが応 答側によって再開されるまで待つ。
データを送出可能なクロックの2つ前以降のクロックでバスのオーナシップを 要求する。
自分がオーナになれたかどうかを確認する。オーナになれなかった場合は次以 降のクロックで再びオーナシップを要求する。
記憶しておいたトランザクションIDを復帰させ、read_ack
パケットを
返す。
トランザクションIDが一致していることを確認し、read_ack
パケット
を受け取る。このパケットを受け取ったら、要求側は次のクロック以降でデー
タを受け取れるようにする。
read_data
パケットを送出する。
read_data
パケットを受け取る。
バス上のパケットを消去し、オーナシップを放棄する。そのまま次の動作に移 る場合、このフェーズでオーナシップを放棄せずに次のパケットを送出しても よい。
オーナシップを要求する。
自分がオーナになれたかどうかを確認する。オーナになれなかった場合は次以 降のクロックで再びオーナシップを要求する。オーナになれた場合は、このト ランザクションに割り当てられたトランザクションIDを記憶しておく。
write_request
パケットを発行する。
write_request
パケットを受け取る。この時のトランザクションIDを記
憶しておく。
write_grant
パケットを送信し、一旦バスを開放するよう指示する。
write_grant
パケットを受け取る。
バス上のパケットを消去し、オーナシップを放棄する。トランザクションが応 答側によって再開されるまで待つ。
データを受信可能なクロックの3つ前以降のクロックでバスのオーナシップを 要求する。
自分がオーナになれたかどうかを確認する。オーナになれなかった場合は次以 降のクロックで再びオーナシップを要求する。
記憶しておいたトランザクションIDを復帰させ、write_ack
パケットを
返す。
トランザクションIDが一致していることを確認し、write_ack
パケット
を受け取る。このパケットを受け取ったら、要求側は次のクロック以降で書き
込むデータを送ることができる。
write_data
パケットを送出する。
write_data
パケットを受け取る。
バス上のパケットを消去し、オーナシップを放棄する。そのまま次の動作に移 る場合、このフェーズでオーナシップを放棄せずに次のパケットを送出しても よい。
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |