Guys,
I am designing a conventional Digital down converter on virtex
-4 Sx55 FPGA for GSM applications.
The Input clock frequency is above 160 Mhz for the initial CIC
decimation filter. After decimation , the data is fed to low pass
filter at a very low rate of ~1 Mhz
The issue is ,I am not able to generate this low frequency clcok with
Virtex -4 DCM , obviously the min output frequency is 32 Mhz.
After I looked into the previous threads , i dont feel its a clean way
to generate the divided clock by internal clock divider or clock
gating circuit in FPGA .
Can anyone let me know any other way of generating the low frequency
clock or is it safe to use internal clock divider considering my
asynchronous design ( FIFO between each filter stage) ?
Iam using the latest FIR compiler to generate the LP filter core. but
i do see the option of input sample per no of clock cycles in
previous Distributed FIR core which made life easy. but the FIR
compiler core doesnt have this option.
Please advice
Thanks in Advance
Vijay
Low frequency clock generation - need help
Started by ●September 28, 2008
Reply by ●September 29, 20082008-09-29
Vjay, If you need to generate a low frequency that is an integer fraction of your incoming clock frequency, then you just build a synchronous divider, and you get an output frequency that has its edges aligned with your incoming clock, but one clock-to-Q delay later. Your concern may be the phase alignment between the fast clock and the slow clock. If that is critical, just use the synchronous integer divider, and rely on the fact thet the edges of the slow frequency are very slightly later than the rising edge of the high frequency, say 2 or 3 ns max. You might alteratively use the fast clock to also do the slow clocking, but with a control signal disabling the clock most of the time. That gives you a totally synchronous system (with slightly higher power consumption) If the ratio is not an integer, then you can use the DCM to do some multiply/divide operation, followed up by an integer divider, For example, you can use the DCM to multiply 160 MHz by 17 and simultaneously divide it by 27, and follow that up by any integer division. Obviously, the phase relationship between the clocks is then an unontrolled variable, but that is unavoidably part of your assumptions. Peter Alfke, on Sunday watch from home. Old habits never die.
Reply by ●September 29, 20082008-09-29
vlodiya@gmail.com wrote:> Guys, > > I am designing a conventional Digital down converter on virtex > -4 Sx55 FPGA for GSM applications. > > The Input clock frequency is above 160 Mhz for the initial CIC > decimation filter. After decimation , the data is fed to low pass > filter at a very low rate of ~1 Mhz > > The issue is ,I am not able to generate this low frequency clcok with > Virtex -4 DCM , obviously the min output frequency is 32 Mhz. >Hi Vijay, You don't need to generate a 1MHz clock, instead you should generate a 1MHz clock enable for the parts of your design that run at 1MHz. The whole design is clocked at 160MHz, but the slow part is only enabled for one cycle in 160. This makes it a trivial task to pass data between the domains of the design. Cheers, Syms.
Reply by ●September 30, 20082008-09-30
vlodiya@gmail.com writes:> Guys, > > I am designing a conventional Digital down converter on virtex > -4 Sx55 FPGA for GSM applications. > > The Input clock frequency is above 160 Mhz for the initial CIC > decimation filter. After decimation , the data is fed to low pass > filter at a very low rate of ~1 Mhz > > The issue is ,I am not able to generate this low frequency clcok with > Virtex -4 DCM , obviously the min output frequency is 32 Mhz. > > After I looked into the previous threads , i dont feel its a clean way > to generate the divided clock by internal clock divider or clock > gating circuit in FPGA . > > Can anyone let me know any other way of generating the low frequency > clock or is it safe to use internal clock divider considering my > asynchronous design ( FIFO between each filter stage) ? > > Iam using the latest FIR compiler to generate the LP filter core. but > i do see the option of input sample per no of clock cycles in > previous Distributed FIR core which made life easy. but the FIR > compiler core doesnt have this option. > > Please advice > > Thanks in Advance > > VijayI'm certainly no expert in the field of hardware design, but I've had good luck using the master clock signal and an 'enable' that runs at the desired clock speed. I've successfully used this technique to divide the Spartan 3E 50MHz clock down to 230Khz for serial port transmission. I'd be happy to provide the entity which produces the 'enable' signal and an example of how to use it if you're interested. thutt -- Hoegaarden!
Reply by ●October 1, 20082008-10-01
On Sep 30, 6:01 am, thutt <thutt...@comcast.net> wrote:> vlod...@gmail.com writes: > > Guys, > > > I am designing a conventional Digital down converter on virtex > > -4 Sx55 FPGA for GSM applications. > > > The Input clock frequency is above 160 Mhz for the initial CIC > > decimation filter. After decimation , the data is fed to low pass > > filter at a very low rate of ~1 Mhz > > > The issue is ,I am not able to generate this low frequency clcok with > > Virtex -4 DCM , obviously the min output frequency is 32 Mhz. > > > After I looked into the previous threads , i dont feel its a clean way > > to generate the divided clock by internal clock divider or clock > > gating circuit in FPGA . > > > Can anyone let me know any other way of generating the low frequency > > clock or is it safe to use internal clock divider considering my > > asynchronous design ( FIFO between each filter stage) ? > > > Iam using the latest FIR compiler to generate the LP filter core. but > > i do see the option of input sample per no of clock cycles in > > previous Distributed FIR core which made life easy. but the FIR > > compiler core doesnt have this option. > > > Please advice > > > Thanks in Advance > > > Vijay > > I'm certainly no expert in the field of hardware design, but I've had > good luck using the master clock signal and an 'enable' that runs at > the desired clock speed. I've successfully used this technique to > divide the Spartan 3E 50MHz clock down to 230Khz for serial port > transmission. > > I'd be happy to provide the entity which produces the 'enable' signal > and an example of how to use it if you're interested.please provide, I have currently been using a divided clock for spi-modules when I run into the problem of not having any more clock-buffer ressources in the spartan-3dsp that I am using. I developed a clock enabler circuit that was basically a counter and a pulse shortener to have an enable pulse that is 1 sys_clk wide every nth sys_clk period, where n is number of division. In my case 16. The shift registers and the state machine gets this 16ths enable to catch data on the sys_clk rising edge. Pulse shortener is made with one flip-flop clocked by sys_clk taking qn to and with sys_clk. Both the counter and the pulse shortener is clocked by the negative edge of sys_clk to have the clock enable signal high when rising_edge on sys_clk happens. (Does using negative edge (inverted sys_clk) need another clock buffer?) Now I have the issue that the SPI sclk that I generate needs to have a clock enable that is double the rate of the one that enables the shift registers in order to enable sclk toggling between the shift register clock enables. This seems like an awful lot of extra code (and logic) just to avoid spending a global clock buffer or risk hazards by using local nets and use the good old if risng_edge(sclk) then.... I could surely add another pulse shortener to the counter as the higher frequencies are available but I wonder if that is the best way to do it. I don't have enough DCMs to spend one on each SPI. We need them for FIR filters. I think I have understood the benefits of using clock enable, both through not having enough ressources and through different postings in webforums, so I sat down and coded and coded but didn't really like what I saw as a result. I have searched on the net for some hours without finding any document that really shows a best-practices solution on how to generate and use clock enables for peripheral serial devices. I really wonder why. It is not rocket science, is it? -- Svenn
Reply by ●October 2, 20082008-10-02
Svenn Are Bjerkem wrote:> > I think I have understood the benefits of using clock enable, both > through not having enough ressources and through different postings in > webforums, so I sat down and coded and coded but didn't really like > what I saw as a result. > > I have searched on the net for some hours without finding any document > that really shows a best-practices solution on how to generate and use > clock enables for peripheral serial devices. I really wonder why. It > is not rocket science, is it?Hi Svenn, No it's not. Try something like this... gen_enable : process(clk, res_n) begin if res_n = 0 then count <= 0; enable <= '0'; elsif rising_edge(clk) then count <= (count + 1) mod 16; if count = 15 then enable <= '1'; else enable <= '0'; end if; end if; end process; do_stuff : process(clk, res_n) begin if res_n = 0 then -- insert resets here elsif rising_edge(clk) then if enable = '1' then -- insert enabled code here end if; end if; end process; HTH., Syms.
Reply by ●October 2, 20082008-10-02
On Oct 1, 4:33=A0pm, Svenn Are Bjerkem <svenn.bjer...@googlemail.com> wrote:> On Sep 30, 6:01 am, thutt <thutt...@comcast.net> wrote: > I have currently been using a divided clock for spi-modules when I run > into the problem of not having any more clock-buffer ressources in the > spartan-3dsp that I am using. I developed a clock enabler circuit that > was basically a counter and a pulse shortener to have an enable pulse > that is 1 sys_clk wide every nth sys_clk period, where n is number of > division. In my case 16.Sounds good.> The shift registers and the state machine gets this 16ths enable to > catch data on the sys_clk rising edge. > > Pulse shortener is made with one flip-flop clocked by sys_clk taking > qn to and with sys_clk. Both the counter and the pulse shortener is > clocked by the negative edge of sys_clk to have the clock enable > signal high when rising_edge on sys_clk happens. (Does using negative > edge (inverted sys_clk) need another clock buffer?) >No, but it is also unneeded and not helpful to use the negative edge of the clock. You should be using the rising edge for the clock enable, using the negative edge simply cuts down by 1/2 the max clock rate that you can run the design at.> Now I have the issue that the SPI sclk that I generate needs to have a > clock enable that is double the rate of the one that enables the shift > registers in order to enable sclk toggling between the shift register > clock enables.So you need something that fires at 8 as well as 16.> This seems like an awful lot of extra code (and logic)A lot?? Once you have the counter to count your longest period enable, adding additional count enables is simply adding a couple lines of code. In the example below, signal 'ce2' which occurs every 8th clock cycle added one more case to the case statement, and three assignments. This will get implemented as a simple decode of the counter states, each clock enable will be implemented in a single logic cell. if rising_edge(clock) then if (reset =3D '1') or (count =3D 15) then count <=3D 0; else count <=3D count + 1; end if; case count is when 7 =3D> ce2 <=3D '1'; when 15 =3D> ce1 <=3D '1'; ce2 <=3D '1'; when others =3D> ce1 <=3D '0'; ce2 <=3D '0'; end case; end if;> just to avoid spending a global clock buffer or risk hazards by using > local nets and use the good old if risng_edge(sclk) then....The issue is being able to pass timing analysis and reliably crossing clock domains when you generate multiple clocks.> I could > surely add another pulse shortener to the counter as the higher > frequencies are available but I wonder if that is the best way to do > it. I don't have enough DCMs to spend one on each SPI. We need them > for FIR filters.I have no idea why you are using any DCMs for SPI. At the start you said that you had implemented the counter and clock enable both running off of the system clock. In any case, it is simple to add whatever additional clock enables you may need.> > I think I have understood the benefits of using clock enable, both > through not having enough ressources and through different postings in > webforums, so I sat down and coded and coded but didn't really like > what I saw as a result. >What did you see? Why did you not like it?> I have searched on the net for some hours without finding any document > that really shows a best-practices solution on how to generate and use > clock enables for peripheral serial devices.You didn't look too hard then. Symon reply also shows how to generate and use the clock enables.> I really wonder why. It > is not rocket science, is it? >Not rocket science, just simple sequential boolean logic. KJ
Reply by ●October 2, 20082008-10-02
On Thu, 2 Oct 2008 10:13:20 +0100, "Symon" <symon_brewer@hotmail.com> wrote:>Svenn Are Bjerkem wrote: >> >> I think I have understood the benefits of using clock enable, both >> through not having enough ressources and through different postings in >> webforums, so I sat down and coded and coded but didn't really like >> what I saw as a result. >> >> I have searched on the net for some hours without finding any document >> that really shows a best-practices solution on how to generate and use >> clock enables for peripheral serial devices. I really wonder why. It >> is not rocket science, is it? > >Hi Svenn, >No it's not. Try something like this... > >gen_enable : process(clk, res_n) > begin > if res_n = 0 then > count <= 0; > enable <= '0'; > elsif rising_edge(clk) then > count <= (count + 1) mod 16; > if count = 15 then > enable <= '1'; > else > enable <= '0'; > end if; > end if; > end process;or: (2 changes; (a) using default initialisations (b) extend by adding a 2x clock enable) gen_enable : process(clk, res_n) begin if res_n = 0 then count <= 0; enable <= '0'; enable_2x <= '0'; elsif rising_edge(clk) then enable <= '0'; enable_2x <= '0'; count <= (count + 1) mod 16; if count = 15 then enable <= '1'; -- else -- enable <= '0'; end if; if count(2 downto 0) = 7 then -- = 3 for a 90 degree phase shift enable_2x <= '1'; end if; end if; end process; Hardware generated by any of these is tiny; too small to be worth worrying about unless your target is a PAL16V8. - Brian
Reply by ●October 3, 20082008-10-03
Svenn Are Bjerkem <svenn.bjerkem@googlemail.com> writes:> On Sep 30, 6:01 am, thutt <thutt...@comcast.net> wrote: > > vlod...@gmail.com writes: > > > Guys, > ><snip>> > I'm certainly no expert in the field of hardware design, but I've had > > good luck using the master clock signal and an 'enable' that runs at > > the desired clock speed. I've successfully used this technique to > > divide the Spartan 3E 50MHz clock down to 230Khz for serial port > > transmission. > > > > I'd be happy to provide the entity which produces the 'enable' signal > > and an example of how to use it if you're interested. > > please provide,Svenn, Since you asked, and since it appears to be something that's not so easily findable on the net -- at least with my google-fu -- I'm going to post the sample and the library here rather than in private email. I hope it doesn't violate any general rules of this newsgroup. I also hope that if I've done something insanely stupid in the code that someone more knowledgeable will point that out. 1. the clock divider. I started out with a clock divider I found by Brian Boorman. The version I downloaded didn't compile, and I had to make modifications. After getting it to work, I decided that *I* felt the code was ugly and could use a little sprucing up to make it more accessible. I then used that version for a while until I ran into some clock issues and I was admonished by my hardware guardian angel that it would be best to have only a single clock in your design and to use an 'enable'. Of course, it's not straightforward how to get an 'enable pulse' to occur when desired, but only for one cycle of the master clock signal. For example, consider a 50MHz master clock (like the Spartan 3E) and a divided clock of 230,400 Hz. Originally, the clock divider entity output a wave form that was 230,400Hz - but that would be many, many clocks at 50MHz. I only wanted ONE pulse at 50 MHz for each transition of the 230,400 Hz clock. This is accomplished with a two flip flops (i.e., the normal trick used to cross clock domains) and a little extra logic. This is implemented using 'shift_reg' and the assignment to 'clk_enable'. The 'clock_divisor' generic input is the divisor used to produce the desired clock. Taking the 50MHz / 230400 Hz example, the divisor is 14. The 230,400 Hz value is a serial port speed. So, the value is calculated like this: master clock / desired-bps / special-divisor 50,000,000 / 230,400 / 15 The special divisor was tediously calculated by hand. I won't go into the details here, but I may someday on http://www.harp-project.com/. Below I have an example which will blink the LEDs on the Spartan 3E board at 1, 10 and 100 Hz, so you'll see another example. --- begin clock divider --- -- Copyright (c) 1997 Brian Boorman, Harris RF Communications, Rochester, NY -- -- Originally code found here: -- http://www.edn.com/archives/1997/081597/17di_01.htm -- -- This version of the code is fixed from the original, and then -- cleaned up in terms of formatting and simplicity, but the original -- code still is largely intact. library ieee; use ieee.std_logic_1164.all; entity clkdiv_enable is generic(clock_divisor: natural := 3); port(clkin : in std_logic; -- 50% Duty Cycle Input Clock reset : in std_logic; -- Active high reset clk_enable : out boolean); end clkdiv_enable; architecture lms of clkdiv_enable is -- This subtype will constrain counter width. subtype divtype_t is natural range 0 to clock_divisor - 1; constant is_valid : boolean := clock_divisor >= 1; constant is_passthru : boolean := clock_divisor = 1; constant is_half : boolean := clock_divisor = 2; constant is_odd : boolean := (((((clock_divisor / 2) * 2)) = (clock_divisor - 1)) and (clock_divisor > 2)); constant is_even : boolean := (((((clock_divisor / 2) * 2)) = clock_divisor) and (clock_divisor > 2)); signal enable : std_logic; signal shift_reg : std_logic_vector(1 downto 0); signal counter : divtype_t; signal en_tff : std_logic_vector(boolean'pos(is_odd) downto 0); signal divisor : std_logic_vector(boolean'pos(is_odd) downto 0); function std_logic_to_bool(s : std_logic) return boolean is begin if s = '1' then return true; else return false; end if; end function std_logic_to_bool; begin assert(is_valid) report "Clock divisor must be a positive number >= 1" severity failure; assert(not is_odd) report "Clock divisor is odd; will result in a combinatorial clock signal" severity failure; assert(not is_half) report "Generating a half-cycle clock" severity warning; assert(not is_passthru) report "Generating a passthrough clock" severity warning; assert(not is_even) report "Generating an even clock" severity warning; gOne: if is_passthru generate enable <= clkin when reset = '0' else '0'; end generate; gTwo: -- generate a T Flip-Flop if is_half generate pTwo: process(clkin, reset, divisor(0)) begin if reset = '1' then divisor(0) <= '0'; elsif rising_edge(clkin) then divisor(0) <= not(divisor(0)); end if; end process; enable <= divisor(0); end generate; gOdd: if is_odd generate pOdd: process(clkin, reset, counter) begin if reset = '1' then counter <= 0; elsif rising_edge(clkin) then if counter = clock_divisor - 1 then counter <= 0; else counter <= counter + 1; end if; end if; end process; en_tff(0) <= '1' when counter = 0 else '0'; en_tff(1) <= '1' when counter = (((clock_divisor - 1) / 2) + 1) else '0'; pOddDiv1: process(clkin, reset, en_tff(0), divisor(0)) begin if reset = '1' then divisor(0) <= '1'; elsif rising_edge(clkin) then if en_tff(0) = '1' then divisor(0) <= not(divisor(0)); end if; end if; end process; pOddDiv2: process(clkin, reset, en_tff(1), divisor(1)) begin if reset = '1' then divisor(1) <= '1'; elsif falling_edge(clkin) then if en_tff(1) = '1' then divisor(1) <= not(divisor(1)); end if; end if; end process; enable <= divisor(0) xor divisor(1); end generate; gEven: if is_even generate pEvenDiv: process(clkin, reset, counter) begin if reset = '1' then counter <= 0; elsif rising_edge(clkin) then if counter = clock_divisor - 1 then counter <= 0; else counter <= counter + 1; end if; end if; end process; en_tff(0) <= '1' when ((counter = 0) or (counter = ((clock_divisor / 2) - 1)) ) else '0'; pEvenDiv1: process(clkin, reset, en_tff(0), divisor(0)) begin if reset = '1' then divisor(0) <= '0'; elsif rising_edge(clkin) then if en_tff(0) = '1' then divisor(0) <= not(divisor(0)); end if; end if; end process; enable <= divisor(0); end generate; shift_reg <= enable & shift_reg(1) when rising_edge(clkin); clk_enable <= std_logic_to_bool(shift_reg(1) and not shift_reg(0)); end lms; --- end clock divider --- 2. Constraints file Below is the constraint file which assigns the LEDs to my divided clocks. If you're not using Xilinx software, you'll have to come up with your own constraints. -- begin UCF file --- # This file is part of the Harp Project. # Copyright (c) 2007, 2008 Taylor Hutt, Logic Magicians Software # http://www.harp-project.com/ # # This program is free software: you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # NET "CLK_50MHZ" LOC = "C9" | IOSTANDARD = LVCMOS33 ; NET "CLK_50MHZ" PERIOD = 20.0ns HIGH 40%; NET "CLK_1HZ" LOC = "F12" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ; NET "CLK_10HZ" LOC = "E12" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ; NET "CLK_100HZ" LOC = "E11" | IOSTANDARD = LVTTL | SLEW = SLOW | DRIVE = 8 ; --- end UCF file --- 3. Sample Design -- Blink LEDs Finally, a simple example that I just cooked up that will blink some LEDs on the Xilinx board at 1, 10 and 100Hz. --- begin Sample VHDL --- -- This file is part of the Harp Project. -- Copyright (c) 2007, 2008 Taylor Hutt, Logic Magicians Software -- http://www.harp-project.com/ -- -- This program is free software: you can redistribute it and/or -- modify it under the terms of the GNU General Public License as -- published by the Free Software Foundation, either version 3 of the -- License, or (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, but -- WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see <http://www.gnu.org/licenses/>. -- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity main is Port (CLK_50MHZ : in STD_LOGIC; CLK_100HZ : out STD_LOGIC; CLK_10HZ : out STD_LOGIC; CLK_1HZ : out STD_LOGIC); end main; architecture Behavioral of main is signal output_1Hz : std_logic := '0'; signal output_10Hz : std_logic := '0'; signal output_100Hz : std_logic := '0'; signal enable_1Hz : boolean; signal enable_10Hz : boolean; signal enable_100Hz : boolean; begin blink_1Hz : process(CLK_50MHZ, enable_1Hz) begin if enable_1Hz then if rising_edge(CLK_50MHZ) then output_1Hz <= not output_1Hz; end if; end if; end process blink_1Hz; blink_10Hz : process(CLK_50MHZ, enable_10Hz) begin if enable_10Hz then if rising_edge(CLK_50MHZ) then output_10Hz <= not output_10Hz; end if; end if; end process blink_10Hz; blink_100Hz : process(CLK_50MHZ, enable_100Hz) begin if enable_100Hz then if rising_edge(CLK_50MHZ) then output_100Hz <= not output_100Hz; end if; end if; end process blink_100Hz; one_hz: entity clkdiv_enable -- 1 Hz generic map (clock_divisor => 50000000) port map (clkin => CLK_50MHZ, reset => '0', clk_enable => enable_1HZ); ten_hz: entity clkdiv_enable -- 10 Hz generic map (clock_divisor => 5000000) port map (clkin => CLK_50MHZ, reset => '0', clk_enable => enable_10HZ); one_hundred_hz: entity clkdiv_enable -- 100 Hz generic map (clock_divisor => 500000) port map (clkin => CLK_50MHZ, reset => '0', clk_enable => enable_100HZ); CLK_100HZ <= output_100Hz; CLK_10HZ <= output_10Hz; CLK_1HZ <= output_1Hz; end behavioral; --- end Sample VHDL --- Keep in mind that I'm not a hardware guy! I'm a low-level software guy who's learning hardware. So, there could very well be things that I've done that no sane hardware engineer would actually do. Please be gentle in critiquing this work. I do however, think that my version of the clock divider is definitely easier to read. thutt --- Hoegaarden!
Reply by ●October 3, 20082008-10-03
I know an easier way of generating enable at any rate lower than a master clock. Use a modulo adder that increments by your required rate and the modulus to be your master clock. You can even scale the ratio to get power of 2 modulus. So to get 230400Hz on master clock of 50MHz, your adder can increment by 230400 and overflow at 50,000,000. Then at overflow generate an enable pulse. Thats all... kadhiem






