2013-06-19 59 views
0

我已將我的代碼修改爲以下內容以從50Mhz傳入時鐘生成0.5 Mhz時鐘我已使用同步計數器時鐘使能並檢測din輸入數據中的00110001模式並輸出圖像中所示的同步脈衝。但是我希望在檢測模式中的最後一位的同時不要同時進行。請在下面檢查我的代碼,並讓我知道我的錯在哪裏。我非常感謝你的幫助。謝謝。 enter image description hereVHDL模式檢測器

pattern_detector_clk_0_5mhz : process(clk_50mhz) 
begin 
if clk_50mhz'event and clk_50mhz = '1' then 
    if rst = '0' then 
    clk_enable_0_5mhz <= '0'; 
    temp1 <= (others => '0'); 
    else 
      temp1 <= temp1 +"1"; 
      clk_enable_0_5mhz <= '0'; 
     if temp1 >= x"63" then  --hexadecimal value for 99 
      temp1 <= (others => '0'); 
      clk_enable_0_5mhz <= not clk_enable_0_5mhz; 
     end if;    
    end if; 
    end if; 
end process; 

    decoder_shift_reg_proc: process (clk_50mhz) 
    begin 
    if clk_50mhz'event and clk_50mhz = '1' then 
    if rst = '0' then 
     decoder_shift8 <= (others => '0'); 
    elsif clk_enable_0_5mhz = '1' then 
      for i in 0 to 6 loop 
      decoder_shift8(i+1) <= decoder_shift8(i); 
     end loop;   
     decoder_shift8(0) <= din; 
    end if; 
    end if; 
end process; 

sync_detector_process: process(decoder_shift8) 
begin 
if decoder_shift8 = PATTERN_TO_DETECT or decoder_shift8 = not PATTERN_TO_DETECT then 
      sync_detected <= '1'; 
     else 
      sync_detected <= '0'; 
end if; 
end process; 
+0

格式的代碼可以正確 – gawi

+0

與您的代碼的問題是,你仍然可以使用50MHz的時鐘來檢查模式,你的第二個proccess應該只引用對clk_enable_0_5mhz和RST – gawi

+0

感謝gawi,當我在只使用clk_enable_0_5mhz第二個進程和實現代碼,然後我得到以下警告:路由:455 - CLK網絡:clk_enable_0_5mhz_OBUF可能會有過度歪斜,因爲 – user24883

回答

1

問題是,您的使能信號會很長!僅在一個時鐘週期內設置使能信號!

... 
    clk_enable_0_5mhz<='0'; -- clear enable by default 

    if temp >= x"31" then 
     temp <= (others => '0'); 
     clk_enable_0_5mhz <= '1';-- set enable only for one clock cycle 
    end if; 
    ... 

你不需要使能信號添加到您的敏感列表,因爲該進程將運行同步到你的時鐘信號呢(除非重置異步)。

