library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- Uncomment the following lines to use the declarations that are -- provided for instantiating Xilinx primitive components. --library UNISIM; --use UNISIM.VComponents.all; -- ************************************************************************ -- ALL Signals are active LOW unless specified -- ************************************************************************ -- -- ************************************************************************ -- REV 1.1 / February 25 2004 -- Addition of the FIFO3 enable to start the -- transfer into FIFO3 -- ************************************************************************ -- ************************************************************************ -- REV 1.2 / November 22 2004 -- a> Split of the counters N1 and 4095-N1 -- b> Reset dataready used to reset 2nd cnt and its ovf -- ************************************************************************ -- ************************************************************************ -- REV 1.3 / June 2006 -- Major revision ! -- (a)consolidation of fifo1,2,3 codes into a single fsm -- (b)Change in the data transfer to fifo3: -- (b-1) In acq with trigger, the transfer takes place after -- the record has been stored in fifo2. The acquisition -- is halted (no write in fifo2) until transfer completed. -- (b-2) In acq w/o trigger, the fifo are transparent and the data ready -- is generated once the record length is fifo3 is 4086 (4096-10). -- ************************************************************************ -- ************************************************************************ -- REV 1.4 / July 2006 -- In order to cope with the different clock frequencies between the syst -- and the channel, the reset dataready is made synchronous. -- ************************************************************************ -- ************************************************************************ -- REV 1.5 / July 2006 -- Modification of the reset of the transfer counter -- ************************************************************************ -- ##################################################################### -- -- TRIGGER MODE -- -- trigmode -- -- 0: Acquisition WITH trigger -- -- 1: Acquisition WITHOUT trigger -- -- ##################################################################### -- -- ##################################################################### -- -- DECIMATION RATIO -- -- The decimation is performed by controlling the write and read enable. -- -- The clock signals are NOT gated. -- -- decim_ratio: -- -- 00 <=> No decimation -- -- 01 <=> 1:2 -- -- 10 <=> 1:4 -- -- 11 <=> 1:8 -- -- Once the decim flag (trigger received) is active then the decimation -- -- stops -- -- ##################################################################### -- -- ##################################################################### -- -- Pretrigger Data Record Length -- -- ptrig_data -- -- 00: 512 -- -- 01: 1024 -- -- 10: 2048 -- -- 11: 2560 -- -- ##################################################################### -- entity fsm1 is Port ( reset : in std_logic; -- reset clk : in std_logic; -- clk (sampling) acqen : in std_logic; -- acquisition enable (command) trigmode : in std_logic; -- = 0 , acq w/ trig ## = 1 w/o trig trigger : in std_logic; -- trigger signal (synch'd) decim_ratio : in std_logic_vector(1 downto 0); -- decimation ratio ptrig_data : in std_logic_vector(1 downto 0); -- pre-trigger data record length rstdataready : in std_logic; rst1 : out std_logic; -- fifo#1 Reset wen1 : out std_logic; -- fifo#1 Write Enable ren1 : out std_logic; -- fifo#1 Read Enable rst2 : out std_logic; -- fifo#2 Reset wen2 : out std_logic; -- fifo#2 Write Enable ren2 : out std_logic; -- fifo#2 Read Enable rst3 : out std_logic; -- fifo#3 Reset wen3 : out std_logic; -- fifo#3 Write Enable trigger_en : out std_logic; -- Trigger Enable decim_flag : out std_logic; -- Decimation Flag dataready : out std_logic); end fsm1; architecture Behavioral of fsm1 is -- Components COMPONENT ren_wen PORT( reset : IN std_logic; clk : IN std_logic; decim_ratio : IN std_logic_vector(1 downto 0); decim_en : IN std_logic; decim_flag : IN std_logic; enable_r : IN std_logic; enable_w : IN std_logic; wen2 : OUT std_logic; ren2 : OUT std_logic ); END COMPONENT; -- Signals ------------------------------------------------------- type state_TYPE is (s0, s1, s2, s3, s4, s5, s6, s7); attribute ENUM_ENCODING: STRING; attribute ENUM_ENCODING of state_TYPE: type is "000 001 010 011 100 101 110 111"; signal state, next_state : state_TYPE; signal rst_fifo_cnt : std_logic; -- rst fifos and cnt signal enable_w2 : std_logic; -- enable w from FSM to ren_wen signal enable_r2 : std_logic; -- enable r from FSM to ren_wen signal decim_en : std_logic; -- decim enable to ren_wen signal decim_flag_sig : std_logic; -- decimation flag sig signal wen2_sig : std_logic; signal ren2_sig : std_logic; signal cnt_delay_en : std_logic; -- cnt enable delay (delay between read and write for fifo#1) signal cnt_record_en : std_logic; -- cnt enable data record (pre- and post-trigger data counter) signal cnt_transfer_en : std_logic; -- cnt enable transfer from fifo#2 to fifo#3 signal cnt_delay : integer range 31 downto 0; -- counter signal cnt_record : integer range 4095 downto 0; -- counter signal cnt_transfer : integer range 4095 downto 0; -- counter signal cnt_delay_ovf : std_logic; -- =0 when count = fs (32) signal cnt_record_ptrg : std_logic; -- =0 when count = pretrigger data amount (ptrig_par) signal cnt_record_ovf : std_logic; -- =0 when count = fs (4k) signal cnt_transfer_ovf : std_logic; -- =0 when count = fs (4k) signal ptrg_val_sig : integer range 4095 downto 0; -- pre trigger data amount setting for counter/comparator to generate cnt_record_ptrg signal dataready_sig : std_logic; ------------------------------------------------------- -- architecture description ------------------------------------------------------- begin ---------------------------------------------------- -- component's call ---------------------------------------------------- Inst_ren_wen: ren_wen PORT MAP( reset => reset, clk => clk, decim_ratio => decim_ratio, decim_en => decim_en, decim_flag => decim_flag_sig, enable_r => enable_r2, enable_w => enable_w2, wen2 => wen2_sig, ren2 => ren2_sig ); -------------------------------------------------------------------------------------- -- assignments -------------------------------------------------------------------------------------- rst1 <= rst_fifo_cnt; rst2 <= rst_fifo_cnt; rst3 <= rst_fifo_cnt; wen2 <= wen2_sig; ren2 <= ren2_sig; decim_flag <= decim_flag_sig; dataready <= dataready_sig; -------------------------------------------------------------------------------------- -- processes -------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------- -- FSM sequence / definition -------------------------------------------------------------------------------------- process (reset, clk) begin if reset = '0' then state <= s0; elsif (clk'event and clk= '1') then state <= next_state; else state <= state; end if; end process; -------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------- -- FSM Description -------------------------------------------------------------------------------------- process (state, acqen, trigmode, cnt_delay_ovf, cnt_record_ptrg, trigger, cnt_record_ovf, cnt_transfer_ovf, dataready_sig, rstdataready) begin case state is -------------------------------------------------------------------------------------- -- Initial State -- -------------------------------------------------------------------------------------- when s0 => rst_fifo_cnt <= '0'; decim_en <= '1'; decim_flag_sig <= '0'; wen1 <= '1'; ren1 <= '1'; enable_w2 <= '1'; enable_r2 <= '1'; wen3 <= '1'; cnt_delay_en <= '1'; cnt_record_en <= '1'; cnt_transfer_en <= '1'; trigger_en <= '1'; if acqen = '0' then if trigmode = '0' then -- acq w/ trigger next_state <= s1; else next_state <= s6; -- acq w/o trigger end if; else next_state <= s0; end if; -------------------------------------------------------------------------------------- -- acquisition w/ trigger -- Acq starts / Wait for FIFO1 delay -------------------------------------------------------------------------------------- when s1 => rst_fifo_cnt <= '1'; --* decim_en <= '0'; --* decim_flag_sig <= '0'; wen1 <= '0'; --* ren1 <= '1'; enable_w2 <= '1'; enable_r2 <= '1'; wen3 <= '1'; cnt_delay_en <= '0'; --* start counter for delay cnt_record_en <= '1'; cnt_transfer_en <= '1'; trigger_en <= '1'; if acqen = '0' then if cnt_delay_ovf = '0' then next_state <= s2; else next_state <= s1; end if; else next_state <= s0; end if; -------------------------------------------------------------------------------------- -- acquisition w/ trigger -- Record the pretrigger data samples -------------------------------------------------------------------------------------- when s2 => rst_fifo_cnt <= '1'; decim_en <= '0'; decim_flag_sig <= '0'; wen1 <= '0'; ren1 <= '0'; --* fifo1 is now only a pipeline delay enable_w2 <= '0'; --* enable write operation for fifo2 enable_r2 <= '1'; wen3 <= '1'; cnt_delay_en <= '1'; --* stop counter for delay cnt_record_en <= '0'; --* start the record counter cnt_transfer_en <= '1'; trigger_en <= '1'; if acqen = '0' then if cnt_record_ptrg = '0' then -- Pre-trigger data amount in fifo2 next_state <= s3; else next_state <= s2; end if; else next_state <= s0; end if; -------------------------------------------------------------------------------------- -- acquisition w/ trigger -- Arm trigger and refresh data record in fifo2 (halt record counter) -- If a request (dataready = 1) is already pending the trigger is not armed -------------------------------------------------------------------------------------- when s3 => rst_fifo_cnt <= '1'; decim_en <= '0'; decim_flag_sig <= '0'; wen1 <= '0'; ren1 <= '0'; enable_w2 <= '0'; enable_r2 <= '0'; --* wen3 <= '1'; cnt_delay_en <= '1'; cnt_record_en <= '1'; --* stop the record counter cnt_transfer_en <= '1'; trigger_en <= '0'; if acqen = '0' then if ( dataready_sig = '0' and trigger = '1' ) then next_state <= s4; else next_state <= s3; end if; else next_state <= s0; end if; -------------------------------------------------------------------------------------- -- acquisition w/ trigger --Trigger received / Record post trigger samples -------------------------------------------------------------------------------------- when s4 => rst_fifo_cnt <= '1'; decim_en <= '0'; decim_flag_sig <= '1'; --* wen1 <= '0'; ren1 <= '0'; enable_w2 <= '0'; enable_r2 <= '1'; --* stop reading and accumualte the rest of the samples wen3 <= '1'; cnt_delay_en <= '1'; cnt_record_en <= '0'; --* restart the record counter cnt_transfer_en <= '1'; trigger_en <= '1'; if acqen = '0' then if cnt_record_ovf = '0' then -- all the samples are recorded next_state <= s5; else next_state <= s4; end if; else next_state <= s0; end if; -------------------------------------------------------------------------------------- -- acquisition w/ trigger --transfer into FIFO3 -------------------------------------------------------------------------------------- when s5 => rst_fifo_cnt <= '1'; decim_en <= '0'; decim_flag_sig <= '1'; wen1 <= '1'; ren1 <= '1'; enable_w2 <= '1'; --* stop writing enable_r2 <= '0'; --* start reading into ffio3 wen3 <= '0'; --* write data from fifo2 into fifo3 cnt_delay_en <= '1'; cnt_record_en <= '1'; --* stops the record counter cnt_transfer_en <= '0'; trigger_en <= '1'; if acqen = '0' then if cnt_transfer_ovf = '0' then next_state <= s7; else next_state <= s5; end if; else next_state <= s0; end if; -------------------------------------------------------------------------------------- -- acquisition w/o trigger -- FIFO 1 and FIFO 2 are transparent, data is written into FIFO3 -------------------------------------------------------------------------------------- when s6 => rst_fifo_cnt <= '1'; decim_en <= '1'; decim_flag_sig <= '1'; wen1 <= '0'; --* enable write / read from fifo 1 to 2 to 3 ren1 <= '0'; --* enable_w2 <= '0'; --* enable_r2 <= '0'; --* wen3 <= '0'; --* cnt_delay_en <= '1'; cnt_record_en <= '1'; cnt_transfer_en <= '0'; --* enable counter trigger_en <= '1'; if acqen = '0' then if cnt_transfer_ovf = '0' then next_state <= s7; else next_state <= s6; end if; else next_state <= s0; end if; -------------------------------------------------------------------------------------- -- acquisition with and without trigger - Disable all transfers until the rsdry is received -------------------------------------------------------------------------------------- when s7 => rst_fifo_cnt <= '1'; decim_en <= '1'; decim_flag_sig <= '1'; wen1 <= '1'; --* ren1 <= '1'; --* enable_w2 <= '1'; --* enable_r2 <= '1'; --* wen3 <= '1'; --* cnt_delay_en <= '1'; cnt_record_en <= '1'; cnt_transfer_en <= '1'; --* disable counter trigger_en <= '1'; if acqen = '0' then -- if rstdataready = '0' then if trigmode = '0' then -- acq w/ trigger next_state <= s2; else next_state <= s6; -- acq w/o trigger end if; else next_state <= s7; end if; else next_state <= s0; end if; ------------------------- when others => rst_fifo_cnt <= '0'; decim_en <= '1'; decim_flag_sig <= '1'; wen1 <= '1'; ren1 <= '1'; enable_w2 <= '1'; enable_r2 <= '1'; wen3 <= '1'; cnt_delay_en <= '1'; cnt_record_en <= '1'; cnt_transfer_en <= '1'; trigger_en <= '1'; next_state <= s0; end case; end process; ---------------------------------------------------- -------------------------------------------------------------------------------------- -- Pretrigger data amount - Value Selection -------------------------------------------------------------------------------------- process (ptrig_data) begin case ptrig_data is -- remove the ";--" from the following n1_val assignments -- to get the proper values: 511, 1023, 2047, 2559 when "00" => ptrg_val_sig <= 511; -- Value - 1 when "01" => ptrg_val_sig <= 1023; when "10" => ptrg_val_sig <= 2047; when others => ptrg_val_sig <= 2559; end case; end process; -------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------- -- process counter - DELAY between WEN and REN for FIFO#1 for Decimation ratio -------------------------------------------------------------------------------------- process(rst_fifo_cnt, clk, cnt_delay_en, cnt_delay, cnt_delay_ovf) begin if rst_fifo_cnt = '0' then cnt_delay <= 0; cnt_delay_ovf <= '1'; elsif ( clk'event and clk = '1' ) then if cnt_delay_en = '0' then if cnt_delay < 31 then cnt_delay_ovf <= '1'; cnt_delay <= cnt_delay + 1; else cnt_delay_ovf <= '0'; cnt_delay <= cnt_delay; end if; else cnt_delay_ovf <= cnt_delay_ovf; cnt_delay <= cnt_delay; end if; end if; end process; -------------------------------------------------------------------------------------- -- process counter - RECORD -- Counter Value is Record-2 counts -- Header size = 10 -- Record = 4096 -- FS = 4096-10-2= 4084 -------------------------------------------------------------------------------------- process(rst_fifo_cnt, clk, cnt_record_en, cnt_record, cnt_record_ovf, wen2_sig, cnt_transfer_ovf) begin if ( rst_fifo_cnt = '0' or cnt_transfer_ovf = '0' )then cnt_record <= 0; cnt_record_ovf <= '1'; elsif ( clk'event and clk = '1' ) then if ( cnt_record_en = '0' and wen2_sig = '0' ) then if cnt_record < 4084 then cnt_record <= cnt_record + 1; cnt_record_ovf <= '1'; else cnt_record <= cnt_record; cnt_record_ovf <= '0'; end if; else cnt_record <= cnt_record; cnt_record_ovf <= cnt_record_ovf; end if; end if; end process; -------------------------------------------------------------------------------------- -- Process pre trigger data counter -- Generates an overflow signal when counter value reached ptrg_data -------------------------------------------------------------------------------------- process(rst_fifo_cnt, cnt_transfer_ovf, clk, cnt_record, ptrg_val_sig) begin if ( rst_fifo_cnt = '0' or cnt_transfer_ovf = '0' )then cnt_record_ptrg <= '1'; elsif ( clk'event and clk = '1' ) then if cnt_record < ptrg_val_sig then cnt_record_ptrg <= '1'; else cnt_record_ptrg <= '0'; end if; end if; end process; -------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------- -- process counter - TRANSFER -------------------------------------------------------------------------------------- process(rst_fifo_cnt, rstdataready, clk, cnt_transfer_en, cnt_transfer, cnt_transfer_ovf) begin if ( rst_fifo_cnt = '0' or rstdataready = '0' ) then -- modification 7/20 cnt_transfer <= 0; cnt_transfer_ovf <= '1'; elsif ( clk'event and clk = '1' ) then if cnt_transfer_en = '0' then if cnt_transfer < 4084 then cnt_transfer <= cnt_transfer + 1; cnt_transfer_ovf <= '1'; else cnt_transfer <= cnt_transfer; cnt_transfer_ovf <= '0'; end if; else cnt_transfer <= cnt_transfer; cnt_transfer_ovf <= cnt_transfer_ovf; end if; end if; end process; -------------------------------------------------------------------------------------- -- process counter - DATAREADY -------------------------------------------------------------------------------------- process(rst_fifo_cnt, clk, dataready_sig, cnt_transfer_ovf,rstdataready) begin if ( clk'event and clk = '1' ) then if ( rst_fifo_cnt = '0' or rstdataready = '0') then dataready_sig <= '0'; elsif cnt_transfer_ovf = '0' then dataready_sig <= '1'; else dataready_sig <= dataready_sig; end if; else dataready_sig <= dataready_sig; end if; end process; -------------------------------------------------------------------------------------- end Behavioral;