zoukankan      html  css  js  c++  java
  • 【连载】【FPGA黑金开发板】Verilog HDL那些事儿独立按键封装(十五)

    声明:本文为原创作品,版权归akuei2及黑金动力社区(http://www.heijin.org)共同所有,如需转载,请注明出处http://www.cnblogs.com/kingst/

    4

    第五章:低级建模-封装(接口建模)

    在这章开始,笔记不再讨论“低级建模”相关的基础了,在前几章笔记已经说过,“低级建模”为“后期准备”的影响力是可大可小。在这里我们先讨论这样一个话题:

    一层高楼,我们必须从地基开始建起。第一楼的“地基”必须稳固,而且结构必须良好。不然的话,第二楼的建筑工作就有困难。

    Verilog HDL 语言的建模就是这样一回事,早期的模块建模,我们只是针对每一个硬件资源,建立一个“基础”而已。这个“基础”虽然可以调用,但是却不是真正的完成品。

    然而每一个“基础”的最后工程就是所谓的“封装”。

    封装”的定义可以是很多,但是笔者把它看为是“建模的最后工程”。我们知道每一个建筑物都需要地基,但是完成地基不代表完成建筑

    5.1 实验十四 - 独立按键封装

    请回忆一下,在实验三和实验四是我们不是建立了“按键消抖”的功能模块。估计读者们在早期可能会误会“就这样简单?实验就完了?”。实验三和实验四就宛如“按键的地基”而已,因为“消抖功能”对按键来说是必须拥有的。但是在实验三和实验四却没有针对黑金开发板上的“按键资源”,执行所谓“竣工”意义上的建模。

    clip_image002

    在针对某一个硬件资源的封装之前,不同的硬件资源都有不同的考虑。如黑金开发板上的5个独立按键,如果我要为它们封装的话,我们必须考虑什么?

    (一)按键的功能 - 按键按下消抖,按键按下产生高脉冲,按键释放消抖。

    (二)按键的数目 - 5个按键资源。

    然而实验四的debounce_module2.v符合如上的功能,那么我们只要基于该模块,执行5次的的实例化再组合以后,就会完成“针对黑金开发板的独立按键”封装工作。

    clip_image004

    上图是基于实验四 debounce_module2.v 经过5次实例化后,再以 key_interface.v 组合模块执行封装而成的“按键接口”。

    key_interface.v

    clip_image006

    clip_image007

    上面代码就是利用实验四的debounce_module2.v 多次实例化的结果。

     Key_In[4..0] Key_Out[4..0] 位分配的如下。

    按键资源

    Key_In[4..0]

    Key_Out[4..0]

    ↑上

    Key_In[4]

    Key_Out[4]

    ↓下

    Key_In[3]

    Key_Out[3]

    ←左

    Key_In[2]

    Key_Out[2]

    →右

    Key_In[1]

    Key_Out[1]

    ·中

    Key_In[0]

    Key_Out[0]

    实验十四演示:

    clip_image009

    实验十四演示,是利用5位按键分别去调制“可调PWM模块”。我们知道按键接口的作用,就是除了按键消抖以外,每当按下某一个按钮,某一个输出就是输出一个高脉冲。

    在这个演示中,最陌生应该是 optional_pwm_module.v 这个模块吧。

    可调PWM模块”笔者在初期的笔记打算加入的,但是考虑到初期的问题,才延后到这里。PWM实验对于Verilog HDL 语言来说是一个经典的实验。那么什么是PWM,我们来简单认识一下:

    clip_image011

     

     1k频率:

     T = 1 / f = 1 / 1k = 1ms

     

     1/100 PWM = 1ms / 100 = 10us

     10 % PWM = 10 x 10us = 100 us

     50 % PWM = 50 x 10us = 500 us

     80 % PWM = 80 x 10us = 800 us

    PWM信号在宏观上是拥有不同占空比比率的信号周期。从上图我们可以看到,假设我要求1k的频率方波信号,那么一个周期就是 1ms 。再假设我求得占空比的比率是可以从1~100%之间调节,那么我必须将一个周期的时间再分为 100 份,亦即 10us 一个PWM块。

    上图中指示了3个不同占空比的PWM信号:

    10% PWM信号,高电平保持时间 100us 低电平保持时间 900us

    50% PWM信号,高电平保持时间 500us 低电平保持时间 500us

    80% PWM信号,高电平保持时间 800us 低电平保持时间 200us

    PWM信号在电流(电压)的调节上是非常方便的。一些简单的计算可以是如下:

    假设某输出口的驱动能力是10mA,当仅有10% PWM 的情况下,驱动能力降落仅剩原有的10%能力,亦即 1mA

    在实验十四的演示中,利用optional_pwm_module.v 控制对 LED 发光亮度。然而不同的是,optional_pwm_module.v 虽然是1k的输出频率,但是PWM块分为256份(0~255),而不是典型的100 PWM块。

    T = 1 / f = 1 / 1k = 1ms

    256PWM = 1ms / 256 = 3.9us

    如果以20Mhz的频率产生 3.9us的定时:

    N = ( 3.9E-6 ) / ( 1 / 20 E+6 )

      = 78.125

      = 78

    ===================================================================

    我们知道 key_interface.v Key_In[4..0] Key_Out[4..0] 位分配是如下:

    [4]Up(Button)  [3]Down(Button)  [2]Left(Button)  [1]Right(Button)  [0]Middle(Button)

    我们以key_interface.v的位分配,针对optional_pwm_module.v PWM调节如下:

    位分配

    按键映射

    optional_pwm_module.v 的调节功能

    [4]

    Up(Button)

    PWM +10

    [3]

    Down(Button)

    PWM -10

    [2]

    Left(Button)

    PWM -1

    [1]

    Right(Button)

    PWM +1

    [0]

    Middle(Button)

    PWM1/2

    具体的内容,我们直接看源码。

    optional_pwm_module.v

    clip_image013

    clip_image014

    clip_image015

    在源码第11行,定义了以20Mhz频率定时3.9us 的常量。15~23行是3.9us的定时器。

    27~35行是256PWM的计数器。37~70行是该模块的核心功能:

    Option_Key(亦即 key_interface.v Key_Out 的连线口)其中某一位产生高脉冲的时候,都会有各种的功能, 37~70行简略下,功能如下表:

    key_interface.v

    Key_Out[4..0]

    optional_pwm_module.v

    Option_Key[4..0]

    按键映射

    功能

    [4]

    [4]

    Up

    PWM +10

    [3]

    [3]

    Down

    PWM -10

    [2]

    [2]

    Left

    PWM -1

    [1]

    [1]

    Right

    PWM +1

    [0]

    [0]

    Middle

    PWM 1/2

    寄存器 Option_Seg 表示了可调节的PWM块。假设 Option_Seg 的值调节至 127, 已经是 127 / 255 也就是 50% PWM

    然而寄存器 System_Seg 是自动递增的 PWM块,每 3.9us 定时 System_Seg 就会自动递增(34~35行)。当 System_Seg 0值递增至255值,这就表示 3.9us x 256 = 1ms ,亦即一个周期已经计数完毕。然后又从下一个周期开始计数。(32~33行)

    假设我要产生 50 % PWM的信号,必然 Option_Seg 的值必须调制 127。然后再经72行表达式的关系,就会产生50%占空比的PWM信号,PWM产生过程如下:

    System_Seg 计数器从 0 ~ 127 递增的时候,由于 72行的表达式 ( System_Seg < Option_Seg ) 的关系,在 System_Seg 计数器的值在 0~127之间,LED的输出都是高电平。当System_Seg 计数器的值递增超过 127之后,亦即 128~255 之间,LED的输出都是低电平。

    clip_image017

    左图是 72 行表达式的关系图,Option_Seg 可以看成是一个比对常量,当 System_Seg 小于 Option_Seg 常量值 LED的输出是高电平。当 System_Seg 的值超过Option_Seg的常量值,LED的输出就是低电平。

    在这里我们稍微来讨论46~68行的功能。

    Option_Key[4] 产生一个高脉冲,如果 Option_Seg 的值小于 245,那么 Option_Seg 的值就增加 10 。反之如果 Option_Seg 的值大于 245Option_Seg 就直接赋予255

    Option_Key[3] 产生一个高脉冲,如果 Option_Seg 的值大于 9,那么 Option_Seg 的值就减少 10 。反之如果 Option_Seg 的值小于 9Option_Seg 就直接赋予0

    Option_Key[2] 产生一个高脉冲,如果 Option_Seg 的值小于 255,那么 Option_Seg 的值就增加 1 。反之如果 Option_Seg 的值大于等于255Option_Seg 就直接赋予255

    Option_Key[1] 产生一个高脉冲,如果 Option_Seg 的值大于 0,那么 Option_Seg 的值就减少 1 。反之如果 Option_Seg 的值小于等于 0Option_Seg 就直接赋予0

    Option_Key[0] 产生一个高脉冲,Option_Seg 就直接赋予127

    exp14_demo.v

    clip_image019

    这个组合模块,也没有什么特别 ... 超级简单的。

    实验十四演示说明:

    这个演示主要是演示 key_interface.v 如何调用而已。然而 key_interface.v 调用的重点就是在于 Key_Out[4..0] 每个位的为分配。

    完成扩展图:

    clip_image021

    key_interface.v

    clip_image023

    key_interface_demo.v

    实验十四演示结论:

    这个实验比较简单,主要是利用实验四的debounce_module2.v 然后针对5位的按键资源执行实例化成为 key_interface.v ,然后在 key_interface_demo.v 中调用。这章的实验,对于封装来讲,算是最简单的一种吧。前面我都说了,不同的封装都有不同的考虑。把这个实验当成暖身吧。

  • 相关阅读:
    C语言调用VIX_API开关虚拟机
    (转)Vix_API 操作 VMware
    C# U盘扫描
    设置字符集
    LIS系统通讯程序原理与实现
    Linux命令的简写和全称
    远程桌面如何退出全屏或全屏切换
    C#编程总结(七)数据加密
    c# 小叙 Encoding(三)
    c# 小叙 Encoding(二)
  • 原文地址:https://www.cnblogs.com/kingst/p/1864678.html
Copyright © 2011-2022 走看看