How do you make vhdl counter that can count in tenths of a millisecond?

倖福魔咒の 提交于 2019-12-13 05:38:36

问题


I am working on an IR Decoder in VHDL and I know that the widths of an IR 1 bit is 1.2 ms, an IR 0 bit is 0.6 ms, and the start bit is 2.5 ms. I am trying to make a counter that takes in the 50MHz clock and converts to tenths of a millisecond. How can I do this?

entity counter is
    Port ( EN : in  STD_LOGIC;
           RESET : in  STD_LOGIC;
           CLK : in  STD_LOGIC;
           COUNT : out  STD_LOGIC_VECTOR (4 downto 0));
end counter;

architecture Behavioral of counter is

constant max_count : integer := (2);  
begin
   startCounter: process(EN, RESET, CLK)
      variable cnt : integer := 0;
      variable div_cnt : integer := 0;
   begin

      if (RESET = '1') then
         cnt := 0;
         div_cnt := 0;
      elsif (EN = '1' and rising_edge(CLK)) then
         if (cnt = max_count) then
            cnt := 0;
            div_cnt:= div_cnt + 1;
         else
            cnt := cnt + 1;
         end if;
      end if;
      COUNT <= conv_std_logic_vector(cnt, 5);
--      COUNT <= temp_count(16 downto 13);

   end process startCounter;
end Behavioral;

回答1:


Since you have a 50 MHz clock and want to generate a 0.1 msec pulse, you can use the ieee library, math_real, to compute the number of 50 MHz clocks to create a 0.1 msec pulse. Here's a code fragment.

library ieee;
use     ieee.math_real.all;

-- omitting for clarity...

-- generate one clk cycle pulse with period of 0.1 msec
gen_0p1mspulse_p : process(Clk)
    constant CLK_PERIOD     : real := 1/50e6;
    constant PULSE_PERIOD   : real := 0.1e-3;
    constant MAX_CNT        : integer := INTEGER(PULSE_PERIOD/CLK_PERIOD);
    variable cnt            : integer range 0 to MAX_CNT-1 := 0;
begin
    if rising_edge(Clk) then
        if reset = '1' then
            cnt := 0;
            pulse_0p1msec <= '0';            
        else
            pulse_0p1msec <= '0';  -- default value
            if cnt < MAX_CNT-1 then
                cnt := cnt + 1;
            else
                cnt := 0;
                pulse_0p1msec <= '1';
            end if;
        end if;
    end if;
end process;

-- logic using 0.1 msec pulse
your_logic_p : process(Clk)
begin
    if rising_edge(Clk) then
        if reset = '1' then
            your_cnt := 0;
        else
            if pulse_0p1msec = '1' then
                -- insert your logic here
            end if;
        end if;        
    end if;
end process;

I like to split up my VHDL processes so that they're short. I also prefer to use synchronous resets and enables since they synthesize to less hardware for Xilinx FPGAs as well as running at a higher clock rates. Hope that addresses your issue.



来源:https://stackoverflow.com/questions/29027688/how-do-you-make-vhdl-counter-that-can-count-in-tenths-of-a-millisecond

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!