2

合成で問題が発生しました。if ステートメントに 2 つの変数があると、合成が失敗します (非常に誤解を招きやすく、役に立たないエラー メッセージが表示されます)。

以下のコードスニペットを考えると

case(state)
//other states here
GET_PAYLOAD_DATA:
        begin
                if (packet_size < payload_length) begin
                    packet_size <= packet_size + 1;
                    //Code to place byte into ram that only triggers with a toggle flag
                    next_state = GET_PAYLOAD_DATA;
                end else begin
                    next_state = GET_CHKSUM2;
                end
end

合成中にザイリンクス ISEでエラーが発生します。

 ERROR:Xst:2001 - Width mismatch detected on comparator next_state_cmp_lt0000/ALB. Operand     A and B do not have the same size.

エラーは、next_state が正しくないと主張していますが、静的な値を取り出しpayload_length て割り当てると、完全に正常に動作します。packet_size と payload_length はどちらも整数型であるため、同じサイズであり、それは問題ではありません。したがって、定義された終了を持つ静的ループでない限り、for ループがハードウェアに実装できないのと同様の問題だと思います。ただし、If ステートメントは、2 つのバイナリ値の間の単なるコンパレータであるため、機能するはずです。

ここで私がしようとしていたのは、モジュールがバイトを受信すると、ペイロード全体のサイズ (以前のパケット データから取得したもの) に達するまで RAM に追加され、その後別の状態に変更されることです。チェックサムを処理します。データは一度に 1 バイトしか入らないので、カウンターが限界に達するまでこの状態を何度も呼び出してから、次の状態を別の状態に設定します。

私の質問は、エラーが表示されずにカウンターがペイロードの長さに達するまで、状態を呼び出して同じ結果を得るにはどうすればよいですか?

編集: コメントで要求されているように、packet_sizeとpayload_lengthがどのように宣言されているかのスニペット

integer payload_length, packet_size;

initial begin
    //other stuff
    packet_size <= 0;
end

always @ (posedge clk) begin
    //case statements with various states
    GET_PAYLOAD_LEN:
        begin
            if (rx_toggle == 1) begin
                packet_size <= packet_size + 1;
                addr <= 3;
                din <= rx_byte_buffer;
                payload_length <= rx_byte_buffer;
                next_state = GET_PAYLOAD_DATA;
            end else begin
                next_state = GET_PAYLOAD_LEN;
            end
        end

rx_byte_buffer私のモジュールが8ビット幅として受け取る入力データのレジスタであり、上記packet_sizeの状態より前のマシンの他のさまざまな状態でインクリメントされます。

if ステートメントの条件を切り替えることでエラーを回避しましたが、それでも何かが変わる理由を理解したいと思っています。

4

1 に答える 1

1

コードに関してすぐに突き出るエラーがいくつかありますが、この問題は修正されない場合がありますが、シミュレーションとハードウェア テストで違いが生じるため、修正する必要があります。

nextstate ロジックは、クロックのポーズエッジに基づいて変化しない別の always ブロックにある必要があります。機密リストには、「状態」や「*」などを含める必要があります。そして、nextstate ロジックを現在のように登録したい場合 (そうではありません)、ノンブロッキング代入を使用する必要があります。

http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA_rev1_2.pdf

コードは次のようになります。

always @ (*) begin
    //case statements with various states
    GET_PAYLOAD_LEN:
        begin
            if (rx_toggle == 1) begin
                packet_size_en = 1'b1;
    //these will need to be changed in a similar manner 
                addr <= 3;
                din <= rx_byte_buffer;
                payload_length <= rx_byte_buffer;
    /////////////////////////////////////////////////////
                next_state = GET_PAYLOAD_DATA;
            end else begin
                next_state = GET_PAYLOAD_LEN;
            end
        end

always@(posedge clk) begin 
   if(pcket_size_en)
       packet_size <= packet_size +1 ;
end 

また、私が最初に試みることは、これらをreg型にすることで、これらを定義された長さにすることです(符号付きの数値は必要ないので、シミュレーションでは違いがないはずです)。生成ブロックの外では、合成で整数をいじらないようにしてください。

于 2013-06-05T22:44:07.233 に答える