VHDL模式检测器

时间:2013-06-19 09:15:33

标签: vhdl

我已将我的代码修改为以下内容,从50Mhz输入时钟生成0.5 Mhz时钟我已使用同步计数器时钟使能并检测din输入数据上的00110001模式并输出同步脉冲,如图所示。但我希望dout同时检测到模式中的最后一位。请检查下面的代码,让我知道我哪里出错了。我非常感谢你的帮助。谢谢。enter image description here

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;

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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;

答案 2 :(得分:-1)

你真的需要clk_enable_0_5mhz吗?也许信号就足够了? 当然你应该在开始时初始化它:

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

我希望这会有所帮助。