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 / DEC 5 2004 -- -- #0-HEADER SIZE =10 -- #1-CHANNEL ADDRESS -- #2-EVENT TIMER MSB -- #3-EVENT TIMER LSB -- #4-BEAM ON MSB -- #5-BEAM ON LSB -- #6-BEAM OFF MSB -- #7-BEAM OFF LSB -- #8-DECIMATION WORD COUNT -- #9-NON-DECIMATION WORD COUNT -- -- ************************************************************ -- ************************************************************ -- REV 1.2 -- 2006/07/13 -- Consolidation of the FSM into one -- SYNCHRONOUS RESET -- -- transfer of the data from the Timer, Ebeam and Channel -- (1) Timer - Header -- (2) Timer - Channel ID -- (3) Timer - Timer MSB -- (4) Timer - Timer LSB -- (5) Ebeam - Timer1 MSB -- (6) Ebeam - Timer1 LSB -- (7) Ebeam - Timer2 MSB -- (8) Ebeam - Timer2 LSB -- (9) Timer - Decimation Word Count -- (10)Timer - Non-Decimation Word Count -- ************************************************************ ENTITY transfer_fsm IS PORT (reset : IN STD_LOGIC; clk : IN STD_LOGIC; enable : IN STD_LOGIC; txreq : IN STD_LOGIC; dataready : IN STD_LOGIC; -- added for handshake with channel -- control CPLD latchen1 : OUT STD_LOGIC; latchen2 : OUT STD_LOGIC; timer_oe : OUT STD_LOGIC; -- sel chn/output buffer timer_header : OUT STD_LOGIC; -- mux sel header timer_chnid : OUT STD_LOGIC; -- mux sel channel addr timer_upper : OUT STD_LOGIC; -- mux sel timer msb timer_lower : OUT STD_LOGIC; -- mux sel timer msb timer_dwc : OUT STD_LOGIC; -- mux sel decimation word count timer_ndwc : OUT STD_LOGIC; -- mux sel non decimation word count ebeam_oe : OUT STD_LOGIC; -- sel chn/output buffer ebeam_timer1 : OUT STD_LOGIC; -- mux sel header ebeam_timer2 : OUT STD_LOGIC; -- mux sel channel addr ebeam_upword : OUT STD_LOGIC; -- mux sel timer msb ebeam_loword : OUT STD_LOGIC; -- mux sel timer msb chn_data_ren : OUT STD_LOGIC; -- channel data read enavle clr_req : OUT STD_LOGIC; wen4 : OUT STD_LOGIC -- ); END transfer_fsm; ARCHITECTURE Behavioral OF transfer_fsm IS ----------------------------------------------------------------------------------------------------------------- -- Signals ----------------------------------------------------------------------------------------------------------------- -- fsm TYPE STATE_TYPE IS (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20); SIGNAL state : STATE_TYPE; SIGNAL next_state : STATE_TYPE; ATTRIBUTE ENUM_ENCODING : STRING; ATTRIBUTE ENUM_ENCODING OF STATE_TYPE : TYPE IS "00000 00001 00010 00011 00100 00101 00110 00111 01000 01001 01010 01011 01100 01101 01110 01111 10000 10001 10010 10011 10100"; SIGNAL data_tx_cnt : INTEGER RANGE 0 TO 4095; SIGNAL data_tx_en : STD_LOGIC; -- ACTIVE LOW counter enable SIGNAL data_tx_ovf : STD_LOGIC; -- ACTIVE LOW counter overflow SIGNAL clr_req_cnt : INTEGER RANGE 0 TO 31; SIGNAL clr_req_en : STD_LOGIC; -- ACTIVE LOW counter enable SIGNAL clr_req_ovf : STD_LOGIC; -- ACTIVE LOW counter overflow ----------------------------------------------------------------------------------------------------------------- -- Architecture description ----------------------------------------------------------------------------------------------------------------- BEGIN chn_data_ren <= data_tx_en; clr_req <= clr_req_en; ------------------------------------------------------------------------------------------ -- FSM Definition ------------------------------------------------------------------------------------------ PROCESS (reset, clk) BEGIN IF reset = '0' THEN state <= s0; ELSIF (clk'EVENT AND clk = '1') THEN state <= next_state; END IF; END PROCESS; ------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------ -- FSM Description ----------------------------------------------------------------------------------------- PROCESS (state, enable, txreq, data_tx_ovf, clr_req_ovf) BEGIN CASE state IS WHEN s0 => -- Idle State latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '1'; IF enable = '0' THEN next_state <= s1; ELSE next_state <= s0; END IF; WHEN s1 => -- Enable latch 1 and 2 latchen1 <= '0'; latchen2 <= '0'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '1'; IF enable = '0' THEN IF txreq = '1' THEN next_state <= s2; ELSE next_state <= s1; END IF; ELSE next_state <= s0; END IF; WHEN s2 => -- disable latch 1 and 2 latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '1'; IF enable = '0' THEN next_state <= s3; ELSE next_state <= s0; END IF; WHEN s3 => -- access timer / transfer header / write data into FIFO4 latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '0'; timer_header <= '0'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '0'; IF enable = '0' THEN next_state <= s4; ELSE next_state <= s0; END IF; WHEN s4 => -- access timer / transfer channel address / write data into FIFO4 latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '0'; timer_header <= '1'; timer_chnid <= '0'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '0'; IF enable = '0' THEN next_state <= s5; ELSE next_state <= s0; END IF; WHEN s5 => -- access timer / transfer timer MSB / write data into FIFO4 latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '0'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '0'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '0'; IF enable = '0' THEN next_state <= s6; ELSE next_state <= s0; END IF; WHEN s6 => -- access timer / transfer timer LSB / write data into FIFO4 latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '0'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '0'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '0'; IF enable = '0' THEN next_state <= s7; ELSE next_state <= s0; END IF; WHEN s7 => -- NOP latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '1'; IF enable = '0' THEN next_state <= s8; ELSE next_state <= s0; END IF; WHEN s8 => -- access header / transfer timer1 MSB / write data into FIFO4 latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '0'; ebeam_timer1 <= '0'; ebeam_timer2 <= '1'; ebeam_upword <= '0'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '0'; IF enable = '0' THEN next_state <= s9; ELSE next_state <= s0; END IF; WHEN s9 => -- access header / transfer timer1 LSB / write data into FIFO4 latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '0'; ebeam_timer1 <= '0'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '0'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '0'; IF enable = '0' THEN next_state <= s10; ELSE next_state <= s0; END IF; WHEN s10 => -- access header / transfer timer2 MSB / write data into FIFO4 latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '0'; ebeam_timer1 <= '1'; ebeam_timer2 <= '0'; ebeam_upword <= '0'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '0'; IF enable = '0' THEN next_state <= s11; ELSE next_state <= s0; END IF; WHEN s11 => -- access header / transfer timer2 LSB / write data into FIFO4 latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '0'; ebeam_timer1 <= '1'; ebeam_timer2 <= '0'; ebeam_upword <= '1'; ebeam_loword <= '0'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '0'; IF enable = '0' THEN next_state <= s12; ELSE next_state <= s0; END IF; WHEN s12 => -- NOP latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '1'; IF enable = '0' THEN next_state <= s13; ELSE next_state <= s0; END IF; WHEN s13 => -- access timer / Decimation count / write data into FIFO4 latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '0'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '0'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '0'; IF enable = '0' THEN next_state <= s14; ELSE next_state <= s0; END IF; WHEN s14 => -- access timer / Non-Decimation count / write data into FIFO4 latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '0'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '0'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '0'; IF enable = '0' THEN next_state <= s15; ELSE next_state <= s0; END IF; WHEN s15 => -- NOP latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '1'; IF enable = '0' THEN next_state <= s16; ELSE next_state <= s0; END IF; WHEN s16 => -- data transfer from channel latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '0'; clr_req_en <= '1'; wen4 <= '0'; IF enable = '0' THEN IF data_tx_ovf = '0' THEN next_state <= s17; ELSE next_state <= s16; END IF; ELSE next_state <= s0; END IF; WHEN s17 => -- clear request latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '0'; wen4 <= '1'; IF enable = '0' THEN IF clr_req_ovf = '0' THEN next_state <= s18; ELSE next_state <= s17; END IF; ELSE next_state <= s0; END IF; WHEN s18 => -- Update content of latch 2 latchen1 <= '1'; latchen2 <= '0'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '1'; next_state <= s19; WHEN s19 => -- NOP latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '1'; next_state <= s20; WHEN s20 => -- NOP latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '1'; IF (enable = '0' AND txreq = '0') THEN next_state <= s0; ELSE next_state <= s2; END IF; WHEN OTHERS => latchen1 <= '1'; latchen2 <= '1'; timer_oe <= '1'; timer_header <= '1'; timer_chnid <= '1'; timer_upper <= '1'; timer_lower <= '1'; timer_dwc <= '1'; timer_ndwc <= '1'; ebeam_oe <= '1'; ebeam_timer1 <= '1'; ebeam_timer2 <= '1'; ebeam_upword <= '1'; ebeam_loword <= '1'; data_tx_en <= '1'; clr_req_en <= '1'; wen4 <= '1'; next_state <= s0; END CASE; END PROCESS; ------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------ -- Process - Counter for Data Transfer. ------------------------------------------------------------------------------------------ PROCESS (reset, clk, data_tx_en) BEGIN IF (clk'EVENT AND clk = '1') THEN IF reset = '0' THEN data_tx_cnt <= 0; data_tx_ovf <= '1'; ELSIF data_tx_en = '0' THEN IF data_tx_cnt < 4083 THEN data_tx_cnt <= data_tx_cnt +1; data_tx_ovf <= '1'; ELSE data_tx_cnt <= 0; data_tx_ovf <= '0'; END IF; ELSE data_tx_cnt <= 0; data_tx_ovf <= '1'; END IF; END IF; END PROCESS; ------------------------------------------------------------------------------------------ -- Process - Counter Delay for the Dataready reset signal ------------------------------------------------------------------------------------------ PROCESS (reset, clk, clr_req_en) BEGIN IF (clk'EVENT AND clk = '1') THEN IF reset = '0' THEN clr_req_cnt <= 0; clr_req_ovf <= '1'; ELSIF clr_req_en = '0' THEN --IF clr_req_cnt < 31 THEN IF dataready = '1' THEN -- add data ready to input clr_req_cnt <= clr_req_cnt +1; clr_req_ovf <= '1'; ELSE clr_req_cnt <= 0; clr_req_ovf <= '0'; END IF; ELSE clr_req_cnt <= 0; clr_req_ovf <= '1'; END IF; END IF; END PROCESS; END Behavioral;