verilog语法实例学习(5)

子电路模块

子电路模块的使用

     一个verilog模块能够作为一个子电路包含在另一个模块中。采用这种方式,所有的模块都必须定义在一个文件中,那么verilog编译器就必须被告知每个模块的所属。模块例化的通用形式和门例化语句类似。

      modulename [#(parameter overrides)] instance_name(

         port_name([expression]) {,port_name([expression])});

      instance_name可以是任何合法的verilog标识符,端口连接指定了模块之间的连接方式。在一个设计中,相同的模块可以多次例化,但每个例化名字必须是唯一的。[#(parameter overrides)] 是用来传入子模块内部参数值的,这个在前面讲过。port_name对应子模块的一个端口名,每个expression指定了端口的连接。port_name可以使例化语句列表中的信号顺序不必与子电路模块中的端口顺序一致,在verilog中,这叫做名称端口连接。如果端口排序与子电路相同,那个.port_name就可以省略,这种连接就叫顺序端口连接

module fulladd(cin, x, y, s, cout);
   input cin;//carry in bit
	input x;
	input y;

	output s;
	output cout;//carryout bit

	assign s = x^y^cin;
	assign cout = (x&y)|(x&cin)|(y&cin);

endmodule


/*
  通过实例化全加器模块实现四位加法的功能。
  输入:cin,进位
       x, y 被加数和加数
		 s 和
		 cout 进位
*/
module adder4(cin, x, y,s,cout);

  input cin;
  input [3:0] x;
  input [3:0] y;

  output [3:0] s;
  output cout;
  wire [3:1] c; //内部线网类型信号c,用来存储串行进位

  fulladd stage0(.cin(cin),.x(x[0]),.y(y[0]),.s(s[0]),.cout(c[1]));
  fulladd stage1(.cin(c[1]),.x(x[1]),.y(y[1]),.s(s[1]),.cout(c[2]));
  fulladd stage2(.cin(c[2]),.x(x[2]),.y(y[2]),.s(s[2]),.cout(c[3]));
  fulladd stage3(.cin(c[3]),.x(x[3]),.y(y[3]),.s(s[3]),.cout(cout));

endmodule

在上面四位加法器的模块中,我们例化了一位全加器模块四次,每次例化都有不同的例化名字。


子电路的参数

当子电路包含参数时候,参数的默认值可以在例化语句中修改。具体参照下面链接中:verilog中的参数

https://www.cnblogs.com/mikewolf2002/p/10183150.html


生成块

如果要在循环语句中例化模块,则需要使用generate 结构,它的语法如下:

generate

  [for loops]

  [if-else statements]

  [case statements]

  [instantiate statements]

endgenerate

    这种结构提高了verilog模块的灵活度,因为它允许例化语句包含在for循环和if-else语句内部。如果某一个for循环包含在generate块内,则循环变量必须声明为genvar类型。genvar类似于integer,但是它只能使正数,且只能用在generate块内。

    下面的代码中,我们在generate块中用for循环例化了32个全加器子模块。每个for循环中产生的实例名都是一个唯一的由编译器产生的例化名:addbits[0].stage,…,addbits[n-1].stage

    generate块中可hi包括并行语句和过程语句,但是它的主要优点在于for循环内与if-else语句内的门例化和模块例化。


module fulladd(cin, x, y, s, cout);
   input cin;//carry in bit
	input x;
	input y;

	output s;
	output cout;//carryout bit

	assign s = x^y^cin;
	assign cout = (x&y)|(x&cin)|(y&cin);

endmodule
module addern_2(x, y, s, cout);
  parameter n=32;
  input [n-1:0] x;
  input [n-1:0] y;
  output [n-1:0] s;
  output  cout;

  wire [n:0] c;
  genvar k;
  assign c[0]=0;
  assign cout=c[n];

  generate
	 for(k = 0; k <= n-1; k = k + 1) begin:addbit
       fulladd stage(c[k],x[k],y[k],s[k],c[k+1]);
	 end
  endgenerate

endmodule







posted on 2018-12-27 10:24  迈克老狼2012  阅读(2061)  评论(0编辑  收藏  举报

导航