titanruoya 发表于 2012-4-8 11:47:21

用Modelsim仿真的Altera FFT IP核

虽然有结果出来,而且结果貌似也正确,但是用的时间太长了,有图为证。希望有人能指出我的错误,IO用的Streaming。

cqv 发表于 2012-4-8 12:44:26

114.2us,不长吧?

xtx 发表于 2012-4-8 15:00:56

请教下图中的正弦波是如何产生的

lvyunzeng 发表于 2012-4-8 15:03:23

这种FFT变换,还是自己试着写写吧。这样成就感比较好,点数也随心所欲。收到的束缚少。

lvyunzeng 发表于 2012-4-8 15:07:55

光说不练,假把式。给个参考程序吧!
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;

titanruoya 发表于 2012-4-8 20:01:12

xtx 发表于 2012-4-8 15:00 static/image/common/back.gif
请教下图中的正弦波是如何产生的

用matlab产生的数据,放在rom中,然后读出来。

titanruoya 发表于 2012-4-8 20:02:09

lvyunzeng 发表于 2012-4-8 15:07 static/image/common/back.gif
光说不练,假把式。给个参考程序吧!
LIBRARY ieee;
USE ieee.std_logic_1164.all;


thanks,仔细研究一下。

titanruoya 发表于 2012-4-8 20:03:07

cqv 发表于 2012-4-8 12:44 static/image/common/back.gif
114.2us,不长吧?

我感觉512点fft,不需要这么久吧。

titanruoya 发表于 2012-4-8 20:07:22

lvyunzeng 发表于 2012-4-8 15:07 static/image/common/back.gif
光说不练,假把式。给个参考程序吧!
LIBRARY ieee;
USE ieee.std_logic_1164.all;


随便说一句”光说不练,假把式“这句话听着好熟悉(一个老师常说)。
再弱问一下:自己写的fft模块,可定制性不强吧。比如点数,数据位数等。

lvyunzeng 发表于 2012-4-8 20:20:00

titanruoya 发表于 2012-4-8 20:07 static/image/common/back.gif
随便说一句”光说不练,假把式“这句话听着好熟悉(一个老师常说)。
再弱问一下:自己写的fft模块,可定 ...

老师还经常说一句:“调电路啊,没病不死人”
程序都是你的了,想怎么改就怎么改啊!这还不灵活?主要是熟悉FFT到底是什么玩意,老奥的书上写的比较绕,实际就那么一点点东西。一通百通,是这个意思。

wangkang00299 发表于 2012-4-9 01:01:08

还是自己写来的快 优化下结构

titanruoya 发表于 2012-4-9 15:33:26

……已解决,原来是时钟的问题,仿真用的时钟速率太低(5M),改为200M后,时间变得比较短了。

ADO1234 发表于 2012-4-9 19:42:20

LZ用的是verilog还是vhdl

titanruoya 发表于 2012-4-10 12:26:34

ADO1234 发表于 2012-4-9 19:42 static/image/common/back.gif
LZ用的是verilog还是vhdl

verilog……

绿羊 发表于 2012-4-10 13:43:56

额,可惜了,VHDL不熟悉

zxbyt2006 发表于 2012-4-10 19:53:33

楼主问题解决了么,我现在也在做这个,不知道怎么进行仿真IP核,请赐教!

titanruoya 发表于 2012-4-10 20:05:08

zxbyt2006 发表于 2012-4-10 19:53 static/image/common/back.gif
楼主问题解决了么,我现在也在做这个,不知道怎么进行仿真IP核,请赐教! ...

你用什么仿真工具?

zxbyt2006 发表于 2012-4-11 11:11:39

titanruoya 发表于 2012-4-10 20:05 static/image/common/back.gif
你用什么仿真工具?

我用的modelsim啊,也可以用quartus,但是都没仿真出来。502223447,我的QQ,能qq交流一下么?

zhenglu891028 发表于 2012-4-13 13:45:44

我也准备学学FPGA,这货入门也比单片机难啊!

lsw0136 发表于 2012-4-13 14:56:01

留着5楼

Julius20110 发表于 2012-5-13 21:35:04

{:lol:}好东西真好现在自己也在学习

moxiaoxiong 发表于 2012-7-21 23:01:00

mark!!

mmmomo 发表于 2012-8-1 22:42:29

titanruoya 发表于 2012-4-10 20:05 static/image/common/back.gif
你用什么仿真工具?

你好,现在正在做FFT IP核的应用,可以讨论下嘛,遇到些问题,qq:411953835

vickyphan 发表于 2013-1-4 16:15:35

楼主,我现在也在用fft的ip核,遇到了一个问题,能加qq讨论一下吗,1653416261,谢谢!

ctqvsly 发表于 2013-2-27 19:49:19

楼主能开源吗?想借鉴参考一下

nnimo 发表于 2013-2-28 12:40:27

lvyunzeng水平可以啊!
页: [1]
查看完整版本: 用Modelsim仿真的Altera FFT IP核