【翻译】在Verilog设计中使用参数化模块库(Quartus II)(Verilog)

本文介绍如何在Quartus II里使用Altera的模块库。

 

Contents:

 

范例电路

参数化模块库

使用LPM的扩展电路(Arguemented Circuit)

扩展设计的结果

 

    实际设计中经常包含通用的电路块,比如:加法器、减法器、乘法器、译码器、计数器和移位寄存器。Altera以模块库的

形式提供这些电路块,可在Verilog设计中例化。编译器可以识别模块库里用Verilog代码指定的标准功能,这样就会自动推断这个模块。但是,很多模块库提供太复杂的功能而不能被自动识别。这些模块必须被用户在设计里明确的例化。

    Quartus II包含一个参数化的模块库(LPM)。这些模块采用通用结构,并且需要修该指定的参数值来实现指定的应用。

 

完成本文,读者将学会:

  • 参数化的模块库(LPMs)
  • 在电路里配置一个LPM
  • 在设计电路里例化一个LPM

 

本文范例的细节由Quartus II 9.1截取,其他版本类似。

 

1. 范例电路

 

作为范例,我们使用图1所示的加/减器电路。它可以加、减,并以2的补码表示运算n-bit的数。2个主要的输入是数A=

an-1an-2…a0和B=bn-1bn-2…b0,主要的输出是Z=zn-1zn-2…z0。另一个输入是控制信号AddSub,当AddSub

=0时Z=A+B;当AddSub=1时,Z=A-B.第2个输入控制信号Sel被用来选择运算模式的操作。当Sel=0时,Z=A+-B;

当Sel=1时,B被从当前Z的值加到或减去。如果加法或减法操作的结果溢出,一个输出信号Overflow被激活。

    为了较容易处理异步输入信号,在时钟上升沿它们被加载到触发器。因此,输入A和B将被加载到寄存器Areg和Breg,

而Sel和AddSub将被加载到触发器SelR和AddSubR。加/减器电路的结果放在寄存器Zreg。

001

图 1

    需要的电路如图2 描述。在我们的例子里,我们用一个16位的电路,指定n=16.实现的过程如下:

  • 创建一个工程addersubtractor。
  • 在工程里包含图2相应的文件addersubtractor.v。为了方便,这个文件在DE2附带光盘里提供:DE2_tutorial\

        design_files。

  • 选择器件Cyclone II EP2C35F672C6,因为DE2上用得这个:)
  • 编译设计
  • 通过应用一些典型的输入仿真设计

 

代码:

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

 

 

2. 参数化模块库

 

LPM采用通用结构,通过指定参数值来应用。选择Help > Megafunctions/LPM打开可用的LPM列表。其中一个是加/减器

模块,lpm_add_sub megafunction。选择这个模块,查看其描述。这个模块有一些输入和输出,其中部分可省略。几个

参数可用来定义指定的操作。比如,操作数的位由参数LPM_WIDTH指定。参数LPM_REPRESENTATION指定操作数作为

有符号数还是无符号数,等等。在模块描述中给出如何例化一个LPM的模板。使用这些模板稍微不便,因此Quartus II提供

一个更容易的例化向导。

    我们将使用lpm_add_sub模块来简化图1和图2的加/减器。修改电路如图3.lpm_add_sub模块例化为megaddsub,代

替加法电路里提供加法输入H的异或门。既然运算溢出是LPM的一个输出,就没必要单独用一个异或门生成。

    要完成这个加减器电路,创建一个新的目录tutorial_lpm,并创建一个新工程addersubtractor2。

002

图 3

 

   新的设计将包括目标LPM子电路,并在顶层设计模块例化。LPM子电路的Verilog 模块生成步骤如下:

  1. 选择Tools > MegaWizard Plug-in Manager,弹出配置窗口。
  2. 在图4,选择Create a new custom megafunction variation 然后单击Next。

        004

        图 4

       005

        图 5

   3. 在图5的窗口提供可用的LPM列表。展开arithmetic子列表并选择LPM_ADD_SUB。选择输出文件类型为Verilog HDL。指定输出文件名megaddsub.v和路径。单击Next。

       006

       图 6

    4. 在图6中指定输入数据的位宽为16位,通过一个端口指定操作模式,执行加或减运算。在窗口的左上角可以看到这个

       LPM的符号。注意,当add_sub=1时,result=A+B;反之,result=A-B.这个图1的设计不同。在图3中已经提到。

       单击Next.

       007

       图 7

    5. 在图7的窗口,选择输入值都可改变,单击Next。

       008

       图 8

    6. 在图8窗口选择Create an overflow output,单击Next。

      009

      图 9

    7. 在图9窗口,选择No,单击next。

    8. 图10给出向导创建的文件的总结。单击Finish。

     010

     图 10

 

 

