verilog基本电路设计(包括:时钟域同步、无缝切换、异步fifo、去抖滤波))(精编版)_第1页
verilog基本电路设计(包括:时钟域同步、无缝切换、异步fifo、去抖滤波))(精编版)_第2页
verilog基本电路设计(包括:时钟域同步、无缝切换、异步fifo、去抖滤波))(精编版)_第3页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、verilog 基本电路设计(包括:时钟域同步、无缝切换、异步 fifo 、去抖滤波)verilog 基本电路设计共包括四部分:单 bit 跨时钟域同步时钟无缝切换异步fifo 去抖滤波verilog 基本电路设计之一: 单 bit 跨时钟域同步(帖子链接: 看到坛子里不少朋友,对于基本数字电路存在这样那样的疑惑,本人决定开贴,介绍数字电路最常见的模块单元,希望给初学者带来帮助,也欢迎大佬们前来拍砖。如果想要做数字设计,下面这些电路是一定会碰到的,也是所有大型ip,soc 设计必不可少的基础, 主要包括异步信号的同步处理,同步 fifo , 异步 fifo ,时钟无缝切换,信号滤波deboun

2、ce等等,后面会根据大家反馈情况再介绍新电路。首先介绍异步信号的跨时钟域同步问题。一般分为单bit 的控制信号同步,以及多bit 的数据信号同步。多bit 的信号同步会使用异步fifo 完成,而单 bit 的信号同步, 又是时钟无缝切换电路以及异步fifo 电路的设计基础,这里先介绍单bit 信号同步处理。clka 域下的信号signal_a ,向异步的 clkb 域传递时, 会产生亚稳态问题。所有的亚稳态,归根结底就是setup/hold时间不满足导致。在同一个时钟域下的信号,综合以及布线工具可以在 data 路径或者 clock 路径上插入buffer 使得每一个dff 的 setup/h

3、old时间都满足;但是当signal_a 在 clkb 域下使用时, 由于 clka 与 clkb 异步,它们的相位关系不确定,那么在 clkb 的时钟沿到来时, 无法确定 signal_a 此时是否处于稳定无变化状态,也即setup/hold时间无法确定,从而产生亚稳态。这种异步信号在前后端流程里面是无法做时序分析的,也就是静态时序分析里常说的false_path 。消除亚稳态,就是采用多级dff 来采样来自另一个时钟域的信号,级数越多,同步过来的信号越稳定。对于频率很高的设计,建议至少用三级dff ,而两级 dff 同步则是所有异步信号处理的最基本要求。单 bit 的信号跨时钟域同步,又分

4、成电平信号同步以及脉冲信号同步。 电平信号, 就是说 clka 下的信号 signal_a 在 clkb看来,是一个很宽的信号,会保持多个clkb 的时钟周期,一定能被 clkb 采到。这种情况,只需要使用clkb 用至少两级dff 连续抓 signal_a 即可,特别需要强调的是, 此时 signal_a必须是 clka 下的寄存器信号,如果signal_a 是 clka 下的组合逻辑信号,一定要先在clka 下用 dff 抓一拍,再使用两级 dff 向 clkb 传递。这是因为clka 下的组合逻辑信号会有毛刺,在 clka 下使用时会由setup/hold时间保证毛刺不会被clka 采到

5、,但由于异步相位不确定,组合逻辑的毛刺却极有可能被 clkb 采到。电平信号的同步处理,一般用于知道确定的时钟频率大小关系或者极慢时钟下的信号向极快时钟域传递时使用,简单处理如下:always (posedge clkb or negedge rst_n)begin if (!rst_n) begin levl_b_d1 levl_b_d2 levl_b_d3 end else begin levl_b_d1 levl_b_d2 levl_b_d3 endendassign puls_b_pos = levl_b_d2 & (levl_b_d3);assign puls_b_neg =

6、 levl_b_d3 & (levl_b_d2); assign levl_b_out = levl_b_d2; 上面三个输出分别是经过同步之后,clkb 下可以使用的0 变1 脉冲信号, 1 变 0 脉冲信号以及电平信号。再次强调:levl_a_in 必须是 clka 的 dff 信号!下面是更常见的,clka下的脉冲信号,同步到clkb 时钟域下,它对于clka 与 clkb的时钟频率关系没有任何限制,快到慢,慢到快都没问题。其主要原理就是先把脉冲信号在clka 下展宽,变成电平信号,再向 clkb 传递,当确认clkb 已经“看见”信号同步过去之后,再清掉 clka 下的电平信号

7、。 脉冲信号同步处理电路,有两个地方使用了上面的电平信号同步处理原则,请仔细揣摩原因。详细见下面的rtl ,其中省略了信号定义声明:module sync_pulse ( / input rst_n, / system reset clka, / clocka clkb, / clockb puls_a_in, / pulse input from clka / output puls_b_out, / pulse output in clkb levl_b_out / level output in clkb );parameter dly = 1; /always (posedge clk

8、a or negedge rst_n) begin if (rst_n = 1b0) signal_a else if (puls_a_in) signal_a else if (signal_b1_a2) signal_a else ; endalways (posedge clkb or negedge rst_n) begin if (rst_n = 1b0) signal_b else signal_b endalways (posedge clkb or negedge rst_n) begin if (rst_n = 1b0) begin signal_b_b1 signal_b_

9、b2 end else begin signal_b_b1 signal_b_b2 end endalways (posedge clka or negedge rst_n) begin if (rst_n = 1b0) begin signal_b1_a1 signal_b1_a2 end else begin signal_b1_a1 signal_b1_a2 end endassign puls_b_out = signal_b_b1 & (signal_b_b2) ; assign levl_b_out = signal_b_b1 ;endmodule 下一篇讲时钟切换电路。留

10、下一个思考题:clka 下的同一个寄存器信号signal_a ,电平宽度对clkb 而言足够长, 如果同时调用两个相同的电平同步模块向clkb 时钟传递, 分别得到levl_b1 和 levl_b2 ,那么在 clkb 时钟域下看到的lev_b1 和levl_b2 信号是否一样?这个问题是实际设计中一不小心就会犯错的,如果能够想明白正确回答这个问题,异步信号的理解就可以过关了。verilog 基本电路设计之二:时钟无缝切换(帖子链接:http:/ 住的,即使切出毛刺也不会导致 dff 误触发,这样的模块可以选择用此种切换方式。写法很简单assign clk_o = sel_clkb ? clk

11、b : clka ,当sel_clkb 为 1 时选择 clkb ,否则选择clka 。不过在实际设计中,建议直接调用库里的mux 单元 set_dont_touch ,不要采用这里的assign 写法,因为这种写法最后综合得到的可能不是 mux 而是复杂组合逻辑,给前后端流程的时钟约束和分析带来不便。 无缝切换, 就是切换时无毛刺时钟平稳过渡。在时钟切换中,只要出现比clka 或者 clkb 频率更高的窄脉冲,不论是窄的高电平还是窄的低电平,都叫时钟毛刺。工作在切换后时钟clk_o 下的电路模块,综合约束是在maxclka,clkb 频率下的, 也就是说设计最后signoff 的时候,只保证

12、电路可以稳定工作的最高频率是maxclka,clkb,如果切换中出现更高频的时钟毛刺,电路可能出现无法预知的结果而出错。无缝切换,一般用在处于工作状态的模块需要调频或者切换时钟源,比如内部系统总线,cpu 等。你刚用手机打完游戏后马上关屏听音乐,这两种场景中, cpu 在满足性能前提下为了控制功耗,其工作频率会动态地从很高调至较低,此时就可能是在cpu 一直处于工作状态下,通过无缝切换时钟源头实现的。在无缝切换电路中,切换信号sel_clkb 可以是任意时钟域下的信号,包括但不限于clka 或者 clkb 域,但是 sel_clkb 必须是一个dff 输出信号; clka与 clkb 的频率大

13、小相位关系可以任意。无缝切换需要解决两个问题,一是异步切换信号的跨时钟域同步问题,这里需要使用verilog 基本电路设计之一里的同步电路原理消除亚稳态;二是同步好了的切换信号与时钟信号如何做逻辑,才能实现无毛刺。下面写出无缝切换电路的主体部分,忽略了内部信号的定义声明等。module clk_switch ( rst_n, clka, clkb, sel_clkb, clk_o ); always (posedge clka or negedge rst_n) begin if (!rst_n) begin sel_clka_d0 sel_clka_d1 end else begin sel

14、_clka_d0 sel_clka_d1 end end/ part2 /always (posedge clka_n or negedge rst_n) always (posedge clka or negedge rst_n) begin if (!rst_n) begin sel_clka_dly1 sel_clka_dly2 sel_clka_dly3 end else begin sel_clka_dly1 sel_clka_dly2 sel_clka_dly3 end end/ part3 /always (posedge clkb_n or negedge rst_n) alw

15、ays (posedge clkb or negedge rst_n) begin if (!rst_n) begin sel_clkb_d0 sel_clkb_d1 end else begin sel_clkb_d0 sel_clkb_d1 end end/ part4 /always (posedge clkb_n or negedge rst_n) always (posedge clkb or negedge rst_n) begin if (!rst_n) begin sel_clkb_dly1 sel_clkb_dly2 sel_clkb_dly3 end else begin

16、sel_clkb_dly1 sel_clkb_dly2 sel_clkb_dly3 end end/ part5 clk_gate_xxx clk_gate_a ( .cp(clka), .en(sel_clka_dly3), .q(clka_g) .te(1b0) ); clk_gate_xxx clk_gate_b ( .cp(clkb), .en(sel_clkb_dly3), .q(clkb_g) .te(1b0) ); /assign clka_g = clka & sel_clka_dly3 ; /assign clkb_g = clkb & sel_clkb_dl

17、y3 ; assign clk_o = clka_g | clkb_g ; endmodule 上面是我认为比较合理的无缝切换电路,其他切换方式跟这个会有些许出入,但基本大同小异原理是一样的。有几点说明:1、抛开注释掉的电路不看,由于 part5 部分直接调用库里的clock gating cell,使得整个切换电路全部只需要用到时钟上升沿, 无需额外定义反向时钟, 精简了 dc 综合的时钟约束;直接调用 gating cell的 另一个好处是,前后端工具会自动检查 gating cell的 cp 信号与 en 信号的 setup/hold时间,使得 gating 后的 q 时钟输出无毛刺尖峰

18、。te 端可以根据实际需要接上scan 测试模式信号。如果使用part5 部分的gating cell实现,前面的part1,2,3,4全部替换成注释掉的反相时钟也是没有问题。2、part2 和 part4 部分,具体需要多少级 dff ,甚至完全不要也是可以的,这就回到了verilog基本电路设计之一 里讨论的到底多少级dff 消除亚稳态才算合理的问题。时钟频率很低可能无所谓,如果时钟频率达到 ghz ,这部分建议至少保留三级dff ,因为三级dff 延时也仅仅只有3ns 的时间裕度。 没必要为了省这么几个dff降低电路可靠性,在复杂ip 以及大型 soc 系统中,你会发现多几十个dff ,

19、面积上可以忽略, 系统可靠性和稳定性才是首要的。 3、如果 part5 部分希望使用注释掉的两行“与”逻辑实现时钟gating ,此时 part1 与 part3 使用正相或者反相时钟都可以,但是必须把part2 和 part4 部分改为注释掉的反相时钟实现,目的是初步从rtl 设计上避免“与”逻辑的毛刺,同时还需要后端配合,因为很多后端工具对时钟“与”逻辑的 clock gating check未必会检查。用clk 下降沿拍出的en 信号,再跟clk 做与逻辑得到的门控时钟,在rtl 仿真阶段看到的一定不会有毛刺,但是布线完成后,如果clk 相对 en 后移,那与逻辑得到的门控时钟就有毛刺了

20、。这就是用与逻辑做门控的缺点,由于后端工具可能不会去检查这个与门的时序关系而导致出错。但直接调用库里的gating cell ,工具天然就会去检查这个时序,免去人工确认的后顾之忧。最后,请大家仔细看看sel_clka_d0 (sel_clkb_dly3) 和sel_clkb_d0 verilog 基本电路设计之三:异步 fifo (帖子链接:http:/ 用于为匹配读写速度而设置的数据缓冲buffer , 当读写时钟异步时,就是异步 fifo 。多 bit 的数据信号,并不是直接从写时钟域同步到读时钟域的,而是读写时钟域分别派遣了一个信使,去通知对方时钟域,当前本方所处的读写情况,来判断还能不

21、能写以及可不可以读,这两个信使就是读写指针。在verilog 基本电路设计之一里已讨论过,即使单bit 的异步信号,通过两个相同的同步电路,达到 clkb 域时都可能“长”的不是一个模样,更加不用说多bit 的异步信号同时传递到clkb 域会变成什么五花八门的模样了。这里读写指针不是单bit 信号,它们如何向对方时钟域去同步呢?格雷码!它的特点是每次只有一个bit 发生变化, 这样就把多bit 信号同步转变为了单 bit 信号同步,这也是为什么多bit 的格雷码信号,可以类似于单bit 信号那样,直接使用两级dff 去同步的根本原因。下面给出异步fifo 的主体部分,同样,省略了信号声明定义。

22、 module asyn_fifo ( / input af_wclk , / async-fifo clear in write clock af_rclk , / async-fifo clear in read clock rst_n, / system reset af_wr_en, / async-fifo write enable af_rd_en, / async-fifo read enable af_dati, / async-fifo data in /output af_full , / async-fifo full flag af_empty, / async-fif

23、o empty flag af_dato / async-fifo data out );/- data input - assign nxt_wptr_wclk = (af_wr_en & !af_full) ? (wptr_wclk + 1b1) : wptr_wclk ; assign nxt_wptr_gray = (nxt_wptr_wclk 1) nxt_wptr_wclk ;always (posedge af_wclk or negedge rst_n) begin if (rst_n = 1b0) begin wptr_wclk wptr_gray end else

24、begin wptr_wclk wptr_gray end endreg 31:0 ram15:0 ; / always (posedge af_wclk) begin if (af_wr_en = 1b1) ramwptr_wclk3:0 else ; end/- data output - assign nxt_rptr_rclk = (af_rd_en & !af_empty) ? (rptr_rclk + 1b1) : rptr_rclk ; assign nxt_rptr_gray = (nxt_rptr_rclk 1) nxt_rptr_rclk ;always (pose

25、dge af_rclk or negedge rst_n) begin if (rst_n = 1b0) begin rptr_rclk rptr_gray end else begin rptr_rclk rptr_gray end endassign af_dato = ramrptr_rclk3:0 ;/ sync read pointer always (posedge af_wclk or negedge rst_n) begin if (rst_n = 1b0) begin rptr_sp1 rptr_sp2 end else begin rptr_sp1 rptr_sp2 end

26、 end/ sync write pointer always (posedge af_rclk or negedge rst_n) begin if (rst_n = 1b0) begin wptr_sp1 wptr_sp2 end else begin wptr_sp1 wptr_sp2 end endassign af_full = (wptr_gray = rptr_sp24,rptr_sp23,rptr_sp22:0) ; assign af_empty = (rptr_gray = wptr_sp2) ;assign wptr_bin4 = wptr_sp24 ; assign w

27、ptr_bin3 = (wptr_sp24:3) ; assign wptr_bin2 = (wptr_sp24:2) ; assign wptr_bin1 = (wptr_sp24:1) ; assign wptr_bin0 = (wptr_sp24:0) ;assign rptr_bin4 = rptr_sp24 ; assign rptr_bin3 = (rptr_sp24:3) ; assign rptr_bin2 = (rptr_sp24:2) ; assign rptr_bin1 = (rptr_sp24:1) ; assign rptr_bin0 = (rptr_sp24:0) ;assign af_wlevel = wp

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论