|
Взаимодействие с сигналом между процесами. |
|
|
|
Jul 17 2017, 05:45
|
Профессионал
    
Группа: Участник
Сообщений: 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
|
|
|
|
|
 |
Ответов
|
Jul 17 2017, 12:37
|
Местный
  
Группа: Участник
Сообщений: 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;
Переменные в таком стиле не применял, но так тоже должно синтезнуться.
|
|
|
|
|
Jul 17 2017, 13:11
|
Профессионал
    
Группа: Участник
Сообщений: 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 клока. поэтому я применил такой подход.
|
|
|
|
|
Jul 17 2017, 16:12
|
Местный
  
Группа: Участник
Сообщений: 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;
|
|
|
|
|
Jul 18 2017, 06:31
|
Профессионал
    
Группа: Участник
Сообщений: 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?
|
|
|
|
|
Jul 18 2017, 08:41
|
Местный
  
Группа: Участник
Сообщений: 236
Регистрация: 7-02-11
Пользователь №: 62 755

|
Цитата(Jenya7 @ Jul 18 2017, 09:31)  тут в чем проблема. кто обнулит сигнал count_rst? Тот же конечный автомат. Во всех ситуациях, когда его не нужно устанавливать в единицу - устанавливайте в ноль.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|