数字电路模块结构
verilog 的基本设计单元是“模块”(block)。一个模块是由两部分组成的,一部分描述接口。一部分描述逻辑功能。
从上面的的这个例子可以看出verilog结构位于module 和endmodule 声明语句之间,每个verilog程序包括4个主要部分:端口定义、I/O说明、内部信号声明、功能定义
端口定义
模块的端口表示的是模块的输入输出口名,也就是他与他与别的模块联系的端口的标识。
在模块被引用时,在引用的模块中有些信号需要输入到被引用的模块中(输入信号:input),有的信号需要从被引用的模块中取出来(输出信号:output),在引用模块时其端口可以用两种方式连接(这里说的连接就是常说的端口的例化):
方法1:
在引用时,严格按照模块定义的端口顺序来链接,不用标明原来模块定义时规定的端口名,如:
模块名(连接端口1信号名 ,连接端口2信号名 ,连接端口3信号名,… );
方法2:
在引用时用"."符号标明原来原模块是定义时规定的端口名,例如:
模块名( .端口1名(连接信号1名),
.端口2名(连接信号2名),
.端口3名(连接信号3名)
…
);
比较:方法2相比于方法1的好处在于可以用端口名与被引用的模块的端口相对应,而不必严格按照端口顺序对应,提高了程序的可读性和可移植性。
I/O说明格式
输入:
input [信号位宽-1 :0] 端口名1;
input [信号位宽-1 :0] 端口名2;
输出:
output [信号位宽-1 :0] 端口名1;
output [信号位宽-1 :0] 端口名2;
模块内部信号说明:
在模块内部用到的和端口有关的wire 和 reg 类型变量的声明
reg [信号位宽-1 : 0] R 变量1, R 变量2,…;
wire [信号位宽-1 : 0] W 变量1, W 变量2,…;
功能定义
模块中最重要的部分是逻辑功能定义的部分。
理解为把输入信号进行一系列的运算,得出输出信号的过程,大致分为组合逻辑和时序逻辑两大类。
模块结构示例代码如下
module example (a,b,c,d); // 端口声明:a b c d
input i_a;
input i_b; //I/O说明 :输入a b
output o_c;
output o_d; //I/O说明:输出 c d
assign o_c = i_a | i_b;
assign o_d = i_a & i_b; //功能定义:逻辑功能描述
endmodule
I/O说明也可以写在端口声明语句里面
上面的代码还可以这样写:
module example (
input i_a, //注意这里不再是分号,而是逗号
input i_b,
output o_c,
output o_d //最后这里没有分号也没有逗号
);
assign o_c = i_a | i_b;
assign o_d = i_a & i_b;
endmodule
模块的引用
wire a1; //顶层内部变量
wire b1; //顶层内部变量
wire c1; //顶层内部变量
wire d1; //顶层内部变量
example my_example(
.a(a1), //逗号
.b(b1),
.c(c1),
.d(d1) //没有逗号,也没有分号
);