Module
到目前为止,您已经熟悉了模块,它是一种通过输入和输出端口与外部交互的电路。更大、更复杂的电路是由更小的模块组成更大的模块,并将其他部分(如赋值语句和always块)连接在一起来构建的。这形成了一个层次结构,因为模块可以包含其他模块的实例。
下图显示了一个非常简单的带有子模块的电路。在本练习中,创建模块mod_a的一个实例,然后将模块的三个引脚(in1、in2和out)连接到顶层模块的三个端口(连接a、b和out)。模块mod_a是为你提供的-你必须实例化它。
连接模块时,只有模块上的端口是重要的。您不需要知道模块内部的代码。模块mod_a的代码如下所示:
module mod_a ( input in1, input in2, output out ); // Module body endmodule
模块的层次结构是通过在另一个模块中实例化一个模块来创建的,只要所有使用的模块都属于同一个项目(这样编译器就知道在哪里可以找到这个模块)。一个模块的代码不写入另一个模块的内部(不同模块的代码不嵌套)。
您可以通过端口名称或端口位置将信号连接到模块。对于额外的练习,两种方法都试试。
连接信号到模块端口有两种常用的方法将导线连接到端口:按位置或按名称。
按位置连接
按照位置将连线连接到端口的语法应该很熟悉,因为它使用类似于c的语法。当实例化一个模块时,端口根据模块的声明从左到右连接。
例如:Mod_a instance1 (wa, wb, wc);
这将实例化一个mod_a类型的模块,并给它一个实例名“instance1”,然后将信号wa(新模块外部)连接到新模块的第一个端口(in1), wb连接到第二个端口(in2), wc连接到第三个端口(out)。这种语法的一个缺点是,如果模块的端口列表改变了,模块的所有实例化也需要被找到并改变以匹配新的模块。
按名字连接
通过名称将信号连接到模块的端口,这样即使端口列表发生变化,线路也能保持正确连接。但是,这种语法更加冗长。
mod_a instance2 (.out (wc) .in1 (wa) .in2 (wb));
上面这行代码实例化了一个名为“instance2”的mod_a类型的模块,然后将信号wa(模块外部)连接到名为in1的端口,wb连接到名为in2的端口,wc连接到名为out的端口。请注意,端口的顺序在这里是不相关的,因为无论它在子模块的端口列表中的位置如何,都将连接到正确的名称。还要注意此语法中紧邻端口名的句点。
module top_module ( input a, input b, output out );
通过端口名称或端口位置将信号连接到模块。
答案:
通过位置连接
通过名字连接
module top_module ( input a, input b, output out ); mod_a instance2 ( .out(out), .in1(a), .in2(b) ); endmodule
按位置进行模块连接
这个问题类似于上一个。给定一个名为mod_a的模块,该模块按此顺序有2个输出和4个输入。您必须按位置将6个端口连接到顶级模块的端口out1、out2、a、b、c和d,按此顺序。
你会得到以下模块:
module mod_a ( output, output, input, input, input, input );
Module Declaration
module top_module ( input a, input b, input c, input d, output out1, output out2 );
答案:
module top_module ( input a, input b, input c, input d, output out1, output out2 ); mod_a inst1_mod_a( out1, out2, a, b, c, d ); endmodule
按名字进行模块连接
这个问题类似前两个。给定一个名为mod_a的模块,该模块按一定顺序有2个输出和4个输入。你必须将这6个端口按名称连接到你的顶级模块的端口:
你会得到以下模块:
module mod_a ( output out1, output out2, input in1, input in2, input in3, input in4);
Module Declaration
module top_module ( input a, input b, input c, input d, output out1, output out2 );
答案:
module top_module ( input a, input b, input c, input d, output out1, output out2 ); mod_a u_mod_a( .out1(out1), .out2(out2), .in1(a), .in2(b), .in3(c), .in4(d) ); endmodule
Module shift(移位寄存器)
你会得到一个模块my_dff,它有两个输入和一个输出(它实现了D触发器)。实例化它们中的三个,然后将它们链在一起,生成一个长度为3的移位寄存器。clk端口需要连接到所有实例。
module my_dff ( input clk, input d, output q );
注意,要建立内部连接,需要声明一些连接。在命名连线和模块实例时要小心:名称必须唯一。
Module Declaration
module top_module ( input clk, input d, output q );
答案:
按位置:
module top_module ( input clk, input d, output q ); wire q1,q2; my_dff u1_my_dff( clk, d, q1 ); my_dff u2_my_dff( clk, q1, q2 ); my_dff u3_my_dff( clk, q2, q ); endmodule
按名字:
module top_module ( input clk, input d, output q ); wire q1,q2; my_dff u1_my_dff( .clk(clk), .d(d), .q(q1) ); my_dff u2_my_dff( .clk(clk), .d(q1), .q(q2) ); my_dff u3_my_dff( .clk(clk), .d(q2), .q(q )); endmodule