0

コードを次のように変更して、50Mhz の着信クロックから 0.5Mhz のクロックを生成しました。しかし、パターンの最後のビットを検出すると同時に、dout を実行したいと考えています。以下のコードを確認して、どこが間違っているか教えてください。本当にありがとうございました。ありがとうございました。ここに画像の説明を入力

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;
4

3 に答える 3

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;
于 2013-06-19T14:04:10.017 に答える
1

問題は、イネーブル信号が長すぎることです! イネーブル信号を 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;
于 2013-06-19T12:27:17.513 に答える
-1

clk_enable_0_5mhz が inout として本当に必要ですか? 多分信号で十分でしょうか?もちろん、最初に初期化する必要があります。

signal clk_enable_0_5mhz: std_logic := '0';

プロセスの開始は次のようになります (if ステートメントの 1 つを削除します)。

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

これが役立つことを願っています。

于 2013-06-19T11:13:41.897 に答える