2015-12-10 68 views
0

我正在使用VHDL和一塊FPGA板,一個VGA接口和一個PS/2鍵盤接口來創建一個迷宮並製作一個可以在迷宮中移動的正方形。當我按下其中一個鍵(WASD)時,方塊只移動一個位置,然後不再移動。每次按下其中一個鍵時,我都需要它移動。這裏是我的代碼:VHDL PS/2接口

ENTITY hw_image_generator IS 

    PORT(
     ps2_code : IN STD_LOGIC_VECTOR(7 DOWNTO 0); 
     game_clk : IN STD_LOGIC; 
     disp_ena : IN STD_LOGIC; --display enable ('1' = display time, '0' = blanking time) 
     row   : IN INTEGER;  --row pixel coordinate 
     column  : IN INTEGER;  --column pixel coordinate 
     red   : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0'); --red magnitude output to DAC 
     green  : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0'); --green magnitude output to DAC 
     blue  : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0')); --blue magnitude output to DAC 
END hw_image_generator; 

ARCHITECTURE behavior OF hw_image_generator IS 
    signal x_position: INTEGER := 20; 
    signal y_position: INTEGER := 20; 
    CONSTANT max_count: NATURAL := 500000; 
    SIGNAL reset: STD_LOGIC; 


BEGIN 

    PROCESS(game_clk, reset, x_position, y_position) 

     VARIABLE count : NATURAL range 0 to max_count; 

    BEGIN 

     IF (reset = '1') THEN 
      count := 0; 
      x_position <= 20; 
      y_position <= 20; 

     ELSIF(rising_edge(game_clk) AND count = 0) THEN 

      IF(count < max_count)THEN 

       IF(ps2_code = "00101001") THEN -- space bar 
        count := 0; 
        x_position <= 20; 
        y_position <= 20; 
       END IF; 

       IF(ps2_code = "00011101") THEN  --W key 
        count := count + 1; 
        y_position <= y_position; 
        x_position <= x_position - 10; 
       END IF; 

       IF(ps2_code = "00011011") THEN  --S key 
        count := count + 1; 
        y_position <= y_position; 
        x_position <= x_position + 10; 
       END IF; 

       IF(ps2_code = "00100011") THEN  --D key 
        count := count + 1; 
        x_position <= x_position; 
        y_position <= y_position + 10; 
       END IF; 

       IF(ps2_code = "00011100") THEN  --A key 
        count := count + 1; 
        x_position <= x_position; 
        y_position <= y_position - 10; 
       END IF; 

      ELSE 
      count := 0; 
      END IF; 
     END IF; 
    END PROCESS; 


    PROCESS(disp_ena, row, column) 
    BEGIN 

     IF(disp_ena = '1') THEN  --display time 

      IF(row < 512 AND column > 231 AND column < 281) THEN 
       red <= (OTHERS => '0'); 
       green <= (OTHERS => '0'); 
       blue <= (OTHERS => '0'); 

      ELSIF(row > 743 AND row < 793 AND column < 512) THEN 
       red <= (OTHERS => '0'); 
       green <= (OTHERS => '0'); 
       blue <= (OTHERS => '0'); 

      ELSIF(row > 1024 AND column > 231 AND column < 281) THEN 
       red <= (OTHERS => '0'); 
       green <= (OTHERS => '0'); 
       blue <= (OTHERS => '0'); 

      ELSIF(row > 256 AND row < 1024 AND column > 487 AND column < 537) THEN 
       red <= (OTHERS => '0'); 
       green <= (OTHERS => '0'); 
       blue <= (OTHERS => '0'); 

      ELSIF(row > 487 AND row < 537 AND column > 536 AND column < 768) THEN 
       red <= (OTHERS => '0'); 
       green <= (OTHERS => '0'); 
       blue <= (OTHERS => '0'); 

      ELSIF(row > 231 AND row < 281 AND column > 768) THEN 
       red <= (OTHERS => '0'); 
       green <= (OTHERS => '0'); 
       blue <= (OTHERS => '0'); 

      ELSIF(row > 743 AND row < 793 AND column > 768) THEN 
       red <= (OTHERS => '0'); 
       green <= (OTHERS => '0'); 
       blue <= (OTHERS => '0'); 

      ELSIF(row > 974 AND row < 1024 AND column > 536 AND column < 768) THEN 
       red <= (OTHERS => '0'); 
       green <= (OTHERS => '0'); 
       blue <= (OTHERS => '0'); 

      ELSE 
       red <= (OTHERS => '1'); 
       green <= (OTHERS => '1'); 
       blue <= (OTHERS => '1'); 

      END IF; 

      IF(row > x_position AND row < x_position+50 AND column > y_position AND column < y_position+50) THEN 
       red <= (OTHERS => '1'); 
       green <= (OTHERS => '0'); 
       blue <= (OTHERS => '0'); 
      END IF; 

      ELSE        --blanking time 
       red <= (OTHERS => '0'); 
       green <= (OTHERS => '0'); 
       blue <= (OTHERS => '0'); 

     END IF; 
    END PROCESS; 
END behavior; 
+0

它在模擬中是否正常工作? –

+0

我得到它使用不同的代碼工作。 – SWade

回答

0

在你未標記的過程敏感game_clk:

process (game_clk, reset, x_position, y_position) 
     variable count: natural range 0 to max_count; 
    begin 

     if reset = '1' then 
      count := 0; 
      x_position <= 20; 
      y_position <= 20; 
     elsif rising_edge(game_clk) and count = 0 then 
      if count < max_count then 

       if ps2_code = "00101001" then -- space bar 
        count := 0; 
        x_position <= 20; 
        y_position <= 20; 
       end if; 

       if ps2_code = "00011101" then  --w key 
        count := count + 1; 
        y_position <= y_position; 
        x_position <= x_position - 10; 
       end if; 

       if ps2_code = "00011011" then  --s key 
        count := count + 1; 
        y_position <= y_position; 
        x_position <= x_position + 10; 
       end if; 

       if ps2_code = "00100011" then  --d key 
        count := count + 1; 
        x_position <= x_position; 
        y_position <= y_position + 10; 
       end if; 

       if ps2_code = "00011100" then  --a key 
        count := count + 1; 
        x_position <= x_position; 
        y_position <= y_position - 10; 
       end if; 

      else 
       count := 0; 
      end if; 
     end if; 
    end process; 

通知你不需要x_position和y_position在敏感列表。所有的信號分配都是由於重置事件或game_clk事件造成的。

還要注意的ELSIF的條件使count = 0

 elsif rising_edge(game_clk) and count = 0 then 

而且在條件以下if語句:

  if count < max_count then 

一旦你的任何ps2_code識別器(除了空格鍵)是有效的,你將增加計數並且不再在game_clk的上升沿啓用任何觸發器和寄存器。你也不知道你是否連續擊中空格鍵。而不會擊中另一個識別器。

您的代碼與您的問題描述相匹配,這是一項功能。

0
PROCESS(game_clk) 
BEGIN 
    IF(game_clk'EVENT AND game_clk = '1')THEN 
     count <= count + 1; 
     IF(count = 5000000 AND ps2_code = "00101001")THEN --space key 
      count <= 0; 
      x_position <= 20; 
      y_position <= 20; 
     END IF; 

     IF(count = 5000000 AND ps2_code = "00011101")THEN --W key 
      count <= 0; 
      IF((y_position >  0 AND y_position < 181 AND x_position > 0 and x_position < 512) --1 
       OR (y_position >  0 AND y_position < 437 AND x_position > 512 AND x_position < 693) --2 
       OR (y_position > 281 AND y_position < 437 AND x_position > 0 and x_position < 512) --3 
       OR (y_position > 437 AND y_position < 537 AND x_position > 0 AND x_position < 206) --4 
       OR (y_position > 537 AND y_position < 1227 AND x_position > 0 AND x_position < 181) --5 
       OR (y_position > 537 AND y_position < 718 AND x_position > 181 AND x_position < 437) --6 
       OR (y_position > 768 AND y_position < 1227 AND x_position > 281 AND x_position < 718) --7 
       OR (y_position > 537 AND y_position < 768 AND x_position > 537 AND x_position < 693) --8 
       OR (y_position > 537 AND y_position < 718 AND x_position > 693 AND x_position < 793) --9 
       OR (y_position > 537 AND y_position < 768 AND x_position > 793 AND x_position < 975) --10 
       OR (y_position > 768 AND y_position < 1227 AND x_position > 793 AND x_position < 1027) --11 
       OR (y_position > 718 AND y_position < 768 AND x_position > 281 AND x_position < 437) --12 
       ) THEN 
        x_position <= x_position - 10; 
       ELSE 
        x_position <= x_position + 5; 
        y_position <= y_position; 
      END IF; 

     ELSIF(count = 5000000 AND ps2_code = "00011011") THEN --S key 
      count <= 0; 
      IF((y_position >  0 AND y_position < 181 AND x_position > 0 and x_position < 512) --1 
       OR (y_position >  0 AND y_position < 437 AND x_position > 512 AND x_position < 693) --2 
       OR (y_position > 281 AND y_position < 437 AND x_position > 0 and x_position < 512) --3 
       OR (y_position > 437 AND y_position < 537 AND x_position > 0 AND x_position < 206) --4 
       OR (y_position > 537 AND y_position < 1227 AND x_position > 0 AND x_position < 181) --5 
       OR (y_position > 537 AND y_position < 718 AND x_position > 181 AND x_position < 437) --6 
       OR (y_position > 768 AND y_position < 1227 AND x_position > 281 AND x_position < 718) --7 
       OR (y_position > 537 AND y_position < 768 AND x_position > 537 AND x_position < 693) --8 
       OR (y_position > 537 AND y_position < 718 AND x_position > 693 AND x_position < 793) --9 
       OR (y_position > 537 AND y_position < 768 AND x_position > 793 AND x_position < 975) --10 
       OR (y_position > 768 AND y_position < 1227 AND x_position > 793 AND x_position < 1027) --11 
       OR (y_position > 718 AND y_position < 768 AND x_position > 281 AND x_position < 437) --12 
       ) THEN 
        x_position <= x_position + 10; 
       ELSE 
        x_position <= x_position - 5; 
        y_position <= y_position; 
      END IF; 

     ELSIF(count = 5000000 AND ps2_code = "00100011") THEN --D key 
      count <= 0; 
      IF((y_position >  0 AND y_position < 181 AND x_position > 0 and x_position < 512) --1 
       OR (y_position >  0 AND y_position < 437 AND x_position > 512 AND x_position < 693) --2 
       OR (y_position > 281 AND y_position < 437 AND x_position > 0 and x_position < 512) --3 
       OR (y_position > 437 AND y_position < 537 AND x_position > 0 AND x_position < 206) --4 
       OR (y_position > 537 AND y_position < 1227 AND x_position > 0 AND x_position < 181) --5 
       OR (y_position > 537 AND y_position < 718 AND x_position > 181 AND x_position < 437) --6 
       OR (y_position > 768 AND y_position < 1227 AND x_position > 281 AND x_position < 718) --7 
       OR (y_position > 537 AND y_position < 768 AND x_position > 537 AND x_position < 693) --8 
       OR (y_position > 537 AND y_position < 718 AND x_position > 693 AND x_position < 793) --9 
       OR (y_position > 537 AND y_position < 768 AND x_position > 793 AND x_position < 975) --10 
       OR (y_position > 768 AND y_position < 1227 AND x_position > 793 AND x_position < 1027) --11 
       OR (y_position > 718 AND y_position < 768 AND x_position > 281 AND x_position < 437) --12 
       ) THEN 
        y_position <= y_position + 10; 
       ELSE 
        x_position <= x_position; 
        y_position <= y_position -5; 
      END IF; 

     ELSIF(count = 5000000 AND ps2_code = "00011100") THEN --A key 
      count <= 0; 
      IF((y_position >  0 AND y_position < 181 AND x_position > 0 and x_position < 512) --1 
       OR (y_position >  0 AND y_position < 437 AND x_position > 512 AND x_position < 693) --2 
       OR (y_position > 281 AND y_position < 437 AND x_position > 0 and x_position < 512) --3 
       OR (y_position > 437 AND y_position < 537 AND x_position > 0 AND x_position < 206) --4 
       OR (y_position > 537 AND y_position < 1227 AND x_position > 0 AND x_position < 181) --5 
       OR (y_position > 537 AND y_position < 718 AND x_position > 181 AND x_position < 437) --6 
       OR (y_position > 768 AND y_position < 1227 AND x_position > 281 AND x_position < 718) --7 
       OR (y_position > 537 AND y_position < 768 AND x_position > 537 AND x_position < 693) --8 
       OR (y_position > 537 AND y_position < 718 AND x_position > 693 AND x_position < 793) --9 
       OR (y_position > 537 AND y_position < 768 AND x_position > 793 AND x_position < 975) --10 
       OR (y_position > 768 AND y_position < 1227 AND x_position > 793 AND x_position < 1027) --11 
       OR (y_position > 718 AND y_position < 768 AND x_position > 281 AND x_position < 437) --12 
       ) THEN 
        y_position <= y_position - 10; 
       ELSE 
        x_position <= x_position; 
        y_position <= y_position +5; 
      END IF; 
     END IF; 
    END IF; 
END PROCESS;