From: Tobias Weber Date: Tue, 8 Aug 2017 11:41:26 +0000 (+0200) Subject: separating mupix readout and hit generation state machines. X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=2c173472e8ebd72a462d1ef749e5dab7189cc9db;p=trb3.git separating mupix readout and hit generation state machines. --- diff --git a/mupix/sources/MuPix3_interface.vhd b/mupix/sources/MuPix3_interface.vhd index ca593b1..dec6d77 100644 --- a/mupix/sources/MuPix3_interface.vhd +++ b/mupix/sources/MuPix3_interface.vhd @@ -50,20 +50,20 @@ end mupix_interface; architecture RTL of mupix_interface is + + type ro_state_type is (idle, loadpix, pulld, loadcol, readcol, pause); + type hitgen_state_type is (idle, genheader, genhits, hitgeneratorwait); - - type ro_state_type is (waiting, readman, loadpix, pulld, loadcol, readcol, hitgenerator, hitgeneratorwait, pause); - signal state : ro_state_type := waiting; - + signal ro_state : ro_state_type := idle; + signal hitgen_state : hitgen_state_type := idle; - signal delcounter : unsigned(7 downto 0) := (others => '0'); + signal ro_delcounter : unsigned(7 downto 0) := (others => '0'); + signal hitgen_delcounter : integer range 0 to 2 := 2; signal delaycounters1 : std_logic_vector(31 downto 0) := (others => '0'); signal delaycounters2 : std_logic_vector(31 downto 0) := (others => '0'); signal pauseregister : std_logic_vector(31 downto 0) := (others => '0'); signal pausecounter : unsigned (31 downto 0) := (others => '0'); - signal ro_busy_int : std_logic := '0'; signal graycount : std_logic_vector(7 downto 0) := (others => '0'); - signal eventcounter : unsigned(31 downto 0) := (others => '0'); signal hitcounter : unsigned(10 downto 0) := (others => '0'); signal maxNumberHits : std_logic_vector(31 downto 0) := (others => '1'); signal graycounter_clkdiv_counter : std_logic_vector(31 downto 0) := (others => '0'); @@ -72,7 +72,6 @@ architecture RTL of mupix_interface is signal triggering : std_logic := '0'; signal continousread : std_logic := '0'; signal readnow : std_logic := '0'; - signal readmanual : std_logic := '0'; signal reseteventcount : std_logic := '0'; signal generatehit : std_logic := '0'; signal generatehits : std_logic := '0'; @@ -95,15 +94,35 @@ architecture RTL of mupix_interface is signal timestampcontrolbits : std_logic_vector(31 downto 0) := (others => '0'); signal generatehitswait : std_logic_vector(31 downto 0) := (others => '0'); - signal ignorehitflag : std_logic := '0'; - --readout signal registers signal priout_reg : std_logic := '0'; signal ld_pix_reg : std_logic := '0'; signal pulldown_reg : std_logic := '0'; signal ld_col_reg : std_logic := '0'; signal rd_col_reg : std_logic := '0'; - + + --data multiplexing + signal selecthitgen : std_logic := '0'; + signal memdata_mupix_i : std_logic_vector(31 downto 0); + signal memwren_mupix_i : std_logic; + signal endofevent_mupix_i : std_logic; + signal ro_busy_mupix_i : std_logic; + signal memdata_hitgen_i : std_logic_vector(31 downto 0); + signal memwren_hitgen_i : std_logic; + signal endofevent_hitgen_i : std_logic; + signal ro_busy_hitgen_i : std_logic; + + --event counting + signal eventcounter : unsigned(31 downto 0) := (others => '0'); + signal increase_eventcounter_mpx_i : std_logic; + signal increase_eventcounter_hitgen_i : std_logic; + + --start readouts + type ro_ctrl_type is (idle, mupix_reading, hitgen_running); + signal ro_ctrl_state : ro_ctrl_type := idle; + signal start_mupix_ro_i : std_logic := '0'; + signal start_hitgen_i : std_logic := '0'; + signal ro_busy_vec : std_logic_vector(1 downto 0) := (others => '0'); begin @@ -118,12 +137,10 @@ begin --x0506: Pause Register --x0507: Delay Counters 2 --x0508: Divider for graycounter clock - --x0509: mask flag for (col,row) = (0,0) --x0510: testoutro --x0511: Sensor-ID --x0512: maximal frame size ----------------------------------------------------------------------------- - SLV_HANDLER : process(clk) begin -- process SLV_HANDLER if rising_edge(clk) then @@ -162,9 +179,6 @@ begin when x"0508" => SLV_DATA_OUT <= graycounter_clkdiv_counter; SLV_ACK_OUT <= '1'; - when x"0509" => - SLV_DATA_OUT(0) <= ignorehitflag; - SLV_ACK_OUT <= '1'; when x"0510" => SLV_DATA_OUT <= testoutro; SLV_ACK_OUT <= '1'; @@ -175,7 +189,7 @@ begin SLV_DATA_OUT <= maxNumberHits; SLV_ACK_OUT <= '1'; when x"0513" => - SLV_DATA_OUT(0) <= ro_busy_int; + SLV_DATA_OUT(0) <= ro_busy_hitgen_i or ro_busy_mupix_i; SLV_ACK_OUT <= '1'; when others => SLV_UNKNOWN_ADDR_OUT <= '1'; @@ -209,9 +223,6 @@ begin when x"0508" => graycounter_clkdiv_counter <= SLV_DATA_IN; SLV_ACK_OUT <= '1'; - when x"0509" => - ignorehitflag <= SLV_DATA_IN(0); - SLV_ACK_OUT <= '1'; when x"0511" => sensor_id <= SLV_DATA_IN; SLV_ACK_OUT <= '1'; @@ -235,7 +246,6 @@ begin triggering <= '0'; continousread <= '0'; readnow <= '0'; - readmanual <= '0'; reseteventcount <= '0'; generatehit <= '0'; generatehits <= '0'; @@ -249,7 +259,6 @@ begin else readnow <= '0'; end if; - readmanual <= roregister(3); if((roregister(4) = '1' and roregwritten = '1') or eventcounterreset_in = '1') then reseteventcount <= '1'; else @@ -267,6 +276,51 @@ begin end if; end process; + readout_ctrl : process (clk) is + begin + if rising_edge(clk) then + if rst = '1' then + ro_ctrl_state <= idle; + start_mupix_ro_i <= '0'; + start_hitgen_i <= '0'; + ro_busy_vec <= (others => '0'); + else + start_mupix_ro_i <= '0'; + start_hitgen_i <= '0'; + selecthitgen <= '0'; + ro_busy_vec <= ro_busy_vec(0) & (ro_busy_mupix_i or ro_busy_hitgen_i); + case ro_ctrl_state is + when idle => + if(continousread = '1' or readnow = '1' or + (triggering = '1' and trigger_ext = '1' and generatetriggeredhits = '0')) then + start_mupix_ro_i <= '1'; + ro_ctrl_state <= mupix_reading; + elsif((generatetriggeredhits = '1' and trigger_ext = '1') or + (generatehit = '1' or generatehits = '1')) then + start_hitgen_i <= '1'; + selecthitgen <= '1'; + ro_ctrl_state <= hitgen_running; + else + ro_ctrl_state <= idle; + end if; + when mupix_reading => + if ro_busy_vec = "10" then + ro_ctrl_state <= idle; + else + ro_ctrl_state <= mupix_reading; + end if; + when hitgen_running => + if ro_busy_vec = "10" then + ro_ctrl_state <= idle; + else + selecthitgen <= '1'; + ro_ctrl_state <= hitgen_running; + end if; + end case; + end if; + end if; + end process readout_ctrl; + ----------------------------------------------------------------------------- --MuPix 3/4/6 Readout Statemachine @@ -275,234 +329,270 @@ begin begin if rising_edge(clk) then if(rst = '1') then - state <= waiting; + ro_state <= idle; ld_pix_reg <= '0'; ld_col_reg <= '0'; rd_col_reg <= '0'; pulldown_reg <= '0'; - memwren <= '0'; - ro_busy_int <= '0'; - eventcounter <= (others => '0'); - testoutro <= (others => '0'); - endofevent <= '0'; + ro_busy_mupix_i <= '0'; + endofevent_mupix_i <= '0'; else - testoutro <= (others => '0'); - testoutro(31) <= mupixreadout.priout; - memwren <= '0'; - memdata <= (others => '0'); - endofevent <= '0'; - ro_busy_int <= '0'; + testoutro(0) <= mupixreadout.priout; + testoutro(5 downto 1) <= (others => '0'); + memwren_mupix_i <= '0'; + memdata_mupix_i <= (others => '0'); + endofevent_mupix_i <= '0'; + ro_busy_mupix_i <= '0'; + increase_eventcounter_mpx_i <= '0'; ld_pix_reg <= '0'; pulldown_reg <= '0'; ld_col_reg <= '0'; rd_col_reg <= '0'; - case state is + case ro_state is when pause => - pausecounter <= pausecounter + 1; + pausecounter <= pausecounter + 1; + ro_busy_mupix_i <= '1'; if(std_logic_vector(pausecounter) = pauseregister) then - state <= waiting; + ro_state <= idle; pausecounter <= (others => '0'); end if; - when waiting => + + when idle => testoutro(1) <= '1'; - delcounter <= (others => '0'); + ro_delcounter <= (others => '0'); hitcounter <= (others => '0'); - eventcounter <= eventcounter; - if(reseteventcount = '1') then - eventcounter <= (others => '0'); - end if; - if(readmanual = '1') then - state <= readman; - elsif(continousread = '1' or readnow = '1' or(triggering = '1' and trigger_ext = '1' and generatetriggeredhits = '0')) then - state <= loadpix; + if(start_mupix_ro_i = '1') then + ro_state <= loadpix; + ro_busy_mupix_i <= '1'; ld_pix_reg <= '1'; - delcounter <= unsigned(delaycounters1(7 downto 0)); - eventcounter <= eventcounter + 1; - elsif(generatetriggeredhits = '1' and trigger_ext = '1') then - state <= hitgenerator; - delcounter <= "00000100"; - eventcounter <= eventcounter + 1; - elsif(generatehit = '1' or generatehits = '1') then - state <= hitgenerator; - delcounter <= "00000100"; - eventcounter <= eventcounter + 1; + ro_delcounter <= unsigned(delaycounters1(7 downto 0)); + increase_eventcounter_mpx_i <= '1'; else - state <= waiting; + ro_state <= idle; end if; - when readman => - testoutro(9) <= '1'; - ro_busy_int <= '1'; - ld_pix_reg <= rocontrolbits(0); - pulldown_reg <= rocontrolbits(1); - ld_col_reg <= rocontrolbits(2); - rd_col_reg <= rocontrolbits(3); - if(readmanual = '1') then - state <= readman; - else - state <= waiting; - end if; when loadpix => - ro_busy_int <= '1'; + ro_busy_mupix_i <= '1'; testoutro(2) <= '1'; --data output - case delcounter is - when "00000010" => - memdata <= sensor_id; - memwren <= '1'; - when "00000001" => - memdata <= x"FABEABBA"; - memwren <= '1'; - when "00000000" => - memdata <= std_logic_vector(eventcounter); - memwren <= '1'; - when others => - memdata <= (others => '0'); - memwren <= '0'; + case ro_delcounter(7 downto 0) is + when "00000010" => + memdata_mupix_i <= sensor_id; + memwren_mupix_i <= '1'; + when "00000001" => + memdata_mupix_i <= x"FABEABBA"; + memwren_mupix_i <= '1'; + when "00000000" => + memdata_mupix_i <= std_logic_vector(eventcounter); + memwren_mupix_i <= '1'; + when others => + memdata_mupix_i <= (others => '0'); + memwren_mupix_i <= '0'; end case; --state machine - if(delcounter = "00000000") then - state <= pulld; + if(ro_delcounter = "00000000") then + ro_state <= pulld; pulldown_reg <= '1'; - delcounter <= unsigned(delaycounters1(15 downto 8)); + ro_delcounter <= unsigned(delaycounters1(15 downto 8)); else pulldown_reg <= '0'; - delcounter <= delcounter - 1; - state <= loadpix; + ro_delcounter <= ro_delcounter - 1; + ro_state <= loadpix; end if; when pulld => - ro_busy_int <= '1'; - testoutro(3) <= '1'; - delcounter <= delcounter - 1; - state <= pulld; - if(delcounter = "00000000") then - state <= loadcol; + ro_busy_mupix_i <= '1'; + testoutro(3) <= '1'; + ro_delcounter <= ro_delcounter - 1; + ro_state <= pulld; + if(ro_delcounter = "00000000") then + ro_state <= loadcol; ld_col_reg <= '1'; - delcounter <= unsigned(delaycounters1(23 downto 16)); + ro_delcounter <= unsigned(delaycounters1(23 downto 16)); end if; when loadcol => - ro_busy_int <= '1'; + ro_busy_mupix_i <= '1'; testoutro(4) <= '1'; - delcounter <= delcounter - 1; - state <= loadcol; - if(delcounter = "00000000") then + ro_delcounter <= ro_delcounter - 1; + ro_state <= loadcol; + if(ro_delcounter = "00000000") then if mupixreadout.priout = '1' then - state <= readcol; + ro_state <= readcol; rd_col_reg <= '1'; - delcounter <= unsigned(delaycounters1(31 downto 24)); + ro_delcounter <= unsigned(delaycounters1(31 downto 24)); else - memwren <= '1'; - memdata <= x"BEEFBEEF"; - endofevent <= '1'; - state <= pause; + memwren_mupix_i <= '1'; + memdata_mupix_i <= x"BEEFBEEF"; + endofevent_mupix_i <= '1'; + ro_state <= pause; end if; end if; when readcol => - ro_busy_int <= '1'; + ro_busy_mupix_i <= '1'; testoutro(5) <= '1'; - delcounter <= delcounter - 1; - state <= readcol; + ro_delcounter <= ro_delcounter - 1; + ro_state <= readcol; --issue read signal - if(delcounter > unsigned(delaycounters1(31 downto 24)) - unsigned(delaycounters2(15 downto 8))) then + if(ro_delcounter > unsigned(delaycounters1(31 downto 24)) - unsigned(delaycounters2(15 downto 8))) then rd_col_reg <= '1'; end if; --sample priout - if (std_logic_vector(delcounter) = delaycounters2(23 downto 16)) then + if (std_logic_vector(ro_delcounter) = delaycounters2(23 downto 16)) then priout_reg <= mupixreadout.priout; end if; --write hit information - if(std_logic_vector(delcounter) = delaycounters2(31 downto 24)) then - memdata <= x"F0F" & mupixreadout.hit_col & mupixreadout.hit_row & mupixreadout.hit_time; - memwren <= '1'; + if(std_logic_vector(ro_delcounter) = delaycounters2(31 downto 24)) then + memdata_mupix_i <= x"F0F" & mupixreadout.hit_col & mupixreadout.hit_row & mupixreadout.hit_time; + memwren_mupix_i <= '1'; hitcounter <= hitcounter + 1; - state <= readcol; - elsif(delcounter = "00000000") then + ro_state <= readcol; + elsif(ro_delcounter = "00000000") then if(hitcounter = unsigned(maxNumberHits(10 downto 0))) then -- maximal number of hits reaced -- force end of event - memwren <= '1'; - memdata <= x"BEEFBEEF"; --0xBEEFBEEF - endofevent <= '1'; - state <= pause; + memwren_mupix_i <= '1'; + memdata_mupix_i <= x"BEEFBEEF"; --0xBEEFBEEF + endofevent_mupix_i <= '1'; + ro_state <= pause; else if ( mupixreadout.priout = '1' or (delaycounters2(23 downto 16) /= "00000000" and priout_reg = '1')) then - state <= readcol; + ro_state <= readcol; rd_col_reg <= '1'; - delcounter <= unsigned(delaycounters1(31 downto 24)); + ro_delcounter <= unsigned(delaycounters1(31 downto 24)); else - state <= pulld; + ro_state <= pulld; pulldown_reg <= '1'; - delcounter <= unsigned(delaycounters2(7 downto 0)); + ro_delcounter <= unsigned(delaycounters2(7 downto 0)); end if; end if; - end if; - - when hitgenerator => - ro_busy_int <= '1'; - testoutro(6) <= '1'; - state <= hitgenerator; - delcounter <= delcounter - 1; - if(delcounter = "00000011") then -- write event header - state <= hitgenerator; - memdata <= sensor_id; - memwren <= '1'; - ngeneratehitscounter <= unsigned(ngeneratehits); - generatehitswaitcounter <= unsigned(generatehitswait); - gen_hit_col <= (others => '0'); - gen_hit_row <= (others => '0'); - elsif(delcounter = "00000010") then -- write event header - state <= hitgenerator; - memdata <= x"FABEABBA"; --0xFABEABBA - memwren <= '1'; - elsif(delcounter = "00000001") then -- write event counter - state <= hitgenerator; - memdata <= std_logic_vector(eventcounter); - memwren <= '1'; - elsif(delcounter = "00000000") then - if ngeneratehitscounter > "0000000000000000" then - state <= hitgenerator; - delcounter <= delcounter; - ngeneratehitscounter <= ngeneratehitscounter - 1; - gen_hit_col <= std_logic_vector(unsigned(gen_hit_col) + 5); - gen_hit_row <= std_logic_vector(unsigned(gen_hit_row) + 7); - if(gen_hit_row > "10000") then - gen_hit_row <= "000000"; - end if; - memdata <= x"F0F" & "0" & gen_hit_col(4 downto 0) & gen_hit_row & graycount; - memwren <= '1'; - else - if generatehits = '0' then - state <= waiting; - -- end of event - memwren <= '1'; - memdata <= x"BEEFBEEF"; - endofevent <= '1'; - else - state <= hitgeneratorwait; - -- end of event - memwren <= '1'; - memdata <= x"BEEFBEEF"; - endofevent <= '1'; - end if; - end if; - else - state <= hitgenerator; - end if; - - when hitgeneratorwait => - state <= hitgeneratorwait; - testoutro(7) <= '1'; - generatehitswaitcounter <= generatehitswaitcounter - 1; - if(to_integer(generatehitswaitcounter) = 0)then - state <= hitgenerator; - delcounter <= "00000100"; - eventcounter <= eventcounter + 1; - end if; + end if; end case; end if; end if; end process; + hitgen_statemachine : process (clk) is + begin + if rising_edge(clk) then + if rst = '1' then + hitgen_state <= idle; + else + memdata_hitgen_i <= (others => '0'); + memwren_hitgen_i <= '0'; + endofevent_hitgen_i <= '0'; + ro_busy_hitgen_i <= '0'; + increase_eventcounter_hitgen_i <= '0'; + testoutro(7 downto 6) <= (others => '0'); + case hitgen_state is + when idle => + hitgen_delcounter <= 2; + if(start_hitgen_i = '1') then + hitgen_state <= genheader; + increase_eventcounter_hitgen_i <= '1'; + ro_busy_hitgen_i <= '1'; + else + hitgen_state <= idle; + end if; + + when genheader => + testoutro(6) <= '1'; + hitgen_state <= genheader; + hitgen_delcounter <= hitgen_delcounter - 1; + ro_busy_hitgen_i <= '1'; + case hitgen_delcounter is + when 2 => --write event header + memdata_hitgen_i <= sensor_id; + memwren_hitgen_i <= '1'; + ngeneratehitscounter <= unsigned(ngeneratehits); + generatehitswaitcounter <= unsigned(generatehitswait); + gen_hit_col <= (others => '0'); + gen_hit_row <= (others => '0'); + when 1 => + memdata_hitgen_i <= x"FABEABBA"; + memwren_hitgen_i <= '1'; + when 0 => + memdata_hitgen_i <= std_logic_vector(eventcounter); + memwren_hitgen_i <= '1'; + hitgen_state <= genhits; + when others => + hitgen_state <= genheader; + end case; + + when genhits => --write event data + testoutro(7) <= '1'; + ro_busy_hitgen_i <= '1'; + if ngeneratehitscounter > "0000000000000000" then + hitgen_delcounter <= hitgen_delcounter; + ngeneratehitscounter <= ngeneratehitscounter - 1; + gen_hit_col <= std_logic_vector(unsigned(gen_hit_col) + 5); + gen_hit_row <= std_logic_vector(unsigned(gen_hit_row) + 7); + memdata_hitgen_i <= x"F0F" & "0" & gen_hit_col(4 downto 0) & gen_hit_row & graycount; + memwren_hitgen_i <= '1'; + if(gen_hit_row > "10000") then + gen_hit_row <= "000000"; + end if; + else + if generatehits = '0' then + hitgen_state <= idle; + -- end of event + memwren_hitgen_i <= '1'; + memdata_hitgen_i <= x"BEEFBEEF"; + endofevent_hitgen_i <= '1'; + else + hitgen_state <= hitgeneratorwait; + -- end of event + memwren_hitgen_i <= '1'; + memdata_hitgen_i <= x"BEEFBEEF"; + endofevent_hitgen_i <= '1'; + end if; + end if; + + when hitgeneratorwait => + hitgen_state <= hitgeneratorwait; + testoutro(8) <= '1'; + generatehitswaitcounter <= generatehitswaitcounter - 1; + ro_busy_hitgen_i <= '1'; + if(to_integer(generatehitswaitcounter) = 0)then + hitgen_state <= genheader; + hitgen_delcounter <= 2; + increase_eventcounter_hitgen_i <= '1'; + end if; + end case; + end if; + end if; + end process hitgen_statemachine; + + --increment event counter + event_counter : process (clk) is + begin + if rising_edge(clk) then + if rst = '1' then + eventcounter <= (others => '0'); + else + if reseteventcount = '1' then + eventcounter <= (others => '0'); + end if; + if increase_eventcounter_hitgen_i = '1' or increase_eventcounter_mpx_i = '1' then + eventcounter <= eventcounter + 1; + end if; + end if; + end if; + end process event_counter; + + --data multiplexing + data_mux : with selecthitgen select + memdata <= + memdata_hitgen_i when '1', + memdata_mupix_i when others; + + wren_mux : with selecthitgen select + memwren <= + memwren_hitgen_i when '1', + memwren_mupix_i when others; + + endofevent <= endofevent_hitgen_i or endofevent_mupix_i; + ro_busy <= ro_busy_mupix_i or ro_busy_hitgen_i; + + --timestamp generation tsgen : process(clk) begin if rising_edge(clk) then @@ -531,8 +621,6 @@ begin counter => graycount ); - - ro_busy <= ro_busy_int; mupixcontrol.ldpix <= ld_pix_reg; mupixcontrol.pulldown <= pulldown_reg; mupixcontrol.ldcol <= ld_col_reg; diff --git a/mupix/sources/TriggerHandler.vhd b/mupix/sources/TriggerHandler.vhd index 9de6ca1..dd260c5 100644 --- a/mupix/sources/TriggerHandler.vhd +++ b/mupix/sources/TriggerHandler.vhd @@ -110,9 +110,6 @@ architecture behavioral of TriggerHandler is status_trigger, write_data_to_eventbuffer, write_data_to_ipu, - wait_for_trg_data_valid_a, - wait_for_trg_data_valid_b, - wait_for_trg_data_valid_c, trigger_release_a, trigger_release_b, trigger_release_c, @@ -289,8 +286,6 @@ begin else trigger_handler_fsm <= idle; end if; - - when others => null; end case; end if; end process trigger_handler_proc;