赞
踩
本实验的解决关键在于能否正确填写下发的实验表格。如果能理解表格中填写的各位置函数关系并在代码相应位置对应更改,就可以轻松完成所有实验内容。
上图为下发的实验表格,经观察可知:示例的I型模块旋转过程分为四个form,每旋转90°为一个form,依次对应“00”“01”“10”“11”状态。旋转前组成I型模块的四个点阵由数字1-4表示,旋转后的I型模块位置用〇表示,旋转过程中的阻挡位置用×表示。旋转中心用带圈的数字③表示。每个点阵由两个坐标函数pnx, pny表示。坐标原点位于点阵屏的左上角,即从左往右,八列点阵的坐标分别为000, 001, 010, 011, 100, 101, 110, 111,从上往下,八行点阵的坐标分别为000, 001, 010, 011, 100, 101, 110, 111(注意是从0开始,0代表第一行,这里非常重要!!!)。同时,表中还给出了旋转中心的坐标限制"000"<p3y<"110",即点阵3需要保证位于第二行至第六行。
旋转过程中,测试空位和测试阻挡的坐标均由原始点阵坐标导出。以forms="00"点“4”上方的阻挡为例(下图标红×),其坐标可由点“4”写出,由于其与“4”位于同一列,故横坐标相同,其位于“4”上方一个单位,故纵坐标为p4y-1。因此此阻挡的坐标可表示为p4x, p4y-1。
旋转后的坐标由对应的点坐标导出。以forms="00"点“1”为例,其逆时针旋转90°后位置见下图标红〇。与原坐标相比,向右移动两个单位,向下移动两个单位。故其旋转后坐标可表示为p1x+2, p1y+2。
综上,我们可以补全表1,得到以下完整表格。
本实验的主要控制过程代码在模块ctrl_Irotate.vhd中给出,故我们可以研究此模块代码,来分析如何实现模块的旋转功能。通过观察给出的代码,我们可以发现影响模块旋转功能的代码主要有以下几个部分组成:
- when test_n=>
- case next_n is--共4种测试项
- when"00"=>--测试旋转
- forms<="00";--I型模块,p1 p2 p3 p4
- --
- --
- --p1 p2 p3 p4,左上,第三行
- p1x<="000";p2x<="001";p3x<="010";p4x<="011";
- p1y<="010";p2y<="010";p3y<="010";p4y<="010";
- p5x<="111";p5y<="010";
-
- when"01"=>--测试边界
- forms<="00";
- --
- --p1 p2 p3 p4,左上角,第2行
- p1x<="000";p2x<="001";p3x<="010";p4x<="011";
- p1y<="001";p2y<="001";p3y<="001";p4y<="001";
- p5x<="110";p5y<="111";
-
- when"10"=>--测试位置被占
- forms<="00";
- --p1 p2 p3 p4,居中
- -- p5
- p1x<="010";p2x<="011";p3x<="100";p4x<="101";
- p1y<="100";p2y<="100";p3y<="100";p4y<="100";
- p5x<="100";p5y<="101";
-
- when"11"=>--测试旋转路径有阻挡
- forms<="00";
- --p1 p2 p3 p4,居中
- -- p5
- p1x<="010";p2x<="011";p3x<="100";p4x<="101";
- p1y<="100";p2y<="100";p3y<="100";p4y<="100";
- p5x<="101";p5y<="101";
-
- when others=>null;
- end case;
- make<=X"1"; state<=display;
这里给出的是四种测试项,对应实验设计任务上的正常旋转、靠近点阵四周、位置被占、旋转路径有阻挡。由第一节已知各点坐标的表示方法,即可表示出四种情况的对应坐标。其中p5表示一种可能的阻挡,在前两种情况中无需考虑,将p5设置为任意远离模块的坐标即可。在第三种情况中,需要考虑测试位置被占的情况,因此可以将p5置于p3下方,模拟旋转目标点阵位置被占的情况。同理,在第四种情况中,将p5置于p4下方。
- --测试I型模块能否以p3为轴心逆时针旋转--
- --测试边界、空位与阻挡--
- when test_Lp3=>
- case test is
- --测试边界与空位1--
- when X"1"=>--test
- if(forms="00")then
- if(p3y>"000" and p3y<"110")then--边界条件
- cx<=p3x; cy<=p3y-1; test<=X"2";--测试空位1
- else
- state<=wait_btn;--不能旋转,等待操作键
- end if;
- elsif(forms="01")then
- if(p3x>"000" and p3x<"110")then
- cx<=p3x-1; cy<=p3y; test<=X"2";
- else
- state<=wait_btn;
- end if;
- elsif(forms="10")then
- if(p3y>"001" and p3y<"111")then
- cx<=p3x; cy<=p3y-2; test<=X"2";
- else
- state<=wait_btn;
- end if;
- elsif(forms="11")then
- if(p3x>"001" and p3x<"111")then
- cx<=p3x-2; cy<=p3y; test<=X"2";
- else
- state<=wait_btn;
- end if;
- end if;
- when X"2"=>
- if(dotin="1")then--高电平点亮,位置已被占
- state<=wait_btn;--不能旋转,等待操作键
- else
- test<=X"3";--有空位,测试下一个位置
- end if;
-
- --测试空位2--
- when X"3"=>--test
- if(forms="00")then
- cx<=p3x; cy<=p3y+1; test<=X"4";
- elsif(forms="01")then
- cx<=p3x+1; cy<=p3y; test<=X"4";
- elsif(forms="10")then
- cx<=p3x; cy<=p3y-1; test<=X"4";
- elsif(forms="11")then
- cx<=p3x-1; cy<=p3y; test<=X"4";
- end if;
- when X"4"=>
- if(dotin="1")then state<=wait_btn;
- else
- test<=X"5";
- end if;
-
- --测试空位3--
- when X"5"=>--test
- if(forms="00")then
- cx<=p3x; cy<=p3y+2; test<=X"6";
- elsif(forms="01")then
- cx<=p3x+2; cy<=p3y; test<=X"6";
- elsif(forms="10")then
- cx<=p3x; cy<=p3y+1; test<=X"6";
- elsif(forms="11")then
- cx<=p3x+1; cy<=p3y; test<=X"6";
- end if;
- when X"6"=>
- if(dotin="1")then state<=wait_btn;
- else
- test<=X"7";
- end if;
-
- --测试阻挡1--
- when X"7"=>--test
- if(forms="00")then
- cx<=p1x; cy<=p1y+1; test<=X"8";
- elsif(forms="01")then
- cx<=p1x+1; cy<=p1y; test<=X"8";
- elsif(forms="10")then
- cx<=p1x; cy<=p1y-1; test<=X"8";
- elsif(forms="11")then
- cx<=p1x-1; cy<=p1y; test<=X"8";
- end if;
- when X"8"=>
- if(dotin="1")then --高电平点亮,有阻挡
- state<=wait_btn;--不能旋转,等待操作键
- else
- test<=X"9";--无阻挡,测试下一个位置
- end if;
-
- --测试阻挡2--
- when X"9"=>--test
- if(forms="00")then
- cx<=p2x; cy<=p2y+1; test<=X"A";
- elsif(forms="01")then
- cx<=p2x+1; cy<=p2y; test<=X"A";
- elsif(forms="10")then
- cx<=p2x; cy<=p2y-1; test<=X"A";
- elsif(forms="11")then
- cx<=p2x-1; cy<=p2y; test<=X"A";
- end if;
- when X"A"=>
- if(dotin="1")then
- state<=wait_btn;
- else
- test<=X"B";
- end if;
-
- --测试阻挡3--
- when X"B"=>--test
- if(forms="00")then
- cx<=p2x; cy<=p2y+2; test<=X"C";
- elsif(forms="01")then
- cx<=p2x+2; cy<=p2y; test<=X"C";
- elsif(forms="10")then
- cx<=p2x; cy<=p2y-2; test<=X"C";
- elsif(forms="11")then
- cx<=p2x-2; cy<=p2y; test<=X"C";
- end if;
- when X"C"=>
- if(dotin="1")then
- state<=wait_btn;
- else
- test<=X"D";
- end if;
-
- --测试阻挡4--
- when X"D"=>--test
- if(forms="00")then
- cx<=p4x; cy<=p4y-1; test<=X"E";
- elsif(forms="01")then
- cx<=p4x-1; cy<=p4y; test<=X"E";
- elsif(forms="10")then
- cx<=p4x; cy<=p4y+1; test<=X"E";
- elsif(forms="11")then
- cx<=p4x+1; cy<=p4y; test<=X"E";
- end if;
- when X"E"=>
- if(dotin="1")then
- state<=wait_btn;
- else
- make<=X"8"; state<=rotate_Lp3;
- end if;
-
- when others=>null;
-
- end case;
在以上函数中,依次判断表中填写的边界条件、空位和阻挡。首先判断旋转中心p3位置是否在边界之内,否则无法旋转,跳出。在满足边界条件的情况下,依次判断空位1、空位2、空位3、阻挡1、阻挡2、阻挡3、阻挡4的点是否亮起(高电平),如果亮起则表示该位置无法旋转,跳出。注意这里的空位和阻挡要按顺序写,即空位1为表中每种状态下填写的第一个空位点(下图用黄色标出),以此类推。空位和阻挡的个数可视具体问题增删,在后续实验任务中会解释。
- --I型模块以p3为轴心逆时针旋转--
- when rotate_Lp3=>
- case make is --make:8~F
- --清空原片--
- when X"8"=>
- wen_tmp<="1";--开写使能
- dotout_tmp<="0";--低电平,熄灭led灯
- cx<=p1x; cy<=p1y; make<=X"9";
- when X"9"=>
- cx<=p2x; cy<=p2y; make<=X"A";
- when X"A"=>
- cx<=p4x; cy<=p4y; make<=X"B";
-
- --更新p1,p2,p4新片位置--
- when X"B"=>--make
- if(forms="00")then
- p1x<=p1x+2; p1y<=p1y+2;
- p2x<=p2x+1; p2y<=p2y+1;
- p4x<=p4x-1; p4y<=p4y-1;
- elsif(forms="01")then
- p1x<=p1x+2; p1y<=p1y-2;
- p2x<=p2x+1; p2y<=p2y-1;
- p4x<=p4x-1; p4y<=p4y+1;
- elsif(forms="10")then
- p1x<=p1x-2; p1y<=p1y-2;
- p2x<=p2x-1; p2y<=p2y-1;
- p4x<=p4x+1; p4y<=p4y+1;
- elsif(forms="11")then
- p1x<=p1x-2; p1y<=p1y+2;
- p2x<=p2x-1; p2y<=p2y+1;
- p4x<=p4x+1; p4y<=p4y-1;
- end if;
- make<=X"C";
-
- --显示新片--
- when X"C"=>--make
- dotout_tmp<="1";--高电平,点亮led灯
- cx<=p1x; cy<=p1y; make<=X"D";
- when X"D"=>
- cx<=p2x; cy<=p2y; make<=X"E";
- when X"E"=>
- cx<=p4x; cy<=p4y; make<=X"F";
-
- when X"F"=>--make
- wen_tmp<="0";--关写使能
此函数内需要我们填写旋转后的各点坐标,与表中最后一列内容对应。注意最后“显示新片”位置需要考虑旋转轴,示例的旋转轴为p3,因此p3位置始终不更新,只需要更新p1, p2, p4的位置。
至此,I型模块的逆时针旋转测试与动作实验所有内容全部实现,相信你也掌握了旋转控制代码的原理。接下来将更新任务2:I型模块的顺时针旋转测试与动作。敬请期待。
- --库
- library ieee;
- use ieee.std_logic_1164.all;
- use ieee.std_logic_arith.all;
- use ieee.std_logic_unsigned.all;
-
- --实体
- entity Irotate_top is
- port (clk_50M : in std_logic; --50MHz
- rst : in std_logic;
- btn_in : in std_logic_vector(2 downto 0);
-
- DIN: out std_logic;
- CS: out std_logic;
- CLK_MAX7219 : out std_logic);
- end;
-
- --结构体
- architecture behavioral of Irotate_top is
- component clkdiv_50M
- port (clk_50M : in std_logic; --50MHz
- rst : in std_logic;
- clk_btn: out std_logic;
- clk_game:out std_logic;
- clk_rama : out std_logic);
- end component;
-
- component btn_detect
- port (clk_btn : in std_logic;
- rst : in std_logic;
- btn_in : in std_logic_vector(2 downto 0);
- btn_en : out std_logic;
- btn_nlr : out std_logic_vector(2 downto 0));
- end component;
-
- component ctrl_Irotate
- port (clk_game : in std_logic;
- rst : in std_logic;
- btn_en : in std_logic;
- dotin : in std_logic_vector(0 downto 0);
- btn_nlr : in std_logic_vector(2 downto 0);
- addrb : out std_logic_vector(8 downto 0);
- web : out std_logic_vector(0 downto 0);
- dotout : out std_logic_vector(0 downto 0));
- end component;
-
- component ctrl_dotcasebitT
- port (clk_rama : in std_logic;
- rst : in std_logic;
- dataa : in std_logic_vector(0 downto 0);
- btn_en:in std_logic;
- dispgame:in std_logic;
- din : out std_logic;
- load_cs : out std_logic;
- clk_max7219 : out std_logic;
- addra : out std_logic_vector(8 downto 0));
- end component;
-
- component ram2ip
- port (clka : in std_logic;
- addra : in std_logic_vector(8 downto 0);
- wea : in std_logic_vector(0 downto 0):="0";
- dina : in std_logic_vector(0 downto 0):="0";
- clkb : in std_logic;
- addrb : in std_logic_vector(8 downto 0);
- web : in std_logic_vector(0 downto 0);
- dinb : in std_logic_vector(0 downto 0);
- douta : out std_logic_vector(0 downto 0);
- doutb : out std_logic_vector(0 downto 0));
- end component;
-
- signal clk_rama1:std_logic;
- signal clk_game: std_logic;
- signal clk_btn:std_logic;
- signal btn_en1:std_logic;
- signal btn_nlr: std_logic_vector(2 downto 0);
- signal dotin1:std_logic_vector(0 downto 0);
- signal addrb:std_logic_vector(8 downto 0);
- signal web:std_logic_vector(0 downto 0);
- signal dotout1:std_logic_vector(0 downto 0);
- signal dataa1:std_logic_vector(0 downto 0);
- signal addra:std_logic_vector(8 downto 0);
-
- begin
- --元件例化语句
- u1:clkdiv_50M port map(
- clk_50M => clk_50M,
- rst => rst,
- clk_rama => clk_rama1,
- clk_game => clk_game,
- clk_btn => clk_btn);
-
- u2:btn_detect port map(
- clk_btn => clk_btn,
- rst => rst,
- btn_in => btn_in,
- btn_en => btn_en1,
- btn_nlr => btn_nlr);
-
- u3:ctrl_Irotate port map(
- rst => rst,
- clk_game => clk_game,
- btn_en => btn_en1,
- btn_nlr => btn_nlr,
- dotin => dotin1,
- addrb => addrb,
- web => web,
- dotout => dotout1);
-
- u4:ctrl_dotcasebitT port map(
- clk_rama => clk_rama1,
- rst => rst,
- btn_en => btn_en1,
- dataa => dataa1,
- dispgame => btn_nlr(2),
- addra => addra,
- din => DIN,
- load_cs => CS,
- clk_max7219 => CLK_MAX7219);
-
- u5:ram2ip port map(
- clka => clk_rama1,
- addra => addra,
- clkb => clk_50M,
- addrb => addrb,
- web => web,
- dinb => dotout1,
- douta => dataa1,
- doutb => dotin1);
-
- end behavioral;
- --库
- library ieee;
- use ieee.std_logic_1164.all;
- use ieee.std_logic_arith.all;
- use ieee.std_logic_unsigned.all;
-
- --实体
- entity clkdiv_50M is
- port (clk_50M : in std_logic; --50MHz
- rst : in std_logic;
- clk_btn: out std_logic;
- clk_game:out std_logic;
- clk_rama : out std_logic);
- end;
-
- --结构体
- architecture behavioral of clkdiv_50M is
- signal cnt:std_logic_vector(25 downto 0);
- begin
- process(rst,clk_50M)
- begin
- if(rst='1')then
- cnt<=(others=>'0');
- elsif rising_edge(clk_50M)then
- cnt<=cnt+1;
- end if;
- end process;
-
- clk_btn<=cnt(7);
- clk_game<=cnt(2);
- clk_rama<=cnt(8);
-
- end behavioral;
- --库
- library ieee;
- use ieee.std_logic_1164.all;
- use ieee.std_logic_arith.all;
- use ieee.std_logic_unsigned.all;
-
- --实体
- entity btn_detect is
- port (clk_btn : in std_logic;
- rst : in std_logic;
- btn_in : in std_logic_vector(2 downto 0);
- btn_en : out std_logic;
- btn_nlr : out std_logic_vector(2 downto 0));
- end;
- --结构体
- architecture behavioral of btn_detect is
- component debounce is
- port(clk:in std_logic;
- rst:in std_logic;
- start:in std_logic;
- done:out std_logic);
- end component;
-
- signal start,done:std_logic:='0';
- signal btn_down,en_tmp:std_logic:='0';
-
- begin
- process(rst,clk_btn,btn_in)
- begin
- if(rst='1')then
- btn_down<='0';
- elsif rising_edge(clk_btn)then
- if(btn_in/="000")then --有键按下
- if(done='0')then
- start<='1';
- else
- start<='0';
- end if;
- if(start&done="11")then
- btn_nlr<=btn_in;
- btn_down<='1'; --确实有键按下
- end if;
- else
- btn_down<='0';
- start<='0';
- end if;
- end if;
- end process;
-
- --检测到有键按下,则btn_en翻转,控制ctrl_Irotate
- process(btn_down)
- begin
- if rising_edge(btn_down)then
- en_tmp<=not en_tmp;
- end if;
- end process;
- btn_en<=en_tmp;
-
- u2i:debounce port map(
- clk=>clk_btn,
- rst=>rst,
- start=>start,
- done=>done);
-
- end behavioral;
- --库
- library ieee;
- use ieee.std_logic_1164.all;
- use ieee.std_logic_arith.all;
- use ieee.std_logic_unsigned.all;
-
- --实体
- entity debounce is
- port (clk: in std_logic;
- rst: in std_logic;
- start: in std_logic;
- done: out std_logic);
- end;
-
- --结构体
- architecture behavioral of debounce is
- signal cnt_delay:std_logic_vector(13 downto 0);--延时计数
- signal done_tmp:std_logic:='0';
-
- begin
- process(rst,clk,start)
- begin
- if(rst='1')then
- done_tmp<='0';
- cnt_delay<=(others=>'0');
- elsif rising_edge(clk)then
- if(start='1')then --有键按下
- if(cnt_delay>X"300")then
- done_tmp<='1'; --确实有键按下
- else
- cnt_delay<=cnt_delay+1;
- end if;
- else --无键按下
- done_tmp<='0';
- cnt_delay<=(others=>'0');
- end if;
- end if;
- done<=done_tmp;
- end process;
-
- end behavioral;
- --库
- library ieee;
- use ieee.std_logic_1164.all;
- use ieee.std_logic_arith.all;
- use ieee.std_logic_unsigned.all;
-
- --实体
- entity ctrl_Irotate is
- port (clk_game: in std_logic;
- rst: in std_logic;
- btn_en: in std_logic;
- dotin: in std_logic_vector(0 downto 0);
- btn_nlr: in std_logic_vector(2 downto 0);
- addrb: out std_logic_vector(8 downto 0);
- web: out std_logic_vector(0 downto 0);
- dotout: out std_logic_vector(0 downto 0));
- end;
-
-
- --结构体
- architecture behavioral of ctrl_Irotate is
- type state_group is(wait_btn,clr_screen,test_n,display,test_Lp3,rotate_Lp3);
- signal state:state_group:=wait_btn;
-
- signal test:std_logic_vector(3 downto 0):=X"0";--测试
- signal make:std_logic_vector(3 downto 0):=X"0";--动作
- signal makex,makey:std_logic_vector(3 downto 0):=X"0";--清屏
-
- signal next_n:std_logic_vector(1 downto 0):="00";--切换测试项
- signal rst_en,btnen_tmp:std_logic:='0';
- signal wen_tmp:std_logic_vector(0 downto 0):="0";
- signal dotout_tmp:std_logic_vector(0 downto 0);
-
- signal cy:std_logic_vector(2 downto 0):="000";--8行
- signal cx:std_logic_vector(2 downto 0):="000";--8列
-
- signal p1x,p2x,p3x,p4x,p5x:std_logic_vector(2 downto 0):="000";
- signal p1y,p2y,p3y,p4y,p5y:std_logic_vector(2 downto 0):="000";
-
- signal forms:std_logic_vector(1 downto 0):="00";--I型模块的形状
- begin
- web<=wen_tmp;
- addrb<="01"&cy&"1"&cx;--俄罗斯方块旋转测试界面的地址
- dotout<=dotout_tmp;
-
- process(rst,clk_game,btn_en,dotin,state,make,test)
- begin
- if(rst='1')then
- rst_en <= '1';
- btnen_tmp <= btn_en;
- makey <= X"0";
- makex <= X"0";
- state <= clr_screen;
- elsif rising_edge(clk_game)then
- --识别操作键
- if(btnen_tmp/=btn_en)then
- btnen_tmp<=not btnen_tmp;
- --BTN3:切换测试项
- if(btn_nlr="100" and state=wait_btn)then
- next_n<=next_n+1;
- makey<=X"0"; makex<=X"0"; state<=clr_screen;
- --BTN2:逆时针旋转(向左转)
- elsif(btn_nlr="010"and state=wait_btn)then
- test<=X"1"; state<=test_Lp3;
- --BTN1:顺时针旋转(向右转),此功能待开发(实验任务)
- elsif(btn_nlr="001"and state=wait_btn)then
- test<=X"1";state<=test_Rp3;
- end if;
- else
- case state is
- --等待按键操作--
- when wait_btn=>null;
-
-
- --清屏--
- when clr_screen=>
- if(makex<X"8")then
- wen_tmp<="1";--开写使能
- dotout_tmp<="0";--清空点阵显示,低电平不亮
- cx<=makex(2 downto 0); makex<=makex+1;
- cy<=makey(2 downto 0);
- else
- if(makey<X"8")then
- makey<=makey+1; makex<=X"0";
- else
- wen_tmp<="0";--关写使能
- if(rst_en='1')then
- rst_en<='0'; state<=wait_btn;
- else state<=test_n;
- end if;
- end if;
- end if;
-
-
- --选择新的测试项--
- when test_n=>
- case next_n is--共4种测试项
- when"00"=>--测试旋转
- forms<="00";--I型模块,p1 p2 p3 p4
- --
- --
- --p1 p2 p3 p4,左上,第三行
- p1x<="000";p2x<="001";p3x<="010";p4x<="011";
- p1y<="010";p2y<="010";p3y<="010";p4y<="010";
- p5x<="111";p5y<="010";
-
- when"01"=>--测试边界
- forms<="00";
- --
- --p1 p2 p3 p4,左上角,第2行
- p1x<="000";p2x<="001";p3x<="010";p4x<="011";
- p1y<="001";p2y<="001";p3y<="001";p4y<="001";
- p5x<="110";p5y<="111";
-
- when"10"=>--测试位置被占
- forms<="00";
- --p1 p2 p3 p4,居中
- -- p5
- p1x<="010";p2x<="011";p3x<="100";p4x<="101";
- p1y<="100";p2y<="100";p3y<="100";p4y<="100";
- p5x<="100";p5y<="101";
-
- when"11"=>--测试旋转路径有阻挡
- forms<="00";
- --p1 p2 p3 p4,居中
- -- p5
- p1x<="010";p2x<="011";p3x<="100";p4x<="101";
- p1y<="100";p2y<="100";p3y<="100";p4y<="100";
- p5x<="101";p5y<="101";
-
- when others=>null;
- end case;
- make<=X"1"; state<=display;
-
- --显示新的测试项形状--
- when display=>
- case make is --make:1~5
- when X"1"=>
- wen_tmp<="1";--开写使能
- dotout_tmp<="1";--高电平,点亮led灯
- cx<=p1x; cy<=p1y; make<=X"2";
- when X"2"=>
- cx<=p2x; cy<=p2y; make<=X"3";
- when X"3"=>
- cx<=p3x; cy<=p3y; make<=X"4";
- when X"4"=>
- cx<=p4x; cy<=p4y; make<=X"5";
- when X"5"=>
- cx<=p5x; cy<=p5y; make<=X"0";
- when others=>
- wen_tmp<="0";--关写使能
- state<=wait_btn;--等待操作键
- end case;
-
- --测试I型模块能否以p3为轴心逆时针旋转--
- --测试边界、空位与阻挡--
- when test_Lp3=>
- case test is
- --测试边界与空位1--
- when X"1"=>--test
- if(forms="00")then
- if(p3y>"000" and p3y<"110")then--边界条件
- cx<=p3x; cy<=p3y-1; test<=X"2";--测试空位1
- else
- state<=wait_btn;--不能旋转,等待操作键
- end if;
- elsif(forms="01")then
- if(p3x>"000" and p3x<"110")then
- cx<=p3x-1; cy<=p3y; test<=X"2";
- else state<=wait_btn;
- end if;
- elsif(forms="10")then
- if(p3y>"001" and p3y<"111")then
- cx<=p3x; cy<=p3y-2; test<=X"2";
- else state<=wait_btn;
- end if;
- elsif(forms="11")then
- if(p3x>"001" and p3x<"111")then
- cx<=p3x-2; cy<=p3y; test<=X"2";
- else state<=wait_btn;
- end if;
- end if;
- when X"2"=>
- if(dotin="1")then--高电平点亮,位置已被占
- state<=wait_btn;--不能旋转,等待操作键
- else
- test<=X"3";--有空位,测试下一个位置
- end if;
-
- --测试空位2--
- when X"3"=>--test
- if(forms="00")then
- cx<=p3x; cy<=p3y+1; test<=X"4";
- elsif(forms="01")then
- cx<=p3x+1; cy<=p3y; test<=X"4";
- elsif(forms="10")then
- cx<=p3x; cy<=p3y-1; test<=X"4";
- elsif(forms="11")then
- cx<=p3x-1; cy<=p3y; test<=X"4";
- end if;
- when X"4"=>
- if(dotin="1")then state<=wait_btn;
- else test<=X"5";
- end if;
-
- --测试空位3--
- when X"5"=>--test
- if(forms="00")then
- cx<=p3x; cy<=p3y+2; test<=X"6";
- elsif(forms="01")then
- cx<=p3x+2; cy<=p3y; test<=X"6";
- elsif(forms="10")then
- cx<=p3x; cy<=p3y+1; test<=X"6";
- elsif(forms="11")then
- cx<=p3x+1; cy<=p3y; test<=X"6";
- end if;
- when X"6"=>
- if(dotin="1")then state<=wait_btn;
- else test<=X"7";
- end if;
-
- --测试阻挡1--
- when X"7"=>--test
- if(forms="00")then
- cx<=p1x; cy<=p1y+1; test<=X"8";
- elsif(forms="01")then
- cx<=p1x+1; cy<=p1y; test<=X"8";
- elsif(forms="10")then
- cx<=p1x; cy<=p1y-1; test<=X"8";
- elsif(forms="11")then
- cx<=p1x-1; cy<=p1y; test<=X"8";
- end if;
- when X"8"=>
- if(dotin="1")then --高电平点亮,有阻挡
- state<=wait_btn;--不能旋转,等待操作键
- else
- test<=X"9";--无阻挡,测试下一个位置
- end if;
-
- --测试阻挡2--
- when X"9"=>--test
- if(forms="00")then
- cx<=p2x; cy<=p2y+1; test<=X"A";
- elsif(forms="01")then
- cx<=p2x+1; cy<=p2y; test<=X"A";
- elsif(forms="10")then
- cx<=p2x; cy<=p2y-1; test<=X"A";
- elsif(forms="11")then
- cx<=p2x-1; cy<=p2y; test<=X"A";
- end if;
- when X"A"=>
- if(dotin="1")then
- state<=wait_btn;
- else
- test<=X"B";
- end if;
-
- --测试阻挡3--
- when X"B"=>--test
- if(forms="00")then
- cx<=p2x; cy<=p2y+2; test<=X"C";
- elsif(forms="01")then
- cx<=p2x+2; cy<=p2y; test<=X"C";
- elsif(forms="10")then
- cx<=p2x; cy<=p2y-2; test<=X"C";
- elsif(forms="11")then
- cx<=p2x-2; cy<=p2y; test<=X"C";
- end if;
- when X"C"=>
- if(dotin="1")then
- state<=wait_btn;
- else
- test<=X"D";
- end if;
-
- --测试阻挡4--
- when X"D"=>--test
- if(forms="00")then
- cx<=p4x; cy<=p4y-1; test<=X"E";
- elsif(forms="01")then
- cx<=p4x-1; cy<=p4y; test<=X"E";
- elsif(forms="10")then
- cx<=p4x; cy<=p4y+1; test<=X"E";
- elsif(forms="11")then
- cx<=p4x+1; cy<=p4y; test<=X"E";
- end if;
- when X"E"=>
- if(dotin="1")then
- state<=wait_btn;
- else
- make<=X"8"; state<=rotate_Lp3;
- end if;
- when others=>null;
- end case;
-
-
- --I型模块以p3为轴心逆时针旋转--
- when rotate_Lp3=>
- case make is --make:8~F
- --清空原片--
- when X"8"=>
- wen_tmp<="1";--开写使能
- dotout_tmp<="0";--低电平,熄灭led灯
- cx<=p1x; cy<=p1y; make<=X"9";
- when X"9"=>
- cx<=p2x; cy<=p2y; make<=X"A";
- when X"A"=>
- cx<=p4x; cy<=p4y; make<=X"B";
-
- --更新p1,p2,p4新片位置--
- when X"B"=>--make
- if(forms="00")then
- p1x<=p1x+2; p1y<=p1y+2;
- p2x<=p2x+1; p2y<=p2y+1;
- p4x<=p4x-1; p4y<=p4y-1;
- elsif(forms="01")then
- p1x<=p1x+2; p1y<=p1y-2;
- p2x<=p2x+1; p2y<=p2y-1;
- p4x<=p4x-1; p4y<=p4y+1;
- elsif(forms="10")then
- p1x<=p1x-2; p1y<=p1y-2;
- p2x<=p2x-1; p2y<=p2y-1;
- p4x<=p4x+1; p4y<=p4y+1;
- elsif(forms="11")then
- p1x<=p1x-2; p1y<=p1y+2;
- p2x<=p2x-1; p2y<=p2y+1;
- p4x<=p4x+1; p4y<=p4y-1;
- end if;
- make<=X"C";
-
- --显示新片--
- when X"C"=>--make
- dotout_tmp<="1";--高电平,点亮led灯
- cx<=p1x; cy<=p1y; make<=X"D";
- when X"D"=>
- cx<=p2x; cy<=p2y; make<=X"E";
- when X"E"=>
- cx<=p4x; cy<=p4y; make<=X"F";
-
- when X"F"=>--make
- wen_tmp<="0";--关写使能
- --切换I型模块的形状--
- if(forms="00")then forms<="01";
- elsif(forms="01")then forms<="10";
- elsif(forms="10")then forms<="11";
- elsif(forms="11")then forms<="00";
- end if;
- make<=X"0"; state<=wait_btn;
-
- when others=>null;
- end case;
-
- end case;
- end if;
- end if;
-
- end process;
- end behavioral;
- --库
- library ieee;
- use ieee.std_logic_1164.all;
- use ieee.std_logic_arith.all;
- use ieee.std_logic_unsigned.all;
-
- --实体
- entity ctrl_dotcasebitT is
- port (clk_rama : in std_logic;
- rst : in std_logic;
- dataa : in std_logic_vector(0 downto 0);
- btn_en:in std_logic;
- dispgame:in std_logic;
-
- din : out std_logic;
- load_cs : out std_logic;
- clk_max7219 : out std_logic;
- addra : out std_logic_vector(8 downto 0));
- end;
-
- --结构体
- architecture behavioral of ctrl_dotcasebitT is
- type state_group is(load_shiften,SISO_16,clkedgeR_upaddr);
- signal state:state_group:=load_shiften;
-
- signal shift_en:std_logic:='0';
- signal btnen_tmp:std_logic:='0';
-
- signal addr_init:std_logic:='1';--1控制寄存器,0数据寄存器
- signal addr_game:std_logic:='0';--游戏界面/go
- signal addr_reg:std_logic_vector(2 downto 0):="000";
- signal addr_bit:std_logic_vector(3 downto 0):=X"0"; --16位数据的每一位
-
- begin
- addra<=addr_init&addr_game&addr_reg&addr_bit;
-
- process(rst,clk_rama,btn_en,state,dataa)
- variable cnt_shift:std_logic_vector(3 downto 0):=X"0";--移位计数
- variable cnt_delay:std_logic_vector(2 downto 0):="000";--延时计数
- begin
- if(rst='1')then
- addr_init<='0'; addr_game<='0'; --进入go界面
- addr_reg<="000"; addr_bit<=X"0";
- btnen_tmp<=btn_en;
- shift_en<='0'; load_cs<='1'; clk_max7219<='0';
- cnt_shift:=X"0"; cnt_delay:="000";
- state<=load_shiften;
- elsif rising_edge(clk_rama)then
- if(btnen_tmp/=btn_en and dispgame='1')then--切换测试项按钮
- btnen_tmp<=not btnen_tmp;
- addr_init<='0'; addr_game<='1'; --进入游戏的旋转测试界面
- addr_reg<="000"; addr_bit<=X"0";
- shift_en<='0'; load_cs<='1'; clk_max7219<='0';
- cnt_shift:=X"0"; cnt_delay:="000";
- state<=load_shiften;
- else
- case state is
- when load_shiften=>--装载锁存数据/移位使能
- clk_max7219<='0';
- if(shift_en='1')then
- load_cs<='0';--允许移位
- state<=SISO_16;
- else
- load_cs<='1';--装载锁存数据
- if(cnt_delay="111")then--延时,间隔各寄存器信息
- shift_en<='1'; cnt_delay:="000";
- else
- cnt_delay:=cnt_delay+1;
- end if;
- end if;
-
- when SISO_16=>--16位数据串行输入、串行输出
- clk_max7219<='0';
- din<=dataa(0);
- addr_bit<=addr_bit+1;--16位数据中的下一位
- state<=clkedgeR_upaddr;
-
- when clkedgeR_upaddr=>--产生时钟上升沿,切换寄存器地址
- clk_max7219<='1';--产生时钟clk_max7219上升沿
- --MAX7219各寄存器的切换
- if(cnt_shift=X"F")then--16位移完
- if(addr_init='1')then--MAX7219初始化
- if(addr_reg="100")then--初始化只执行一遍
- addr_init<='0'; addr_reg<="000";
- else
- addr_reg<=addr_reg+1;--下一个控制寄存器
- end if;
- else
- addr_reg<=addr_reg+1;--下一个数据寄存器
- end if;
- shift_en<='0';
- cnt_shift:=X"0"; state<=load_shiften;
- else
- cnt_shift:=cnt_shift+1; state<=SISO_16;
- end if;
- end case;
- end if;
- end if;
- end process;
- end behavioral;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。