Verdvana

空持千百偈 不如吃茶去

可編程逻辑常用设计思想与技巧

08 Jan 2020 » Digital IC Design, FPGA

1 前言

        FPGA的设计思想和技巧多种多样,这里选四个有代表性的方法加以简要介绍。


2 乒乓操作

        “乒乓操作”是一个常常应用于数据流控制的处理技巧,典型的乒乓操作如下图:

1

        输入数据流通过“输入数据流选择单元”,等时地将数据流分配到两个数据缓冲模块。数据缓冲模块可以是任何存储模块,比较常用的存储单元为双口RAM、单口RAM和FIFO等。

        在第一个缓冲周期,将输入的数据流缓存到“数据缓冲模块1”。

        在第二个缓冲周期,通过“输入数据流选择单元”的切换,将输入的数据流缓存到“数据缓冲模块2”,与此同时,“数据缓冲模块1”缓存的第一个周期的数据通过“输出数据流选择单元”的选择,送到“数据流运算处理模块”被运算处理。

        第三个缓冲周期,通过“输入数据流选择单元”的再次切换,将输入的数据流缓存到“数据缓冲模块1”,与此同时,将“数据缓冲模块2”缓存的第2个周期的数据通过“输出数据流选择单元”的切换,送到“数据流运算处理模块”被运算处理。如此循环,周而复始。

        乒乓操作的最大特点是,通过“输入数据流选择单元”和“输出数据流选择单元”按节拍、相互配合地切换,将经过缓冲的数据流没有时间停顿的送到“数据流运算处理模块”,被运算与处理。把乒乓操作模块当作一个整体,站在这个模块的两端看数据,输入数据流和输出数据流都是连续不断的,没有任何停顿,非常适合对数据流进行流水线式处理,所以乒乓操作常常应用与流水线式算法,完成数据的无缝缓冲与处理。

        乒乓操作的另一个优点是可以解决缓冲区空间。比如在WCDMA基带应用中,1帧是由15个时隙(Slot)组成的,有时需要将1整帧的数据演示一个时隙后处理,比较直接的办法是将这帧数据缓存起来,然后延时1个时隙进行处理。这时缓冲区的长度是1整帧数据长,假设数据速率是3.84Mbit/s,1帧长10ms,则此时需要缓冲区长度是38400bit。如果采用乒乓操作,只需定义两个能缓冲1个Slot数据的RAM(单口RAM即可),当向一块RAM写数据时,从另一块RAM读数据,然后送到处理单元处理,此时,每块RAM的容量仅需2560bit,两块RAM加起来也只有5120bit容量。

        另外,巧妙的运用乒乓操作,还可以达到用低速模块处理高速数据流的效果:

2

        如上图所示,数据缓冲模块采用了双口RAM,并在DPRAM后引入了一级数据预处理模块,这个数据预处理可根据需要进行各种数据运算,比如在WCDMA设计中,对输入数据流的解扩、解扰、去旋转等。假设端口A的输入数据流的速率为100Mbit/s,乒乓操作的缓冲周期是10ms,下面分析以下各节点端口的数据速率。

        输入数据流A端口处数据速率为100Mbit/s,在第一个缓冲周期10ms内,通过“输入数据流选择单元”,从B到达DPRAM1。B1的数据速率也是100Mbit/s,在10ms内,DPRAM1要写入1Mbit/s数据。同理在第2个10ms,数据流被切换到DPRAM2,端口B2的数据速率也为100Mbit/s,DPRAM2在第2个10ms被写入1Mbit数据。周而复始,在第3个10ms,数据流有切换到DPRAM1,DPRAM1被写入1Mbit数据。

        仔细分析一下,就会发现到第3个缓冲周期时,留给DPRAM1读取数据并送到“数据预处理模块1”的时间一共是20ms。对于DPRAM1的读数时间是20ms,是由如下方法实现的:首先在第2个缓冲周期,向DPPAM2写数据的10ms内,DPRAM1可以进行读操作;在第1个缓冲周期的第5ms起(绝对时间为5ms时刻),DPRAM1就可以边向500kbit以后的地址写数据,边从地址0读数,到达10ms时,DPRAM1刚好洗完了1Mbit数据,并且读了500kbit数据,这个缓冲时间内DPRAM1读了5ms的时间;在第3个缓冲周期的第5ms起(绝对时间为35ms时刻),同理可以边向500kbit以后的地址写数,边从地址0读数,又读取了5个ms,截止到DPRAM1第1个周期存入的数据被完全覆盖以前,DPRAM1最多可以读取20ms时间,而所需读取的数据为1Mb,所以端口C1的数据速率为1Mbit/20ms=50Mbit/s,因此“数据预处理模块1”的最低数据吞吐能力也仅仅要求为50Mbit/s。同理,“数据预处理模块2”的最低数据吞吐能力也仅仅要求为50Mbit/s。换言之,通过乒乓操作,“数据预处理模块”的时序压力减轻了,所要求的数据处理速率仅仅为输入数据速率的1/2。

        通过乒乓操作实现低速模块处理高速数据的实质是通过DPRAM这种缓存单元,实现了数据流的串并转换,并行用“数据预处理模块1”和“数据预处理模块2”处理分流的数据,是面积与速度互换原则的又一体现。


