0

私はvhdlプログラミングが初めてです。最近、ボタンを押すことで、クロック信号に敏感なシフト レジスタの std_logic_vector の値を変更するタスクを取得しました。

KEY(2) を押しているとシフトレジスタの値が変わりますが、ボタンを離さない限りシフトしません。以下のコードを変更して、KEY(2) の立ち上がりエッジに敏感になるようにすることはできますか? または、KEY(2)ボタンを押してベクトルの値を変更する可能性は他にあり、ボタンを押したままにしてもシフトしますか?

ご回答ありがとうございます。私は本当に感謝していますし、それは本当に私を大いに助けてくれるでしょう.

私の悪い英語でごめんなさい。よいひとときを。

ENTITY hadvhdl  IS PORT (
    CLOCK_50 : IN STD_LOGIC;
    KEY      : IN STD_LOGIC_VECTOR  (3 downto 0);
    LEDR     : OUT STD_LOGIC_VECTOR (15 downto 0)
);
END hadvhdl;

ARCHITECTURE rtl OF hadvhdl IS
    shared variable register : std_logic_vector(15 downto 0) := (1 downto 0=>'1', others=>'0');
    shared variable count   : integer range 1 to 4 :=1;
BEGIN

    changecount: process (KEY)
    begin    
        if rising_edge(KEY(2)) then
            if count<4 then
                count := count + 1; 
            else
                count := 1;
            end if;
        end if; 
    end process;

    shift: process (CLOCK_50, KEY)
        variable up : BOOLEAN := FALSE;
        variable reg : std_logic_vector(15 downto 0) := (1 downto 0=>'1', others=>'0'); 
    begin   
        if rising_edge(CLOCK_50) then
            if (KEY(2)='1') then
                case count is 
                    when 1 => register := (1 downto 0=>'1', others=>'0'); 
                    when 2 => register := (2 downto 0=>'1', others=>'0'); 
                    when 3 => register := (3 downto 0=>'1', others=>'0'); 
                    when 4 => register := (4 downto 0=>'1', others=>'0'); 
                end case; 
            end if;

            reg := register;
            LEDR <= reg;

            if up then
                reg := reg(0) & reg(15 downto 1); 
            else 
                reg := reg(14 downto 0) & reg(15);  
            end if;

            register := reg;

        end if;
    end process;

END rtl;
4

1 に答える 1

-1
  1. 変数を使用しないでください。(少なくともVHDL初心者として)
  2. プッシュ ボタンをクロックとして使用しないでください (たとえば、rising_edge 内)。
  3. デザインで1 つのクロックのみを使用します (この場合は問題ないようです)。
  4. 機械式の押しボタンはバウンドすることに注意してください。

そして、ここにエッジ検出のバリアントがあります:

  -- in entity
  clk    ; in std_logic;
  sig_in : in std_logic;

...

signal sig_old  : std_logic;
signal sig_rise : std_logic;
signal sig_fall : std_logic;

...

  process
  begin
    wait until rising_edge( clk);

    -- defaults
    sig_rise <= '0';
    sig_fall <= '0';

    -- shift value in
    sig_old <= sig_in;

    -- do some real action
    if sig_old = '0' and sig_in = '1' then
      sig_rise <= '1';
    end if;

    if sig_old = '1' and sig_in = '0' then
      sig_fall <= '1';
    end if;

  end process;
于 2013-03-16T18:40:28.607 に答える