Verilog同步复位的解决方法

本文详细介绍了同步复位的概念及其在Wishbone总线接口中的实现方式,通过代码示例展示了如何在Verilog中正确处理复位信号,确保模块在时钟上升沿时完成复位过程。同时,通过测试代码验证了同步复位功能的有效性,最终实现了模块的稳定运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先来明确下什么是同步复位:

同步复位:就是指复位信号只有在时钟上升沿到来时,才能有效,否则无法完成对系统的复位工作。用verilog描述如下:

always @ (posedge clk)
begin
    if (!Rst_n)
    ...
end
异步复位:它是指无论时钟沿是否到来,只要复位信号有效,就对系统进行复位。用Verilog描述如下:

always @ (posedge clk or negedge Rst_n)
begin
    if (!Rst_n)
    ...
end 

quote:”Wishbone规范规定的复位是同步复位,因此在复位信号有效后接下来的时钟上升沿,所有信号和寄存器进入预定状态。“

为了实现同步复位,在编写Wishbone总线接口时应该注意对复位信号的处理。

举例说明:

Wishbone接口的verilog文件中对复位信号的处理为:

// reset signal
    wire reset_sig;
    wire reset;
    reg  reset_r;
    assign reset = wb_stb_i & wb_cyc_i & (wb_adr_i[6:2]==5'h3) & wb_we_i;
    always@(posedge wb_clk_i)
    begin
        if(wb_rst_i)
            reset_r <= 1'b0;
        else
            reset_r <= reset;
    end
    assign reset_sig = (reset_r == 1'b1)&&(reset == 1'b0);

// Instantiate the Unit Under Test (UUT)
    uut uut (
        .clk_i(wb_clk_i),
        .rst_i(reset_sig),
        .other_signal(other_signal),
    );
分析此段代码不要被wb_rst_i信号干扰,wb_rst_i信号是Wishbone的复位信号,与模块uut的复位信号是两码事。这段代码现将实时信号reset存入寄存器reset_r,每次时钟上升沿更新reset_r值,reset_sig 信号可在时钟上升沿时捕捉到可能存在的reset下降沿,从而实现同步复位。

在testbench中用以下语句来测试:

always #5 wb_clk_o = ~wb_clk_o;
initial
begin
  
  @(posedge wb_clk_o);
  @(posedge wb_clk_o);

  #21 wb_we_o = 1;
      wb_adr_o[6:2] = 5'h3;//复位信号
  #17 wb_we_o = 0;
      wb_adr_o[6:2] = 5'h0;

  ...
end
可获得如下波形:


如图所示,实现了模块的同步复位。

PS:洗洗睡了~~

### Verilog设计中不采用同步复位信号的原因 在某些情况下,Verilog设计可能选择不使用同步复位信号。这主要是因为同步复位存在一些潜在缺点: - **资源消耗增加**:为了使复位信号与时钟同步,需要额外的逻辑门和寄存器来构建同步电路。这样做会占用更多的芯片面积并引入延迟[^3]。 - **复杂度提升**:当系统中有多个时钟域时,确保每个时钟域内的所有组件都能正确响应同一个同步复位脉冲变得非常困难。不同频率下的时钟可能会导致难以预测的行为,尤其是在跨时钟域通信的情况下[^2]。 - **性能影响**:由于同步复位依赖于特定时钟边沿触发,在高频率工作条件下,等待下一个合适的时钟周期完成复位过程可能导致不必要的延时,进而降低整个系统的吞吐量[^4]。 因此,在追求高效能、低功耗的应用场景下,工程师们有时会选择放弃传统的同步复位方式而寻找其他解决方案。 ### 替代方案 对于那些决定不在其Verilog代码里加入同步复位机制的情况,以下是几种常见的处理办法: #### 使用异步复位 最直接的方式就是转而采用异步复位策略。这种方式允许立即响应外部中断请求而不必等到最近的一个时钟前沿到达。虽然这种方法简单易行,但在解除复位状态时需要注意避免亚稳态问题的发生[^1]。 ```verilog module async_reset_example ( input wire clk, input wire rst_n, // Active low asynchronous reset output reg q ); always @(posedge clk or negedge rst_n) begin : proc_q if (!rst_n) q <= 0; else // Normal operation code here... end endmodule ``` #### 局部化复位管理 另一种方法是在靠近目标模块的地方创建独立的小范围复位控制单元——即所谓的“局部复位”。这样做的好处是可以更精细地调整哪些部分应该受到影响以及何时生效,从而减少全局效应带来的不确定性。 ```verilog // Example of a local reset generator that can be used within specific modules. module local_reset_gen( input wire global_rst_n, input wire enable_local_rst, output wire local_rst_n ); reg internal_rst; assign local_rst_n = (global_rst_n && !enable_local_rst)? 1'b1 :internal_rst ; initial begin internal_rst = 0; // Initial state is asserted reset end always @(negedge global_rst_n or posedge enable_local_rst) begin if(!global_rst_n || enable_local_rst ) internal_rst <= ~local_rst_n ; // Toggle the reset signal based on conditions end endmodule ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值