reg宣言を使った簡単な順序回路

前回から繰り返すが仕様はこうであった。

『プッシュスイッチpush1, push2, push3がある。push1,push2,push3の順に押されたらledが点灯する回路を設計せよ』

順序回路は

  • 「過去の入力から決まる値」と「現在の入力」から出力が決まる回路
  • 過去の入力から決まる値を保持するもの, つまり変数に相当するものが必要
  • 変数はフリップフロップやラッチといった記憶素子で実現する

であった。では記憶素子をverilogで記述するにはどうしたらいいのだろうか?
verilogではreg宣言でレジスタ(フリップフロップの塊)を宣言できる。
ハードウェアを学習すれば(フリップフロップでググレば)同期式回路の説明が
嫌というほどでてくるので調べてくらはいm(_ _)m

フリップフロップで値を保持するのだが、どのタイミングで値を保持するかが問題である。
ここではクロックの立ち上がりエッジで値を保持するとしよう。
初期値はどうなるか?C言語では暗黙に0に初期化してくれるありがたい仕様があったが、
verilogではハードウェアという現実の物を使うので、人間が初期値をかならず指定しなければならない。
そこでリセット信号を使おう。
結局仕様を満たす記述はこうなる。

module sequential_circuit( clock, reset, push1, push2, push3, led);
  input clock, reset;
  input push1, push2, push3;
  output led;
  
  reg [1:0]state;
  
  always@( poedge clock or posedge reset)begin
    if( reset == 1'b1)begin
      state <= 2'b00;
    end else begin
      if( state == 2'b00 && push1 == 1'b1)begin
        state <= 2'b01;
      end else if( state == 2'b01 && push2 == 1'b1)begin
        state <= 2'b10;
      end else if( state == 2'b10 && push3 == 1'b1)begin
        state <= 2'b11;
      end
    end
  end

  assign led = ( state == 2'b11) ? 1'b1 ; 1'b0;

endmodule

verilogで順序回路を記述するにはalways@構文を使う。
always@以降の'()'内の式はイベント式といい、イベント式の値が変化すればalways@内部の式を実行する。
イベントの変化は'posedge','negedge'で信号の立ち上がり限定か信号の立下り限定かを指定できる。
また'or', 'and'でそれらの組合せを指定できる。 (通常はクロック信号の'posedge'または'negedge'を指定し'or'で 
リセット信号を指定する非同期式で設計するといいだろう)
とりあえずは呪文のように always@( posedge clock or posedge reset) を書いてください。
(リセット信号が負論理の場合は negedge resetね)。

もう一つ大事なことが!
always文内では代入は'assign'は不要で'<='を使う。
(詳しい説明は後でするので…)

順序回路の記述ポイントは

  • クロック信号とリセット信号を用意する
  • レジスタ変数を宣言する
  • always@(イベント式)を書く
  • レジスタ信号は必ずリセットしてね

順序回路で新しく覚えるverilogの構文はこれだけ。
(他にもいっぱいあるがたいていの順序回路はこれくらいで記述できる)
むしろ記述法がややこしいので次回からは例題を使っていっぱい練習しよう。

状態遷移図から回路を設計する【Altera DE0】へ進む
Verilog入門へ戻る


トップ   編集 凍結解除 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2011-04-13 (水) 11:54:49 (2205d)