2014-04-14 21 views
4

我正在用VHDL實現一個正交解碼器,並提出了兩種解決方案。VHDL正交解碼器:順序/組合邏輯

在方法1中,所有的邏輯都放在一個對時鐘和復位敏感的進程中。 在Spartan-3A上,它使用四個片,七個FF和四個輸入LUT。

代碼1

architecture Behavioral of quadr_decoder is 
    signal chan_a_curr : std_logic; 
    signal chan_a_prev : std_logic; 
    signal chan_b_curr : std_logic; 
    signal chan_b_prev : std_logic; 
begin 
    process (n_reset, clk_in) begin 
     if (n_reset = '0') then 
      -- initialize internal signals 
      chan_a_curr <= '0'; 
      chan_a_prev <= '0'; 
      chan_b_curr <= '0'; 
      chan_b_prev <= '0'; 
      -- initialize outputs 
      count_evt <= '0'; 
      count_dir <= '0'; 
      error_evt <= '0'; 
     elsif (clk_in'event and clk_in = '1') then 
      -- keep delayed inputs 
      chan_a_prev <= chan_a_curr; 
      chan_b_prev <= chan_b_curr; 
      -- read current inputs 
      chan_a_curr <= chan_a; 
      chan_b_curr <= chan_b; 
      -- detect a count event 
      count_evt <= ((chan_a_prev xor chan_a_curr) xor 
          (chan_b_prev xor chan_b_curr)); 
      -- determine count direction 
      count_dir <= (chan_a_curr xor chan_b_prev xor 
          count_mode); 
      -- detect error conditions 
      error_evt <= ((chan_a_prev xor chan_a_curr) and 
          (chan_b_prev xor chan_b_curr)); 
     end if; 
    end process; 
end Behavioral; 

方法2拆分邏輯成單獨的順序和組合過程。它使用兩個切片,四個FF和四個輸入LUT。

代碼2

architecture Behavioral of quadr_decoder is 
    signal chan_a_curr : std_logic; 
    signal chan_a_prev : std_logic; 
    signal chan_b_curr : std_logic; 
    signal chan_b_prev : std_logic; 
begin 
    process (n_reset, clk_in) begin 
     if (n_reset = '0') then 
      -- initialize internal signals 
      chan_a_curr <= '0'; 
      chan_a_prev <= '0'; 
      chan_b_curr <= '0'; 
      chan_b_prev <= '0'; 
     elsif (clk_in'event and clk_in = '1') then 
      -- keep delayed inputs 
      chan_a_prev <= chan_a_curr; 
      chan_b_prev <= chan_b_curr; 
      -- read current inputs 
      chan_a_curr <= chan_a; 
      chan_b_curr <= chan_b; 
     end if; 
    end process; 

    process (chan_a_prev, chan_a_curr, chan_b_prev, chan_b_curr) begin 
      -- detect a count event 
      count_evt <= ((chan_a_prev xor chan_a_curr) xor 
          (chan_b_prev xor chan_b_curr)); 
      -- determine count direction 
      count_dir <= (chan_a_curr xor chan_b_prev xor count_mode); 
      -- detect error conditions 
      error_evt <= ((chan_a_prev xor chan_a_curr) and 
         (chan_b_prev xor chan_b_curr)); 
    end process; 
end Behavioral; 

當我模擬代碼(行爲),這兩種結果已經很好了。但我不能相信這兩種方法是同樣有效的。 有人可以說明哪種方法比其他方法更受歡迎?

回答

4

您的代碼版本2個驅動輸出組合地而代碼版本1個寄存器的輸出:

  • count_evt
  • count_dir
  • error_evt

這佔了3個額外的觸發器(並且由於斯巴達3每片有2個寄存器,意味着你需要2個額外的片)。

雖然由代碼執行的邏輯功能是相同的,但它們的行爲不一樣。如果/當您將輸出連接到另一個塊輸入時,結果將在版本2提前1個週期可用。假設下游塊獲取這些輸入並應用更多邏輯,您將看到版本2導致較長的路徑,因此可獲得的頻率較低。

一些準則聲明,您通常應該將輸出註冊到塊以提高計時。有時候你想要能夠將多個區塊組合在一起,所有指南總是有一些例外。如果任何產出是組合驅動的,那麼在聲明中評論是一個好習慣。如果你感覺特別敏銳,你可以使用通用的輸出寄存器進行選擇。