FPGA跨时钟域处理方式

FPGA时钟是整个系统的心跳,如果各个模块的心跳异常,会导致手脚不协调。

跨时钟处理有三种方式

  1. 控制信号脉冲检测法,适合于快时钟采慢时钟;
  2. 握手信号法,适合慢时钟采快时钟;
  3. 异步fifo法,适合大量数据的传输

脉冲检测法       

在快时钟的上升沿,使用两级或三级寄存器,检测慢时钟域的使能信号,然后在快时钟域产生一个周期的脉冲信号。

input    clk;
input    rst;
input    wr_en;

reg      wr_r;
reg      wr_r2;
wire     pos_wr;

always@(posedge clk ,negedge rst)
begin
    if(rst)begin
        wr_r <= 1'b0;
        wr_r2<= 1'b0;
    end else 
        wr_r <= wr_en;
        wr_r2 <= wr_r;
    end
end

assign    pos_wr= !wr_r && wr_r2 ; //写选通信号上升沿,拉高一个周期的脉冲信号

握手信号法

快时钟域产生写请求和data,慢时钟域检测到写请求,锁存数据后产生应答信号,快时钟域检测到应答信号后,撤销写请求,至此完成一次写操作。

module handshack (
    input        clk,
    input        rst_n,
    input        req,
    input  [7:0] datain,
    output       ack,
    output       data_out
)
//****************************
//上升沿信号检测
reg    req_r ,req_r2,req_r3 ;
always@ (posedge clk or negedge rst_n)
begin
    if (!rst_n)begin
        req_r  <= 1'b1 ;
        req_r2 <= 1'b1 ;
        req_r3 <= 1'b1 ; 
    end else begin
        req_r <= req ;
        req_r2 <= req_r ;
        req_r3 <= req_r2 ;
    end
end
        
//pos_req2 比 pos_req1 延时一个时钟周期,确保数据被稳定锁存
wire     pos_req1 =  req_r &&  ~ req_r2 ;
wire     pos_req2 =  req_r2 && ~ req_r3 ; 
//***************************************
// 数据锁存
reg  [7:0]     dataoutr;

always@(posedge clk or negedge rst_n )begin
    if(!rst_n)
        dataoutr <= 8'h0;
    else if(pos_req1)
        dataoutr <= datain ; //检测到req有效后锁存输入数据
end

assign dataout =dataoutr
//**************************************
//产生应答信号ack
reg ackr;

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

assign ack =ackr;

endmoudle

异步fifo法

读写时钟各自按照两个时钟域的时钟,控制wreq、和req进行读写命令操作。

发布了22 篇原创文章 · 获赞 19 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/baidu_25816669/article/details/103817314
今日推荐