3. 戏说VHDL之入门游戏一:流水灯

一.   流水灯

1.1流水灯原理

    流水灯是每个学电子的入门“游戏” ,示意图如图1,其原理极其简单,但是可玩性却极强,可以就8个LED写出不同花样的程序。在1.2中我们列出两个不同思路的代码作为VHDL的入门例程。

 

戏说VHDL之入门游戏一:流水灯

1 流水灯电路图

1.2 流水灯例程

    这里提供两个不同的代码。

第一个代码的思路是先对系统时钟分频,产生1s信号(即变量count取值到25000000,这样分频时间=20ns*25000000*2=1s),然后使用移位操作符指令进行操作。该指令是在VHDL93中引入的,包括sll,srl,sla,sra,rol,ror6个指令,指令操作如图2一目了然。值得注意的是,使用该指令,左操作数必须是BIT_VECTOR类型,右操作数必须是INTEGER类型(前面可以有负号)。

 戏说VHDL之入门游戏一:流水灯

2 移位操作符示意图

例如:令x <= “10110”,则

y <= x sll 2 ;--逻辑左移两位,y <= “ 11000”,空余位填充0

y <= x srl 2 ;--逻辑右移两位,y <= “00101”,空余位填充0

y <= x sla 2 ;--算术左移两位,y <= “11000”,空余位复制最右边上的数值

y <= x sra 2 ;--算术右移两位,y <= “11101”,空余位复制最左边上的数值

y <= x rol 2 ;--循环逻辑左移两位,y <= “11010”,左侧移出位填补到右侧

y <= x ror 2 ;--循环逻辑右移两位,y <= “10101”,右侧移出位填补到左侧

例程一:

 1 --------------------------------------------------------------------------------------------------
 2 
 3 library IEEE;
 4 
 5 use IEEE.std_logic_1164.all;
 6 
 7 --------------------------------------------------------------------------------------------------
 8 
 9 entity VHDL_LEDWATER1 is
