文章目录
- 一、项目场景
- 二、基本模块原理与调试方法分析——信源部分:
- 三、信号处理部分和显示部分:
- 四、基本的通信链路搭建:
- 四、特殊模块:interpreted MATLAB function:
- 五、总结和坑点提醒
一、项目场景
最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。
在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记录这次MIMO串扰消除的链路的debug心路历程。
二、基本模块原理与调试方法分析——信源部分:
大多数人一开始做simulink的时候会觉得他和MATLAB没有太大的区别,诚然这两个使用的语言都是m语言,但是这两个背后蕴含的思想是很不一样的。simulink相比于MATLAB而言,多引入了时序的思想,这点我倒是认为可以类比数字电路的角度去进行分析,现在Xilinx的system generator工具已经支持将simulink中特定的HDL模块直接转化成Verilog代码了。因此,分析好时序的思想,是simulink链路搭建成功的前提。而一共simulink模块,可以大致分为信源部分,信号处理部分和结果展示部分。
接下来先说明信源部分。以最基本的模块:random integer generator为例进行说明。 其标识如下:
点开这个模块,其内部的参数设置如下:
这个地方有三个主要参数,set size就不多说了,决定了随机数的取值范围,我们主要分析sample time和sample per frame的意义。我们可以认为sample time是对应着符号速率,即一个符号(sample)对应的时间。而sample per frame是什么呢?这个地方可以理解为,1帧即为simulink处理数据个数的最小单位,本质还是一系列串行的数据,且每一个数据的持续时间由sample time参数决定。
举一个具体的例子来进行说明,如下图所示:
现在对其进行delay=2的时延(直接搜索delay模块即可),如下图所示。但是这个地方有一个特别要注意而且特别容易错的地方!如刚才所言,simulink处理过程是把一个帧中的数据当成一个整体,因此但凡是模块中的这个参数,都需要手动frame based!(我曾经因为这花了3天时间)
接下来需要进行一些基本的调试,这里总结一些调试方法:
1.展示信号的维度。上图中的random integer generator模块后面有一个5×15 \times 15×1,这个就对应着sample per frame。这个是不会自动显示的,需要我们手动设置,设置方法如下图所示,点击signal dimensions即可,即出现上图所示的效果:
这个地方有一个很容易让人误解的地方,因为5×15 \times 15×1我们通常会将其vector,从而误以为他是5个数据并行输出的,但其实数据输出的本质就是串行输出,只是我们在链路里面把5个连续的串行数据整体作为一帧进行处理。或者说,simulink自动把这5个时刻的数据并行存储了起来,相当于自动作了一次串并转换,而无需我们和写Verilog代码一样手动去做。总结起来,就是signal dimension中的n×1n \times 1n×1就代表了一个模块处理数据的一帧中有多少个符号。
2.可以使用display模块观察数据的取值(但是数据过多时只能观察前面几个)
我们使用刚才的基本模块,加上display模块进行调试,如下图所示:
我们先直接点击run按钮进行调试,(当然前提是如上文所说,delay中的参数设置的是frame based,不然会出现很多奇奇怪怪无法解释的问题)得到的结果如下(因为是随机数,所以每个人结果不一样):
来分析一下这个结果,我们发现delay之后的3-5个数据对应delay之前的1-3个数据(1、1、2),说明delay是正确的,而delay之后的1-2个数据(1、7)则是上一帧中的最后两个数据通过平移得到(1、7)。那这里就存在一个问题了,我们只能看到运行结束,即最后一帧的结果,如何观察到整个数据变化流程呢,那么就是下一个技巧:step forward。
3.可以使用step forward按钮进行步进调试。
简单来说,simulink会对数据源源不断的以帧为单位进行处理,但当运行完成后显示的只有最后一帧的数据,因此,可以采用step forward进行处理,step forward的处理即可以展现中间过程,当然,设置的stop time要足够大,例如此处sample time和sample per frame分别为2s和5,相当于一帧5个数据对应10s的持续时间,将stop time设置为20s,如下图所示:
整个过程中的数据结果分别如下,一开始T=0时刻显示的数据:
T=10时刻显示的数据,delay之前是总体串行数据中的6-10个,而delay后前两位的6和8对应T=0时刻的delay前的帧中的最后两位:
T=20时的数据显示,delay之前是总体串行数据中的11-15个,而delay后的前两位5和7对应T=10时刻的delay前的帧中的最后两位:
当然,刚才的内容都是产生的随机数,那么如果要自己生成一个有规律的帧,(这个在工程中显然是十分常见的,例如802.11系列协议),或者将已知的数据作为信源进行信号处理,那么该如何做呢?
先说对于已知数据,通常以.mat文件存在,只需要使用load函数将其导入工作区。再使用constant模块即可,因为constant模块可以自动读取工作区中的变量。如下图所示:
当然上面的模块的dimension显示的是31162032*2,这个地方我理解的是这个只是simulink的一个表示机制,还是相当于simulink自动给你进行了一次串并转换,如果从数字电路的角度,数据一开始本质都是一串bit流串行接收的,只是将两组输入都通过寄存器进行并行存储与并行运算而已。
再说对于自己手动生成数据,依然可以使用constant的模块,先写好代码,再运行使其出现在工作区即可。不过这里需要介绍一个很好用的模块,reshape模块!!刚才说过了,simulink中的维度只是一种表示机制,和我们从数字电路角度去写Verilog的代码思维是不完全一样的,因为simulink的模块本身可以自动帮我们进行串并时序转换。但如果维度不对应的话,有时候会出现报错的问题。这个时候就需要用到reshape模块,通过这个模块来调整维度,防止报错:
三、信号处理部分和显示部分:
这个地方其实没什么要说的,主要问题就是做信号处理的模块里面的参数需要调成frame based而非sample based,因为是按一帧为单位进行处理(当然,如果对于比较简单的链路,sample per frame为1,不涉及帧结构,就是一个bit一个bit的进行处理,那么这个设置什么就无所谓了)。同时对于涉及到上采和下采的模块,需要对应的选择enforce single-rate processing(不能allow multi-rate process)。当然更多的模块参数,只能实践出真知,此处无法一概而论。此处以我设置的RRC滤波器的参数为例:
而对于如何显示数据,除了之前说过的display以外,主要就是频谱图模块和星座图模块:
constellation diagram:自动显示星座图
spectrum analyzer:自动显示频谱图(注意不要选audio toolbox大类,选择dsp toolbox大类里面的)
四、基本的通信链路搭建:
此处以一个基本的QPSK链路为例进行说明:
具体的链路见该链接,或者请直接私聊3060068746@qq.com:
https://download.csdn.net/download/weixin_45813401/74921483
四、特殊模块:interpreted MATLAB function:
当有些模块用simulink固有的模块无法实现的时候,可以自己通过MATLAB函数进行实现,需要使用该模块:interpreted MATLAB function。核心思想就是自己编写MATLAB函数,然后在这个simulink模块内部输入MATLAB函数的名称即可。
不过这个模块有一个很垃圾的地方,就是要求输入和输出必须都能只有一个端口,对于多输入多输出的函数,我们就需要用到如下的模块:matrix concatenate,将里面的参数选择为vector,可以将多个输入合并成一个总的input向量。同理,我们也可以使用sub_matrix模块,将输出的矩阵或者向量取其子部分。(当然就是会比较麻烦)
最后要说一下这个模块的调试,这个模块是可以使用设置断点的方法进行调试的,在自己写的函数内部设置断点,就会自动停止并在工作区显示这个函数的所有变量,是十分实用的调试技巧。
五、总结和坑点提醒
最后总结一下刚才说的几个simulink的调试经验,以及一些闭坑经验:
1.展示信号维度有助于对时序的理解和调试。
2.不要随便的在链路中间加入buffer模块,如刚才所言,simulink和Verilog不完全一样,按帧为处理单位时,很多模块会自动进行串并转换,在链路中间使用buffer很容易导致时序出现大问题。
3.不要随便的在interpreted MATLAB function中加入figure函数。如刚才所言,一个模块的一次执行是以串行数据中一帧的长度对应的时间作为一个单位,在到达设置的仿真时间之前,是会源源不断的执行的,如果在里面加入figure,可能会一下子执行几百次。
最后:多调链路多尝试,多设断点debug,毕竟,熟能生巧。码字不易,还望得到点赞收藏,感谢。