Verilog 模组与埠
模组与埠
学习目标:
- 了解 Verilog 中模组的定义,如模组的名称,埠列 ( port list ) ,参数、变数的宣告,陈述资料的处理程序,行为模式的陈述,取用低阶模组的别名,任务 (Tasks)与函数 (functions )。
- 了解在 Verilog 中如何定义一个模组的埠列。
- 了解在一个模组的别名与另一个别名,埠与埠之间相互连接的规则。
- 了解如何藉由依照顺序或是指定名称的方式来连接不与外部的输入讯号。
- 解释在 Verilog 中阶层化名称的架构。
4-1 模组
- 在 Verilog 中一个模组其架构与组成如图 4-1 所示。
- 一个模组都是以一组关键字 module 与 endmodule 包装起来的,开头永远是一个关键字 module。接下来是模组的名称,结尾一定是 endmodule 。且只有这叁部份是必要的。
- 图 4-1 的其他部份则视设计的需要而加入,且在排列上没有一定的顺序,可以任意排列。
- 模组中的每一个描述的结尾都要加上分号,以示结束,包括模组一开始以 module 开头的那一行,只有结束时的 endmodule 不用。
- 底下以一个全加器,来说明图 4-1 中各个部分。
例题 4-1 全加器的各个部分
// 这个例题主要是在说明一个模组中的不同元件
// 模组名称与埠列 // 取用低阶层次模组的别名 // 关键字 endmodule // 模组名称与埠列 // 宣告 wire reg 与其他变数 // 关键字 endmodule |
4-2 埠
- 埠提供一个模组与外界沟通的介面,好比一个晶片的输出、输入脚一样。
- 外界仅能由埠来跟一个模组沟通,而一个模组内部的详细情况外界是无法得知的,这点提供设计的人对於模组的内部有较大的修改空间。
4-2.1 埠列
- 一个模组通常经由一系列的埠来与外界沟通,相反若一个模组不需要与外界沟通自然就没有埠。
例题 4-2 埠列
module fa32(sum,c_out,a,b,c_in) ; // 有埠列的模组 module test; // 没有埠列的模组,通常用在模拟方块 |
4-2.2 埠的宣告
- 在埠列中的埠都必须要在模组中宣告。埠的宣告有以下几种类别:
例题 4-3 埠的宣告
module fulladd4 (sum,c_out,a,b,c_in) ; // 开始宣告埠 output [ 3: 0] sum ; output c_cout ; input [3:0] a, b; input c_in ; // 结束埠的宣告 ... <module internals> ... endmodule |
- 在 Verilog 中内定的埠的宣告种类为 wire ,因此假若在埠的宣告中只有宣告 output、input 或是 inout,则皆将其视为 wire,然而假如需要将讯号的值储存起来,就要将埠的种类宣告为 reg。
例题 4-4 DFF 埠的宣告
module DFF (q,d,clk,reset) ; output q ; reg q ; // 输出埠 q 需要储存资料,所以宣告成 reg 型态的变数 input d, clk, reset ; ... ... endmodule |
- 注意!input 与 inout 型态的埠不能被宣告为 reg。因为 reg 储存值,而输入讯号只是表现出外来讯号的改变情况,所以不能储存其值。
4-2.3 埠的连接规定
- 埠分为模组内外相互连接的两部分,在 Verilog 中埠的内与外部的连接则必须要遵守某些规定,如图 4-4 所示:
- 输入
- 在模组的内部,输入埠永远只是一个接点 ( net )。而由外部到输入埠的讯号则可以是暂存器 ( reg ) 或是一个接点 ( net )。
- 输出
- 在模组的内部输出讯号可以是暂存器或是接点的形式,接到外面的讯号就必须是一个接点,不可以为暂存器的型态。
- 双向
- 双向埠不管是在模组内或外都必须是接点的型态。
- 埠的宽度
- 在 Verilog 中允许埠的内外宽度不同,但模拟器会发出警告的讯号。
- 埠的浮接
- Verilog 允许埠可以浮接,如在一个用来除错的埠在正常工作的时候不需要接到任何的讯号,就可以将它浮接。底下是一个浮接的例子:
fulladd4 fa0 (SUM, ,A,B,C_IN) ; // 输出埠 c_out 浮接 |
120306 输入输出问题:输入输出与接点和寄存器的约定。
-输入-
在模组内部,输入埠永远是一个接点net.
在模组外部,输入埠的信号可以是寄存器reg或接点net
-输出-
在模组内部,输出信号可以是寄存器或是接点形式.
在模组外部,读出该模组的信号必须是一个接点,不可以是寄存器.
-双向-
双向埠不管是在模组内或外都必须是接点的形态.
-埠的宽度-
在Verilog中允许埠的内外宽度不同,但模拟器会发出警告信号.
-埠的浮接-
Verilog允许埠可以浮接,如fulladd4 fa0 (SUM, ,A,B,C_IN) ; // 输出埠 c_out 浮接
- 非法的埠连接例题,底下在例题 4-5 将以一个非法的例题来说明埠的连接规定,如下所示:
例题 4-5 非法的埠连接
module Top; // 宣告连接用的变数 reg [3:0] A, B ; reg C_IN ; reg [3:0] SUM ; wire C_OUT ; // 引用模组 fulladd4 并取别名为 fa0 fulladd4 fa0 (SUM,C_OUT,A,B,C_IN ) ; // 这是一个非法的连结,因为模组 fulladd4 的输出埠 连接到一个 // 型态为 reg 的 SUM 变数上 . . < stimulus > . . endmodule |
- 在这例题中我们可以看到 fa0 的输出埠 sum 输出到一个暂存器 SUM 是错误的,因此必须要把 SUM 的型态改成接点 ( net )。
4-2.4 埠与外部讯号连接的方法
- 将一个模组的埠与外部讯号连接的方法有两种:
- 依照定义模组时埠列的顺序来连接
例题 4-6 依照埠列顺序连接
module Top; // 宣告用来连接的变数 reg [3:0] A, B ; reg C_IN ; wire [3:0] SUM ; wire C_OUT ; // 引用模组 fulladd4 并取别名为 fa_ordered. // 讯号依照埠列宣告的顺序连接 fulladd4 fa_ordered ( SUM,C_OUT,A,B,C_IN ) ; ... < stimulus > ... endmodule module fulladd4 ( sum, c_out, a, b, c_in ) ; |
- 用指定名称的方法 ( Connecting ports by name )
// 讯号依照指定埠的名称的方式连接 fulladd4 fa_byname ( .c_out ( C_OUT ), .sum ( SUM ), .b ( B ), .c_in ( C_IN ), .a ( A ), ) ; |
- 注意,只有需要与外部连接的埠才被指名连接,其馀不需要连接的埠的名称就可以不用写出,如上面例子中若埠 c_out 不想与外面的讯号相连,只要不写出来即可,如下面所示。
// 讯号依照指定埠的名称的方式连接 fulladd4 fa_byaname ( .sum ( SUM ), .b ( B ), .c_in ( C_IN ), .a ( A ), ) ; |
4-3 总结
- 模组定义包含以下各个部份,其中关键字 module 与 endmodule 和模组名称是一定要的,其馀的部份包含有:埠列 ( port list ),埠的宣告 ( port declarations ),变数与讯号的宣告 ( variable and signal declarations ),资料处理 ( dataflow statments ),行为模式 ( behavioral blocks ),低阶模组的引用 ( lower-level module instantiations ),任务 (task ) 或是函数 (functions ),这些部份是视设计的需要再加入即可。
- 埠提供一个模组与周遭环境的沟通介面。一个需要与外界讯号沟通得模组皆有一个埠列,在埠列中的每个埠依照其方向分别宣告为 input、output 或是 inout,当引用一个模组时对於埠与讯号的连接必须遵守 Verilog 的规定。
- 埠的连接方法有依照埠列的顺序与指定名称两种方式。
- 在设计中任何一个变数、讯号或是别名都有一个单一阶层化名称,藉由这个阶层化的名称,我们可以在其他的等级订位到这个我们所需要的别名、讯号或是变数。