筆記:以C/C++概念來說正確的VHDL除頻器

我昨天還為下面這樣的寫法而驚呼,想說這樣都能Compile,那VHDL是否可寫遞迴?

這個程式碼是一個除頻器,我希望能夠利用 generic 於 Compile time 動態改變程式碼內容的特性,進而造就一個"只"需要指定數的數字,就能動態的計算出數字所需要的 bit 數目,如此一來,我只需要在使用component的時候,設定數數,就能完成除頻器,好用的不得了。

VHDL程式碼
01 library IEEE;
02 use ieee.std_logic_1164.all;
03 use ieee.numeric_std.all;
04
05 entity Vhdl1 is
06  generic(COUNT_NUMBER : integer := 16);
07  port(clk: in std_logic;
08  clkout: out std_logic);
09 end entity Vhdl1;
10
11 architecture main of Vhdl1 is
12  function getCountNumberBits (number :integer)
13  return integer is
14   variable c: integer := 0;
15   variable n: integer := number;
16  begin
17   while n /= 0 loop
18    n := n /2;
19    c := c + 1;
20   end loop;
21   return c;
22  end function getCountNumberBits;
23 begin
24  count: process(clk) is
25   variable COUNTED_NUMBER: integer := COUNT_NUMBER-1;
26   variable COUNTED_NUMBER_BITS: integer := getCountNumberBits(COUNTED_NUMBER);
27    variable cnt: unsigned(COUNTED_NUMBER_BITS-1 downto 0) := (others=>'0');
28   begin
29   if rising_edge(clk) then
30    if cnt = COUNTED_NUMBER then
31     cnt := (others=>'0');
32    else
33     cnt := cnt + 1;
34    end if;
35   end if;
36   clkout <= cnt(COUNTED_NUMBER_BITS-1); 37  end process count; 38 end architecture main;

結果今天就得到噩耗,其實上面的 Code 是沒辦法使用的,雖然就C/C++的寫法是可能的,但畢竟電路不是能購動態的配置出來的,所以 cnt 也就不能被動態的改變,只是我剛好都使用設定初值,這使得編譯器認為它是個固定數值。
如果將設定初值的改為在電路一開始時運作,Compile就只會得到下面的訊息
Error (10394): VHDL error at Vhdl1.vhd(27): left bound of range must be a constant
所以在C/C++的概念上,可以運作的程式,並不是都能直接套用在VHDL的程式上,如上面的這個範例以及遞迴。

留言