0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

FPGA跨时钟域处理方法(三)

CHANBAEK 来源:FPGA自学笔记分享 作者:FPGA自学笔记分享 2023-05-25 15:19 次阅读

所谓数据流跨时钟域即:时钟不同但是时间段内的数据量一定要相同。

常用的数据流跨时钟域可以使用fifo或者ram实现。fifo的实现我们之前文章中fifo资源的介绍中已经详细讲解过了,xilinx FIFO 硬核的结构如下:

图片

但是FIFO实现有一个问题,由于没有地址控制,需要固定时延是不方便,另外就是xilinx IP的fifo深度较大,可能存在资源浪费。

第二种方法就是使用ram自己搭建跨时钟域模块。我们使用bram做数据流跨时钟域。

例示代码如下 ,代码时钟比例为5:4,a时钟每5个clk写入4个数据,b时钟每个clk输出,代码中有两个点要注意:

1、0地址的写是能;

2、有一个防抖处理。

// ============================================================
// File Name: cm_cdc_bram
// VERSION  : V1.0
// DATA     : 2022/10/4
// Author   : FPGA干货分享
// ============================================================
// 功能:数据流使用bram跨时钟域模块
// ============================================================




`timescale 1ns/1ps
module cm_cdc_bram (
    input wire          I_clk_a         , ///输入时钟a,500Mhz
    input wire          I_clk_b         , ///输入时钟b,400Mhz
    input wire          I_data_a_valid  , ///输入时钟b
    input wire [31:0]   I_data_a        , ///a时钟输入信号
    output wire[31:0]   O_data_b          ///b时钟输出信号
    );
// ============================================================
// wire reg
// ============================================================
reg     [8:0]           S_wr_addr           ;
reg                     S_wr_zero_flag      ;


wire                    S_wr_zero_flag_rd   ;
reg     [3:0]           S_clk_cnt           ;
reg                     S_wr_clr_falg_temp  ;
reg                     S_wr_clr_falg       ;
reg     [8:0]           S_rd_addr           ;


// ============================================================
// main code
// ============================================================




// ============================================================
// clk_a
// ============================================================


always @(posedge I_clk_a)
    if(I_data_a_valid)
        S_wr_addr <= S_wr_addr + 9'd1;
    else
        S_wr_addr <= S_wr_addr ; 


always @(posedge I_clk_a)
    S_wr_zero_flag <= (!(|S_wr_addr));


// ============================================================
// clk_b
// ============================================================


cm_cdc_1bit cm_cdc_1bit (
    .I_clk_a        (I_clk_a            ) , ///输入时钟a
    .I_clk_b        (I_clk_b            ) , ///输入时钟b
    .I_single_a     (S_wr_zero_flag     ) , ///a时钟输入信号
    .O_single_b     (S_wr_zero_flag_rd  )   ///b时钟输出信号
    );

always @(posedge I_clk_b)
    if(S_wr_zero_flag_rd & (S_clk_cnt > 4'd2))
        S_clk_cnt <= 4'd2;
    else
        S_clk_cnt <= S_clk_cnt + 4'd1;


always @(posedge I_clk_b)
    if(S_wr_zero_flag_rd)
        S_wr_clr_falg_temp <= 1'b1;
    else if(&S_clk_cnt)
        S_wr_clr_falg_temp <= 1'b0;
    else
        S_wr_clr_falg_temp <= S_wr_clr_falg_temp ;


always @(posedge I_clk_b)
    S_wr_clr_falg <= S_wr_clr_falg_temp & (&S_clk_cnt) ;

always @(posedge I_clk_b)
    if(S_wr_clr_falg)
        S_rd_addr <= 9'd256;
    else
        S_rd_addr <= S_rd_addr + 'd1;


BRAM_SDP_MACRO #(
   .BRAM_SIZE    ("18Kb"         ), // Target BRAM, "18Kb" or "36Kb" 
   .DEVICE       ("7SERIES"      ), // Target device: "7SERIES" 
   .WRITE_WIDTH  (32             ), // Valid values are 1-72 (37-72 only valid when BRAM_SIZE="36Kb")
   .READ_WIDTH   (32             ), // Valid values are 1-72 (37-72 only valid when BRAM_SIZE="36Kb")
   .DO_REG       (1              ), // Optional output register (0 or 1)
   .INIT_FILE    ("NONE"         )
) BRAM_SDP_MACRO_inst (
   .DO           (O_data_b       ), // Output read data port, width defined by READ_WIDTH parameter
   .DI           (I_data_a       ), // Input write data port, width defined by WRITE_WIDTH parameter
   .RDADDR       (S_rd_addr      ), // Input read address, width defined by read port depth
   .RDCLK        (I_clk_b        ), // 1-bit input read clock
   .RDEN         (1'b1           ), // 1-bit input read port enable
   .REGCE        (1'b1           ), // 1-bit input read output register enable
   .RST          (1'b0           ), // 1-bit input reset
   .WE           (4'hf           ), // Input write enable, width defined by write port depth
   .WRADDR       (S_wr_addr      ), // Input write address, width defined by write port depth
   .WRCLK        (I_clk_a        ), // 1-bit input write clock
   .WREN         (I_data_a_valid )  // 1-bit input write port enable
);






endmodule
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1624

    文章

    21608

    浏览量

    601081
  • Xilinx
    +关注

    关注

    71

    文章

    2154

    浏览量

    120814
  • fifo
    +关注

    关注

    3

    文章

    386

    浏览量

    43484
  • 数据流
    +关注

    关注

    0

    文章

    119

    浏览量

    14317
  • 时钟域
    +关注

    关注

    0

    文章

    51

    浏览量

    9524
收藏 人收藏

    评论

    相关推荐

    FPGA设计中解决时钟大方案

    介绍3种时钟处理方法,这3种方法可以说是FPGA
    的头像 发表于 11-21 11:13 3812次阅读
    <b class='flag-5'>FPGA</b>设计中解决<b class='flag-5'>跨</b><b class='flag-5'>时钟</b><b class='flag-5'>域</b>的<b class='flag-5'>三</b>大方案

    关于时钟信号的处理方法

    我在知乎看到了多bit信号时钟的问题,于是整理了一下自己对于时钟信号的处理
    的头像 发表于 10-09 10:44 5879次阅读

    如何处理FPGA设计中时钟问题?

    时钟处理方法,这三种方法可以说是 FPGA 界最常用也最实用的
    发表于 09-22 10:24

    探寻FPGA时钟处理方法

    时钟处理方法,这三种方法可以说是 FPGA 界最常用也最实用的
    发表于 10-20 09:27

    时钟处理方法

    时钟处理方法,这三种方法可以说是FPGA界最常用也最实用的
    发表于 01-08 16:55

    FPGA界最常用的时钟处理法式

    处理方法,这三种方法可以说是FPGA界最常用也最实用的方法,这三种方法包含了单bit和多bit
    发表于 02-21 07:00

    FPGA初学者的必修课:FPGA时钟处理3大方法

    处理方法,这三种方法可以说是FPGA界最常用也最实用的方法,这三种方法包含了单bit和多bit
    发表于 03-04 09:22

    如何处理FPGA设计中时钟间的数据

    介绍3种时钟处理方法,这3种方法可以说是FPGA
    发表于 07-29 06:19

    FPGA时钟处理简介

    (10)FPGA时钟处理1.1 目录1)目录2)FPGA简介3)Verilog HDL简介4
    发表于 02-23 07:47

    FPGA界最常用也最实用的3种时钟处理方法

    介绍3种时钟处理方法,这3种方法可以说是FPGA
    发表于 11-15 20:08 1.4w次阅读

    揭秘FPGA时钟处理方法

    时钟处理方法,这三种方法可以说是 FPGA
    的头像 发表于 12-05 16:41 1594次阅读

    介绍3种方法时钟处理方法

    介绍3种时钟处理方法,这3种方法可以说是FPGA
    的头像 发表于 09-18 11:33 2.2w次阅读
    介绍3种<b class='flag-5'>方法</b><b class='flag-5'>跨</b><b class='flag-5'>时钟</b><b class='flag-5'>域</b><b class='flag-5'>处理</b><b class='flag-5'>方法</b>

    时钟处理方法

    时钟处理FPGA设计中经常遇到的问题,而如何处理
    的头像 发表于 10-18 09:12 7453次阅读

    FPGA时钟处理方法(一)

    时钟FPGA设计中最容易出错的设计模块,而且一旦时钟
    的头像 发表于 05-25 15:06 1882次阅读
    <b class='flag-5'>FPGA</b><b class='flag-5'>跨</b><b class='flag-5'>时钟</b><b class='flag-5'>域</b><b class='flag-5'>处理</b><b class='flag-5'>方法</b>(一)

    FPGA时钟处理方法(二)

    上一篇文章已经讲过了单bit时钟处理方法,这次解说一下多bit的
    的头像 发表于 05-25 15:07 948次阅读
    <b class='flag-5'>FPGA</b><b class='flag-5'>跨</b><b class='flag-5'>时钟</b><b class='flag-5'>域</b><b class='flag-5'>处理</b><b class='flag-5'>方法</b>(二)