Jump to content

    

Просэмплировать по времени

У меня есть процесс который длиться 40 милисекунд.

Мне нужно прочитать ADC в 3, 6, 12, 15 милисекунд.

Конвертация ADC запускается сигналом TRIG а результат готов по сигналу READY.

process (CLK)
begin

    if (rising_edge(CLK)) then
	 
	     if (count_reset = '1') then
		      ticks_counter <= (others => '0');
				ms_counter <= (others => '0');
		  end if;
		  
        ticks_counter <= ticks_counter + '1';
        if (ticks_counter = TICKS_FOR_1MS) then
		      ticks_counter <= (others => '0');
		      ms_counter <= ms_counter + '1';
        end if;		  
	 end if;	  
end process;


CONTROL: process (CLK)
begin

    if (rising_edge(CLK)) then
	 
	      case ChargeState is
			
			    when ST_IDLE =>
					  --start
				     if (tuben_3 = '1') then
						  ChargeState <= ST_START;  
					  end if;
				 
				 when ST_START =>
				     count_reset <= '1';
					  ChargeState <= ST_SAMPLE;  
					  
				 when ST_SAMPLE =>
				     count_reset <= '0';
					  
				     case ms_counter is 
					      when X"03" =>  --3 ms
							    --TRIG <= '1';
								 --if (READY <= '1') then
							when X"06" =>  --6 ms
							
							when X"0С" =>  --12 ms
							
							when X"0F" =>  --15 ms
							
							when others =>
					  end case;
					  
					  --end
				     if (tuben_4 = '1') then
						  ChargeState <= ST_IDLE;  
					  end if;  
				     
			    when others => ChargeState <= ST_IDLE;
				 
			end case;
			
	 end if;

end process  CONTROL;

Вопрос как лучше организовать сэмплирование? В каждом кейсе запускать TRIG и ждать READY?

Или создать отдельный процесс и передавать туда сигнал TRIG?

Edited by jenya7

Share this post


Link to post
Share on other sites
15 minutes ago, jenya7 said:

В каждом кейсе запускать TRIG и ждать READY?

Переходить в последовательность состояний запуск TRIG - ожидание READY.

P.S. count_reset в коде работать не будет.

Share this post


Link to post
Share on other sites
2 minutes ago, aaarrr said:

Переходить в последовательность состояний запуск TRIG - ожидание READY.

отдельный кейс в том же процессе?

2 minutes ago, aaarrr said:

P.S. count_reset в коде работать не будет.

почему не будет? чего бы ему не работать. я уже делал рисет сигналов из одного процесса в другой.

Share this post


Link to post
Share on other sites
1 hour ago, jenya7 said:

отдельный кейс в том же процессе?

В том же, зачем плодить процессы? Только это не одно состояние, разумеется.

 

1 hour ago, jenya7 said:

чего бы ему не работать. я уже делал рисет сигналов из одного процесса в другой

А с процессами это никак не связано.

Share this post


Link to post
Share on other sites
16 minutes ago, aaarrr said:

В том же, зачем плодить процессы? Только это не одно состояние, разумеется.

 

А с процессами это никак не связано.

что же вы такой загадочный :) покажите как надо делать.

Edited by jenya7

Share this post


Link to post
Share on other sites
2 minutes ago, jenya7 said:

покажите как надо делать

У вас в коде последовательно производится два присвоения одной переменной. Вопрос: какое значение она примет в результате?

Share this post


Link to post
Share on other sites
20 minutes ago, aaarrr said:

У вас в коде последовательно производится два присвоения одной переменной. Вопрос: какое значение она примет в результате?

я выставляю count_reset на один такт. этого не достаточно для захвата в другом процессе?

Share this post


Link to post
Share on other sites
2 minutes ago, jenya7 said:

я выставляю count_reset на один такт. этого не достаточно для захвата в другом процессе?

Я же написал, что с процессами не связано.

 

if (count_reset = '1') then
    ticks_counter <= (others => '0');
    ms_counter <= (others => '0');
end if;
ticks_counter <= ticks_counter + '1';

Будет ли значение ticks_counter зависить от count_reset?

Share this post


Link to post
Share on other sites

аааа... верно. тогда так

