1

verilogで有限ステートマシンを作成しようとしています。システムには、4つの入力1-bit 、、、 rstおよび1つの出力、があります。clkABZ

次のいずれかの場合、Zは1に等しくなります。Aの最後の2つのクロックエッジで同じ値があった。

または、最後のルールが真であったため、すべてのクロックエッジでBがハイ(1)になっています。

それ以外の場合z=0;

私の試みのATMをシミュレートするためのツールがありません。だから私はこれが正しい方法であるかどうか、そして私が正しい軌道に乗っているかどうか疑問に思っていますか?

module StateMachine( R, A, B, clk, Z);
   input R, A, B, clk;
   output reg Z;

   reg ATemp;
   reg state;

   always @ (posedge clk or A)
      if (A == 1'b1) 
      /////////////////
      begin
         if (ATemp == 1'b1) state <= 1'b1; 
         else ATemp <= A;
       end
       ////////////////
       else
       ////////////
       begin
          if (ATemp == 1'b0) state <= 1'b1;
          else ATemp <= A;
       end


   always @ (state)
      case(state)
         1'b0: Z=0;
         1'b1: Z=1;

         default: Z=0;
      endcase

endmodule
4

3 に答える 3

1

次のツールを使用できます。

GHDLは、VHDL言語用のオープンソースシミュレータです(ユーザーガイド) 。

さらに、これらは最も人気のあるシミュレーションツールです:

その他のリソース:

スタックエクスチェンジエレクトロニクスコミュニティとコードレビューもあります。

さらに、CtoHDLコンパイラツールに注意してください

(..多くの人が3分であなたのコードをレビューできるとは思えませんし、私もそれらを望んでいません)

于 2012-09-24T17:58:11.737 に答える
0

次の状態ロジックがないため、状態が変更されることはなく、リセットも行われないため、状態は1'bzとして開始されます。ステートマシンをコーディングするときは、ザイリンクスのガイドラインから始めることをお勧めします。

于 2012-09-24T17:58:52.147 に答える
0

フリップフロップの定義が少し間違っています。あなたが持っていalways @ (posedge clk or A)ます。エッジトリガーと非エッジトリガーを組み合わせないでください。シミュレーションでは機能するかもしれませんが、合成で必要なものは得られません。

値をクロックエッジでのみ変更する場合は、または組み合わせ入力に使用します。つまり、入力の使用またはより新しいバージョンalways @( posedge clk)で出力が変更されます。@ *は、変更があればトリガーします。感度リストに項目がないことが、合成コードがRTLと同じようにシミュレートされない主な理由でした。always @( A )always @*

フリップフロップを作成している場合は、リセットを含める必要があると言います。always @ (posedge clk or negedge rst_n)

また、状態が0に設定されることはないため、第一印象は、これが特定の状態/出力に固定されることです。コードが質問されている質問をどのように実装しているかを理解するのは難しいです。私の解決策は次のようなものになります:

module statemachine(
  input      rst,
  input      A,
  input      B,
  input      clk,
  output reg Z
);

  reg  [1:0] a_last_two;
  wire      rule_one;

  always @ (posedge clk or negedge rst) begin
    if (~rst) begin
      a_last_two <= 2'b0;
    end
    else begin
      a_last_two <= {a_last_two[0] ,A}; 
    end
  end

  assign rule_one = (a_last_two[1] == a_last_two[0]); 
  //rule one could be written as ~^a_last_two (xnor reduction operator)

  reg rule_two;
  always @ (posedge clk or negedge rst) begin
    if (~rst) begin
      rule_two <= 1'b0 ;
    end
    else begin
      //rule 2 resets when rule_one is true
      if (rule_one) begin
        rule_two <= 1'b1 ;
      end
      else begin
        rule_two <= rule_two & B ;
      end
    end
  end

  assign Z = rule_one | rule_two ;

endmodule
于 2012-09-25T06:54:41.007 に答える