加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

Verilog HDL基础之:其他常用语句

2013/08/20
阅读需 15 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

 

循环语句

在Verilog HDL中存在着4种类型的循环语句,用来控制执行语句的执行次数。

(1)forever:连续的执行语句。

(2)repeat:连续执行一条语句 n 次。

(3)while:执行一条语句直到某个条件不满足。如果一开始条件即不满足(为假),则语句一次也不能被执行。

(4)for通过以下3个步骤来决定语句的循环执行。

① 先给控制循环次数的变量赋初值。

② 判定控制循环的表达式的值,如为假则跳出循环语句,如为真则执行指定的语句后,转到步骤③。

③ 执行一条赋值语句来修正控制循环变量次数的变量的值,然后返回步骤②。

下面将详细地对各种循环语句进行介绍。

1.forever语句

forever语句的格式如下:

forever 语句;

或者:

forever begin

      多条语句

end

forever循环语句常用于产生周期性的波形,用来作为仿真测试信号。它与always语句不同之处在于它不能独立写在程序中,而必须写在initial块中。

2.repeat语句

repeat语句的格式如下:

repeat(表达式) 语句;

或者:

repeat(表达式) begin

      多条语句

end

在repeat语句中,其表达式通常为常量表达式。下面的例子中使用repeat循环语句及加法和移位操作来实现一个乘法器。

parameter size=8,longsize=16;                 //参数声明

reg [size:1] opa, opb;                            //寄存器声明

reg [longsize:1] result;

begin: mult                                          //为begin_end模块定名模块名

     reg [longsize:1] shift_opa, shift_opb;    //寄存器声明

     shift_opa = opa;                                //将opa、opb的值赋为shift_opa、shift_opb

     shift_opb = opb;

     result = 0;

     repeat(size) begin                            //循环次数

          if(shift_opb[1])

          result = result + shift_opa;             //加法操作

          shift_opa = shift_opa <<1;               //左移1位

          shift_opb = shift_opb >>1;               //右移1位

     end

end

3.while语句

while语句的格式如下:

while(表达式)  语句

或者:

while(表达式) begin

     多条语句

end

下面举一个while语句的例子,该例子用while循环语句对rega这个8位二进制数中值为1的位进行计数。

begin: count1s

     reg[7:0] tempreg;

     count=0;

     tempreg = rega;

     while(tempreg) begin                //当tempreg中有不为0的位时,循环执行

          if(tempreg[0])  count = count + 1;    //低位为1时,计数

          tempreg = tempreg>>1;                     //否则右移1位,此时高位用0填补

     end

end

4.for语句

for语句的一般形式为:

for(表达式1;表达式2;表达式3)  语句

它的执行过程如下。

① 先求解表达式1。

② 求解表达式2,若其值为真(非0),则执行for语句中指定的内嵌语句,然后执行步骤③;若为假(0),则结束循环,转到步骤⑤。

③ 若表达式为真,在执行指定的语句后,求解表达式3。

④ 转到步骤②继续执行。

⑤ 执行for语句下面的语句。

for语句最简单的应用形式是很易理解的,其形式如下:

for(循环变量赋初值;循环结束条件;循环变量增值)

     执行语句

for循环语句实际上相当于采用while循环语句建立以下的循环结构:

begin

     循环变量赋初值;

     while(循环结束条件) begin

          执行语句

          循环变量增值;

     end

end

这样对于需要8条语句才能完成的一个循环控制,for循环语句只需两条即可。

下面分别举两个使用for循环语句的例子。例1用for语句来初始化memory。例2则用for循环语句来实现前面用repeat语句实现的乘法器。

例1:for语句1。

begin: init_mem

     reg[7:0] tempi;

     for(tempi=0;tempi<memsize;tempi=tempi+1)  //使用for循环语句初始化存储器

          memory[tempi]=0;

     end

 

例2:for语句2。

parameter  size = 8, longsize = 16;

reg[size:1] opa, opb;

reg[longsize:1] result;

begin: mult

     integer bindex;

     result=0;

     for( bindex=1; bindex<=size; bindex=bindex+1 )//使用for循环语句实现前面的乘法器

          if(opb[bindex])

               result = result + (opa<<(bindex-1)); //加法并移位

end

