fftSm.vhd
881 lines
| 31.5 KiB
| text/x-vhdl
|
VhdlLexer
pellion
|
r418 | -------------------------------------------------------------------------------- | ||
-- 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; | ||||
------------------------------------------------------------------------------ | ||||