2017-06-22 113 views
1

這裏是來自Xilinx Zynq示例的代碼。我無法理解這是爲了什麼?奇怪的邊緣檢測或其他?

在我pulse_d2僅在s_axi_resetn的下降沿爲1。

以這種方式檢測下降沿的原因是什麼?

爲什麼不使用事件,像「if(s_axi_resetn'event和s_axi_resetn ='0')」?

process(s_axi_clk) 
    begin 
     if (s_axi_clk'event and s_axi_clk = '1') then 
      if (s_axi_resetn = '0') then 
       pulse <= '0'; 
      else 
       pulse <= '1'; 
      end if; 
     end if; 
    end process; 

    process(s_axi_clk) 
    begin 
     if (s_axi_clk'event and s_axi_clk = '1') then 
      if (s_axi_resetn = '0') then 
       pulse_d1 <= '0'; 
      else 
       pulse_d1 <= pulse; 
      end if; 
     end if; 
    end process; 

    pulse_d2 <= pulse and (not pulse_d1); 
+0

這是Xilinx的例子嗎?他們然後在這裏做了一些低質量的代碼。奇怪的信號命名。不使用'rising_edge'。一切都可以寫得更有效率。 – JHBonarius

+0

是的,這段代碼來自AXI Datamover示例。您能否爲了學習的目的給出一些更高效的代碼或其他具有相同功能的變體? – eloiman

回答

1

s_axi_clk爲其s_axi_resetn低,pulsepulse_d1上升沿被迫'0'pulse_d2也需要值「0」。

s_axi_clk第一個上升沿爲哪些s_axi_resetn高,pulse變高但pulse_d1樣品pulse的電流值,即,'0'pulse_d2因此取值'1'。

s_axi_clk的第二個上升沿,其中s_axi_resetn爲高,pulse爲高,pulse_d1爲高。 pulse_d2因此取值'0'。

s_axi_clk以下的上升沿,其中s_axi_resetn高,pulsepulse_d1保持高位。 pulse_d2因此取值'0'。

所以,這種設計是一種檢測復位解除的方法,並用pulse_d2上的單個時鐘週期脈衝高電平來發信號。

1

您引用的代碼是同步邊緣檢測器的示例 - 請參閱例如this on my company's website

這是用來檢測一些信號的邊緣上不是時鐘,因此是同步設計

對於一個設計成同步

  1. 所有觸發器應計時所有的時間從相同的時鐘的同一邊緣
  2. 應該不存在鎖存器
  3. 應該是否組合反饋

如果您使用的代碼

if (s_axi_resetn'event and s_axi_resetn = '0') 

那麼這將合成到由信號s_axi_resetn主頻觸發器來實現您的邊緣檢測。你剛剛違反規則#1,你的設計不再同步。

由於各種原因,真正的設計不太可能完全同步。但是,你應該儘量減少離開同步設計的次數,任何離開都應該讓你在晚上保持清醒。因此,您應始終使用同步邊沿檢測器來檢測信號的邊沿,而不是將該信號連接到觸發器的時鐘輸入。

+0

謝謝,非常有用!我想這種邊緣檢測器可以做成一個組件設計。 – eloiman