top_down设计技巧

写在前面的话

之前梦翼师兄和大家一起学习了层次化设计方法,大家应该懂了,哦,原来所谓的层次化设计就是将一个大的系统不断地拆分成一些便于实现的最小逻辑单元。如果大家真的只是这么想的话,那么梦翼师兄真的是误人子弟喽。在梦翼师兄看来,所谓的层次化设计绝不仅仅是简单的模块拆分,更重要的是要设计好组成各功能单元的各子模块之间的握手级联关系以及各功能模块之间的级联关系。这也是本节梦翼师兄想要给大家重点说明的一些问题。

电平触发

FPGA内部两个不同的模块之间通信,除了需要我们所熟知的数据总线、地址总线以外,通常还需要一些控制信号线以及模块间的握手、反馈信号。

现在我们提出一种假设,假设我们的设计中有两个这样的模块,一个是控制模块,一个是被控制的数据采集模块,简易结构如下图所示

 

我们将两个模块之间的控制信号定义为Start_ctl,控制模块通过Start_ctl信号控制数据采集模块启动或停止。那么就是这样的一个看似简单的逻辑,我们应该如何实现呢?我们首先来学习一种方法触发方式:电平触发。数据模块检测到Start_ctl为高电平则开始数据采集,检测到Start_ctl为低电平则停止采集。这种方式看起来很简单,但真的可以轻易地实现我们的目标吗?假设数据采集模块采集一组有效数据的时间是不确定的(根据外部输的信号的情况来决定)。那么如果我们需要控制数据采集模块只采集一组数据,当我们将Start_ctl信号置为高电平以后,数据采集模块开始采集数据,那么在什么时间我们应该将Start_ctl信号置为低电平结束采集呢?答案是:不知道。因此我们必须再设计一条反馈信号线,数据采集模块采集结束以后,将反馈信号置为高电平,控制模块接收到反馈信号之后,再将启动信号置为低电平。简易结构图如下图所示

那么这样的控制—反馈关系真的一定可以解决问题吗?如果大家够细心的话,其实还是存在隐患的。控制模块只有接收到flag信号以后才能进一步地决定Start_ctl信号的状态,那么这个过程中可能会存在周期差,那么在这个周期差的时间内,数据采集模块很可能再次被启动。因此,这点我们需要特别注意。

尖峰脉冲

除了电平触发可以作为握手信号,梦翼师兄在这里给大家分享另外一种在同步时序逻辑设计条件下,比较行之有效的方式:模块之间使用尖峰脉冲作为握手信号。示图如下:

注:这里的尖峰指的是有且只有一个时钟周期高电平的脉冲信号

模块功能介绍

模块名

功能描述

Key_scan

矩阵键盘按键扫描模块

shift

键值移位寄存模块

模块端口介绍

模块名

功能描述

Clk

系统时钟

Rst_n

系统低电平复位信号

Row

矩阵键盘“行线”

Result

移位寄存结果输出

模块内部连线介绍

模块名

功能描述

Col

矩阵键盘“列线”

Key_num

键值移位寄存模块

Key_flag

尖峰脉冲

系统功能描述

以上系统主要由两个模块组成,一个是矩阵键盘的按键扫描模块,另一个是按键值的移位、保存模块。Key_scan按键检测模块的主要任务就是负责扫描检测按键动作,并将确定的键值输出到信号线Key_num,而shift键值移位寄存模块的主要任务就是将每次检测到的键值通过移位的方式存储到一个大位宽的输出寄存器Result。

那么,试想一下,如果我们只是直接地将Key_num输入到shift模块,可以实现每次按键的正确移位寄存吗?答案一定是 NO! 因为我们每次按键的时间长短是不一定的,可能是短短的几秒,也可能是几分钟按着不放。那么这种情况下,每隔多长时间我们进行一次数据采集和移位工作呢?很明显,由于时间的不确定性,通过这种方式的模块级联,注定是要失败的。

两个模块之间的直接级联,之所以会失败是因为我们没有为两个模块设置“握手”信号,因此,我们才会设置Key_flag这样的一个信号作为两个模块之间通信的桥梁。Key_flag是一个有且只有一个时钟周期的尖峰脉冲信号,当按键检测模块检测到按键按下并将按键值输出到Key_num的同时驱动Key_flag出现一个时钟周期的高电平,之后一直置为低,直到按键放开并检测到有新的按键按下,Key_flag信号才有可能会再次出现尖峰脉冲。也就是说,每当有一个尖峰脉冲出现就代表有一个新的按键动作发生。那么,shift 模块只要检测到尖峰脉冲就可以进行一次移位操作。

 由以上分析可以看出,合理、巧妙的利用尖峰脉冲可以使我们的系统变得高效而简单,同时不容易出现周期差的问题。因此,梦翼师兄建议大家做系统级联的时候,应该尽可能使用尖峰脉冲的方式而非电平触发的方式作为握手信号。

 

 

 

 

posted @ 2019-09-12 20:21  梦翼师兄  阅读(664)  评论(0编辑  收藏  举报