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