[Verilog HDL]

编程规范——RESET

[复制链接]
3027|0
手机看帖
扫描二维码
随时随地手机跟帖
gaochy1126|  楼主 | 2023-5-29 16:10 | 显示全部楼层 |阅读模式
VERILOG 编程规范中的复位

规则1:禁止采用以下代码实现同步复位。

正常情况下,任何一个模块都可以同步复位和异步复位。但一般情况下,在同 一时钟域内必须使用单一的全局同步复位电路,或者使用单一的全局异步复位电路。

而大多数ASIC设计通常还需要在FPGA上进行验证,而FPGA对同步与异步复位的处理方式是不一致的。

为保证代码的通用性,针对ASIC项目,均强制使用异步复位方式,因此下述同步复位方式禁止使用;

always @ ( posedge clk ) begin    if (syn_rst) begin        ;    end else begin        ;    endend
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

规则2:建议使用同步化异步复位信号,实现电路如下图:

上图中,ext_asy_rst是来自外部的复位信号,虽然asy_rst_12p88的下降沿与时钟同步,但它还是用作异步复位。

原则上每一个时钟源都输出一个异步复位信号。

上述电路的标准Verilog程序如下:

always @ ( posedge clk_122p88 or posedge ext_asy_rst ) begin    if ( ext_asy_rst ) begin        rst_shft[1:0] <= 2'b11;     end else begin        rst_shft[1:0] <= {rst_shft[0], 1'b0};    endendassign asy_rst_122p88 = rst_shft[1];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

标准的异步复位语句规则如下:

always @ ( posedge clk_122p88 or posedge asy_rst_122p88 ) begin    if ( asy_rst_122p88 ) begin        ;    end else begin        ;    endend
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

规则3:除非第三方IP制定,否则所有的异步复位必须采用统一的有效电平;

FPGA中复位的应用场景

对于ASIC而言,任何一个同步寄存器单元都需要复位;对于FPGA而言,没有确切的规定。

实际上,很多FPGA单元无需复位,因为复位信号通常需要占用FPGA内部的通道资源,而复位信号的负载通常很多,容易造成复位信号布线困难,整体性能下降,编译时间增加的问题。

因此在FPGA设计中能省略的复位尽量省略。

此外FPGA通常在高级选项中会统一制定寄存器的复位信号电平,这样能够进一步节省复位资源开销。

下面给出几个能够省略的复位例子,但不是绝对适用。

移位寄存器

通常情况下,只需要复位第一级移位寄存器,然后保持若干个周期,移位寄存器就被彻底复位了,而不用为每个移位单元都添加复位。

如果每个单元都需要复位,必然会导致纯粹的D触发器实现,而FPGA厂商提供的是IP映射。

分频用的计数器

分频电路就是一个多位计数器,如果初始相位无需控制,就没有必要对计数器进行初始复位,只需要每个时钟加1即可。例如下面是一个2**N的计数分频器。

reg [N-1:0] cnt;always @ ( posedge clk ) begin   cnt <= cnt + 1'b1; end
  • 1
  • 2
  • 3
  • 4
MOORE型状态机输出

对于Moore型状态机的输出,只要复位了状态机,下一周期就会被复位。对存储状态不复位可能会引起反震出现不定态(X)的问题。这个问题可以通过寄存器赋初值解决,例如:

reg[N-1:0] current_state = 0;
  • 1
同步复位与异步复位

在复位设计中,一个常见的问题是电路采用同步复位还是异步复位。

Xilinx推荐电路采用同步复位,但笔者采用同步化的异步复位方式,下表阐述优缺点:

下面是笔者推荐的异步复位同步化方法,如图所示:

实现代码如下:

module reset_sync(        input clk,         input  rst_x_in, //         output reg rst_x_out //         );reg rst_x1,rst_x2,rst_x3;wire rst_x_pulse; always @(posedge clk)begin        rst_x1<=rst_x_in;        rst_x2<=rst_x1;        rst_x3<=rst_x2;end assign rst_x_pulse=rst_x2|rst_x3;always @(posedge clk)        rst_x_out<=rst_x_pulse;endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
AFTER

上述中的一些设计,无论时同步复位,还是异步复位,亦或者是异步复位同步化,之前都有遇到过;但是一直没有成规则,搞不清楚,什么时候该用什么类型的复位。

以前做设计的时候,随着自己的想法来,想怎么弄,怎么弄;

现在急需一套实用的Design rules,不止是节约时间,避免重复设计,更需要跟进行业内的标准;统一的标准会有很大的效率提升。

言而总之,复位的设计:

按照本人的理解,全部用最后推荐的异步时钟同步化,就是最合适的方案。


使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:这个社会混好的两种人:一是有权有势,二是没脸没皮的。

1025

主题

11271

帖子

24

粉丝