当前位置: 首页 > news >正文

米联客-FPGA程序设计Verilog语法入门篇连载-15 Verilog语法_跨时钟域设计

软件版本:无

操作系统:WIN10 64bit

硬件平台:适用所有系列FPGA

板卡获取平台:https://milianke.tmall.com/

登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!

1概述

本小节主要讲解Verilog语法的跨时钟域设计,需要掌握跨时钟域时快慢时钟之间信号是如何同步的。

2跨时钟域慢速到快速时钟

由慢时钟到快时钟的信号传递,就传输的信号位宽一般分为两种,单比特信号和多比特信号。下面我们分开进行讨论。

2.1 单比特信号

上一节课同步异步设计有提到慢时钟到快时钟的设计方法,一般分析,快时钟域的信号总能采集到慢时钟域的信号,但是如果存在异步时钟域可能会导致采样数据出错,因此需要进行时钟同步处理。同步处理针对单比特信号采取打三拍进行同步。

异步时钟域的信号从一个时钟域进入另一个时钟域之前,将该信号用三级触发器缓存两次,可有效降低因为时序而导致的亚稳态问题。例:

module async_data(input       clk_1,                                //输入时钟clk_1input       data_1,                               //输入数据data_1input       clk_2,                                //输入时钟clk_2  output      data_2                                //输出数据data_2);reg [2:0]    data_ff ;                            //寄存器变量data_ffalways @(posedge clk_2)                           //clk_2敏感posedge,上升沿触发begin  data_ff  <= {data_ff[1:0], data_1};         //data_1数据采样End                                                //data_ff[0]表示最新采样的数据,!data_ff[1]为上一个时钟周期采样的数据assign data_2 = !data_ff[2] && data_ff[1];     //最新的电平为1,之前的电平为0,判断为上升沿检测

 

clk_1为慢时钟,clk_2为快时钟,将data_1在快时钟域进行三拍缓存,检测信号的上升沿,此时将信号进行了同步化。

2.2多比特信号

对于多比特信号的传输,我们要考虑两种情况,即单时钟周期突发信号和多时钟周期连续信号的传输。

针对单时钟周期突发信号我们可以采用利用打拍法延迟采样。例:

module async_data_1(input               clk_1,                //输入时钟clk_1input [7:0]         data_in,             //输入数据data_1input               din_en,               //输入突发信号input               clk_2,                //输入时钟clk_2output  reg[7:0]    data_out,            //输出数据dataoutput  reg         dout_en               //输出突发数据有效信号);reg [2:0]    din_en_ff ;wire din_en_pos;always @(posedge clk_2 )begindin_en_ff  <= {din_en_ff[1:0], din_en} ;    //输入突发信号打拍缓存2拍endassign din_en_pos = !din_en_ff[2] && din_en_ff[1] ; //din_en_ff[1]为新缓存的信号,为1时有效,din_en_ff[2]为上一拍缓存的信号//为0时有效,所以din_en_pos为捕捉 din_en信号上升沿always @(posedge clk_2)beginif (din_en_pos)data_out   <= din ;                              //din_en_pos信号拉高,说明数据有效,将输入数据输出else;endalways @(posedge clk_2 )begindout_en <= din_en_pos ;                              //输出突发数据有效信号为din_en_pos信号endendmodule

 

针对多时钟周期连续信号我们可以采用检测慢时钟的边沿进行采样。如果两个时钟的频率相差较小,可能还需要对数据进行延迟缓存,以保证采集到的是当拍时钟的数据;如果两个时钟的频率相差较大,数据采样时刻可以通过计数的方法获得,而不用对数据进行缓存。例:

module async_data_2(input               clk_1,input [7:0]         data_in,input               din_en,input               clk_2,output  reg[7:0]    data_out,output  reg         dout_en);reg [3:0]    din_en_ff ;wire din_edge_pos;reg [3:0] cnt ;always @(posedge clk_2 )begindin_en_ff  <= {din_en_ff[2:0], clk_1} ;endassign din_edge_pos = !din_en_ff[2] && din_en_ff[1] ;always @(posedge clk_2)                        //clk_2为驱动时钟,进行计数if (din_edge_pos & din_en)                 //din_edge_pos信号为捕捉到上升沿,且din_en信号持续拉高cnt <= 4'h0 ;else if (cnt != 4'hf)                      //计数值为4'hfcnt <= cnt + 1'b1 ;endalways @(posedge clk_2)                         //clk_2为驱动时钟beginif (din_en && cnt == 7)                    //din_en信号持续拉高并且完成7次计数时,确认数据有效data_out   <= din ;                     //数据完成赋值else;endalways @(posedge clk_2 )beginif(din_en && cnt == 8)                     //din_en信号持续拉高并且完成8次计数时,确认数据有效dout_en <= 1 ;                          //输出突发数据有效信号进行拉高elsedout_en <= 0;endendmodule

 

3跨时钟域快速到慢速时钟

由快时钟到慢时钟的信号传递,就传输的信号位宽一般分为两种,单比特信号和多比特信号。下面我们分开进行讨论。

3.1 单比特信号

由快时钟到慢时钟的单比特信号传递,我们需要考虑信号本身是单时钟周期的脉冲信号还是连续多个周期的电平信号。针对单时钟周期的脉冲信号,最好的传送方法是握手法,假设单时钟周期脉冲信号的高电平为有效信号,其基本原理如下。

(1) 快时钟域对脉冲信号进行检测,检测有高电平时输出一个高电平信号。快时钟域输出高电平信号时,保持输出信号为高电平状态。

(2) 慢时钟域对快时钟域的检测信号进行延迟打拍采样。因为此时的脉冲信号被快时钟域保持拉高状态,延迟打拍会采集到该信号。

(3) 慢时钟域确认采样得到高电平检测信号后,再反馈信号给快时钟域。

(4) 快时钟域对反馈信号进行延迟打拍采样。如果检测到反馈信号为高电平,证明慢时钟域已经接收到有效的高电平信号。如果此时快时钟域自身逻辑不再要求脉冲信号为高电平状态,拉低快时钟域的脉冲信号即可。

此方法是通过相互握手的方式对窄脉冲信号进行脉宽扩展。例:

module pulse_fast_2_slow(input                rst_n,                               //复位信号input                clk_fast,                            //快时钟input                pulse_fast,                          //快时钟握手信号input                clk_slow,                            //慢时钟output               pulse_slow                           //慢时钟握手信号);wire                 clear_up ;reg                  pulse_fast_detect ;reg  [1:0]           pulse_fast_detect_ff ;reg  [1:0]           pulse_slow_2_fast ;always@(posedge clk_fast or negedge rst_n)beginif (!rst_n)pulse_fast_detect  <= 1'b0 ;           //pulse_fast_detect拉低复位else if (clear_up)pulse_fast_detect  <= 1'b0 ;           //pulse_fast_detect拉低复位else if (pulse_fast)                      //在快时钟域中对快时钟握手信号进行抓取pulse_fast_detect  <= 1'b1 ;          //信号抓取后,将 pulse_fast_detect持续拉高,可能为多个时钟周期,方便慢时钟域捕捉endalways@(posedge clk_slow or negedge rst_n)beginif (!rst_n)pulse_fast_detect_ff     <= 3'b0 ;                                                //缓存三拍清零elsepulse_fast_detect_ff     <= {pulse_fast_detect_ff[0], pulse_fast_detect} ;  //在慢时钟域中对pulse_fast_detect信号进行抓取End                                                                                    //不要求一翻转立刻捕捉到,只要求延时捕捉assign pulse_slow = pulse_fast_detect_ff[1] ;                                     //取中间一拍进行输出给快时钟域always@(posedge clk_fast or negedge rst_n)beginif (!rst_n)pulse_slow_2_fast  <= 1'b0 ;elsepulse_slow_2_fast  <= {pulse_slow_2_fast[0], pulse_slow};                    //快时钟域对慢时钟握手信号进行捕捉endassign clear_up = !pulse_fast && pulse_slow_2_fast[1];                           //捕捉到回应,将 pulse_fast_detect拉低endmodule

 

3.2 多比特信号

当多位宽数据进行同步时,如果数据变化速率过快,就不能再使用延迟打拍采样的方法。因为此时数据各 bit 位变化的时间参差不齐,用异步时钟进行打拍采样,可能会采集到因路径延迟不同而导致的错误数据。解决此类异步问题的常用方法是采用异步 FIFO (First In First Out)进行数据的交异步FIFO在后面的一节课专门介绍。

http://www.lryc.cn/news/423917.html

相关文章:

  • gradio 对话界面实现支持图片、视频正常显示
  • 催收业务怎么提高接通率
  • 动态生成sitemaps和robots.txt文件:提升SEO与网站可爬性
  • LeetCode 第二十五天 2024.8.12
  • Elasticsearch 全文查询详解
  • 20240810在荣品RK3588S-AHD开发板的预置Android13下挂载exFAT的256GB的TF卡
  • java基础进阶——log日志、类加载器、XML、单元测试、注解、枚举类
  • 《向量数据库指南》——控制Chatbot对话内容:Dopple AI的创新实践与用户体验优化
  • 构建实时数据仓库:流式处理与实时计算技术解析
  • python算术表达式遗传算法
  • net.sf.jsqlparser.statement.select.SelectItem
  • lua匹配MAC地址 正则表达式
  • Chainlit快速实现AI对话应用并将聊天数据的AWS S3 和 Azure Blob云服务中
  • 浅谈性能优化(基于C++)
  • Python 报错:ModuleNotFoundError: No module named ‘Crypto‘
  • UE(User Equipment) 和 UA(User Agent)
  • 视觉SLAM ch3补充——在Linux中配置VScode以及CMakeLists如何添加Eigen库
  • 开关电源:优化电子产品中的能源使用
  • Java语言程序设计——篇十三(2)
  • python结合csv和正则实现条件筛选数据统计分数
  • Ubuntu系统的基础操作和使用|Linux|安装|网络连接|更新与升级系统|系统维护|故障排除|监控|桌面环境|虚拟机|快捷键
  • day 38
  • 352532
  • Day.38 | 1143.最长公共子序列 1035.不相交的线 53.最大子序和 392.判断子序列
  • pytorch 3 计算图
  • 一文吃透:暗水印是什么?企业防泄密可以加暗水印吗?
  • Ajax-02.Axios
  • NodeJS的核心配置文件package.json和package.lock.json详解
  • 开源数据采集和跟踪系统:助力营销决策的关键工具
  • Luminar Neo for Mac/Win:创新AI图像编辑软件的强大功能