3 串并转换

        串并转换是FPGA设计的一个重要思想,从小的着眼点讲,他是数据流处理的常用手段;从大的着眼点将,他是面积与速度互换思想的直接体现。总的来说,将串行轉換為并行,一般旨在通过复制逻辑,提高整个设计的数据吞吐率,其本质是通过面积的消耗提高工作速率;而将并行转换为串行,一般旨在节约资源,因为设计速度有足够余量,通过提高串行通道的工作速率而节约了面积,其本质是通过速度的提高节约芯片面积。SERDES技术就是串并转换的一个最典型体现。

        数据流串并转换的实现方法多种多样,根据数据的排序和数量要求,可选用寄存器、RAM等实现。

        对于排列顺序有规定的串并转换,可以用case语句判断实现;对于复杂的串并转换,还可以用状态机实现。


4 流水线操作

        这里所讲的流水线是指一种处理流程和顺序操作的设计思想,并非FPGA、ASIC设计中优化时序所用的“Pipelining”。

        流水线处理是高速设计中的一个常用的设计手段。如果某个设计的处理流程分为若干步骤,而整个数据处理是“单流向”的,既没有反馈或者迭代运算,前一个步骤输出是下一个步骤的输入,则可以考虑采用流水线按设计方法提高系统的工作频率。

        具体原理和实现可以看之前的文章:硬件算法之流水线结构

        流水线的设计关键在于整个设计时序的合理安排、前后级接口间数据流速的匹配,这就要求每个操作步骤的划分必须合理,要统筹考虑各个操作步骤间的数据流量。如果前级操作时间恰好等于后级操作时间,设计最为简单,前级的输出直接汇入后级的输入即可;如果前级的操作时间小于后级的操作时间,则需要对前级的输出数据适当缓存,才能汇入后级,还必须注意速率的匹配,防止后级数据的溢出;如果前级操作时间大于后级操作时间。则必须通过逻辑复制、串并转换等手段将数据流分流,或者在前级对数据采用存储、后处理方式,否则会造成与后级的处理节拍不匹配。

        流水线处理方式之所以频率较高,是因为复制了处理模块,它是面积换取速度思想的又一种具体体现。


5 异步时钟域数据同步

        异步时钟域数据同步是FPGA/CPLD设计的一个常见问题,既是一个重点也是一个难点,很多设计工作时的不稳定都是源于异步时钟域数据同步不稳定。

5.1 两类异步时钟域同步的表现形式

        异步时钟域数据同步也被称为数据接口同步,顾名思义,又指如何在两个时钟不同的数据域之间可靠地进行数据交换的问题。数据的时钟域不同步主要有以下两种情况:

  • 两个时钟域频率相同,但是相差不固定,或者相差固定但不可测,简称同频异相问题;
  • 两个时钟域频率不同,简称异频问题。

