ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Verilog中for循环的使用

2022-06-23 11:05:28  阅读:630  来源: 互联网

标签:语句 wire always 循环 Verilog 使用 input result


Verilog 中重复的内容可以使用for循环来完成,目前总结的注意点如下:
1、always 内部用for循环,需要定义interger类型变量,否则有些仿真工具会报错
在这里插入图片描述
2、异步复位时序逻辑always@下面第一行必须是异步复位,不能有for循环,否则综合工具会报错
在这里插入图片描述

3、for语句在always 外部,或者使用for循环例化模块,需要定义genvar变量,否则有些仿真工具会报错。
在这里插入图片描述

 

在C语言中,经常用到for循环语句,但在硬件描述语言中for语句的使用较C语言等软件描述语言有较大的区别。

     在Verilog中除了在Testbench(仿真测试激励)中使用for循环语句外,在Testbench中for语句在生成激励信号等方面使用较普遍,但在RTL级编码中却很少使用for循环语句。主要原因就是for循环会被综合器展开为所有变量情况的执行语句,每个变量独立占用寄存器资源,每条执行语句并不能有效地复用硬件逻辑资源,造成巨大的资源浪费。简单的说就是:for语句循环几次,就是将相同的电路复制几次,因此循环次数越多,占用面积越大,综合就越慢。

     在RTL硬件描述中,遇到类似的算法,推荐的方法是先搞清楚设计的时序要求,做一个reg型计数器。在每个时钟沿累加,并在每个时钟沿判断计数器情况,做相应的处理,能复用的处理模块尽量复用,即使所有的操作不能复用,也采用case语句展开处理。

对于下面的for循环语句:  

1 for(i=0;i<16;i++)
2   DoSomething();
  1.    
  2.   可以采用如下代码实现: 
复制代码
reg [3:0] counter;
always @(posedge clk)
  if(syn_rst)
    counter<=4'b0;
  else
    counter<=counter+1;
always @(posedge clk)
  begin
    case(counter)
        4'b0000:
        4'b0001:
        ......
    default:
    endcase
  end
复制代码
  1.        另外,有几个语法的细节需要注意一下。for(i=0;i<16;i=i+1)中的i既可以是reg型的变量也可以是integer类型的变量,但是当i是reg型的变量时,需要注意因为判断语句i<16的缘故,i应定义为reg[4:0] i而不是reg[3:0] i 。由于verilog中没有自增运算符,文中提到的for语句不能写成for(i=0;i<16; i++)的形式。
  2.    
  3.   下面简单的列举几个用for实现的程序代码:
  4.   示例一:

 

 仿真结果如下:


仿真后的结果,由于采用了非阻塞赋值语句,所以每次在always借宿后才把值付给左边的寄存器。
不过在使用了阻塞赋值语句后,得到了目的,但是由于for语句的综合效率不高,且在时序逻辑中一般采用非阻塞赋值,因此最好不能这样写   ----转自特权同学《深入浅出玩转FPGA》   示例二:for用在纯组合逻辑中 举例:4位左移器(将低4位输入的数移到高4位) 复制代码
  1.   1 //Leftshift for 4 bits
  2.   2 module For_Leftshift(
  3.   3 input wire [3:0]inp,
  4.   4 input wire L_EN,
  5.   5 output reg [7:0]result
  6.   6 );
  7.   7
  8.   8 integer i;
  9.   9 always@(inp or L_EN)
  10.   10 begin
  11.   11 result[7:4] = 0;
  12.   12 result[3:0] = inp;
  13.   13 if(L_EN == 1)
  14.   14 begin
  15.   15 for(i=4;i<=7;i=i+1)
  16.   16 begin
  17.   17 result[i] = result[i-4];
  18.   18 end
  19.   19 result[3:0] = 0;
  20.   20 end
  21.   21 end
  22.   22
  23.   23 endmodule
复制代码

综合结果(RTL视图,实际是一个4位选择器)

 
示例三:for不仅可以用在组合逻辑中,而且还可以用在时序逻辑中,用于在1个周期类完成整个for循环。
举例:在一个周期类完成对输入总线中高电平位的计数,则利用for循环实现加法器 复制代码
 1 module For_Counter(
 2 input wire clk,
 3 input wire rst_n,
 4 input wire [12:0] data,
 5 output wire [3:0] numout
 6 );
 7 integer i;
 8 reg[3:0] num;
 9  
10 always @(posedge clk)
11  begin
12  if(!rst_n)
13   num = 0;
14  else
15   begin
16   for(i=0;i<13;i=i+1)
17    if(data[i]) num = num + 1;
18   end
19  end
20  
21 assign numout = num;
22  
23 endmodule
复制代码

综合结果(RTL视图,加法器+触发器)

      综上,可以看出for循环是可以综合的,而且效率很高。但所消耗的逻辑资源较大。在对速度(时钟周期数)要求不是很高的情况下,可以多用几个时钟周期完成任务,而没有必要用for循环来做。

 

标签:语句,wire,always,循环,Verilog,使用,input,result
来源: https://www.cnblogs.com/amxiang/p/16404275.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有