---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
--
|
--
|
-- Title : address
|
-- Title : address
|
-- Design : cfft
|
-- Design : cfft
|
-- Author : ZHAO Ming
|
-- Author : ZHAO Ming
|
-- email : sradio@opencores.org
|
-- email : sradio@opencores.org
|
--
|
--
|
---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
--
|
--
|
-- File : address.vhd
|
-- File : address.vhd
|
-- Generated : Thu Oct 3 01:44:47 2002
|
-- Generated : Thu Oct 3 01:44:47 2002
|
--
|
--
|
---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
--
|
--
|
-- Description : Generate RAM read write address and start finish control signal
|
-- Description : Generate RAM read write address and start finish control signal
|
--
|
--
|
---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
--
|
--
|
-- Revisions : 0
|
-- Revisions : 0
|
-- Revision Number : 1
|
-- Revision Number : 1
|
-- Version : 1.1.0
|
-- Version : 1.1.0
|
-- Date : Oct 17 2002
|
-- Date : Oct 17 2002
|
-- Modifier : ZHAO Ming
|
-- Modifier : ZHAO Ming
|
-- Desccription : Data width configurable
|
-- Desccription : Data width configurable
|
--
|
--
|
---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
--
|
--
|
-- Revisions : 0
|
-- Revisions : 0
|
-- Revision Number : 2
|
-- Revision Number : 2
|
-- Version : 1.2.0
|
-- Version : 1.2.0
|
-- Date : Oct 18 2002
|
-- Date : Oct 18 2002
|
-- Modifier : ZHAO Ming
|
-- Modifier : ZHAO Ming
|
-- Desccription : Data width configurable
|
-- Desccription : Data width configurable
|
--
|
--
|
---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
--
|
--
|
-- Revisions : 1
|
-- Revisions : 1
|
-- Revision Number : 2
|
-- Revision Number : 2
|
-- Version : 1.2.1
|
-- Version : 1.2.1
|
-- Date : Oct 19 2002
|
-- Date : Oct 19 2002
|
-- Modifier : ZHAO Ming
|
-- Modifier : ZHAO Ming
|
-- Desccription : modified fuction counter2address for syn
|
-- Desccription : modified fuction counter2address for syn
|
-- add rmask1,rmask2,wmask1,wmask2 signal
|
-- add rmask1,rmask2,wmask1,wmask2 signal
|
--
|
--
|
---------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------
|
|
|
|
|
library IEEE;
|
library IEEE;
|
use IEEE.STD_LOGIC_1164.all;
|
use IEEE.STD_LOGIC_1164.all;
|
use IEEE.STD_LOGIC_ARITH.all;
|
use IEEE.STD_LOGIC_ARITH.all;
|
use IEEE.std_logic_unsigned.all;
|
use IEEE.std_logic_unsigned.all;
|
use IEEE.std_logic_signed.all;
|
use IEEE.std_logic_signed.all;
|
|
|
entity address is
|
entity address is
|
generic (
|
generic (
|
WIDTH : Natural;
|
WIDTH : Natural;
|
POINT : Natural;
|
POINT : Natural;
|
STAGE : Natural
|
STAGE : Natural
|
);
|
);
|
port(
|
port(
|
clk : in STD_LOGIC;
|
clk : in STD_LOGIC;
|
rst : in STD_LOGIC;
|
rst : in STD_LOGIC;
|
start : in STD_LOGIC;
|
start : in STD_LOGIC;
|
Iin : in std_logic_vector( WIDTH-1 downto 0 );
|
Iin : in std_logic_vector( WIDTH-1 downto 0 );
|
Qin : in std_logic_vector( WIDTH-1 downto 0 );
|
Qin : in std_logic_vector( WIDTH-1 downto 0 );
|
fftI : in std_logic_vector( WIDTH-1 downto 0 );
|
fftI : in std_logic_vector( WIDTH-1 downto 0 );
|
fftQ : in std_logic_vector( WIDTH-1 downto 0 );
|
fftQ : in std_logic_vector( WIDTH-1 downto 0 );
|
wdataI : out std_logic_vector( WIDTH-1 downto 0 );
|
wdataI : out std_logic_vector( WIDTH-1 downto 0 );
|
wdataQ : out std_logic_vector( WIDTH-1 downto 0 );
|
wdataQ : out std_logic_vector( WIDTH-1 downto 0 );
|
raddr : out STD_LOGIC_VECTOR(STAGE*2-1 downto 0);
|
raddr : out STD_LOGIC_VECTOR(STAGE*2-1 downto 0);
|
waddr : out STD_LOGIC_VECTOR(STAGE*2-1 downto 0);
|
waddr : out STD_LOGIC_VECTOR(STAGE*2-1 downto 0);
|
wen : out std_logic;
|
wen : out std_logic;
|
factorstart : out STD_LOGIC;
|
factorstart : out STD_LOGIC;
|
cfft4start : out STD_LOGIC;
|
cfft4start : out STD_LOGIC;
|
outdataen : out std_logic;
|
outdataen : out std_logic;
|
inputbusy : out std_logic
|
inputbusy : out std_logic
|
);
|
);
|
end address;
|
end address;
|
|
|
|
|
architecture address of address is
|
architecture address of address is
|
|
|
|
|
-- function counter2addr(counter : std_logic_vector; state:std_logic_vector) return std_logic_vector is
|
-- function counter2addr(counter : std_logic_vector; state:std_logic_vector) return std_logic_vector is
|
-- variable result :std_logic_vector(counter'range);
|
-- variable result :std_logic_vector(counter'range);
|
-- variable istate : Natural;
|
-- variable istate : Natural;
|
-- begin
|
-- begin
|
-- istate:=CONV_INTEGER(unsigned(state));
|
-- istate:=CONV_INTEGER(unsigned(state));
|
-- if istate=0 then
|
-- if istate=0 then
|
-- result := counter( 1 downto 0 )&counter( counter'high downto 2 );
|
-- result := counter( 1 downto 0 )&counter( counter'high downto 2 );
|
-- elsif istate=(counter'high-1)/2 then
|
-- elsif istate=(counter'high-1)/2 then
|
-- result := counter;
|
-- result := counter;
|
-- elsif istate<(counter'high-1)/2 then
|
-- elsif istate<(counter'high-1)/2 then
|
-- result := counter( counter'high downto counter'high-istate*2+1 )&counter( 1 downto 0 )&counter( counter'high-istate*2 downto 2 );
|
-- result := counter( counter'high downto counter'high-istate*2+1 )&counter( 1 downto 0 )&counter( counter'high-istate*2 downto 2 );
|
-- else
|
-- else
|
-- result := counter;
|
-- result := counter;
|
-- end if;
|
-- end if;
|
-- return result;
|
-- return result;
|
-- end counter2addr;
|
-- end counter2addr;
|
|
|
function counter2addr(
|
function counter2addr(
|
counter : std_logic_vector;
|
counter : std_logic_vector;
|
mask1:std_logic_vector;
|
mask1:std_logic_vector;
|
mask2:std_logic_vector
|
mask2:std_logic_vector
|
) return std_logic_vector is
|
) return std_logic_vector is
|
variable result :std_logic_vector(counter'range);
|
variable result :std_logic_vector(counter'range);
|
begin
|
begin
|
for n in mask1'range loop
|
for n in mask1'range loop
|
if mask1(n)='1' then
|
if mask1(n)='1' then
|
result( 2*n+1 downto 2*n ):=counter( 1 downto 0 );
|
result( 2*n+1 downto 2*n ):=counter( 1 downto 0 );
|
elsif mask2(n)='1' and n/=STAGE-1 then
|
elsif mask2(n)='1' and n/=STAGE-1 then
|
result( 2*n+1 downto 2*n ):=counter( 2*n+3 downto 2*n+2 );
|
result( 2*n+1 downto 2*n ):=counter( 2*n+3 downto 2*n+2 );
|
else
|
else
|
result( 2*n+1 downto 2*n ):=counter( 2*n+1 downto 2*n );
|
result( 2*n+1 downto 2*n ):=counter( 2*n+1 downto 2*n );
|
end if;
|
end if;
|
end loop;
|
end loop;
|
return result;
|
return result;
|
end counter2addr;
|
end counter2addr;
|
|
|
|
|
signal rstate,wstate,state:std_logic_vector( 3 downto 0 );
|
signal rstate,wstate,state:std_logic_vector( 3 downto 0 );
|
signal rmask1,rmask2,wmask1,wmask2:std_logic_vector( STAGE-1 downto 0 );
|
signal rmask1,rmask2,wmask1,wmask2:std_logic_vector( STAGE-1 downto 0 );
|
signal counter,wcounter,rcounter:std_logic_vector( STAGE*2-1 downto 0 );
|
signal counter,wcounter,rcounter:std_logic_vector( STAGE*2-1 downto 0 );
|
signal outcounter:std_logic_vector( STAGE*2 downto 0 );
|
signal outcounter:std_logic_vector( STAGE*2 downto 0 );
|
|
|
constant FFTDELAY:integer:=12+2*STAGE;
|
constant FFTDELAY:integer:=12+2*STAGE;
|
constant FACTORDELAY:integer:=6;
|
constant FACTORDELAY:integer:=6;
|
constant OUTDELAY:integer:=7;
|
constant OUTDELAY:integer:=7;
|
|
|
|
|
|
|
begin
|
begin
|
outdataen<=outcounter(STAGE*2);
|
outdataen<=outcounter(STAGE*2);
|
|
|
count:process( clk, rst )
|
count:process( clk, rst )
|
begin
|
begin
|
if rst='1' then
|
if rst='1' then
|
counter<=( others=>'0' );
|
counter<=( others=>'0' );
|
state<=CONV_STD_LOGIC_VECTOR( STAGE+1,4);
|
state<=CONV_STD_LOGIC_VECTOR( STAGE+1,4);
|
elsif clk'event and clk='1' then
|
elsif clk'event and clk='1' then
|
if start='1' then
|
if start='1' then
|
counter<=( others=>'0' );
|
counter<=( others=>'0' );
|
state<=(others=>'0');
|
state<=(others=>'0');
|
elsif unsigned(state)/=STAGE+1 then
|
elsif unsigned(state)/=STAGE+1 then
|
counter<=unsigned(counter)+1;
|
counter<=unsigned(counter)+1;
|
if signed(counter)=-1 then
|
if signed(counter)=-1 then
|
state<=unsigned(state)+1;
|
state<=unsigned(state)+1;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process count;
|
end process count;
|
|
|
readaddr:process( clk,rst )
|
readaddr:process( clk,rst )
|
begin
|
begin
|
if rst='1' then
|
if rst='1' then
|
raddr<=( others=>'0' );
|
raddr<=( others=>'0' );
|
rcounter<=( others=>'0' );
|
rcounter<=( others=>'0' );
|
rstate<=( others=>'0' );
|
rstate<=( others=>'0' );
|
rmask1<=( others=>'0' );
|
rmask1<=( others=>'0' );
|
rmask2<=( others=>'0' );
|
rmask2<=( others=>'0' );
|
elsif clk'event and clk='1' then
|
elsif clk'event and clk='1' then
|
if unsigned(state)=0 and signed(counter)=-1 then
|
if unsigned(state)=0 and signed(counter)=-1 then
|
rmask1(STAGE-1)<='1';
|
rmask1(STAGE-1)<='1';
|
rmask1(STAGE-2 downto 0)<=(others=>'0');
|
rmask1(STAGE-2 downto 0)<=(others=>'0');
|
rmask2(STAGE-1)<='0';
|
rmask2(STAGE-1)<='0';
|
rmask2(STAGE-2 downto 0)<=(others=>'1');
|
rmask2(STAGE-2 downto 0)<=(others=>'1');
|
elsif signed(counter)=-1 then
|
elsif signed(counter)=-1 then
|
rmask1<='0'&rmask1( STAGE-1 downto 1 );
|
rmask1<='0'&rmask1( STAGE-1 downto 1 );
|
rmask2<='0'&rmask2( STAGE-1 downto 1 );
|
rmask2<='0'&rmask2( STAGE-1 downto 1 );
|
end if;
|
end if;
|
if unsigned(state)/=STAGE+1 and signed(counter)=-1 then
|
if unsigned(state)/=STAGE+1 and signed(counter)=-1 then
|
rcounter<=( others=>'0' );
|
rcounter<=( others=>'0' );
|
rstate<=state;
|
rstate<=state;
|
else
|
else
|
rcounter<=unsigned(rcounter)+1;
|
rcounter<=unsigned(rcounter)+1;
|
end if;
|
end if;
|
raddr<=counter2addr( rcounter, rmask1, rmask2 );
|
raddr<=counter2addr( rcounter, rmask1, rmask2 );
|
-- modified for point configurable
|
-- modified for point configurable
|
-- case rstate is
|
-- case rstate is
|
-- when "000" =>
|
-- when "000" =>
|
-- raddr<=rcounter( 1 downto 0 )&rcounter( 9 downto 2);
|
-- raddr<=rcounter( 1 downto 0 )&rcounter( 9 downto 2);
|
-- when "001" =>
|
-- when "001" =>
|
-- raddr<=rcounter( 9 downto 8 )&rcounter( 1 downto 0 )&rcounter( 7 downto 2);
|
-- raddr<=rcounter( 9 downto 8 )&rcounter( 1 downto 0 )&rcounter( 7 downto 2);
|
-- when "010" =>
|
-- when "010" =>
|
-- raddr<=rcounter( 9 downto 6 )&rcounter( 1 downto 0 )&rcounter( 5 downto 2);
|
-- raddr<=rcounter( 9 downto 6 )&rcounter( 1 downto 0 )&rcounter( 5 downto 2);
|
-- when "011" =>
|
-- when "011" =>
|
-- raddr<=rcounter( 9 downto 4 )&rcounter( 1 downto 0 )&rcounter( 3 downto 2);
|
-- raddr<=rcounter( 9 downto 4 )&rcounter( 1 downto 0 )&rcounter( 3 downto 2);
|
-- when "100" =>
|
-- when "100" =>
|
-- raddr<=rcounter( 9 downto 2 )&rcounter( 1 downto 0 );
|
-- raddr<=rcounter( 9 downto 2 )&rcounter( 1 downto 0 );
|
-- when others =>
|
-- when others =>
|
-- raddr<=( others=> '0' );
|
-- raddr<=( others=> '0' );
|
-- end case;
|
-- end case;
|
end if;
|
end if;
|
end process readaddr;
|
end process readaddr;
|
|
|
writeaddr:process( clk,rst )
|
writeaddr:process( clk,rst )
|
begin
|
begin
|
if rst='1' then
|
if rst='1' then
|
waddr<=( others=>'0' );
|
waddr<=( others=>'0' );
|
wcounter<=( others=>'0' );
|
wcounter<=( others=>'0' );
|
wstate<=( others=>'0' );
|
wstate<=( others=>'0' );
|
wmask1<=( others=>'0' );
|
wmask1<=( others=>'0' );
|
wmask2<=( others=>'0' );
|
wmask2<=( others=>'0' );
|
elsif clk'event and clk='1' then
|
elsif clk'event and clk='1' then
|
if unsigned(state)=0 then
|
if unsigned(state)=0 then
|
waddr<=counter;
|
waddr<=counter;
|
else
|
else
|
if UNSIGNED(rstate)=0 and unsigned(rcounter)=FFTDELAY-1 then
|
if UNSIGNED(rstate)=0 and unsigned(rcounter)=FFTDELAY-1 then
|
wmask1(STAGE-1)<='1';
|
wmask1(STAGE-1)<='1';
|
wmask1(STAGE-2 downto 0)<=(others=>'0');
|
wmask1(STAGE-2 downto 0)<=(others=>'0');
|
wmask2(STAGE-1)<='0';
|
wmask2(STAGE-1)<='0';
|
wmask2(STAGE-2 downto 0)<=(others=>'1');
|
wmask2(STAGE-2 downto 0)<=(others=>'1');
|
elsif unsigned(rcounter)=FFTDELAY-1 then
|
elsif unsigned(rcounter)=FFTDELAY-1 then
|
wmask1<='0'&wmask1( STAGE-1 downto 1 );
|
wmask1<='0'&wmask1( STAGE-1 downto 1 );
|
wmask2<='0'&wmask2( STAGE-1 downto 1 );
|
wmask2<='0'&wmask2( STAGE-1 downto 1 );
|
end if;
|
end if;
|
if UNSIGNED(rstate)<STAGE and unsigned(rcounter)=FFTDELAY-1 then
|
if UNSIGNED(rstate)<STAGE and unsigned(rcounter)=FFTDELAY-1 then
|
wcounter<=( others=>'0' );
|
wcounter<=( others=>'0' );
|
wstate<=rstate;
|
wstate<=rstate;
|
else
|
else
|
wcounter<=unsigned(wcounter)+1;
|
wcounter<=unsigned(wcounter)+1;
|
end if;
|
end if;
|
waddr<=counter2addr( wcounter, wmask1, wmask2 );
|
waddr<=counter2addr( wcounter, wmask1, wmask2 );
|
-- modified for point configurable
|
-- modified for point configurable
|
-- case wstate is
|
-- case wstate is
|
-- when "000" =>
|
-- when "000" =>
|
-- waddr<=wcounter( 1 downto 0 )&wcounter( 9 downto 2);
|
-- waddr<=wcounter( 1 downto 0 )&wcounter( 9 downto 2);
|
-- when "001" =>
|
-- when "001" =>
|
-- waddr<=wcounter( 9 downto 8 )&wcounter( 1 downto 0 )&wcounter( 7 downto 2);
|
-- waddr<=wcounter( 9 downto 8 )&wcounter( 1 downto 0 )&wcounter( 7 downto 2);
|
-- when "010" =>
|
-- when "010" =>
|
-- waddr<=wcounter( 9 downto 6 )&wcounter( 1 downto 0 )&wcounter( 5 downto 2);
|
-- waddr<=wcounter( 9 downto 6 )&wcounter( 1 downto 0 )&wcounter( 5 downto 2);
|
-- when "011" =>
|
-- when "011" =>
|
-- waddr<=wcounter( 9 downto 4 )&wcounter( 1 downto 0 )&wcounter( 3 downto 2);
|
-- waddr<=wcounter( 9 downto 4 )&wcounter( 1 downto 0 )&wcounter( 3 downto 2);
|
-- when others =>
|
-- when others =>
|
-- waddr<=( others=> '0' );
|
-- waddr<=( others=> '0' );
|
-- end case;
|
-- end case;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process writeaddr;
|
end process writeaddr;
|
|
|
writeen : process( clk, rst )
|
writeen : process( clk, rst )
|
begin
|
begin
|
if rst='1' then
|
if rst='1' then
|
wen<='0';
|
wen<='0';
|
elsif clk'event and clk='1' then
|
elsif clk'event and clk='1' then
|
if unsigned(state)=0 then
|
if unsigned(state)=0 then
|
wen<='1';
|
wen<='1';
|
elsif unsigned(state)=1 and unsigned(counter)=0 then
|
elsif unsigned(state)=1 and unsigned(counter)=0 then
|
wen<='0';
|
wen<='0';
|
elsif unsigned(rstate)=0 and unsigned(rcounter)=FFTDELAY then
|
elsif unsigned(rstate)=0 and unsigned(rcounter)=FFTDELAY then
|
wen<='1';
|
wen<='1';
|
elsif unsigned(rstate)=STAGE-1 and unsigned(rcounter)=FFTDELAY then
|
elsif unsigned(rstate)=STAGE-1 and unsigned(rcounter)=FFTDELAY then
|
wen<='0';
|
wen<='0';
|
end if;
|
end if;
|
end if;
|
end if;
|
end process writeen;
|
end process writeen;
|
|
|
otherstart : process( clk, rst )
|
otherstart : process( clk, rst )
|
begin
|
begin
|
if rst='1' then
|
if rst='1' then
|
factorstart<='0';
|
factorstart<='0';
|
cfft4start<='0';
|
cfft4start<='0';
|
outcounter<=(others=>'0');
|
outcounter<=(others=>'0');
|
inputbusy<='0';
|
inputbusy<='0';
|
elsif clk'event and clk='1' then
|
elsif clk'event and clk='1' then
|
if start='1' then
|
if start='1' then
|
inputbusy<='1';
|
inputbusy<='1';
|
elsif unsigned(state)=STAGE and unsigned(counter)=FFTDELAY then
|
elsif unsigned(state)=STAGE and unsigned(counter)=FFTDELAY then
|
inputbusy<='0';
|
inputbusy<='0';
|
end if;
|
end if;
|
if unsigned(state)=1 and unsigned(counter)=0 then
|
if unsigned(state)=1 and unsigned(counter)=0 then
|
cfft4start<='1';
|
cfft4start<='1';
|
else
|
else
|
cfft4start<='0';
|
cfft4start<='0';
|
end if;
|
end if;
|
if unsigned(rstate)=0 and unsigned(rcounter)=FACTORDELAY then
|
if unsigned(rstate)=0 and unsigned(rcounter)=FACTORDELAY then
|
factorstart<='1';
|
factorstart<='1';
|
else
|
else
|
factorstart<='0';
|
factorstart<='0';
|
end if;
|
end if;
|
if unsigned(state)=STAGE and unsigned(rcounter)=OUTDELAY then
|
if unsigned(state)=STAGE and unsigned(rcounter)=OUTDELAY then
|
outcounter<=CONV_STD_LOGIC_VECTOR(POINT,2*STAGE+1);
|
outcounter<=CONV_STD_LOGIC_VECTOR(POINT,2*STAGE+1);
|
elsif outcounter(STAGE*2)='1' then
|
elsif outcounter(STAGE*2)='1' then
|
outcounter<=unsigned(outcounter)+1;
|
outcounter<=unsigned(outcounter)+1;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process otherstart;
|
end process otherstart;
|
|
|
datasel : process( clk,rst )
|
datasel : process( clk,rst )
|
begin
|
begin
|
if rst='1' then
|
if rst='1' then
|
wdataI<=( others=>'0' );
|
wdataI<=( others=>'0' );
|
wdataQ<=( others=>'0' );
|
wdataQ<=( others=>'0' );
|
elsif clk'event and clk='1' then
|
elsif clk'event and clk='1' then
|
if unsigned(state)=0 then
|
if unsigned(state)=0 then
|
wdataI<=Iin;
|
wdataI<=Iin;
|
wdataQ<=Qin;
|
wdataQ<=Qin;
|
else
|
else
|
wdataI<=fftI;
|
wdataI<=fftI;
|
wdataQ<=fftQ;
|
wdataQ<=fftQ;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process datasel;
|
end process datasel;
|
|
|
end address;
|
end address;
|
|
|