verilog generate

来源:互联网 发布:linux查看用户组信息 编辑:程序博客网 时间:2024/06/02 04:48

Abtract

    generate语句允许细化时间(Elaboration-time)的选取或者某些语句的重复。这些语句可以包括模块实例引用的语句、连续赋值语句、always语句、initial语句和门级实例引用语句等。细化时间是指仿真开始前的一个阶段,此时所有的设计模块已经被链接到一起,并完成层次的引用。

Introduction

1.generate语法

  • 定义genvar,作为generate种的循环变量。
  • generate语句中定义的for语句,必须要有begin,为后续增加标签做准备。
  • begin必须要有名称,也就是必须要有标签,因为标签会作为generate循环的实例名称。
  • 可以使用在generate语句中的类型主要有:
    • ü  module(模块)
    • ü  UDP(用户自定义原语)
    • ü  门级原语
    • ü  连续赋值语句
    • ü  initial或always语句
  • 基本结构如下:

genvar 循环变量名;

generate

    // generate循环语句

    // generate 条件语句

    // generate 分支语句

    // 嵌套的generate语句

endgenerate

    下面将就generate常用的几种情况举例说明。

2. generate-loop循环语句

 

3.generate-conditional条件语句

    generate允许对语句进行条件选择,即将条件选择加入到generate中的for循环中,只例化条件成立时对应的语句或者module。

 

4.generate-case分支语句

    generate-case分支语句与generate-条件语句类似,只不过将原来的分支语句换做了case语句。

 

Conclusion

    genvar与generate是Verilog 2001才有的,功能非常强大,可以配合条件语句、分支语句等做一些有规律的例化或者赋值等操作,对于提高简洁代码很有帮助,同时也减少了人为的影响。


一:generate

 

Verilog-2001添加了generate循环,允许产生module和primitive的多个实例化,同时也可以产生多个variable,net,task,function,continous assignment,initial和always。在generate语句中可以引入if-else和case语句,根据条件不同产生不同的实例化。

用法:

1. generate语法有generate for, genreate if和generate case三种

2. generate for语句必须有genvar关键字定义for的变量

3. for 的内容必须加begin和end

4. 必须给for语段起个名字

例子:

1. generate for例子:

   generate

   genvar i; //generate 8 samll fifo for in_data[i] 8X72

   for(i=0; i<NUM_QUEUES; i=i+1) begin: in_arb_queues //NUM_QUEUES = 8

      small_fifo

        #( .WIDTH(DATA_WIDTH+CTRL_WIDTH),

           .MAX_DEPTH_BITS(2))

      in_arb_fifo

        (// Outputs

         .dout                           ({fifo_out_ctrl[i], fifo_out_data[i]}),

         .full                           (),

         .nearly_full                    (nearly_full[i]),

       .prog_full                      (),

         .empty                          (empty[i]),

         // Inputs

         .din                            ({in_ctrl[i], in_data[i]}),

         .wr_en                          (in_wr[i]),

         .rd_en                          (rd_en[i]),

         .reset                          (reset),

         .clk                            (clk));

   end // block: in_arb_queues

   endgenerate

2.generate if例子:

   generate

      if (REG_WIDTH == WRITE_WIDTH) begin : new_data_a_generation

         assign new_data_a = merge_update ? merge_wr_data : held_wr_data_a;

      end

      else begin

         assign new_data_a = merge_update ?

            {{(REG_WIDTH - WRITE_WIDTH - 1){merge_wr_data_sign}}, merge_wr_data} :

            {{(REG_WIDTH - WRITE_WIDTH){held_wr_data_sign_a}}, held_wr_data_a};

      end

   endgenerate

3.generate还可以进行多个assign赋值!

    module anytest_v(
    input clk,
    input[7:0] datain,
    output[7:0] dataout,
    output finish
    );

   wire[7:0] mem[31:0];
   wire[32*8-1:0] xxx;
    //reg[7:0] i;
    generate
         genvar i;
         for(i=0;i<=31;i=i+1) 
         begin :wiertech
               assign mem[i]= 8'b0; 
         end
   endgenerate
   endmodule

ps:   对于a[8*i+:8]

  this is the so-called "Indexed vector part selects"

在Verilog-1995中,可以选择向量的任一位输出,也可以选择向量的连续几位输出,不过此时连续几位的始末数值的index需要是常量。而在Verilog-2001中,可以用变量作为index,进行part select。
[base_expr +: width_expr] //positive offset
[base_expr -: width_expr] //negative offset

       其中base_expr可以是变量,而width_expr必须是常量。+:表示由base_expr向上增长width_expr位,-:表示由base_expr向上递减width_expr位。例如:

reg [63:0] word;

reg [3:0] byte_num; //a value from 0 to 7

wire [7:0] byteN = word[byte_num*8 +: 8];

       如果byte_num的值为4,则word[39:32]赋值给byteN

二、参数传递

类似VHDL的Generic语句,Verilog也可以在例化时传递参数

传递的参数是子模块中定义的parameter。

传递的方法:

1、module_name #( parameter1, parameter2) inst_name( port_map);

2、module_name #( .parameter_name(para_value), .parameter_name(para_value)) inst_name (port map);

用#方法和port map的写法差不多

module multiplier (a, b, product);
          parameter a_width = 8, b_width = 8;
          localparam product_width = a_width+b_width;
          input [a_width-1:0] a;
          input [b_width-1:0] b;
          output[product_width-1:0]product;
             generate
                 if((a_width < 8) || (b_width < 8))
                     CLA_multiplier #(a_width, b_width) u1 (a, b, product);
                 else
                      WALLACE_multiplier #(a_width, b_width)  u1 (a, b, product);
             endgenerate
endmodule



0 0
原创粉丝点击