]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
Add busy logic to prevent race conditions
authorAndreas Neiser <neiser@kph.uni-mainz.de>
Mon, 23 Feb 2015 08:10:05 +0000 (09:10 +0100)
committerAndreas Neiser <neiser@kph.uni-mainz.de>
Sat, 13 Jun 2015 15:36:58 +0000 (17:36 +0200)
ADC/source/adc_processor_cfd.vhd
ADC/source/adc_processor_cfd_ch.vhd

index 71396b2a31368f52043febdf4ba8738effb68dcb..2751d857fdab724088394ecf2bc55d983ed7b9e2 100644 (file)
@@ -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";
index 4730097760d5832e6d0fb766861e3370b76ace97..7e274d1ff5dc5b2263ae925acdb273eb9ba5b3ea 100644 (file)
@@ -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;