From 6efa45520f58d72305b2dde1f08c7e609f239158 Mon Sep 17 00:00:00 2001 From: Andreas Neiser Date: Mon, 23 Feb 2015 09:10:05 +0100 Subject: [PATCH] Add busy logic to prevent race conditions --- ADC/source/adc_processor_cfd.vhd | 27 ++++++++++++++++++++++----- ADC/source/adc_processor_cfd_ch.vhd | 21 ++++++++++++++++++--- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/ADC/source/adc_processor_cfd.vhd b/ADC/source/adc_processor_cfd.vhd index 71396b2..2751d85 100644 --- a/ADC/source/adc_processor_cfd.vhd +++ b/ADC/source/adc_processor_cfd.vhd @@ -56,13 +56,15 @@ architecture arch of adc_processor_cfd is 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); @@ -71,6 +73,8 @@ begin 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; @@ -84,6 +88,8 @@ begin 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) ); @@ -115,6 +121,8 @@ begin RDO_data_main <= (others => '0'); RDO_write_main <= '0'; + busy_in_sys <= (others => '0'); + case state is when IDLE => READOUT_TX.statusbits <= (others => '0'); @@ -124,10 +132,8 @@ begin 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 => @@ -154,7 +160,16 @@ begin 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; @@ -164,6 +179,7 @@ begin channelselect := 0; else channelselect := channelselect + 1; + state <= WAIT_BSY; end if; else RDO_data_main <= ram_data_sys(channelselect); @@ -171,6 +187,7 @@ begin ram_counter(channelselect) <= ram_counter(channelselect) + 1; end if; + when SEND_STATUS => RDO_write_main <= '1'; RDO_data_main <= x"20000000"; diff --git a/ADC/source/adc_processor_cfd_ch.vhd b/ADC/source/adc_processor_cfd_ch.vhd index 4730097..7e274d1 100644 --- a/ADC/source/adc_processor_cfd_ch.vhd +++ b/ADC/source/adc_processor_cfd_ch.vhd @@ -20,6 +20,8 @@ entity adc_processor_cfd_ch is 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 ); @@ -90,7 +92,7 @@ architecture arch of adc_processor_cfd_ch is 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'); @@ -235,6 +237,8 @@ begin zeroX := '0'; end if; + RAM_BSY_OUT <= '0'; + case state is when IDLE => RAM_DATA <= (others => '0'); -- always write zeros as end marker @@ -249,14 +253,20 @@ begin 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)); @@ -265,29 +275,34 @@ begin -- 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; -- 2.43.0