1

256 ビット ベクトルのハミング重み計算に K&R アルゴリズムを実装したいと考えています。vhdl でコードを次のように記述しました。

entity counter_loop is
    Port ( dataIn : in  STD_LOGIC_VECTOR (255 downto 0);
              dataOut : out STD_LOGIC_VECTOR (8 downto 0);
           threshold : in  STD_LOGIC_VECTOR (8 downto 0);
           clk : in  STD_LOGIC;
           flag : out  STD_LOGIC);
end counter_loop;

architecture Behavioral of counter_loop is
    signal val : STD_LOGIC_VECTOR (255 downto 0) := X"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
begin
    process (clk)
        variable count : STD_LOGIC_VECTOR (8 downto 0):= "000000000";       
    begin
        flag <= '0';
        val <= dataIn;
        --if(clk'event and clk = '1') then 
            while (val > 0) loop
                count := count+1;
                val <= (val and (val-1));
                if (count > threshold) then
                    flag <= '1';
                end if;
            end loop;
                dataOut <= count;
        --end if;
    end process;
end Behavioral;

しかし、ザイリンクスを使用して合成している間、エラーが次のように表示されます

53 行目: 非静的ループ制限を超えました

手がかりはありますか?

PS: 53 行目は - while (val > 0) ループです

4

2 に答える 2

3

したがって、実際にタイミングを満たす (val - 1コストがかかる) という問題は無視し、実際にあなたのロジックについて話します。

これがあなたのコードの一部です:

signal val : std_logic_vector(255 downto 0) := (others => '1');

process (clk)
begin
    while (val > 0) loop
        val <= (val and (val-1));
    end loop;
end process;

val変数ではなく信号です。つまり、デルタ サイクルが終了すると更新されます。この場合、これは決してありません。したがって、無限ループがあります。


数値のポップカウントを計算しようとしているだけなら、これをやってみませんか。これもタイミングを満たすとは思えませんが(おそらく、複数のクロックサイクルに分割する必要があります)。

process (clk)
    variable count : std_logic_vector(8 downto 0) := "0" & x"00";
begin
    if rising_edge(clk) then
        for i in dataIn'range loop
            if dataIn(i) = '1' then
                count := count + 1;
            end if;
        end loop;

        dataOut <= count_i;
    end if;
end process;

そして最後に、ほとんどの人は、C コード用に設計されたアルゴリズムは、ハードウェアではパフォーマンスが低下することが多いと主張するでしょう。これは、ハードウェアが固定プロセッサとは異なる機能を備えているためです。

于 2013-02-09T19:17:25.707 に答える
3

signalaとの違いについて学ぶ必要がありvariableます。

に割り当てると、signal時間が進む次の時点の変更のみをスケジュールします (あなたのようなクロックプロセスでは、これはプロセスが終了し、現在実行がスケジュールされている他のすべてのプロセスも終了したときです) )。

val <= somethingそのため、プロセスのループに書き込むと、val更新されるようにスケジュールされているだけです。プロセスがその値を検査するvalと、スケジュールされた値ではなく、現在の値が表示されます。このように物事を追跡するには、変数を使用する必要があります。

ただし、他の場所で述べたように、単に数えたい場合は、はるかに簡単です。

count:=0;
for i in dataIn'range loop
   if dataIn(i) = '1' then 
      count:=count+1; 
   end if;
end loop;
于 2013-02-11T14:17:30.723 に答える