jenya7 0 17 июля, 2017 Опубликовано 17 июля, 2017 (изменено) · Жалоба В одном процессе есть сигнал обнуляющий счетчик - 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 ------------------------------------ Насколько это правильно? Или так делать нельзя? Изменено 17 июля, 2017 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KalashKS 0 17 июля, 2017 Опубликовано 17 июля, 2017 · Жалоба Так как вы используете ресет, он у вас не будет срабатывать если counter_ena='1'. Перепишите процесс в стиле if count_rst='1' then elsif count_ena='1' then end if; По генерации ресета есть вопрос, где он устанавливается в единицу. Если в процессе IR_PARSE, то в принципе работать будет, хотя мне не нравится такой стить написания. Я бы для повышения читаемости прописал установку ресета там же, где он сбрасывается, например после else. if count_rst='1' then else end if; Переменные в таком стиле не применял, но так тоже должно синтезнуться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 17 июля, 2017 Опубликовано 17 июля, 2017 · Жалоба Так как вы используете ресет, он у вас не будет срабатывать если counter_ena='1'. Перепишите процесс в стиле 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; По генерации ресета есть вопрос, где он устанавливается в единицу. Если в процессе IR_PARSE, то в принципе работать будет, хотя мне не нравится такой стить написания. Я бы для повышения читаемости прописал установку ресета там же, где он сбрасывается, например после else. 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 клока. поэтому я применил такой подход. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KalashKS 0 17 июля, 2017 Опубликовано 17 июля, 2017 · Жалоба понял. а если так Так, да. Только через elsif немного короче. В следующем процессе (так как написано), должно заработать при обнулении переменной ticks одновременно с установкой count_rst. Кстати, у вас это обнуление вообще куда-то пропало. Хотя и это я это назвал бы костылем. Если нужно продержать сброс в течение двух тактов, я бы на вашем месте выставлял count_rst на один такт, а дальше прощелкнул бы его в еще один регистр, например, так 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; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flip-fl0p 4 17 июля, 2017 Опубликовано 17 июля, 2017 · Жалоба Я вообще предпочитаю задерживать сигналы в сдвиговом регистре. Такой способ самый понятный с точки зрения описания. Подключил сдвиговый регистр в проект, указал разрядность, и назвал его как-нибудь типа RESET_DELAY_SHREG.В итоге код становиться простым, понятным. Так-же разрядность регистра можно вынести в область GENERIC и очень гибко управлять временем задержки. Счётчик - хорошо когда надо много считать. А когда надо подождать несколько тактов как мне кажется сдвиговый регистр удобнее. Очень многое еще зависит от максимальной частоты. Были случаи, когда скорости счетчика просто не хватало для счета. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 18 июля, 2017 Опубликовано 18 июля, 2017 · Жалоба Так, да. Только через elsif немного короче. В следующем процессе (так как написано), должно заработать при обнулении переменной ticks одновременно с установкой count_rst. Кстати, у вас это обнуление вообще куда-то пропало. Хотя и это я это назвал бы костылем. Если нужно продержать сброс в течение двух тактов, я бы на вашем месте выставлял count_rst на один такт, а дальше прощелкнул бы его в еще один регистр, например, так 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? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 18 июля, 2017 Опубликовано 18 июля, 2017 · Жалоба Я вообще предпочитаю задерживать сигналы в сдвиговом регистре. Такой способ самый понятный с точки зрения описания. Подключил сдвиговый регистр в проект, указал разрядность, и назвал его как-нибудь типа RESET_DELAY_SHREG.В итоге код становиться простым, понятным. Так-же разрядность регистра можно вынести в область GENERIC и очень гибко управлять временем задержки. Счётчик - хорошо когда надо много считать. А когда надо подождать несколько тактов как мне кажется сдвиговый регистр удобнее. Очень многое еще зависит от максимальной частоты. Были случаи, когда скорости счетчика просто не хватало для счета. если здержка больше 64/128 тактов можно подумать про использование блочной памяти для заержки library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity delay_line is generic( W : integer := 8; -- data width L : integer := 1200); -- delay length, shall be > 3 port( i_clk : in std_logic; i_sync_reset : in std_logic; i_data : in std_logic_vector(W-1 downto 0); o_data : out std_logic_vector(W-1 downto 0)); end delay_line; architecture rtl of delay_line is type t_ram is array (L-2 downto 0) of std_logic_vector(W-1 downto 0); signal m_ram : t_ram; signal r_addr_wr : integer range 0 to L-2; signal r_addr_rd : integer range 0 to L-2; signal r_enable_read : std_logic; begin p_write : process (i_clk) begin if rising_edge(i_clk) then if(i_sync_reset='1') then r_addr_wr <= 0; r_enable_read <= '0'; else m_ram(r_addr_wr) <= i_data; if(r_addr_wr<L-2) then r_addr_wr <= r_addr_wr + 1; else r_addr_wr <= 0; r_enable_read <= '1'; -- enable reading section end if; end if; end if; end process p_write; p_read : process (i_clk) begin if rising_edge(i_clk) then if(i_sync_reset='1') then r_addr_rd <= 0; else if(r_enable_read='1') then o_data <= m_ram(r_addr_rd); -- additional delay if(r_addr_rd<L-2) then r_addr_rd <= r_addr_rd + 1; else r_addr_rd <= 0; end if; end if; end if; end if; end process p_read; end rtl; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KalashKS 0 18 июля, 2017 Опубликовано 18 июля, 2017 · Жалоба тут в чем проблема. кто обнулит сигнал count_rst? Тот же конечный автомат. Во всех ситуациях, когда его не нужно устанавливать в единицу - устанавливайте в ноль. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 18 июля, 2017 Опубликовано 18 июля, 2017 · Жалоба Тот же конечный автомат. Во всех ситуациях, когда его не нужно устанавливать в единицу - устанавливайте в ноль. понял. спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться