2012-04-05 13 views
2

私は、私に取り組んでいるAGC/SPIコントローラの奇妙な振る舞いのように思えます。これは、ザイリンクスのSpartan 3e FPGAをターゲットにしたVerilogで行われています。コントローラは外部入力を使用して起動するFSMです。 FSMの状態は明示的に初期化されていないstate_regに格納されています。初期化されていないレジスタはデフォルトでゼロになると思います。コントローラを実装すると、FSMは実行されませんでした。 SPIバスを監視して、私は何の活動も観察しなかった。 FSMを監視するために、state_regをLEDバンクに送られる出力バスにルーティングしました。これは、という行がdata_out = state_regを割り当てている行為です。私はこれを行ったときに、SPIバスで観測されたように、AGC/SPIコントローラが正しく動作していることに気付きました。何が起こっているのかは、state_regが初期化時に未定義状態であるため、FSMが決してどの状態にもないので実行されないようです。しかし、state_regを出力に割り当てることによって、最初からやり直すと期待していた通り、に初期化されました。だから私の質問は、初期化されていないレジスタは0の値を取ることになっていますか?初期化されていないレジスタを出力に割り当てることで、強制的にゼロに見えるようになりますか?それとも私が理解していない何かがここで起こっていますか?以下は私のコードです。 * state_reg **が出力ワイヤ[7:0] data_outに割り当てられている関連部分についてコメントしました。私は、これは長い質問です知っているが、私は「本当に私は期待すべき行動の種類を理解しようとmは感謝Verilog、FPGA、ユニット化されたレジスタの使用

module agc_control 
     (
      input wire [7:0] agc_data, 
      input wire clk, 
      input wire agc_start, 
      input wire AMP_DO, 
      output reg MOSI, 
      output reg SCK, 
      output reg CS_AMP, 
      output wire inhibit_ADC, 
      output wire [7:0] data_out 
     ); 

     //signals 
     reg [4:0] state_reg, 
     reg [2: 

0] ampclkreg; 
    reg ampclk; 
    reg [7:0] agc_data_reg; 
    reg agc_running; 
    reg [7:0] data_out_reg; 
    wire agc_done; 




    //ampclk generation 
    always @(posedge clk) 
     begin 
      ampclkreg = ampclkreg + 1; 
      if (ampclkreg == 3) 
       begin 
        ampclkreg = 0; 
        ampclk = ~ampclk; 
       end 
     end 

    always @(posedge clk) 
     begin 
      if(agc_start == 1) 
       begin 
        agc_running = 1'b1; 
        agc_data_reg = agc_data; 
       end 
      if(agc_done == 1) 
       begin 
        agc_running = 1'b0; 
       end 
     end 



    //FSM 
    always @(posedge ampclk) 
     begin 
      if (agc_running == 0) 
       begin 
        SCK = 0; 
        state_reg = 0; 
        CS_AMP = 1; 
       end 
      if (agc_running == 1) 
       begin 
        case (state_reg) 
         0: begin 
           CS_AMP = 1; 
           SCK = 0; 
           state_reg = 1; 
          end 
         1: begin 
           CS_AMP = 0; 
           MOSI = agc_data_reg[7]; 
           state_reg = 2; 
          end 
         2: begin 
           SCK = 1; 
           state_reg = 3; 
          end 
         3: begin 
           SCK = 0; 
           MOSI = agc_data_reg[6]; 
           state_reg = 4; 
          end 
         4: begin 
           SCK = 1; 
           state_reg = 5; 
          end 
         5: begin 
           SCK = 0; 
           MOSI = agc_data_reg[5]; 
           state_reg = 6; 
          end 
         6: begin 
           SCK = 1; 
           state_reg = 7; 
          end 
         7: begin 
           SCK = 0; 
           MOSI = agc_data_reg[4]; 
           state_reg = 8; 
          end 
         8: begin 
           SCK = 1; 
           state_reg = 9; 
          end 
         9: begin 
           SCK = 0; 
           MOSI = agc_data_reg[3]; 
           state_reg = 10; 
          end 
         10:begin 
           SCK = 1; 
           state_reg = 11; 
          end 
         11:begin 
           SCK = 0; 
           MOSI = agc_data_reg[2]; 
           state_reg = 12; 
          end 
         12:begin 
           SCK = 1; 
           state_reg = 13; 
          end 
         13:begin 
           SCK = 0; 
           MOSI = agc_data_reg[1]; 
           state_reg = 14; 
          end 
         14:begin 
           SCK = 1; 
           state_reg = 15; 
          end 
         15:begin 
           SCK = 0; 
           MOSI = agc_data_reg[0]; 
           state_reg = 16; 
          end 
         16:begin 
           SCK = 1; 
           state_reg = 17; 
          end 
         17:begin 
           CS_AMP = 1; 
           state_reg = 18; 
          end 
         18:begin 
           SCK = 0; 
           state_reg = 19; 
          end 
         19:begin 
           state_reg = 19; 
          end 
        default: state_reg = 19; 
       endcase 
      end 
     end 

    //retrieve previous vlaues 
    always @(posedge clk) 
    begin 
     case(state_reg) 
      2: begin 
        if (ampclkreg == 2)    
         data_out_reg[7] = AMP_DO; 
       end 
      4: begin 
        if (ampclkreg == 2) 
         data_out_reg[6] = AMP_DO; 
       end 
      6: begin 
        if (ampclkreg == 2) 
         data_out_reg[5] = AMP_DO; 
       end 
      8: begin 
        if (ampclkreg == 2) 
         data_out_reg[4] = AMP_DO; 
       end 
      10:begin 
        if (ampclkreg == 2) 
         data_out_reg[3] = AMP_DO; 
       end 
      12:begin 
        if (ampclkreg == 2) 
         data_out_reg[2] = AMP_DO; 
       end 
      14:begin 
        if (ampclkreg == 2) 
         data_out_reg[1] = AMP_DO; 
       end 
      16:begin 
        if (ampclkreg == 2) 
         data_out_reg[0] = AMP_DO; 
       end 

     endcase 
    end 


    //output wire [7:0] data_out--to top module to drive 7 LEDs and display state_reg 
    assign data_out = state_reg; 

    assign agc_done = (state_reg == 19); 
    assign inhibit_ADC = (agc_running == 1); 


    endmodule 