process(clk_50mhz, rst) 
begin 
    if(rst = '0') then 
     ... 
    elsif (clk_50mhz'event and clk_50mhz = '1') then 
     if(clk_enable_0_5mhz = '1') then 
     ... 

這裏是我用

-- testbench 
library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL; 

entity pattern_tb is 
end pattern_tb; 

architecture Behavior of pattern_tb is 

component clk0_5mhz_top 
port (

     clk_50mhz : in std_logic; 
     rst : in std_logic; 
     din : IN std_logic; 
     dout : OUT std_logic; 
     clk_enable_0_5mhz : inout std_logic 
     ); 

end component; 

signal clk_50mhz : std_logic; 
signal rst : std_logic; 
signal din : std_logic; 
signal dout : std_logic; 
signal clk_enable_0_5mhz : std_logic; 

constant pattern: std_logic_vector(7 downto 0):="00110001"; 
begin 

uut: clk0_5mhz_top 
port map(
     clk_50mhz => clk_50mhz, 
     rst => rst, 
     din => din, 
     dout => dout, 
     clk_enable_0_5mhz => clk_enable_0_5mhz 
     ); 

gen_clk: process 
begin 
    clk_50mhz<='0'; 
    wait for 10 ns; 
    clk_50mhz<='1'; 
    wait for 10 ns; 
end process; 

gen_sigs: process 
begin 
    rst<='0'; 
    din<=pattern(7); 
    wait for 10 us; 
    rst<='1'; 
    wait for 10 us; 
    for i in 7 downto 0 loop 
     wait until falling_edge(clk_enable_0_5mhz); 
     din<=pattern(i); 
    end loop; 
    wait; 
end process; 

end Behavior; 
+0

感謝baldyHDL,我厭倦了實現你的建議,但沒有輸出,即dout始終保持'0',並且沒有錯誤和警告。 – user24883

+0

其實它工作!我在上面的答案中添加了我使用的測試臺。 – baldyHDL

+0

baldyHDL,我想我知道它爲什麼與你的測試平臺一起工作,因爲你建議的代碼會產生1us時間段內的clk_enable_0_5mhz信號,並且你的測試臺中的每一位都是1us長度,因爲我需要clus_enable_0_5mhz時間段,因爲它應該檢測din中的模式00110001包含長度爲2us的每一位,這就是爲什麼我無法獲得dout的原因。你知道如何解決這個問題嗎? – user24883

-1

你真的需要clk_enable_0_5mhz爲INOUT?也許信號就夠了? 當然,你應該在一開始初始化:

signal clk_enable_0_5mhz: std_logic := '0'; 

那麼該過程的開始應該像(刪除if語句之一):

process(clk_enable_0_5mhz, rst) 
begin 
    if(rst = '0') then 
     dout <= '0'; 
     state <= A; 
    elsif (clk_enable_0_5mhz'event and clk_enable_0_5mhz = '1') then 

我希望這會有所幫助。

+0

這種設計不是很好的做法!它會讓合成器將clk_enable_0_5mhz信號視爲時鐘而不是啓用。 user24883的初始方法更好,因爲它與ONE時鐘真正同步。 – baldyHDL

1

這裏測試平臺你走。我用8位移位寄存器替換了狀態機。我認爲它更乾淨。

library ieee; 

use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 


entity clk0_5mhz_top is 
port (
     clk_50mhz : in std_logic; 
     rst : in std_logic; 
     din : in std_logic; 
     dout : out std_logic; 
     clk_enable_0_5mhz : out std_logic 
); 
end clk0_5mhz_top; 

architecture behavioral of clk0_5mhz_top is 

    constant PATTERN_TO_DETECT : std_logic_vector(7 downto 0) := "00110001"; 
    signal din_sr8 : std_logic_vector(7 downto 0); 

    signal clk_5_mhz : std_logic; 
    signal counter : unsigned(5 downto 0); 

begin 

    --generating the synchronous counter clock enable 
    p_5mhz_clk_generator : process(clk_50mhz, rst) 
    begin 

     clk_enable_0_5mhz <= clk_5_mhz; 

     if(rst = '0') then 
      clk_5_mhz <= '0'; 
      counter <= (others => '0'); 

     elsif(rising_edge(clk_50mhz)) then 
      counter <= counter +"1"; 

      if counter >= x"31" then --49 
       counter <= (others => '0'); 
       clk_5_mhz <= '1'; 
      else 
       clk_5_mhz <= '0'; 
      end if; 

     end if; 

    end process; 

    --generating 00110001 pattern detector 
    p_pattern_detector : process(clk_5_mhz, rst) 
    begin 
     if(rst = '0') then 
      dout <= '0'; 
      din_sr8 <= "XXXXXXXX"; 
     elsif (clk_5_mhz='1') then 
      for i in 0 to 6 loop --register shifter 
       din_sr8(i+1) <= din_sr8(i); 
      end loop;   

      din_sr8(0) <= din; 

      if din_sr8 = PATTERN_TO_DETECT then 
       dout <= '1'; 
      else 
       dout <= '0'; 
      end if; 

     end if; 

    end process; 

end; 
+0

非常感謝Passepartout。我能夠得到輸出,即在檢測到00110001模式的最後一位'1'時,在相同的時鐘上升沿dout變高。在整個模式被檢測到之後,我怎麼能在clk_enable_0_5mhz的下一個上升沿上升到最高?如果我忽略此警告,我仍然會收到此警告?警告:路由:455 - CLK網絡:clk_enable_0_5mhz_OBUF可能會產生過度偏斜,因爲0個CLK引腳和2個NON_CLK引腳無法使用CLK模板進行路由。 – user24883

+0

你只需要記錄你的輸出任務就有額外的延遲。我編輯了我的代碼來解決這個問題。此外,您的警告幾乎肯定是由於您的時鐘是一個幾乎不應該使用的輸入信號而造成的。如果你需要一個你也需要在內部使用的輸出,你應該創建另一個信號。我也做了更正。你現在不應該得到任何警告。 – Passepartout

+0

非常感謝Passepartout你一直很有幫助。我得到了我需要的輸出,但警告?警告:路由:455 - CLK Net:clk_5_mhz可能會產生過度偏斜,因爲0 CLK引腳和2 NON_CLK引腳無法使用CLK模板進行路由。 – user24883