![]() |
|
|
|
#1 |
|
Hi,
following entity should divide a 50 MHz clock into 8khz, 2Hz and 1 Hz. In principle it would work, but 2 Hz clock is 1 Hz and the duty cycle ist about 30/70. If I check Q23 is OK but Q24 and Q25 not. In RTL view the implementation of Q24 and Q25 looks a little bit strange. Did anyone know how the design ist not working well? Thanks Volker Code: -- DIV_COUNTER is a VHDL Design -- -- Author: V.Meiss -- -- Version 1.0 from 13.08.2008 -- Altera QuartusII 8.0 SP1 library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; entity DIV_COUNTER is port(CLK : in STD_LOGIC; CLK1, CLK2, CLK8k : out STD_LOGIC); end DIV_COUNTER; architecture BEHAVIOR of DIV_COUNTER is signal Q : std_logic_vector(25 downto 0); signal LOAD : STD_LOGIC; begin process(CLK, LOAD) constant PRESET : NATURAL :=50000000; -- input 50 MHz begin if (LOAD = '0') then Q <= CONV_STD_LOGIC_VECTOR(PRESET, 26); LOAD <= '1'; elsif (CLK'EVENT and CLK='1') then Q <= Q - 1; end if; if (Q = "00000000000000000000000000") then LOAD <= '0'; end if; CLK1 <= Q(25); -- 1HZ CLK CLK2 <= Q(24); -- 2HZ CLK CLK8k <= Q(12);-- 8 kHZ CLK end process; end BEHAVIOR; Volker |
|
|
|
|
#2 |
|
Posts: n/a
|
Volker wrote:
> In principle it would work, but 2 Hz clock is 1 Hz and the duty cycle > ist about 30/70. If I check Q23 is OK but Q24 and Q25 not. In RTL view > the implementation of Q24 and Q25 looks a little bit strange. Did > anyone know how the design ist not working well? In principle, it *won't* work as you hope. The '1Hz' clock has 30/70 duty cycle because (2^25)/50e6 is about 70%. IMHO don't feed back an async preset from the process logic, just preset the counter explicitly. And your 1Hz clock should be asserted whenever Q reaches a certain (any) value. The other clocks don't divide nicely into 50e6 so you can't really do what you're trying to do. I'd probably derive an 8KHz clock enable and use that to increment a counter that you can derive the 1Hz and 2Hz clock enables from... you're not clocking logic with these clocks, are you!?! Regards, -- Mark McDougall, Engineer Virtual Logic Pty Ltd, <http://www.vl.com.au> 21-25 King St, Rockdale, 2216 Ph: +612-9599-3255 Fax: +612-9599-3266 Mark McDougall |
|
|
|
#3 |
|
Posts: n/a
|
On 1 Aralýk, 06:15, "Volker" <jr...@gmx.de> wrote:
> Hi, > > following entity should divide a 50 MHz clock into 8khz, 2Hz and 1 Hz. In > principle it would work, but 2 Hz clock is 1 Hz and the duty cycle ist about > 30/70. If I check Q23 is OK but Q24 and Q25 not. In RTL view the > implementation of Q24 and Q25 looks a little bit strange. Did anyone know > how the design ist not working well? > > Thanks > Volker > > Code: > -- DIV_COUNTER is a VHDL Design > -- > -- Author: V.Meiss > -- > -- Version 1.0 from 13.08.2008 > -- Altera QuartusII 8.0 SP1 > > library IEEE; > use IEEE.STD_LOGIC_1164.all; > use IEEE.STD_LOGIC_ARITH.all; > use IEEE.STD_LOGIC_UNSIGNED.all; > > entity DIV_COUNTER is > * * *port(CLK * : in STD_LOGIC; > * * * * * *CLK1, CLK2, CLK8k : out STD_LOGIC); > end DIV_COUNTER; > > architecture BEHAVIOR of DIV_COUNTER is > * * *signal Q *: std_logic_vector(25 downto 0); > * * *signal LOAD *: STD_LOGIC; > begin > > *process(CLK, LOAD) > * * * constant PRESET : NATURAL :=50000000; -- input 50 MHz > *begin > * * * if (LOAD = '0') then > * * * * * *Q <= CONV_STD_LOGIC_VECTOR(PRESET, 26); > * * * * * *LOAD <= '1'; > * * * elsif (CLK'EVENT and CLK='1') then > * * * *Q <= Q - 1; > * * * *end if; > > * * * if (Q = "00000000000000000000000000") then > * * * *LOAD <= '0'; > * * * end if; > > * * * CLK1 <= Q(25); -- 1HZ CLK > * * * CLK2 <= Q(24); -- 2HZ CLK > * * * CLK8k <= Q(12);-- 8 kHZ CLK > *end process; > > end BEHAVIOR; The duty cycle of 1 Hz is about 164/500 how did I calculate this? Try to write a code which counts a less number. The problem is that 50_000_000 is something like 1011111010.. so when you say that Q(25) is a 1 Hz signal you will get a wrong result. the same applies for others too (also for 8 khz) If I were you I would create an enable signal to create a 8 Khz signal and using this enable signal I would create the clock signals for 1 Hz and 2 Hz signals by the help of another counter. Good luck. Enes Erdin |
|
|
|
#4 |
|
Posts: n/a
|
On 1 Aralýk, 06:51, Mark McDougall <ma...@vl.com.au> wrote:
> > The '1Hz' clock has 30/70 duty cycle because (2^25)/50e6 is about 70%. > That's better Enes Erdin |
|
|
|
#5 |
|
Posts: n/a
|
On 1 Dec, 14:15, "Volker" <jr...@gmx.de> wrote:
> Hi, > > following entity should divide a 50 MHz clock into 8khz, 2Hz and 1 Hz. In > principle it would work, but 2 Hz clock is 1 Hz and the duty cycle ist about > 30/70. If I check Q23 is OK but Q24 and Q25 not. In RTL view the > implementation of Q24 and Q25 looks a little bit strange. Did anyone know > how the design ist not working well? > > Thanks > Volker > > Code: > -- DIV_COUNTER is a VHDL Design > -- > -- Author: V.Meiss > -- > -- Version 1.0 from 13.08.2008 > -- Altera QuartusII 8.0 SP1 > > library IEEE; > use IEEE.STD_LOGIC_1164.all; > use IEEE.STD_LOGIC_ARITH.all; > use IEEE.STD_LOGIC_UNSIGNED.all; > > entity DIV_COUNTER is > * * *port(CLK * : in STD_LOGIC; > * * * * * *CLK1, CLK2, CLK8k : out STD_LOGIC); > end DIV_COUNTER; > > architecture BEHAVIOR of DIV_COUNTER is > * * *signal Q *: std_logic_vector(25 downto 0); > * * *signal LOAD *: STD_LOGIC; > begin > > *process(CLK, LOAD) > * * * constant PRESET : NATURAL :=50000000; -- input 50 MHz > *begin > * * * if (LOAD = '0') then > * * * * * *Q <= CONV_STD_LOGIC_VECTOR(PRESET, 26); > * * * * * *LOAD <= '1'; > * * * elsif (CLK'EVENT and CLK='1') then > * * * *Q <= Q - 1; > * * * *end if; > > * * * if (Q = "00000000000000000000000000") then > * * * *LOAD <= '0'; > * * * end if; > > * * * CLK1 <= Q(25); -- 1HZ CLK > * * * CLK2 <= Q(24); -- 2HZ CLK > * * * CLK8k <= Q(12);-- 8 kHZ CLK > *end process; > > end BEHAVIOR; If you are using individual bits from a counter for your output clocks (as you are) you can only get a nice 50/50 mark space ratio on clocks outputs that are 1/2^n speeds. Using an asyncronous reset will just skew the duty cycle as you have seen. So as you have a 50MHz clock, you can only get a nice 50/50 duty cycle if you want 25Mhz, 12.5Hz, 6.25MHz etc. As for the synthesisor implementing something odd, its probably because you have an asyncronous load, which is never a good idea. Ive built it myself, and yes, theres alot of unnessary logic. You also havent put Q in the sensitivity list so this code will not simulate properly (it wont reset when Q gets to 0, it will just wrap). I would recommend using a fully syncronous version: library IEEE; use IEEE.STD_LOGIC_1164.all; use ieee.numeric_std.all; entity DIV_COUNTER is port(CLK : in STD_LOGIC; CLK1, CLK2, CLK8k : out STD_LOGIC); end test_build; architecture BEHAVIOR of DIV_COUNTER is signal Q : unsigned(25 downto 0); begin process(CLK, LOAD) constant PRESET : NATURAL :=50000000; -- input 50 MHz begin if rising_edge(clk) then if Q = 0 then Q <= unsigned(PRESET) else Q <= Q - 1; end if; end if; CLK1 <= Q(25); -- 1HZ CLK CLK2 <= Q(24); -- 2HZ CLK CLK8k <= Q(12);-- 8 kHZ CLK end process; end BEHAVIOR; NOTE: It is HIGHLY recommended to use enables rather than logic- generated clocks on other registers. Tricky |
|
|
|
#6 |
|
Posts: n/a
|
> * * * * Q <= unsigned(PRESET) whooops, that should be: Q <= to_unsigned(PRESET, Q'length) Tricky |
|
|
|
#7 |
|
Posts: n/a
|
Tricky wrote:
> entity DIV_COUNTER is > port(CLK : in STD_LOGIC; > CLK1, CLK2, CLK8k : out STD_LOGIC); > end test_build; Make that "end div_counter;" > > NOTE: It is HIGHLY recommended to use enables rather than logic- > generated clocks on other registers. Clock enables can be implied for variable registers. For example: http://mysite.verizon.net/miketreseler/count_enable.vhd -- Mike Treseler Mike Treseler |
|
|
|
#8 |
|
Posts: n/a
|
Thanks for your answers,
My problem is not the 50/50 duty cycle but that the 1HzCLK and the 2HzClk are at the same frequency (1Hz). Making the load synchronous will not help. Is there a limiting of type NATURAL? Thanks for help Volker "Mark McDougall" <> schrieb im Newsbeitrag news:... > Volker wrote: > >> In principle it would work, but 2 Hz clock is 1 Hz and the duty cycle >> ist about 30/70. If I check Q23 is OK but Q24 and Q25 not. In RTL view >> the implementation of Q24 and Q25 looks a little bit strange. Did >> anyone know how the design ist not working well? > > In principle, it *won't* work as you hope. > > The '1Hz' clock has 30/70 duty cycle because (2^25)/50e6 is about 70%. > > IMHO don't feed back an async preset from the process logic, just preset > the counter explicitly. And your 1Hz clock should be asserted whenever Q > reaches a certain (any) value. The other clocks don't divide nicely into > 50e6 so you can't really do what you're trying to do. > > I'd probably derive an 8KHz clock enable and use that to increment a > counter that you can derive the 1Hz and 2Hz clock enables from... you're > not clocking logic with these clocks, are you!?! > > Regards, > > -- > Mark McDougall, Engineer > Virtual Logic Pty Ltd, <http://www.vl.com.au> > 21-25 King St, Rockdale, 2216 > Ph: +612-9599-3255 Fax: +612-9599-3266 > Volker |
|