VHDL PS / 2接口

时间:2015-12-10 18:25:19

标签: interface keyboard vhdl

我正在使用VHDL和FPGA板,VGA接口和PS / 2键盘接口来创建迷宫并制作可以穿过迷宫的正方形。当我按下其中一个键(WASD)时,方块只移动一个位置,然后不再移动。每次按下其中一个键时我都需要它移动。这是我的代码:

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;

2 个答案:

答案 0 :(得分: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上升沿分配的任何触发器和寄存器。你也无法判断你是否击中了连续的空格键。没有打另一个识别器。

您的代码符合您对问题的描述,这是一项功能。

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