在KeyStone器件上实现高效的LTE上行基带前端处理
2013-12-30
作者:范伟,尹志新
来源:TI Multicore DSP / FAE
摘要
LTE上行基带前端处理包括为PUSCH、PUCCH、SRS 信道执行的FFT,以及为PRACH信道执行的时频转换。这些操作处理的是原始时域天线数据,数据量大,对计算资源和存储资源的需求都较高。文本针对TI 的KeyStone器件给出了完整的LTE 上行基带前端处理设计,目标是尽可能减少核的干预,消耗尽可能少的资源。本文还详细列出了该设计对各种硬件资源的需求,以及c66x 核上任务的实测负载。
1、引言
LTE(Long Term Evolution)是由3GPP 组织制定的3G 演进标准,在物理层采用OFDM和MIMO 技术。LTE 分为FDD 和TDD 两种双工模式。目前,LTE-FDD 在20MHz 频谱带宽下的实际速率大约能达到下行100Mbps、上行50Mbps。LTE-TDD(国内通常称为TD-LTE)的实际速率会随上、下行子帧的配比关系而变化。
[1][2][3][4]是主要的几个LTE 物理层协议文本。[1]描述了上、下行发射机从星座点调制到基带信号上变频之间的处理步骤,通常称为符号级处理。[2]描述了星座点调制之前的处理步骤,通常称为比特级处理。[3]描述了各种物理层过程。[4]描述了各种物理层测量。
LTE 的上行物理信道信道包括用来传输数据和物理层随路控制信令的PUSCH,专门用来传输物理层控制信令的PUCCH,用于随机接入的PRACH,以及用于上行信道探测的SRS。下行物理信道包括用来传输数据的PDSCH,用来传输各种物理层控制信令的控制信道PCFICH、PHICH和PDCCH。
本文描述的是LTE 上行基带前端处理。如图1 所示,LTE 上行基带前端处理包括从天线接口接收时域数据,以及随后的时频变换。LTE 中所有上行信道接收机的第一步都是把信号从时域变到频域,这是上行基带前端处理最主要的任务。PRACH 采用和其它上行物理信道不同的时频结构,因此,前端时频变换需要做两次,一次用于PRACH,一次用于其它上行物理信道。本文把前者称为“PRACH 前端时频转换”,把后者称为“上行前端FFT”。
TI 推出了一系列用于LTE 基站基带处理的SoC(System On Chip)。这些SoC 基于TI 的KeyStone 架构,该架构目前已演进了两代——KeyStone I 和KeyStone II。KeyStone I 家族基于40nm 工艺,包括如下基带SoC 器件型号:
• TCI6616,详细资料参见[5]
• TCI6618,详细资料参见[6]
• TCI6614 和TCI6612,详细资料参见[7]和[8]
• TMS320C6670,详细资料参见[9]
KeyStone II 家族基于28nm 工艺,包括如下基带SoC 器件型号:
• TCI6636K2H,详细资料参见[10]
• TCI6634K2K,详细资料参见[11]
• TCI6638K2K,详细资料参见[12]
• TCI6630K2L,详细资料参见[13]
所有这些器件都具有多模能力,支持GSM/EDGE、WCDMA、TD-SCDMA、WiMAX、LTE 的单模实现或混模实现。所有这些器件使用的DSP 核都是c66x,但个数不同。TCI6614 和TCI6612带一颗ARM Cortex A8,TCI6636K2H 和TCI6638K2K 带4 颗ARM Cortex A15,TCI6630K2L带2 颗A15,它们除支持物理层以外,还支持高层(层2,层3)和传输处理。这些器件也可用于基于OFDM的无线回传(wireless backhaul),如LTE relay 站。
本文介绍如何在上述KeyStone 器件上实现高效的LTE 上行基带前端处理。上述KeyStone 器件中,只有TCI6630K2L 包含中频处理模块,称为DFE 模块,该模块通过IQNet 模块和系统总线相连。图1 中的天线接口对TCI6630K2L 来说指的是IQNet,对其它器件来说指的是AIF2。IQNet和AIF2 都使用PktDMA 作为对内接口,行为方式类似。本文用AIF 统一指代IQNet 和AIF2,描述的前端处理方法同时适用于两者。关于KeyStone I 和II 的AIF2,请参考[14]和[15]。关于PktDMA,请参考[16]。天线接口一旦配置完毕,在实时运行过程中不需要软件干预,不产生实时负载。本文重点描述时频转换。对天线接口,仅描述其与时频转换交互的部分。
基带前端工作在基带时域采样率上,对20MHz 载波通常为30.72Msps,而系统中通常存在多个这样的数据流,对应多天线和/或多载波。对这样高速的数据流做处理,效率至关重要,应尽量减少对处理资源、存储资源、总线资源的占用。上行基带前端的处理效率是基带整体效率的重要组成部分。本文给出了在KeyStone 器件上用FFTC 硬件加速器完成尽可能多的时频转换,并将天线接口和两类时频转换用EDMA 进行直连的方法。该方法使相关的软件负载降至最低,并且尽可能地降低对内存和总线的占用。本文还给出了由c66x 和FFTC 共同完成PRACH 时频转换的方法,并给出了实测负载。该方法减少了对FFTC、内存、总线的占用,但增加了c66x 负载。用户可根据自身系统的资源消耗情况选择不同的PRACH 时频转换方法。关于EDMA,请参考[17]。关于FFTC,请参考[18]。
本文中的“符号”默认指的是OFDM符号。
2、上行前端FFT
图2 以单片TCI6634K2K 或TCI6638K2K 实现2 个8 天线TD-LTE 载扇为例,描述了上行前端FFT 的设计,包括对Tx/Rx 通道、flow、Q(本文用Q 表示硬件队列)、Tx 和Rx 描述符、Acc(本文用Acc 表示Accumulator)等物理资源的使用,以及描述符的传递路径。相关的原理和更多的细节参见以下各节。
虽然这里以单片TCI6634K2K/TCI6638K2K 实现8 天线TDD 双载扇为例,本文描述的设计实际上适用于在所有KeyStone 器件上实现各种部署场景。注意,对于TCI6634K2K/TCI6638K2K,当不要求所有载扇同时达到最高规格(比如在所有RB 上执行带信道估计时域内插的MU-MIMO IRC均衡,下行每载扇瞬时数据流量300Mbps,每载扇400 个激活用户等)且经过充分优化时,单片可支持8 天线TDD 三载扇。
该设计以一个载扇为基本设计单位。多载扇时,每个载扇使用相同的设计,但可以配置不同的硬件资源。考虑到一个FFTC 可以在一个符号周期内完成8 次带1/2 子载波频偏校正的2048 点FFT,为简单起见,要求一个载扇的上行前端FFT 处理由一个FFTC 完成。
图2 中的例子采用的物理层核间分工策略是:8 个c66x 核分为2 组,核0~3 是一组,核4~7 是另一组,每组处理一个载扇。对第一组:核0 和核1 处理PUSCH,其中信道估计按天线分工,均衡按时隙分工;核2 处理PUCCH 和PRACH;核3 处理下行和SRS,包括上行子帧最后一个符号上的SRS,以及UpPTS 内的SRS。第二组内的核间分工与第一组相同。
2.1 FFTC Tx侧设计
AIF 每收齐一根天线上的一个完整符号,就把一个包push 到一个RxQ 中。本设计假设一个载扇的NA根接收天线与基带之间的延时是相同的,则对一个符号,NA根天线对应的NA个包几乎同时被AIF 的Rx PktDMA push 到RxQ 中。为避免对Rx 描述符的回收操作,可把AIF 的RxQ 和Rx FDQ 配置成同一个Q。除了AT timer,其它关于AIF 的部分没有在图2 中画出。
AIF 和FFTC 之间的直连不是通过AIF 的Rx PktDMA 把接收包直接push 到FFTC 的TxQ 来实现的。实际上,AIF 可以通过内部的AT timer 产生符号级事件,在一个符号的NA个Rx 包被push 到RxQ 之后,立即产生一个系统事件。该事件被用于触发一个EDMA 操作,该操作把NA个包push到FFTC 的TxQ 中。称该EDMA 为FFT 入队EDMA。
对TD-LTE,AIF 可以做到只接收上行子帧和UpPTS 内的符号数据,但无法屏蔽其它符号对应的AT timer 事件。FFT 入队EDMA 接收所有的AT timer 事件,但仅为上行符号对应的事件执行入队操作。
为了给应用提供尽可能多的灵活性,为一个子帧内的每个【符号,天线】分配一个FFTC Tx 描述符,并使用描述符的PS data 承载FFTC 本地配置(Local Configuration)。记一个子帧的符号数为sym,则需要分配symNA个Tx 描述符,每个描述符的大小是64B。这样,应用可以在初始化时为每个【符号,天线】配置任意的参数,如destination Q、output scaling 等。
用Acc 对Tx return Q 中的描述符进行自动回收,但不需要产生Acc 中断或EDMA 事件。为了正常工作,Acc 要求在一个乒或乓List Buffer Page 满了之后,向Interrupt N Count 寄存器写1,作为应用对Acc 的响应。因为不需要产生Acc 事件,响应时不需要写EOI 寄存器。
结合以上几点,FFT 入队EDMA 的设计如图3 和图4 所示。
图3 以Normal CP 为例给出了FDD 时的设计。此时用到了3 个PaRAM set:PaRAM set 0 只用一次,为系统启动后的第一个上行子帧的符号执行FFTC 入队操作;PaRAM set 2 以子帧为单位被周期性地使用,为第一个上行子帧之后的所有上行符号执行入队操作;PaRAM set 1 用于在每个上行子帧开始时,响应前一个上行子帧的Acc 操作。注意,为了使Acc 操作正常,这里实际上有一个隐性前提:Acc 总能以略短于一个符号的延时处理完被FFTC 的Tx PktDMA push 进Tx return Q 的描述符。该条件在通常的Acc 负载下都能被满足。对Extended CP,只要把PaRAM set 0 和2 中的CCNT 从14 改为12 即可。
FFT 入队EDMA 在处理完入队操作后,通过chain 机制产生PRACH 触发事件,该事件将触发PRACH 前端时频转换。
图4 以“UL/DL 配置6、特殊子帧配置5~8(UpPTS 包含2 个符号)、Normal CP”为例给出了TDD 时的FFT 入队EDMA 设计。在该系统配置下,用到了8 个PaRAM set:
• PaRAM set 0 只用一次,用于消耗掉系统启动后的第一个UpPTS 之前的所有AT timer 事件,不执行有实际意义的数据搬移操作。
• PaRAM set 2 和5 以无线帧为单位被周期性地使用,分别为一个无线帧的前、后半帧中的所有上行子帧的符号执行FFTC 入队操作。
• PaRAM set 1 和4 分别为一个无线帧的前、后半帧中的UpPTS 符号执行FFTC 入队操作。
• PaRAM set 3 和6 负责消耗掉非上行符号对应的AT timer 事件。
• PaRAM set 7 响应前一个操作周期的Acc 操作,这里的操作周期指的是从一个无线帧的第一个UpPTS 开始的一个10ms。
对UL/DL 配置6,需要为前、后半帧的上行子帧集合、UpPTS、其它符号集合的AT timer 事件响应使用不同的PaRAM set,这是因为两个半帧包含的上行子帧数是不一样的。对其它所有UL/DL配置,只需要5 个PaRAM set,对应的操作周期等于上下行切换周期(UL/DL 配置0~2 是5ms,3~5 是10ms)。
不论是FDD 还是TDD,服务于上行子帧或UpPTS 的PaRAM set 使用AB-sync,每次事件触发当前上行符号的NA个Tx 描述符的FFTC 入队操作。CCNT 等于该上行子帧集合或UpPTS 包含的符号数。
上行子帧集合和UpPTS 对应的PaRAM set 使用的源buffer 的大小,以及Acc 的List Buffer Page的大小,参见图2。
对TDD,如果当前载扇使用的是长RACH(PRACH preamble 格式0~3),上行子帧中的FFT入队EDMA 在处理完入队操作后,还需通过chain 机制产生长RACH 触发事件,该事件将触发针对长RACH 的前端时频转换;如果当前扇区使用的是短RACH(PRACH preamble 格式4),UpPTS 中的FFT 入队EDMA 通过chain 机制产生短RACH 触发事件,触发针对短RACH 的前端时频转换。一个TDD 小区不会同时使用长RACH 和短RACH,因此这两类PRACH 触发事件不需要同时配置。注意,AIF 无法屏蔽非上行符号对应的AT timer 事件,但是,经过FFT 入队EDMA 的过滤,PRACH 前端时频转换功能模块只会收到上行子帧对应的符号级事件。
图5 以TDD 8 天线、normal CP 为例描述了Tx 描述符的配置。所有的配置域都是静态的,也就是说,只需要在小区建立或重配时配置,实时运行过程中无需修改。大部分配置域的取值对上行前端FFT 应用来说是确定的,也有一些域的配置具有一定程度的灵活度,可根据算法、软件框架、资源分配等方面的考虑灵活配置,这些域在图5 中用下划线标识,并说明如下。
• Return Q 和flow 根据应用的硬件资源分配进行配置。
• 为了尽可能节省内存,这个例子为AIF 接收数据使用符号级乒乓缓存。挂在Tx 描述符上的buffer 指针根据该描述符对应的【符号,天线】指向16 个buffer 中的一个。AIF 使用的是monolithic 描述符,这种描述符的净荷直接跟在描述符头的后面。为了避免数据搬移,FFTC Tx 描述符的buffer 指针直接指向AIF Rx monolithic 描述符中净荷的起始位置。注意,即使不按符号乒乓设计AIF 接收数据缓存,其它方面的设计无需变化,只影响Tx 描述符中buffer 指针的配置。
• 这个例子使用了FFTC 的动态scaling 功能,使FFT 计算过程完全不发生饱和截位,同时每步蝶形运算的输入数据都有最大有效位宽,因而获得最高的计算精度。此时,每个【符号,天线】的FFT 输出数据块的定标各不相同,应用应使能FFTC 的side information 输出,该信息包括FFTC 内部实际执行的各级scaling 的总和,应用在随后的信道估计、测量、均衡处理中应考虑到各【符号,天线】上的scaling 的不同,执行必要的定标对齐。应用也可以不使用动态scaling,直接配置各级蝶形运算之前的移位量。无论使用动态还是静态scaling,都需要配置静态的output scaling factor 参数。该参数限制了FFT 输出I/Q 分量的最大幅度,应用可根据随后的信道估计和均衡所执行的计算,分别限制导频符号和数据符号的FFT 输出最大幅度,使随后的计算在不出现饱和或溢出的情况下具有尽可能高的有效数据位宽。这个例子把output scaling factor 配置成了0x40,这使得输出数据的I/Q 分量最大幅度是Q15 定标下的1/2,也就是说,输出复样本的最大幅度是Q15 定标下的1。不使用动态scaling 时,通常不需要使能side information 输出。
• 上行前端FFT 通过将Rx 描述符push 进相应的QPend RxQ 来通知c66x 核,从而启动信道估计或均衡。在这个例子中,一个核处理天线0~3 的信道估计,另一个核处理天线4~7 的信道估计,因此:每个导频符号上的天线3 的Rx 包被push 进一个QPend Q,触发前一个核上的信道估计;每个导频符号上的天线7 的Rx 包被push 进另一个QPend Q,触发后一个核上的信道估计。另外,子帧中最后一个符号上的天线7 的Rx 包被push 进第3 个QPend Q,该QPend Q 触发均衡。剩下的所有【符号,天线】对应的Rx 包进一个General Purpose Q。对不同的核间分工,触发c66x 核的细节也会不同,但只影响Tx 描述符中的destination Q 的配置,其它方面的设计不变。
o 本设计用FFTC 提供的destination Q 本地配置域指定RxQ。其实还可以把FFTC 本地配置中的destination Q 配置成无效值(0x3FFF),然后配置多个flow,为每个flow配置不同的destination Q,并为每个【符号,天线】的Tx 描述符指定相应的flow。
o 如果一个上行子帧的最后一个符号是SRS 符号,当PUSCH 和SRS 由不同的核处理时,收到QPend 中断的PUSCH 核应向SRS 核发送核间中断,触发后者的SRS 处理。
• UpPTS 使用和上行子帧不同的flow。UpPTS 符号统一由一个核来处理,每个UpPTS 符号的最后一根天线对应的Rx 包触发对该符号的处理。UpPTS 也采用符号级乒乓缓存,且和上行子帧共用缓存,但需要注意,当UpPTS 仅含一个符号时,该符号使用的是乓(而非乒)缓存。
Front-end FFT Tx packet 0~14*8-1 for UL TTI
图5: 上行前端FFT Tx 描述符配置(例子:同图2)
2.2 FFTC Rx侧设计
在Tx 侧,在一个符号内接收到的时域天线数据可以由FFTC 在下一个符号内处理完毕,因此可以使用符号级乒乓缓存。在Rx 侧,FFTC 输出的频域数据需要被PUSCH、PUCCH、SRS 接收机处理,其中PUSCH 和PUCCH 处理不是符号级的,需要对整个子帧的数据做综合处理,且处理时间较长,理论上只要在该子帧全部收齐后1ms 内处理完即可。因此,Rx 侧数据的生存期较长,需要使用子帧级乒乓缓存。
如前所述,在图2 所示的例子中,上行前端FFT 之后,PUSCH 导频符号按天线在双核间分工,PUSCH 数据符号按时隙分工。数据符号按时隙分工的优点是:当使用IRC 均衡算法时,每个RB的所有RE 共用一个噪声干扰空间相关阵Rn,因此,把一个RB 的所有RE 的处理集中在一个核上,有利于核尽可能多地复用加载到寄存器中的Rn元素,执行效率更高;当不做时域信道估计内插时,一个子载波在一个时隙内的6 个数据RE 共用一个信道估计矩阵H,因此,把一个子载波在一个时隙内的所有RE 的处理集中在一个核上,有利于核尽可能多地复用加载到寄存器中的H元素,执行效率更高。对不同的核间分工,基本设计不变,只是Rx 描述符中的buffer 指针会有不同的配置,宗旨是尽量把FFT 输出数据直接送到将要处理该数据的那个核的LL2,以使随后的处理有尽可能高的执行效率。
和Tx 侧类似,在Rx 侧,用Acc 对Rx General Q 中的描述符进行自动回收,但不需要产生Acc中断或EDMA 事件。为了正常工作,Acc 要求在一个乒或乓List Buffer Page 满了之后,向Interrupt N Count 寄存器写1,作为应用对Acc 的响应。因为不需要产生Acc 事件,响应时不需要写EOI 寄存器。Tx 侧的响应由EDMA 完成,Rx 侧的响应由核完成。对FDD,Rx 侧的Acc 响应周期是一个子帧;对TDD UL/DL 配置0~5,响应周期是UL/DL 切换周期;对TDD UL/DL 配置6,响应周期是10ms。对FDD,Rx 侧的Acc 响应在“TTI 配置函数”中实现;对TDD,该响应在“UpPTS 配置函数”中实现。“TTI 配置函数”和“UpPTS 配置函数”的主要任务是修改Rx描述符中的动态域,并完成Rx FDQ 入队,参见后面关于Rx 描述符配置的部分。注意,Acc 不处理进入QPend Q 的Rx 描述符——如图2 所示,这些Rx 描述符的回收由中断处理函数执行。
为了尽量减少实时运行时修改Rx 描述符所引入的开销,为两个子帧内的每个【符号,天线】分配一组FFTC Rx 描述符。当软件架构要求FFT 输出的PUSCH 和PUCCH 数据分开存放时,每个Rx 包由5 个描述符链接而成;当不要求这样的PUSCH/PUCCH 数据分离时,每个Rx 包由3 个描述符链接而成。因此,总共需要分配的Rx 描述符个数是2 ∙ sym ∙ A ∙ 5或2 ∙ sym ∙ NA∙ 3。每个Rx 描述符的大小是32B。
一次FFT 的输出数据块格式如图6 所示——先是16 字节的side information(如果使能的话),然后是低频侧保护子载波,接着是PUCCH 低频侧RB、PUSCH RB、PUCCH 高频侧RB,最后是高频侧保护子载波。FFTC 的Rx PktDMA 不能自动去除两边的保护子载波。为了减少内存占用,可以让所有FFT 输出数据块的左侧和右侧保护段都输出到同一块内存中。
对PUSCH/PUCCH 数据分离的情况,图7 以动态scaling 为例描述了上行子帧Rx 描述符的配置。Rx PktDMA 为每个FFT 输出块从Rx FDQ 中pop 出5 个描述符,将这5 个描述符链接成一个Rx包,按顺序将输出数据块(包括side information)写入这5 个描述符提供的5 个buffer,再将这个包的SOP 描述符(也就是构成这个包的第一个描述符)push 到RxQ 中。因为每个上行子帧中实际承载PUCCH 的RB 数是动态变化的(实际上,频段外侧用于2 类格式的RB 数是半静态配置的,内侧用于1 类格式的RB 数动态变化的),所以,用于PUSCH 和PUCCH 的Rx 描述符中的original buffer length 域需要根据当前上行子帧实际包含的PUCCH RB 数进行修改。另外,当存在位于上行子帧的SRS 符号,且软件架构要求SRS 使用和PUSCH 最后一个数据符号不同的buffer 时,上行子帧中最后一个符号对应的用于PUSCH 的Rx 描述符中的original buffer pointer域也需要根据该符号属于PUSCH 还是SRS 动态更新。注意,SRS 符号上的PUCCH RB 数和非SRS 符号可能不同(SRS 可能使PUCCH 1 类格式采用协议中定义的shortened 格式)。上行子帧Rx 描述符动态域的修改以及它们的Rx FDQ 入队操作都在“TTI 配置函数”中完成,该函数必须在相应上行子帧开始之前、在该上行子帧之前使用相同的乒或乓描述符集合的最近上行子帧结束之后调用。为降低核负载,TTI 配置函数用EDMA 完成Rx 描述符的修改和入队,启动后无需等待传输结束,最多需要3 个EDMA 通道,分别对应非最后一个符号的Rx 描述符修改、最后一个符号的Rx 描述符修改、Rx 描述符入Rx FDQ。
在图7 中,对乒或乓,高频侧保护段的输出地址是固定的,低频侧保护段的输出地址按照FFTC实际处理的【符号,天线】顺序从左向右递进,每次增加16B,目的是保存一个子帧中每个【符号,天线】对应的side information。Side information 区域必须是子帧级乒乓的,导致保护段区域也不得不按乒乓分配。
当不要求PUSCH 和PUCCH 数据分离时,每个Rx 包由3 个描述符链接而成,PUCCH 位于每个buffer 的两侧。
图8 以动态scaling 为例描述了UpPTS Rx 描述符的配置。和上行子帧相比,UpPTS 没有PUSCH/PUCCH 分离的问题,所以一个Rx 包总是由3 个描述符链接而成,而且描述符的所有域都是静态域,不需要动态修改。UpPTS Rx 描述符的Rx FDQ 入队操作在“UpPTS 配置函数”中完成,该函数必须在相应UpPTS 开始之前、前一个UpPTS 结束之后调用。为降低核负载,用EDMA 完成描述符入队。注意,对TDD UL/DL 配置6,“UpPTS 配置函数”每半帧调一次,但Rx 侧Acc 响应每10ms 只需执行一次。
图9 以单片TCI6634K2K/TCI6638K2K 实现3 载扇为例描述了从QPend 事件到核中断的传递路径实例。在这个例子中:
• 分配给每载扇的3 个QPend Q 的Q 编号分别是652/653/654、655/656/657、658/659/660。
• 每个核的QPend 中断索引都是10。
• 核0/1、2/3、4/5 分别处理三个载扇的PUSCH。PUSCH 导频符号按天线分工,数据符号按时隙分工。每对核中的第一个核只需接收导频符号上第NA⁄2 − 1(从0 开始编号)根天线对应的QPend 中断(触发信道估计,而均衡可以在第二个时隙的信道估计完成后立即执行);第二个核既要接收导频符号上最后一根天线对应的QPend 中断(触发信道估计),还要接收最后一个数据符号上最后一根天线对应的QPend 中断(触发均衡)。
• 核6 处理前载扇0 和2 的PUCCH,核7 处理载扇1 的PUCCH。因此,每个QPend Q 654/657/660 事件要传递到2 个核(载扇0 是核1 和核6,载扇1 是核3 和核7,载扇2 是核5 和核6)。
关于TCI6634K2K/TCI6638K2K 的内部事件路由,参见[19]。关于CIC(Chip Interrupt Controller),参见[20]。
2.3硬件资源需求
对每个载扇,上行前端FFT 所需的硬件资源如下:
• 1 个FFTC 实例。
• 该FFTC 实例上的1 个Tx/Rx 通道(和该FFTC 实例的一个TxQ 绑定)。
• 1 个用于上行子帧的flow。TDD 时,还需1 个用于UpPTS 的flow。
• 1 个Tx return Q,1 个用于上行子帧的Rx FDQ,1 个Rx General Q,若干个Rx QPend Q(具体个数由核间分工确定,比如:当PUSCH 双核处理,PUCCH 在另一个核上处理时,需要3 个;当单核处理单载扇时,只需1 个)。TDD 时,还需1 个用于UpPTS 的Rx FDQ。
• symA个用于上行子帧的Tx 描述符。TDD 时,还需UpPTS,symA个用于UpPTS 的Tx 描述符。每个Tx 描述符的大小是64B。
• 2 ∙ sym ∙ A ∙ 5(要求PUSCH/PUCCH 数据分离时)或2 ∙ sym ∙ A ∙ 3(不要求数据分离时)个用于上行子帧的Rx 描述符。TDD 时,还需UpPTS,sym ∙ A ∙ 3个用于UpPTS 的Rx 描述符。每个Rx 描述符的大小是32B。
• 用于Tx 和Rx 描述符回收的Acc 所使用的PDSP 实例。
• 用于Tx 描述符回收的Accumulator 通道,用于Rx 描述符回收的Accumulator 通道。
• Tx 侧TxQ 入队EDMA 用到的1 个CC 实例,1 个TC 实例,1 个EDMA 通道,3(FDD)、5(TDD UL/DL 配置0~5)或8(TDD UL/DL 配置6)个PaRAM set。
• Rx 侧为上行子帧用到了3 个EDMA 通道,分别对应非最后一个符号的Rx 描述符修改、最后一个符号的Rx 描述符修改、Rx FDQ 入队。每类操作涉及1 个CC 实例,1 个TC 实例,1个EDMA 通道,1 个PaRAM set。Rx FDQ 入队也可以改用QDMA,其它两类操作涉及3D搬移,只能用EDMA。TDD 时,只要在使用时间上不冲突,针对上行子帧和针对UpPTS 的操作可以合用一套资源。
• Acc 内存资源:
o 用于Tx 描述符回收的List Buffer Page:
l FDD 时,以子帧为单位乒乓,总大小为字节。
l TDD UL/DL 配置0~5 时,以UL/DL 切换周期为单位乒乓,总大小为字节,其中TTI表示一个UL/DL 切换周期包含的上行子帧数。
l TDD UL/DL 配置6 时,以10ms 为单位乒乓,总大小为字节。
o 用于Rx 描述符回收的List Buffer Page:
l FDD 时,以子帧为单位乒乓,总大小为字节,其中TTI,QPend表示一个上行子帧中进入QPend Q 的Rx 包个数。
l TDD UL/DL 配置0~5 时,以UL/DL 切换周期为单位乒乓,总大小为字节,其中UpPTS,QPend表示一个UpPTS 中进入QPend Q 的Rx 包个数。
l TDD UL/DL 配置6 时,以10ms 为单位乒乓,总大小为字节。
只要处理能力足够,多个载扇可以共用一个FFTC 实例、一个CC 甚至TC 实例。多扇区通常共用一个Acc PDSP 实例。所有用于通知某个核或某组核的QPend 事件可以来自同一个QPend Q,软件通过从中pop 出的描述符地址辨别事件类型。其它资源通常不适合多载扇共用,需要为每个载扇单独分配。
2.4 C66x核负载测量
采用本设计,大部分配置工作在小区建立或重配时完成,需要在实时运行过程中调用的函数仅限于TTI 配置函数和UpPTS 配置函数。表1 给出了TTI 配置函数的实测cycle 数。TTI 配置函数的任务主要是响应Acc 以及配置/启动用于Rx 描述符修改和入队的3 个EDMA,因为无需等待EDMA 传输结束,所以该函数的负载和天线数无关。UpPTS 配置函数的负载比TTI 配置函数更低,此处从略。本测试使用TCI6638K2K EVM;L1P/L1D cache 初始状态都为cold,也就是说,函数开始执行时,代码和数据都不在L1 cache 中。
3、PRACH前端时频转换
图10 给出了PRACH 接收机的流程图,本章描述的PRACH 前端时频转换包括去CP 和转换至频域这两个步骤。
本文用短RACH 指代PRACH preamble 格式4,用长RACH 指代其它格式。表2 给出了各种小区带宽情况下,长、短RACH 的前端时频转换所需的DFT 原始长度。下面分情况描述时频转换方案设计:
• 长RACH:
o 对20、15、10MHz 小区,FFTC 不支持DFT 原始长度,需要采用间接的时频转换法,具体分为两种:
l 大点DFT 法。该方法主要使用FFTC,辅以少量的核处理,直接完成一个大点数的DFT。参见3.1 节。
l 混合法。该方法使用核完成下变频和滤波降采样,然后用FFTC 在降低后的采样率上执行小点DFT。参见3.2 节。
o 对更窄带宽的小区,可以直接用FFTC 执行DFT。参见3.3 节。
•短RACH:
o 总是可以直接用FFTC 执行DFT。参见3.4 节。
3.1长RACH——大点DFT法
本节先描述原理,再给出实现方案。
3.1.1原理
一个长度为N 的序列()的N 点DFT 定义为
其中是时间索引,是频率索引,。大点DFT 法直接实现一个长度超过FFTC 支持范围的FFT。用于实现快速DFT 的FFT 算法通常可以分为时域抽取法(DIT)和频域抽取法(DIF)两类。当计算完整的DFT 时,DIT 和DIF 的计算复杂度是一样的。但是,PRACH 前端时频转换实际上只需要计算一部分X(),比如,对20MHz 小区、频域仅1 个opportunity 的情况,N=24576,但真正需要的X()只有839 点。通过对比分析可知,只有DIT 可以利用到这个应用特性降低核负载。因此,我们选择采用DIT 法。
DIT 法将一个N 点DFT 分解成P 个N/P 点DFT 的方式为
定义() = (P ∙ + );= 0,1,⋯,N⁄P − 1,下标= 0,1,⋯, P − 1,定义F()是()的N/P点DFT,并注意到= WN⁄P,可得
进一步地,定义= ′+ ′∙ N⁄P,′= 0,1,⋯,N⁄P − 1,′= 0,1,⋯, P − 1,因为F()以N/P 为周期,且X()可以拆分成如下的多个表达式
其中′= 0,1,⋯,N⁄P − 1。这组表达式可以用图11 表示,并描述如下:
1. 对输入N 点序列做P 点抽取,获得P 个子序列,每个子序列的长度是N/P。
2. 分别对P 个子序列做N/P 点DFT 运算,得到F(),= 0,1,⋯, P − 1,= 0,1,⋯,N⁄P − 1
3. 第p 个子序列F()点乘。
4. 对第3 步输出的P 个子序列,执行P 点“块DFT”,相当于每次取P 个子序列相同位置上的点,构成一个P 点序列,然后对该P 点序列执行P 点DFT,第m 次P 点DFT 输出的P 个结果对应X(), X(+ N/P),⋯, X(+ (P − 1) ∙ N/P)。
对20MHz 小区,按照FFTC 支持的DFT 长度对整个24576 点序列做分割,有24576 = 8192*3 =6144*4 = 4096*6 = 3072*8 = 2048*12 = ……,对应的抽取因子P 分别是3、4、6、8、12 等。对P 的选取应综合考虑以下因素:
• C66x 核负载。P 越大,步骤3 和4 涉及的计算量就越大。
• 抽取EDMA 的配置复杂度。如前一章所述,AIF 收到的上行时域天线数据是按符号乒乓缓存的,为了用EDMA 完成P 点抽取,最直接的方法是在FFT 入队EDMA 完成后,触发另一个EDMA 把当前符号的时域数据以P 点抽取的方式搬到别的地方去。为了EDMA 配置的简单性,一个符号内的样本数最好是P 的倍数。对20M小区、normal CP 场景,为了满足此需要,P只能等于1、2、4、8、16。
• FFTC 执行效率。根据[21],1GHz KeyStone 器件上的一个FFTC 的流量在DFT 长度为8192、6144、4096、3072、2048 时分别为378、360、437、413、431 Msps。不同长度对应的流量有较为可观的差异,比如,4096 点时的流量比6144 点时高21.4%。
综合考虑以上因素,本文推荐使用P=4 作为20MHz 小区的抽取因子,对应6144 点DFT。对15和10MHz 小区,假设采样率按带宽等比下降,则PRACH 序列长度从20M 时的24576 降为18432 和12288。对这两类小区带宽,分别使用P=3 和2,而保持6144 作为DFT 点数。这样的选择偏向更轻的核负载和EDMA 配置简单性,牺牲了一些FFTC 执行效率。
3.1.2实现
如上所述,基于DIT 的大点DFT 有4 个处理步骤。实现时,步骤1(P 点抽取)由EDMA 完成,步骤2 由FFTC 完成,步骤3 和4 由c66x 核完成。
抽取EDMA 需要用到2 个EDMA 通道,分别称为trigger 通道和working 通道。图12 以“TDD UL/DL 配置1,PRACH 配置10,20MHz,Normal CP”为例给出了抽取EDMA 的配置细节。
根据附录A,在该系统配置下,trigger 通道需要7 个EDMA PaRAM set 来响应上行前端FFT 产生的长RACH 触发事件。第1 个PaRAM set 只用一次,用于响应系统初始化后最初的若干上行子帧符号对应的事件。之后的6 个PaRAM set 以10ms 为周期重复使用,用于处理该系统配置下一个无线帧包含的3 个opportunity,以及相邻opportunity 之间不承载PRACH 数据的上行子帧符号。对不承载PRACH 的上行子帧符号,相应的长RACH 触发事件不触发实际操作,本文称这样不承载实际数据搬移任务的EDMA 为dummy 类型的EDMA。对承载PRACH 的上行子帧符号,相应的长RACH 触发事件通过trigger 通道的chain 机制间接触发working 通道,并且在触发working 通道之前先用trigger 通道修改working 通道将要用到的PaRAM set 中的符号级动态域。
Working 通道需要NA + 3个PaRAM set。第1 个PaRAM set 只用到1 次,属于dummy 类型的。后面的NA + 2个PaRAM set 以link 加self-chain 的方式,以上行子帧符号为周期重复使用。对每个上行子帧符号,先执行1 个dummy 类型的PaRAM set,用于确保trigger 通道对接下来的NA + 1个PaRAM set 的动态域的修改已经完成。接下来的NA个PaRAM set 用于完成NA根天线的P 点抽取。最后1 个PaRAM set 用于在整个序列的最后一个符号处执行FFTC TxQ 入队操作,非序列最后一个符号对应的该PaRAM set 属于dummy 类型。
Working 通道的后NA + 1个PaRAM set 中的动态域包括SRC、DST 和BCNT。Trigger 通道为每个上行子帧符号执行一次对这NA + 1个working 通道PaRAM set 的动态更新,数据源位于内存中,称为PaRAM set LUT,其内容在小区初始化或重配时由驱动软件配置。
对图12 示例之外的其它系统配置,基本原理是类似的,但细节上有一些差别。
• Trigger 通道用到的PaRAM set 个数等于附录A 表格中“EDMA 分段”列给出的值加1。
• Trigger 通道的每个PaRAM set 负责响应的上行子帧符号数等于附录A 表格中“初始Dummy符号数”列或“EDMA 段内符号数”列给出的值。对dummy 类型的PaRAM set,这个值配置到BCNT;对其它PaRAM set,配置到CCNT。
• 对PRACH 格式0 和1,一个抽取目的buffer 包含1 个PRACH 序列,仅需为最后一个符号执行FFTC 入队操作。对PRACH 格式2 和3,一个抽取目的buffer 包含2 个序列。此时,为了在一个序列收齐之后立刻启动FFTC,需要为每个序列的最后一个符号执行FFTC 入队操作。这些都通过配置PaRAM set LUT 实现。
• 对PRACH 格式0,如果两个相邻的上行子帧都承载了PRACH,需要分配两个抽取目的buffer,以子帧为单位乒乓使用。此时,每个buffer 有自己的PaRAM set LUT。对其它PRACH 格式,一个buffer 就够了,但格式2 和3 的一个buffer 实际上包含2 个序列。
• 对PRACH 格式2 和3,不能把一个opportunity 的两个序列的抽取输出连续排列,这是因为DCIDX 域最大只有16 位(包括符号位),连续排列的话正好超出了表达范围。
• 对PRACH 格式2 和3,为了让两个序列各自放在连续的内存中,需要对两个序列交接处的那个符号的抽取EDMA 做特殊处理。为此,对working 通道,在原有的NA + 3个PaRAM set的基础上增加NA个,这些新增的PaRAM set 不需要动态更新,负责处理交接符号中属于后一个序列的部分的抽取,而原有的用于抽取的NA个PaRAM set 现在只处理属于前一个序列的部分。这两组PaRAM set 以相互交织的方式link 和self-chain,为此,LINK 必须成为动态更新域,以便动态改变link 目标。
步骤2,也就是6144 点DFT,由FFTC 完成。这一步采用原位操作以节省内存。推荐采用动态scaling,此时每个6144 点的buffer 需要在头部多留出16B 以容纳FFTC 输出的side information。
步骤3 和4 由核实现。一个PRACH opportunity 在频域占用6 个RB,但并不是整个6 RB 带宽都被PRACH 占用,因为两侧有相同宽度的保护频带。图13 给出了一个例子,其中,PRACH 导频子载波被标记为红色。
对FDD,每小区在一个特定时刻最多只有1 个opportunity,其起始物理RB 索引是其中,表示半静态的PRACH 频偏参数。
对TDD,一个小区在一个特定时刻可以有多个opportunity,其中第RA个opportunity 的起始物理RB 索引是其中表示小区上行RB 数。
假设一个PRACH opportunity 的起始物理RB 索引是以20MHz 小区为例,它的第一个子载波在整个24576 点DFT 输出中的位置是
参考图11,假设该起始位置落在第0 ∈[0, P − 1]个大点DFT 输出块内,在该块内的内部偏移是O0,则如果O0≤6144 − 839 = 5305,这个opportunity位于一个大点DFT 输出块内;否则,这个opportunity 跨越2 个大点DFT 输出块,其最后O0− 5305个点位于块1 = (0 + 1) mod 6的起始处。
如果该opportunity 位于一个输出块内,核执行下面的计算
如果跨越2 个块,计算
当FFTC 为步骤2 执行动态scaling 时,核在处理步骤3 和4 时,除了上述公式描述的计算,还要执行定标对齐。
3.1.3硬件资源需求
对每个载扇,PRACH 前端时频转换所需的硬件资源如下:
• 1 个FFTC 实例。
• 该FFTC 实例上的1 个Tx/Rx 通道(和该FFTC 实例的一个TxQ 绑定)。
• 1 个flow。
• 1 个Tx return Q,1 个Rx FDQ,1 个Rx QPend Q。
• X ∙ S∙ A ∙ P个Tx 描述符,其中S表示一个opportunity 中的序列个数,X表示前面所说的抽取目的buffer 个数(1 或2,仅格式0 在部分配置下取2)。每个Tx 描述符的大小是32B。
• Rx 描述符的个数和Tx 描述符一样。每个Rx 描述符的大小是32B。
• 抽取EDMA 用到的1 个CC 实例,1 个TC 实例,2 个EDMA 通道。Trigger 通道需要的PaRAM set 个数等于附录A 表格的“EDMA 分段”列取值加1,最大值等于11,发生在TDD UL/DL 配置0、PRACH 配置为15/16/17 时。对PRACH 格式0 或1,working 通道需要NA + 3个PaRAM set;对格式2 或3,需要2NA + 3个。
• 用于控制的内存资源:
o PaRAM set LUT,PRACH 格式0 或1 时的大小是X ∙ ∙ (A + 1) ∙ 12字节,格式2 或3 时的大小是∙ (A + 1) ∙ 20字节,其中表示一个opportunity 的序列部分占用的符号数,如附录A 中的表4 所示。
o 描述符地址数组(用于PRACH 前端FFTC 入队的源buffer),大小是Tx 描述符个数乘以4 字节。
只要处理能力足够,多个载扇可以共用一个FFTC 实例、一个CC 甚至TC 实例。所有用于通知某个核或某组核的QPend 事件可以来自同一个QPend Q,软件通过从中pop 出的描述符地址辨别事件类型。其它资源通常不适合多载扇共用,需要为每个载扇单独分配。
3.1.4负载测量
步骤3 和4 在c66x 核上的硬件实测负载如表3 所示,对应一个opportunity。如果在频域有多个opportunity,则总cycle 数要乘以opportunity 个数。本测试使用TMS320C6670 EVM,内存配置是:输入、输出buffer 都位于LL2;L1P/L1D cache 初始状态都为cold,也就是说,函数开始执行时,代码和数据都不在L1 cache 中。
3.2增大Cboot电容的风险分析
混合法的原理如图14 所示。C66x 核负责下变频和低通滤波抽取,并启动FFTC 完成降采样序列的DFT。当频域有多个opportunity 时,为每个opportunity 分别执行整个处理流程。降采样后的序列长度等于1536,20、15、10MHz 小区分别对应16、12、8 倍降采样。
图14: 混合法原理
C66x 核处理任务可以每符号执行一次,也可以在一个PRACH 序列收集完毕后执行一次。前者的优点是节省内存;缺点是由多任务相互打断而导致的cache 开销和任务切换开销,由“重叠相加”或“重叠保留”分段滤波带来的额外计算量,以及更频繁的中断开销。反之,后者的优点是核开销较低,缺点是需要更多的内存。对后者,如果因片内内存不够而需要把PRACH 序列收集buffer放到DDR,则核开销方面的优点可能会被更低的内存访问效率抵消。
采用逐符号处理时,PRACH 前端EDMA 配置和图12 之间的区别是:
• 只用到了trigger 通道,working 通道及其PaRAM set 不再需要。
• 原本用于触发working 通道的事件现在用于触发核中断,相应的PaRAM set 仅做dummy 数据搬运。
采用逐序列处理时,PRACH 前端EDMA 配置和图12 之间的区别是:
• PaRAM set LUT 中的配置参数对应连续内存搬移,而非抽取操作。
• Working 通道用于FFTC 入队的PaRAM set 不再需要,而它之前的那个PaRAM set 的final事件不仅触发self-chain 事件,还产生核中断。
下变频和低通滤波抽取在c66x 核上的硬件实测负载为:一个opportunity、一个序列、一根天线上的cycle 数是55,958。本测试使用TMS320C6670 EVM,系统参数和内存配置是:20MHz 小区,32 阶滤波器;分为12 段按重叠相加法处理;输入、输出buffer 都位于LL2;L1P/L1D cache 初始状态都为cold。注意,这里测量的负载没有包含多任务互相打断而导致的额外开销。
3.3长RACH——直接DFT
5、3、1.4MHz 小区中的长RACH 使用直接DFT,因为根据表2,这些小区带宽下的DFT 原始长度可以被FFTC 直接处理。此时,PRACH 前端EDMA 配置类似图12,唯一的区别是PaRAM set LUT 中的配置参数对应连续内存搬移,而非抽取操作。
直接DFT 没有实时c66x 核开销。
3.4短RACH
UpPTS 的长度可以是1 或2 个符号,而短RACH 仅在UpPTS 长度是2 个符号时才允许存在。短RACH 在UE 侧UpPTS 结束点之前4832Ts 处发射,CP 长度是448Ts,序列部分从第1 个UpPTS 符号的0Ts(normal CP)或736Ts(extended CP)开始,长度是4096Ts。
如图4 所示,前端FFT 入队EDMA 可以为UpPTS 中的每个符号产生一个短RACH 事件,该事件触发短RACH 的working 通道,完成数据搬移和FFTC 入队。短RACH 的working 通道使用4 个PaRAM set,第一个用于初始dummy,接下来的两个分别用于两个符号的数据搬移,最后一个用于FFTC 入队。
对每个载扇,短RACH 前端时频转换所需的硬件资源如下:
• 1 个FFTC 实例。
• 该FFTC 实例上的1 个Tx/Rx 通道(和该FFTC 实例的一个TxQ 绑定)。
• 1 个flow。
• 1 个Tx return Q,1 个Rx FDQ,1 个Rx QPend Q。
• NA个Tx 描述符。每个Tx 描述符的大小是32B。
• Rx 描述符的个数和Tx 描述符一样。每个Rx 描述符的大小是32B。
• 数据搬移EDMA 用到的1 个CC 实例,1 个TC 实例,1 个EDMA 通道,4 个PaRAM set。
• 用于控制的内存资源:
o 描述符地址数组(用于短RACH 前端FFTC 入队的源buffer),大小是Tx 描述符个数乘以4 字节。
只要处理能力足够,多个载扇可以共用一个FFTC 实例、一个CC 甚至TC 实例。所有用于通知某个核或某组核的QPend 事件可以来自同一个QPend Q,软件通过从中pop 出的描述符地址辨别事件类型。其它资源通常不适合多载扇共用,需要为每个载扇单独分配。
4、小结
本文详细描述了在TI 的KeyStone 器件上实现高效的LTE 上行基带前端处理的方法,包括对常规前端FFT 的处理和对PRACH 前端时频转换的处理,并给出了实测的c66x 核负载。
从本文的描述可见,KeyStone 架构提供的EDMA 和Navigator 机制非常灵活,可以把数据搬运、加速器启动、核触发等操作步骤串联成一个可自动执行的整体流程,极大降低了对核实时干预的需求。
当输入数据位于DDR 时,FFTC 的执行效率较低。因此,对PRACH 前端处理,建议把从符号级乒乓缓存搬移出来的数据放在片内。
对PRACH 前端处理,大点DFT 法比混合法节省10 倍以上的核负载。当FFTC 和片内存储资源足够时(比如对小基站),大点DFT 较为合适。在其它情况下,哪种方法合适需要根据系统对c66x 核、FFTC、内存的使用情况选择。
参考资料
[1] 3GPP TS-36.211
[2] 3GPP TS-36.212
[3] 3GPP TS-36.213
[4] 3GPP TS-36.214
[5] http://www.ti.com/product/tms320tci6616
[6] http://www.ti.com/product/tms320tci6618
[7] http://www.ti.com/product/tms320tci6614
[8] http://www.ti.com/product/tms320tci6612
[9] http://www.ti.com/product/tms320c6670
[10] http://www.ti.com/product/tci6636k2h
[11] http://www.ti.com/product/tci6634k2k
[12] http://www.ti.com/product/tci6638k2k
[13] http://www.ti.com/product/tci6630k2l
[14] KeyStone Architecture Antenna Interface 2 (AIF2) User Guide (SPRUGV7)
[15] KeyStone II Architecture Antenna Interface 2 (AIF2) User Guide (SPRUHL2)
[16] Multicore Navigator User Guide (SPRUGR9)
[17] Enhanced Direct Memory Access (EDMA3) Controller User Guide (SPRUGS5)
[18] Fast Fourier Transform Coprocessor (FFTC) User Guide (SPRUGS2)
[19] TCI6638K2K Data Manual (SPRS836)
[20] KeyStone Architecture Chip Interrupt Controller (CIC) User Guide (SPRUGW4)
[21] Throughput Performance Guide for TCI66x KeyStone Devices (SPRABH2)
附录A:PRACH 分布与EDMA 参数
表5 到表12 分别给出了FDD 以及7 种TDD UL/DL 配置下的PRACH 分布描述表。解释如下。
• “缓存数”一列描述每种配置下需要的缓存个数,等于1 或2,2 表示需要乒乓缓存。对于PRACH 格式2 和3,每个opportunity 包含2 个序列,1 个缓存对应一个opportunity,而非一个序列。格式2 和3 时,缓存数总是等于1,为了强调该缓存实际上要容纳2 个序列,在表中用“1’”标识。当缓存数等于1 时,这个唯一的缓存用1 编号;当缓存数等于2 时,两个缓存分别用1 和2 编号。确定缓存数时,假设系统能够在“下下个”序列到达前处理完当前序列的时频转换。
• 假设系统启动后总是从一个无线帧的第一个子帧开始接收天线数据,则一开始会有若干个上行子帧符号不承载PRACH 数据,这些上行子帧符号的个数在“初始Dummy 符号数”一列给出。注意,如前所述,经过FFT 入队EDMA 的过滤,PRACH 前端时频转换功能模块只会收到上行子帧对应的符号级事件。
• 经过初始阶段的不承载PRACH 数据的若干个符号后,随后的PRACH 时域承载模式按周期重复,每个周期包含若干个EDMA 分段,在“EDMA 分段”一列给出。1 表示该分段内的符号数据被EDMA 搬运到缓存1,2 表示该分段内的符号数据被EDMA 搬运到缓存2,0 表示在该分段内不执行实际的天线数据搬运,只是消耗长RACH 触发事件。“EDMA 段内符号数”一列给出每个EDMA 分段中的上行子帧符号数。
表示一个上行子帧内的符号数,(= , , , )表示格式的一个opportunity 中的1 或2 个序列跨越的总符号数,表示格式的一个opportunity 从起始子帧的头部到序列开始前不承载PRACH 的符号数(字母h 表示head),表示格式的一个opportunity 从序列结束后到结束子帧的末尾的不承载PRACH 的符号数(字母t 表示tail)。
• 表4 给出两种CP 模式下,这些变量的取值。