process (CLK)
begin
   if (rising_edge(CLK)) then
       if (count_reset = '1') then
           ticks_counter <= (others => '0');
           ms_counter <= (others => '0');
       else
           ticks_counter <= ticks_counter + '1';
           if (ticks_counter = TICKS_FOR_1MS) then
                ticks_counter <= (others => '0');
                ms_counter <= ms_counter + '1';
            end if;
        end if;		  
    end if;	  
end process;

 

а сам процесс, так правильно?

CONTROL: process (CLK)
variable idx : integer := 0; 
begin

    if (rising_edge(CLK)) then
	 
        case ChargeState is
  
            when ST_IDLE =>
                --start
                if (tuben_3 = '1') then
                    ChargeState <= ST_START;  
                end if;
				 
            when ST_START =>
                count_reset <= '1';
                ChargeState <= ST_SAMPLE;  
					  
            when ST_SAMPLE =>
                count_reset <= '0';
					  
                idx := 0;
                ChargeState <= ST_TRIG; 
					  
                case ms_counter is 
                    when X"03" =>  --3 ms
                        ADC_VAL_3MS <= ADC_DATA;
                    when X"06" =>  --6 ms
                        ADC_VAL_6MS <= ADC_DATA;
                    when X"0C" =>  --12 ms
                        ADC_VAL_12MS <= ADC_DATA;
                    when X"0F" =>  --15 ms
                        ADC_VAL_15MS <= ADC_DATA;
                    when others =>
                end case;
					  
                --end
                if (tuben_4 = '1') then
                    ChargeState <= ST_IDLE;  
                end if;  
				     
                when ST_TRIG =>
                    TRIG <= '1';
                    if (READY = '1') then
                        TRIG <= '0'; 
                        ChargeState <= ST_SAMPLE;
                    end if;
					  
                when others => ChargeState <= ST_IDLE;
				 
        end case;
			
    end if;

end process  CONTROL;

 

Edited by jenya7

Share this post


Link to post
Share on other sites

вобщем чтоб синхронизироваться по времени выходит что то такое

 

ADC_CONTROL: process (CLK)
variable idx : integer := 0; 
begin

    if (rising_edge(CLK)) then
	 
	    case ChargeState is
			
		    when ST_IDLE =>
				--start
				if (tuben_3 = '1') then
				   ChargeState <= ST_START;  
				end if;
				 
			when ST_START =>
				 count_reset <= '1';
				 idx := 0;
				 ChargeState <= ST_SAMPLE;  
					  
			when ST_SAMPLE =>
			    count_reset <= '0';
					  
				case ms_counter is 
				    when X"03" =>  --3 ms
						if (idx = 0) then
						     ChargeState <= ST_TRIG; 
							 idx := 1;	   
						end if;
								 
					when X"06" =>  --6 ms
					    if (idx = 1) then
							idx := 2;
							ChargeState <= ST_TRIG; 	 
						end if;
								 
					when X"0C" =>  --12 ms
						if (idx = 2) then
							idx := 3;
							ChargeState <= ST_TRIG;    	 
						 end if;
								 
					when X"0F" =>  --15 ms
						if (idx = 3) then
							idx := 4;
							ChargeState <= ST_TRIG; 
						 end if;
								 
					when X"14" =>  --20 ms
							
					when others =>
			end case;
					  
			 --end
			 if (tuben_4 = '1') then
				 ChargeState <= ST_IDLE;  
			 end if;  
				     
			 when ST_TRIG =>
			     ADC_TRIG <= '1';
			     if (ADC_READY = '1') then
					conv_ready  <= '1'; 
					ADC_TRIG <= '0'; 
							
					case ms_counter is 
						when X"03" => ADC_VAL_3MS <= ADC_VAL_IN;
						when X"06" => ADC_VAL_6MS <= ADC_VAL_IN;
						when X"0C" => ADC_VAL_12MS <= ADC_VAL_IN;
						when X"0F" => ADC_VAL_15MS <= ADC_VAL_IN;
						when others =>
					end case;
							
					ChargeState <= ST_SAMPLE;
				 end if;
					  
		    when others => ChargeState <= ST_IDLE;
				 
	    end case;
			
    end if;

end process  ADC_CONTROL;

 

Share this post


Link to post
Share on other sites
20 minutes ago, aaarrr said:

