0

以下は、非復元平方根アルゴリズムです。正常に動作していますが、合成中に「46行目:非静的ループ制限を超えました」というエラーが表示されます。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;

ENTITY code IS
    GENERIC(n: NATURAL:= 8);
    PORT(
        Xin: IN STD_LOGIC_VECTOR(2*n-1 DOWNTO 0);
        clk :IN STD_LOGIC ;
        root: OUT STD_LOGIC_VECTOR(n-1 DOWNTO 0) ;
        root2: OUT STD_LOGIC_VECTOR(2*n-1 DOWNTO 0) ;
        intval: IN STD_LOGIC_VECTOR(n-1 DOWNTO 0)  
    );
END code;

architecture Behavioral of code is

    Signal Outp : STD_LOGIC_VECTOR(n-1 DOWNTO 0);
    Signal Const1 : STD_LOGIC_VECTOR(n-1 DOWNTO 0) ;
    Signal Const2 : STD_LOGIC_VECTOR(n-1 DOWNTO 0) ;

--Signal Var : STD_LOGIC_VECTOR(n-1 DOWNTO 0);

begin

    Const1 <= "00000010";
    Const2 <= "00000000";
    --D <= intval;
    --Var <= intval;

    Process (clk) 
        Variable Acc1 : STD_LOGIC_VECTOR(2*n-1 DOWNTO 0);
        Variable Acc2 : STD_LOGIC_VECTOR(n-1 DOWNTO 0);
        Variable D   : STD_LOGIC_VECTOR(n-1 DOWNTO 0);
        Variable Var : STD_LOGIC_VECTOR(n-1 DOWNTO 0);
        Variable Q : STD_LOGIC_VECTOR(2*n-1 DOWNTO 0);
    begin
        Var := "00000000";
        D   := intval;
        Var := intval;

        while (Var > "00000000") loop

            Q := signed(D)*signed(D);
            Acc1 := signed(Xin) - signed(Q);

            if  (Acc1 = "0000000000000000") then
                var:= Const2;

            elsif (Acc1 < "1000000000000000") then
                --root2<=Acc1;
                Acc2 := '0' & var(n-1 downto 1);
                Var := Acc2;
                D := signed(D) + signed(Var);

            elsif (Acc1 > "0111111111111111") then
                --root2<=Acc1; 
                Acc2 := '0' & var(n-1 downto 1);
                Var := Acc2;
                --root <= Var;
                D := signed(D) - signed(Var);

            end if;
        end loop;

        Outp <= D;
    end process;

    root <= Outp;
end Behavioral;
4

3 に答える 3

5

適切に再フォーマットしない限り、そのコードを読むつもりはありません。そのため、問題の大まかな説明を提供します。[編集:親切な人がそれを再フォーマットしました]

合成は、非静的境界を持つループの処理にはあまり適していません。これは、考えてみれば明らかです。合成では、ループ (明示的な WAIT ステートメントが含まれていない限り) は、すべての反復が並列で実行できるようになるまで展開されます。これは、ループ境界が生成されるハードウェアのサイズを定義することを意味します。

したがって、非静的境界は、ハードウェアが実際に実行されるまで、必要なハードウェアの量がわからないことを意味します! その時までに、さらにゲートを生成するには少し遅すぎます...

答えは、アルゴリズムを静的ループ境界を持つ同等のものに変換することです。実際には、これは通常難しいことではありません: 単に変換するだけです

while (Var > "00000000") loop
   do something;
end loop;

の中へ

constant max_iterations : natural := <some number>;

for i in 1 to max_iterations loop
   -- assuming Var is numeric_std.unsigned, you can simply compare it to 0
   if Var > 0 then      
         do something
   end if;
end loop;
于 2013-03-21T15:18:33.710 に答える
0

ハードウェアを定義していることに注意してください。ループは合成で展開されるため、境界は静的でなければなりません。

ただし、静的な境界で for ループを使用したとしても、おそらく実際のシステムではおそらく利用できない大量のリソースを定義することになります (たとえば、n=8 の場合、256 乗数につながる!)。コードを調整してパイプラインを使用し、リソースと速度を最適化してください。

合成可能なコードの場合、センシティビティ リストにクロックを入れるだけでなく、アクティブなクロック エッジも定義する必要があります。

Process (clk)      
    ...   
begin
    if rising_edge(clk) then
        ...
于 2013-03-22T06:50:33.513 に答える