реклама на сайте
подробности

 
 
> Взаимодействие с сигналом между процесами.
Jenya7
сообщение Jul 17 2017, 05:45
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



В одном процессе есть сигнал обнуляющий счетчик - count_rst.
Код
COUNTER : process(CLK)
begin
    if (rising_edge(CLK)) then

         if (count_rst = '1') then
            ir_counter <= (others => '0');
            ir_prescaler   <= (others => '0');
         end if;    
        
        if (count_ena = '1') then
            if (ir_prescaler = PRESCALE_VAL) then
                ir_prescaler   <= (others => '0');
                ir_counter <= not ir_counter;
               else
               ir_prescaler <= ir_prescaler + '1';
               end if;            
        end if;  
          
  end if;
end process COUNTER;

В другом процессе в некоторых состояниях я поднимаю этот сигнал и для того чтоб сигнал подержался пару клоков я делаю так
Код
IR_PARSE : process(CLK)
variable ticks : integer range 0 to 255 := 0;
variable bit_idx : integer range 0 to 255 := 0;
begin
    if (rising_edge(CLK)) then
        
        if (count_rst = '1') then
            ticks := ticks + 1;
            if (ticks > 1) then
                count_rst <= '0';
            ticks := 0;
           end if;
         end if;

     -----------------------------------
      --дальше идет State Machine    
     ------------------------------------

Насколько это правильно? Или так делать нельзя?

Сообщение отредактировал Jenya7 - Jul 17 2017, 05:48
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
KalashKS
сообщение Jul 17 2017, 12:37
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 236
Регистрация: 7-02-11
Пользователь №: 62 755



Так как вы используете ресет, он у вас не будет срабатывать если counter_ena='1'. Перепишите процесс в стиле
CODE
if count_rst='1' then
elsif count_ena='1' then
end if;

По генерации ресета есть вопрос, где он устанавливается в единицу. Если в процессе IR_PARSE, то в принципе работать будет, хотя мне не нравится такой стить написания.
Я бы для повышения читаемости прописал установку ресета там же, где он сбрасывается, например после else.
CODE
if count_rst='1' then
else
end if;

Переменные в таком стиле не применял, но так тоже должно синтезнуться.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 17 2017, 13:11
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(KalashKS @ Jul 17 2017, 18:37) *
Так как вы используете ресет, он у вас не будет срабатывать если counter_ena='1'. Перепишите процесс в стиле
CODE
if count_rst='1' then
elsif count_ena='1' then
end if;

понял. а если так
Код
    if (count_rst = '1') then
     ir_counter <= (others => '0');
      ir_prescaler   <= (others => '0');
    else    
      if (count_ena = '1') then
        if (ir_prescaler = PRESCALE_VAL) then
             ir_prescaler   <= (others => '0');
             --every 1us
             ir_counter <= ir_counter + '1';  
        else
            ir_prescaler <= ir_prescaler + '1';
             end if;
                    
         end if;  
    end if;

Цитата(KalashKS @ Jul 17 2017, 18:37) *
По генерации ресета есть вопрос, где он устанавливается в единицу. Если в процессе IR_PARSE, то в принципе работать будет, хотя мне не нравится такой стить написания.
Я бы для повышения читаемости прописал установку ресета там же, где он сбрасывается, например после else.
CODE
if count_rst='1' then
else
end if;

Переменные в таком стиле не применял, но так тоже должно синтезнуться.

