【IC设计】跨时钟域终结篇

本文介绍了如何在异步信号环境下进行跨时钟域处理,通过数据生成模块和边沿检测技术,如上升沿和下降沿检测,以及带置位的处理方法,确保数据的稳定性和准确性。内容涵盖了HDL编程和CMOS模拟集成电路设计中的关键概念。

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

在这里插入图片描述

一、单bit信号

慢时钟域→快时钟域

电平同步器

适用于单比特位的控制信号或者进行格雷码编码的连续变化的数据信号。

跨时钟域处理(打两拍)

接收的信号若与所设计模块处于不同时钟域下,即该是异步信号。为防止数据不稳定,需要在本模块clk下打 2 拍,从而同步时钟域。

module data_dff(
    input   clk     ,
    input   rst_n   ,
    input   data_in ,
    output  data_out );

//reg define
reg   data_in1;
reg   data_in2;

//*********main code**********
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        data_in1 <= 1'b0;
        data_in2 <= 1'b0;
    end else begin
        data_in1 <= data_in;
        data_in2 <= data_in1;
    end 
end

assign data_out = data_in2;

endmodule

快时钟域→慢时钟域

脉冲同步,脉冲展宽(单bit,快→慢)

校招Verilog——单bit跨时钟域(脉冲展宽法-握手法)
从某个时钟域取出一个脉冲,然后在新的时钟域中建立另一个单时钟宽度的脉冲。

二、多bit信号

异步 FIFO

数据信号不存在依次变化的特性,格雷码对此类数据无效,因此采用异步FIFO、握手协议或者用使能信号控制这样的方式来进行数据的传输。

三、复位和时钟切换

复位信号同步器

通常在对时序电路进行复位时建议使用异步复位,但是异步复位会带来亚稳态的问题,通过异步复位同步释放模块可以改善这个问题

时钟切换

时钟切换要防止出现毛刺。

Testbench

数据生成模块

数据生成模块常用于测试,写一个输出:写使能、0~254写数据的数据生成模块

module data_gen(
    input   clk     ,
    input   rst_n   ,
    output reg  wr_en   ,
    output reg [7:0] wr_data );

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        wr_en <= 1'b0;
    end else begin
        wr_en <= 1'b1;    
    end
end

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        wr_data <= 8'd0;
    end else if(wr_en==1'b1 && (wr_data <= 8'd254))begin
        wr_data <= wr_data + 8'd1;
    end else begin
        wr_data <= 8'd0;    //wr_data <= wr_data;
    end
end
endmodule

边沿检测

  • 脉冲边沿检测原理

脉冲边沿的特性:两侧电平发生了变化。
若检测的是下降沿,那就是高电平变低电平。
若检测的是上升沿,那就是低电平变高电平。
若检测脉冲边沿,只需将前后进来的信号做异或运算,即两个电平不相同则是发生边沿。

  • 思路:

设计寄存器用来接收被检测的信号;若{先进reg,后进reg}=2’b10,则是下降沿;
若{先进reg,后进reg}=2’b01,则为上升沿。
注:使用多个寄存器可以更好的检测边沿,防止干扰脉冲。具体看下例:

posedge、negedge、anyedge

`timescale 1ns/10ps

module edge_detect(
    input   clk,
    input   rst_n,
    input   data_in,

    output  posedge_det,
    output  negedge_det,
    output  anyedge_det
);

reg [1:0]   data_in_r;

always@(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        data_in_r <= 2'b0;
    end else begin
        data_in_r <= {data_in_r[0], data_in};
    end
end

assign posedge_det = data_in_r[0] & ~data_in_r[1];
assign negedge_det = ~data_in_r[0] & data_in_r[1];
assign anyedge_det = posedge_det ^ negedge_det;

endmodule
  • testbench
`timescale 1ns/10ps

module edge_detect_tb();

reg clk;
reg rst_n;
reg data_in;

wire    posedge_det;
wire    negedge_det;
wire    anyedge_det;

initial begin
    clk = 0;
    rst_n = 0;
    data_in = 0;
    #15
    rst_n = 1;
    #15
    data_in <= 1'b1;
    #20
    data_in <= 1'b1;
    #20
    data_in <= 1'b0;
    #20
    data_in <= 1'b0;
    #20
    data_in <= 1'b1;
    #20
    data_in <= 1'b1;
    #100
    $stop();
end

always #10 clk= ~clk;

edge_detect u_edge_detect(
    .clk         (clk        ),
    .rst_n       (rst_n      ),
    .data_in     (data_in    ),
                             
    .posedge_det (posedge_det),
    .negedge_det (negedge_det),
    .anyedge_det (anyedge_det)   
);

endmodule
  • 结果

在这里插入图片描述

参考链接

  1. HDLBits第十章
  2. 《CMOS模拟集成电路全流程设计》 李金城 机械工业出版社
  3. 校招Verilog——单bit跨时钟域(脉冲展宽法-握手法)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值