2013-02-09 56 views
1

我想實現K & R算法,用於計算256位向量的漢明重量。我寫我的代碼的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; 

但是,儘管採用Xilinx合成它,在錯誤出現的

53行:非靜態環超限

任何線索嗎?

P.S:53號線 - 而(值> 0)環

回答

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是一個信號,而不是一個變量。這意味着它將在完成增量循環時更新。在這種情況下,將永遠不會。所以你有一個無限循環。


如果你只是想計算一個數字的popcount,那麼爲什麼你不這樣做。雖然我懷疑這會符合時序(可能需要在多個時鐘週期內分解它)。

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代碼算法通常在硬件表現不佳,因爲硬件已經不是一個固定的處理器不同的能力。

+0

不要你的意思是「循環結束;」而不是「結束」;? – 2014-12-21 23:59:09

+0

@LuísMarques:你是對的。謝謝。 – 2014-12-22 00:35:32

3

您需要了解signalvariable之間的區別。

當您分配給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;