3

私が取り組んでいる AGC/SPI コントローラの奇妙な動作について質問があります。これは Verilog で行われ、Xilinx Spartan 3e FPGA をターゲットにしています。コントローラーは、外部入力に依存して開始する FSM です。FSM の状態は、明示的に初期化されていないstate_regに格納されます。コントローラーを実装したとき、FSM は実行されませんでした。SPI バスの監視 アクティビティは見られませんでした。FSM を監視するために、state_regを LED バンクに接続する出力バスにルーティングしました。それが行assign data_out = state_reg ですやっています。私がこれを行ったとき、FSM は AGC/SPI コントローラが SPI バスで観察されたように正しく動作することがわかりました。初期化時にstate_regが未確定の状態にあるため、FSM がどのような状態にもならないため、実行されないようです。しかし、state_regを出力に割り当てることで、最初から期待していたように00000000に初期化されました。私の質問は、初期化されていないレジスタは値 0 を想定しているのでしょうか? 初期化されていないレジスタを出力に割り当てることで、一見したように強制的にゼロになるのでしょうか? それとも、私が理解できない他の何かがここで起こっていますか? 以下は私のコードです。*state_reg** が出力ワイヤ [7:0] data_outに割り当てられている関連部分をコメントしました. これが長い質問であることは承知していますが、どのような種類の動作を期待すべきかを本当に理解しようとしています。ありがとう.

  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
4

2 に答える 2

10

FPGA のコンテキストで回答します (ザイリンクス FPGA の経験が最も豊富です)。私はティムの答えに同意しません。

FPGA がプログラムおよび初期化されると、多くの内部リソースが既知の状態に初期化されます。これには、すべてのフリップフロップとブロック RAM が含まれます。設計全体にブランケット リセット ロジックを追加すると、内部要素が既知の状態に初期化されることに期待できる場合、必要以上に複雑になる可能性があります。リセット ネットのファンアウトが大きいと、デザインのインプリメンテーションがルーターにとってより困難になる可能性があり、デザインをスライスにマッピングすることも、リセット (特に非同期のもの) の選択によって複雑になります。

私の提案:

  • レジスタの初期化値を使用します。サポートされている構文については、使用しているバージョンのザイリンクス XST ドキュメントを再確認してください。広く信じられていることとは反対に、ほとんどの場合、初期化値は尊重されます。これを行う副次的な利点は、チップの初期状態がシミュレーションの初期状態と一致することです。
  • 必要な制御信号のみをリセットし、データパス レジスタはそのままにして、より効率的なマッピング (シフト レジスタへのパイプラインなど) を可能にします。
于 2012-04-06T16:35:38.140 に答える
0

私の質問は、初期化されていないレジスタは値 0 を想定しているのでしょうか?

いいえ、彼らは x を想定しています。合成の場合、値が保持されている可能性があるため、リセットする必要があります。私は FPGA の経験がありませんが、Nathan Farrington はそれらもリセット/初期化されることを提案しています。

FPGA の場合、以下を実行するだけで十分です。

reg [4:0] state_reg = 'b0,

合成の場合は、reset 句内でこれを行うことをお勧めします。

always @(posedge clk or negedge reset) begin
  if (!reset) begin
    state_reg <= 'b0 ;
  end
  else begin
    ..
  end
end
于 2012-04-11T13:50:18.917 に答える