library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.std_logic_signed.all; library fact_fad_lib; use fact_fad_lib.fad_definitions.all; ENTITY drs_pulser is port ( -- input CLK; RSRLOAD and SRCLK are derived from this signal CLK : in std_logic; -- async reset; reset : in std_logic; start_endless_mode : in std_logic; start_read_stop_pos_mode : in std_logic; SROUT_in_0 : in std_logic; SROUT_in_1 : in std_logic; SROUT_in_2 : in std_logic; SROUT_in_3 : in std_logic; -- stop_pos_0 : out std_logic_vector(9 downto 0); -- stop_pos_1 : out std_logic_vector(9 downto 0); -- stop_pos_2 : out std_logic_vector(9 downto 0); -- stop_pos_3 : out std_logic_vector(9 downto 0); stop_pos : out drs_s_cell_array_type; stop_pos_valid : out std_logic; RSRLOAD : out std_logic; SRCLK : out std_logic; busy :out std_logic ); end drs_pulser; ARCHITECTURE behavior of drs_pulser IS type states is (idle, started_endless, started_read_stop_pos , waiting_e, waiting_r, running_e, running_r); signal current_state : states := idle; signal next_state : states := idle; signal CEN,LEN : std_logic; signal local_roi : std_logic_vector (9 downto 0):= (others => '0'); signal flag_read_stop_pos : std_logic := '0'; signal cell_cntr : std_logic_vector (9 downto 0); signal cc_en : std_logic; signal cc_reset : std_logic; signal wait_cntr : std_logic_vector (2 downto 0); signal wc_en : std_logic; signal wc_reset : std_logic; signal int_stop_pos_0 : std_logic_vector(9 downto 0) := (others => '0'); signal int_stop_pos_1 : std_logic_vector(9 downto 0) := (others => '0'); signal int_stop_pos_2 : std_logic_vector(9 downto 0) := (others => '0'); signal int_stop_pos_3 : std_logic_vector(9 downto 0) := (others => '0'); begin RSRLOAD <= (LEN and CLK); SRCLK <= (CEN and CLK); stop_pos(0) <= int_stop_pos_0; stop_pos(1) <= int_stop_pos_1; stop_pos(2) <= int_stop_pos_2; stop_pos(3) <= int_stop_pos_3; state_register: process(clk, reset) begin IF reset = '1' THEN current_state <= idle ; ELSIF clk = '0' and clk'event THEN -- ! falling edge ! current_state <= next_state ; END IF; end process state_register; --Folgezustandsberechnung asynchron transition: process(current_state, start_endless_mode, start_read_stop_pos_mode, wait_cntr, cell_cntr, local_roi) begin CASE current_state IS WHEN idle => if start_endless_mode = '1' then next_state <= started_endless ; elsif start_read_stop_pos_mode = '1' then next_state <= started_read_stop_pos ; end if; WHEN started_endless => if cell_cntr = conv_std_logic_vector(1,10) then next_state <= waiting_e; end if; WHEN started_read_stop_pos => if cell_cntr = conv_std_logic_vector(1,10) then next_state <= waiting_r; end if; WHEN waiting_e => if wait_cntr = conv_std_logic_vector(0,3) then next_state <= running_e; else next_state <= waiting_e; end if; WHEN waiting_r => if wait_cntr = conv_std_logic_vector(0,3) then next_state <= running_r; end if; WHEN running_e => IF (start_endless_mode = '0') THEN next_state <= idle; END IF; WHEN running_r => if cell_cntr >= local_roi THEN next_state <= idle; end if; END CASE; end process transition; output_proc: process(current_state) --Ausgangsberechnung synchron, da current_state sich nur synchron aendert begin case current_state is when idle => local_roi <= (others => '0'); flag_read_stop_pos <= '0'; stop_pos_valid <= '1'; LEN <= '0'; CEN <= '0'; busy <= '0'; cc_en <= '0'; cc_reset <= '1'; wc_en <= '0'; wc_reset <= '0'; when started_endless => local_roi <= "0111111111"; flag_read_stop_pos <= '0'; stop_pos_valid <= '0'; LEN <= '1'; CEN <= '0'; busy <= '1'; cc_en <= '1'; cc_reset <= '0'; wc_en <= '0'; wc_reset <= '1'; when started_read_stop_pos => local_roi <= conv_std_logic_vector(11,10); flag_read_stop_pos <= '1'; stop_pos_valid <= '0'; LEN <= '1'; CEN <= '0'; busy <= '1'; cc_en <= '1'; cc_reset <= '0'; wc_en <= '0'; wc_reset <= '1'; when waiting_e | waiting_r => local_roi <= local_roi; stop_pos_valid <= '0'; busy <= '1'; LEN <= '0'; CEN <= '0'; cc_en <= '0'; cc_reset <= '0'; wc_en <= '1'; wc_reset <= '0'; when running_e => flag_read_stop_pos <= '0'; stop_pos_valid <= '0'; LEN <= '0'; CEN <= '1'; cc_en <= '1'; cc_reset <= '0'; wc_en <= '0'; wc_reset <= '0'; busy <= '1'; when running_r => flag_read_stop_pos <= '1'; stop_pos_valid <= '0'; LEN <= '0'; CEN <= '1'; cc_en <= '1'; cc_reset <= '0'; wc_en <= '0'; wc_reset <= '0'; busy <= '1'; end case; end process output_proc; cellcounter: process (clk, cc_reset) begin if (cc_reset = '1') then cell_cntr <= (others=>'0'); elsif (rising_edge(clk)) then if (cc_en = '1') then cell_cntr <= cell_cntr + 1; end if; end if; end process cellcounter; waitcounter: process (clk, wc_reset) begin if (wc_reset = '1') then wait_cntr <= "011"; -- RSRLOAD -> warte 3 -> SRCLK elsif (rising_edge(clk)) then if (wc_en = '1') then wait_cntr <= wait_cntr - 1; end if; end if; end process waitcounter; -- laut DRS4_rev09.pdf Seite 13 Figure 15 -- funktioniert das auslesen der Stop bzw. Startadresse so: -- Sende 1x RSRLOAD- und mind. 9 SRCLK- pulse und sample SROUT zur -- steigenden Flanke von SRCLK. -- MSB first LSB last, kommen dann die 10 bits, -- die die Stopposition darstellen. -- -- diese Architecture liefert immer dann eine steigende Flanke -- auf RSRCLK, wenn CLK eine steigende Flanke hat und CEN='1' ist. -- Die an SROUT zur steigenden Flanke anliegenden Werte werden wie in einem Schieberegister -- Schritt fuer Schritt in die stop_pos_x vectoren geschoben. -- -- wenn sie 10 schritte weit reingschoben wurden, ist der process fertig. -- es gibt keinen eigenen counter fuer die 10 schritte, der cell counter kann hier -- missbraucht werden. -- -- da der process eine steigende flanke auf SRCLK braucht um SROUT zu sampeln -- wird im Prinzip ein Puls aud SRCLK *zuviel* erzeugt, das ist aber egal... -- stop_pos_reader: process (CEN, clk, flag_read_stop_pos) begin IF (flag_read_stop_pos = '1') THEN -- nur wenn ich im read_stop_mode bin, laeuft dieser process IF (CEN = '1') THEN -- nur wenn CEN='1' ist kommen SRCLK pulse raus. IF (rising_edge(CLK)) THEN -- wenn steigende Flanke, dann SROUT samplen. int_stop_pos_0 <= int_stop_pos_0(8 downto 0) & SROUT_in_0; int_stop_pos_1 <= int_stop_pos_1(8 downto 0) & SROUT_in_1; int_stop_pos_2 <= int_stop_pos_2(8 downto 0) & SROUT_in_2; int_stop_pos_3 <= int_stop_pos_3(8 downto 0) & SROUT_in_3; END IF; -- rising edge CLK END IF; -- CEN ='1' END IF; -- flag_read_stop_pos = '1' end process stop_pos_reader; end behavior;