1

コードは次のとおりです。 コードの目的は、レジスタの 1 つから先行ゼロの数を計算することです。レジスタ仮数から先行ゼロを一度だけ計算したいだけです。これには常にブロックを使用する必要があります。ここで、最初に a を 1'b1 として割り当て、後で 1'b0 に変更して、ブロックが 1 回実行されるようにしました。コードをシミュレートしようとすると。always ブロックは実行されません。ただし、後で a を 0'b1 として割り当てた場合 (意味がありません)。コードはシミュレータで適切にシミュレートされます。しかし、FPGA キットでコードを合成すると、誤った結果が得られます。私を助けてください

integer count,index;
wire a;
assign a=1'b1;
always@(a)
begin
    for(count=0;count<7;count=count+1) begin
        index=4*count;
        if((significand[index  ]==1'b0) && (significand[index+1]==1'b0) &&
           (significand[index+2]==1'b0) && (significand[index+3]==1'b0))
             lzero=lzero+1;
    end 
end
assign a=1'b0;
// If I use assign a=0'b1, it simulates properly, 
// but 0'b1 doesn't make any sense, also If I keep 0'b1, 
// I dont get proper result in actual synthesis onto the board.

実際、質問をする私の意図は、「常に」ブロックをどのように使用できるようにするかということでした。このブロックを 1 回だけ実行したかったので、「posedge clk」または「negedge clock」を always で設定する必要はありません。それで、私は何をすべきですか?? 私のプロジェクトは私を要求するので助けてくださいforループif elseループの多用

4

3 に答える 3

5

あなたはプログラムを書こうとしているソフトウェア エンジニアのように見えますが、ハードウェアを説明しようとしているわけではありません。

コーディング中は、非常に並行して考える必要があります。

あなたのコードは、「継続的かつ常に 1 の値を a に割り当てます」と言い、後で「継続的かつ常に 0 の値を a に割り当てます」と言います。これは明らかにあなたが望むものではありません。これらの割り当てステートメントは、必要に応じて一時的なものではありません。

したがって、次のようなものが必要です (疑似コードで): 1) 入力レジスタを読み取る 2) 0 の数をカウントする 3) 0 の数を出力する

ソフトウェアでは、次のようにステップ 2 を実行します。

for i=msb to lsb loop
   if (input[i] == 1) then break;
end loop
return i;

HW の for ループは、ステート マシンを記述することを意味します (再帰を使用して関数型言語で for ループを実行する方法を考えてみてください。入力の 1 つは現在のインデックスです)。または、自分でループを展開することもできます。

if (msb == 1 ) then return 0
else if (msb-1 == 1) then return 1
...
else if (msb-31 == 1) then return 31
else return 32
end if
于 2012-06-30T03:57:24.727 に答える
1

フラグを作成し、開始時にフラグを0に設定し、alwaysブロックでフラグの値を確認します。フラグが0に等しい場合は、これが初めてのフラグであることを意味します。操作とその内部で、フラグを1に設定します。

このようにして、起動時にこれらの操作を1回だけ実行することを保証します。

于 2012-06-30T18:05:06.033 に答える
1

ここには、ハードウェアを記述するための Verilog 言語の不適切な使用と思われるものがいくつかあります。

これが初期化が必要なテストベンチ コンポーネントである場合は、これinitial begin .. endを実行する方法になります。

これが合成を意図しており、一度だけ実行される場合、alwaysブロックはそれを設計する正しい方法として私には思えません。電源投入時に 1 回実行する場合は、事前に計算 (パラメーター) することができるため、コンパイル/合成で修正されます。

変更可能な入力に基づいている場合、計算を実行できるようにする必要はありません。ハードウェアの電源投入シーケンスによっては、この入力が時間 0 で設定されない場合があるためです。

これが合成用の場合は、次のものがより適しています。

module count_lzero(
  input             clk,
  input             rst_n,
  input             enable, // Toggle high 1 Clk to calc new lzero
  output reg [31:0] lzero
);

always @(posedge clk or negedge rst_n) begin
  if (~rst_n) begin
    lzero <= 'b0;
  end
  else if ( enable ) begin
    for(count=0;count<7;count=count+1) begin
        index=4*count;
        if((significand[index  ]==1'b0) && (significand[index+1]==1'b0) &&
           (significand[index+2]==1'b0) && (significand[index+3]==1'b0))
             lzero<=lzero+1;
    end 
  end
end
于 2013-01-24T12:34:07.777 に答える