资源描述
Textmasterformate durch Klicken bearbeiten,Zweite Ebene,Dritte Ebene,Vierte Ebene,Fnfte Ebene,Klicken Sie,um das Titelformat zu bearbeiten,Page,*,HDL,语言硬件设计,第三章,模块和端口,3.1,模块的结构,Verilog,的基本设计单元是“模块”,(block),。一个模块是由两部分组成的,一部分描述接口,另一部分描述逻辑功能,即定义输入是如何影响输出的。,图 简单模块实例,模块的特点:,模块定义以关键字,module,开始,模块名、端口列表、端口声明和可选的参数声明必须出现在其他部分的前面,,endmodule,语句必须为模块的最后一条语句。,端口是模块与外部环境交互的通道,只有在模块有端口的情况下才需要有端口列表和端口声明。,模块内部的,5,个组成部分是:变量声明、数据流语句、低层模块实例、行为语句块以及任务和函数。这些部分可以在模块中的任意位置,以任意顺序出现。在模块的所有组成部分中,只有,module,、模块名和,endmodule,必须出现,其他部分都是可选的,用户可以根据设计的需要随意选用。在一个,Verilog,源文件中可以定义多个模块,,Verilog,对模块的排列顺序没有要求。,3.2,端口,1.,端口列表,模块的端口声明了模块的输入输出口。其格式如下:,module,模块名,(,口,1,,口,2,,口,3,,口,4,);,在模块的定义中包括一个可选的端口列表。如果模块和外部环境没有交换任何信号,则可以没有端口列表。考虑一个在顶层模块,Top,中被调用(实例引用)的四位加法器,如下图所示。,全加器对应的端口列表,2.,端口声明,端口列表中的所有端口必须在模块中进行声明,,Verilog,中的端口具有三种类型:,(1)input,(输入端口),(2)output,(输出端口),(2)inout,(输入,/,输出双向端口)。,针对前面的全加器模块,fulladd4,的端口声明如下:,在,Verilog,中,所有的端口隐含地声明为,wire,类型,因此如果希望端口具有,wire,数据类型,将其声明为三种类型之一即可。如果输出类型的端口需要保存数值,则必须将其显式地声明为,reg,数据类型。,在下面的例子中,,DFF,触发器模块的输出端口,q,需要保持它的值,直到下一个时钟边沿,其端口声明如下所示:,注意:,不能将,input,和,inout,类型的端口声明为,reg,数据类型,这是因为,reg,类型的变量是用于保存数值的,而输入端口只反映与其相连的外部信号的变化,并不能保存这些信号的值,端口声明的一些说明:,3.,端口连接规则,我们可以将一个端口看成是由相互连接的两个部分组成,一部分在模块内部,另一部分在模块的外部。当在一个模块中调用(实例引用)另一个模块时,端口之间的连接必须遵守一些规则。下图中对这些规则进行了总结。,从模块内部来讲,输入端口必须为线网数据类型;从模块外部来看,输入端口可以连接到线网或,reg,数据类型的变量。,从模块内部来讲,输入,/,输出端口必须为线网数据类型;从模块外部来看,输入,/,输出端口也必须连接到线网类型的变量,从模块内部来讲,输出端口可以是线网或,reg,数据类型;从模块外部来看,输出必须连接到线网类型的变量,而不能连接到,reg,类型的变量。,端口连接还应注意:,位宽匹配,在对模块进行调用(实例引用)的时候,,Verilog,允许端口的内、外两个部分具有不同的位宽。在一般情况下,,Verilog,仿真器会对此给予警告。,未连接端口,Verilog,允许模块实例的端口保持未连接的状态。例如,如果模块的某些输出端口只用于调试,那么这些端口可以不与外部信号连接。例如下面的模块调用(实例引用)方法,让其中一个端口不与其他模块连接。举例如下:,若将,SUM,变量声明为,wire,类型,则这种连接是正确的。,一个非法连接的示例,4.,端口与外部信号的连接,在对模块调用(实例引用)的时候,可以使用两种方法将模块定义的端口与外部环境中的信号连接起来:按顺序连接以及按名字连接。,(1),顺序端口连接,在引用时,严格按照模块定义的端口顺序来连接:,模块名(连接端口,1,信号名,连接端口,2,信号名,连接端口,3,信号名,,),(2),命名端口连接,在引用时用“,.”,,标明原模块是定义时的端口名,例如,模块名(,.,端口,1,名(连接信号,1,名),,.,端口,2,名(连接信号,2,名),,),顺序端口连接的例子,二者端口顺序完全一致,命名端口连接的例子,注意,在这种连接方法中,需要与外部信号连接的端口必须用名字进行说明,而不需要连接的端口只需简单地忽略掉即可。例如,如果端口,c_out,需要悬空,则,Verilog,程序代码如下所示。注意,在端口连接列表中端口,c_out,被忽略。,注意,在端口连接列表中端口,c_out,被忽略。,3.3,层次命名,每一个模块实例、信号或变量都使用一个标识符进行定义;在整个设计层次中,每个标识符都具有惟一的位置。层次命名允许设计者在整个设计中通过惟一的名字表示每个标识符。层次名由一连串使用“,.”,分隔的标识符组成,每个标识符代表一个层次。设,stimulus,是顶层模块。,习题,1,一个,4,位并行移位寄存器的,I/O,引脚如下图所示。写出模块,shift_reg,的定义,只需写出端口列表和端口定义,不必写出模块的内部结构。,module,shift_reg(reg_out,clock,reg_in,);,input clock;,input 3:0,reg_in,;,output 3:0,reg_out,;,/*XXXXXXX*,endmodule,习题,2,定义一个顶层模块,stimulus,,在其中声明,reg,变量,REG_IN,(,4,位)和,CLK,(,1,位)以及,wire,变量,REG_OUT,(,4,位)。在其中调用(实例引用)模块,shift_reg,,实例名为,sr1,,使用顺序端口连接。,module stimulus();,reg,CLOCK;,reg,3:0 REG_IN;,wire 3:0 REG_OUT;,/*connect in order*,shift_reg,sr1(,REG_OUT,CLOCK,REG_IN);,endmodule,习题,3,将上题的端口连接方法改为命名连接。,module stimulus();,reg,CLOCK;,reg,3:0 REG_IN;,wire 3:0 REG_OUT;,/*connect by name*,shift_reg,sr1(.clock(CLOCK),.reg_in(REG_IN),.reg_out(REG_OUT);,endmodule,习题,4,写出,REG_IN,,,CLK,和,REG_OUT,的层次名。,分别是:,stimulus.REG_IN,stimulus.CLK,stimulus.REG_OUT,习题,5,写出模块实例,sr1,及其端口,clock,和,reg_in,的层次名。,分别是:,stimulus.sr1,stimulus.sr1.clock,stimulus.sr1.reg_in,stimulus.sr1.reg_out,
展开阅读全文