Не будет работать.

ну давайте не томите. :)

 

 

Edited by jenya7

Share this post


Link to post
Share on other sites
1 hour ago, aaarrr said:

idx всегда будет равен 0.

ну никак.

 

st1.thumb.png.727fb49321bf18bdabb45a9b9c83c62f.png

после 3 мили тригер поднялся и индекс изменился.

Edited by jenya7

Share this post


Link to post
Share on other sites

Вот решение задачи в лоб (код не проверял, но суть думаю ясна)

    type state_type is 
    (
        idle,                                            
        st_3ms_read,                                     
        st_6ms_read,                                     
        st_12ms_read,                                    
        st_15ms_read                                     
    );
    signal press_state, next_state : state_type := idle;       -- Начальное состояние по умолчанию - состояние ожидания
    attribute syn_encoding : string;                          -- Атрибуты синтеза
    attribute syn_encoding of state_type : type is "safe";    -- Создать машину состояний, выходящую из ошибочных состояний

    signal counter_sload_ena  : std_logic := '0';                          
    signal counter_sload_data : unsigned(31 downto 0);                       
    signal counter            : unsigned(31 downto 0) := (others => '0'); 
	signal adc_3ms_valid      : std_logic := '0'; 
    signal adc_6ms_valid      : std_logic := '0'; 
    signal adc_12ms_valid     : std_logic := '0'; 
    signal adc_15ms_valid     : std_logic := '0'; 
begin

    --======================================================================
    -- Процесс переключения состояния автомата на следующее состояние
    --======================================================================
    next_state_proc : process(clk)
    begin  
        if(rising_edge(clk)) then
            press_state <= next_state;             -- иначе каждый такт меняем сосстояние автомата
        end if;
    end process;
    
    --=====================================================================================
    -- Процесс вычисления следующего состояния авмтомата
    --=====================================================================================
    next_state_logic : process(all)
    begin
		counter_sload_ena  <= '0';
		counter_sload_data <= (others => '-');
		adc_3ms_valid      <= '0';
		adc_6ms_valid      <= '0';
		adc_12ms_valid     <= '0';
		adc_15ms_valid     <= '0';
        case pres_state is                                                          
            --======================================================================
            when idle           =>                                              
                                        next_state <= idle;                         
										if (tuben_3 = '1') then
										    next_state         <= st_3ms_read;  
											counter_sload_ena  <= '1';               -- Разрешение загрузки в счетчик
											counter_sload_data <= TIME_3MS;          -- Значение счетчика для отсчета требуемого интервала
										end if;
            --======================================================================
            when st_3ms_read    =>                                              
                                        next_state <= st_3ms_read;      
										if (to_integer(counter) = 0) then 
											next_state         <= st_6ms_read;
											counter_sload_ena  <= '1';               -- Разрешение загрузки в счетчик
											counter_sload_data <= TIME_6MS;          -- Значение счетчика для отсчета требуемого интервала
											adc_3ms_valid      <= '1';               -- Валидность данных АЦП
										end if;
            --======================================================================
            when st_6ms_read    =>   
										next_state <= st_6ms_read;  
										if (to_integer(counter) = 0) then 
											next_state         <= st_12ms_read;
											counter_sload_ena  <= '1';
											counter_sload_data <= TIME_12MS;         -- Значение счетчика для отсчета требуемого интервала
											adc_6ms_valid      <= '1';
										end if;

            --======================================================================
            when st_12ms_read   =>   
									    next_state <= st_12ms_read;  
										if (to_integer(counter) = 0) then 
											next_state         <= st_15ms_read;
											counter_sload_ena  <= '1';
											counter_sload_data <= TIME_15MS;        
											adc_12ms_valid     <= '1';
										end if;
                                           
            --======================================================================
            when st_15ms_read   =>    
										next_state <= st_15ms_read;  
										if (to_integer(counter) = 0) then 
											next_state     <= idle;
											adc_15ms_valid <= '1';
										end if;
									

            --======================================================================
            when others        => next_state <= idle;;
        end case;
    end process;
	
	process(clk)
	begin
		if (rising_edge(clk)) then
			counter <= counter - '1';
			if (counter_sload_ena = '1') then
				counter <= counter_sload_data;
			end if
		end if;
	end process;

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this