2016-11-30 52 views
0

私はスタックを表すためにVerilogで有限状態マシンを設計しています。"複数の定数ドライバ"エラーVerilog with Quartus Prime

module state_machine (s, Enable, Clock, Resetn, c, OF_Err, UF_Err); 
input [2:0] s; 
input Enable, Clock, Resetn; 
output reg [1:0] c; 
output reg OF_Err = 0, UF_Err = 0; 
reg [2:0] y, Y; 
parameter [2:0] A = 3'b000, B = 3'b001, C = 3'b010, D = 3'b011, E = 3'b100; 

always @(s, y, Enable) 
    if (Enable) 
     begin 
      case (y) 
       A: if (s == 3'b000) Y = B; 
        else 
         begin 
          Y = A; 
          UF_Err = 1; 
         end 

       B: if (s == 3'b000) Y = C; 
        else if (s == 3'b001) Y = A; 
        else 
         begin 
          Y = B; 
          UF_Err = 1; 
         end 

       C: if (s == 3'b000) Y = D; 
        else if (s == 3'b100) Y = C; 
        else Y = B; 

       D: if (s == 3'b000) Y = E; 
        else if (s == 3'b100) Y = D; 
        else Y = C; 

       E: if (s == 3'b000) 
         begin 
          Y = E; 
          OF_Err = 1; 
         end 
        else if (s == 3'b100) Y = E; 
        else Y = D; 

       default: Y = 3'bxxx; 
      endcase 

      c[1] = y[1]; 
      c[0] = y[0]; 
     end 

always @(negedge Resetn, posedge Clock) 
    begin 
     if (Resetn == 0) 
      begin 
       y <= A; 
       OF_Err = 0; //Problem 
       UF_Err = 0; //Problem 
      end 
     else y <= Y; 
    end 

OF_ErrUF_Errは、それぞれ、オーバーフロー及びアンダーフローの誤差の指標である次のようにモジュールです。私のプロジェクトをコンパイルするとき

はしかし、私は、次のエラーを取得:

Error (10028): Can't resolve multiple constant drivers for net "OF_Err" at state_machine.v(59) Error (10029): Constant driver at state_machine.v(10) Error (10028): Can't resolve multiple constant drivers for net "UF_Err" at state_machine.v(59)

私はコメント行を追加した後、これらのみ登場しました。私は、FSMがリセットされたときに、オーバーフローとアンダーフローのインジケータをリセットしたいのですが、私が持っている方法ではできません。これをどうやって行うのですか?

(任意の値の場合、これはアルテラDE2-115で実行されます)。

+0

「推測ラッチ」については、インストラクタまたはTAにお尋ねください。このコードにはいくつかのコードがあり、修正する必要があります。 – skrrgwasme

答えて

0

は、OF_ErrUF_Errは、合成のために違法で常に2つのブロックでドライバーでした。 Arvindのように、2つの追加変数of_Erruf_Errを作成することをお勧めします。しかし、私はOF_ErrUF_Errをフロップとして保存することをお勧めします。

組み合わせブロック内のif (Enable)は、レベルセンスラッチとしてY,cおよび*_Errを示しています。私はこれがあなたが意図したものであることを非常に疑う。 if (Enable)を同期させて常にブロックし、組合せ論理を純粋な組み合わせとして維持することをお勧めします。

cは単純な割り当てであるため、単純な割り当てステートメントでregの代わりにワイヤーとして使用する方が意味があります。組み合わせブロックに入れることもできますが、組み合わせ入力と出力を分離することをお勧めします。

@(s, y, Enable)を正しく使用しましたが、@*または同義語@(*)が組み合わせブロック用に再開されました。 @*は入力、保守を省き、信号を忘れるリスクを除去する自動感度リストです。

always @* 
begin 
    of_Err = OF_Err; // <-- default values 
    uf_Err = UF_Err; 

    case (y) 
    // ... your original case code with OF_Err/UF_Err renamed to of_Err/uf_Err 
    endcase 
end 

always @(posedge Clock, negedge Resetn) // style difference, I prefer the clock to be first 
begin 
    if (Resetn == 1'b0) 
    begin 
    y <= A; 
    OF_Err <= 1'b0; 
    UF_Err <= 1'b0; 
    end 
    else if (Enable) 
    begin 
    y <= Y; 
    OF_Err <= of_Err; 
    UF_Err <= uf_Err; 
    end 
end 
assign c[1:0] = y[1:0]; 
+0

ボタンを使用して、マシンが状態を変更したときに制御することができます(したがって、組み合わせセクション内に元々有効になっています)。しかし、最初にボタンを押すと、マシンはすべてのケースを通過し、リリース前に数クロックサイクル間Enable {1}を読み込んでいるので 'E 'で停止します。私は 'Clock'入力までボタンをフックできますが、それはバウンスの問題を引き起こします。希望する機能を実現するためにこれを変更できる方法はありますか? –

+0

ほとんどのFPGAボードがあなたの非難を処理します。 'Enable'を押すごとに状態変更をトリガするためには、' always @(posedge Clock)history <= {history、Enable}; 'の履歴を保持します。次にif(Enable)をif(history == 4'b0011)に変更します。比較に先行ゼロがあり、他のビットが1である限り、履歴の長さを選択できます。 – Greg

0

2つの常時ブロックでは、OF_ErrとUF_Errに値を割り当てました。これが、複数の一定のドライバエラーを表示している理由です。

module state_machine (s, Enable, Clock, Resetn, c, OF_Err, UF_Err); 
    input [2:0] s; 
    input Enable, Clock, Resetn; 
    output reg [1:0] c; 
    output OF_Err, UF_Err;   //modified 
    reg [2:0] y, Y; 
    reg of_Err, uf_Err;    //added 
    parameter [2:0] A = 3'b000, B = 3'b001, C = 3'b010, D = 3'b011, E =3'b100; 

    always @* 
    begin 
     if (Enable) 
     begin 
      case (y) 
       A: if (s == 3'b000) 
         Y = B; 
        else 
        begin 
         Y = A; 
         uf_Err = 1;  //modified 
        end 

       B: if (s == 3'b000) 
        Y = C; 
        else if (s == 3'b001) 
        Y = A; 
        else 
        begin 
        Y = B; 
        uf_Err = 1;  //modified 
        end 

      C: if (s == 3'b000) 
        Y = D; 
       else if (s == 3'b100) 
        Y = C; 
       else 
        Y = B; 

      D: if (s == 3'b000) 
       Y = E; 
       else if (s == 3'b100) 
        Y = D; 
       else Y = C; 

      E: if (s == 3'b000) 
        begin 
         Y = E; 
         of_Err = 1;   //modified 
        end 
       else if (s == 3'b100) Y = E; 
       else Y = D; 

      default: Y = 3'bxxx; 
     endcase 

     c[1] = y[1]; 
     c[0] = y[0]; 
    end 
     else 
     begin 
    //write the condition if the Enable signal is not high.I guess you're trying to synthesize 
     end 

    end 

always @(negedge Resetn, posedge Clock) 
begin 
    if (Resetn == 0) 
     begin 
      y <= A; 
     // OF_Err = 0; //Problem 
     // UF_Err = 0; //Problem 
     end 
    else y <= Y; 
end 

assign OF_Err = !Resetn? of_Err : 1'b0;  //added 
assign UF_Err = !Resetn? uf_Err : 1'b0;  //added 

endmodule 
+0

私はコードが動作することをテストしました – Arvind

+0

申し訳ありません私はテストしていません – Arvind

+0

'OF_Err'と' UF_Err'を 'reg'のままにして、' else'のそれぞれの 'of_Err'と' uf_Err'に割り当てます。 'y <= Y;'である条件。こうすることで、出力グリッチの変化を減らすことができます。 – Greg

0

ためOF_ErrUF_ERRは、常に複数のブロックによって駆動されます。

regは1つのalwaysブロックのみで駆動する必要があります。また、設計上複数のドライバが の場合は、ワイヤでなければなりません。

ここにあなたの変更されたコードがあります。他の人がすでに指摘したように

module state_machine (s, Enable, Clock, Resetn, c, OF_Err, UF_Err); 
input [2:0] s; 
input Enable, Clock, Resetn; 
output reg [1:0] c; 
output reg OF_Err = 0, UF_Err = 0; 
reg [2:0] y, Y; 
parameter [2:0] A = 3'b000, B = 3'b001, C = 3'b010, D = 3'b011, E = 3'b100; 

always @(s, y, Enable, negedge reset) 
begin 
    if (!reset) 
    begin 
    OF_Err = 0; //Problem 
    UF_Err = 0; //Problem 
    end 
    else 
    begin 
    if (Enable) 
    begin 
     case (y) 
     A: if (s == 3'b000) Y = B; 
     else 
     begin 
      Y = A; 
      UF_Err = 1; 
     end 
     B: if (s == 3'b000) Y = C; 
     else if (s == 3'b001) Y = A; 
     else 
     begin 
      Y = B; 
      UF_Err = 1; 
     end 
     C: if (s == 3'b000) Y = D; 
     else if (s == 3'b100) Y = C; 
     else Y = B; 
     D: if (s == 3'b000) Y = E; 
     else if (s == 3'b100) Y = D; 
     else Y = C; 
     E: if (s == 3'b000) 
     begin 
      Y = E; 
      OF_Err = 1; 
     end 
     else if (s == 3'b100) Y = E; 
     else Y = D; 
     default: Y = 3'bxxx; 
     endcase 

     c[1] = y[1]; 
     c[0] = y[0]; 
    end 
    end 
end 

always @(negedge Resetn, posedge Clock) 
begin 
    if(Resetn == 0) 
    y <= A; 
    else 
    y <= Y; 
end 
関連する問題