2014-04-14 25 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导致较长的路径,因此可获得的频率较低。

一些准则声明,您通常应该将输出注册到块以提高计时。有时候你想要能够将多个区块组合在一起,所有指南总是有一些例外。如果任何产出是组合驱动的,那么在声明中评论是一个好习惯。如果你感觉特别敏锐,你可以使用通用的输出寄存器进行选择。