-------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 15:31:32 03/13/06 -- Design Name: -- Module Name: control_unit - Behavioral -- Project Name: -- Target Device: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- -------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity analyser is Port ( clk : in std_logic; reset : in std_logic; ANA_record_len : in std_logic_vector(12 downto 0); ANA_addr_pointer : out std_logic_vector(12 downto 0); ANA_RD_addr : in std_logic_vector(13 downto 0); ANA_RD_DAT : out std_logic_vector(31 downto 0); ANA_slope : in std_logic; ANA_ARM : in std_logic; ANA_timer_en : in std_logic; ANA_DATA_ACQUIRED : out std_logic; ANA_trig : in std_logic_vector(7 downto 0); data_0 : in std_logic_vector(31 downto 0); data_1 : in std_logic_vector(31 downto 0); data_2 : in std_logic_vector(31 downto 0); data_3 : in std_logic_vector(31 downto 0); data_4 : in std_logic_vector(31 downto 0); data_5 : in std_logic_vector(31 downto 0); data_6 : in std_logic_vector(31 downto 0); data_7 : in std_logic_vector(31 downto 0); ANA_trig_src : in std_logic_vector(2 downto 0); ANA_CH1_src : in std_logic_vector(2 downto 0); ANA_CH2_src : in std_logic_vector(2 downto 0); ANA_timer : in std_logic_vector(23 downto 0); ANA_delay : in std_logic_vector(31 downto 0) ); end analyser; architecture Behavioral of analyser is --counters signals signal addr_cnt,RAM_addr, sample_cnt : std_logic_vector(12 downto 0); signal addr_cnt_en, sample_cnt_en, sample_cnt_end, sample_cnt_load : std_logic; signal delay_cnt : std_logic_vector(31 downto 0) ; signal delay_cnt_en, delay_cnt_load, delay_cnt_end : std_logic; signal RAM1_rd_dat, RAM2_rd_dat, CH1_din, CH2_din : std_logic_vector(31 downto 0) ; signal clk_en,clock_enable : std_logic; signal timer : std_logic_vector(23 downto 0) ; signal trig_sel, RAM_wren : std_logic; signal trig_edge_det : std_logic_vector(3 downto 0) ; signal trig_edge_r : std_logic; signal trig_edge_f : std_logic; signal trig_edge : std_logic; TYPE STATE_TYPE IS (idle,wait_trig,capture,completed,trig_delay); SIGNAL state: STATE_TYPE; component spram8192x32 port ( addr: IN std_logic_VECTOR(12 downto 0); clk: IN std_logic; din: IN std_logic_VECTOR(31 downto 0); dout: OUT std_logic_VECTOR(31 downto 0); we: IN std_logic); end component; begin --*************************************************************************************************** --*************************************** data input selector ******************************* --*************************************************************************************************** with ANA_CH2_src select CH2_din <= data_0 when "000", data_1 when "001", data_2 when "010", data_3 when "011", data_4 when "100", data_5 when "101", data_6 when "110", data_7 when others; with ANA_CH1_src select CH1_din <= data_0 when "000", data_1 when "001", data_2 when "010", data_3 when "011", data_4 when "100", data_5 when "101", data_6 when "110", data_7 when others; --*************************************************************************************************** --*************************************** trigger input selector ******************************* --*************************************************************************************************** with ANA_trig_src select trig_sel <= ANA_trig(0) when "000", ANA_trig(1) when "001", ANA_trig(2) when "010", ANA_trig(3) when "011", ANA_trig(4) when "100", ANA_trig(5) when "101", ANA_trig(6) when "110", ANA_trig(7) when others; --*************************************************************************************************** --*************************************** trigger edge detection ******************************* --*************************************************************************************************** process (clk) begin if rising_edge(clk) then trig_edge_det(0)<= trig_sel; trig_edge_det(1)<=trig_edge_det(0); trig_edge_det(2)<=trig_edge_det(1); trig_edge_det(3)<=trig_edge_det(2); end if; end process; trig_edge_f <= (not trig_edge_det(0)) and (not trig_edge_det(1)) and trig_edge_det(2)and trig_edge_det(3) ; trig_edge_r <= (not trig_edge_det(3)) and (not trig_edge_det(2)) and trig_edge_det(1)and trig_edge_det(0) ; trig_edge <= trig_edge_r when ANA_slope = '0' else trig_edge_f; --*************************************************************************************************** --*************************************** main state machine ******************************* --*************************************************************************************************** PROCESS (clk, reset) BEGIN IF reset = '1' THEN state <= idle; ELSIF rising_edge(clk) and clock_enable = '1' THEN CASE state IS WHEN idle => IF ANA_ARM ='1' THEN state <= wait_trig; END IF; WHEN wait_trig=> IF trig_edge ='1' THEN state <= trig_delay; END IF; WHEN trig_delay => IF delay_cnt_end='1' THEN state <= capture; END IF; WHEN capture=> IF sample_cnt_end ='1' THEN state <= completed; END IF; WHEN completed=> IF ANA_ARM ='0' THEN state <= idle; END IF; END CASE; END IF; END PROCESS; WITH state SELECT delay_cnt_en <= '1' WHEN trig_delay, '0' WHEN others; WITH state SELECT delay_cnt_load <= '1' WHEN wait_trig, '0' WHEN others; WITH state SELECT addr_cnt_en <= '0' WHEN completed, --register data all the time except reading sequence clock_enable WHEN others; WITH state SELECT sample_cnt_en <= '1' WHEN capture, '0' WHEN others; WITH state SELECT sample_cnt_load <= '1' WHEN trig_delay, '0' WHEN others; WITH state SELECT RAM_wren <= '0' WHEN completed, --register data all the time except reading sequence clock_enable WHEN others; WITH state SELECT ANA_DATA_ACQUIRED <= '1' WHEN completed, '0' WHEN others; --*************************************************************************************************** --*************************************** bufer momories ******************************* --*************************************************************************************************** --switching address bus between writes/reads RAM_addr <= ANA_RD_addr(12 downto 0) when (state <= completed) else addr_cnt; buffer1 : spram8192x32 port map ( addr => RAM_addr, clk => clk, din => CH1_din, dout => RAM1_rd_dat, we => RAM_wren ); buffer2 : spram8192x32 port map ( addr => RAM_addr, clk => clk, din => CH2_din, dout => RAM2_rd_dat, we => RAM_wren ); --switching RAM READ data bus between 2 memories depending on MSB READ address bit. ANA_RD_DAT <= RAM1_rd_dat when ANA_RD_addr(13) = '0' else RAM2_rd_dat; --*************************************************************************************************** --*************************************** counters ******************************* --*************************************************************************************************** --DPRAM address counter process(clk,reset) begin if rising_edge(clk) then if reset = '1' then addr_cnt <= (others=>'0'); elsif addr_cnt_en = '1' then addr_cnt <= addr_cnt+'1'; end if; end if; end process; --trigger delay counter process(clk,reset) begin if rising_edge(clk) then if reset = '1' then delay_cnt <= (others=>'0'); elsif delay_cnt_load = '1' then delay_cnt <= ANA_delay; elsif delay_cnt_en = '1' then delay_cnt <= delay_cnt - '1'; end if; if delay_cnt = x"FFFFFFFF" then delay_cnt_end <= '1'; else delay_cnt_end <= '0'; end if; end if; end process; --sample number counter process(clk,reset) begin if rising_edge(clk) then if reset = '1' then sample_cnt <= (others=>'0'); elsif sample_cnt_load = '1' then sample_cnt <= ANA_record_len; elsif sample_cnt_end = '1' then sample_cnt <= sample_cnt - '1'; end if; if sample_cnt = "0000000001" then sample_cnt_end <= '1'; else sample_cnt_end <= '0'; end if; end if; end process; --data address pointer latch process(clk) begin if rising_edge(clk) then if reset = '1' then ANA_addr_pointer <= (others=>'0'); elsif state = completed then ANA_addr_pointer <= addr_cnt; end if; end if; end process; ------------------------------------------------------------------------------------------------------ --CLK generator ------------------------------------------------------------------------------------------------------ process(clk,reset,timer) begin if reset='1' then timer<=x"000100"; elsif clk'event and clk ='0' then if clk_en = '1' then timer <= ANA_timer ; else timer <=timer -'1'; end if; end if; if timer = "000000" then clk_en<='1'; else clk_en<='0'; end if; end process; clock_enable <= clk_en when ANA_timer_en = '1' else '1'; end Behavioral;