pal信号verilog实现_(HLS实现verilog)使用HLS实现m序列

301383ce443c98f27bb9035582cd36d5.png

整体的工程公开在这:

maxs-well/HLS4BPSK​github.com
16c6c97859b01bb69488002811b74448.png

本工程主要使用HLS实现m序列,文中将介绍HLS的使用和优化,HLS的C库文件的使用,HLS的单bit信号的实现,并最终生成IP核。

m序列的相关基础知识可以参考m序列的verilog实现以及使能信号解决跨时钟域问题。

初次自主使用HLS生成代码,学习HLS从简入深,这意味着我写的程序可能会有部分错误和不足,欢迎指出!


HLS作为Xilinx推出的一款工具,旨在降低FPGA的使用难度和学习难度,能够更快地使用软件编程语言C/C++生成需要的verilog代码。

作为HLS初学者的我,通过C/C++生成m序列的verilog代码,下面跟着步骤一步步来吧。

使用HLS创建新的工程,参数设置如下:

b3226940a0964c2dd3e8d69fcc3c5258.png
图1 设置项目名称和存储路径

在图1填写项目名称和存储路径,然后一路'Next',直到出现下图的设置;

11c4c46a4101a792905184ba428dfc16.png
图2 设置时钟周期和FPGA型号

如图2,设置工程的时钟周期和FPGA型号;

注意,可以将时钟周期设置的比实际用的周期要小,比如m序列实际使用的时钟周期为20ns,但在HLS中,时钟周期设为10ns,这样HLS生成的代码,时钟会有更高的冗余性,分析结果更为准确;

86ac6f27e6b6157e052a993c1c95feaf.png
图3 HLS项目结构

Source里添加需要生成的C/C++代码,Test Bench添加对Source代码的仿真验证C/C++代码。

由于m序列产生的只是'0','1'代码,m序列输出的信号为1bit信号,所以m序列的产生函数不能使用C中常见的char、int类型,需要使用更加精确的数据类型。

be84268a2459e0a2961208692a322955.png
图4 m_seq.h头文件使用ap_uint控制精度

而Xilinx正好为用户提供了这种精确的数据类型的实现方式,使用前提需要在m_seq.h的头文件里include一个"ap_int.h"。

使用ap_int<W> 或ap_uint<W>可以实现一个Wbit精度的有符号整数或无符号整数信号;为了后续优化和使用方便,m_seq.h使用typedef将ap_int<1>设为'BIT'的别名;

m_seq.cpp中初始化一个'BIT'的数组code,长度为4,并赋予初值{0, 0,0,1};void m_seq(BIT * y)是最终m序列生成函数,变量y是函数的输出; m_seq中的实现逻辑也较为简单:

  1. 将code[0]赋值给y ;
  2. for循环,将code整体右移,并将for循环使用一个标签'SHIFT_REG'标记;
  3. 将原code[0]和原code[3]异或后的结果保存到code[3];

dd830f6308f661b83d95cb4814257787.png
图5 m_seq.cpp实现细节

在实现仿真和综合前,需要在项目的选项中做一个设置,让HLS的编译器知道该分析实现哪一个函数。

53645b4cf6cc3bb4a23d95bced3ee726.png
图6 Synthesis Setting

在Synthesis Setting的Top Function中,选择需要实现的函数m_seq();

m_seq_test.cpp里使用文件存储m_seq函数产生的结果,并与预期结果比较,根据比较结果判断输出结果是否正确;

在不做优化的情况下,经过C simulation和C synthesis后,可以看到HLS的分析结果;

0d9e151e7f0cd5d6afbfe3fdbc05fcd7.png
图7 实现结果

可以从图6看到,最终实现中,时钟预估是满足10ns周期的要求,整个运算周期,也就是输出数值更新周期为4,也就是4个时钟周期后才能更新一次m序列的输出结果;Utilization Estimates的Summary表格显示了最终生成的verilog代码所使用的的资源预估情况。

根据m序列的verilog实现以及使能信号解决跨时钟域问题可以知道,m序列的更新周期是可以达到0周期(也就是一个时钟周期输出一个数值);

所以还需要对HLS的代码进行优化,点击C Synthesis结果页面的Analysis标签,可以看到下图:

a4e363382141dc1121275b71b42c14fd.png
图8 Analysis

可以看到,for循环占用了一个时钟周期实现,而这个for循环其实只是简单的寄存器组左右移,是可以展开实现的。

回到m_seq.cpp,点击Directive标签,找到m_seq下的SHIFT_REG,右键点击'Insert Directive',Directive选择'UNROLL',点击OK;

c71f43c8d8893015dbe6e71ccfacec6b.png
图9 优化for循环

重新仿真综合之后,可以看到结果:

7c41872ad8255f4889d18750ffadbf67.png
图10 优化后的结果

可以与图7做对比,优化后Latency和资源占用都达到极致。

'UNROLL'在这里的作用是展开for循环,减小关键路径的Latency;可以看到展开for循环后,资源占用不仅没有增多,反而减少,这也许就是优化指令的魅力吧。

通过Project下的Export RTL,会产生一个zip的压缩文件;

0465ec090803c4aa0b9107183bc3e15f.png
图11 生成RTL IP核

将zip复制到Vivado项目文件夹下解压,在Vivado项目Project Setting下的IP标签的Repository里,将zip解压的文件夹加入进去;HLS的IP核就加入IP Catalog;

4a375b31f135fa403f724921371f9a90.png
图13 HLS IP核

VCS仿真中,我们不使用IP核,而直接中仿真源文件m_seq.v,Testbench采用m序列的verilog实现以及使能信号解决跨时钟域问题的仿真文件;

在解压文件夹的hdlverilog文件夹下,将m_seq.v做仿真;ap_clk,ap_rst连接时钟和复位信号,ap_start可以用作m序列的使能信号,实现高速时钟下的低速运行;y_V是m序列的输出数值,y_V_ap_vld是输出数据的有效信号值;

a5a0b34219fde3ef87f49ec2cd417765.png
图14 m_seq的例化

802f783ce62a78a539f39304f400bf1d.png
图15 仿真结果图

可以看到,图15的仿真图与m序列的verilog实现以及使能信号解决跨时钟域问题中的最终仿真结果一样。

第一次使用HLS生成verilog,欢迎各位给出更有建设性的意见。

学习HLS主要参考资料为Xilinx的UG871和UG902,关注BUG记录公众号回复102获取HLS的参考资料。

18e2dff45bb07ac4a956683da355fca0.png
微信号:BugRec

万物皆可卷积:(实现BPSK学习Verilog)2. m序列的verilog实现以及使能信号解决跨时钟域问题​zhuanlan.zhihu.com
68b46e058411868e61f1beb5bc2e9a1e.png
万物皆可卷积:(实现BPSK学习Verilog)1. Simulink仿真实现​zhuanlan.zhihu.com
68b46e058411868e61f1beb5bc2e9a1e.png
万物皆可卷积:(LVDS差分信号简单处理)5. 使用OSERDES发送高速串行数据​zhuanlan.zhihu.com
ad7cd648270116ebf60d5af3ec11cf3d.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值