搜索
bottom↓
回复: 25

用Modelsim仿真的Altera FFT IP核

[复制链接]

出0入0汤圆

发表于 2012-4-8 11:47:21 | 显示全部楼层 |阅读模式
虽然有结果出来,而且结果貌似也正确,但是用的时间太长了,有图为证。希望有人能指出我的错误,IO用的Streaming。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2012-4-8 12:44:26 | 显示全部楼层
114.2us,不长吧?

出0入0汤圆

发表于 2012-4-8 15:00:56 | 显示全部楼层
请教下图中的正弦波是如何产生的

出0入0汤圆

发表于 2012-4-8 15:03:23 | 显示全部楼层
这种FFT变换,还是自己试着写写吧。这样成就感比较好,点数也随心所欲。收到的束缚少。

出0入0汤圆

发表于 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);
variable  add2_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;

出0入0汤圆

 楼主| 发表于 2012-4-8 20:01:12 | 显示全部楼层
xtx 发表于 2012-4-8 15:00
请教下图中的正弦波是如何产生的

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

出0入0汤圆

 楼主| 发表于 2012-4-8 20:02:09 | 显示全部楼层
lvyunzeng 发表于 2012-4-8 15:07
光说不练,假把式。给个参考程序吧!
LIBRARY ieee;
USE ieee.std_logic_1164.all;

thanks,仔细研究一下。

出0入0汤圆

 楼主| 发表于 2012-4-8 20:03:07 | 显示全部楼层
cqv 发表于 2012-4-8 12:44
114.2us,不长吧?

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

出0入0汤圆

 楼主| 发表于 2012-4-8 20:07:22 | 显示全部楼层
lvyunzeng 发表于 2012-4-8 15:07
光说不练,假把式。给个参考程序吧!
LIBRARY ieee;
USE ieee.std_logic_1164.all;

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

出0入0汤圆

发表于 2012-4-8 20:20:00 | 显示全部楼层
titanruoya 发表于 2012-4-8 20:07
随便说一句”光说不练,假把式“这句话听着好熟悉(一个老师常说)。
再弱问一下:自己写的fft模块,可定 ...

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

出0入0汤圆

发表于 2012-4-9 01:01:08 | 显示全部楼层
还是自己写来的快 优化下结构

出0入0汤圆

 楼主| 发表于 2012-4-9 15:33:26 | 显示全部楼层
……已解决,原来是时钟的问题,仿真用的时钟速率太低(5M),改为200M后,时间变得比较短了。

出0入0汤圆

发表于 2012-4-9 19:42:20 | 显示全部楼层
LZ用的是verilog还是vhdl

出0入0汤圆

 楼主| 发表于 2012-4-10 12:26:34 | 显示全部楼层
ADO1234 发表于 2012-4-9 19:42
LZ用的是verilog还是vhdl

verilog……

出0入0汤圆

发表于 2012-4-10 13:43:56 | 显示全部楼层
额,可惜了,VHDL不熟悉

出0入0汤圆

发表于 2012-4-10 19:53:33 | 显示全部楼层
楼主问题解决了么,我现在也在做这个,不知道怎么进行仿真IP核,请赐教!

出0入0汤圆

 楼主| 发表于 2012-4-10 20:05:08 | 显示全部楼层
zxbyt2006 发表于 2012-4-10 19:53
楼主问题解决了么,我现在也在做这个,不知道怎么进行仿真IP核,请赐教! ...

你用什么仿真工具?

出0入0汤圆

发表于 2012-4-11 11:11:39 | 显示全部楼层
titanruoya 发表于 2012-4-10 20:05
你用什么仿真工具?

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

出0入0汤圆

发表于 2012-4-13 13:45:44 | 显示全部楼层
我也准备学学FPGA,这货入门也比单片机难啊!

出0入0汤圆

发表于 2012-4-13 14:56:01 | 显示全部楼层
留着5楼

出0入0汤圆

发表于 2012-5-13 21:35:04 | 显示全部楼层
好东西  真好现在自己也在学习

出0入0汤圆

发表于 2012-7-21 23:01:00 | 显示全部楼层
mark  !!

出0入0汤圆

发表于 2012-8-1 22:42:29 | 显示全部楼层
titanruoya 发表于 2012-4-10 20:05
你用什么仿真工具?

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

出0入0汤圆

发表于 2013-1-4 16:15:35 | 显示全部楼层
楼主,我现在也在用fft的ip核,遇到了一个问题,能加qq讨论一下吗,1653416261,谢谢!

出0入0汤圆

发表于 2013-2-27 19:49:19 | 显示全部楼层
楼主能开源吗?想借鉴参考一下

出0入0汤圆

发表于 2013-2-28 12:40:27 | 显示全部楼层
lvyunzeng  水平可以啊!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 07:11

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表