FPGA FFT IP使用问题
在使用FFTIP核的时候,输出格式是Natural order ,输入的是8位的AD数据,参数如截图:(1)(2)
FFT例化的如下:
输入是
reg sink_real;
reg sink_imag;
FFT_IP输出的是18位
wire source_real;
wire source_imag;
输入FFT的AD数据除以2最高位取0,为正数
提问:输出的18位怎么处理得到可以送给下一级处理的数据,
下面的计算应该是除以128/2得到8位数据,怎样得到那个待除的数字??{:cry:} 能把河蟹文件共享一下啊
FFT输入的是信号的实部 与 虚部
输出两路 平方和 然后开更号就是 FFT结果的幅度值 本帖最后由 ctqvsly 于 2013-3-16 10:13 编辑
yuhang 发表于 2013-3-14 21:33 static/image/common/back.gif
能把河蟹文件共享一下啊
FFT输入的是信号的实部 与 虚部
能把你的工程分享一下吗?还有结果的位宽能解释一下吗?
只要将我的文件中网卡号,稍加修改即可 你好!我能请教一下您再做FFT IP核仿真的时候如果用QII自带的仿真软件 这样的话 输入数据要怎么设置。我现在写了一个状态机 控制其他信号输入 但是sink_real信号纠结了不知道怎么输入本想是做完AD采集再输入的 但是现在又急于先做这一块,请指教 stream 的 fft, 输出还有一个exp, 是2的指数,
fft megacore 输出的乘以 2^exp (即帯符号左移(<<<)exp位)得到fft原始定义的输出,
这个输出 要再除以 N(fft长度), 的到幅相谱(有实有虚), 幅度谱是其模, 相位谱是其幅角.
注意,其中除了直流和N/2位置,其它的谱都是有关于N/2位置对称的两个共轭值的,因此它们的幅度谱是两个共轭值的模的和,当然就是某一个的模的两倍.
loywong 发表于 2013-3-27 13:08 static/image/common/back.gif
stream 的 fft, 输出还有一个exp, 是2的指数,
fft megacore 输出的乘以 2^exp (即帯符号左移( ...
没看懂{:cry:} 能举例说明一下吗?
比如AD采样得到8位的数据输入,然后输出的17位怎么转换为十六进制的无符号数? 本帖最后由 loywong 于 2013-3-29 13:26 编辑
你用nios2吗?如果用需要sg-dma和一个stream的wrapper,这个我有做过的现成代码给你参考:
比较久远了,有些参数你自己看看。
先做一个fft,再用这个wrapper调用它:
module fft_avalon_wraper
(
input clk,
input reset_n,
input mm_address,
input mm_read,
output mm_readdate,
input mm_write,
input mm_writedate,
output sink_ready,
input sink_valid,
input sink_sop,
input sink_eop,
input sink_data,
input sink_empty,
input sink_error,
input source_ready,
output source_valid,
output source_sop,
output source_eop,
output source_data,
output source_empty,
output source_error
);
parameter WIDTH = 16;
reg inverse;
reg exponent;
wire source_exp;
assign mm_readdate = (mm_address == 1'b0) ? {exponent, exponent ,exponent} : {7'b0, inverse};
assign source_empty = 2'b0;
always@(posedge clk)
begin
if(~reset_n)
begin
inverse <= 1'b0;
exponent <= 6'b0;
end
else
begin
if(mm_write)
begin
inverse <= mm_writedate;
end
if(source_sop)
begin
exponent <= source_exp;
end
end
end
wire sink_data_xe;
wire source_data_xe;
localparam W = WIDTH * 2;
genvar i;
generate
for(i = 0; i < W; i = i + 8)
begin :xe_byte
assign sink_data_xe = sink_data;
assign source_data = source_data_xe;
end
endgenerate
fft thefft
(
clk,
reset_n,
inverse,
sink_valid,
sink_sop,
sink_eop,
sink_data_xe,
sink_data_xe,
sink_error,
source_ready,
sink_ready,
source_error,
source_sop,
source_eop,
source_valid,
source_exp,
source_data_xe,
source_data_xe
);
endmodule
然后做成一个memory map的slave外设,它有两个地址,地址0读出exp,地址1读出 是FFT或是IFFT变换,任何地址写0,表示做FFT,写1表示做IFFT。
sopc builder中做两个sg-dma,一个用于给fft送数据,另一个收fft数据。
软件:
#include <system.h>
#include <stdio.h>
#include <stdlib.h>
#include <altera_avalon_sgdma.h>
#include <altera_avalon_sgdma_regs.h>
#include <altera_avalon_sgdma_descriptor.h>
#include <altera_avalon_performance_counter.h>
#include "sys/alt_cache.h"
#include "sys/alt_sys_wrappers.h"
#define FFT_LEN 1024
alt_sgdma_dev *pPreFftDma;
alt_sgdma_descriptor *pPreFftDmaDescrs;
alt_sgdma_dev *pPostFftDma;
alt_sgdma_descriptor *pPostFftDmaDescrs;
#pragma pack(1)
typedef struct __ShortCplx
{
alt_16 Real;
alt_16 Imag;
} ShortCplx;
ShortCplx X;
ShortCplx F;
alt_8 Fexp;
alt_8 FftTransFinished = 0;
alt_8 FftRecvFinished = 0;
void createPreFftDmaDescr()
{
pPreFftDmaDescrs = (alt_sgdma_descriptor *)malloc(2 * sizeof(alt_sgdma_descriptor));
alt_avalon_sgdma_construct_mem_to_stream_desc(
pPreFftDmaDescrs,
pPreFftDmaDescrs + 1,
(alt_u32 *)X,
FFT_LEN * sizeof(ShortCplx),
0,
1,
1,
0);
}
void createPostFftDmaDescr()
{
pPostFftDmaDescrs = (alt_sgdma_descriptor *)malloc(2 * sizeof(alt_sgdma_descriptor));
alt_avalon_sgdma_construct_stream_to_mem_desc(
pPostFftDmaDescrs,
pPostFftDmaDescrs + 1,
(alt_u32 *)F,
0/*FFT_LEN * sizeof(ShortCplx)*/,
0);
}
static void preFftDma_ISR(void *pContext)
{
int i, ctrl;
ctrl = IORD_ALTERA_AVALON_SGDMA_STATUS(pPreFftDma->base);
if(ctrl & ALTERA_AVALON_SGDMA_STATUS_CHAIN_COMPLETED_MSK)
{
i = 1;
FftTransFinished = 1;
}
}
static void postFftDma_ISR(void *pContext)
{
int i, ctrl;
ctrl = IORD_ALTERA_AVALON_SGDMA_STATUS(pPostFftDma->base);
if(ctrl & ALTERA_AVALON_SGDMA_STATUS_EOP_ENCOUNTERED_MSK)
{
i = 1;
FftRecvFinished = 1;
}
}
int main()
{
alt_u32 control;
int i;
printf("Hello from Nios II!\n");
pPreFftDma = alt_avalon_sgdma_open(SGDMA_PREFFT_NAME);
pPostFftDma = alt_avalon_sgdma_open(SGDMA_POSTFFT_NAME);
alt_avalon_sgdma_register_callback(
pPreFftDma,
preFftDma_ISR,
ALTERA_AVALON_SGDMA_CONTROL_IE_GLOBAL_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK,
NULL);
alt_avalon_sgdma_register_callback(
pPostFftDma,
postFftDma_ISR,
ALTERA_AVALON_SGDMA_CONTROL_IE_GLOBAL_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_EOP_ENCOUNTERED_MSK,
NULL);
createPreFftDmaDescr();
createPostFftDmaDescr();
control = IORD_ALTERA_AVALON_SGDMA_CONTROL(pPreFftDma->base);
control |= ALTERA_AVALON_SGDMA_CONTROL_PARK_MSK;
IOWR_ALTERA_AVALON_SGDMA_CONTROL(pPreFftDma->base, control);
control = IORD_ALTERA_AVALON_SGDMA_CONTROL(pPostFftDma->base);
control |= ALTERA_AVALON_SGDMA_CONTROL_PARK_MSK;
IOWR_ALTERA_AVALON_SGDMA_CONTROL(pPostFftDma->base, control);
for(i = 0; i < FFT_LEN; i++)
{
X.Imag = 0;
if(i < FFT_LEN / 2)
{
X.Real = 32767;
}
else
{
X.Real = -32767;
}
}
alt_dcache_flush((void *)X, FFT_LEN * sizeof(ShortCplx));
PERF_RESET(PFC_BASE);
PERF_START_MEASURING(PFC_BASE);
PERF_BEGIN(PFC_BASE, 1);
alt_avalon_sgdma_do_async_transfer(pPostFftDma, pPostFftDmaDescrs);
alt_avalon_sgdma_do_async_transfer(pPreFftDma, pPreFftDmaDescrs);
while(1)
{
if(FftRecvFinished)
{
PERF_END(PFC_BASE, 1);
FftRecvFinished = 0;
alt_dcache_flush((void *)F, FFT_LEN * sizeof(ShortCplx));
Fexp = IORD(FFT_AVALON_BASE, 0);
PERF_STOP_MEASURING(PFC_BASE);
perf_print_formatted_report((void *)PFC_BASE, alt_get_cpu_freq(), 1, "FFT");
PERF_RESET(PFC_BASE);
PERF_START_MEASURING(PFC_BASE);
alt_avalon_sgdma_do_async_transfer(pPostFftDma, pPostFftDmaDescrs);
alt_avalon_sgdma_do_async_transfer(pPreFftDma, pPreFftDmaDescrs);
PERF_BEGIN(PFC_BASE, 1);
}
}
return 0;
}
当中有大量sg-dma的操作,特别是描述符链表,请到altera.com上搜其user guide并自行理解。
如有那条不明白,上altera.com搜之。如果你没有用sopc系统和nios2软核的经验,可能需要学的还很多。
如果单纯用逻辑写stream if,会稍麻烦,我没做过,不敢妄言。 loywong 发表于 2013-3-29 13:24 static/image/common/back.gif
你用nios2吗?如果用需要sg-dma和一个stream的wrapper,这个我有做过的现成代码给你参考:
比较久远了,有 ...
太谢谢啦,正需要! mark,很不错的帖子! 飞鹤王子 发表于 2013-4-24 12:39 static/image/common/back.gif
mark,很不错的帖子!
LZ 我现在调试 Altera FFT IP Burst 架构出现了和官方提供的Testbench不一样的结果,但是source_erro 没有报错 ctqvsly 发表于 2013-3-27 20:51 static/image/common/back.gif
没看懂 能举例说明一下吗?
比如AD采样得到8位的数据输入,然后输出的17位怎么转换为十六进制的无 ...
LZ 我现在调试 Altera FFT IP Burst 架构出现了和官方提供的Testbench不一样的结果,但是source_erro 没有报错
YA1W@Y$ZEKOG)`TA5QYTD{S.jpg (281.65 KB, 下载次数: 0)
激励给的是直流 幅值为1
Laden 发表于 2013-4-30 12:29 static/image/common/back.gif
LZ 我现在调试 Altera FFT IP Burst 架构出现了和官方提供的Testbench不一样的结果,但是source_erro 没 ...
我也没看懂~ 实部和虚部上出现的类似噪声的是什么啊? 不错有空研究一下 ctqvsly 发表于 2013-4-30 16:00 static/image/common/back.gif
我也没看懂~ 实部和虚部上出现的类似噪声的是什么啊?
谢谢 调试出来了 是我在后仿真的时候 时钟频率 太高了 不错, 有收获 ,晚上这方面的资料太少了 网上 请问一下要如何用ModelSim仿真 FFT ip core呢? liyusnoopy 发表于 2013-8-22 10:02 static/image/common/back.gif
请问一下要如何用ModelSim仿真 FFT ip core呢?
自己百度搜试试,网上有教程 想问一下,你的FFT ip 核的数据输出处理好了吗?是像楼上那位给的用NIOS实现的处理吗? liyusnoopy 发表于 2013-8-22 20:59
想问一下,你的FFT ip 核的数据输出处理好了吗?是像楼上那位给的用NIOS实现的处理吗? ...
没有,直接串口打印,和da输出波形,留着以后备用,现考研没时间搞~ ctqvsly 发表于 2013-8-22 22:27 static/image/common/back.gif
没有,直接串口打印,和da输出波形,留着以后备用,现考研没时间搞~
楼主能否分享一下!!! 正在用,正好看一下
页:
[1]