zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    asp.net core 2.0的认证和授权
    数据库性能优化详解
    StringUtils.defaultIfBlank
    SQL优化(二) 快速计算Distinct Count
    SQL语句中Left join,right join,inner join用法
    sql中的limit关键字
    多线程之间的资源共享
    面试长谈的String,StringBuffer,StringBuilder三兄弟有啥区别
    关于java中的值传递与引用传递遇到的问题
    Struts1和Struts2的区别和对比:
  • 原文地址:https://www.cnblogs.com/584709796-qq-com/p/5161049.html
Copyright © 2011-2022 走看看