0****1系统模块划分
要实现一个与或非逻辑的电路,可以先将这个电路进行模块划分,根据功能划分为与门和或非门,如下图所示。
△ 与或非门模块划分
0****2子模块设计
模块划分好后,分别对与门和或非门进行独立设计。在这里,我们可以将子功能模块看作一个电路或者一个具有一定功能的芯片,我们现在要对这个芯片进行设计。设计包括模块名称、端口声明,电路功能描述。
△ 子功能模块设计
03顶层模块搭建
子模块设计好后,我们需要再新建一个源程序.v文件作为顶层文件,并进行顶层模块的设计。顶层模块的端口就是最终整个电路的端口。与或非门有四个输入端口,分别是A、B、C和D,输出端口是L。
**规则:**顶层模块中只出现模块的实例化,不要有assign或always等功能描述语句。
接下来,我们要将设计的子模块实例化到顶层文件中。这个过程就好像将一个个带引脚的芯片,用导线将他们的引脚根据输入输出关系进行连接,形成最终的数字电路系统。
模块实例化中信号与模块端口的接方式有两种,位置对应方式和名称对应方式。
(1)位置对应方式
实例化模块时,上层模块的信号必须严格按照低层模块端口声明的顺序一一对应连接。例如本示例中可以这样写:
my_AND U1 (A, B, c1);
my_AND U2 (C, D, c2);
my_NOR U3 (c1, c2, L);
(2)名称对应方式(推荐)
实例化模块时,使用端口名称进行连接,使用“.”符号标明原模块定义的端口,其后所跟括号中为与之相连接的信号名,如下图所示,即为名称对应方式的写法。此方式不需要按顺序排列。
△ 顶层模块设计
my_AND是子模块的模块名,实例化后的实例需要一个名称来唯一指定该器件,例如这里的U1、U2和U3。a、b、c是原子模块中定义的端口名称,括号中是在顶层模块中所要连接的端口。
模块内部信号,要声明为wire型,如这里的c1和c2。
总结一下,在设计之初,我们需要将电路系统进行模块划分,然后进行子模块设计,具有相同功能和端口的电路,只需要设计一次,然后在顶层模块中进行子模块的实例化,每个实例都有独一无二的实例名,因为他对应的实实在在的电路,在对相同的模块进行实例化时,实例化几次就产生几个相同的电路,由实例名唯一指定。最后通过端口和信号线将子模块的输入输出根据逻辑关系进行连接。
04自顶向下的设计
自顶向下是一种设计思想,是解决复杂问题的有效方法。在数字系统设计中,设计者要先从整个系统的功能和结构出发,先进行最上层的设计。例如,与或非门设计示例中,我们先设计整个系统的模块名,输入、输出端口。
接下来,将系统分成若干个子系统,每个子系统分成若干功能模块,模块还可以继续向下划分成子模块,直至分成许多最基本的数字功能电路。
在自顶向下的设计中,我们可以先逐级设计每一层次中各个子系统或子模块的输入、输出端口,以及模块之间的连接关系。根据设计可以在在顶层模块中,将各个子系统通过实例化进行连接。此时,可以不必关心模块具体是如何实现的,底层模块的具体设计可以放在最后去完成。
也就是说,实际上,上述“ 02子模块设计” 与“ 03顶层模块的搭建 ”两部分的顺序应该颠倒一下,先从全局视角进行顶层模块的设计与搭建,最终再进行子模块功能设计。
而最终的系统设计与验证,则是一个自底向下的过程。先完成每个底层模块的设计与验证,再一步步逐级向上进行验证,直至整个系统正常运行。