当前位置:   article > 正文

串行/解串器的设计_串解器

串解器

 

 

 

 

PCIe总线是用来取代PCI总线的新型串行总线协议。这个与将要设计的串行解串器类似。对于利用串行解串器来进行数据传输的两个系统,要发送的数据会先被保存下来,然后被送入到一个缓冲区内(即FIFO),接着,它们被串行化,然后一个一个比特地被发送给目标系统。在接收端,输入的串行数据被解串,然后再次保存到缓冲区内,并按照并行的格式被发送到接收系统的并行总线上,为了实现数据的同步,接收端必须从接收的串行数据中提取出数据的有效时钟信息。这里的时钟其实和接收数据的帧边界其实是同一个概念,整个串行/解串器的结构如图所示:

SerDes原理图

先从时钟源设计开始:

一个典型的锁相环(PLL)由以下三部分构成:输出时钟产生器,可变频率振荡器(VFO)。PLL会比较输入时钟相位和VFO时钟的差别,并根据这个差别来调整VFO产生的时钟的频率,其原理图如下:

我们用目标库中速度最快的延迟单元来完成 这个可以工作很高时钟下的振荡器的设计,在verilog方面主要体现在以下两方面:1.用generate来表示线延迟;2.添加DC的set_dont_touch来阻止综合工具把我们认为增加的线延迟给优化掉;

 

 

把这个振荡器命名为FsatClock,并作为时钟驱动计数器,把计数器的门限值VaryFreq,用来控制VFO的时钟频率。

VFO的内部的比较器将计数值与计数器的溢出门限值VaryFreq相比较,当计数值达到门限值,计数器被复位。

以上我们可以得到一个32x的PLL,32xPLL受到1MHz的时钟驱动,并且采样VFO的PLL输出。设置两个计数器,一个是被外部的PLL1MHz的输入时钟驱动,另一个是被PLL内部的P1MHZ的溢出计数器产生的时钟驱动,每个时钟到来时把计数值进行比较,从而得到两个时钟的相对关系。只要两个计数值不相等就会去调整VFO的频率。这两个2比特的计数器对32xPLL Muounter计数器产生时钟输出连续计数,在每一个PLL时钟的上升沿,对应边沿的计数值都用来做比较,从而产生乐调整VFO且及时更新的调整量。模块Zeroer不断检测ClockIn的计数值,当计数值为3时,计数器同时清零。

模块的代码如下:

1.Top

  1. module PLLTop (output ClockOut, input ClockIn, Reset);
  2. //
  3. wire[1:0] AdjFreq;
  4. wire MHz32, CtrCarry;
  5. //
  6. // -----------------------------------------------
  7. // The new sample edge generator:
  8. wire SampleWire;
  9. //
  10. DEL005 SampleDelay1 (.Z(SampleWire), .I(ClockIn));
  11. //
  12. //synopsys dc_tcl_script_begin
  13. // set_dont_touch SampleDelay1
  14. // set_dont_touch SampleWire
  15. // set_dont_touch ClockIn
  16. //synopsys dc_tcl_script_end
  17. //
  18. // -----------------------------------------------
  19. assign ClockOut = MHz32;
  20. //
  21. ClockComparator
  22. Comp1 ( .AdjustFreq(AdjFreq), .ClockIn(ClockIn)
  23. , .CounterClock(CtrCarry), .Reset(Reset)
  24. );
  25. //
  26. VFO
  27. VFO1 ( .ClockOut(MHz32), .AdjustFreq(AdjFreq)
  28. , .Sample(SampleWire), .Reset(Reset)
  29. );
  30. //
  31. MultiCounter
  32. MCntr1 (.CarryOut(CtrCarry), .Clock(MHz32), .Reset(Reset));
  33. //
  34. endmodule // PLLTop.
  35. //

