Inoutポート
CoddyのVerilogジャーニー「基礎」セクションの一部。レッスン 32/90。
inoutポートは、信号を送信することも受信することもできる双方向ポートです。異なるタイミングで入力または出力として機能できます。ほとんどのポートは、input(データが入ってくる)かoutput(データが出ていく)のどちらかです。inoutポートはその両方ができます。状況に応じて、データを出力したり、データを受信したりできます。
一方通行の道路ではなく、双方向の道路のようなものだと考えてください。
双方向ポートは次の用途に使われます:
- 共有バス:複数のデバイスが同じ配線に接続されている
- メモリデータバス:データの読み取りや書き込みができる
- 双方向通信:I2C、SPIなど
一度にバスを駆動できるデバイスは1つだけです。他のデバイスは高インピーダンス状態(Z)でなければなりません。
Inoutポートの宣言
inout [7:0] data_bus; // 8ビット双方向バス
inout ready; // 単一ビットの双方向信号Inoutの仕組み
inoutポートでは、入力として動作するか出力として動作するかを決める制御信号が必要です。
module bidir (
inout [7:0] bus,
input [7:0] data_out,
input enable,
output [7:0] data_in
);
assign bus = (enable) ? data_out : 8'bZ; // Drive bus when enabled, else Z
assign data_in = bus; // Always read the bus
endmoduleenable = 1のとき、モジュールはバスを駆動します(出力モード)。enable = 0のとき、モジュールはバスを解放します(入力モード、ハイインピーダンス)。
Inout の重要なルール
| ルール | 理由 |
|---|---|
wireとして宣言する必要があります | regにはできません |
| 複数のデバイスが同時にバスを駆動してはいけません | ドライバーが競合すると X が発生します |
Zを使ってバスを解放します | ほかのデバイスが駆動できるようになります |
| 一度に駆動できるのは1つのドライバーだけです | バスの競合を防ぎます |
双方向入出力と入力と出力の違い
| ポートの種類 | 方向 | 駆動できるか | 読み取れるか |
|---|---|---|---|
input | 一方向(入力のみ) | いいえ | はい |
output | 一方向(出力のみ) | はい | はい(駆動している値) |
inout | 双方向(両方) | はい(有効な場合) | はい(常に) |
よくある間違い
// 誤り: always ブロック内では inout に代入できません
always @(posedge clk) begin
data_bus <= something; // エラー!条件付きの assign を使用してください
end
// 正しい例: enable 条件付きの assign を使用します
assign data_bus = (enable) ? something : 8'bZ;チャレンジ
この双方向バッファが動作するように、不足している inout ポートと assign 文を追加してください。
すること:
- 8ビットの
inoutポートio_busを追加する send_enableが1のときはio_busにsend_valueを出力し、それ以外の場合はZを出力するassign文を追加するio_busの値をreceive_valueに読み込むassign文を追加する
自分で試してみよう
module bidir_buffer (
// タスク 1: ここに io_bus という名前の 8 ビットの inout ポートを追加する
input [7:0] send_value,
input send_enable,
output [7:0] receive_value
);
// タスク 2: send_enable が 1 のときは send_value で io_bus を駆動し、それ以外のときは Z にする assign 文を追加する
// タスク 3: io_bus を読み取って receive_value に代入する assign 文を追加する
endmoduleこのレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
基礎のすべてのレッスン
自分で練習してみよう: Verilogオンラインコンパイラ