##// END OF EJS Templates
Few fixes....
Few fixes. Whole LFR simulation WIP.

File last commit:

r631:df7b3a51dab6 simu_with_Leon3
r682:c53e1b6b3045 default
Show More
fftSm.vhd
881 lines | 31.5 KiB | text/x-vhdl | VhdlLexer
--------------------------------------------------------------------------------
-- Copyright 2007 Actel Corporation. All rights reserved.
-- ANY USE OR REDISTRIBUTION IN PART OR IN WHOLE MUST BE HANDLED IN
-- ACCORDANCE WITH THE ACTEL LICENSE AGREEMENT AND MUST BE APPROVED
-- IN ADVANCE IN WRITING.
-- Revision 3.0 April 30, 2007 : v3.0 CoreFFT Release
-- File: fftSm.vhd
-- Description: CoreFFT
-- FFT state machine module
-- Rev: 3.0 3/28/2007 4:43PM VlaD : Variable bitwidth
--
--
--------------------------------------------------------------------------------
--************************** TWIDDLE rA GENERATOR **************************
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_unsigned.all;
USE work.fft_components.all;
ENTITY twid_rA IS
GENERIC (LOGPTS : integer := 8;
LOGLOGPTS : integer := 3 );
PORT (clk : IN std_logic;
timer : IN std_logic_vector(LOGPTS-2 DOWNTO 0);
stage : IN std_logic_vector(LOGLOGPTS-1 DOWNTO 0);
tA : OUT std_logic_vector(LOGPTS-2 DOWNTO 0));
END ENTITY twid_rA;
ARCHITECTURE translated OF twid_rA IS
CONSTANT timescale : time := 1 ns;
--twiddleMask = ~(0xFFFFFFFF<<(NumberOfStages-1));
--addrTwiddle=reverseBits(count, NumberOfStages-1)<<(NumberOfStages-1-stage);
--mask out extra left bits: addrTwiddle = addrTwiddle & twiddleMask;
--reverse bits of the timer;
SIGNAL reverseBitTimer : bit_vector(LOGPTS-2 DOWNTO 0);
SIGNAL tA_w, tA_reg : std_logic_vector(LOGPTS-2 DOWNTO 0);
BEGIN
tA <= tA_reg;
PROCESS (timer)
BEGIN
reverseBitTimer <= reverse(timer);
END PROCESS;
-- Left shift by
tA_w <= To_StdLogicVector(reverseBitTimer SLL (LOGPTS-1 - to_integer(stage)) )
AFTER timescale;
PROCESS (clk)
BEGIN
IF (clk'EVENT AND clk = '1') THEN
tA_reg <= tA_w AFTER timescale;
END IF;
END PROCESS;
END ARCHITECTURE translated;
--------------------------------------------------------------------------------
--***************************** TIMERS & rdValid ***************************
-- FFT computation sequence is predefined. Once it gets started it runs for
-- a number of stages, `HALFPTS+ clk per stage. The following module sets the
-- read inBuf time sequence. Every stage takes HALFPTS + inBuf_RWDLY clk for
-- the inBuf to write Bfly results back in place before it starts next stage
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE work.fft_components.all;
ENTITY rdFFTtimer IS
GENERIC (LOGPTS : integer := 8;
LOGLOGPTS : integer := 3;
HALFPTS : integer := 128;
inBuf_RWDLY : integer := 12 );
PORT (
clk, cntEn, rst, nGrst : IN std_logic;
startFFT, fft_runs : IN std_logic;
timerTC, lastStage : OUT std_logic; --terminal counts of rA and stage
stage : OUT std_logic_vector(LOGLOGPTS-1 DOWNTO 0);
timer : OUT std_logic_vector(LOGPTS-1 DOWNTO 0);
rdValid : OUT std_logic );
END ENTITY rdFFTtimer;
ARCHITECTURE translated OF rdFFTtimer IS
CONSTANT dlta : time := 1 ns;
SIGNAL preRdValid : std_logic;
SIGNAL pipe1, pipe2 : std_logic;
SIGNAL rst_comb, timerTCx1 : std_logic;
SIGNAL lastStage_xhdl2 : std_logic;
SIGNAL stage_xhdl3 : std_logic_vector(LOGLOGPTS-1 DOWNTO 0);
SIGNAL timer_xhdl4 : std_logic_vector(LOGPTS-1 DOWNTO 0);
SIGNAL rdValid_xhdl5 : std_logic;
BEGIN
timerTC <= timerTCx1;
lastStage <= lastStage_xhdl2;
stage <= stage_xhdl3;
timer <= timer_xhdl4;
rdValid <= rdValid_xhdl5;
rst_comb <= rst OR startFFT;
rA_timer : counter
GENERIC MAP (WIDTH =>LOGPTS, TERMCOUNT =>HALFPTS+inBuf_RWDLY-1)
PORT MAP (clk => clk, nGrst => nGrst, rst => rst_comb,
cntEn => cntEn, tc => timerTCx1, Q => timer_xhdl4);
stage_timer : counter
GENERIC MAP (WIDTH => LOGLOGPTS, TERMCOUNT => LOGPTS-1)
PORT MAP (clk => clk, nGrst => nGrst, rst => rst_comb,
cntEn => timerTCx1, tc => lastStage_xhdl2,
Q => stage_xhdl3);
PROCESS (clk, nGrst)
BEGIN
IF (NOT nGrst = '1') THEN
preRdValid <= '0';
ELSIF (clk'EVENT AND clk = '1') THEN
IF (rst = '1') THEN
preRdValid <= '0' AFTER dlta;
ELSE
IF (cntEn = '1') THEN
IF ( to_integer(timer_xhdl4) = HALFPTS-1 ) THEN
preRdValid <= '0' AFTER dlta;
END IF;
-- on startFFT the valid reading session always starts
IF (startFFT = '1') THEN preRdValid <= '1' AFTER dlta;
END IF;
-- reading session starts on rTimerTC except after the lastStage
IF ((((NOT lastStage_xhdl2) AND timerTCx1) AND fft_runs) = '1') THEN
preRdValid <= '1' AFTER dlta;
END IF;
END IF;
END IF;
END IF;
END PROCESS;
PROCESS (clk)
BEGIN
IF (clk'EVENT AND clk = '1') THEN
rdValid_xhdl5 <= pipe2 AFTER dlta;
pipe2 <= pipe1 AFTER dlta;
pipe1 <= preRdValid AFTER dlta;
END IF;
END PROCESS;
END ARCHITECTURE translated;
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE work.fft_components.all;
ENTITY wrFFTtimer IS
GENERIC (LOGPTS : integer := 8;
LOGLOGPTS : integer := 3;
HALFPTS : integer := 128 );
PORT (
clk, cntEn, nGrst, rst : IN std_logic;
rstStage, rstTime : IN std_logic;
timerTC, lastStage : OUT std_logic; -- terminal counts of wA and stage
stage : OUT std_logic_vector(LOGLOGPTS-1 DOWNTO 0);
timer : OUT std_logic_vector(LOGPTS-2 DOWNTO 0));
END ENTITY wrFFTtimer;
ARCHITECTURE translated OF wrFFTtimer IS
CONSTANT timescale : time := 1 ns;
SIGNAL rst_VHDL,rstStage_VHDL : std_logic;
SIGNAL timerTC_xhdl1 : std_logic;
SIGNAL lastStage_xhdl2 : std_logic;
SIGNAL stage_xhdl3 : std_logic_vector(LOGLOGPTS-1 DOWNTO 0);
SIGNAL timer_xhdl4 : std_logic_vector(LOGPTS-2 DOWNTO 0);
BEGIN
timerTC <= timerTC_xhdl1;
lastStage <= lastStage_xhdl2;
stage <= stage_xhdl3;
timer <= timer_xhdl4;
rst_VHDL <= rstTime OR rst;
wA_timer : counter
GENERIC MAP (WIDTH => LOGPTS-1, TERMCOUNT =>HALFPTS-1)
PORT MAP (clk => clk, nGrst => nGrst, rst => rst_VHDL, cntEn => cntEn,
tc => timerTC_xhdl1, Q => timer_xhdl4);
rstStage_VHDL <= rstStage OR rst;
stage_timer : counter
GENERIC MAP (WIDTH => LOGLOGPTS, TERMCOUNT =>LOGPTS-1)
PORT MAP (clk => clk, nGrst => nGrst, rst => rstStage_VHDL,
cntEn => timerTC_xhdl1, tc => lastStage_xhdl2,
Q => stage_xhdl3);
END ARCHITECTURE translated;
--------------------------------------------------------------------------------
--********************* inBuf LOAD ADDRESS GENERATOR *********************
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE work.fft_components.all;
ENTITY inBuf_ldA IS
GENERIC (PTS : integer := 256;
LOGPTS : integer := 8 );
PORT (
clk, clkEn, nGrst : IN std_logic;
--comes from topSM to reset ldA count & start another loading cycle
startLoad : IN std_logic;
ifi_dataRdy : IN std_logic; -- inData strobe
ifo_loadOn : OUT std_logic;-- inBuf is ready for new data
--tells topSM the buffer is fully loaded and ready for FFTing
load_done : OUT std_logic;
ldA : OUT std_logic_vector(LOGPTS-1 DOWNTO 1);
wEn_even, wEn_odd : OUT std_logic;
ldValid : OUT std_logic);
END ENTITY inBuf_ldA;
ARCHITECTURE translated OF inBuf_ldA IS
CONSTANT timescale : time := 1 ns;
-- just LSB of the counter below. Counts even/odd samples
SIGNAL ldCountLsb_w : std_logic;
SIGNAL closeLoad_w, cntEn_w : std_logic;
SIGNAL loadOver_w : std_logic;
SIGNAL xhdl_9 : std_logic_vector(LOGPTS-1 DOWNTO 0);
SIGNAL ifo_loadOn_int : std_logic;
SIGNAL load_done_int : std_logic;
SIGNAL ldA_int : std_logic_vector(LOGPTS-1 DOWNTO 1);
SIGNAL wEn_even_int : std_logic;
SIGNAL wEn_odd_int : std_logic;
SIGNAL ldValid_int : std_logic;
BEGIN
ifo_loadOn <= ifo_loadOn_int;
load_done <= load_done_int;
ldA <= ldA_int;
wEn_even <= wEn_even_int;
wEn_odd <= wEn_odd_int;
ldValid <= ldValid_int;
cntEn_w <= clkEn AND ifi_dataRdy ;
loadOver_w <= closeLoad_w AND wEn_odd_int ;
ldValid_int <= ifo_loadOn_int AND ifi_dataRdy ;
wEn_even_int <= NOT ldCountLsb_w AND ldValid_int ;
wEn_odd_int <= ldCountLsb_w AND ldValid_int ;
-- xhdl_9 <= ldA_int & ldCountLsb_w;
ldA_int <= xhdl_9(LOGPTS-1 DOWNTO 1);
ldCountLsb_w <= xhdl_9(0);
-- counts samples loaded. There is `PTS samples to load, not `PTS/2
ldCount : counter
GENERIC MAP (WIDTH =>LOGPTS, TERMCOUNT =>PTS-1)
PORT MAP (clk => clk, nGrst => nGrst, rst => startLoad,
cntEn => cntEn_w, tc => closeLoad_w, Q => xhdl_9);
-- A user can stop supplying ifi_dataRdy after loadOver gets high, thus
-- the loadOver can stay high indefinitely. Shorten it!
edge_0 : edgeDetect
GENERIC MAP (INPIPE => 0, FEDGE => 1)
PORT MAP (clk => clk, clkEn => clkEn, edgeIn => loadOver_w,
edgeOut => load_done_int);
PROCESS (clk, nGrst)
BEGIN
-- generate ifo_loadOn:
IF (NOT nGrst = '1') THEN
ifo_loadOn_int <= '0';
ELSE
IF (clk'EVENT AND clk = '1') THEN
IF (clkEn = '1') THEN
-- if (load_done) ifo_loadOn <= #1 0;
IF (loadOver_w = '1') THEN
ifo_loadOn_int <= '0' AFTER timescale;
ELSE
IF (startLoad = '1') THEN
ifo_loadOn_int <= '1' AFTER timescale;
END IF;
END IF;
END IF;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE translated;
--------------------------------------------------------------------------------
--****************** inBuf ADDRESS GENERATOR for BFLY DATA *****************
-- Implements both read and write data generators. The core utilizes inPlace
-- algorithm thus the wA is a delayed copy of the rA
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;
USE work.fft_components.all;
ENTITY inBuf_fftA IS
GENERIC (LOGPTS : integer := 8;
LOGLOGPTS : integer := 3 );
PORT (
clk, clkEn :IN std_logic;
timer :IN std_logic_vector(LOGPTS-2 DOWNTO 0);
stage :IN std_logic_vector(LOGLOGPTS-1 DOWNTO 0);
timerTC, lastStage :IN std_logic;
fftDone, swCross :OUT std_logic;
bflyA :OUT std_logic_vector(LOGPTS-2 DOWNTO 0));
END ENTITY inBuf_fftA;
ARCHITECTURE translated OF inBuf_fftA IS
CONSTANT timescale : time := 1 ns;
CONSTANT offsetConst : bit_vector(LOGPTS-1 DOWNTO 0):=('1', others=>'0');
CONSTANT addrMask1: BIT_VECTOR(LOGPTS-1 DOWNTO 0) := ('0', OTHERS=>'1');
CONSTANT addrMask2: BIT_VECTOR(LOGPTS-1 DOWNTO 0) := (OTHERS=>'1');
SIGNAL fftDone_w, swCross_w: std_logic;
SIGNAL bflyA_w : std_logic_vector(LOGPTS-2 DOWNTO 0);
SIGNAL addrP_w, offsetPQ_w : std_logic_vector(LOGPTS-1 DOWNTO 0);
--rA takes either Paddr or Qaddr value (Qaddr=Paddr+offsetPQ) per clock.
--At even clk rA=Paddr, at odd clk rA=Qaddr. (Every addr holds a pair of
--data samples). Timer LSB controls which clk is happening now. LSB of
--the same timer controls switch(es).
SIGNAL bflyA_w_int : std_logic_vector(LOGPTS-1 DOWNTO 1);
SIGNAL swCross_w_int,swCross_int: std_logic;
SIGNAL fftDone_int : std_logic;
SIGNAL bflyA_int : std_logic_vector(LOGPTS-2 DOWNTO 0);
BEGIN
fftDone <= fftDone_int;
bflyA <= bflyA_int;
swCross <= swCross_int;
--addrP_w=( (timer<<1)&(~(addrMask2>>stage)) ) | (timer&(addrMask1>>stage));
addrP_w <= To_StdLogicVector(
( (('0'& To_BitVector(timer)) SLL 1) AND (NOT (addrMask2 SRL to_integer(stage)) ) )
OR ( ('0'& To_BitVector(timer)) AND (addrMask1 SRL to_integer(stage)) ) );
-- address offset between P and Q offsetPQ_w= ( 1<<(`LOGPTS-1) )>>stage;
offsetPQ_w <= To_StdLogicVector(offsetConst SRL to_integer(stage));
-- bflyA_w = timer[0] ? (addrP_w[`LOGPTS-1:1]+offsetPQ_w[`LOGPTS-1:1]):
-- addrP_w[`LOGPTS-1:1];
bflyA_w_int <=
(addrP_w(LOGPTS-1 DOWNTO 1) + offsetPQ_w(LOGPTS-1 DOWNTO 1)) WHEN
timer(0) = '1'
ELSE addrP_w(LOGPTS-1 DOWNTO 1);
bflyA_w <= bflyA_w_int AFTER timescale;
fftDone_w <= lastStage AND timerTC AFTER timescale;
swCross_w_int <= '0' WHEN lastStage = '1' ELSE timer(0);
swCross_w <= swCross_w_int AFTER timescale;
PROCESS (clk)
BEGIN
IF (clk'EVENT AND clk = '1') THEN
IF (clkEn = '1') THEN
bflyA_int <= bflyA_w AFTER timescale;
swCross_int <= swCross_w AFTER timescale;
fftDone_int <= fftDone_w AFTER timescale;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE translated;
--------------------------------------------------------------------------------
--************************** TWIDDLE wA GENERATOR ****************************
-- initializes Twiddle LUT on rst based on contents of twiddle.v file.
-- Generates trueRst when the initialization is over
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE work.fft_components.all;
ENTITY twid_wAmod IS
GENERIC (LOGPTS : integer := 8 );
PORT (
clk, ifiNreset : IN std_logic; -- async global reset
twid_wA : OUT std_logic_vector(LOGPTS-2 DOWNTO 0);
twid_wEn,twidInit : OUT std_logic;
rstAfterInit : OUT std_logic);
END ENTITY twid_wAmod;
ARCHITECTURE translated OF twid_wAmod IS
CONSTANT timescale : time := 1 ns;
CONSTANT allOnes : std_logic_vector(LOGPTS+1 DOWNTO 0):=(OTHERS=>'1');
SIGNAL slowTimer_w : std_logic_vector(LOGPTS+1 DOWNTO 0);
SIGNAL preRstAfterInit : std_logic;
SIGNAL twid_wA_int : std_logic_vector(LOGPTS-2 DOWNTO 0);
SIGNAL twid_wEn_int : std_logic;
SIGNAL rstAfterInit_int : std_logic;
SIGNAL twidInit_int : std_logic;
BEGIN
twid_wA <= twid_wA_int;
twid_wEn <= twid_wEn_int;
rstAfterInit <= rstAfterInit_int;
twidInit <= twidInit_int;
-- slow counter not to worry about the clk rate
slowTimer : bcounter
GENERIC MAP (WIDTH => LOGPTS+2)
PORT MAP (clk => clk, nGrst => ifiNreset, rst => '0',
cntEn => twidInit_int, Q => slowTimer_w);
-- wEn = 2-clk wide for the RAM to have enough time
twid_wEn_int <= to_logic(slowTimer_w(2 DOWNTO 1) = "11");
twid_wA_int <= slowTimer_w(LOGPTS+1 DOWNTO 3);
PROCESS (clk, ifiNreset)
BEGIN
IF (NOT ifiNreset = '1') THEN
twidInit_int <= '1' AFTER timescale;
ELSIF (clk'EVENT AND clk = '1') THEN
rstAfterInit_int <= preRstAfterInit AFTER timescale;
IF (slowTimer_w = allOnes) THEN twidInit_int <='0' AFTER timescale;
END IF;
preRstAfterInit <= to_logic(slowTimer_w = allOnes) AFTER timescale;
END IF;
END PROCESS;
END ARCHITECTURE translated;
--------------------------------------------------------------------------------
----------------------------------- outBufA ------------------------------------
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;
USE work.fft_components.all;
ENTITY outBufA IS
GENERIC (PTS : integer := 256;
LOGPTS : integer := 8 );
PORT (clk, clkEn, nGrst : IN std_logic;
rst, outBuf_wEn : IN std_logic;
timer : IN std_logic_vector(LOGPTS-2 DOWNTO 0);
-- host can slow down results reading by lowering the signal
rdCtl : IN std_logic;
wA : OUT std_logic_vector(LOGPTS-2 DOWNTO 0);
rA : OUT std_logic_vector(LOGPTS-1 DOWNTO 0);
outBuf_rEn, rdValid : OUT std_logic);
END ENTITY outBufA;
ARCHITECTURE translated OF outBufA IS
CONSTANT timescale : time := 1 ns;
SIGNAL reverseBitTimer, wA_w : std_logic_vector(LOGPTS-2 DOWNTO 0);
SIGNAL outBufwEnFall_w : std_logic;
SIGNAL rA_TC_w, preOutBuf_rEn: std_logic;
SIGNAL pipe11, pipe12, pipe21: std_logic;
SIGNAL pipe22, rdCtl_reg : std_logic;
-- Reset a binary counter on the rear edge
SIGNAL rstVhdl, rdValid_int : std_logic;
SIGNAL wA_int : std_logic_vector(LOGPTS-2 DOWNTO 0);
SIGNAL rA_int : std_logic_vector(LOGPTS-1 DOWNTO 0);
SIGNAL outBuf_rEn_int : std_logic;
BEGIN
wA <= wA_int;
rA <= rA_int;
outBuf_rEn <= outBuf_rEn_int;
rdValid <= rdValid_int;
PROCESS (timer)
VARIABLE reverseBitTimer_int : std_logic_vector(LOGPTS-2 DOWNTO 0);
BEGIN
reverseBitTimer_int := reverseStd(timer);
reverseBitTimer <= reverseBitTimer_int;
END PROCESS;
wA_w <= reverseBitTimer AFTER timescale;
-- rA generator. Detect rear edge of the outBuf wEn
fedge_0 : edgeDetect
GENERIC MAP (INPIPE => 0, FEDGE => 1)
PORT MAP (clk => clk, clkEn => '1', edgeIn => outBuf_wEn,
edgeOut => outBufwEnFall_w);
rstVhdl <= rst OR outBufwEnFall_w;
outBuf_rA_0 : counter
GENERIC MAP (WIDTH => LOGPTS, TERMCOUNT =>PTS-1)
PORT MAP (clk => clk, nGrst => nGrst, rst => rstVhdl,
cntEn => rdCtl_reg, tc => rA_TC_w, Q => rA_int);
PROCESS (clk, nGrst)
BEGIN
-- RS FF preOutBuf_rEn
IF (NOT nGrst = '1') THEN
preOutBuf_rEn <= '0' AFTER timescale;
ELSE
IF (clk'EVENT AND clk = '1') THEN
IF ((rst OR outBuf_wEn OR rA_TC_w) = '1') THEN
preOutBuf_rEn <= '0' AFTER timescale;
ELSE
IF (outBufwEnFall_w = '1') THEN
preOutBuf_rEn <= '1' AFTER timescale;
END IF;
END IF;
END IF;
END IF;
END PROCESS;
PROCESS (clk)
BEGIN
IF (clk'EVENT AND clk = '1') THEN
wA_int <= wA_w AFTER timescale;
rdCtl_reg <= rdCtl AFTER timescale;
outBuf_rEn_int <= pipe12 AFTER timescale;
pipe12 <= pipe11 AFTER timescale;
pipe11 <= preOutBuf_rEn AFTER timescale;
rdValid_int <= pipe22 AFTER timescale;
pipe22 <= pipe21 AFTER timescale;
pipe21 <= preOutBuf_rEn AND rdCtl_reg AFTER timescale;
END IF;
END PROCESS;
END ARCHITECTURE translated;
----------------------------------------------------------------------------------------------
--********************************** SM TOP ********************************
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.std_logic_arith.all;
USE work.fft_components.all;
ENTITY sm_top IS
GENERIC ( PTS : integer := 256;
HALFPTS : integer := 128;
LOGPTS : integer := 8;
LOGLOGPTS : integer := 3;
inBuf_RWDLY : integer := 12 );
PORT (clk,clkEn : IN std_logic;
ifiStart, ifiNreset : IN std_logic; --sync and async reset
ifiD_valid, ifiRead_y : IN std_logic;
ldA, rA, wA, tA : OUT std_logic_vector(LOGPTS-2 DOWNTO 0);
twid_wA, outBuf_wA : OUT std_logic_vector(LOGPTS-2 DOWNTO 0);
outBuf_rA : OUT std_logic_vector(LOGPTS-1 DOWNTO 0);
wEn_even, wEn_odd : OUT std_logic;
preSwCross, twid_wEn : OUT std_logic;
inBuf_wEn, outBuf_wEn : OUT std_logic;
smPong, ldValid : OUT std_logic;
inBuf_rdValid : OUT std_logic;
wLastStage : OUT std_logic;
smStartFFTrd : OUT std_logic;
smStartLoad, ifoLoad : OUT std_logic;
ifoY_valid, ifoY_rdy : OUT std_logic);
END ENTITY sm_top;
ARCHITECTURE translated OF sm_top IS
CONSTANT timescale : time := 1 ns;
COMPONENT inBuf_fftA
GENERIC (LOGPTS : integer := 8;
LOGLOGPTS : integer := 3 );
PORT (clk, clkEn : IN std_logic;
timer : IN std_logic_vector(LOGPTS-2 DOWNTO 0);
stage : IN std_logic_vector(LOGLOGPTS-1 DOWNTO 0);
timerTC, lastStage : IN std_logic;
fftDone, swCross : OUT std_logic;
bflyA : OUT std_logic_vector(LOGPTS-2 DOWNTO 0) );
END COMPONENT;
COMPONENT inBuf_ldA
GENERIC (PTS : integer := 8;
LOGPTS : integer := 3 );
PORT (
clk, clkEn, nGrst : IN std_logic;
startLoad, ifi_dataRdy : IN std_logic;
ifo_loadOn, load_done : OUT std_logic;
ldA : OUT std_logic_vector(LOGPTS-1 DOWNTO 1);
wEn_even, wEn_odd : OUT std_logic;
ldValid : OUT std_logic);
END COMPONENT;
COMPONENT outBufA
GENERIC (PTS : integer := 256;
LOGPTS : integer := 8 );
PORT (clk,clkEn,nGrst : IN std_logic;
rst, outBuf_wEn, rdCtl : IN std_logic;
timer : IN std_logic_vector(LOGPTS-2 DOWNTO 0);
wA : OUT std_logic_vector(LOGPTS-2 DOWNTO 0);
rA : OUT std_logic_vector(LOGPTS-1 DOWNTO 0);
outBuf_rEn, rdValid : OUT std_logic);
END COMPONENT;
COMPONENT rdFFTtimer
GENERIC (LOGPTS : integer := 8;
LOGLOGPTS : integer := 3;
HALFPTS : integer := 128;
inBuf_RWDLY : integer := 12 );
PORT (clk, cntEn, rst : IN std_logic;
startFFT,fft_runs,nGrst : IN std_logic;
timerTC, lastStage : OUT std_logic;
stage : OUT std_logic_vector(LOGLOGPTS-1 DOWNTO 0);
timer : OUT std_logic_vector(LOGPTS-1 DOWNTO 0);
rdValid : OUT std_logic );
END COMPONENT;
COMPONENT twid_rA
GENERIC (LOGPTS : integer := 8;
LOGLOGPTS : integer := 3 );
PORT (
clk : IN std_logic;
timer : IN std_logic_vector(LOGPTS-2 DOWNTO 0);
stage : IN std_logic_vector(LOGLOGPTS-1 DOWNTO 0);
tA : OUT std_logic_vector(LOGPTS-2 DOWNTO 0));
END COMPONENT;
COMPONENT twid_wAmod
GENERIC (LOGPTS : integer := 8 );
PORT (clk, ifiNreset: IN std_logic;
twid_wA : OUT std_logic_vector(LOGPTS-2 DOWNTO 0);
twid_wEn,twidInit : OUT std_logic;
rstAfterInit : OUT std_logic );
END COMPONENT;
COMPONENT wrFFTtimer
GENERIC (LOGPTS : integer := 8;
LOGLOGPTS : integer := 3;
HALFPTS : integer := 128 );
PORT (
clk, cntEn, nGrst, rst : IN std_logic;
rstStage, rstTime : IN std_logic;
timerTC, lastStage : OUT std_logic;
stage : OUT std_logic_vector(LOGLOGPTS-1 DOWNTO 0);
timer : OUT std_logic_vector(LOGPTS-2 DOWNTO 0));
END COMPONENT;
SIGNAL rTimer_w : std_logic_vector(LOGPTS-1 DOWNTO 0);
SIGNAL wTimer_w, timerT1 : std_logic_vector(LOGPTS-2 DOWNTO 0);
SIGNAL rStage_w,wStage_w : std_logic_vector(LOGLOGPTS-1 DOWNTO 0);
SIGNAL stageT1, stageT2 : std_logic_vector(LOGLOGPTS-1 DOWNTO 0);
SIGNAL rLastStage_w : std_logic;
SIGNAL rTimerTC_w : std_logic;
SIGNAL wTimerTC_w : std_logic;
SIGNAL load_done_w : std_logic;
SIGNAL sync_rAwA : std_logic;
SIGNAL fftRd_done_w : std_logic;
SIGNAL preInBuf_wEn : std_logic;
SIGNAL preOutBuf_wEn : std_logic;
SIGNAL trueRst : std_logic;
SIGNAL smBuf_full : std_logic; -- top level SM registers
SIGNAL smFft_rdy : std_logic; -- top level SM registers
SIGNAL smFft_runs : std_logic; -- top level SM registers
-- Reset logic:
-- - On ifiNreset start loading twidLUT.
-- - While it is loading keep global async rst nGrst active
-- - Once load is over issue short rstAfterInit which is just another ifiStart
SIGNAL initRst, nGrst : std_logic;
SIGNAL rstAfterInit : std_logic;
SIGNAL trueRst_w : std_logic;
SIGNAL xhdl_27, rdTimer_cntEn : std_logic;
SIGNAL port_xhdl37 : std_logic_vector(LOGPTS-2 DOWNTO 0);
SIGNAL ldA_xhdl1 : std_logic_vector(LOGPTS-2 DOWNTO 0);
SIGNAL rA_xhdl2 : std_logic_vector(LOGPTS-2 DOWNTO 0);
SIGNAL wA_xhdl3 : std_logic_vector(LOGPTS-2 DOWNTO 0);
SIGNAL tA_xhdl4 : std_logic_vector(LOGPTS-2 DOWNTO 0);
SIGNAL twid_wA_xhdl5 : std_logic_vector(LOGPTS-2 DOWNTO 0);
SIGNAL outBuf_wA_xhdl6 : std_logic_vector(LOGPTS-2 DOWNTO 0);
SIGNAL outBuf_rA_xhdl7 : std_logic_vector(LOGPTS-1 DOWNTO 0);
SIGNAL wEn_even_xhdl8 : std_logic;
SIGNAL wEn_odd_xhdl9 : std_logic;
SIGNAL preSwCross_xhdl10 : std_logic;
SIGNAL twid_wEn_xhdl11 : std_logic;
SIGNAL inBuf_wEn_xhdl12 : std_logic;
SIGNAL outBuf_wEn_xhdl13 : std_logic;
SIGNAL smPong_xhdl14 : std_logic;
SIGNAL ldValid_xhdl15 : std_logic;
SIGNAL inBuf_rdValid_int : std_logic;
SIGNAL wLastStage_xhdl17 : std_logic;
SIGNAL smStartFFTrd_int : std_logic;
SIGNAL smStartLoad_int : std_logic;
SIGNAL ifoLoad_xhdl20 : std_logic;
SIGNAL ifoY_valid_xhdl21 : std_logic;
SIGNAL ifoY_rdy_xhdl22 : std_logic;
SIGNAL smStartLoad_w : std_logic;
BEGIN
ldA <= ldA_xhdl1;
rA <= rA_xhdl2;
wA <= wA_xhdl3;
tA <= tA_xhdl4;
twid_wA <= twid_wA_xhdl5;
outBuf_wA <= outBuf_wA_xhdl6;
outBuf_rA <= outBuf_rA_xhdl7;
wEn_even <= wEn_even_xhdl8;
wEn_odd <= wEn_odd_xhdl9;
preSwCross <= preSwCross_xhdl10;
twid_wEn <= twid_wEn_xhdl11;
inBuf_wEn <= inBuf_wEn_xhdl12;
outBuf_wEn <= outBuf_wEn_xhdl13;
smPong <= smPong_xhdl14;
ldValid <= ldValid_xhdl15;
inBuf_rdValid <= inBuf_rdValid_int;
wLastStage <= wLastStage_xhdl17;
smStartFFTrd <= smStartFFTrd_int;
smStartLoad <= smStartLoad_int;
ifoLoad <= ifoLoad_xhdl20;
ifoY_valid <= ifoY_valid_xhdl21;
ifoY_rdy <= ifoY_rdy_xhdl22;
nGrst <= ifiNreset AND (NOT initRst) ;
trueRst_w <= rstAfterInit OR ifiStart ;
-- Top SM outputs
smStartFFTrd_int <= smBuf_full AND smFft_rdy ;
-- Start loading on FFT start or initially on trueRst.
smStartLoad_w <= trueRst_w OR smStartFFTrd_int ;
-- To prevent fake ifoY_rdy and ifoY_valid do not let rdFFTTimer run
-- outside smFft_runs
rdTimer_cntEn <= clkEn AND (smFft_runs OR smStartFFTrd_int);
-- FFT read inBuf timer
rdFFTtimer_0 : rdFFTtimer
GENERIC MAP (LOGPTS => LOGPTS,
LOGLOGPTS => LOGLOGPTS,
HALFPTS => HALFPTS,
inBuf_RWDLY => inBuf_RWDLY )
PORT MAP (
clk => clk,
cntEn => rdTimer_cntEn,
nGrst => nGrst,
rst => trueRst,
startFFT => smStartFFTrd_int,
timer => rTimer_w,
timerTC => rTimerTC_w,
stage => rStage_w,
lastStage => rLastStage_w,
fft_runs => smFft_runs,
rdValid => inBuf_rdValid_int);
-- FFT write inBuf timer
sync_rAwA <= To_logic(rTimer_w = CONV_STD_LOGIC_VECTOR(inBuf_RWDLY, LOGPTS-1)) ;
xhdl_27 <= sync_rAwA OR smStartFFTrd_int;
wrFFTtimer_0 : wrFFTtimer
GENERIC MAP (LOGPTS => LOGPTS,
LOGLOGPTS => LOGLOGPTS,
HALFPTS => HALFPTS )
PORT MAP (
clk => clk,
rst => trueRst,
nGrst => nGrst,
rstStage => smStartFFTrd_int,
rstTime => xhdl_27,
cntEn => clkEn,
timer => wTimer_w,
timerTC => wTimerTC_w,
stage => wStage_w,
lastStage => wLastStage_xhdl17);
--inData strobe
--out; inBuf is ready for new data (PTS new samples)
--out; tells topSM the buffer is fully loaded and ready for FFTing
inBuf_ldA_0 : inBuf_ldA
GENERIC MAP (PTS => PTS,
LOGPTS => LOGPTS )
PORT MAP (
clk => clk,
clkEn => clkEn,
nGrst => nGrst,
startLoad => smStartLoad_int,
ifi_dataRdy => ifiD_valid,
ifo_loadOn => ifoLoad_xhdl20,
load_done => load_done_w,
ldA => ldA_xhdl1,
wEn_even => wEn_even_xhdl8,
wEn_odd => wEn_odd_xhdl9,
ldValid => ldValid_xhdl15);
port_xhdl37 <= rTimer_w(LOGPTS-2 DOWNTO 0);
inBuf_rA_0 : inBuf_fftA
GENERIC MAP (LOGPTS => LOGPTS,
LOGLOGPTS => LOGLOGPTS )
PORT MAP (
clk => clk,
clkEn => clkEn,
timer => port_xhdl37,
stage => rStage_w,
timerTC => rTimerTC_w,
lastStage => rLastStage_w,
fftDone => fftRd_done_w,
bflyA => rA_xhdl2,
swCross => preSwCross_xhdl10); -- out
twid_rA_0 : twid_rA
GENERIC MAP (LOGPTS => LOGPTS,
LOGLOGPTS => LOGLOGPTS )
PORT MAP (
clk => clk,
timer => timerT1,
stage => stageT2,
tA => tA_xhdl4);
-- Twiddle LUT initialization
twid_wA_0 : twid_wAmod
GENERIC MAP (LOGPTS => LOGPTS )
PORT MAP (
clk => clk,
ifiNreset => ifiNreset,
twid_wA => twid_wA_xhdl5,
twid_wEn => twid_wEn_xhdl11,
twidInit => initRst,
rstAfterInit => rstAfterInit);
-- wA generator. On the last stage the fftRd_done comes before the last
-- FFT results get written back to the inBuf, but it is not necessary since
-- the results get written into the output buffer.
inBuf_wA_0 : inBuf_fftA
GENERIC MAP (LOGPTS => LOGPTS,
LOGLOGPTS => LOGLOGPTS )
PORT MAP (
clk => clk,
clkEn => clkEn,
timer => wTimer_w,
stage => wStage_w,
timerTC => wTimerTC_w,
lastStage => wLastStage_xhdl17,
fftDone => open,
bflyA => wA_xhdl3,
swCross => open);
outBufA_0 : outBufA
GENERIC MAP (PTS => PTS,
LOGPTS => LOGPTS )
PORT MAP (
clk => clk,
clkEn => clkEn,
nGrst => nGrst,
rst => trueRst,
timer => wTimer_w,
outBuf_wEn => outBuf_wEn_xhdl13,
rdCtl => ifiRead_y,
wA => outBuf_wA_xhdl6,
rA => outBuf_rA_xhdl7,
outBuf_rEn => ifoY_rdy_xhdl22,
rdValid => ifoY_valid_xhdl21);
PROCESS (clk)
BEGIN
IF (clk'EVENT AND clk = '1') THEN -- pipes
trueRst <= trueRst_w AFTER timescale;
smStartLoad_int <= smStartLoad_w AFTER timescale;
timerT1 <= rTimer_w(LOGPTS-2 DOWNTO 0) AFTER timescale;
stageT1 <= rStage_w AFTER timescale;
stageT2 <= stageT1 AFTER timescale;
inBuf_wEn_xhdl12 <= preInBuf_wEn AFTER timescale;
outBuf_wEn_xhdl13 <= preOutBuf_wEn AFTER timescale;
END IF;
END PROCESS;
PROCESS (clk, nGrst)
BEGIN
IF (NOT nGrst = '1') THEN -- reset topSM
smBuf_full <= '0';
smFft_rdy <= '0';
smFft_runs <= '0';
smPong_xhdl14 <= '1';
preInBuf_wEn <= '0';
preOutBuf_wEn <= '0';
--nGrst
ELSIF (clk'EVENT AND clk = '1') THEN
--mark A
IF (trueRst = '1') THEN
-- reset topSM
smBuf_full <= '0' AFTER timescale;
smFft_rdy <= '1' AFTER timescale;
smFft_runs <= '0' AFTER timescale;
smPong_xhdl14 <= '1' AFTER timescale;
preInBuf_wEn <= '0' AFTER timescale;
preOutBuf_wEn <= '0' AFTER timescale;
ELSE
-- mark B
IF (load_done_w = '1') THEN
smBuf_full <= '1' AFTER timescale;
END IF;
IF (fftRd_done_w = '1') THEN
smFft_rdy <= '1' AFTER timescale;
smFft_runs <= '0' AFTER timescale;
END IF;
IF (smStartFFTrd_int = '1') THEN
smBuf_full <= '0' AFTER timescale;
smFft_rdy <= '0' AFTER timescale;
smFft_runs <= '1' AFTER timescale;
smPong_xhdl14 <= NOT smPong_xhdl14 AFTER timescale;
END IF;
IF (sync_rAwA = '1') THEN
IF (rLastStage_w = '1') THEN
preOutBuf_wEn <= '1' AFTER timescale;
ELSE
IF (smFft_runs = '1') THEN
preInBuf_wEn <= '1' AFTER timescale;
END IF;
END IF;
END IF;
IF (wTimerTC_w = '1') THEN
preInBuf_wEn <= '0' AFTER timescale;
preOutBuf_wEn <= '0' AFTER timescale;
END IF;
END IF;
-- mark B
END IF;
-- mark A
END PROCESS;
END ARCHITECTURE translated;
------------------------------------------------------------------------------