Frank

【转载】verilog例化

0
阅读(2967)


  • 声明:转载自@宋桓公,http://blog.chinaaet.com/songhuangong

    【技术分享】谈谈verilog例化

  • 2014-02-20 09:42 发表      系统分类:模拟技术      自定义分类:默认
  • 标签:


      昨天在altera的一篇官方文档上看到一段程序,代码如下:

 

 1: //Top-level module
 2: module TEST_NO(A,B,Clock,Reset,Sel,AddSub,Z,Overflow);
 3:  parameter n=16;
 4:  input [n-1:0]A,B;
 5:  input Clock,Reset,Sel,AddSub;
 6:  output [n-1:0]Z;
 7:  output Overflow;
 8:  reg SelR,AddSubR,Overflow;
 9:  reg [n-1:0]Areg,Breg,Zreg;
 10:  wire [n-1:0]G,H,M,Z;
 11:  wire carryout,over_flow;
 12:  
 13: //Define combinational logic circuit
 14:  assign H=Breg^{n{AddSubR}};
 15:  mux2to1 multiplexer(Areg,Z,SelR,G);
 16:  defparam multiplexer.k=n;
 17:  
 18:  adderk nbit_adder(AddSubR,G,H,M,carryout);
 19:  defparam nbit_adder.k=n;
 20:  assign over_flow=carryout^G[n-1]^H[n-1]^M[n-1];
 21:  assign Z=Zreg;
 22:  
 23:  
 24: //Define flip-flops and registers
 25:  always @(posedge Reset or posedge Clock)
 26:  if(Reset==1)
 27:  begin
 28:  Areg<=0;
 29:  Breg<=0;
 30:  Zreg<=0;
 31:  SelR<=0;
 32:  AddSubR<=0;
 33:  Overflow<=0;
 34:  end
 35:  else
 36:  begin
 37:  Areg<=A;
 38:  Breg<=B;
 39:  Zreg<=M;
 40:  SelR<=Sel;
 41:  AddSubR<=AddSub;
 42:  Overflow<=over_flow;
 43:  end
 44: endmodule
 45:  
 46: //k-bit 2-to-1 multiplexer
 47: module mux2to1(V,W,Sel,F);
 48:  parameter k=8;
 49:  input [k-1:0]V,W;
 50:  input Sel;
 51:  output [k-1:0]F;
 52:  reg [k-1:0]F;
 53:  
 54:  always @(V or W or Sel)
 55:  if(Sel==0)
 56:  F=V;
 57:  else
 58:  F=W;
 59: endmodule
 60:  
 61: //k-bit adder
 62: module adderk(carryin,X,Y,S,carryout);
 63:  parameter k=3;
 64:  input carryin;
 65:  input [k-1:0]X,Y;
 66:  output [k-1:0]S;
 67:  output carryout;
 68:  reg [k-1:0]S;
 69:  reg carryout;
 70:  
 71:  always @(X or Y or carryin)
 72:  {carryout,S}=X+Y+carryin;
 73:  
 74: endmodule

       从第46行往下,是两个module ,一个叫mux2to1,一个叫adderk;15行和18行分别例化了它们:

       mux2to1 multiplexer(Areg,Z,SelR,G);

       adderk nbit_adder(AddSubR,G,H,M,carryout);

       这种例化,和我平时用的不太一样,平时的话:

       mux2to1        multiplexer 
                              (     
                                   .Areg(Areg),  
                                   .Z(Z),   
                                   .SelR(SelR),  
                                   .G(G) 
                              );

     他这种例化方法叫做顺序例化,虽然简洁但是,顺序必须是和原模块的引脚顺序一样。当然本文的重点并不是顺序例化。

我们在顺序例化的下面紧接着有一句:defparam multiplexer.k=n; 这句话是干什么用的呢?

     首先,multiplexer就是模块mux2to1的例化名,n就是一个parameter等于16,那k是什么?multiplexer.k是个什么意思?

我们定位到mux2to1原模块,发现k就是mux2to1模块内部的一个parameter且等于8。且k是与引脚的位宽相关联的——input [k-1:0]V,W;

也就是说模块引脚的weikuan是8,可是我们观察RTL视图发现:

image

引脚的位宽不是8而是16。导致这个结果的原因就是:defparam multiplexer.k=n;这句话的意思就是从新定义这个模块的k的值为n,即16。我感觉这个方法挺不错的,增加了例化的灵活性。

总结:

      我们可以将自己的模块定义添加某些parameter,并且可将parameter关联上某些值,比如上述程序中的引脚的位宽。然后通过defparam multiplexer.参数名,这种语法来例化出不同的模块,是不是很赞呢。