Menu
Coddy logo textTech

Inoutポート

CoddyのVerilogジャーニー「基礎」セクションの一部 — レッスン 32/90。

inout ポートは、信号の送信と受信の両方を行うことができる双方向ポートです。これは、時によって入力または出力として機能します。

ほとんどのポートは、input(データが入力される)またはoutput(データが出力される)のいずれかです。inoutポートはその両方が可能です。状況に応じて、データを出力したり、入力を受け取ったりすることができます。

一方通行の道路ではなく、双方向の道路のように考えてください。

Inoutポートは以下のような場合に使用されます:

  • 共有バス — 同じ配線に接続された複数のデバイス
  • メモリデータバス — データの読み取りまたは書き込みが可能
  • 双方向通信 — I2C、SPIなど

一度にバスを駆動できるデバイスは1つだけです。他のデバイスはハイインピーダンス状態 (Z) である必要があります。

Inoutポートの宣言

inout [7:0] data_bus;   // 8ビット双方向バス
inout ready;             // 1ビット双方向信号

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;  // 有効な時はバスを駆動し、それ以外はZ(ハイインピーダンス)
  assign data_in = bus;                     // 常にバスを読み取る
  
endmodule
  • enable = 1 のとき、モジュールはバスを駆動します(出力モード)
  • enable = 0 のとき、モジュールはバスを解放します(入力モード、high-Z)

Inoutに関する重要なルール

ルール理由
wireとして宣言する必要がありますregにすることはできません
同時に読み書きすることはできません競合(X)が発生します
バスを解放するためにZを使用します他のデバイスが駆動できるようになります
一度に一つのドライバのみバスの衝突を防ぎます

Inout vs Input vs Output

ポートタイプ方向ドライブ可能読み取り可能
input単方向 (入力のみ)いいえはい
output単方向 (出力のみ)はいいいえ
inout双方向 (両方)はい (有効時)はい (常に)

よくある間違い

// 誤り: alwaysブロック内でinoutに代入することはできません
always @(posedge clk) begin
  data_bus <= something;   // エラー!条件付きのassignを使用してください
end
// 正解: イネーブル条件付きで assign を使用する
assign data_bus = (enable) ? something : 8'bZ;
challenge icon

チャレンジ

不足している inout ポートと assign 文を追加して、この双方向バッファを動作させてください。

作業内容:

  1. io_bus という名前の 8ビット inout ポートを追加します。
  2. send_enable が 1 のときは io_bussend_value で駆動し、それ以外の場合は Z とする assign 文を追加します。
  3. io_busreceive_value に読み込む assign 文を追加します。

チートシート

inout は、信号の送信(ドライブ)と受信の両方が可能な双方向ポートです。一度にバスをドライブできるデバイスは1つだけで、他のデバイスは高インピーダンス (Z) を出力しなければなりません。

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; // 有効な時にドライブし、それ以外は解放する
  assign data_in = bus;                    // 常にバスを読み取る
endmodule

主なルール:

  • wire 型である必要があります(reg は不可)
  • 三項演算子を用いた assign 文を使用します。always ブロック内での代入は決して行わないでください
  • バスの衝突を避けるため、ドライブしていない時は Z で解放します

自分で試してみよう

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
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

基礎のすべてのレッスン