5.2 两种不推荐的异步时钟域操作方法

        首先讨论两种在FPGA/CPLD设计中不推荐的异步时钟域转换方法,一种是通过增加Buffer或其他们演示调整采样,另一种是盲目使用时钟正负沿调整数据采样。

  • 通过Buffer等组合逻辑延迟线调整采样时间:
    • 在早期逻辑电路图设计阶段,有一些设计者养成了手工加入Buffer或非门调整数据延迟的习惯,从而保证本级模块的时钟对上级模块数据的建立、保持时间的要求。这些做法目前主要应用的场合有两种,一是使用分立逻辑元件(如74系列)搭建数字逻辑电路,另一种是在ASIC设计领域。目前使用分立逻辑元件搭建数字逻辑电路的场合一般为系统复杂度相对较低,系统灵活性要求不高的场合。在上述场合使用分立逻辑器件设计数字逻辑电路,由于可以使用的调整延时的手段相对有限,而且采用插入Buffer、数字延迟逻辑甚至两个非门等手段调整采样的Setup和Hold时间是可以接受。而ASIC设计领域采用这种方法是以严格的仿真和约束条件作为强力支持的。
    • 而使用组合逻辑方法产生延迟,容易产生毛刺,而且这种设计方法的时序余量较差,一旦外界条件变换,采样时序就有可能完全问了,造成电路瘫痪。另外,一旦芯片更新换代,或者移植到其他器件族的芯片上,采样延时必须重新调整,电路的可维护性和继承性都很差。
  • 盲目使用时钟正负沿调整数据采样:
    • 很多初学者习惯随意使用时钟的正负沿调整采样,甚至产生一系列不同相位或不同占空比的时钟,使用其正负沿调整时钟。这种做法是不推荐的,原因如下:
      • 如果在一个时钟周期内,使用时钟的双延同时操作,则使用该时钟的同相倍频时钟也能实现相同的功能。此时因为设计的时钟频率提升,所有相关的使用约束都会变得更紧,不利于可靠实现;
      • 在FPGA中,一般PLL和DLL都能较好的保证某个时钟沿的Jitter,Skew和占空比等各种参数指标,而对于另一个时钟沿的指标控制并不是那么严格。特别对于综合、实现等EDA软件,如果没有明确对另外一个沿进行相关,这个沿的时序分析不一定完善,其综合或实现结果就不一定能严格满足用户期望的时序要求,往往造成该沿操作不稳定的结果。
    • 如果设计者并不十分清楚,同时使用上下沿,不如直接使用同相倍频时钟更加简单、明确、可靠;如果设计者十分清楚同一时期使用双沿的注意事项,附加了相应的约束,这种做法并非不可。
    • 还要补充三点:
      • 使用者虽然使用了同一个时钟的两个沿,但没有在同一个周期内同时使用双沿,则不会增加时钟频率;
      • 关于ASIC的DDR和QDR。DDR、QDR本身就是利用了上下沿采样的原理,这是因为,存储器高速发展,时钟速度已經成為存储器件的瓶颈,所以可用时钟上下沿操作缓解对Single edge RAM时钟振荡器的要求。但是大家必须清楚,DDR,QDR的时钟电路都是专用高速设计电路。对视中的正沿及负沿的Jitter、Skew和占空比等指标都有详细和明确的要求,这一点是和FPGA中的情况完全不同的。这是ASIC芯片中DDR和QDR的设计方法。
      • 关于FPGA内部的DDR、QDR 接口。目前所有主流FPGA都支持DDR接口,Altera和Lattice的DDR接口电路还支持自动调整DQS采样DQ的功能。FPGA的DDR接口电路通过专用硬件电路和相关的约束解决时序瓶颈。

