counter - Count Edges over specific Period of Time in VHDL -


for speedmeasurement of electric motor count amount of rising , falling edges of encoder-input in time-intervall of 10ms.

to have implementet clock divider 40 mhz clock follows:

entity speedclk port ( clk          : in  std_logic;        clkspeed     : out  std_logic); end speedclk; architecture behavioral of speedclk signal counterclk   : natural range 0 400001; begin  speedcounter : process begin wait until rising_edge(clk); counterclk <= counterclk + 1; if counterclk < 400000     clkspeed        <= '0'; else     clkspeed        <= '1';     counterclk      <= 0; end if; end process speedcounter;  end behavioral; 

this should make clkspeed '1' every 10 ms. use block component in toplevel vhdl-module. in next block count edges encoderinput(qepa) shift register debounce input signal.

entity speedmeasure port (     qepa        :   in      std_logic;     clk     :   in      std_logic;     clkspeed    :   in      std_logic;     speed       :   out integer -- in rpm     ); end speedmeasure;  architecture behavioral of speedmeasure  begin edges : process(clkspeed, clk)  variable detect     : std_logic_vector(5 downto 0) := "000000"; variable    edgespertime    : integer := 0; variable    countqepa       : integer := 0;  begin if clkspeed = '1'     edgespertime := countqepa;     countqepa := 0; elsif (clk'event , clk = '1')     detect(5 downto 1) := detect(4 downto 0);     detect(0) := qepa; if (detect = "011111") or (detect = "100000")  countqepa := countqepa + 1;     else         countqepa := countqepa;     end if; end if;  speed <= edgespertime; end process edges; 

end behavioral;

this should write current value of countqepa in variable edgespertime every 10 ms , reset counter afterwards. signal speed gets transmitted via uart. unfortunatly reset of countqepa every 10ms receive constant value of 0 edgespertime. if remove reset line in code, can receive increasing value edgespertime until largest number integer (2^16) reached, @ point counter resets 0.

what correct implementation in vhdl count rising , falling edges in set period of time?

any apreciated still new vhdl.

you're building latch using variable. synthesis tool inferred asynchronous reset clkspeed countqepa , since latch edgespertime latches countqepa when write enable clkspeed asserted, see reset countqepa value of 0.

you should build proper synchronous logic:

signal countqepa : integer                      := 0; signal detect    : std_logic_vector(5 downto 0) := (others => '0'); begin  edge_cnt_p : process (     clk     ) begin      if (rising_edge(clk))          -- synchronous reset         if (clkspeed = '1')              countqepa <= 0;          elsif ((detect = "011111") or (detect = "100000"))              countqepa <= countqepa + 1;          end if;      end if;  end process edge_cnt_p;  edge_debounce_p : process (     clk     ) begin      if (rising_edge(clk))          detect <= detect(detect'left downto 1) & qepa;      end if;  end process edge_debounce_p;  count_register_p : process (     clk     ) begin      if (rising_edge(clk))          -- synchronous write enable         if (clkspeed = '1')              speed <= countqepa;          end if;      end if;  end process count_register_p; 

i'm not big fan of variables, seems synthesis tools got lot smarter these days. can see, made 3 separate processes show want going on. countqepa , debounce signals now, because need readable other processes.

i assume clkspeed synchronous clk (40 mhz). if isn't, should think handshaking between clock domains.

you can of course make single process out of these individual processes. in general, try avoid variables, because can used describe behavior not synthesizable, found out hard way.


i'm not sure how long encoder bounces, if sample @ 40 mhz, 6 bit shift register not work that's 125 ns debounce (you use lower 5 bits debouncing, top bit noticing state changes).

speaking of debouncer. consider following case:

debounce qepa  111111   1  111111   0 <-- glitch/bounce on encoder line; 25 ns wide  111110   1  111101   1  111011   1  110111   1  101111   1  011111   1 <-- fake edge detected 

that's not want. should compare debounced signal last stable state instead of assuming state'delayed(5 * clk_period) being stable state.


as said above, i'm assuming clk 40 mhz clock. needn't sample encoder signal fast, because proper debouncer take large number of shift register bits @ no added value you, because have divide clock down 1 khz anyway time-slot counting.

instead, take account maximum frequency of encoder signal. want oversample @ least double frequency, quadruple frequency safe. have 4 samples per "bit time".

since you're expecting many edges @ 1 khz, assume encoder @ least 2 orders of magnitude fast, i.e. 100 khz. scale 40 mhz down 400 khz , shift in qepa debouncing. sample these 400 khz down 1 khz time slot measurements.


on side note: kind of motor encoding uses single bit? sure you're not dealing quadrature encoder?


Comments

Popular posts from this blog

Magento/PHP - Get phones on all members in a customer group -

php - .htaccess mod_rewrite for dynamic url which has domain names -

Website Login Issue developed in magento -