[time-nuts] Re: Microcontroller based frequency divider

ghf at hoffmann-hochfrequenz.de ghf at hoffmann-hochfrequenz.de
Sat Apr 30 21:43:15 UTC 2022


Am 2022-04-30 21:33, schrieb Clint Jay:
> I think the reason the PICDiv is so well regarded is because of the
> specific chips used and the way the timers etc. are implemented in 
> them.
> 
> So, an alternate chip outside of the Microchip PIC range just might not 
> be
> capable of the performance.

For me, the alternate chip is a Xilinx Coolrunner II with the following
half page of VHDL code.  For my board, there is also a phase comparator
on the chip, options for different OCXOs / more frequencies and space
for syncing an OCXO  to an incoming 1 pps (not tested).
Just 1 pps generation should fit into an X2C32 (i.e. half the size), to 
200 MHz.
Pulse precision is like a 74LVC flip flop.

Cheers, Gerhard


----------------------------------------------------------------------------------
-- Company:              Hoffmann RF & DSP
-- Create Date:          09:09:37 08/08/2012
-- Module Name:          ppps1_generator - Behavioral
-- Target Devices:       X2c64A-5VQ44
-- Additional Comments:  Free firmware under BSD license
----------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity pps1_generator is
	Port(
		clk         : in  STD_LOGIC;
		RunAt100MHz : in  STD_LOGIC;
		pps1_out    : out STD_LOGIC;
	);
end pps1_generator;

architecture Behavioral of pps1_generator is
	signal tctr       : integer range 0 to 99999999;
	signal pw_ctr     : integer range 0 to 199999;
	signal cycle_done : boolean;
	signal pw_done    : boolean;

	function bool2sl(b : boolean) return std_logic is
	begin
		if b then
			return '1';
		else
			return '0';
		end if;
	end function bool2sl;

begin
	u_div: process(clk) is
	begin
		if rising_edge(clk) then
			cycle_done <= (tctr = 0); -- pipeline the comparator

			if cycle_done
			then
				if RunAt100MHz = '1' then      -- reload
					tctr <= 100000000 - 2; -- divide by 100 Meg
				else
					tctr <= 10000000 - 2; -- divide by 10 Meg
				end if;
			else
				tctr <= tctr - 1;
			end if;

		end if;    -- rising_edge()
	end process u_div;

-- produce the standard 20 usec pulsewidth

	u_pulsewidth : process(clk) is
	begin
		if rising_edge(clk) then
			if cycle_done then
				if RunAt100MHz = '1' then
					pw_ctr <= 19999;
				else
					pw_ctr <= 1999;
				end if;

			elsif pw_ctr /= 0 then
				pw_ctr <= pw_ctr - 1;
			end if;

			pps1_out <= bool2sl(pw_ctr /= 0);

		end if;    -- rising_edge()
	end process u_pulsewidth;

end Behavioral;




More information about the Time-nuts_lists.febo.com mailing list