3 使用LPM的扩展电路

 

在修改的设计中将使用megaddsub.v。

代码megaddsub.v

 

代码
   
     
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module megaddsub (
add_sub,
dataa,
datab,
overflow,
result);

input add_sub;
input [ 15 : 0 ] dataa;
input [ 15 : 0 ] datab;
output overflow;
output [ 15 : 0 ] result;

wire sub_wire0;
wire [ 15 : 0 ] sub_wire1;
wire overflow = sub_wire0;
wire [ 15 : 0 ] result = sub_wire1[ 15 : 0 ];

lpm_add_sub lpm_add_sub_component (
.dataa (dataa),
.add_sub (add_sub),
.datab (datab),
.overflow (sub_wire0),
.result (sub_wire1)
// synopsys translate_off
,
.aclr (),
.cin (),
.clken (),
.clock (),
.cout ()
// synopsys translate_on
);
defparam
lpm_add_sub_component.lpm_direction
= " UNUSED " ,
lpm_add_sub_component.lpm_hint
= " ONE_INPUT_IS_CONSTANT=NO,CIN_USED=NO " ,
lpm_add_sub_component.lpm_representation
= " UNSIGNED " ,
lpm_add_sub_component.lpm_type
= " LPM_ADD_SUB " ,
lpm_add_sub_component.lpm_width
= 16 ;


endmodule

 

修改后的加减器代码如下。将这个代码加入文件tutorial_lpm\addersubtractor2。为了方便,DE2附带光盘也提供了这个

文件。这个代码和前面的不同之处在于:

  • 定义over_flow信号的赋值语句和异或门不再需要。
  • 加法电路的实例adderk被megaddsub取代。注意在图6输入dataa和datab各自被变量G和Breg驱动。信号AddSub

        取反以适合这个控制信号在LPM里的用法。

  • 删除adderk模块。

 

代码 addersubtractor2

 

代码
   
     
1 // Top-level module
2   module addersubtractor2(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,M,Z;
11 wire over_flow;
12
13   // Define combinational logic circuit
14   mux2to1 multiplexer(Areg,Z,SelR,G);
15 defparam multiplexer.k = n;
16 megaddsub nbit_adder( ~ AddSubR,G,Breg,M,over_flow);
17 assign Z = Zreg;
18
19   // Define flip-flop and register
20   always @( posedge Reset or posedge Clock)
21 if (Reset == 1 )
22 begin
23 Areg <= 0 ;
24 Breg <= 0 ;
25 Zreg <= 0 ;
26 SelR <= 0 ;
27 AddSubR <= 0 ;
28 Overflow <= 0 ;
29 end
30 else
31 begin
32 Areg <= A;
33 Breg <= B;
34 Zreg <= M;
35 SelR <= Sel;
36 AddSubR <= AddSub;
37 Overflow <= over_flow;
38 end
39 endmodule
40
41 // k-bit 2-to-1 multiplexer
42 module mux2to1(V,W,Selm,F);
43 parameter k = 8 ;
44 input [k - 1 : 0 ]V,W;
45 input Selm;
46 output [k - 1 : 0 ]F;
47 reg [k - 1 : 0 ]F;
48
49 always @(V or W or Selm)
50 if (Selm == 0 )
51 F = V;
52 else
53 F = W;
54 endmodule
55

 

 

 

    添加megaddsub.v到工程。选择Porject > Add/Remove Files in Project(图13)。文件addersubtractor2.v已经存在,添加megaddsub.v,单击Ok。

     013

     图 13

 

     014

     图 14

 

 

4 结果

编译设计,查看总结,图15.注意修改后的电路使用52个le。因为本例比较简单,使用LPM的优势并不明显。在更复杂的设

计中使用LPM,优势比较明显。当有合适的LPM时,建议使用。

 015

  图 15

 

Seealso

 

Using Library Modules in Verilog Designs

你可能感兴趣的:(Verilog)