我最近用VHDL创建了一个乒乓球游戏,模拟效果很好,游戏表现也很好。游戏是1比1.每个玩家都有一个球拍,由led矩阵上下两个点亮的LED指示。
球被LED指示灯矩形末端滚动的点亮的LED指示,它们必须由两个按钮(每个玩家的左按钮和右按钮)显示的球拍打孔。
我使用配备50 Mhz时钟的cpld maxII。所以我把频率分开来控制LED的滚动。
在我与我的妹妹玩了很多游戏之后(她非常喜欢它:D),我决定让它变得更有趣。这个想法是在3,6,9,12,15推球之后改变滚动LED的频率。当计数器(名为cnt_win)低于3时,滚动速度很慢,频率正在增加,直到cnt_win达到15.当一个玩家失败时,计数器等于0 ......
我使用许多时钟来改变频率并使游戏更具吸引力,但由于错误而无法正常工作。错误(10822):pong_game.vhd(350)处的HDL错误:无法在此时钟边沿上为分配实现寄存器"。
library ieee;
use ieee.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity pong_game is
port(
d1 : in std_logic; -- right push button player 1
g1 : in std_logic; -- left push button player 1
d2 : in std_logic; -- " " player 2
g2 : in std_logic; -- " " player 2
clk_50Mhz : in std_logic;
clk_20hz : buffer std_logic :='0';
RST : in std_logic; -- reset button
leds : buffer std_logic_vector (30 downto 1);
led_barre_2 : buffer std_logic_vector (5 downto 1):="00011";
led_barre_1 : buffer std_logic_vector (5 downto 1):="00011"
);
end pong_game;
architecture pong_game_arch of pong_game is
constant position1 : std_logic_vector(5 downto 1) := "00011";
constant position2 : std_logic_vector(5 downto 1) := "00110";
constant position3 : std_logic_vector(5 downto 1) := "01100";
constant position4 : std_logic_vector(5 downto 1) := "11000";
type etat is (led1,led2,led3,led4,led5,led6_1,led7_1_g,led7_1_d,led8_1_g,led8_1_d,led9_1_g,led9_1_d,led10_1,led11_1,led12_1_g,led12_1_d,led13_1_g,led13_1_d,led14_1_g,led14_1_d,led15_1,
led16_1,led17_1_g,led17_1_d,led18_1_g,led18_1_d,led19_1_g,led19_1_d,led20_1,led21_1,led22_1_g,led22_1_d,led23_1_g,led23_1_d,led24_1_g,led24_1_d,led25_1,led26,led27,led28,led29,led30,
led6_2,led7_2_g,led7_2_d,led8_2_g,led8_2_d,led9_2_g,led9_2_d,led10_2,led11_2,led12_2_g,led12_2_d,led13_2_g,led13_2_d,led14_2_g,led14_2_d,led15_2,led16_2,led17_2_g,led17_2_d,led18_2_g,led18_2_d,led19_2_g,led19_2_d,
led20_2,led21_2,led22_2_g,led22_2_d,led23_2_g,led23_2_d,led24_2_g,led24_2_d,led25_2,
led6_init,
led7_init,
led8_init,
led9_init,
led10_init,
led11_init_1,
led11_init_2,
led12_init_1,
led12_init_2,
led13_init_1,
led13_init_2,
led14_init_1,
led14_init_2,
led15_init_1,
led15_init_2, -- Sequence led initiale
led16_init_1,
led16_init_2,
led17_init_1,
led17_init_2,
led18_init_1,
led18_init_2,
led19_init_1,
led19_init_2,
led20_init_1,
led20_init_2,
led21_init,
led22_init,
led23_init,
led24_init,
led25_init,
all_led_loose_on,
all_led_loose_off);
signal etat_present, etat_futur : etat :=led11_init_1; -- etat initial
signal cnt : integer range 11 to 20 :=11; -- Permet de choisir quelle led initial
signal cnt1 : integer range 3 downto 0 :=0; -- gère les positions de led_barre_1
signal cnt2 : integer range 3 downto 0 :=0; -- idem pour led_barre_2
--signal clk_20hz : std_logic :='0'; -- gère les boutons poussoirs gauche-droite
--------- gère les sequences de leds avec 4 signals d'horloge -----------
signal clk_0 : std_logic :='0'; -- niveau lent
signal clk_1 : std_logic :='0'; -- niveau normal
signal clk_2 : std_logic :='0'; -- niveau rapide
signal clk_3 : std_logic :='0'; -- niveau très rapide
signal cnt_clk_20 : std_logic_vector (22 downto 1):= (others=>'0');
signal cnt_clk_0 : std_logic_vector (25 downto 1):= (others=>'0');
signal cnt_clk_1 : std_logic_vector (24 downto 1):= (others=>'0');
signal cnt_clk_2 : std_logic_vector (24 downto 1):= (others=>'0');
signal cnt_clk_3 : std_logic_vector (24 downto 1):= (others=>'0');
--------------------------------------------------------------------------------
-------- choix binaire des fréquences de défilements --------------------------
constant lent : std_logic_vector (1 downto 0) :="00";
constant normal : std_logic_vector (1 downto 0) :="01";
constant rapide : std_logic_vector (1 downto 0) :="10";
constant rapide_v : std_logic_vector (1 downto 0) :="11";
signal choix : std_logic_vector (1 downto 0) :=lent;
signal cnt_win : integer range 15 downto 0 :=0;
begin
diviseur_clk : process(clk_50Mhz)
begin
if rising_edge(clk_50Mhz) then
if cnt_clk_0 < "1011111010111100001000000" then --25.000.000
cnt_clk_0 <= cnt_clk_0+'1';
else
clk_0<=not(clk_0);
cnt_clk_0<= (others => '0');
end if;
if cnt_clk_1 < "111001001110000111000000" then --15.000.000
cnt_clk_1<=cnt_clk_1+'1';
else
clk_1<=not(clk_1);
cnt_clk_1<= (others =>'0');
end if;
if cnt_clk_2 < "100110001001011010000000" then --10.000.000
cnt_clk_2<=cnt_clk_2+'1';
else
clk_2<=not(clk_2);
cnt_clk_2<= (others=>'0');
end if;
if cnt_clk_3 < "11100100111000011100000" then --7.500.000
cnt_clk_3 <= cnt_clk_3+'1';
else
clk_3<=not(clk_3);
cnt_clk_3<= (others=>'0');
end if;
if cnt_clk_20 < "1001100010010110100000" then --2.500.000
cnt_clk_20<=cnt_clk_20+'1';
else
clk_20hz<=not(clk_20hz);
cnt_clk_20<= (others =>'0');
end if;
end if;-- rising_edge
end process diviseur_clk ;
position_1 : process (clk_20hz,d1,g1)
begin
if rising_edge(clk_20hz) then
case cnt1 is
when 0=>
if d1='1' and g1='0' then
led_barre_1<="00110";
cnt1<=1;
end if;
when 1=>
if d1='1' and g1='0' then
led_barre_1<="01100";
cnt1<=2;
elsif d1='0' and g1='1' then
led_barre_1<="00011";
cnt1<=0;
end if;
when 2=>
if d1='1' and g1='0' then
led_barre_1<="11000";
cnt1<=3;
elsif d1='0' and g1='1' then
led_barre_1<="00110";
cnt1<=1;
end if;
when 3 =>
if d1='0' and g1='1' then
led_barre_1<="01100";
cnt1<=2;
end if;
when others =>
end case;
end if;
end process position_1;
position_2 : process (clk_20hz,d2,g2)
begin
if rising_edge(clk_20hz) then
case cnt2 is
when 0=>
if d2='1' and g2='0' then
led_barre_2<="00110";
cnt2<=1;
end if;
when 1=>
if d2='1' and g2='0' then
led_barre_2<="01100";
cnt2<=2;
elsif d2='0' and g2='1' then
led_barre_2<="00011";
cnt2<=0;
end if;
when 2=>
if d2='1' and g2='0' then
led_barre_2<="11000";
cnt2<=3;
elsif d2='0' and g2='1' then
led_barre_2<="00110";
cnt2<=1;
end if;
when 3 =>
if d2='0' and g2='1' then
led_barre_2<="01100";
cnt2<=2;
end if;
when others =>
end case;
end if;
end process position_2;
--end architecture pong_game_arch;
--architecture led_matrix of pong_game is
compteur : process(clk_50Mhz)
begin
if rising_edge(clk_50Mhz) then
if cnt < 20 then
cnt<= cnt+1;
else
cnt<=11;
end if;
end if;
end process compteur ;
initialisation : process(RST,clk_0,clk_1,clk_2,clk_3)
begin
if RST='1' then
case cnt is
when 11 => etat_present <= led11_init_1;
when 12 => etat_present <= led12_init_1;
when 13 => etat_present <= led13_init_1;
when 14 => etat_present <= led14_init_1;
when 15 => etat_present <= led15_init_1;
when 16 => etat_present <= led16_init_2;
when 17 => etat_present <= led17_init_2;
when 18 => etat_present <= led18_init_2;
when 19 => etat_present <= led19_init_2;
when 20 => etat_present <= led20_init_2;
end case ;
else
case choix is
when lent => -- choice of the
-- frequency (the error
-- occurs here )
if rising_edge(clk_0) then
etat_present <= etat_futur;
end if;
when normal =>
if rising_edge(clk_1) then
etat_present <= etat_futur;
end if;
when rapide =>
if rising_edge(clk_2) then
etat_present <= etat_futur;
end if;
when rapide_v =>
if rising_edge(clk_3) then
etat_present <= etat_futur;
end if;
end case ;
end if;
end process initialisation ;
sequence_led : process(etat_present,led_barre_1,led_barre_2)
begin
case etat_present is
-- sequence initiale
when led6_init =>
etat_futur <= led1;
when led7_init =>
etat_futur <= led2;
when led8_init =>
etat_futur <= led3;
when led9_init =>
etat_futur <= led4;
when led10_init =>
etat_futur <= led5;
when led11_init_2 =>
etat_futur <= led6_init;
when led12_init_2 =>
etat_futur <= led7_init;
when led13_init_2 =>
etat_futur <= led8_init;
when led14_init_2 =>
etat_futur <= led9_init;
when led15_init_2 =>
etat_futur <= led10_init;
when led16_init_2 =>
etat_futur <= led11_init_2;
when led17_init_2 =>
etat_futur <= led12_init_2;
when led18_init_2 =>
etat_futur <= led13_init_2;
when led19_init_2 =>
etat_futur <= led14_init_2;
when led20_init_2 =>
etat_futur <= led15_init_2;
when led11_init_1 =>
etat_futur <= led16_init_1;
when led12_init_1 =>
etat_futur <= led17_init_1;
when led13_init_1 =>
etat_futur <= led18_init_1;
when led14_init_1 =>
etat_futur <= led19_init_1;
when led15_init_1 =>
etat_futur <= led20_init_1;
when led16_init_1 =>
etat_futur <= led21_init;
when led17_init_1 =>
etat_futur <= led22_init;
when led18_init_1 =>
etat_futur <= led23_init;
when led19_init_1 =>
etat_futur <= led24_init;
when led20_init_1 =>
etat_futur <= led25_init;
when led21_init =>
etat_futur <= led26;
when led22_init =>
etat_futur <= led27;
when led23_init =>
etat_futur <= led28;
when led24_init =>
etat_futur <= led29;
when led25_init =>
etat_futur <= led30;
-- fin sequence initiale
when led1 =>
if led_barre_1 = position1 then
etat_futur <= led7_1_d;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
else
etat_futur <= all_led_loose_on;
cnt_win <= 0;
end if;
when led2 =>
if led_barre_1 = position1 then
etat_futur <= led8_1_d;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
elsif led_barre_1 = position2 then
etat_futur <= led6_1;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
else
etat_futur <= all_led_loose_on;
cnt_win <= 0;
end if;
when led3 =>
if led_barre_1 = position2 then
etat_futur <= led9_1_d;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
elsif led_barre_1 = position3 then
etat_futur <= led7_1_g;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
else
etat_futur <= all_led_loose_on;
cnt_win <= 0;
end if;
when led4 =>
if led_barre_1 = position3 then
etat_futur <= led10_1;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
elsif led_barre_1 = position4 then
etat_futur <= led8_1_g;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
else
etat_futur <= all_led_loose_on;
cnt_win <= 0;
end if;
when led5=>
if led_barre_1 = position4 then
etat_futur <= led9_1_g;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
else
etat_futur<= all_led_loose_on;
cnt_win <= 0;
end if;
when led6_1=>
etat_futur <= led12_1_d;
when led6_2=>
etat_futur <= led2;
when led7_1_g =>
etat_futur <= led11_1;
when led7_1_d=>
etat_futur <= led13_1_d;
when led7_2_g =>
etat_futur <= led1;
when led7_2_d =>
etat_futur <= led3;
when led8_1_g =>
etat_futur <= led12_1_g;
when led8_1_d =>
etat_futur <= led14_1_d;
when led8_2_g =>
etat_futur <= led2;
when led8_2_d =>
etat_futur <= led4;
when led9_1_g =>
etat_futur <= led13_1_g;
when led9_1_d =>
etat_futur <= led15_1;
when led9_2_g =>
etat_futur <= led3;
when led9_2_d =>
etat_futur <= led5;
when led10_1 =>
etat_futur <= led14_1_g;
when led10_2 =>
etat_futur <= led4;
when led11_1 =>
etat_futur <= led17_1_d;
when led11_2 =>
etat_futur <= led7_2_d;
when led12_1_g =>
etat_futur <= led16_1;
when led12_1_d =>
etat_futur <= led18_1_d;
when led12_2_g =>
etat_futur <= led6_2;
when led12_2_d =>
etat_futur <= led8_2_d;
when led13_1_g =>
etat_futur <= led17_1_g;
when led13_1_d =>
etat_futur <= led19_1_d;
when led13_2_g =>
etat_futur <= led7_2_g;
when led13_2_d =>
etat_futur <= led9_2_d;
when led14_1_g =>
etat_futur <= led18_1_g;
when led14_1_d =>
etat_futur <= led20_1;
when led14_2_g =>
etat_futur <= led8_2_g;
when led14_2_d =>
etat_futur <= led10_2;
when led15_1 =>
etat_futur <= led19_1_g;
when led15_2 =>
etat_futur <= led9_2_g;
when led16_1 =>
etat_futur <= led22_1_d;
when led16_2 =>
etat_futur <= led12_2_d;
when led17_1_g =>
etat_futur <= led21_1;
when led17_1_d =>
etat_futur <= led23_1_d;
when led17_2_g =>
etat_futur <= led11_2;
when led17_2_d =>
etat_futur <= led13_2_d;
when led18_1_g =>
etat_futur <= led22_1_g;
when led18_1_d =>
etat_futur <= led24_1_d;
when led18_2_g =>
etat_futur <= led12_2_g;
when led18_2_d=>
etat_futur <= led14_2_d;
when led19_1_g =>
etat_futur <= led23_1_g;
when led19_1_d =>
etat_futur <= led25_1;
when led19_2_g =>
etat_futur <= led13_2_g;
when led19_2_d =>
etat_futur <= led15_2;
when led20_1 =>
etat_futur <= led24_1_g;
when led20_2 =>
etat_futur <= led14_2_g;
when led21_1 =>
etat_futur <= led27;
when led21_2 =>
etat_futur <= led17_2_d;
when led22_1_g =>
etat_futur <= led26;
when led22_1_d=>
etat_futur <= led28;
when led22_2_g =>
etat_futur <= led16_2;
when led22_2_d=>
etat_futur <= led18_2_d;
when led23_1_g =>
etat_futur <= led27;
when led23_1_d =>
etat_futur <= led29;
when led23_2_g =>
etat_futur <= led17_2_g;
when led23_2_d =>
etat_futur <= led19_2_d;
when led24_1_g =>
etat_futur <= led28;
when led24_1_d =>
etat_futur <= led30;
when led24_2_g =>
etat_futur <= led18_2_g;
when led24_2_d =>
etat_futur <= led20_2;
when led25_1 =>
etat_futur <= led29;
when led25_2 =>
etat_futur <= led19_2_g;
when led26 =>
if led_barre_2=position1 then
etat_futur<=led22_2_d;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
else --loose
etat_futur <= all_led_loose_on;
cnt_win <= 0;
end if;
when led27 =>
if led_barre_2=position1 then
etat_futur<=led23_2_d;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
elsif led_barre_2=position2 then
etat_futur<=led21_2;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
else --loose
etat_futur <= all_led_loose_on;
cnt_win <= 0;
end if;
when led28 =>
if led_barre_2=position2 then
etat_futur <= led24_2_d;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
elsif led_barre_2=position3 then
etat_futur <= led22_2_g;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
else
etat_futur <= all_led_loose_on;
cnt_win <= 0;
end if;
when led29 =>
if led_barre_2 = position4 then
etat_futur <= led23_2_g;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
elsif led_barre_2 = position3 then
etat_futur <= led25_2;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
else
etat_futur <= all_led_loose_on;
cnt_win <= 0;
end if;
when led30 =>
if led_barre_2 = position4 then
etat_futur <= led24_2_g;
if cnt_win < 15 then
cnt_win <= cnt_win + 1;
end if;
else
etat_futur <= all_led_loose_on;
cnt_win <= 0;
end if;
when all_led_loose_on => -- cycle entre ces deux états
etat_futur <= all_led_loose_off; -- jusqu'à ce que RST = '1'
when all_led_loose_off =>
etat_futur <= all_led_loose_on;
end case ;
end process sequence_led ;
affichage_sequence : process(etat_present)
begin
case etat_present is
when led1 =>
leds <= ( 1 => '1', others => '0');
when led2 =>
leds <= ( 2 => '1', others => '0');
when led3 =>
leds <= ( 3 => '1', others => '0');
when led4 =>
leds <= ( 4 => '1', others => '0');
when led5=>
leds <= ( 5 => '1', others => '0');
when led6_1|led6_2|led6_init=>
leds <= ( 6 => '1', others => '0');
when led7_1_d|led7_1_g|led7_2_d|led7_2_g|led7_init =>
leds <= ( 7 => '1', others => '0');
when led8_1_d|led8_1_g|led8_2_d|led8_2_g|led8_init =>
leds <= ( 8 => '1', others => '0');
when led9_1_d|led9_1_g|led9_2_d|led9_2_g|led9_init =>
leds <= ( 9 => '1', others => '0');
when led10_1|led10_2|led10_init =>
leds <= ( 10 => '1', others => '0');
when led11_1|led11_2|led11_init_1|led11_init_2 =>
leds <= ( 11 => '1', others => '0');
when led12_1_g|led12_1_d|led12_2_g|led12_2_d|led12_init_1|led12_init_2 =>
leds <= ( 12 => '1', others => '0');
when led13_1_g|led13_1_d|led13_2_g|led13_2_d|led13_init_1|led13_init_2 =>
leds <= ( 13 => '1', others => '0');
when led14_1_d|led14_1_g|led14_2_g|led14_2_d|led14_init_1|led14_init_2 =>
leds <= ( 14 => '1', others => '0');
when led15_1|led15_2|led15_init_1|led15_init_2 =>
leds <= ( 15 => '1', others => '0');
when led16_1|led16_2|led16_init_1|led16_init_2 =>
leds <= ( 16 => '1', others => '0');
when led17_1_g|led17_1_d|led17_2_g|led17_2_d|led17_init_1|led17_init_2 =>
leds <= ( 17 => '1', others => '0');
when led18_1_g|led18_1_d|led18_2_g|led18_2_d|led18_init_1|led18_init_2 =>
leds <= ( 18 => '1', others => '0');
when led19_1_g|led19_1_d|led19_2_g|led19_2_d|led19_init_1|led19_init_2 =>
leds <= ( 19 => '1', others => '0');
when led20_1|led20_2|led20_init_1|led20_init_2 =>
leds <= ( 20 => '1', others => '0');
when led21_1|led21_2|led21_init =>
leds <= ( 21 => '1', others => '0');
when led22_1_g|led22_1_d|led22_2_g|led22_2_d|led22_init =>
leds <= ( 22 => '1', others => '0');
when led23_1_g|led23_1_d|led23_2_g|led23_2_d|led23_init =>
leds <= ( 23 => '1', others => '0');
when led24_1_g|led24_1_d|led24_2_g|led24_2_d|led24_init =>
leds <= ( 24 => '1', others => '0');
when led25_1|led25_2|led25_init =>
leds <= ( 25 => '1', others => '0');
when led26 =>
leds <= ( 26 => '1', others => '0');
when led27 =>
leds <= ( 27 => '1', others => '0');
when led28 =>
leds <= ( 28 => '1', others => '0');
when led29 =>
leds <= ( 29 => '1', others => '0');
when led30 =>
leds <= ( 30 => '1', others => '0');
when all_led_loose_on =>
leds <= (others =>'1');
when all_led_loose_off =>
leds <= (others =>'0');
end case ;
end process affichage_sequence ;
variation_frequence : process (cnt_win)
begin
case cnt_win is
when 0|1|2|3 => choix <= lent ;
when 4|5|6 => choix <= normal ;
when 7|8|9 => choix <= rapide ;
when 10|11|12 => choix <= normal ;
when 13|14|15 => choix <= rapide_v;
end case;
end process variation_frequence ;
end architecture pong_game_arch;
错误发生在流程&#34;初始化&#34;。
答案 0 :(得分:-1)
除了用户1155120在评论中所说的内容之外,你还做了一件非常糟糕的事情(除非你正在做ASIC)这是时钟门控。您不应该从组合逻辑中获取时钟。仅限时钟源,如时钟引脚和PLL。在我看来,更改代码的最佳方法是对信号进行上升沿检测(不要将它们称为时钟)clk_0,clk_1,clk_2和clk_3。使用这些&#34;上升边缘&#34;在你的if语句中(第351,359,367和375行)。这种方法的主要问题是您要为流添加至少一个延迟周期,这可能会影响您的最终输出,也可能不会影响您的最终输出。你必须以某种方式调整它。