FPGA数字信号处理基础----使用HLS生成信号

前言

  HLS 是Xilinx推出的高层次综合工具,可以用来加速算法的设计。我在之前,用这玩意儿做了些简单的图像算法的处理的,感觉还是比手撸Verilog代码要来的快一点,正好现在在学习数字信号处理,先拿HLS来进行一些简单的算法验证还是可以的。

1 使用HLS生成正余弦波形

1.1 使用matlab产生ram 中存储的波形数据

  产生正余弦信号的波形,其中采样频率40MHz,正余弦的频率为1.25MHz。生成将一个周期内的正余弦数据进行保存。

clear all; close all; clc;
Fs = 40*10^6;   %采样频率
Fcarrier = 1.25*10^6;   %载波速率
Fsymbol = 100*19^3;    %符号速率

t = 0 : Fcarrier/Fs : 1 - Fcarrier/Fs; % 一个周期内的的信号
y1 = 255*sin(2*pi*t);
y2 = 255*cos(2*pi*t);
y1 = round(y1);
y2 = round(y2);
fid = fopen('./rom.txt', 'w+');     %打开一个文件并写入
fprintf(fid, '%d ,', y1);
fprintf(fid, '\r\n');
fprintf(fid, '%d ,', y2);

subplot(211);plot(t,y1);title('正弦信号');
subplot(212);plot(t,y2);title('余弦信号');

在这里插入图片描述

2 HLS中完成信号的产生

  先把套路搞起来,HLS的主要步骤就是 C仿真,C综合,C-RTL的联合仿真

C仿真就是对C代码进行仿真,比如自己写了一个C的算法函数的实现,可以先给一个C的激励,来测试算法是否正确。C仿真通过后,就可以进行C综合。
C综合就是把C代码通过在HLS添加约束,最终能够对应上FPGA内部的资源。同时能够生成电路上对应的接口。
C-RTL cosimulation就是通过C仿真的代码,和RTL电路进行联合的仿真。这个过程,就和在FPGA开发中进行仿真是类似的。

  首先搞个头文件,这里面引入比较重要的数据类型 ap_int.h 这个头文件。在C/C++当中,存储数据都是以字节为单位的,因此,一个数据最少就需要使用8bit来表示。在FPGA中,可以对这个进行更加灵活的表示,位宽可以是任意的,这个 “ap_int.h” 就是这么一个可以自定义位宽的头文件。通过模板的形式,传递模板参数,生成不同的数据类型。

2.1 头文件

#ifndef __ASK_TX_H_
#define __ASK_TX_H_

#include "ap_int.h"

void ask_mod(ap_uint<1> symbol, ap_int<16> *sin, ap_int<16> *cos);

#endif

2.2 实现文件

  这个实现的文件,就是实现整个算法模块的主要部分。通过HLS的directive,添加对应的约束,可以调节接口的类型,时序的优化,内部资源的占用等等。。。

#include "tx_ask.h"

void ask_mod(ap_uint<1> symbol, ap_int<16> *sin, ap_int<16> *cos)
{
#pragma HLS PIPELINE II=1
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE axis register both port=cos
#pragma HLS INTERFACE axis register both port=sin
#pragma HLS INTERFACE axis register both port=symbol
	// counter for lookup table
	static ap_int<8> counter = 0;

	// lut store the wave
	ap_int<16> sin_table[32] = {0 ,50 ,98 ,142 ,180 ,212 ,236 ,250 ,
								255 ,250 ,236 ,212 ,180 ,142 ,98 ,50 ,
								0 ,-50 ,-98 ,-142 ,-180 ,-212 ,-236 ,-250 ,
								-255 ,-250 ,-236 ,-212 ,-180 ,-142 ,-98 ,-50 };
#pragma HLS RESOURCE variable=sin_table core=ROM_1P_BRAM latency=1

	ap_int<16> cos_table[32] = {255 ,250 ,236 ,212 ,180 ,142 ,98 ,50 ,
								0 ,-50 ,-98 ,-142 ,-180 ,-212 ,-236 ,-250 ,
								-255 ,-250 ,-236 ,-212 ,-180 ,-142 ,-98 ,-50 ,
								0 ,50 ,98 ,142 ,180 ,212 ,236 ,250 };
#pragma HLS RESOURCE variable=cos_table core=ROM_1P_BRAM latency=1

	if(symbol == 1)
	{
		*sin = sin_table[counter.range(4, 0)];
		*cos = cos_table[counter.range(4, 0)];
	}
	else
	{
		*sin = 0;
		*cos = 0;
	}
	// counter self increase
	counter += 1;

	// clear the counter
	if(counter == 32)
	{
		counter = 0;
	}
}

2.3 仿个真

  仿真比较简单啊,就是产生一些符号,然后调用前面的函数,实现不同波形的输出。

#include "tx_ask.h"

int main()
{
	ap_uint<1> symbol[64] = {0, 1, 1, 0, 0, 0, 1, 1,
							 0, 1, 1, 0, 0, 0, 1, 1,
							 0, 1, 1, 0, 0, 0, 1, 1,
							 0, 1, 1, 0, 0, 0, 1, 1,
							 0, 1, 1, 0, 0, 0, 1, 1,
							 0, 1, 1, 0, 0, 0, 1, 1,
							 0, 1, 1, 0, 0, 0, 1, 1,
							 0, 1, 1, 0, 0, 0, 1, 1,};
	ap_int<16> sin, cos;

	for(int i = 0; i < 64; i ++)
	{
		for(int j = 0; j < 400; j ++)
		{
			ask_mod(symbol[i], &sin, &cos);
		}

	}

	return 0;
}

3 结果

  最后就可以把仿真的结果拿出来看一看。
在这里插入图片描述
  可以看到,当符号为1的时候,就产生了正余弦波形,为0的时候,就没有正余弦产生。其实这个就有点ASK调制那味儿了。
在这里插入图片描述  可以看到,这里就产生了这么两个正余弦信号。去观察这个正余弦信号的话,可以发现他们的频率是1.25M

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值