- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
im trying to implement a counter which counts positive, negative, or both edges of an incoming signal. It works, but if I give 10000pulses to it it counts only between 9980...9997. The internal FPGA clk is 10MHz and the signal to count comes along with 1kHz and a ontime of 50usec. Here is the counter part: Detect_Edges : FOR i IN 1 TO nbr_of_Counters GENERATE PROCESS(Clk_I, reset_I, Enable_S, CntEdge_S, DIO_Stati_I, CountPort_S) VARIABLE was_on : boolean; VARIABLE cnt : integer; BEGIN IF reset_I = '1' THEN cnt := 0; was_on := TRUE; ELSIF rising_edge(clk_I) THEN IF ResetCounter_S(i) = '1' THEN cnt := 0; was_on := TRUE; ELSIF Set_Counter_S(i) = '1' THEN cnt := CONV_INTEGER(unsigned(CntSet_value_S)); ELSIF Enable_S(i) = '0' THEN NULL; ELSIF DIO_Stati_I(CountPort_S(i)) = '1' AND was_on = FALSE THEN was_on := TRUE; IF CntEdge_S(i) /= COUNT_ON_FALLING_EDGE THEN IF CntDir_S(i) = '1' THEN cnt := cnt + 1; ELSE cnt := cnt - 1; END IF; END IF; ELSIF DIO_Stati_I(CountPort_S(i)) = '0' AND was_on = TRUE THEN was_on := FALSE; IF CntEdge_S(i) /= COUNT_ON_RISING_EDGE THEN IF CntDir_S(i) = '1' THEN cnt := cnt + 1; ELSE cnt := cnt - 1; END IF; END IF; END IF; CntValues_S(i) <= CONV_STD_LOGIC_VECTOR(cnt,32); END IF; END PROCESS; END GENERATE; Has anyone an idea? If i count the pulses with an other counter the# is correctLink Copied
5 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your code is too nested and complicated...
the following idea of counting may help
signal count : signed(32 downto 0);
signal temp : signed(1 downto 0);
process(reset,clk)
begin
if reset = '1' then
in_signal_d <= '0';
temp <= "00";
count <= (others => '0');
elsif rising_edge(clk) then
in_signal_d <= in_signal; -- your incoming signal
if count_up = '1' then
temp <= "01"; -- +1
else
temp <= "11"; -- -1
end if;
if in_signal /= in_signal_d then -- either edge
count <= count + temp;
end if;
end if;
end process;
cnt <= std_logic_vector(count);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'd add to Kaz's reply by saying that I'd pass in_signal through two registers and not present the "raw" unsynchronised signal to any logic, in order to avoid metastability:
in_signal_d <= in_signal;
in_signal_dd <= in_signal_d;
and then: if in_signal_d /= in_signal_dd then
...
(I'd also probably separate the code out into two processes but that's just my personal preference).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes indeed, but I have assumed the signal is synchronised already
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
thanks for your fast response! The Signal which i want to count is asynchrounous! I'll test the process you wrote. Thanks, Patrick- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Now it works. The problem was the unsynchronised signal. When i register it, as batfink wrote there ar no more problems!
Thanks again
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page