换一种心态来发一篇关于用FPGA实现FFT的帖子
最近在学习用FFT实现FPGA变化,看了user guide,也看了很多网上各家朋友的资料,在这个过程我,我发现我们论坛在这方面内容不是很多,而由一种现象就是,很多帖子都是很多新手在遇到问题时发的求救贴,大呼什么跪求什么资料啊,跪等高手解决之类的,以前我呀发过这种贴,但是后来我发现这种贴最终一般自己收获的东西也很少,浏览帖子的人收获的也很少,所以今天我想换一种心态来发一篇帖子,这不是求救贴,而是希望为论坛里的人,有经验的也会,菜鸟也罢,提供一个交流得窝,再说了,哪个高手不是从菜鸟变来的,所以这里没有蔑视,没有对错,只有交流!!!自己接触FPGA也零零散散差不多半年了,当初只是为了做一个PSD四象限光斑位置探测系统,里面要用到FPGA去控制AD转换芯片和USB接口芯片,所以就学习了FPGA,因为我不是电子类专业的,所以周围基本没有搞FPGA得,说实话,一个人摸索,从前面的运算电路设计,到AD转换,到FPGA,到EZ-USB传输,到MFC编程,半年前,我真的有些闻所未闻,有些只在书上见过,到现在自己差不多完成了这个系统,真的够艰苦的。哪怕,就像个Quartus软件,我想要是有个会用的人指点一下,一两个周就会用了,但是我自己一点一点啃,靠得是坚持。从VHDL(Verilog)到NIOS,反正自己的信念就是趁年轻的时候多学点东西,以希望下面的这个话题,经验之士不吝赐教,不懂之人洗耳恭听,大家一起的目的就是交流,就是让论坛真的成为一个五湖四海的兄弟姐妹们学习的圣地。
结束那个PSD系统之后,又有一个新想法,就是想用FPGA做图像处理,实现一些较复杂的算法,FFT(快速傅里叶变换)就是其中很重要的一种,于是自己开始去学习了一段时间,现在把自己的过程和想法罗列在下面:
一、当今在电子系统中实现FFT算法的途径大致有:
1、DSP芯片:其实,到目前为止,DSP芯片仍然是最重要的实现复杂算法的芯片,但是其电路复杂,而且速度问题一直是它致命的瓶颈,当然,FFT对于DSP来说,已经比较成熟了,所以也正因为这样,我想用FPGA来挑战一下自己。
2、FPGA芯片:近好几年,FPGA真正崛起了,尤其Xlinx和ALTERA公司的FPGA也能实现一些复杂的算法,它的特点就是速度比DSP快很多,由于我接触的是Atera公司的产品,所以我主要谈论它。用Atera公司的FPGA芯片实现FFT也有两个途径:
(1)用NIOS软核,自己构架一个FFT系统,分模块用C语言编程实现。
(2)直接使用Atera公司的FFT IP核,这是一个高效的FFT变换模块。
二、我想用FPGA来实现FFT,所以当然要嘛就是用NIOS软核,用C编程,要嘛就是用FFT IP核,关于如何选择,这里我还想请教大家:
NIOS软核实现较直接用现成的IP核当然要复杂许多,但是我想知道的关键是NIOS软核实现的速度会不会比FFT IP核的速度慢很多,因为我做这个FFT的首要目标就是快速,但是这个疑惑我至今都不是很清楚。
三、这几天,研究了下FFT IP核,但一直没有仿真成功,这个学习的过程我大致给大家说一下:
1、看了FFT的user guide,了解FFT IP的工作时序。
2、学习了NIOS系统,由于之前我的PSD系统才刚接触FPGA,而且那个要用到的都是简单的VHDL语言编写的整个程序,没有涉及NIOS系统,所以自己决定学习它,什么不会就学什么,为以后做准备,学习的是《NIOS 那些事》。
3、开始仿真FFT IPcore,前面已经基本知道了它的工作时序,由于它工作时需要激励的,所以要涉及Modelsim仿真,以前也只是用一下Quartus自带的仿真,所以又为此下载破_解Modelsim SE 6.5g,一副准备要大干一场的气势,准备把这个FFT IPCore仿真出来。
4、后来又知道,Modelsim仿真Quartus工程,有两种方法,一是在Quartus里面调用Modelsim,二是把Quartus编译生成的一些文件拷贝到Modelsim工程目录下,然后编译仿真库,进行仿真。关于这两种仿真我分别找到了两篇网上的文章:
一是关于Modelsim里面仿真的:http://blog.ednchina.com/liuchang5772/283677/message.aspx
一是在Quartus里面调用Modelsim的:点击此处下载 ourdev_664257NY4PEN.rar(文件大小:292K) (原文件名:Quartus中fft_ip_core的使用.rar)
5、当然,网上还有很多这些文章,但是都是他们做成功了,但是留下来的却是新手们没法直接使用的经验,就像4里我讲的简单的过程,我没仿真成功,但我也能说出这个实现的过程。这两篇相对好点。
6、话说,我就照着这两篇帖子去做了,两个仿真都试了,都没成:
(1)第一个网站里面的内容,着重于去讲过程,而实现的细节忽略了,他把看文章的人都当成了高手,呵呵,比如里面的编译库就折腾了我老半天,当这些问题都解决了之后,最后还是仿真得一塌糊涂,得不到结果。我把工程附在下面:
点击此处下载 ourdev_664263BX0STT.rar(文件大小:3.71M) (原文件名:Modelsim.rar)
(2)第二种方式,我也看懂了,他有三个vhdl文件,一个是为fft ip核(fft_burst)提供控制信号的模块,即ctrl_fft,主要是通过一个clk时钟和reset_n复位信号以及fft_burst产生的应答信号sink_ready,从而产生sink_sop,sink_eop,sink_valid时序。顶层模块是fft256,它主要是例化ctrl_fft和fft_burst模块成一个顶层模块,即fft256模块,封装好后的输入信号有clk,reset_n,sink_real,输出信号有sink_valid,sink_sop,sink_eop,sink_real,sink_ready,source_error,source_sop,source_eop,source_valid,source_exp,source_real,source_imag。而还有一个fft256_vhd_tst.vhd文件,这个文件是供Modelsim仿真用的,它的作用是给fft256模块三个输入信号产生激励,clk为10MHZ时钟,reset_n为复位信号,sink_real是一个128个时钟周期改变一次的供转换的数据的实部。
然而篇文档,讲到仿真就戛然而止了,貌似认为就成功了,然后对于想对modelsim还不熟练的人来说,其实还离成功差点距离。每次仿真都有如下警告: ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 nsIteration: 2Instance: /fft256/u1/n1oiol
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 nsIteration: 2Instance: /fft256/u1/n1oilo
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 nsIteration: 2Instance: /fft256/u1/n1oilo
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).
# Time: 0 nsIteration: 2Instance: /fft256/u1/n1oioo
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
后来查阅了说是modelsim仿真和quartus仿真不一样,需要为信号赋上初值,我特意为此又冲新分析了一下那三个vhdl程序,理清了他们的关系,把自己认为应该赋初值都赋上了,可反反复复修改很多遍,还是没有仿真成功,这些警告依然存在,仿真也得不到结果。
最后,我想说的是,我只是想以此引出这个话题,希望大家就这个用FPGA实现FFT的话题,踊跃发言,不要忽略实现过程中的细节,因为来学习的毕竟都是才接触FPGA不久的。
真心希望这个论坛能更活跃,呵呵。 顶 虽然走的是不同方向,也是这么过来的 --- 个人觉得在用FPGA实现FFT之前,先复习下数字信号分析基础内容
例如DFT等等的 点击此处下载 ourdev_664278XLOK5M.rar(文件大小:4.70M) (原文件名:fft8_copy.rar)
这是我一年前自己写的一个8点FFT,因为当时时间不是很多,自己从头到尾的进行摸索,主要是理论感觉不是很好理解,然后就找了大把参考书,弄懂了理论之后才去动手写代码,参考网上的一些例子,终于还是给我成功了,虽然弄的是比较简单的,代码也比较不简洁,所有都放在一个文件了,很不好的习惯,但起码也是完成了,之后就没进一步深入研究了,
希望这个小小资料能给需要的人一点点的帮助,哪怕很渺小
module fft8 ( r_in,i_in,r_out,i_out,clk,rst_n );
input r_in,i_in;
input clk,rst_n;
output r_out,i_out;
reg r_out,i_out;
reg r0_in_reg,i0_in_reg;
reg r1_in_reg,i1_in_reg;
reg r2_in_reg,i2_in_reg;
wire r0_out_reg,i0_out_reg;
wire r1_out_reg,i1_out_reg;
wire r2_out_reg,i2_out_reg;
wire r0_out_reg55,r0_out_reg77;
wire i0_out_reg55,i0_out_reg77;
integer k0,k1,k2;
reg count;
reg count_in;
//////////////////////////////////////////////////////////////////////////////////////////////////STATE0
lpm_add_sub0 r0_0(.add_sub(1'b1),.dataa(r0_in_reg),.datab(r0_in_reg),.result(r0_out_reg));
lpm_add_sub0 r0_1(.add_sub(1'b1),.dataa(r0_in_reg),.datab(r0_in_reg),.result(r0_out_reg));
lpm_add_sub0 r0_2(.add_sub(1'b1),.dataa(r0_in_reg),.datab(r0_in_reg),.result(r0_out_reg));
lpm_add_sub0 r0_3(.add_sub(1'b1),.dataa(r0_in_reg),.datab(r0_in_reg),.result(r0_out_reg));
lpm_add_sub0 r0_4(.add_sub(1'b0),.dataa(r0_in_reg),.datab(r0_in_reg),.result(r0_out_reg));
lpm_add_sub0 r0_5(.add_sub(1'b0),.dataa(r0_in_reg),.datab(r0_in_reg),.result(r0_out_reg));
lpm_add_sub0 r0_6(.add_sub(1'b0),.dataa(r0_in_reg),.datab(r0_in_reg),.result(r0_out_reg));
lpm_add_sub0 r0_7(.add_sub(1'b0),.dataa(r0_in_reg),.datab(r0_in_reg),.result(r0_out_reg));
lpm_add_sub0 r0_55(.add_sub(1'b1),.dataa(shift07(r0_out_reg)),.datab(shift07(i0_out_reg)),.result(r0_out_reg55));
lpm_add_sub0 r0_77(.add_sub(1'b0),.dataa(shift07(i0_out_reg)),.datab(shift07(r0_out_reg)),.result(r0_out_reg77));
lpm_add_sub0 i0_0(.add_sub(1'b1),.dataa(i0_in_reg),.datab(i0_in_reg),.result(i0_out_reg));
lpm_add_sub0 i0_1(.add_sub(1'b1),.dataa(i0_in_reg),.datab(i0_in_reg),.result(i0_out_reg));
lpm_add_sub0 i0_2(.add_sub(1'b1),.dataa(i0_in_reg),.datab(i0_in_reg),.result(i0_out_reg));
lpm_add_sub0 i0_3(.add_sub(1'b1),.dataa(i0_in_reg),.datab(i0_in_reg),.result(i0_out_reg));
lpm_add_sub0 i0_4(.add_sub(1'b0),.dataa(i0_in_reg),.datab(i0_in_reg),.result(i0_out_reg));
lpm_add_sub0 i0_5(.add_sub(1'b0),.dataa(i0_in_reg),.datab(i0_in_reg),.result(i0_out_reg));
lpm_add_sub0 i0_6(.add_sub(1'b0),.dataa(i0_in_reg),.datab(i0_in_reg),.result(i0_out_reg));
lpm_add_sub0 i0_7(.add_sub(1'b0),.dataa(i0_in_reg),.datab(i0_in_reg),.result(i0_out_reg));
lpm_add_sub0 i0_55(.add_sub(1'b0),.dataa(shift07(i0_in_reg)),.datab(shift07(r0_in_reg)),.result(i0_out_reg55));
lpm_add_sub0 i0_77(.add_sub(1'b1),.dataa(shift07(r0_in_reg)),.datab(shift07(i0_in_reg)),.result(i0_out_reg77));
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////STATE1
lpm_add_sub0 r1_0(.add_sub(1'b1),.dataa(r1_in_reg),.datab(r1_in_reg),.result(r1_out_reg));
lpm_add_sub0 r1_1(.add_sub(1'b1),.dataa(r1_in_reg),.datab(r1_in_reg),.result(r1_out_reg));
lpm_add_sub0 r1_2(.add_sub(1'b0),.dataa(r1_in_reg),.datab(r1_in_reg),.result(r1_out_reg));
lpm_add_sub0 r1_3(.add_sub(1'b0),.dataa(r1_in_reg),.datab(r1_in_reg),.result(r1_out_reg));
lpm_add_sub0 r1_4(.add_sub(1'b1),.dataa(r1_in_reg),.datab(r1_in_reg),.result(r1_out_reg));
lpm_add_sub0 r1_5(.add_sub(1'b1),.dataa(r1_in_reg),.datab(r1_in_reg),.result(r1_out_reg));
lpm_add_sub0 r1_6(.add_sub(1'b0),.dataa(r1_in_reg),.datab(r1_in_reg),.result(r1_out_reg));
lpm_add_sub0 r1_7(.add_sub(1'b0),.dataa(r1_in_reg),.datab(r1_in_reg),.result(r1_out_reg));
lpm_add_sub0 i1_0(.add_sub(1'b1),.dataa(i1_in_reg),.datab(i1_in_reg),.result(i1_out_reg));
lpm_add_sub0 i1_1(.add_sub(1'b1),.dataa(i1_in_reg),.datab(i1_in_reg),.result(i1_out_reg));
lpm_add_sub0 i1_2(.add_sub(1'b0),.dataa(i1_in_reg),.datab(i1_in_reg),.result(i1_out_reg));
lpm_add_sub0 i1_3(.add_sub(1'b0),.dataa(i1_in_reg),.datab(i1_in_reg),.result(i1_out_reg));
lpm_add_sub0 i1_4(.add_sub(1'b1),.dataa(i1_in_reg),.datab(i1_in_reg),.result(i1_out_reg));
lpm_add_sub0 i1_5(.add_sub(1'b1),.dataa(i1_in_reg),.datab(i1_in_reg),.result(i1_out_reg));
lpm_add_sub0 i1_6(.add_sub(1'b0),.dataa(i1_in_reg),.datab(i1_in_reg),.result(i1_out_reg));
lpm_add_sub0 i1_7(.add_sub(1'b0),.dataa(i1_in_reg),.datab(i1_in_reg),.result(i1_out_reg));
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////STATE2
lpm_add_sub0 r2_0(.add_sub(1'b1),.dataa(r2_in_reg),.datab(r2_in_reg),.result(r2_out_reg));
lpm_add_sub0 r2_1(.add_sub(1'b0),.dataa(r2_in_reg),.datab(r2_in_reg),.result(r2_out_reg));
lpm_add_sub0 r2_2(.add_sub(1'b1),.dataa(r2_in_reg),.datab(r2_in_reg),.result(r2_out_reg));
lpm_add_sub0 r2_3(.add_sub(1'b0),.dataa(r2_in_reg),.datab(r2_in_reg),.result(r2_out_reg));
lpm_add_sub0 r2_4(.add_sub(1'b1),.dataa(r2_in_reg),.datab(r2_in_reg),.result(r2_out_reg));
lpm_add_sub0 r2_5(.add_sub(1'b0),.dataa(r2_in_reg),.datab(r2_in_reg),.result(r2_out_reg));
lpm_add_sub0 r2_6(.add_sub(1'b1),.dataa(r2_in_reg),.datab(r2_in_reg),.result(r2_out_reg));
lpm_add_sub0 r2_7(.add_sub(1'b0),.dataa(r2_in_reg),.datab(r2_in_reg),.result(r2_out_reg));
lpm_add_sub0 i2_0(.add_sub(1'b1),.dataa(i2_in_reg),.datab(i2_in_reg),.result(i2_out_reg));
lpm_add_sub0 i2_1(.add_sub(1'b0),.dataa(i2_in_reg),.datab(i2_in_reg),.result(i2_out_reg));
lpm_add_sub0 i2_2(.add_sub(1'b1),.dataa(i2_in_reg),.datab(i2_in_reg),.result(i2_out_reg));
lpm_add_sub0 i2_3(.add_sub(1'b0),.dataa(i2_in_reg),.datab(i2_in_reg),.result(i2_out_reg));
lpm_add_sub0 i2_4(.add_sub(1'b1),.dataa(i2_in_reg),.datab(i2_in_reg),.result(i2_out_reg));
lpm_add_sub0 i2_5(.add_sub(1'b0),.dataa(i2_in_reg),.datab(i2_in_reg),.result(i2_out_reg));
lpm_add_sub0 i2_6(.add_sub(1'b1),.dataa(i2_in_reg),.datab(i2_in_reg),.result(i2_out_reg));
lpm_add_sub0 i2_7(.add_sub(1'b0),.dataa(i2_in_reg),.datab(i2_in_reg),.result(i2_out_reg));
/////////////////////////////////////////////////////////////////////////////////////////////////////
function shift07;//乘以0.7071
input xn;
begin
shift07={xn,xn}+ {xn, xn, xn,xn}
+ {xn, xn, xn, xn, xn}
+ {xn, xn, xn, xn, xn, xn, xn}
+ {xn, xn, xn, xn, xn, xn,
xn, xn,xn}+{xn, xn, xn, xn,
xn, xn, xn, xn, xn, xn,
xn, xn, xn, xn,xn};
end
endfunction
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
count <= 6'b0;
else if ( count==6'd39 )
count <= 6'b0;
else
count <= count + 1'b1;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
count_in <= 5'b0;
else if ( count_in==5'd31 )
count_in <= 5'b0;
else
count_in <= count_in + 1'b1;
end
always @ ( posedge clk or negedge rst_n ) begin //data_in
if ( !rst_n )
for (k0=0;k0<=7;k0=k0+1) begin
r0_in_reg <= 16'b0;
i0_in_reg <= 16'b0;
end
else if(count_in<=7)
begin
r0_in_reg <= r_in;
i0_in_reg <= i_in;
end
end
always @ ( posedge clk or negedge rst_n ) begin //control
if ( !rst_n ) begin
r_out <= 0;
i_out <= 0;
end
else
case ( count )
/////////////////////////////////////////////////////////DATA_IN
/* 6'd0: begin
r0_in_reg <= r_in;
i0_in_reg <= i_in;
end
6'd1: begin
r0_in_reg <= r_in;
i0_in_reg <= i_in;
end
6'd2: begin
r0_in_reg <= r_in;
i0_in_reg <= i_in;
end
6'd3: begin
r0_in_reg <= r_in;
i0_in_reg <= i_in;
end
6'd4: begin
r0_in_reg <= r_in;
i0_in_reg <= i_in;
end
6'd5: begin
r0_in_reg <= r_in;
i0_in_reg <= i_in;
end
6'd6: begin
r0_in_reg <= r_in;
i0_in_reg <= i_in;
end
6'd7: begin
r0_in_reg <= r_in;
i0_in_reg <= i_in;
end
*/
//////////////////////////////////////////////////////////STATE0
6'd8: begin
r1_in_reg <= r0_out_reg;
i1_in_reg <= i0_out_reg;
end
6'd9: begin
r1_in_reg <= r0_out_reg;
i1_in_reg <= i0_out_reg;
end
6'd10: begin
r1_in_reg <= r0_out_reg;
i1_in_reg <= i0_out_reg;
end
6'd11: begin
r1_in_reg <= r0_out_reg;
i1_in_reg <= i0_out_reg;
end
6'd12: begin
r1_in_reg <= r0_out_reg;
i1_in_reg <= i0_out_reg;
end
6'd13: begin
r1_in_reg <= r0_out_reg55;
i1_in_reg <= i0_out_reg55;
end
6'd14: begin
r1_in_reg <= i0_out_reg;
i1_in_reg <= {~r0_out_reg+1};
end
6'd15: begin
r1_in_reg <= r0_out_reg77;
i1_in_reg <= ~i0_out_reg77;//////////////
end
//////////////////////////////////////////////////////////////STATE1
6'd16: begin
r2_in_reg <= r1_out_reg;
i2_in_reg <= i1_out_reg;
end
6'd17: begin
r2_in_reg <= r1_out_reg;
i2_in_reg <= i1_out_reg;
end
6'd18: begin
r2_in_reg <= r1_out_reg;
i2_in_reg <= i1_out_reg;
end
6'd19: begin
r2_in_reg <= i1_out_reg;
i2_in_reg <= {~r1_out_reg+1};
end
6'd20: begin
r2_in_reg <= r1_out_reg;
i2_in_reg <= i1_out_reg;
end
6'd21: begin
r2_in_reg <= r1_out_reg;
i2_in_reg <= i1_out_reg;
end
6'd22: begin
r2_in_reg <= r1_out_reg;
i2_in_reg <= i1_out_reg;
end
6'd23: begin
r2_in_reg <= i1_out_reg;
i2_in_reg <= {~r1_out_reg+1};
end
///////////////////////////////////////////////////////////////////STATE2
6'd24: begin
r_out <= r2_out_reg;
i_out <= i2_out_reg;
end
6'd25: begin
r_out <= r2_out_reg;
i_out <= i2_out_reg;
end
6'd26: begin
r_out <= r2_out_reg;
i_out <= i2_out_reg;
end
6'd27: begin
r_out <= r2_out_reg;
i_out <= i2_out_reg;
end
6'd28: begin
r_out <= r2_out_reg;
i_out <= i2_out_reg;
end
6'd29: begin
r_out <= r2_out_reg;
i_out <= i2_out_reg;
end
6'd30: begin
r_out <= r2_out_reg;
i_out <= i2_out_reg;
end
6'd31: begin
r_out <= r2_out_reg;
i_out <= i2_out_reg;
end
default: begin
r_out <= 16'b0;
i_out <= 16'b0;
end
endcase
end
endmodule 回复【3楼】qwerttt
-----------------------------------------------------------------------
呵呵,楼上说得是,我刚学了这些课程,呵呵 回复【4楼】maqingbiao
-----------------------------------------------------------------------
谢谢这位兄弟了,这么热心,我都说了,呵呵,贵在交流。这个程序你是在什么芯片里面实现的,呵呵,好像没用到NIOS,也没用IP核,呵呵,自己写的,自己动手,丰衣足食,呵呵。 回复【5楼】dltyy
-----------------------------------------------------------------------
不过确实,搞这些首先要点FFT方面的专业知识,这个才是实,而这些工程都是把理论转化成实践,只有理论弄懂了,实践才有意义。 回复【6楼】dltyy
-----------------------------------------------------------------------
这是个很简单的实例而已 都是Verilog 完成的啊 单独的FFT实现过程而已没应用,也没做好接口,就仅仅是完成算法那部分 记号! 回复【8楼】maqingbiao
-----------------------------------------------------------------------
好的,我一定会好好看的。呵呵 mark 马克思 mark! 希望明天能有更多的人来交流,提问题的,回答问题的,分享经验与成果的。 我继续发一点:
昨天着重说的是IP 核的方法,今天说一下NIOS的方法。
1、我昨天问了一个问题,问是不是NIOS的方法比用现成的IPcore慢,我想这是当然的,但是并不意味着NIOS就不好,NIOS也可以通过用户定制指令的办法来将比较耗费时间的FFT变换种的复数乘法,加法等算法用hdl语言在quartus中编写模块来实现,然后定制成指令,在NIOS中调用,就相当于C语言中的子函数一样,既方便,又加快了执行速度。
我不想这个贴就沉了,希望有经验的人把自己做过的经验给新人们分享分享! 这个帖子,xilinx的片子,硬件FFT,用了MicroBlaze控制,带VGA显示波形与FFT结果的,楼主可以看下。。。
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4934068&bbs_page_no=1&bbs_id=1029 没做过,帮顶。 回复【16楼】sdu1028
-----------------------------------------------------------------------
谢了。 多谢楼主的文章, 学习了。 IP核我也仿真过,好是好,只是串行的。 回复【20楼】02013063
-----------------------------------------------------------------------
你用的什么仿真,工程还在吗?能不能介绍一下。 jihao 回复【21楼】dltyy
-----------------------------------------------------------------------
那都是好久前的事了。
当时我用Quartus自带的仿真器仿真的,没用modelsim
后来方案改动,用IP核的方案被否定了。
关键是表示开始和结束俩个信号要对准了,应该就没啥问题。 回复【23楼】02013063
-----------------------------------------------------------------------
自带的IP核为什么被否了呢?那后来你们用的什么实现的? 回复【24楼】dltyy
-----------------------------------------------------------------------
IP核对于项目来说,并不适合
1.虽然速度快,但是是串行工作的。
2.N点的FFT核,相邻的两个N点是不重合的,而希望的FFT工作的时候应该相邻的两个N点有N-1个重合
后来用的解决方法是编写符合项目需要的FFT算法。点数少点也可以忍受。 回复【25楼】02013063
-----------------------------------------------------------------------
谢谢楼上的热心分享:
1、我按你说的,又硬着头皮静下心来用Quartus 9.1自带的仿真,最终得到了结果,64点,8位的FFT IP核,把工程(带有仿真文件)与大家分享:
点击此处下载 ourdev_664951BG7OPG.rar(文件大小:8.27M) (原文件名:FFT_sim.rar)
2、还有个问题想请教楼上:你们最终的算法是用HDL语言实现的还是NIOS 实现的?工程还能找到与大家分享吗?不胜感激! 回复【26楼】dltyy
-----------------------------------------------------------------------
nios速度太慢,最终方案是用语言写的,时间过了好久了,那个工程已经找不到了,抱歉
而且我机子里的quartus好像出问题了,昨天想回味下当年仿过的FFT核,居然仿不了了,奇怪的很 有没有fpga实现的fft的资料呢? mark 回复【26楼】dltyy
--------------------------------------------------------------------
这个工程仿真输入信号好像没设置好吧,没有输出 回复【14楼】dltyy
-----------------------------------------------------------------------
楼主和我好像啊。 我也是闷头研究了3天~ 你分享的那几个 程序我也都找到了~
基本情况就是把上边的时序图照搬下来~ 也没有结果~ 很是苦闷~刚刚看了一下你发表的时间~ 竟然是最近~ 非常让我兴奋~
加我扣扣261153494我最近 也是做项目 FFT 不得不做明白~ 希望和你一同攻坚 回复【5楼】dltyy
-----------------------------------------------------------------------
为了一个项目 从头学NIOS袄。。代价有点大了吧~ http://littlestone06.blog.163.com/blog/static/510672292008712114850993/ 这个网址也不错 我下一步准备~ 研究IP核的FIR滤波器~ 楼主有没有兴趣一起搞 呵呵 mark 回复【30楼】cafppla
-----------------------------------------------------------------------
细看是有的,不要拖动那个滚动条快了……有周期性的输出 http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_665287XMWTVH.png
(原文件名:QQ截图未命名.png)
楼主。打开工程出现这个 是什么情况? 回复【28楼】brahen 柏
-----------------------------------------------------------------------
点击此处下载 ourdev_665286XW4F5Y.rar(文件大小:38.98M) (原文件名:FFT.rar) 回复【37楼】dltyy
--------------------------------------------------------
为什么我的没输出?反而那个错误的引脚有一个输出,能否将你的仿真时序图贴上? FFT核使用的时候只需要按照接口时许往里面灌输据就行了,本人用的是Xilinx的器件及IP核,没有问题;
至于搂主说到的Modelsim仿真问题,主要还是软件使用的问题,多看看教程就明白了,如果使用Xilinx的器件,建议在ISE里面调用Modelsim,用户只需准备好激励就OK,其他的工作诸如仿真脚本之类ISE已经自动生成了; 楼主的想法跟我的不谋而合了,最近我也在学习fft,但是基于理论的薄弱,所以我决定先将理论吃透了,再做深入的学习,我也没打算用软核,正如楼主说的,fft追求的是速度,用fpga就是因为看中了他是纯硬件的,处理速度特别快,如果加上软核的话,就和跑程序 类的一样的了,所以要做最好还是纯硬件的比较好。 回复【27楼】02013063
-----------------------------------------------------------------------
我这两天仔细研究了一下算法,4楼哥们贴上来的8点的FFT我也仔细读了,确实感觉到了楼上说的这个问题,串行的接收数据这个问题,你们当时是怎么解决这个问题的? 回复【42楼】cj501813910
-----------------------------------------------------------------------
QQ:983482673.欢迎交流。 回复【40楼】cafppla
-----------------------------------------------------------------------
你说的是错误的source error引脚?我刚试了一下,有输出的,但是我随便给的激励,变换后的值不好,没有4楼兄弟贴上来的自己编的8fft的输出那么好看, 回复【40楼】cafppla
-----------------------------------------------------------------------
这是我刚试过的:
点击此处下载 ourdev_665544ZYKC62.rar(文件大小:8.28M) (原文件名:FFT IP 64.rar) 回复【41楼】philoman
-----------------------------------------------------------------------
呵呵,确实说的有道理,就是新手有些细节自己老是发现不了问题在哪里。 今天想提出点疑惑,希望慷慨为小弟解惑:
1、FFT算法里面,一个问题就是输入输出,只能是串行的吗?有没有什么办法?
2、刚开始我还想一级一级的嵌套模块化,就是先编个8点的模块,然后一个16点的模块(里面封装2个8点的模块),然后一个32点的模块(里面封装2个16点的模块)......这样一级一级的模块化,后来一想,这样光是输入就是个麻烦事,串行,从高一级到第一级还得在高级模块里面串行输入低级模块,这样效率低……有没有什么办法。
3、这里面还有一个问题就是关于有个W_N^k的计算,这个难道只有用2的n次幂的分数和去逼近,就是4楼兄弟*0.7那个通过移位的办法来解决吗? 记得以前实现的事4096点的FFT。然后每一级的蝶形运算中乘法用了4个时钟,然后一轮FFT用时4*4096个CLK。
程序也找不到了。当时是FPGA将10位AD值读完后,开始运算,然后将运算结果通过SPI给单片机显示。
其实只要搞定了蝶形运算的原理就行了。每一次的运算都将他并行就很快。
以上纯属个人灌水 回复【49楼】fjcqv
-----------------------------------------------------------------------
可以解释一下每一次的运算都将它并行是什么意思吗? 呼吁一下,希望更多以前实现过的朋友,把你们的工程上传上来,让我们研究学习一下!!!感激不尽! 回复【46楼】dltyy
-----------------------------------------------------------------------
为什么我把你这个工程编译仿真后波形是这个?我的也是9.1的版本
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_665860GOWUGI.jpg
(原文件名:未命名.jpg) 回复【53楼】cafppla
-----------------------------------------------------------------------
我的是这样:
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_665890ZXV2UY.jpg
(原文件名:fft8.jpg) 呵呵,诚心求FFT的HDL语言实现,点数最好多点。 回复【51楼】dltyy
-----------------------------------------------------------------------
找到以前写的了,之前说的还是有点问题。但是如果用于点数比较低的FFT运算来说,例如N=8,则3轮中的乘法并行起来,速度可以达到最快。但是这样占用的资源有点多。
另外,给你我以前的FFT4096。verilog写的。速度可能不快,点击此处下载 ourdev_666014T0NEVR.rar(文件大小:5K) (原文件名:Desktop.rar) 回复【56楼】fjcqv
-----------------------------------------------------------------------
先行谢过楼上了,我研究一下你当时的工程。然后再交流。 回复【54楼】dltyy
-----------------------------------------------------------------------
我下载你的工程,没有第60引脚,而且时序图是这样的,完全没输出
http://cache.amobbs.com/bbs_upload782111/files_44/ourdev_666174AOVCIC.jpg
(原文件名:Y25`D 是不是压缩后有问题,这个我也不知道,有没有知道的兄弟……怎么换了电脑就不行了 回复【56楼】fjcqv
-----------------------------------------------------------------------
56楼的兄弟,可否讲一下你这个fft4096个点的思路……我发现和那个4楼那个fft8思路不一样,方法也不一样……比那个看起来困难,有没有研究了这几个代码的,交流一下…… 稍微修改了下,出数据了。。。 回复【61楼】cafppla
-----------------------------------------------------------------------
能把你的波形图发出来吗? mark ,FFT:) 回复【61楼】cafppla
-----------------------------------------------------------------------
呵呵,要是你有点数多点的FFT算法代码,可要分享哦。 曾经和楼主有相同的困惑。
现在尝试用stm32做fft了,64点的fft,计算时间不到80us,也能接受 回复【61楼】cafppla
-----------------------------------------------------------------------
怎么改的啊,我也是没有 年前准备做FFT频谱分析,苦于找不到资料,又欠缺很多,所以就放弃了,以前也来过这个网站,今天才感觉到这个网站真的很不赖 为今后搞FPGA留着 mark 这个我试过opencore上面64点的FFT核在modelsim上面做个仿真。。。楼主你可以去试试,那个调用起来简单,就是资源占得多。 我只能是学习了,FPGA正打算用他做个控制器呢 先Mark,看来还有很长的路要走啊 看了楼主的文章,觉得自己还有好长的路要走啊,加油吧。 orz mark mark {:cry:}有同感呀!总感觉身边的人好少学习这个,什么东西都要自己研究,好痛苦,但是俗话说的好--痛并快乐着!! 共同学习,加油楼主 最近一直在研究FFT fpga实现,各位莫友真的有帮助 tortoisechan 发表于 2011-8-29 13:00 static/image/common/back.gif
这个我试过opencore上面64点的FFT核在modelsim上面做个仿真。。。楼主你可以去试试,那个调用起来简单,就 ...
你好我一直没找到,可否分享一下啊 学习中…… 本帖最后由 隐姓埋名 于 2013-10-17 02:38 编辑
NIOS软核实现较直接用现成的IP核当然要复杂许多,但是我想知道的关键是NIOS软核实现的速度会不会比FFT IP核的速度慢很多,因为我做这个FFT的首要目标就是快速,但是这个疑惑我至今都不是很清楚。
虽然没做个这个但是个人认为不要用NIOS,你用NIOS为什么不用DSP?原理上一样的,也都是用C来写,而且DSP专用的不比NIOS好么?这样FPGA的优势完全发挥不出来了,试着自己去用逻辑去实现,具体怎么实现更好更快就看你的努力了 之前没怎么接触过FPGA,现在毕设中用到,非常感谢。 mark一下FFT 多谢。。。。。。。。。。。。。。。。。。。。 sdu1028 发表于 2011-8-5 12:49
这个帖子,xilinx的片子,硬件FFT,用了MicroBlaze控制,带VGA显示波形与FFT结果的,楼主可以看下。。。
ht ...
楼主 这个链接貌似打不开了 能否重新 给个??? 谢过了 很不错的资料,谢谢了 谢了,这个对我帮助很大~ 写的不错
页:
[1]