+0

FPGAデザインでは常に常にレジスタを初期化してください。 –

+0

レジスタを初期化するときに同じ結果が得られますか?私はまだこの奇妙な振る舞いを引き起こしているかも知りません - 通常、あなたが指定しなければ、ツールは0と思っています。 – Josh

答えて

9

私はFPGAに(私はザイリンクスのFPGAで最も経験を持っている)のコンテキストで答える;。。Iティムの答えに反対する。FPGAをプログラムして初期化されると

多く内部リソースが既知の状態に初期化されている。これは、全てのフリップフロップとブロックRAMが含まれています。あなたのデザイン全体で毛布リセットロジックを追加することで、あなたはありそれ以外の場合は、必要以上に複雑になります。そうしないと、内部要素であるinitia既知の状態にライジングする。ファンアウトの高いリセットネットを使用すると、ルータの設計をより困難にすることができ、設計をスライスにマッピングすることも、リセットの選択、特に非同期のものによって複雑になります。

私の提案:あなたのレジスタの

  • 使用初期値。サポートされている構文で使用しているバージョンのXilinx XSTドキュメントを再度確認してください。広く保持されている信念とは対照的に、初期設定値はほとんどの場合に尊重されます。これを行うことの副次的な利点は、チップの初期状態がシミュレーションの初期状態と一致することです。
  • より効率的なマッピング(シフトレジスタへのパイプラインなど)を可能にするために必要な制御信号をリセットし、データパスレジスタだけを残してください。
+1

あなたは良い点を作って、私はデフォルト値がFPGAで広くサポートされていたことに気づいていませんでした。私はASICの経験を曇らせるようにしています:) – Tim

+2

参考までに、これはザイリンクスのホワイトペーパーにも記載されています。http://www.xilinx.com/support/documentation/white_papers/wp272.pdf – sonicwave

0

だから私の質問は、初期化されていないレジスタが0の 値を取ることになっているのですか?

いいえ、それらはxと仮定する。合成では、値を保持しているのでリセットする必要があります。私はFPGAの経験はありませんが、Nathan Farringtonは、それらがリセット/初期化されていることを示唆しています。FPGAは十分なはずです以下を実行するために

:合成のために

reg [4:0] state_reg = 'b0, 

私はリセット句内でこれを行うことをお勧めします。

always @(posedge clk or negedge reset) begin 
    if (!reset) begin 
    state_reg <= 'b0 ; 
    end 
    else begin 
    .. 
    end 
end 
関連する問題