在for语句中,循环变量增值表达式可以不必是一般的常规加法或减法表达式。下面是对rega这个8位二进制数中值为1的位进行计数的另一种方法,如下所示:

begin: count1s

     reg[7:0] tempreg;

     count=0;

     for( tempreg=rega; tempreg; tempreg=tempreg>>1 )//循环变量增值表达式使用右移操作

               if(tempreg[0]) 

                   count=count+1;

end

结构说明语句

Verilog语言中的任何过程模块都从属于以下4种结构的说明语句。

(1)initial说明语句。

(2)always说明语句。

(3)task说明语句。

(4)function说明语句。

initial和always说明语句在仿真的一开始即开始执行。initial语句只执行一次,always语句则是不断地重复执行,直到仿真过程结束。在一个模块中,使用initial和always语句的次数是不受限制的。task和function语句可以在程序模块中的一处或多处调用,其具体使用方法在第4章中详细介绍。这里只对initial和always语句加以介绍。

1.initial语句

initial语句的格式如下:

initial begin

     语句1;

     语句2;

     ......

     语句n;

end

举例说明。

例3:initial语句1。

initial begin

      areg=0;                               //初始化寄存器areg

      for(index=0; index<size; index=index+1)

            memory[index]=0;             //初始化一个memory

end

在这个例子中用initial语句在仿真开始时对各变量进行初始化。

例4:initial语句2。

initial begin

     inputs = 'b000000;                  //初始时刻为0

     #10 inputs = 'b011001;             //赋值时刻为10

     #10 inputs = 'b011011;             //赋值时刻为20

     #10 inputs = 'b011000;             //赋值时刻为30

     #10 inputs = 'b001000;             //赋值时刻为40

end

从这个例子中,我们可以看到initial语句的另一个用途,即用initial语句来生成激励波形作为电路的测试仿真信号。一个模块中可以有多个initial块,它们都是并行运行的。initial块常用于测试文件和虚拟模块的编写,用来产生仿真测试信号和设置信号记录等仿真环境。

2.always语句

always语句在仿真过程中是不断重复执行的,其声明格式如下:

always <时序控制>  <语句>

always语句由于其不断重复执行的特性,只有和一定的时序控制结合在一起才有用。如果一个always语句没有时序控制,则这个always语句将会发成一个仿真死锁,例如:

always  areg = ~areg;

这个always语句将会生成一个0延迟的无限循环跳变过程,这时会发生仿真死锁。如果加上时序控制,则这个always语句将变为一条非常有用的描述语句,例如:

always #half_period  areg = ~areg;

这个例子生成了一个周期为period(2×half_period) 的无限延续的信号波形,常用这种方法来描述时钟信号,作为激励信号来测试所设计的电路。

reg[7:0] counter;

reg tick;

always @(posedge areg) begin

     tick = ~tick;                  //tick反相

     counter = counter + 1;        //计数器递增

end

这个例子中,每当areg信号的上升沿出现时,把tick信号反相,并且把counter增加1。这种时间控制是always语句最常用的。

always 的时间控制可以是沿触发也可以是电平触发的,可以单个信号也可以多个信号,中间需要用关键字 or 连接,如:

always @(posedge clock or posedge reset) begin   //由两个沿触发的always块

    …

end

always @( a or b or c ) begin                        //由多个电平触发的always块

    …

end

沿触发的always块常常描述时序逻辑,如果符合,可综合风格要求,用综合工具自动转换为表示时序逻辑的寄存器组和门级逻辑。电平触发的always块常常用来描述组合逻辑和带锁存器的组合逻辑,如果符合,可综合风格要求,转换为表示组合逻辑的门级逻辑或带锁存器的组合逻辑。

相关推荐

电子产业图谱

华清远见(www.farsight.com.cn)是国内领先嵌入师培训机构,2004年注册于中国北京海淀高科技园区,除北京总部外,上海、深圳、成都、南京、武汉、西安、广州均有直营分公司。华清远见除提供嵌入式相关的长期就业培训、短期高端培训、师资培训及企业员工内训等业务外,其下属研发中心还负责嵌入式、Android及物联网方向的教学实验平台的研发及培训教材的出版,截止目前为止已公开出版70余本嵌入式/移动开发/物联网相关图书。企业理念:专业始于专注 卓识源于远见。企业价值观:做良心教育、做专业教育,更要做受人尊敬的职业教育。