• 【翻译】在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

  • 相关阅读:
    PTA 7-5 有趣的最近公共祖先问题 (30分)
    平衡二叉树的旋转类型及代码实现
    Ubuntu搭建青岛大学开源OJ
    见过猪跑现在开始吃猪肉了
    工作4年的老腊肉的总结
    服务器日志的目录
    Jacoco配置的问题
    一次述职之后的反省
    Python+Webdriver+Phantomjs,设置不同的User-Agent,获得的url不一致
    Eclipse+Pydev 找不到对应的module not in Pythonpath
  • 原文地址:https://www.cnblogs.com/halflife/p/1737530.html
Copyright © 2020-2023  润新知