Verilog基础:标识符的向上向下层次名引用

 相关文章

Verilog基础:表达式位宽的确定(位宽拓展)        

Verilog基础:表达式符号的确定

Verilog基础:数据类型

Verilog基础:位宽拓展和有符号数运算的联系

Verilog基础:case、casex、casez语句

Verilog基础:casex和full_case、parallel_case的使用

Verilog基础:表达式中的整数常量(integer)

Verilog基础:task和function的使用(一)

Verilog基础:task和function的使用(二)

Verilog基础:标识符的层次名引用


1.向上向下层次名引用

        在之前的文章中已经介绍了标识符的层次名引用Verilog基础:标识符的层次名引用,如前文所示,所有的完整层次名都是由Top模块开始的由“.”分隔的一系列标识符组成的。但有时候,模块或模块实例的名称足以标识模块及其在层次结构中的位置。较低级别的模块可以在层次结构中引用它上级模块中的项目。如果上级模块的名字,或模块实例的名字已知,则变量可以被引用。对于任务、函数、命名块和生成块,Verilog将在上级模块中查找名称,直到找到它或直到到达层次结构的根,而且只在更高的封闭模块中搜索模块的名称,而不是模块实例名。

        下图是向上层次引用的语法。

Verilog基础:标识符的向上向下层次名引用_第1张图片

         向上的层次名引用也可以使用以下形式。

        其中scope_name是模块实例名或生成块名。这种形式的名称应按下列方式解析:

a)在当前作用域中查找名为scope_name的作用域。如果未找到且当前作用域不是模块作用域,则在上层作用域中查找该名称,必要时重复查找,直到找到该名称或到达模块作用域。如果仍未找到,则继续执行步骤b)。否则,将此名称引用视为从找到该名称的作用域向下引用。

b)在父模块最外层的作用域中查找名为scope_name的作用域。如果发现,则从该范围解析项目名称。

c)重复步骤b),往上走直到顶层模块。

        在实际操作中,笔者发现虽然从形式上看,这两种形式的层次名引用只能由“.”分隔的两部分构成,但它们依然可以像标识符的层次名引用一样,由“.”分隔的多个部分组成。

        下面将会举例说明以上的内容。

例1

module Top;
  reg x;
  Middle middle_0();
  initial fork:a
    reg x;
  join
endmodule

module Middle;
  reg x;
  Below below_0();
  initial fork:b
    reg x;
  join
endmodule

module Below;
  initial Middle.b.x = 0;       //使用模块名引用上层模块的信号 
 //initial middle_0.b.x = 0;    使用实例名引用上层模块的信号
 //initial Top.middle_0.b.x = 0; 完整层次名引用上层模块的信号
    
endmodule

第一种方法是使用模块名引用上层模块的信号,具体过程为,首先搜索本层次(Below模块)有无名字为Middle的层次,然后向上推进到Middle模块的最外层,此时仍然没有Middle层次(本模块名在本模块内不可见),最后搜索Top模块,发现例化了Middle模块,则可以确定x的位置。

第二种方法是使用实例名,与第一种方法类似,不同的是,此时的指向更为清晰,明确指定了是middle_0实例,而第一种方法使用模块名,指的是层次包括了信号使用处层次的实例。

第三种方法则是使用了之前的文章中提到的完整层次名引用,这其实也可以看做是和第一种方法,只不过这时会向上搜索直到Top模块,然后再逐步解析后面的middle_0、b和x。

例2

module Top;
  reg x;
  Middle middle_0();
  initial fork:a
    reg x;
  join
endmodule

module Middle;
  reg x;
  Below below_0();
  initial below_0.x = 0; //向下层引用
  //initial Middle.below_0.x = 0; 首先向上搜索Middle直到在Top中找到Middle,然后向下解析
  //initial Top.middle_0.below_0.x = 0; 完整层次引用,可以理解为向上搜索Top,直到顶层模块
endmodule

module Below;
reg x;
endmodule

第一种方法先在本层次(Middle模块最外层)搜索below_0,结果显示可以找到,below_0中也可找到x,所以这被解释为向下引用below_0中的信号。

后面两种方法和之前一致,其中第二种方法似乎有点奇怪,是一种不完整的层次引用,先向上查找,然后再向下解析below_0和x。

例3

module Top;
  reg x;
  Middle middle_0();
  initial fork:a
    reg x;
  join
endmodule

module Middle;
  reg x;
  Below below_0();
  fork: Middle
      reg x;
      //fork: Middle
          //reg x;              无法被Middle.x搜索到
      //join  
  join
  
endmodule

module Below;
//fork: Middle
    //reg x;    如果有注释内容,则x在此处就会被解析到,而不会继续向上搜索了
    //fork: b     
        initial Middle.x = 0;
    //join
//join
endmodule

上例可以说明,本模块名在本模块中是不可见的,其中initial语句改变的是Middle命名块中x的值,而不是Middle模块中x的值。注意,在向上搜索引用的第一个结点名字的过程中,只会在上层模块的最外层搜索,注释中的x是无法被Middle.x搜索到的,需要使用Middle.Middle.x才能搜索到。

你可能感兴趣的:(数字IC,数字IC,Verilog,HDL,硬件工程,fpga开发,前端)