用Modelsim仿真的Altera FFT IP核
虽然有结果出来,而且结果貌似也正确,但是用的时间太长了,有图为证。希望有人能指出我的错误,IO用的Streaming。 114.2us,不长吧? 请教下图中的正弦波是如何产生的 这种FFT变换,还是自己试着写写吧。这样成就感比较好,点数也随心所欲。收到的束缚少。 光说不练,假把式。给个参考程序吧!LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
--Entity Declaration
ENTITY fft10241 IS
-- {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE!
PORT
(
clk : IN STD_LOGIC;
rest : IN STD_LOGIC;
start : IN STD_LOGIC; ---新增,由位倒序模块给出使能信号,控制蝶形工作
--***********蝶形运算模块信号
x_ren_din:in std_logic_vector(15 downto 0);
x_im_din:in std_logic_vector(15 downto 0);
w_cos_din:in std_logic_vector(7 downto 0);
w_sin_din:in std_logic_vector(7 downto 0);
--***********ram 控制信号
--------------------------------------------------------------------
wren:out std_logic;
x_rd_addr : OUT STD_LOGIC_VECTOR(10 downto 0);
x_wr_addr: out std_logic_vector(10 downto 0);
w_addr: out std_logic ;
x_ren_dout:out std_logic_vector(15 downto 0);------------------------------本次计算结果的输出(实部)
x_im_dout:out std_logic_vector(15 downto 0);------------------------------- (虚部)
en :out std_logic ----新增使能下一级蝶形
);
-- {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE!
END fft10241;
--Architecture Body
ARCHITECTURE fft_addr_gen_block_architecture OF fft10241 IS
--#######################8bit加法器############################# ;正玄余玄值相加
function add_block(
x1:std_logic_vector(7 downto 0);
x2:std_logic_vector(7 downto 0)
)
return std_logic_vector is
variable y:std_logic_vector(8 downto 0); ----------------------y为两数(正玄余玄)之和(9位)
variable yy:std_logic_vector(7 downto 0);
begin
yy:=x1+x2;
if(x1(7)/=x2(7))then
y:=yy(7)&yy;
else
y:=x1(7)&yy;
end if;
return y;
end add_block;
--****************************************************************
--*********************16bit加法器********************************实虚相加
function add2_block(
x1:std_logic_vector(15 downto 0);--------------------------B的实部和虚部之和,Y为17位
x2:std_logic_vector(15 downto 0)
)
return std_logic_vector is
variable y:std_logic_vector(16 downto 0);
variable yy:std_logic_vector(15 downto 0);
begin
yy:=x1+x2;
if(x1(15)/=x2(15))then
y:=yy(15)&yy;
else
y:=x1(15)&yy;
end if;
return y;
end add2_block;
--###############################################################################
--^^^^^^^^^^^^^^^^^^^^^^^^^^^^16x9乘法器^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
function mul_block(
x1:std_logic_vector(15 downto 0);-------------------------乘积结果为24位
x2:std_logic_vector(8 downto 0)
)
return std_logic_vector is
variable y:std_logic_vector(23 downto 0);
variable exp1:std_logic_vector(15 downto 0);
variable exp2:std_logic_vector(8 downto 0);
variable mul:std_logic_vector(24 downto 0);
begin
if(x1(15)='1')then
exp1:=not(x1-1);
else
exp1:=x1;
end if;
if(x2(8)='1')then
exp2:=not(x2-1);
else
exp2:=x2;
end if;
mul:=exp1*exp2;
if(x1(15)/=x2(8))then
mul:=not(mul)+1;
y:=mul(23 downto 0);
else
y:=mul(23 downto 0);
end if;
return y;
end mul_block;
--###########################################################################
--%%%%%%%%%%%%%%%%%%%%%%%%%%%%%17x8乘法器%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function mul2_block(
x1:std_logic_vector(16 downto 0);-----------------------乘积结果为24位
x2:std_logic_vector(7 downto 0)
)
return std_logic_vector is
variable y:std_logic_vector(23 downto 0);
variable exp1:std_logic_vector(16 downto 0);
variable exp2:std_logic_vector(7 downto 0);
variable mul:std_logic_vector(24 downto 0);
begin
if(x1(16)='1')then
exp1:=not(x1-1);
else
exp1:=x1;
end if;
if(x2(7)='1')then
exp2:=not(x2-1);
else
exp2:=x2;
end if;
mul:=exp1*exp2;
if(x1(16)/=x2(7))then
mul:=not(mul)+1;
y:=mul(23 downto 0);
else
y:=mul(23 downto 0);
end if;
return y;
end mul2_block;
--$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
BEGIN
process(rest,clk)
variable j:std_logic_vector(9 downto 0);-----------地址寄存器
variable jx:std_logic_vector(9 downto 0);-------------------读RAM地址
variable y :integer ;
variable x_wr0,x_wr1,x_wr2,x_wr3,x_wr4,x_wr5,x_wr6,x_wr7,x:std_logic_vector(10 downto 0);-----------------------延迟部分
variable xi_mul2,xr_mul2,x2_mul2,wx2_ren_in,wx2_im_in:std_logic_vector(23 downto 0);
variable x1_ren4,x1_im4,x2_ren_in,x2_im_in:std_logic_vector(17 downto 0);
variableadd2_x:std_logic_vector(16 downto 0);
variable x2_ren1,x2_im1,x1_ren1,x1_im1,x1_ren3,x1_im3:std_logic_vector(15 downto 0);
variable cos1:std_logic_vector(7 downto 0);
variable sub1,add_x:std_logic_vector(8 downto 0);
variable f:integer range 0 to 1;-----------------------------------
variable k:integer ;-----------------------------------
variable m: std_logic_vector(10 downto 0) ;
variable n:std_logic_vector(10 downto 0) ;
variable jm:std_logic_vector(10 downto 0) ;
begin
if(rest='0')then
j:="0000000000";--------------------------初始地址为零
en<='0';--------------------------下一级停止工作
f:=1; ----------计算A-B
wren<='0';--------------------RAM写无效
k:=0 ;
else
if(clk'event and clk='0')then
if(start='1')then----------蝶形模块工作
x:=x_wr5;--进行fft运算
x_wr_addr<=x_wr5;---------------------------延时
--x_wr7:=x_wr6;
--x_wr6:=x_wr5;
x_wr5:=x_wr4;
x_wr4:=x_wr3;
x_wr3:=x_wr2;
x_wr2:=x_wr1;
x_wr1:=x_wr0;
------------------------------------------------------------------------------
if(k<1030) then
k:=k+1 ;
en<='0' ;
else
en<='1' ;
end if ;
------------------------------------------------------------------------------
--****************************************************************************
--***************************蝶形运算模块*************************************
if(f=1)then
x_ren_dout<=x2_ren_in(17)&x2_ren_in(14 downto 0);---输出A-B---------?
x_im_dout<=x2_im_in(17)&x2_im_in(14 downto 0);----------------------?
----------------------------------------------------
x1_ren3:=x1_ren1;--1 -----------------------------------?
x1_im3:=x1_im1;--1传递变量 -----------------------------------?
----------------------------------------------------
wx2_ren_in:=x2_mul2+xi_mul2;---实现复乘运算
xr_mul2:=not(xr_mul2)+1;
wx2_im_in:=x2_mul2+xr_mul2;
-----------------------------------
x2_ren1:=x_ren_din;--1
x2_im1:=x_im_din;--1
add2_x:=add2_block(x2_ren1,x2_im1);--1--------------B的实部和虚部相加
add_x:=add_block(w_sin_din,w_cos_din);--1-----------旋转因子实部和虚部相加
cos1:=not(w_cos_din)+1;-----------------------------not对bit,boolean,std_logic进行操作
sub1:=add_block(w_sin_din,cos1); ----------------旋转因子实部和虚部相减
cos1:=w_cos_din;
------------------------------------
else-----------------------------f=0
x_ren_dout<=x1_ren4(17)&x1_ren4(14 downto 0);---输出A+B-----------------?
x_im_dout<=x1_im4(17)&x1_im4(14 downto 0); ---------------------------?
x1_ren4:=x1_ren3(15)&x1_ren3(15)&x1_ren3+wx2_ren_in(23 downto 6);----------?
x1_im4 :=x1_im3(15)&x1_im3(15)&x1_im3+wx2_im_in(23 downto 6); ------------?
wx2_ren_in(23 downto 6):=not(wx2_ren_in(23 downto 6))+1;
wx2_im_in(23 downto 6):=not(wx2_im_in(23 downto 6))+1;
x2_ren_in:=x1_ren3(15)&x1_ren3(15)&x1_ren3+wx2_ren_in(23 downto 6);
x2_im_in:=x1_im3(15)&x1_im3(15)&x1_im3+wx2_im_in(23 downto 6);
x1_ren1:=x_ren_din;---
x1_im1:=x_im_din;-----
x2_mul2:=mul2_block(add2_x,cos1);
xr_mul2:=mul_block(x2_ren1,add_x);
xi_mul2:=mul_block(x2_im1,sub1);
end if;
--*******************************************************************
--寻址运算--------------------------------------------与PROCESS里的其他关系如何?
if(y<6)then--写输入延时-----------------------这个IF和下面的IF语句时并行
wren<='0';-------------------------------------的吗
y:=y+1 ;
else
wren<='1';
end if;
if(f=1)then--寻址,先输出x2,后x1
jx:=j+1;---利用j读ram
jm:=m(10) & jx(9 downto 0) ;
x_rd_addr<=jm; -----------------------------给出X2的地址,取出待运算的数
x_wr0:=jm; -----------------------------同时将此地址送给RAM,即将结果写回原来的地址
w_addr<='0'; -----------------------------给出ROM的地址
f:=0; -----------------------------使F变为0
else-----f=0
n:=m(10) & j ;
x_rd_addr<=n; -----------------------------给出X1的地址
x_wr0:=n; -----------------------------将结果写回原来的地址
if(j<"1111111110")then
j:=j+2;
else
j:="0000000000";
end if;
f:=1;
end if;
----------------------------------------------------------------------------------------最高位
if(m<=2047)then
m:=m+1 ;
else
m:="00000000000" ;
end if ;
----------------------------------------------------------------------------------------------
end if;
end if;
end if;
end process;
END fft_addr_gen_block_architecture;
xtx 发表于 2012-4-8 15:00 static/image/common/back.gif
请教下图中的正弦波是如何产生的
用matlab产生的数据,放在rom中,然后读出来。 lvyunzeng 发表于 2012-4-8 15:07 static/image/common/back.gif
光说不练,假把式。给个参考程序吧!
LIBRARY ieee;
USE ieee.std_logic_1164.all;
thanks,仔细研究一下。 cqv 发表于 2012-4-8 12:44 static/image/common/back.gif
114.2us,不长吧?
我感觉512点fft,不需要这么久吧。 lvyunzeng 发表于 2012-4-8 15:07 static/image/common/back.gif
光说不练,假把式。给个参考程序吧!
LIBRARY ieee;
USE ieee.std_logic_1164.all;
随便说一句”光说不练,假把式“这句话听着好熟悉(一个老师常说)。
再弱问一下:自己写的fft模块,可定制性不强吧。比如点数,数据位数等。 titanruoya 发表于 2012-4-8 20:07 static/image/common/back.gif
随便说一句”光说不练,假把式“这句话听着好熟悉(一个老师常说)。
再弱问一下:自己写的fft模块,可定 ...
老师还经常说一句:“调电路啊,没病不死人”
程序都是你的了,想怎么改就怎么改啊!这还不灵活?主要是熟悉FFT到底是什么玩意,老奥的书上写的比较绕,实际就那么一点点东西。一通百通,是这个意思。 还是自己写来的快 优化下结构 ……已解决,原来是时钟的问题,仿真用的时钟速率太低(5M),改为200M后,时间变得比较短了。 LZ用的是verilog还是vhdl ADO1234 发表于 2012-4-9 19:42 static/image/common/back.gif
LZ用的是verilog还是vhdl
verilog…… 额,可惜了,VHDL不熟悉 楼主问题解决了么,我现在也在做这个,不知道怎么进行仿真IP核,请赐教! zxbyt2006 发表于 2012-4-10 19:53 static/image/common/back.gif
楼主问题解决了么,我现在也在做这个,不知道怎么进行仿真IP核,请赐教! ...
你用什么仿真工具? titanruoya 发表于 2012-4-10 20:05 static/image/common/back.gif
你用什么仿真工具?
我用的modelsim啊,也可以用quartus,但是都没仿真出来。502223447,我的QQ,能qq交流一下么? 我也准备学学FPGA,这货入门也比单片机难啊! 留着5楼 {:lol:}好东西真好现在自己也在学习 mark!! titanruoya 发表于 2012-4-10 20:05 static/image/common/back.gif
你用什么仿真工具?
你好,现在正在做FFT IP核的应用,可以讨论下嘛,遇到些问题,qq:411953835 楼主,我现在也在用fft的ip核,遇到了一个问题,能加qq讨论一下吗,1653416261,谢谢! 楼主能开源吗?想借鉴参考一下 lvyunzeng水平可以啊!
页:
[1]