![]() |
|
|
|
#1 |
|
Hello, what i need is a counter that counts from a preset value down to 0 with a clock outside of the system clock domain. The counter run on a Cyclone III, 15 out of 16 of the counters work well, but one counts much too slow. Here is the relevant part of the code: -- transfer clock domain, fcntnext is in the system clockdomain cntrclk: process (clk, rst) begin if (rst = '1') then fcntnext <= '0'; fcnttoggle <= '0'; elsif falling_edge(clk) then fcntnext <= '0'; if fcnttoggle /= fcounter then fcnttoggle <= fcnttoggle xor '1'; if fcnttoggle = '1' then fcntnext <= '1'; end if; end if; end if; end process cntrclk; delaycounter: process (clk, rst) begin if (rst = '1') then dcntFin <= '0'; dcounter <= (others => '0'); elsif rising_edge(clk) then if cntr_reload = '1' then dcntFin <= '0'; -- Load counter with previous stored value dcounter <= dcounterLoadVal; elsif dcounter = std_logic_vector(to_unsigned(0, dcounter_bits)) then dcntFin <= '1'; elsif fcntnext = '1' then dcounter <= std_logic_vector(unsigned(dcounter) - 1); end if; end if; end process delaycounter; all signals are std_logic, and dcounter, dcounterLoadVal are std_logic_vector. The FPGA runs with a system clock (clk) of 100 MHz. The fcntnext signal is one clock cycle high (from falling_edge to falling_edge) after every rising clock edge of the fcounter clock. The fcounter clock is much slower than the system clock (max 1 MHz with a Duty-Cycle of 50%). Has anyone advices? Best regards, Steffen Steffen Koepf |
|
|
|
|
#2 |
|
Posts: n/a
|
Steffen Koepf wrote:
> what i need is a counter that counts from a preset value down to 0 > with a clock outside of the system clock domain. A clock outside of the system clock domain must be used as in input and synchronized to the system clock. -- Mike Treseler Mike Treseler |
|
|
|
#3 |
|
Posts: n/a
|
Hello Steffen,
> what i need is a counter that counts from a preset value down to 0 > with a clock outside of the system clock domain. The counter run > on a Cyclone III, 15 out of 16 of the counters work well, but one > counts much too slow. Here is the relevant part of the code: Please don't use both flanks of a clock, and properly transfer signals from one clock domain to the next before using them or you will run into timing and/or meta-stability issues. As an example (I hope I understood your code correctly, and I don't use asynchronous resets): delaycounter: PROCESS IS BEGIN WAIT UNTIL clk = '1'; fcounter_c2c <= fcounter; fcounter_meta <= fcounter_c2c; fcounter_d <= fcounter_meta; IF cntr_reload = '1' THEN dcntFin <= '0'; dcounter <= dcounterLoadVal; ELSIF unsigned( dcounter ) = 0 THEN dcntFin <= '1'; ELSIF fcounter_meta = '1' AND fcounter_d <= '0' THEN -- rising edge fcounter dcounter <= std_logic_vector( unsigned( dcounter ) - 1 ); END IF; IF rst = '1' THEN dcntFin <= '0'; dcounter <= (OTHERS => '0'); END IF; END PROCESS delaycounter; Keep in mind that since cntr_reload is not synchronized with regards to fcounter, your counter is never completely accurate. Also, are you sure you want the reset value of dcntFin to be 0 in stead of 1? What is that signal used for anyway? Kind regards, Pieter Hulshoff Pieter Hulshoff |
|
|
|
#4 |
|
Posts: n/a
|
Hello Pieter,
Pieter Hulshoff <> wrote: > Please don't use both flanks of a clock, Why should one not use this? I know falling edges are not supported on some devices, but when it is supported? > clock domain to the next before using them or you will run into timing and/or > meta-stability issues. As an example (I hope I understood your code correctly, > and I don't use asynchronous resets): In the mean time i improved my code a bit and added a rising-edge synchronizer: -- transfer clock domain, fcntnext is in the system clockdomain cntrclk: process (clk, rst) begin if (rst = '1') then clksyncstage1 <= '0'; clksyncstage2 <= '0'; edgedetectff <= '0'; elsif falling_edge(clk) then clksyncstage1 <= fcounter; clksyncstage2 <= clksyncstage1; edgedetectff <= clksyncstage2; end if; end process cntrclk; cntrclkedge: process (clksyncstage2, edgedetectff) begin fcntnext <= clksyncstage2 and (not edgedetectff); end process cntrclkedge; That solved my problem and the counter works fine now: delaycounter: process (clk, rst) begin if (rst = '1') then dcntFin <= '0'; dcounter <= (others => '0'); elsif rising_edge(clk) then if cntr_reload = '1' then dcntFin <= '0'; dcounter <= dcounterLoadVal; -- Load counter with previous stored val elsif dcounter = std_logic_vector(to_unsigned(0, dcounter_bits)) then dcntFin <= '1'; elsif fcntnext = '1' then dcounter <= std_logic_vector(unsigned(dcounter) - 1); end if; end if; end process delaycounter; Your code should do the same, thank you. > Keep in mind that since cntr_reload is not synchronized with regards to > fcounter, your counter is never completely accurate. Also, are you sure you want > the reset value of dcntFin to be 0 in stead of 1? What is that signal used for > anyway? The signal dcntFin is used as input for a gate for error-signals (from an analogous comparator outside of the fpga). After a enable signal is released, the counter starts to run. As long as enable is low (then cntr_reload = 1) or the counter is running for a certain time after enable switched to 1, the error-signals are "blanked out" so that a overshoot of switching power supplies after switching on (by enable) does not trigger an error. The counter is a 16 bit counter and it is not important if one or two clocks are not counted/wrong counted. Thank you, Steffen Koepf Steffen Koepf |
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Re: Pioneer DVR-105 and Nero Problems | grams@oldtown.com | DVD Video | 1 | 08-12-2003 04:17 AM |
| Re: Pioneer DVR-105 and Nero Problems | Ron | DVD Video | 1 | 08-08-2003 06:33 PM |
| Re: Pioneer DVR-105 and Nero Problems | Flossie | DVD Video | 0 | 08-07-2003 02:25 PM |
| Re: Pioneer DVR-105 and Nero Problems | Flossie | DVD Video | 0 | 08-07-2003 08:11 AM |
| Re: Pioneer DVR-105 and Nero Problems | CAM | DVD Video | 0 | 08-07-2003 02:30 AM |