87,Verilog-2005标准篇:条件generate结构体介绍

条件generate结构体(if-generatecase-generate)根据elaboration过程中评估的常量表达式,从一组可供选择的generate块中最多选择一个generate块,被选中的generate块(如果有的话)将被例化。

条件generate结构中的generate块可以命名,也可以不命名,它们可以只由一个条目组成,在这种情况先不需要用 begin/end 关键字围绕。即使没有 begin/end 关键字,它仍然是一个generate块,与所有generate块一样,它在实例化时包含一个独立的作用域和一个新的层级结构。

由于最多只能例化某一个generate块,因此允许在一个条件generate结构体中存在多个同名块。不允许任何已命名的generate块与同一作用域中任何其他条件generate结构体或循环结构体中的generate块同名,即使未选择同名块进行例化。不允许任何已命名的generate块与同一作用域中的任何其他声明具有相同名称,即使该块未被选中进行实例化。

如果被选中进行例化的generate块已被命名,那么该名称将声明一个生generate块实例,并成为它所创建的作用域的名称。如果被例化的generate块没有命名,那么它仍然会创建一个作用域;但其中的声明不能使用层级结构名称来引用,只能从generate块本身例化的层级结构中引用。

最常见的用法是创建一个包含任意数量 else-if 子句的 if-else-if  generate方案,所有这些子句都可以有相同名称的generate块,因为只有一个会被选中进行实例化。 在同一个复杂的generate方案中,允许结合 if-generate 和 case-generate 结构。下面举几个例子来说明 条件generate结构体的用法:

例子1:

module  test;
parameter  p = 0, q = 0;
wire  a, b, c;
//---------------------------------------------------------
// Code to either generate a u1.g1 instance or no instance.
// The u1.g1 instance of one of the following gates:
// (and, or, xor, xnor) is generated if
// {p,q} == {1,0}, {1,2}, {2,0}, {2,1}, {2,2}, {2, default}
//---------------------------------------------------------
if  (p == 1)
   if  (q == 0)
     begin  : u1  // If p==1 and q==0, then instantiate
       and  g1(a, b, c); // AND with hierarchical name test.u1.g1
     end
   else  if  (q == 2)
     begin  : u1 // If p==1 and q==2, then instantiate
       or   g1(a, b, c); // OR with hierarchical name test.u1.g1
     end
           // "else" added to end "if (q == 2)" statement
   else ;   // If p==1 and q!=0 or 2, then no instantiation
else   if  (p == 2)
   case  (q)
     0, 1, 2:
       begin : u1         // If p==2 and q==0,1, or 2, then instantiate
         xor  g1(a, b, c);// XOR with hierarchical name test.u1.g1
       end
    default :
     begin : u1          // If p==2 and q!=0,1, or 2, then instantiate
       xnor  g1(a, b, c);// XNOR with hierarchical name test.u1.g1
     end
   endcase
endmodule

例 2-参数化d 乘法器模块实现:

例 3-case-generate语句,以处理位宽小于3的情况:

generate 
   case  (WIDTH)
    1: begin : adder              // 1-bit adder implementation
          adder_1bit  x1(co, sum, a, b, ci);
        end
    2: begin : adder              // 2-bit adder implementation
       adder_2bit  x1(co, sum, a, b, ci);
       end
   default :
      begin : adder              // others - carry look-ahead adder
      adder_cla  #(WIDTH)  x1(co, sum, a, b, ci);
      end
endcase
// The hierarchical instance name is adder.x1
endgenerate

例 4--内存模块

module  dimm(addr, ba, rasx, casx, csx, wex, cke, clk, dqm, data, dev_id);
   parameter  [31:0] MEM_WIDTH = 16, MEM_SIZE  = 8; // in mbytes
   input  [10:0] addr;
   input  ba, rasx, casx, csx, wex, cke, clk;
   input  [ 7:0] dqm;
   inout  [63:0] data;
   input  [ 4:0] dev_id;
   genvar  i;
   case ({MEM_SIZE, MEM_WIDTH})
     {32'd8, 32'd16}: // 8Meg x 16 bits wide
       begin : memory
         for (i=0; i<4; i=i+1)  begin :word
          sms_08b216t0  p(.clk(clk), .csb(csx), .cke(cke),.ba(ba),
                          .addr(addr), .rasb(rasx), .casb(casx),
                          .web(wex), .udqm(dqm[2*i+1]), .ldqm(dqm[2*i]),
                          .dqi(data[15+16*i:16*i]), .dev_id(dev_id));
        // The hierarchical instance names are memory.word[3].p,
        // memory.word[2].p, memory.word[1].p, memory.word[0].p,
        // and the task memory.read_mem
         end 
         task  read_mem;
          input   [31:0] address;
          output  [63:0] data;
          begin   // call read_mem in sms module
            word[3].p.read_mem(address, data[63:48]);
            word[2].p.read_mem(address, data[47:32]);
            word[1].p.read_mem(address, data[31:16]);
            word[0].p.read_mem(address, data[15: 0]);
           end 
         endtask 
       end 
   {32'd16, 32'd8}: // 16Meg x 8 bits wide
       begin : memory
         for  (i=0; i<8; i=i+1)  begin :byte
          sms_16b208t0 p(.clk(clk), .csb(csx), .cke(cke),.ba(ba),
                        .addr(addr), .rasb(rasx), .casb(casx),
                        .web(wex), .dqm(dqm[i]),
                        .dqi(data[7+8*i:8*i]), .dev_id(dev_id));
        // The hierarchical instance names are memory.byte[7].p,
        // memory.byte[6].p, ... , memory.byte[1].p, memory.byte[0].p,
  // and the task memory.read_mem
         end 
         task  read_mem;
           input   [31:0] address;
           output  [63:0] data;
           begin  // call read_mem in sms module
            byte[7].p.read_mem(address, data[63:56]);
            byte[6].p.read_mem(address, data[55:48]);
            byte[5].p.read_mem(address, data[47:40]);
            byte[4].p.read_mem(address, data[39:32]);
            byte[3].p.read_mem(address, data[31:24]);
            byte[2].p.read_mem(address, data[23:16]);
            byte[1].p.read_mem(address, data[15: 8]);
            byte[0].p.read_mem(address, data[ 7: 0]);
           end 
         endtask 
       end 
      // Other memory cases ...
   endcase
endmodule

点赞加关注博主(ID:FPGA小飞)的博文,咱们一起系统学习verilog最终标准IEEE Std 1364-2005吧!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值