2.VFO

  1. // The timescale and VFO_MaxDelta from the Deserializer
  2. // design are used in VFO:
  3. //
  4. `include "SerDes.inc"
  5. //
  6. // ---------------------------------------------------
  7. // The empirical frequency-setting parameters:
  8. // DivideFactor is the number of fast-counter increments
  9. // per PLL output clock. Thus, PLL output period is
  10. // given by: T = 2*DivideFactor*ElemDelay, in which,
  11. //
  12. // ElemDelay = DelayElementAvgDelay
  13. //
  14. // ElemDelay is estimated in ns, averaged over rise &
  15. // fall, and it is used in VCS message calculations as
  16. // well as VFO frequency limit stops.
  17. //
  18. // ---------------------------------------------------
  19. // The next macro configures the FastClock oscillator and
  20. // FastDivvy counter (2 elems probably is too fast for
  21. // DEL005 and 90-nm Typical gates):
  22. //
  23. `define NumElems 5 // Delay line length.
  24. //
  25. // ---------------------------------------------------
  26. // We use the PLL multiplication factor, 32, to set the
  27. // initial DivideFactor.
  28. // We want to divide the frequency, and the delay line
  29. // just gives edge delays, so the initial divide factor
  30. // should be about 1/4 the PLL multiplication factor:
  31. //
  32. `define ElemDelay 0.0850 // Delay element avg. delay.
  33. `define DivideFactor 32.0/(4.0*`NumElems*`ElemDelay)
  34. //
  35. // NFastBits will be calculated to ensure that the
  36. // frequency initialization value (`DivideFactor) will
  37. // be less than the maximum value of the FastDivvy and
  38. // DivideFactor regs declared below.
  39. // ---------------------------------------------------
  40. module VFO (output ClockOut, input[1:0] AdjustFreq
  41. , input Sample, Reset
  42. );
  43. reg ClockOutReg;
  44. assign ClockOut = ClockOutReg;
  45. //
  46. // Configure the fast clock counter:
  47. localparam NFastBits =
  48. (`DivideFactor < (2**3 - (`VFO_MaxDelta/(2.0*`ElemDelay) + 1)) )? 3
  49. : (`DivideFactor < (2**4 - (`VFO_MaxDelta/(2.0*`ElemDelay) + 1)) )? 4
  50. : (`DivideFactor < (2**5 - (`VFO_MaxDelta/(2.0*`ElemDelay) + 1)) )? 5
  51. : (`DivideFactor < (2**6 - (`VFO_MaxDelta/(2.0*`ElemDelay) + 1)) )? 6
  52. : (`DivideFactor < (2**7 - (`VFO_MaxDelta/(2.0*`ElemDelay) + 1)) )? 7
  53. : (`DivideFactor < (2**8 - (`VFO_MaxDelta/(2.0*`ElemDelay) + 1)) )? 8
  54. : 9;
  55. //
  56. localparam[NFastBits-1:0] DivideLoLim = `DivideFactor - `VFO_MaxDelta;
  57. localparam[NFastBits-1:0] DivideHiLim = `DivideFactor + `VFO_MaxDelta;
  58. //
  59. // Assertions:
  60. `ifdef DC
  61. `else
  62. initial
  63. begin
  64. $display("VFO FastClock delay chain: %0.0f cells @%1.4f ns; f divider=[%0.0f] bits.\n"
  65. , `NumElems, `ElemDelay, NFastBits
  66. );
  67. $display("VFO divide factor=%0.0f; so, initial SYNTH 1 MHz in => %2.1f MHz out.\n"
  68. , `DivideFactor, 1000.0/32.0
  69. );
  70. $display("`VFO_MaxDelta=[%0.0f] => Divider limits: Low Lim=%0.0f and High Lim=%0.0f.\n"
  71. , `VFO_MaxDelta, DivideLoLim, DivideHiLim
  72. );
  73. end
  74. `endif
  75. //
  76. // ---------------------------
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/820053
推荐阅读
相关标签
  

闽ICP备14008679号