5.3 异步时钟域数据同步常用方法

        下面分别介绍前面提出的两大异步时钟域数据同步问题的解决方法:

  • 同频异相问题:最简单的解决办法是用后级时钟对前级数据采样两次,即通常所说的用寄存器打两次。这种做法有效的减少了亚稳态的传播,使后级电路数据都是有效电平值。但是这种做法并不能保证两级寄存器采样后的数据是正确的电平值,因为一旦Setup或Hold时间不满足,采样发生亚稳态,则经判决时间(Resolution Time)后,可能判决到错误电平值。所以这种方法仅适用与对少量错误不敏感的功能。可靠的做法是用DPRAM、FIFO或者一段寄存器Buffer完成异步时钟域的数据转换。方法是:将上级芯片提供的数据随路时钟作为写信号,将数据写入DPRAM或者FIFO,然后使用本级的采样时钟(一般是数据处理的主时钟)将数据读出即可。由于时钟频率相同,因此DPRAM或FIFO两端的数据吞吐率一致,实现起来相对简单。
  • 异频问题:可靠地完成异频问题的解决办法就是使用DPRAM和FIFO。其实现思路与前面所述一致,用上级随路时钟写上级数据,然后用本级时钟读出数据。由于时钟频率不同,因此两个端口的数据吞吐率不一致,设计时一定要开好缓冲区,并通过监控(Full、Half、Empty)确保数据流不会溢出

5.4 异步时钟域数据同步时使用Altera PLL时钟的注意事项

        在不同时钟域间交换数据时,除了需要注意异步时钟域数据同步所注意事项外,还要注意以下问题:

  • 同步同型时钟域之间的数据交换:
            如果两个PLL时钟是由同一个PLL产生的同类型的时钟(如都是全局时钟,或都是区域性时钟),则这两个时钟域之间的register-to-register数据交换最为简单,不需要附加任何逻辑,在这情况下,使用一级寄存器采样就能完成数据的同步化过程,不会产生错误电平和亚稳态的传播。
  • 同步异型时钟域之间的数据交换:
            如果两个时钟是由不同的PLL产生,或者是不同类型的时钟(一个是全局时钟,一个是区域性时钟),且他们由无延时或相位差的同样的时钟源来驱动,则在进行数据交换时,数据路径上必须插入至少一级LE,以保证两个寄存器能够通过本地互连线资源连接。
  • 异步时钟域之间的数据交换:
            如果是完全异步的时钟域间的数据交换,需要使用DPRAM或FIFO完成,可以简单地绕过异步时钟域数据同步的握手和错误电平或亚稳态等问题。

5.5 亚稳态

        异步时钟域转换的核心就是要保证下级时钟对上级数据采样的Setup时间和Hold时间。如果触发器的Setup时间或Hold时间不满足,就可能产生亚稳态,此时触发器输出端Q在有效时钟沿知乎比较长的一段时间内处于不确定状态,在这段时间内Q端产生毛刺并不断振荡,最终固定在某一电压值,此电压值并不一定等于原来数据输入端D的数值,这段时间称为决断时间(Resolution Time)。经过Resolution Time之后Q端将稳定到0或1上,但究竟是0还是1,这是随机的,与输入没有必然联系。

        亚稳态的危害主要体现在破坏系统的稳定性。由于输出在稳定下来之前可能是毛刺、振荡或固定的某一电压值,因此亚稳态将导致逻辑误判,严重情况下输出0~1之间的中间电压值还会使下一级产生亚稳态,导致亚稳态的传播。逻辑误判导致功能性错误,而亚稳态的传播则扩大了故障面。另外,在亚稳态状态下,任何诸如环境噪声,电源干扰等细微扰动都将导致更恶劣的状态不稳定,这是这个系统的传输延迟增大,状态输出错误,在某些情况下甚至会使寄存器在两个有效判定门限(VoL、VoH)之间长时间地振荡。

        只要系统中有异步元件,亚稳态就无法避免,因此设计的电路首先要减少亚稳态导致的错误,其次要使系统对产生的错误不敏感。前者要靠同步设计来实现,而后者根据不同的设计应用有不同的处理方法。

        使用两级寄存器采用可以有效的减少亚稳态继续传播的概率,但并不能保证第二级输出的稳态就是正确电平。前面说过经过Resolution Time之后寄存器输出电平是一个不确定的稳态值,也就是说这种处理方法并不能排除采样错误的产生,这时就要求所设计的系统对采样错误有一定的容忍度。有些应用本身就对采样错误不敏感,如一帧图像编码,一段语音编码;而有些系统对错误采样比较敏感,这类由于亚稳态造成的采样是一些突发的错误,所以可以采用一些纠错编码手段完成错误的纠正


        告辞。