10 
11        port (
12 
13                      Clk    : in  STD_LOGIC;             --创建时钟端口,连接开发板PIN23
14 
15                      Rst     : in  STD_LOGIC;            --创建复位端口,连接开发板PIN116
16 
17                      Output : out BIT_VECTOR(7 downto 0) --创建输出端口,对应8个LED。分别
18 
19             --为PIN142-PIN133,要使用移位操作符
20 
21               );                                         --其左侧必须为BIT_VECTOR类型
22 
23 end VHDL_LEDWATER1;
24 
25 --------------------------------------------------------------------------------------------------
26 
27 architecture behave of VHDL_LEDWATER1 is
28 
29        signal Clk1 : STD_LOGIC;             --建立中间时钟信号
30 
31 begin
32 
33 P1:process(Clk)
34 
35 variable count : INTEGER range 0 to 25 := 0; --变量初始值不可综合,在仿真中使用,并
36 
37 variable count1: STD_LOGIC := '1';           --且为便于仿真,这里取到25,当烧写到开
38 
39        --发板时候,改写为25000000即可           
40 
41        begin
42 
43               if(Rst = '0') then
44 
45                      count := 0;
46 
47               elsif(Clk'event and Clk = '1') then
48 
49                      count := count + 1;
50 
51                      if(count = 25) then --这里使用=,而不是>=,可以防止产生比较器,节省硬件资源
52 
53                             count := 0;
54 
55                             count1 := not count1;
56 
57                      end if;
58 
59               end if;
60 
61               Clk1 <= count1;
62 
63    end process P1;
64 
65 P2:process(Clk1)
66 
67        variable temp : BIT_VECTOR(7 downto 0) := "11111110";--注意左操作数类型
68 
69        begin
70 
71               if(Clk1'event and Clk1 = '1') then
72 
73                      temp := (temp rol 1);                  
74 
75               end if;
76 
77               Output <= temp;
78 
79        end process P2;
80 
81 end architecture;

--------------------------------------------------------------------------------------------------

仿真波形:

戏说VHDL之入门游戏一:流水灯
从仿真波形中,可以验证例程的正确性。

    第二个代码的思路是先对系统时钟分频,产生1s信号,然后对该1s信号进行模8计数,再利用case-when语句进行判断,进而控制LED。

例程二:

  1 --------------------------------------------------------------------------------------------------
  2 
  3 library IEEE;
  4 
  5 use IEEE.std_logic_1164.all;--该库定义了std_logic(8值)和std_ulogic(9值)多值逻辑结构
  6 
  7 --------------------------------------------------------------------------------------------------
  8 
  9 entity LEDWATER is
 10 
 11 port (
 12 
 13        Clk    : in  STD_LOGIC;                  --创建时钟端口,连接开发板PIN23
 14 
 15        Rst    : in  STD_LOGIC;                  --创建复位端口,连接开发板PIN116
 16 
 17      Output : out  STD_LOGIC_VECTOR(7 downto 0) --创建输出端口,连接开发板PIN142-PIN133
 18 
 19 );
 20 
 21 end LEDWATER;
 22 
 23 --------------------------------------------------------------------------------------------------
 24 
 25 architecture BEHAVIOR_LEDWATER of LEDWATER is
 26 
 27        signal Clk1 : STD_LOGIC;                           --建立中间时钟信号
 28 
 29 begin
 30 
 31 P1: process(Clk)                                          --进程1,对时钟信号进行N分频
 32 
 33 variable count : INTEGER range 0 to 25 := 0;--变量初始值不可综合,在仿真中使用
 34 
 35        variable count1: STD_LOGIC := '1';
 36 
 37        begin
 38 
 39               if(Rst = '0') then
 40 
 41                      count := 0;                   
 42 
 43               elsif(Clk'event and Clk = '1') then
 44 
 45                      count := count + 1;
 46 
 47                      if(count = 25) then
 48 
 49                             count := 0;
 50 
 51                             count1:= not count1;
 52 
 53                      end if;
 54 
 55                      Clk1 <= count1;
 56 
 57               end if;
 58 
 59        end process;
 60 
 61 P2: process(Clk1)                                  --进程2,对分频信号进行计数,进而控制LED亮灭
 62 
 63        variable count2 : INTEGER range 0 to 8 := 0;--变量初始值不可综合,在仿真中使用
 64 
 65        begin
 66 
 67               if(Clk1'event and Clk1 = '1') then
 68 
 69                      count2 := count2 + 1;
 70 
 71                      if(count2 = 8) then
 72 
 73                             count2 := 0;
 74 
 75                      end if;
 76 
 77               end if;
 78 
 79               case count2 is
 80 
 81                      when 0 => Output <= "11111110";
 82 
 83                      when 1 => Output <= "11111101";
 84 
 85                      when 2 => Output <= "11111011";
 86 
 87                      when 3 => Output <= "11110111";
 88 
 89                      when 4 => Output <= "11101111";
 90 
 91                      when 5 => Output <= "11011111";
 92 
 93                      when 6 => Output <= "10111111";
 94 
 95                      when 7 => Output <= "01111111";
 96 
 97                      when others => Output <= (others => 'Z');
 98 
 99               end case;
100 
101        end process;  
102 
103 end BEHAVIOR_LEDWATER;

仿真波形:

戏说VHDL之入门游戏一:流水灯
从仿真波形中,可以验证例程的正确性。

1.3 总结

        其实,肯定还有其他精妙的想法,这里只列举了两种代码作为学习的开头。不过通过两个代码的学习,也熟悉了移位操作符和case-when语句的使用。下一节将开始数码管的学习。

 

参考文献:

[1] Volnei A.Pedroni.VHDL 数字电路设计教程[M].北京:电子工业出版社,2009:39-40;

[2] http://leonmoon.blog.hexun.com/4609284_d.html

原文地址:https://www.cnblogs.com/584709796-qq-com/p/5161049.html