主要内容

设计支持反向通道链路训练的DDR5 IBIS-AMI模型金宝app

这个示例展示了如何使用与IBIS 7.0规范中定义的方法类似的方法创建支持链路训练通信(反向通道)的发送器和接收器AMI模型,方法是将其添加到Ser金宝appDes Toolbox™中的库块中。本例使用DDR5写入传输(控制器到SDRAM)来演示设置。

介绍

IBIS 7.0通过为Tx和Rx AMI可执行模型提供在gewave操作期间通信的机制,引入了模型执行链路训练或自动协商的能力。链路训练算法可以模拟硅正在做什么,或者它可以使用通道分析方法来确定最佳的Tx和Rx均衡设置,然后锁定这些设置用于模拟的其余部分。

Tx和Rx可执行模型之间的通信是Tx和Rx可执行模型都能理解的消息,而EDA工具不需要理解。这些商定的消息称为后信道接口协议。IBIS规范没有描述反向通道接口协议的细节,而只是描述了一种使通信工作的方法。在本例中,我们将生成一个名为DDRx_Write的新协议。

目前,SerDes工具箱不直接支持IBIS-AMI反向通道接口保留参数金宝app。相反,它支持特定于模型的金宝app参数,这些参数的名称后面附加了“_ST”,执行类似的功能。由于这些特定于模型的参数不使用与IBIS规范中的保留参数相同的名称,因此必须将它们用作“匹配集”或与支持相同协议的SerDes Toolbox开发的其他反向通道模型一起使用。金宝app这些模型应该在任何工业标准AMI模型模拟器中都能很好地工作。

DDR5 Tx/Rx IBIS-AMI模型设置在SerDes设计器应用程序

本示例的第一部分从DDR5控制器发送器模型开始DDR5控制器发射器/接收器IBIS-AMI型号和SDRAM接收机AMI模型DDR5 SDRAM发送/接收IBIS-AMI型号。我们添加了一些额外的直通块来支持反向通道通信,然后您将模型导出到Simulink®以进行进一步定制。金宝app金宝app

打开模型DDR5_Write_txrx_ami在MATLAB®命令窗口中输入以下命令:

>>serdesDesigner(“DDR5_Write_txrx_ami”)

对于写事务,发送器(Tx)是使用3分路前馈均衡(FFE)的DDR5控制器,而接收器(Rx)使用具有7个预定义设置的可变增益放大器(VGA)和带有内置时钟数据恢复的4分路决策反馈均衡器(DFE)。为了支金宝app持这种配置,SerDes系统的设置如下:

配置设置

  • 符号时间设为208.3p,因为目标开工率是4.8DDR5-4800的Gbps。

  • 系统设为100年e-18

  • 信号设为单端

  • 每个符号的样本调制保持默认值,它们是16NRZ(不返回零)。

发射机型号设置

  • 直通块Tx_BCI是用于支持此反向通道实现的块。金宝app这个块的操作将在后面的示例中描述。

  • Tx FFE块设置为一个预抽头,一个主抽头和一个后抽头,包括三个抽头权重。这是通过数组[0 1 0]完成的,其中主抽头由数组中的最大值指定。当模型导出到Simulink时,Tap范围将在后面的示例中添加。金宝app

  • 设置Tx模拟输出模型,以便电压1.1V,上升时间One hundred.ps,R(输出电阻)为50 o号,C(电容)0.65最终模型中使用的实际模拟模型将在本示例后面生成。

通道模型设置

  • 频道损失设为5dB,这是典型的DDR信道。

  • 单端阻抗设为40欧姆。

  • 目标频率设为2.4这是奈奎斯特的4.8 GHz频率

接收机型号设置

  • Rx AnalogIn模型的设置是这样的R(输入电阻)为40欧姆,C(电容)0.65 pf。最终模型中使用的实际模拟模型稍后将在本示例中生成。

  • Pass-Through块Rx_BCI_Read是一个用于支持此反向通道实现的块。金宝app这个块的操作将在后面的示例中描述。

  • VGA块设置为获得1和模式设置为开启。在模型导出到Simulink后,将在稍后的示例中添加特定的VGA预设。金宝app

  • DFECDR块为四个DFE抽头设置,包括四个初始抽头重量设置为0。的最小抽头值设为[-0.2 -0.075 -0.06 -0.045]V和最大抽头值设为[0.05 0.075 0.06 0.045]五、DFE已配置为使用2倍丝锥权重,以便与JEDEC DFE丝锥定义一致。

  • 直通块Rx_BCI_Write是一个用于支持这种反向通道实现的块。金宝app这个块的操作将在后面的示例中描述。

导出服务器系统到Simulink金宝app

点击出口按钮,将配置导出到Simulink,以便进一步定制和生成AMI模型可执行文件金宝app。

DDR5 Tx/Rx IBIS-AMI模型的Simulink建立金宝app

本部分示例采用SerDes Designer应用程序导出的SerDes系统,并根据需要在Simulink中定制DDR5反向通道操作。金宝app

回顾Simul金宝appink模型设置

导入到Simulink中的SerDes系统由配置、刺激、Tx、模金宝app拟通道和Rx块组成。所有的设置从SerDes设计器应用程序转移到Simulink模型。金宝app保存模型并检查每个块设置。

  • 在Tx子系统中,双击FFE块打开FFE块参数对话框。扩大IBIS-AMI参数然后取消选择模式参数,有效地硬编码的当前值模式在最终的AMI模型中固定

  • 在Rx子系统中,双击VGA块打开VGA块参数对话框。的模式获得设置是从SerDes Designer应用程序继承过来的。

  • 在Rx子系统中,双击DFECDR块打开DFECDR块参数对话框。的初始抽头重量最小DFE抽头值最大抽头值RMS设置是从SerDes Designer应用程序继承过来的自适应增益自适应步长设置为3 e-061 e-06,这是基于DDR5 SDRAM预期的合理值。扩大IBIS-AMI参数和取消选择相抵消引用偏移量参数,有效地将这些参数硬编码为它们的当前值。

更新发射器(Tx) AMI参数

打开AMI -Tx选项卡中的“SerDes IBIS-AMI Manager”对话框。首先列出保留参数,然后是遵循典型AMI文件格式的特定于模型的参数。

  • 设置预强调:编辑TapWeights 1并设置格式范围Typ0最小值-0.2,马克斯0.2

  • 设置主按键:编辑TapWeights 0并设置格式范围Typ1最小值0.6,马克斯1

  • 设置强调键:编辑TapWeights 1并设置格式范围Typ0最小值-0.2,马克斯0.2

创建新的Tx反向通道AMI参数

为了支金宝app持反向通道操作,需要额外的控制参数。在AMI -Tx选项卡,突出显示Tx_BCI并添加以下6个新参数:

  • FFE_Tapm1:该参数创建一个数据存储,用于在训练期间在Tx块之间传递FFE预tap值。单击添加参数…按钮。集参数名称FFE_Tapm1当前值0使用InOut类型浮动,格式价值。设置描述为:Tx FFE Tap -1用于反向通道培训。保存更改并注意,这会自动在Tx_BCI PassThrough块中创建数据存储。

  • FFE_Tap0:该参数创建一个数据存储,用于在训练期间在Tx块之间传递FFE主tap值。单击添加参数…按钮。集参数名称FFE_Tap0当前值0使用InOut类型浮动,格式价值。设置描述为:Tx FFE点击0进行反向通道培训。保存更改。

  • FFE_Tap1:该参数创建一个数据存储,用于在训练期间在Tx块之间传递FFE post tap值。单击添加参数…按钮。集参数名称FFE_Tap1当前值0使用InOut类型浮动,格式价值。设置描述为:Tx FFE点击1进行反向通道培训。保存更改。

  • BCI_Protocol_ST:该参数仅用于在.ami文件中生成一个名为“BCI_Protocol_ST”的参数,以部分遵守IBIS-AMI规范。此模型不使用此参数。单击添加参数…按钮。集参数名称BCI_Protocol_ST当前值DDRx_Write”使用信息类型字符串,格式价值。设置描述为:该模型支持DDRx写示金宝app例反向通道协议。注意:这个模型目前不支持保留参数BCI_Protocol作为模型的输入。金宝app保存更改。

  • BCI_ID_ST:该参数仅用于在.ami文件中生成一个名为“BCI_ID_ST”的参数,以部分遵守IBIS-AMI规范。此模型不使用此参数。单击添加参数…按钮。集参数名称BCI_ID_ST当前值“bci_comm”使用信息类型字符串,格式价值。设置描述为:该模型创建的文件名称以“bci_comm”开头,用于反向通道通信。注意:这个模型目前不支持AMI保留参数BCI_ID作为模型的输入。金宝app保存更改。

  • BCI_State_ST:该参数用于创建一个数据存储,该数据存储用于通知back-channel训练的状态:1=Off, 2= training, 3=Converged, 4=Failed, 5=Error。单击添加参数…按钮。集参数名称BCI_State_ST使用InOut类型整数,格式列表。设置描述为:后通道培训状态。注意:这个模型目前不支持AMI保留的参数BCI_State作为模型的输入金宝app。设置默认的2列表值[1 2 3 4 5),而List_Tip值[“关闭”“训练”“融合”“失败”“错误”],然后设置当前值“培训”。保存更改。

