Menu
Coddy logo textTech

遷移のタイミング設定

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

challenge icon

チャレンジ

このレッスンでは、各ライトが点灯し続ける時間を制御するカウンターロジックを追加します。カウンターはあらかじめ設定された値からゼロまでカウントダウンし、その後、次の状態への変更をトリガーします。

タイミング要件

状態期間カウンター値
緑30秒30
黄10秒10
赤40秒40

カウンターの動作

  1. 状態が始まると、カウンターに期間の値が読み込まれます
  2. クロックが1回刻まれるごとに、カウンターが1減少します
  3. カウンターが0に達すると、次の状態に変更します

あなたの課題は、ステートマシンに不足しているカウンターロジックを追加することです。前のステップのnext入力はもう使用しません。これでカウンターが状態を変更するタイミングを決定し、テストベンチもnextを駆動しなくなります。

行うこと:

  1. モジュールヘッダーからinput next,を削除し、else if (next)条件を以下のカウンターロジックに置き換えます
  2. reg [5:0] counter宣言を追加します(最初のステップですでに宣言している場合は、そのまま残します)
  3. リセット時にcounterを0に設定します
  4. counter == 0の場合:
    • 次の状態の期間をカウンターに読み込みます
    • 次の状態に変更します
  5. それ以外の場合は、クロックごとにカウンターを1減少させます

自分で試してみよう

module traffic_light (
  input clk,
  input reset,
  output reg red,
  output reg yellow,
  output reg green
);

  reg [1:0] state;
  // TODO: counterレジスタを宣言する(6ビット)
  

  // 出力の代入
  always @(*) begin
    case (state)
      0: begin green = 1; yellow = 0; red = 0; end
      1: begin green = 0; yellow = 1; red = 0; end
      2: begin green = 0; yellow = 0; red = 1; end
      default: begin green = 0; yellow = 0; red = 1; end
    endcase
  end

  // タイミング付きステートマシン
  always @(posedge clk or posedge reset) begin
    if (reset) begin
      state <= 2;      // Redから開始
      // TODO: counterを0に設定する
      
    end else begin
      if (counter == 0) begin
        case (state)
          0: begin
            state <= 1;
            // TODO: Yellow用にcounterをロードする(10秒)
            
          end
          1: begin
            state <= 2;
            // TODO: Red用にcounterをロードする(40秒)
            
          end
          2: begin
            state <= 0;
            // TODO: Green用にcounterをロードする(30秒)
            
          end
        endcase
      end else begin
        // TODO: counterを1減らす
        
      end
    end
  end

endmodule

基礎のすべてのレッスン

自分で練習してみよう: Verilogオンラインコンパイラ