signal ram_counter : ram_counter_t := (others => (others => '0'));
--signal ram_we_adc : std_logic_vector(CHANNELS - 1 downto 0) := (others => '0');
- type state_t is (IDLE, DO_RELEASE, RELEASE_DIRECT, WAIT_FOR_END, CHECK_STATUS_TRIGGER, SEND_STATUS, CFD_READOUT);
+ type state_t is (IDLE, DO_RELEASE, RELEASE_DIRECT, WAIT_FOR_END, CHECK_STATUS_TRIGGER, SEND_STATUS, CFD_READOUT, WAIT_BSY);
signal state : state_t;
signal statebits : std_logic_vector(7 downto 0);
signal RDO_data_main : std_logic_vector(31 downto 0) := (others => '0');
signal RDO_write_main : std_logic := '0';
signal readout_reset : std_logic := '0';
+ signal busy_in_adc, busy_in_sys : std_logic_vector(CHANNELS-1 downto 0) := (others => '0');
+ signal busy_out_adc, busy_out_sys : std_logic_vector(CHANNELS-1 downto 0) := (others => '0');
begin
CONF_adc <= CONFIG when rising_edge(CLK_ADC);
CONF_sys <= CONFIG when rising_edge(CLK_SYS);
TRIGGER_OUT <= or_all(trigger_gen and trigger_mask) when rising_edge(CLK_SYS);
debug_sys <= debug_adc when rising_edge(CLK_SYS);
+ busy_in_adc <= busy_in_sys when rising_edge(CLK_ADC);
+ busy_out_sys <= busy_out_adc when rising_edge(CLK_SYS);
gen_cfd : for i in 0 to CHANNELS - 1 generate
trigger_gen(i) <= debug_sys(i).Trigger;
CONF => CONF_adc,
RAM_ADDR => ram_addr_adc(i),
RAM_DATA => ram_data_adc(i),
+ RAM_BSY_IN => busy_in_adc(i),
+ RAM_BSY_OUT => busy_out_adc(i),
DEBUG => debug_adc(i)
);
RDO_data_main <= (others => '0');
RDO_write_main <= '0';
+ busy_in_sys <= (others => '0');
+
case state is
when IDLE =>
READOUT_TX.statusbits <= (others => '0');
READOUT_TX.statusbits <= (23 => '1', others => '0'); --event not found
state <= RELEASE_DIRECT;
elsif READOUT_RX.valid_timing_trg = '1' then
- state <= CFD_READOUT;
- -- if there's already new data present,
- -- start moving the counter already now
- ram_counter(channelselect) <= ram_counter(channelselect) + 1;
+ state <= WAIT_BSY;
+ busy_in_sys(channelselect) <= '1';
end if;
when RELEASE_DIRECT =>
end if;
end if;
+ when WAIT_BSY =>
+ busy_in_sys(channelselect) <= '1';
+ if busy_out_sys(channelselect) = '0' then
+ -- start moving the counter already now
+ ram_counter(channelselect) <= ram_counter(channelselect) + 1;
+ state <= CFD_READOUT;
+ end if;
+
when CFD_READOUT =>
+ busy_in_sys(channelselect) <= '1';
if ram_data_sys(channelselect) = x"00000000" then
-- for old channel, decrease count since we found the end
ram_counter(channelselect) <= ram_counter(channelselect) - 1;
channelselect := 0;
else
channelselect := channelselect + 1;
+ state <= WAIT_BSY;
end if;
else
RDO_data_main <= ram_data_sys(channelselect);
ram_counter(channelselect) <= ram_counter(channelselect) + 1;
end if;
+
when SEND_STATUS =>
RDO_write_main <= '1';
RDO_data_main <= x"20000000";
RAM_ADDR : out std_logic_vector(8 downto 0);
RAM_DATA : out std_logic_vector(31 downto 0);
+ RAM_BSY_IN : in std_logic;
+ RAM_BSY_OUT : out std_logic;
DEBUG : out debug_cfd_t
);
signal integral_sum : signed(RESOLUTION_CFD - 1 downto 0) := (others => '0');
signal epoch_counter, epoch_counter_save : unsigned(23 downto 0) := (others => '0');
- type state_t is (IDLE, INTEGRATE, WRITE1, WRITE2, WRITE3, WRITE4, FINISH);
+ type state_t is (IDLE, INTEGRATE, WRITE1, WRITE2, WRITE3, WRITE4, FINISH, WAIT_BSY);
signal state : state_t := IDLE;
signal ram_counter : unsigned(8 downto 0) := (others => '0');
zeroX := '0';
end if;
+ RAM_BSY_OUT <= '0';
+
case state is
when IDLE =>
RAM_DATA <= (others => '0'); -- always write zeros as end marker
when INTEGRATE =>
if integral_counter = 0 then
- state <= WRITE1;
+ state <= WAIT_BSY;
else
integral_sum <= integral_sum + resize(delay_integral_out, RESOLUTION_CFD);
integral_counter := integral_counter - 1;
end if;
+
+ when WAIT_BSY =>
+ if RAM_BSY_IN = '0' then
+ state <= WRITE1;
+ RAM_BSY_OUT <= '1';
+ end if;
- when WRITE1 =>
+ when WRITE1 =>
RAM_DATA(31 downto 24) <= x"c0";
RAM_DATA(23 downto 20) <= std_logic_vector(to_unsigned(DEVICE, 4));
RAM_DATA(19 downto 16) <= std_logic_vector(to_unsigned(CHANNEL, 4));
-- assume that ram_counter is already at next position
-- ram_counter <= ram_counter + 1;
state <= WRITE2;
+ RAM_BSY_OUT <= '1';
when WRITE2 =>
RAM_DATA(31 downto 16) <= std_logic_vector(epoch_counter_save(15 downto 0));
RAM_DATA(15 downto 0) <= std_logic_vector(integral_sum);
ram_counter <= ram_counter + 1;
state <= WRITE3;
+ RAM_BSY_OUT <= '1';
when WRITE3 =>
RAM_DATA(31 downto 16) <= std_logic_vector(cfd_prev_save);
RAM_DATA(15 downto 0) <= std_logic_vector(cfd_save);
ram_counter <= ram_counter + 1;
state <= WRITE4;
+ RAM_BSY_OUT <= '1';
when WRITE4 =>
RAM_DATA <= (others => '1'); -- padding word
ram_counter <= ram_counter + 1;
state <= FINISH;
+ RAM_BSY_OUT <= '1';
when FINISH =>
-- move to next position
ram_counter <= ram_counter + 1;
state <= IDLE;
+ RAM_BSY_OUT <= '1';
end case;