更新Receiver (Rx) AMI参数

AMI-Rx选项卡中,保留参数首先列出,然后是遵循典型AMI文件格式的特定于模型的参数。

  • 设置VGA增益:编辑获得。集描述为:Rx放大器增益。确保格式设为列表并设置默认为1。集列表值作为[0.5 0.631 0.794 1 1.259 1.585 2]List_Tip值作为[" 6 dB”“4 dB”“2 dB”“0分贝”“2 dB”“4 dB”“6 dB”),然后设置当前值0分贝。保存更改。

  • 设置第一个DFE轻击权重:编辑TapWeights 1。确保格式设为范围并设置Typ=0最小值=-0.2,马克斯=0.05。保存更改。

  • 设置第二个DFE轻击权重:编辑TapWeights 2。确保格式设为范围并设置Typ=0最小值=-0.075,马克斯=0.075。保存更改。

  • 设置第三次DFE轻击重量:编辑TapWeights 3。确保格式设为范围并设置Typ=0最小值=-0.06,马克斯=0.06。保存更改。

  • 设置第四个DFE轻击权重:编辑TapWeights 4。确保格式设为范围并设置Typ=0最小值=-0.045,马克斯=0.045。保存更改。

创建新的Rx反向通道AMI参数

为了支金宝app持反向通道操作,需要额外的控制参数。在AMI -处方选项卡,突出显示Rx_BCI_Write并添加以下新参数(注:Rx_BCI_Read不需要任何额外参数):

  • sampleVoltage:该参数创建一个数据存储,用于在训练期间将CDR样本电压传递给其他Rx块。单击添加参数…按钮。集参数名称sampleVoltage当前值0使用InOut类型浮动,格式价值。设置描述为:反向通道训练的样本电压。保存更改并注意,这会自动在Rx_BCI_Write PassThrough块中创建数据存储。

  • BCI_Protocol_ST:该参数仅在.ami文件中生成一个名为“BCI_Protocol_ST”的参数,以部分遵守IBIS-AMI规范。此模型不使用此参数。单击添加参数…按钮。集参数名称BCI_Protocol_ST当前值DDRx_Write”使用信息类型字符串,格式价值。设置描述为:该模型支持DDRx写示金宝app例反向通道协议。注意:这个模型目前不支持AMI保留的参数BCI_Protocol作为模型金宝app的输入。保存更改。

  • BCI_ID_ST:该参数仅在.ami文件中生成一个名为“BCI_ID_ST”的参数,以部分遵守IBIS-AMI规范。此模型不使用此参数。单击添加参数…按钮。集参数名称BCI_ID_ST当前值“bci_comm”,使用信息类型字符串,格式价值。设置描述T:他的模型创建了名称以“bci_comm”开头的文件,用于反向通道通信。注意:这个模型目前不支持保留参数BCI_ID作为模型的输入金宝app。保存更改。

  • BCI_State_ST:该参数用于创建一个数据存储,该数据存储用于通知back-channel训练的状态:1=Off, 2= training, 3=Converged, 4=Failed, 5=Error。单击添加参数…按钮。集参数名称BCI_State_ST使用InOut类型整数,格式列表。设置描述为:后通道培训状态。注意:这个模型目前不支持AMI保留的参数BCI_State作为模型的输入金宝app。设置默认的2列表值[1 2 3 4 5),而List_Tip值[“关闭”“训练”“融合”“失败”“错误”],然后设置当前值“培训”。保存更改。

  • BCI_Message_Interval_UI_ST:该参数仅在.ami文件中生成一个名为“BCI_Message_Interval_UI”的参数,以部分遵守IBIS-AMI规范。此模型不使用此参数。单击添加参数…按钮。集参数名称BCI_Message_Interval_UI_ST当前值64使用信息类型整数,格式价值。设置描述:这BCI模型需要每比特1024个样本才能正常运行。保存更改。

  • BCI_Training_UI_ST:该参数仅在.ami文件中生成一个名为“BCI_Training_U_STI”的参数,以部分遵守IBIS-AMI规范。此模型不使用此参数。单击添加参数…按钮。集参数名称BCI_Training_UI_ST当前值100000使用信息类型整数,格式价值。设置描述为:BCI培训可能需要10万UI才能完成。注意:这个模型目前不支持AMI保留的参数BCI_Training_UI作金宝app为模型的输入。保存更改。

运行Refresh Init

要传播所有新的AMI参数,请在Tx和Rx块上运行Refresh Init。

  • 双击Tx块中的Init子系统,然后单击刷新Init按钮。

  • 双击Rx块中的Init子系统,然后单击刷新Init按钮。

运行模型

运行模型以模拟SerDes系统,并验证当前设置是否编译并运行,没有错误或警告。生成了两个图。第一个是实时时域(GetWave)眼图,随着模型运行而更新。第二个图包含四个统计(Init)结果视图,就像SerDes Designer App中可用的图一样,加上两个来自时域(GetWave)结果的视图。

注意:您可以忽略未连接块的任何警告。这是由于自动生成的数据存储块,稍后将对其进行寻址。

提供的文件

需要三套外部文件来支持后台培训。金宝app这些文件的生成超出了本示例的范围,因此将它们包含在本示例中。在运行完整的SerDes系统或生成AMI模型可执行文件之前,将以下9个文件下载到模型目录(Simulink .slx文件的位置)。金宝app

写入反向通道通信文件

这三个文件用于将后通道训练参数和眼指标的当前状态写入外部文件,以便在Tx和Rx AMI模型之间进行通信。

  • MATLAB函数文件:writeBCIfile.m

  • 代码源所需的c++文件:writeamidata.cppwriteamidata.h

从反向通道通信文件中读取

这三个文件用于从外部文件中读取反向通道训练参数和眼睛度量的当前状态,用于Tx和Rx AMI模型之间的通信。

  • MATLAB函数文件:readBCIfile.m

  • 代码源所需的c++文件:readamidata.cppreadamidata.h

写入回通道日志文件

这三个文件用于在每个训练步骤后将反向通道训练参数和眼指标的当前状态写入日志文件以供调试。

  • MATLAB函数文件:writeBCIhistory.m

  • 代码源所需的c++文件:writebcihist.cppwritebcihist.h

修改Tx FFE以启用Tap值的外部控制

当启用反向通道训练时,要从Tx_BCI块控制Tx FFE分接权重,请替换FFEParameter。TapWeights常量块与DataStoreRead块。该数据存储允许在模拟期间更改FFE接点值,并将其传入和传出每个数据路径块。

在Tx子系统中,单击FFE块并键入Ctrl-U在FFE块的面具下看。

  1. 删除FFETapWeights Constant块。

  2. 添加一个DataStoreRead块标记BCIFFETapWeightsIn

  3. 双击DataStoreRead块,设置数据存储名称为:Tx_BCISignal

  4. 在Element Selection选项卡上,展开信号tx_bcissignal并突出显示FFE_Tapm1, FFE_Tap0FFE_Tap1

  5. 按下选择> >按钮选择这3个元素。

  6. 保存更改。

添加一个Mux块,并将输入数量设置为3,以将这三个参数复用为FFE块的矢量。

将Mux模块的输出连接到FFE上的TapWeights输入。

最终的FFE块应该如下所示:

类型ctrl - d编译模型并检查错误。您可以忽略未连接块的任何警告。这是由于自动生成的数据存储块,稍后将对其进行寻址

修改DFECDR输出眼样电压

为了在反向通道训练期间确定一组给定均衡值的质量,将使用CDR在每个符号的眼睛中心采样的电压。此值由DataStoreWrite块捕获,以便其值可用于其他BCI控制块。

在Rx子系统中,单击DFECDR块并键入Ctrl-U来查看Rx DFECDR块的掩码。

打开BusSelector对象

  1. 突出voltageSample从总线中的元素列表中获取。

  2. 打击选择> >将其移动到Selected元素列表中。

  3. 保存更改。

添加一个DataStoreWrite块标记:CDR采样电压

  1. 双击DataStoreWrite块,设置数据存储名称为:Rx_BCI_WriteSignal在Parameters选项卡上。

  2. 在Element Assignment选项卡上,展开信号Rx_BCI_WriteSignal并突出显示sampleVoltage

  3. 按下选择> >按钮以选择此元素。

  4. 保存更改。

将BusSelector的voltageSample输出连接到新DataStoreWrite块的输入。

DFECDR块的这一部分应该如下所示:

类型ctrl - d编译模型并检查错误。您可以忽略未连接块的任何警告。这是由于自动生成的数据存储块,稍后将对其进行寻址

当启用训练时,修改DFECDR以覆盖模式

在反向通道训练时,FFE和DFE模式都需要设置为“固定”。FFE模式已硬编码为“固定”。一个简单的MATLAB函数用于允许您在未启用训练时设置DFE模式。

在Rx子系统中,单击DFECDR块并键入Ctrl-U来查看Rx DFECDR块的掩码。

删除DFECDRMode块与DFECDR的连接。

添加一个新的MATLAB函数块并将标签设置为DFEModeSelect。这个函数块读取BCI_State_ST和DFE的值。模式和forces the DFE Mode to 1 (Fixed) when training is enabled or completed. Copy/Paste the following code into the DFEModeSelect MATLAB function block, replacing the default contents.

function Mode = DFEModeSelect(DFEModeIn, BCI_State_In)如果BCI_State_In == 1 % Training is Off Mode = DFEModeIn;else Mode = 1;强制DFE模式固定为所有其他训练状态结束

添加一个DataStoreRead块标记Rx_BCI_Write_BCI_State_In,因此BCI_State_ST的值可以被送入MATLAB函数块。

  1. 双击DataStoreRead块,设置数据存储名称为:Rx_BCI_WriteSignal

  2. 在Element Selection选项卡上,展开信号Rx_BCI_WriteSignal并突出显示BCI_State_ST

  3. 按下选择> >按钮选择此元素。

  4. 保存更改。

如图所示连接这些新块。最终的DFECDR块应该如下所示:

类型ctrl - d编译模型并检查错误。您可以忽略未连接块的任何警告。这是由于自动生成的数据存储块,稍后将对其进行寻址

设置Tx Init自定义代码

Tx Initialize函数用于建立Tx AMI模型,以便在GetWave分析过程中运行反向通道训练。这将创建反向通道通信和日志文件,设置各种参数并覆盖任何用户定义的FFE tap值。

在Tx子系统中,双击Init块,然后单击显示初始化打开MATLAB中的Initialize函数。

初始化函数是一个自动生成的函数,它提供了SerDes系统块(IBIS AMI-Init)的脉冲响应处理。的% %开始:%结束:线条表示可以输入自定义用户代码的部分。当Refresh Init运行时,不覆盖本节中的数据。

%% BEGIN:自定义用户代码区域(当'Refresh Init'按钮被按下时保留)Tx_BCIBCI_State_ST = Tx_BCIParameter.BCI_State_ST;%用户从服务器中添加AMI参数IBIS-AMI Manager Tx_BCIFFE_Tap0 = Tx_BCIParameter.FFE_Tap0;%用户从服务器中添加AMI参数IBIS-AMI Manager Tx_BCIFFE_Tap1 = Tx_BCIParameter.FFE_Tap1;%用户从服务器中添加AMI参数IBIS-AMI Manager Tx_BCIFFE_Tapm1 = Tx_BCIParameter.FFE_Tapm1;%用户从SerDes中添加AMI参数IBIS-AMI Manager % END:自定义用户代码区域(在按下Refresh Init按钮时保留)

使用此自定义用户代码区域初始化反向通道参数,在反向通道通信文件“BCI_comm_log.csv”中写入第一个条目,并创建反向通道日志文件“BCI_comm_log.csv”。要添加自定义反向通道控制代码,请向下滚动到自定义用户代码区域并复制/粘贴以下代码:

Tx_BCIBCI_State_ST = Tx_BCIParameter.BCI_State_ST;%用户从服务器中添加AMI参数IBIS-AMI Manager Tx_BCIFFE_Tap0 = Tx_BCIParameter.FFE_Tap0;%用户从服务器中添加AMI参数IBIS-AMI Manager Tx_BCIFFE_Tap1 = Tx_BCIParameter.FFE_Tap1;%用户从服务器中添加AMI参数IBIS-AMI Manager Tx_BCIFFE_Tapm1 = Tx_BCIParameter.FFE_Tapm1;%用户从SerDes中添加AMI参数IBIS-AMI Manager %%如果Tx_BCIBCI_State_ST == 2 %训练启用bciWrFile = ' bci_com .csv',则设置GetWave反向通道操作;%% Tx/Rx反向通道通信文件协议= ['DDR5' 0];%%终止字符串以保持fprintf在c++状态下的快乐= ['Training' 0];%%空终止字符串,以保持fprintf在c++中的快乐。%%初始化序列计数器EyeHeight = 0.0;%%初始化训练度量%发布Tx能力numFFEtaps = 3; FFEtaps = [0.0, 1.0, 0.0]; FFEInit.TapWeights = [0.0, 1.0, 0.0]; % Initialize Rx capabilities (actual values set by Rx) numDFEtaps = 1; DFEtaps = 0.0000; % Create new file for back-channel communication writeBCIfile(bciWrFile, 'w', Protocol, numDFEtaps, numFFEtaps, DFEtaps, FFEtaps, Sequence, State, EyeHeight) % Create new BCI_ID_log.csv file (for back-channel history) logFileName = 'BCI_comm_log.csv'; writeBCIhistory(logFileName, 'Tx', 'Init', 0, Tx_BCIBCI_State_ST, numDFEtaps, numFFEtaps, DFEtaps, FFEtaps, Sequence, EyeHeight) end

要测试新的用户代码是否正常工作,请保存并运行模型,然后验证在模型目录中创建了新的反向通道通信(BCI_comm_log.csv)和日志(BCI_comm_log.csv)文件,并且文件中的值与上面设置的值匹配。

设置Rx Init自定义代码

Rx Initialize函数用于建立Rx AMI模型,以便在gewave分析过程中运行反向通道训练。这将读入反向通道通信文件,然后使用Rx配置信息(DFE接点的数量和DFE接点的值)更新该文件。它还更新日志文件。

在Rx子系统中双击Init块,然后单击显示初始化打开MATLAB中的Initialize函数。

初始化函数是一个自动生成的函数,它提供了SerDes系统块(IBIS AMI-Init)的脉冲响应处理。的% %开始:%结束:线条表示可以输入自定义用户代码的部分。当Refresh Init运行时,不覆盖本节中的数据。

%% BEGIN:自定义用户代码区域(当'Refresh Init'按钮被按下时保留)Rx_BCI_WritesampleVoltage = Rx_BCI_WriteParameter.sampleVoltage;%用户从服务器中添加AMI参数IBIS-AMI Manager Rx_BCI_WriteBCI_State_ST = Rx_BCI_WriteParameter.BCI_State_ST%用户从SerDes中添加AMI参数IBIS-AMI Manager % END:自定义用户代码区域(在按下Refresh Init按钮时保留)

使用这个自定义用户代码区域从Tx读取配置,初始化Rx所需的额外反向通道参数,在反向通道通信文件“BCI_comm_log.csv”中写入下一个条目,并附加到反向通道日志文件“BCI_comm_log.csv”中。要添加自定义反向通道控制代码,请向下滚动自定义用户代码区域并复制/粘贴以下代码:

Rx_BCI_WritesampleVoltage = Rx_BCI_WriteParameter.sampleVoltage;%用户从服务器中添加AMI参数IBIS-AMI Manager Rx_BCI_WriteBCI_State_ST = Rx_BCI_WriteParameter.BCI_State_ST%用户从SerDes中添加AMI参数IBIS-AMI Manager %%设置get wave反向通道操作,如果Rx_BCI_WriteBCI_State_ST == 2 %训练启用%%从反向通道通信文件读取以从Tx获得设置bciRdFile = ' bci_com .csv';[Protocol, ~, numFFEtaps, ~, FFEtaps, Sequence, State, EyeHeight] = readBCIfile(bciRdFile);%%将Rx安装程序写入回信道通信文件。bciWrFile = ' bci_com .csv';序列=序列+ 1;%%初始化序列计数器%发布Rx能力numDFEtaps = 4;DFEtaps = [0.0000, 0.0000, 0.0000, 0.0000];writeBCIfile(bciWrFile, 'w', Protocol, numDFEtaps, numFFEtaps, DFEtaps, FFEtaps, Sequence, State, EyeHeight) %写入日志文件logFileName = 'BCI_comm_log.csv'; writeBCIhistory(logFileName, 'Rx', 'Init', 0, Rx_BCI_WriteBCI_State_ST, numDFEtaps, numFFEtaps, DFEtaps, FFEtaps, Sequence, EyeHeight) % Force DFE Mode to Fixed when training is enabled. DFECDRInit.Mode = 1; end

要测试新用户代码是否正常工作,请保存并运行模型,然后验证反向通道通信(BCI_comm_log.csv)和日志(BCI_comm_log.csv)文件是否已经创建,并且文件中的值是否与上面设置的值匹配。在BCI_comm_log.csv文件中,您应该看到第一个RX调用已添加到日志文件中(序列#2)。

设置Tx Tx_BCI直通块

Tx_BCI块用于控制整个后通道训练过程。第一次通过它初始化所有的Tx和Rx参数,将在训练期间优化。在每个反向通道训练周期后,该块将读取由Rx提供的当前眼度量,存储此值,然后为下一个通道更新Tx和Rx参数。当训练完成时,该模块将发出训练完成的信号,将所有Tx和Rx参数设置为最优值,然后将模型返回正常运行。

第一步是为反向通道操作设置Tx_BCI块。控制Tx_BCI块操作的MATLAB函数块稍后在本例中编写。

查看Tx_BCI块中的掩码。您应该看到8个自动生成的数据存储读/写块。

删除Pass-Through系统对象,因为它没有被使用。确保将import连接到Outport。

添加一个Mux阻塞并设置输入数为3。这将用于将三个tapWeightsIn DataStoreRead信号复用为单个向量。

添加一个多路分配器阻塞并设置输出数为3。这将用于将tapWeightsOut向量解复用为三个独立的DataStoreWrite信号。

添加一个新的MATLAB函数块并将标签设置为计数器。这个MATLAB函数返回模型处理的样本总数和结果UI的数量。打开这个新的MATLAB函数块,然后复制/粘贴以下代码,替换默认内容。

函数[sampCount, uiCount] = counter(SymbolTime, SampleInterval) %计算每比特采样数sampBit = round(SymbolTime/SampleInterval);%设置持久变量persistent x y如果isempty(x) x = int32(1);Y = int32(1);Else x = x + 1;如果mod(x,sampBit) == 0 y = y + 1;输出结果sampCount = x;uiCount = y;

这个函数的两个输入的值,SymbolTimeSampleInterval,从模型工作区继承,因此不需要在MATLAB函数块上显示为节点。要从MATLAB函数块中删除这些节点:

  1. 保存MATLAB函数。

  2. 在MATLAB函数签名中突出显示参数SymbolTime

  3. 右键单击参数并选择“SymbolTime”的数据范围

  4. 从更改数据范围信号参数

  5. 重复此过程SampleInterval

  6. 当您保存MATLAB函数时,您应该看到这两个输入参数已从Simulink画布上的函数块中删除。金宝app

此函数输出的数据类型,sampCountuiCount默认设置为“继承”。由于此函数块正在为这两个参数创建值,因此需要显式定义它们的Data Type,而不是基于启发式方法确定它们。显式定义这两个参数的数据类型:

  1. 打开Simulin金宝appk模型资源管理器并导航到Tx->Tx_BCI->计数器。

  2. 突出显示参数sampCount

  3. 将类型从继承更新为int32并点击应用

  4. 重复此过程uiCount

添加另一个新MATLAB函数块并将标签设置为txBackChannel。该MATLAB函数块用于控制反信道训练过程。这个函数的内容将在后面的示例中介绍。但是,要完成Tx_BCI块连接,必须显示所有正确的节点。要启用此功能:

  1. 双击txBackChannel MATLAB函数块,在MATLAB编辑器中打开它。

  2. 删除所有默认内容。

  3. 插入以下功能签名:

函数[tapWeightsOut, BCIStateOut] = txBCtraining(tapWeightsIn, BCIStateIn, sampleCounter, uiCounter, SymbolTime, SampleInterval)

这个函数的两个输入的值,SymbolTimeSampleInterval,从模型工作区继承,因此不需要在MATLAB函数块上显示为节点。要从MATLAB函数块中删除这些节点:

  1. 保存MATLAB函数。

  2. 在MATLAB函数签名中突出显示参数SymbolTime

  3. 右键单击参数并选择“SymbolTime”的数据范围

  4. 从更改数据范围信号参数

  5. 重复此过程SampleInterval

  6. 当您保存MATLAB函数时,您应该看到这两个输入参数已从Simulink画布上的函数块中删除。金宝app

将所有内容连接在一起,如下所示:

设置Rx Rx_BCI_Read块

Rx_BCI_Read块用于读取Tx_BCI块请求的Rx参数值,并为下一个反向通道训练周期设置这些值。如果Tx_BCI块发出训练完成的信号,则该块设置用于模拟剩余部分的最终值。

第一步是为反向通道操作设置Rx_BCI_Read块。控制Rx_BCI_Read块操作的MATLAB函数块稍后在示例中编写。

查看Rx_BCI_Read块中的掩码。

删除Pass-Through系统对象,因为它不会被使用。确保将import连接到Outport。

添加一个DataStoreRead块标记DFECDRTapWeightsIn

  1. 双击DataStoreRead块,设置数据存储名称为:DFECDRSignal

  2. 在Element Selection选项卡上,展开信号DFECDRSignal并突出显示TapWeights [1,4]

  3. 按下选择> >按钮以选择此元素。

  4. 保存更改。

添加一个DataStoreRead块标记RxBCIStateIn

  1. 双击DataStoreRead块,设置数据存储名称为:Rx_BCI_WriteSignal

  2. 在Element Selection选项卡上,展开信号Rx_BCI_WriteSignal并突出显示BCI_State_ST

  3. 按下选择> >按钮以选择此元素。

  4. 保存更改。

添加一个DataStoreWrite块标记RxBCIStateOut

  1. 双击DataStoreWrite块,设置数据存储名称为:Rx_BCI_WriteSignal

  2. 在Element Assignment选项卡上,展开信号Rx_BCI_WriteSignal并突出显示BCI_State_ST

  3. 按下选择> >按钮以选择此元素。

  4. 保存更改。

添加一个DataStoreWrite块标记DFECDRTapWeightsOut

  1. 双击DataStoreWrite块,设置数据存储名称为:DFECDRSignal

  2. 在Element Assignment选项卡上,展开信号DFECDRSignal并突出显示TapWeights [1,4]

  3. 按下选择> >按钮以选择此元素。

  4. 保存更改。

复制计数器MATLAB函数块从Tx_BCI块转换为此块。

添加一个新的MATLAB函数块并将标签设置为rxBackChannelRead。该MATLAB函数块用于控制反信道训练过程。这个函数的内容将在后面的示例中介绍。但是,要完成Rx_BCI_Read块连接,必须显示所有正确的节点。要启用此功能:

  1. 双击rxBackChannelRead MATLAB函数块,在MATLAB编辑器中打开。

  2. 删除所有默认内容。

  3. 插入以下功能签名:

function [BCIStateOut, tapWeightsOut] = rxBCtrainingRead(tapWeightsIn, BCIStateIn, sampleCounter, uiCounter, SymbolTime, SampleInterval)

这个函数的两个输入的值,SymbolTimeSampleInterval,从模型工作区继承,因此不需要在MATLAB函数块上显示为节点。要从MATLAB函数块中删除这些节点:

  1. 保存MATLAB函数。

  2. 在MATLAB函数签名中突出显示参数SymbolTime

  3. 右键单击参数并选择“SymbolTime”的数据范围

  4. 从更改数据范围信号参数

  5. 重复此过程SampleInterval

  6. 当您保存MATLAB函数时,您应该看到这两个输入参数已从Simulink画布上的函数块中删除。金宝app

将所有内容连接在一起,如下所示:

设置Rx Rx_BCI_Write块

Rx_BCI_Write块在每个反向通道训练周期结束时使用,以计算当前的眼睛指标,并将这些指标报告给Tx_BCI块进行分析。

第一步是为反向通道操作设置Rx_BCI_Write块。控制Rx_BCI_Write块操作的MATLAB函数块稍后在示例中写入。

查看Rx_BCI_Write块中的掩码。您应该自动生成数据存储读/写块。

删除Pass-Through系统对象,因为它没有被使用。确保将import连接到Outport。

删除DataStoreWrite块标记sampleVoltage写。它不会被使用。

添加一个DataStoreRead块标记DFECDRTapWeightsIn

  1. 双击DataStoreRead块并将数据存储名称设置为DFECDRSignal

  2. 在Element Selection选项卡上,展开信号DFECDRSignal并突出显示TapWeights(1、4)

  3. 按下选择> >按钮以选择此元素。

  4. 保存更改。

复制计数器MATLAB函数块从Tx_BCI块转换为此块。

添加一个新的MATLAB函数块并将标签设置为rxBackChannelWrite。该MATLAB函数块用于控制反信道训练过程。这个函数的内容将在后面的示例中介绍。然而,要完成Rx_BCI_Write块连接,必须显示所有正确的节点。要启用此功能:

  1. 双击rxBackChannelWrite MATLAB函数块,在MATLAB编辑器中打开。

  2. 删除所有默认内容。

  3. 插入以下功能签名:

函数BCIStateOut = rxBCtrainingWrite(sampleV, tapWeightsIn, BCIStateIn, sampleCounter, uiCounter, SymbolTime, SampleInterval)

这个函数的两个输入的值,SymbolTimeSampleInterval,从模型工作区继承,因此不需要在MATLAB函数块上显示为节点。要从MATLAB函数块中删除这些节点:

  1. 保存MATLAB函数。

  2. 在MATLAB函数签名中突出显示参数SymbolTime

  3. 右键单击参数并选择“SymbolTime”的数据范围

  4. 从更改数据范围信号参数

  5. 重复此过程SampleInterval

  6. 当您保存MATLAB函数时,您应该看到这两个输入参数已从Simulink画布上的函数块中删除。金宝app

将所有内容连接在一起,如下所示:

编辑txBCtraining MATLAB函数块

Tx_BCI块用于控制整个后通道训练过程。第一次通过它初始化所有的Tx和Rx参数,将在训练期间优化。在每个反向通道训练周期之后,该块读取由Rx提供的当前眼度量,存储此值,然后为下一个通道更新Tx和Rx参数。当训练完成时,该块表示训练完成,将所有Tx和Rx参数设置为最优值,然后返回模型正常运行。

Tx_BCI块是在本例前面为反向通道操作设置的。现在,您将在Tx_BCI块的中心创建MATLAB函数块。这个MATLAB函数块,它被标记txBackChannel他控制着整个秘密培训过程。这一过程涉及的步骤如下:

  1. 定义函数签名

  2. 初始化参数并设置持久变量

  3. 定义要扫描的参数及其范围

  4. 在第一次GetWave调用中,设置Tx和Rx的初始起始参数值

  5. 每个反向通道训练周期读取Rx计算的眼睛指标,并决定下一步做什么。当训练完成信号训练完成时,输出仿真过程中使用的最优Tx和Rx参数值,并将这些最终值写入日志文件。

  6. 设置合适的训练状态,输出要使用的FFE参数

以下部分将引导您完成txBackChannel MATLAB函数块中使用的代码。在Tx块中,单击Tx_BCI直通块并键入Ctrl-U推入前面设置的Tx_BCI直通块。双击txBackChannelMATLAB函数块,然后复制/粘贴下面章节中描述的代码。

定义函数签名

txBCtraining块的函数签名有6个输入和2个输出。输入是:

  • tapWeightsIn:在FFE掩码中定义的FFE分接权重数组。

  • BCIStateIn:来自TxBCIStateIn数据存储的回通道状态值。

  • sampleCounter:样本总数。

  • uiCounter:用户界面总数。

  • SymbolTime: UI(秒)。该值继承自模型工作区,因此不需要在MATLAB函数块上显示为节点。为了从MATLAB函数块中删除该节点,之前将Data Scope设置为“Parameter”。

  • SampleInterval:模拟步长(秒)。该值继承自模型工作区,因此不需要在MATLAB函数块上显示为节点。为了从MATLAB函数块中删除该节点,之前将Data Scope设置为“Parameter”。

有两个输出:

  • tapWeightsOut: FFE抽头权重数组输出到BCIFFETapWeightsOut数据存储。

  • BCIStateOut:输出到TxBCIStateOut数据存储的回通道状态值。

函数签名是在最初创建MATLAB函数块时添加的,因此已经存在。

初始化参数和变量

本节设置了计算反向通道训练周期大小所需的三个常数:

  • sampBit:每个UI中的样本数量。

  • messageInterval:每个反向通道训练周期的长度(以UI表示)。这个值目前被设置为~2个PRBS7迭代。

  • BCIwait:启动后通道训练前的延迟时间(UI)。这个值目前被设置为~4个PRBS7迭代。

除了常量值之外,本节还设置了该函数使用的11个持久变量。持久变量在每次调用此MATLAB函数之间保留其值。这11个持久变量是:

  • 协议:此反向通道模型使用的协议。

  • numDFEtaps:在此反向信道训练算法中包含的DFE抽头的数量。

  • numFFEtaps:在此反向通道训练算法中包含的FFE水龙头数量。

  • DFEtaps:当前DFE抽头值。

  • FFEtaps:当前FFE分接值。

  • 序列:一个整数计数器,用于记录训练事件的顺序。

  • 状态:当前后台培训状态。

  • EyeHeight: Rx报告的当前眼高(伏特)。

  • 一步:当前正在运行的训练序列步骤。

  • indx:控制循环的索引变量。

  • 度规一种阵列,用于存储从每个训练步骤进入的眼睛高度。

为了初始化这些参数和变量,将以下代码复制/粘贴到txBackChannel MATLAB函数块中:

%% Setup sampBit = round(SymbolTime/SampleInterval);%%计算每比特采样数messageInterval = 256;%%反向通道训练周期迭代(~2次PRBS7迭代)长度(UI) BCIwait = 512;%%开始训练前的延迟时间(在UI中)(~4次PRBS7迭代)%%读取BCI文件以确定训练值%在时间步之间提供变量持久性协议numDFEtaps numFFEtaps DFEtaps FFEtaps序列状态EyeHeight步长索引度量%初始化变量初始条件如果为空(协议)协议= 'Defaults';end if isempty(numDFEtaps) numDFEtaps = 4;end if isempty(numFFEtaps) numFFEtaps = 3;end if isempty(DFEtaps) = [0.000,0.000,0.000,0.000];end if isempty(FFEtaps) FFEtaps = [0.000,1.000,0.000];end if isempty(Sequence) Sequence = 1;end if isempty(State) State = 'Testing'; end if isempty(EyeHeight) EyeHeight = 0.000; end if isempty(step) step = 1; end if isempty(indx) indx = 1; end if isempty(metric) metric = zeros(50,1); end

定义扫描参数

本例中实现的训练算法分别扫描FFE抽头前后的值和所有4个DFE抽头,然后为每个抽头选择最优值。八个参数用于定义每个节拍的范围和训练过程中使用的步长:

  • ffeTapStep:扫描FFE水龙头时使用的步长。这个值是负的,因为FFE抽头值总是<= 0。

  • dfeTapStep:扫DFE水龙头时使用的步长。

  • regFFEtapm1:扫描FFE预抽头时要使用的最小/最大值范围。

  • regFFEtap1:扫描FFE后接时要使用的值的最小/最大范围。

  • regDFEtap1:扫描第一个DFE抽头时要使用的最小/最大值范围。

  • regDFEtap2:扫描第二个DFE抽头时要使用的最小/最大值范围。

  • regDFEtap3:扫描第三个DFE抽头时要使用的最小/最大值范围。

  • regDFEtap4:扫描第四个DFE水龙头时要使用的最小/最大值范围。

为了定义训练时要扫描的所有参数,将以下代码复制/粘贴到txBackChannel MATLAB函数块中:

%定义参数步长ffeTapStep = -0.050;dfeTapStep = 0.010;%映射范围到寄存器值regFFEtapm1 = (0.000:ffeTapStep:-0.300);regFFEtap1 = (0.000:ffeTapStep:-0.300);regDFEtap1 = (-0.200:dfeTapStep: 0.050);regDFEtap2 = (-0.075:dfeTapStep: 0.075);regDFEtap3 = (-0.060:dfeTapStep: 0.060);regDFEtap4 = (-0.045:dfeTapStep: 0.045);

第一个GetWave呼叫

当启用训练时,对该MATLAB函数的第一次调用需要读取初始化期间写入的反向通道通信文件,以确定Tx和Rx模型的全部功能。本节还设置用于第一个反向通道训练周期的初始值。最后,将所有这些值写入回信道通信日志文件。

要实现第一个GetWave调用,将以下代码复制/粘贴到txBackChannel MATLAB函数块中:

%%如果sampleCounter == 1 && BCIStateIn == 2 %训练启用%读取反向通道通信文件以获得当前设置bciRdFile = ' bci_com .csv';[~, numDFEtaps, numFFEtaps, ~, ~, Sequence, ~, EyeHeight] = readBCIfile(bciRdFile);% Tx参数= [0.000,1.000,0.000];% Rx参数= [0.0000,0.0000,0.0000,0.0000];bciWrFile = ' bci_com .csv';协议= ['DDR5' 0];%%终止字符串以保持fprintf在c++状态下的快乐= ['Training' 0];%%空终止字符串,以保持fprintf在c++中的快乐序列=序列+ 1;writeBCIfile(bciWrFile, 'w', Protocol, numel(DFEtaps), numel(FFEtaps), DFEtaps, FFEtaps, Sequence, State, EyeHeight) %写入日志文件logFileName = 'BCI_comm_log.csv';writeBCIhistory(logFileName, 'Tx', 'GetW', sampleCounter, BCIStateIn, numel(DFEtaps), numel(FFEtaps), DFEtaps, FFEtaps, Sequence, EyeHeight)结束

反信道训练算法

当启用训练时,等待后的UI数量由常数定义BCIwait中定义的每个训练块调用后信道训练算法messageInterval常数。首先读取Rx报告的当前指标,然后将这些结果写入回信道通信日志文件。训练算法使用以下步骤:

  1. 扫描FFE预接的所有值,并确定哪个值导致最大的睁开眼睛。

  2. 扫描后接FFE的所有值,并确定哪个值导致最大的睁眼。

  3. 扫描DFE的所有值,点击1,并确定哪个值导致最大的睁眼。

  4. 扫描DFE点2的所有值,并确定哪个值导致最大的睁眼。

  5. 扫描DFE的所有值,点击3,并确定哪个值导致最大的睁眼。

  6. 扫描DFE点4的所有值,并确定哪个值导致最大的睁眼。

  7. 培训完成后,将State更改为“Converged”,并将最终值写入back-channel通信日志文件。

为了实现反信道训练算法,将以下代码复制/粘贴到txBackChannel MATLAB函数块中:

%%每个后续BCI块(Sequence=5,7,9,11…)如果uiCounter > BCIwait + 2 && mod(sampleCounter - 1, (messageInterval * sampBit)) == 0 && BCIStateIn == 2 %训练启用%读取前16个使用的设置从反向通道通信文件bciRdFile = ' bci_com .csv';[~, ~, ~, ~, ~, Sequence, ~, EyeHeight] = readBCIfile(bciRdFile);%将当前结果写入日志文件Sequence = Sequence + 1;logFileName = 'BCI_comm_log.csv';writeBCIhistory(logFileName, 'Tx', 'GetW', sampleCounter, BCIStateIn, numel(DFEtaps), numel(FFEtaps), DFEtaps, FFEtaps, Sequence, EyeHeight) if index ~= 1%存储当前度量metric(index - 1) = EyeHeight;step 1:确定FFE抽头的最佳值-1 State = ['Training' 0];%%如果索引x <= length(regFFEtapm1),则Null终止字符串在c++中保持fprintf快乐%设置下一次迭代的值FFEtaps(1) = regFFEtapm1(索引x);FFEtaps(3) = 0.0;FFEtaps(2) = 1 - abs(FFEtaps(1)) - abs(FFEtaps(3));索引x =索引x + 1; elseif indx == length(regFFEtapm1) + 1 % Set best metric [~, jj] = max(metric); FFEtaps(1) = regFFEtapm1(jj); FFEtaps(3) = 0.0; FFEtaps(2) = 1 - abs(FFEtaps(1)) - abs(FFEtaps(3)); % Done. Set up for next step metric = zeros(50,1); step = step + 1; indx = 1; end case 2 % Step 2: Determine best value for FFE tap 1 State = ['Training' 0]; if indx <= length(regFFEtap1) % Set values for next iteration %FFEtaps(1) = 0.0; %% Use value from step 1 FFEtaps(3) = regFFEtap1(indx); FFEtaps(2) = 1 - abs(FFEtaps(1)) - abs(FFEtaps(3)); indx = indx + 1; elseif indx == length(regFFEtap1) + 1 % Set best metric [~, jj] = max(metric); FFEtaps(3) = regFFEtap1(jj); FFEtaps(2) = 1 - abs(FFEtaps(1)) - abs(FFEtaps(3)); % Done. Set up for next step metric = zeros(50,1); step = step + 1; indx = 1; end case 3 % Step 3: Determine best value for DFE tap 1 State = ['Training' 0]; if indx <= length(regDFEtap1) % Set values for next iteration DFEtaps = [regDFEtap1(indx), 0.0000, 0.0000, 0.0000]; indx = indx + 1; elseif indx == length(regDFEtap1) + 1 % Set best metric [~, jj] = max(metric); DFEtaps = [regDFEtap1(jj), 0.0000, 0.0000, 0.0000]; % Done. Set up for next step metric = zeros(50,1); step = step + 1; indx = 1; end case 4 % Step 4: Determine best value for DFE tap 2 State = ['Training' 0]; if indx <= length(regDFEtap2) % Set values for next iteration DFEtaps(2:4) = [regDFEtap2(indx), 0.0000, 0.0000]; indx = indx + 1; elseif indx == length(regDFEtap2) + 1 % Set best metric [~, jj] = max(metric); DFEtaps(2:4) = [regDFEtap2(jj), 0.0000, 0.0000]; % Done. Set up for next step metric = zeros(50,1); step = step + 1; indx = 1; end case 5 % Step 5: Determine best value for DFE tap 3 State = ['Training' 0]; if indx <= length(regDFEtap3) % Set values for next iteration DFEtaps(3:4) = [regDFEtap3(indx), 0.0000]; indx = indx + 1; elseif indx == length(regDFEtap3) + 1 % Set best metric [~, jj] = max(metric); DFEtaps(3:4) = [regDFEtap3(jj), 0.0000]; % Done. Set up for next step metric = zeros(50,1); step = step + 1; indx = 1; end case 6 % Step 6: Determine best value for DFE tap 4 State = ['Training' 0]; if indx <= length(regDFEtap4) % Set values for next iteration DFEtaps(4) = regDFEtap4(indx); indx = indx + 1; elseif indx == length(regDFEtap4) + 1 % Set best metric [~, jj] = max(metric); DFEtaps(4) = regDFEtap4(jj); % Done. Set up for next step metric = zeros(50,1); step = step + 1; indx = 1; end case 7 % Step 7: Training is complete State = ['Converged' 0]; % Write final entry in log file logFileName = 'BCI_comm_log.csv'; Sequence = Sequence + 1; writeBCIhistory(logFileName, 'Tx', 'GetW', sampleCounter, 3, numel(DFEtaps), numel(FFEtaps), DFEtaps, FFEtaps, Sequence, EyeHeight) otherwise State = ['Error' 0]; end % Write to back-channel communication file with next pass settings for Rx bciWrFile = 'BCI_comm.csv'; Protocol = ['DDR5' 0]; %% Null terminate string to keep fprintf happy in C++ writeBCIfile(bciWrFile, 'w', Protocol, numel(DFEtaps), numel(FFEtaps), DFEtaps, FFEtaps, Sequence, State, EyeHeight) end

设置训练状态和输出参数值

这个MATLAB函数需要做的最后一件事是更新BCI_State_ST数据存储的状态,并更新FFE抽头数组值。

为了设置训练状态和输出值,将以下代码复制/粘贴到txBackChannel MATLAB函数块中:

%%如果strcmpi(state,'Off') || strcmpi(state,['Off' 0]) BCIStateOut = 1;elseif strcmpi(State,'Training') || strcmpi(State,['Training' 0]) BCIStateOut = 2;elseif strcmpi(State,'Converged') || strcmpi(State,['Converged' 0]) bcstateout = 3;elseif strcmpi(State,'Failed') || strcmpi(State,['Failed' 0]) BCIStateOut = 4;else %Error BCIStateOut = 5;end %%设置基于训练的输出FFE值,如果BCIStateOut == 2 || BCIStateOut == 3%训练启用/融合tapWeightsOut = FFEtaps(:);否则%训练关闭/失败/错误tapWeightsOut = tapWeightsIn;结束

保存并关闭此MATLAB函数块。

编辑rxBCtrainingRead MATLAB函数块

Rx_BCI_Read块用于读取Tx_BCI块请求的Rx参数值,并为下一个反向通道训练周期设置它们。如果Tx_BCI块发出训练完成的信号,则该块设置Rx用于模拟剩余部分的最终值。

Rx_BCI_Read块是在本例前面为反向通道操作设置的。现在在Rx_BCI_Read块的中心创建MATLAB函数块。这个MATLAB函数块,它被标记rxBCtrainingRead,设置要使用的Rx DFE值。这一过程涉及的步骤如下:

  1. 定义函数签名。

  2. 初始化参数并设置持久变量。

  3. 在第一次GetWave调用时,以及在每个反向通道训练周期的开始,读取Tx反向通道训练算法指定的Rx DFE分接值。

  4. 设置合适的训练状态,输出要使用的DFE参数。

下面的部分将引导您完成rxBCtrainingRead MATLAB函数块中使用的代码。在Rx块中,单击Rx_BCI_Read直通块并键入Ctrl-U推入前面设置的Rx_BCI_Read直通块。双击rxBCtrainingRead MATLAB函数块,然后复制/粘贴以下部分中描述的代码。

定义函数签名

rxBCtrainingRead块的函数签名有6个输入和2个输出。输入是:

  • tapWeightsInDFE轻击权重数组,定义在DFECDRTapWeightsIn数据存储中。

  • BCIStateIn:来自RxBCIStateIn数据存储的回通道状态值。

  • sampleCounter:样本总数。

  • uiCounter:用户界面总数。

  • SymbolTime: UI(秒)。该值继承自模型工作区,因此不需要在MATLAB函数块上显示为节点。为了从MATLAB函数块中删除该节点,将Data Scope设置为“Parameter”。

  • SampleInterval:模拟步长(秒)。该值继承自模型工作区,因此不需要在MATLAB函数块上显示为节点。为了从MATLAB函数块中删除该节点,将Data Scope设置为“Parameter”。

有两个输出:

  • tapWeightsOut: DFE抽头权重数组输出到DFECDRTapWeightsOut数据存储。

  • BCIStateOut:输出到RxBCIStateOut数据存储的回通道状态值。

函数签名是在最初创建MATLAB函数块时输入的,因此已经存在。

初始化参数和变量

本节设置了计算反向通道训练周期大小所需的三个常数:

  • sampBit:每个UI中的样本数量。

  • messageInterval:每个反向通道训练周期的长度(以UI表示)。这个值目前被设置为~2个PRBS7迭代。

  • BCIwait:启动后通道训练前的延迟时间(UI)。这个值目前被设置为~4个PRBS7迭代。

除了常量值之外,本节还设置了该函数使用的7个持久变量。持久变量在每次调用此MATLAB函数之间保留其值。这7个持久变量是:

  • 协议:此反向通道模型使用的协议。

  • numDFEtaps:在此反向信道训练算法中包含的DFE抽头的数量。

  • numFFEtaps:在此反向通道训练算法中包含的FFE水龙头数量。

  • DFEtaps:当前DFE抽头值。

  • FFEtaps:当前FFE分接值。

  • 序列:一个整数计数器,用于记录训练事件的顺序。

  • 状态:当前后台培训状态。

为了初始化参数和变量,将以下代码复制/粘贴到rxBCtrainingRead MATLAB函数块中:

%% Setup sampBit = round(SymbolTime/SampleInterval);%%计算每比特采样数messageInterval = 256;%%反向通道训练周期迭代(~2次PRBS7迭代)长度(UI) BCIwait = 512;%%开始训练之前的延迟时间(在UI中)(~4个PRBS7迭代)%在时间步之间使变量可用持久协议numDFEtaps numFFEtaps DFEtaps FFEtaps序列状态;%初始化变量初始条件如果isempty(Protocol) Protocol = 'Defaults';end if isempty(numDFEtaps) numDFEtaps = 4;end if isempty(numFFEtaps) numFFEtaps = 3;end if isempty(DFEtaps) DFEtaps = tapWeightsIn;end if isempty(FFEtaps) FFEtaps = [0,0,0];end if isempty(Sequence) Sequence = 1; end if isempty(State) if BCIStateIn == 1 % Off State = ['Off' 0]; elseif BCIStateIn == 2 % Training State = ['Training' 0]; elseif BCIStateIn == 3 % Converged State = ['Converged' 0]; elseif BCIStateIn == 4 % Failed State = ['Failed' 0]; else % Error State = ['Error' 0]; end end

读取要使用的DFE抽头值

当启用训练时,在第一次调用该MATLAB函数时,以及在定义的每个训练块开始时messageInterval常数时,读取后信道通信文件以确定更新后的DFE分接值,用于下一个训练周期。

为了设置要使用的DFE tap值,将以下代码复制/粘贴到rxBCtrainingRead MATLAB函数块中:

%%每个BCI块的第一个get波块(Sequence=3,5,7,9,11,…)%读取反向通道通信文件以获取当前设置if (sampleCounter == 1 && BCIStateIn == 2) || ((uiCounter > BCIwait + 2 && mod(sampleCounter - 1, (messageInterval * sampBit)) == 0) && BCIStateIn == 2) %训练启用bciRdFile = 'BCI_comm.csv';[Protocol, numDFEtaps, numFFEtaps, DFEtaps(1,1:4), FFEtaps, Sequence, State, ~] = readBCIfile(bciRdFile);结束

设置训练状态和输出参数值

这个MATLAB函数块需要做的最后一件事是更新BCI_State_ST数据存储的状态,并更新DFE tap数组值。

为了设置状态和输出值,将以下代码复制/粘贴到rxBCtrainingRead MATLAB函数块中:

%%如果strcmpi(state,'Off') || strcmpi(state,['Off' 0]) BCIStateOut = 1;elseif strcmpi(State,'Training') || strcmpi(State,['Training' 0]) BCIStateOut = 2;elseif strcmpi(State,'Converged') || strcmpi(State,['Converged' 0]) bcstateout = 3;elseif strcmpi(State,'Failed') || strcmpi(State,['Failed' 0]) BCIStateOut = 4;else %Error BCIStateOut = 5;设置基于训练的输出DFE值,如果BCIStateOut == 2 %训练启用了tapWeightsOut = DFEtaps(1,1:4);否则tapWeightsOut = tapWeightsIn;结束

保存并关闭此MATLAB函数块。

编辑rxBCtrainingWrite MATLAB函数块

Rx_BCI_Write块在每个反向通道训练周期结束时使用,以计算当前的眼睛指标,并将这些指标报告给Tx_BCI块进行分析。

Rx_BCI_Write块是在本例前面为反向通道操作设置的。现在将创建Rx_BCI_Write块中心的MATLAB函数块。这个MATLAB函数块,我们标记了rxBCtrainingWrite,将计算最后127位的最小眼高度,并将这些值写入后信道通信文件和日志文件。这一过程涉及的步骤如下:

  1. 定义函数签名。

  2. 初始化参数并设置持久变量。

  3. 存储电压矢量,以便在计算最小眼高时使用。

  4. 在每个后信道训练周期结束时,计算最小眼高并将其写入后信道通信文件。

  5. 更新训练状态。

下面几节将介绍rxBCtrainingWrite MATLAB函数块中使用的代码。在Rx块中,单击Rx_BCI_Write直通块并键入Ctrl-U推入前面设置的Rx_BCI_Write直通块。双击rxBCtrainingWrite MATLAB函数块,然后复制/粘贴以下部分中描述的代码。

定义函数签名

rxBCtrainingWrite块的函数签名有7个输入和1个输出。输入是:

  • sampleV: CDR采样时间的电压。

  • tapWeightsInDFE轻击权重数组,定义在DFECDRTapWeightsIn数据存储中。

  • BCIStateIn:来自RxBCIStateIn数据存储的回通道状态值。

  • sampleCounter:样本总数。

  • uiCounter:用户界面总数。

  • SymbolTime: UI(秒)。该值继承自模型工作区,因此不需要在MATLAB函数块上显示为节点。为了从MATLAB函数块中删除该节点,将Data Scope设置为“Parameter”。

  • SampleInterval:模拟步长(秒)。该值继承自模型工作区,因此不需要在MATLAB函数块上显示为节点。为了从MATLAB函数块中删除该节点,将Data Scope设置为“Parameter”。

有一个输出:

  • BCIStateOut:输出到RxBCIStateOut数据存储的回通道状态值。

函数签名是在最初创建MATLAB函数块时输入的,因此已经存在。

初始化参数和变量

本节设置了计算反向通道训练周期大小所需的四个常数:

  • sampBit:每个UI中的样本数量。

  • messageInterval:每个反向通道训练周期的长度(以UI表示)。这个值目前被设置为~2个PRBS7迭代。

  • BCIwait:启动后通道训练前的延迟时间(UI)。这个值目前被设置为~4个PRBS7迭代。

  • windowLength:用于计算最小眼高的窗口长度(UI中)。这个值目前被设置为1次PRBS7迭代。

除了常量值之外,本节还设置了该函数使用的5个持久变量。持久变量在每次调用此MATLAB函数之间保留其值。这5个持久变量是:

  • 协议:此反向通道模型使用的协议。

  • 序列:一个整数计数器,用于记录训练事件的顺序。

  • 状态:当前后台培训状态。

  • EyeHeight:眼内高度计算值(伏特)。

  • vSamp: CDR块报告的样本电压。

要初始化该块的所有参数和变量,将以下代码复制/粘贴到rxBCtrainingWrite MATLAB函数块中:

%% Setup sampBit = round(SymbolTime/SampleInterval);%%计算每比特采样数messageInterval = 256;%%反向通道训练周期迭代(~2次PRBS7迭代)长度(UI) BCIwait = 512;%%开始训练前的延迟时间(在UI中)(~4 PRBS7迭代)windowLength = 127;%%用于计算最小眼睛高度的窗口长度(在UI中)(1次PRBS7迭代)%在时间步之间使变量可用持久性协议序列状态EyeHeight vSamp如果isempty(State)如果BCIStateIn == 1 % Off State = ['Off' 0];elseif BCIStateIn == 2% Training State = ['Training' 0];elseif BCIStateIn == 3%聚合状态=['聚合' 0];elseif BCIStateIn == 4%失败状态= ['Failed' 0];else %错误状态=['错误' 0];结束结束

存储报告电压的矢量

这一节累积一个滚动的电压矢量,用于最小眼高的计算。假设这些电压在0V周围对称,因此使用绝对值。

为了存储报告眼电压值,将以下代码复制/粘贴到rxBCtrainingWrite MATLAB函数块中:

如果为空(vSamp), vSamp = 0 (1, windowLength * sampBit),则累积最小眼高计算的电压滚动向量;end vSamp = circshift(vSamp, 1);vSamp(1) = abs(sampleV)假设对称且只使用正值

计算最小眼高度并写入文件

当启用训练时,等待后的UI数量由常数定义BCIwait的定义,在每次训练迭代结束时计算反向通道度量messageInterval常数。首先从后通道通信文件中读取后通道配置,然后计算内眼高度值,并将结果输出到后通道通信文件和日志文件。

为了计算眼指标并写入每个回信道周期的通信文件,将以下代码复制/粘贴到rxBCtrainingWrite MATLAB函数块中:

%%如果uiCounter > BCIwait + 2 && mod(sampleCounter, (messageInterval * sampBit)) == 0 && BCIStateIn == 2 %训练启用(Sequence=4,6,8,10,12,…)%读取最后16个使用的设置从反向通道通信文件bciRdFile = ' bci_com .csv';[Protocol, ~, ~, ~, FFEtaps, Sequence, State, ~] = readBCIfile(bciRdFile);%从采样电压计算内眼高度:EyeHeight = min(vSamp) * 2;% 2x,因为使用绝对值。%写入新的bciwfile = ' bci_com .csv';序列=序列+ 1;writeBCIfile(bciWrFile, 'w', Protocol, numel(tapWeightsIn), numel(FFEtaps), tapWeightsIn, FFEtaps, Sequence, State, EyeHeight) % %写入日志文件:logFileName = 'BCI_comm_log.csv';writeBCIhistory(logFileName, 'Rx', 'GetW', sampleCounter, BCIStateIn, numel(tapWeightsIn), numel(FFEtaps), tapWeightsIn, FFEtaps, Sequence, EyeHeight)结束

设置训练状态

在这个MATLAB函数块中需要做的最后一件事是更新BCI_State_ST数据存储的状态。

为了设置训练状态,将以下代码复制/粘贴到rxBCtrainingRead MATLAB函数块中:

%% Update State Out if StateIn == 3 % converge State = [' converge ' 0];elseif BCIStateIn == 4%失败状态= ['Failed' 0];end if strcmpi(State,'Off') || strcmpi(State,['Off' 0]) BCIStateOut = 1;elseif strcmpi(State,'Training') || strcmpi(State,['Training' 0]) BCIStateOut = 2;elseif strcmpi(State,'Converged') || strcmpi(State,['Converged' 0]) bcstateout = 3;elseif strcmpi(State,'Failed') || strcmpi(State,['Failed' 0]) BCIStateOut = 4;else %Error BCIStateOut = 5;结束

保存并关闭此MATLAB函数块。

在Si金宝appmulink中输入ctrl - d编译模型并检查错误。在继续之前解决任何错误。

运行模型并验证结果

下一步是运行模型并验证反向通道代码是否正确运行。

设置仿真参数

在运行完整模型之前,打开刺激块,设置用于测试模型的刺激模式:

  • 伪随机位序列7,以便在模拟过程中使用PRBS7模式。

  • 设置符号数50000让反向通道训练算法有足够的时间完成。

测试Tx和Rx型号的正常运行

运行模型。当模型运行时,观察每个抽头设置被扫描时时域波形的变化。当模拟完成后,反向通道通信文件bci_com .csv应该看起来像这样:

Protocol,DDR5, numDFEtaps,4, numFFEtaps,3, DFEtaps,0.01000,-0.00500,-0.01000,-0.00500, FFEtaps,0.00000,0.85000,-0.15000, Sequence,176, State,Converged, EyeHeight,0.610993,

在电子表格编辑器中打开反向通道通信日志文件BCI_comm_log.csv。日志文件中的每一行显示序列号,哪个模型写入文件(Tx或Rx),当前样本计数,BCI_State和计算的眼高。日志中的最后7列显示正在模拟的当前FFE和DFE抽头值。观察眼高如何随着每个值的扫描而变化,并且在每次迭代后设置给出最大眼高的参数值。注意,FFE0的值总是从FFE1和FFE1的值计算出来的。

生成DDR5 Tx/Rx IBIS-AMI模型

本示例的最后一部分采用定制的Simulink模型并生成符合IBIS-AMI的DDR5模型可执行文件、IB金宝appIS和AMI文件。

打开IBIS-AMI管理器。

出口的模型

出口页签,在“SerDes IBIS-AMI Manager”对话框中:

  • 更新Tx型号名称ddr5_bc_tx

  • 更新Rx型号名称ddr5_bc_rx

  • 请注意Tx和Rx转角百分比设为10。这将把最小/最大模拟模型角值缩放+/-10%。

  • 验证二元模型为Tx和Rx AMI模型设置选择。这将创建支持统计(Init)和时域(GetWave)分析的模型可执行文件。金宝app

  • 设置Tx模型忽略值3.因为在Tx FFE中有三个水龙头。

  • 设置Rx model忽略值到50000以便有足够的时间在时域模拟中完成训练。

  • 要导出的模型作为同时是Tx和Rx以便选择要生成的所有文件(IBIS文件、AMI文件和DLL文件)。

  • 设置IBIS文件名ddr5_bc_txrx.ibs

  • 如果需要,可以在AMI-Tx和AMI-Rx选项卡上添加抖动。

  • 按下出口按钮以在Target目录中生成模型。

更新AMI文件(如果需要)

由SerDes Toolbox生成的Tx和Rx AMI文件符合IBIS 6.1规范,因此所有特定于回通道的参数都放置在该文件的Model_Specific部分中。

BCI_State_ST参数有完整的反向通道训练所需的5个状态,但是为了使这些模型更加用户友好,最终用户只需要2个状态:“关闭”和“训练”。要做这个改变,在每个AMI文件中更新BCI_State_ST参数如下:

  • 改变(表1、2、3、4、5)(清单1 - 2)

  • 改变(列表提示“关闭”“训练”“聚合”“失败”“错误”)(List_Tip "Off" "Training")

  • 注意,这不会影响模型的操作,只会对用户可见的参数值产生影响。

测试生成的IBIS-AMI模型

DDR5发射器和接收器IBIS-AMI模型现已完成,并准备在任何工业标准AMI模型模拟器中进行测试。

模型的局限性

在行业标准AMI模型模拟器中使用这些模型进行模拟时,请记住以下限制:

  • 这些模型将作为“匹配集”运行,或者与使用SerDes Toolbox生成的其他AMI模型一起运行。

  • 这些模型不能与在SerDes工具箱之外生成的AMI模型一起工作。具体来说,是使用IBIS标准BCI_*关键字的任何模型。

  • 不支持BCI_Protocol。金宝app这些模型已经硬编码到一个名为“DDRx_Write”的协议中。

  • 不支持BCI_ID。金宝app这些模型已经硬编码到名为“bci_comm”的BCI_ID,这意味着每个模拟必须在单独的目录中运行,以避免模拟期间的文件名冲突。

  • 必须在两个模型上启用反向通道培训才能启用培训。这是通过将BCI_State_ST参数设置为“Training”来完成的。

  • 这些模型必须在块大小为1024的情况下运行才能正常运行。

  • 这些模型将与任何UI或采样每位值正确操作。

参考文献

[1] IBIS 7.0规范https://ibis.org/ver7.0/ver7_0.pdf

[2] JEDEC网站,https://www.jedec.org/

另请参阅

||||

相关的话题

外部网站