本文是该系列的第9篇。FPGA设计中经常用到一些控制逻辑,如有限状态机(FSM),如果用各种block搭建一个FSM比较麻烦。System Generator支持调用MATLAB代码,通常可以编写MATLAB代码来实现FSM等控制逻辑,通过MCode block调用到System Generator设计中。
本文将使用MATLAB代码设计一个FSM,对“1011”这个序列进行检测。序列检测应该是很多Verilog/VHDL学习者在学习FSM时接触到的一个简单设计。本文将以该设计在System Generator中的实现为主题,介绍MCode的使用。
本设计使用到的block
1.Xilinx block:
MCode(->Index):调用MATLAB函数
2.其它block:
Repeating Sequence Stair(Simulink->Sources):生成序列
这里给出了设计中用到的所有block在库中的路径,后文不再提及(前文用过的block没有给出;同一block会包含在多个库中,为了寻找方便这里只列出一个路径)。
System Generator设计流程
新建一个文件夹,启动System Generator,建立一个空的Simulink模型(seq_detect.slx)。设置一组二进制序列,对序列中的“1011”进行检测,完成FSM及MATLAB代码的设计。
1.生成二进制序列
将Repeating Sequence Stair添加到model中:
该block可以产生重复的离散时间序列,在Vector of output values中设置一组序列(该值不是必须设置为0或1,只是本设计要检测二进制序列)。Signal Attributes->Output data type中可以设置输出数据的类型,这里设置为Boolean。
设置完毕后,该block在model中的图标会显示一个大致的波形,可以据此判断设置是否正确。
2.序列检测器设计
添加System Generator必要的block:一个Gateway In(数据类型设置为boolean)、一个Gateway Out和一个System Generator(选择创建testbench)。
再添加一个Mcode block。双击打开block的属性窗口:
点击Browse选择需要调用M文件,这里先在M文件中声明函数“function matched = state_machine(din)”,din为输入二进制数据流,matched为检测匹配结果(1表示检测到1组“1011”)。
设置完毕后,该block在model中的图标会更换为对应的函数名称及输入/输出接口。再添加1个scope观察二进制序列与检测结果。model连接图如下:
由于此设计中都为单bit信号,因此数据类型都设置成了布尔类型。
3.有限状态机设计
设计的FSM如下:
为了让读者更容易理解,这里给出了详细的状态转移过程说明(S0-S1的转换记作01,其余类似):
1. S0为起始态,S4为终止态(matched只会在S4时为1,其它状态都为0);
2. S0检测到1时表示一帧序列的开始,01-12-23-34组成1011;
3. S1为1时,仍然可能是一帧序列的开始,11-12-23-34组成1011;
4. 由于只有S1为0时才会跳转到 S2,因此S2为0表明检测失败,重新返回S0状态开始检测;
5. 23为0且S3为1时可能是一帧序列的开始,23-32-23-34组成1011;
6. S4为1时可能是一帧序列的开始,41-12-23-34组成1011;S4为0时返回到S0状态重新开始检测。
4.MATLAB代码设计
在MCode属性配置界面点击“Edit M-File”,根据上文设计的有效状态机编写对应的MATLAB代码。完整代码如下:
function matched = state_machine(din)
persistent state, state = xl_state(0,{xlUnsigned, 3, 0});
switch state
case 0
if din == true
state = 1;
else
state = 0;
end
matched = 0;
case 1
if din == false
state = 2;
else
state = 0;
end
matched = 0;
case 2
if din == true
state = 3;
else
state = 0;
end
matched = 0;
case 3
if din == true
state = 4;
else
state = 2;
end
matched = 0;
case 4
if din == false
state = 0;
else
state = 1;
end
matched = 1;
otherwise
state = 0;
matched = 0;
end
定义一个3Bits宽的(3-0)无符号(xlUnsigned)状态变量xl_state,使用switch语法控制状态之间的转移。由于3Bits位宽数据可表示0~7,而FSM状态只有0~4,所以一定要加上otherwise控制状态转移。
System Generator并不是支持所有的MATLAB语法和格式,还有一部分为Xilinx自定义的函数和数据格式,这部分的详细内容(支持的所有MATLAB语法)都记录在ug958这篇文档中。具体可参考该文档,本系列的第10篇也会介绍其中相对重要的内容。
5.将设计导出到FPGA
在System Generator block中设置好Simulink采样周期,设置好运行时间,开始运行验证设计。这里介绍一个仿真运行时间的设计技巧:假设系统采样率为50MHz,示波器中只需要显示20个点即可,运行时间可设置为“20/50e6”。
可以看到每检测到一组“1011”序列后,便输出一个时钟周期的高电平。生成FPGA设计,在Vivado中进行仿真,结果与Simulink中仿真相同:
testbench的生成及Vivado示例工程的解析已在前面的文章中给出,这里不再赘述。
文章来源:FPGADesigner的博客
*本文由作者授权转发,如需转载请联系作者本人