весь процес такой
Код
IR_PARSE : process(CLK)
variable ticks : integer range 0 to 255 := 0;
variable bit_idx : integer range 0 to 255 := 0;
begin
    if (rising_edge(CLK)) then
        
         if (count_rst = '1') then
            ticks := ticks + 1;
             if (ticks > 1) then
                 count_rst <= '0';
             end if;
          end if;
          
          case IrState is
          
              when IR_ST_IDLE =>
                
                    ir_good  <= '0';
                    
                    count_ena <= '0';
                    
                    if (ir_rx3 = '0') then
                         bit_idx := 0;
                          count_rst <= '1';
                          count_ena <= '1';
                         IrState <= IR_ST_START;
                     end if;
                
              when IR_ST_START => --detect start header
                
                    if (ir_rx3 = '0') then
                          if (ir_counter > HEADER_MAX) then
                              IrState <= IR_ST_IDLE;
                          end if;
                     else --signal goes high
                       if (ir_counter < HEADER_MIN or ir_counter > HEADER_MAX) then --invalid header
                              IrState <= IR_ST_IDLE;
                          else --valid header 2400 us
                              count_rst <= '1';
                             IrState <= IR_ST_BITS;
                         end if;      
                     end if;
                    
                
                when IR_ST_BITS =>
                    if (bit_idx < MAX_BITS) then
                        if (ir_rx3 = '0') then
                                if (ir_counter > BIT_1_MAX) then
                                  IrState <= IR_ST_IDLE;
                                end if;        
                          else --signal goes high
                               if (ir_counter > BIT_0_MIN or ir_counter < BIT_0_MAX) then --logic 0 - 600us
                                    code(bit_idx) <= '0';
                                elsif (ir_counter > BIT_1_MIN or ir_counter < BIT_1_MAX) then --logic 1 - 1200us
                                    code(bit_idx) <= '1';
                                else  
                                   ir_good  <= '0';
                                   IrState <= IR_ST_IDLE;    
                              end if;    
                                count_rst <= '1';
                               bit_idx := bit_idx + 1;    
                          end if;
                     else
                         ir_good  <= '1';
                       IrState <= IR_ST_IDLE;            
                    end if;
                    
          end case;
          
     end if;
end process IR_PARSE;

проблема что сигнал рисета надо обнулять после 1-2 клока. поэтому я применил такой подход.
Go to the top of the page
 
+Quote Post
KalashKS
сообщение Jul 17 2017, 16:12
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 236
Регистрация: 7-02-11
Пользователь №: 62 755



Цитата(Jenya7 @ Jul 17 2017, 16:11) *
понял. а если так

Так, да. Только через elsif немного короче.

В следующем процессе (так как написано), должно заработать при обнулении переменной ticks одновременно с установкой count_rst. Кстати, у вас это обнуление вообще куда-то пропало. Хотя и это я это назвал бы костылем.
Если нужно продержать сброс в течение двух тактов, я бы на вашем месте выставлял count_rst на один такт, а дальше прощелкнул бы его в еще один регистр, например, так
CODE
count_rst_reg<=count_rst;
if (count_rst = '1' or count_rst_reg='1') then
ir_counter <= (others => '0');
ir_prescaler <= (others => '0');
elsif (count_ena = '1') then
if (ir_prescaler = PRESCALE_VAL) then
ir_prescaler <= (others => '0');
--every 1us
ir_counter <= ir_counter + '1';
else
ir_prescaler <= ir_prescaler + '1';
end if;
end if;

Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 18 2017, 06:31
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(KalashKS @ Jul 17 2017, 22:12) *
Так, да. Только через elsif немного короче.

В следующем процессе (так как написано), должно заработать при обнулении переменной ticks одновременно с установкой count_rst. Кстати, у вас это обнуление вообще куда-то пропало. Хотя и это я это назвал бы костылем.
Если нужно продержать сброс в течение двух тактов, я бы на вашем месте выставлял count_rst на один такт, а дальше прощелкнул бы его в еще один регистр, например, так
CODE
count_rst_reg<=count_rst;
if (count_rst = '1' or count_rst_reg='1') then
ir_counter <= (others => '0');
ir_prescaler <= (others => '0');
elsif (count_ena = '1') then
if (ir_prescaler = PRESCALE_VAL) then
ir_prescaler <= (others => '0');
--every 1us
ir_counter <= ir_counter + '1';
else
ir_prescaler <= ir_prescaler + '1';
end if;
end if;

тут в чем проблема. кто обнулит сигнал count_rst?
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 10:16
Рейтинг@Mail.ru


Страница сгенерированна за 0.01448 секунд с 7
ELECTRONIX ©2004-2016