GPS Spew

From Hamsterworks Wiki!

Jump to: navigation, search

This FPGA Project was completed in June 2015.

For testing some projects I needed a way to check the tuning of a GPS antenna. This required a source of the GPS L1 frequency 1.575,420 GHz.

This is a small FPGA project that uses a chain of PLLs to generate square wave that is 1/3rd of that frequency, so the third harmonic is the signal of interest.

It was implemented on a Digilent Basys3 board, using just a 200mm jumper wire connected to JA1 as the radiating element.

As a sort-of bonus, it also works well as a desktop GPS jammer which might be useful if you need to test a design's reaction to loss of GPS fix - so use it with care!

Source files

This is a chain of four PLLs, that converts a 100MHz clock into a 525.140 MHz signal. The 3rd harmonic is 1.575,420 GHz, which is the GPS L1 frequency.

Here is the table of the inputs and output frequency of each PLL, along with the internal Voltage Controlled Oscillator frequency:

Stage Input freq Multiply Vco freq Divide Output freqency
1 100 MHz 7 700 MHz 10 70.0 MHz
2 70 MHz 11 770 MHz 25 30.8 MHz
3 30.8 MHz 31 954.8 MHz 20 47.74 MHz
4 47.74 MHz 22 1050.28 MHz 2 525.14 MHz

gps_signal.vhd

---------------------------------------------------------
-- Generate a signal that is 1/3rd of the GPS L1 signal,
-- so the 3rd harmonic can be used for testing/tuning 
-- GPS antennas.
-- 
-- CAUTION: This will also block GPS close to the device.
-- Please don't do anything dumb with it.
--
-- Author: Mike Field <hamster@snap.net.nz>
---------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library UNISIM;
use UNISIM.VComponents.all;

entity gps_signal is
    Port ( clk100     : in  STD_LOGIC;
           test_signal : out STD_LOGIC);
end gps_signal;

architecture Behavioral of gps_signal is
    signal fb1       : std_logic;
    signal fb2       : std_logic;
    signal fb3       : std_logic;
    signal fb4       : std_logic;
    signal clk1      : std_logic;
    signal clk2      : std_logic;
    signal clk3      : std_logic;
    signal clk_final : std_logic;
    
    constant mult1      : real :=  7.0;
    constant div1       : real := 10.0;
    constant period1_in : real := 10.0;

    constant mult2      : real := 11.0;
    constant div2       : real := 25.0;
    constant period2_in : real := 1000.0/70.0;

    constant mult3      : real := 31.0;
    constant div3       : real := 20.0;
    constant period3_in : real := 1000.0/30.8;

    constant mult4      : real := 22.0;
    constant div4       : real := 2.0;
    constant period4_in : real := 1000.0/47.74;
begin

    -- 100MHz * 7 / 10 = 70MHz
MMCME2_BASE_1 : MMCME2_BASE
   generic map (
      BANDWIDTH => "OPTIMIZED",
      CLKFBOUT_MULT_F => mult1, 
      CLKFBOUT_PHASE => 0.0,
      CLKIN1_PERIOD => period1_in,
      CLKOUT0_DIVIDE_F   => div1,
      CLKOUT1_DIVIDE     => 1,
      CLKOUT2_DIVIDE     => 1,
      CLKOUT3_DIVIDE     => 1,
      CLKOUT4_DIVIDE     => 1,
      CLKOUT5_DIVIDE     => 1,
      CLKOUT6_DIVIDE     => 1,
      CLKOUT0_DUTY_CYCLE => 0.5,
      CLKOUT1_DUTY_CYCLE => 0.5,
      CLKOUT2_DUTY_CYCLE => 0.5,
      CLKOUT3_DUTY_CYCLE => 0.5,
      CLKOUT4_DUTY_CYCLE => 0.5,
      CLKOUT5_DUTY_CYCLE => 0.5,
      CLKOUT6_DUTY_CYCLE => 0.5,
      CLKOUT0_PHASE => 0.0,
      CLKOUT1_PHASE => 0.0,
      CLKOUT2_PHASE => 0.0,
      CLKOUT3_PHASE => 0.0,
      CLKOUT4_PHASE => 0.0,
      CLKOUT5_PHASE => 0.0,
      CLKOUT6_PHASE => 0.0,
      CLKOUT4_CASCADE => FALSE,
      DIVCLK_DIVIDE => 1,
      REF_JITTER1 => 0.0,
      STARTUP_WAIT => FALSE
   )
   port map (
      CLKOUT0   => CLK1,
      CLKOUT0B  => open,
      CLKOUT1   => open,
      CLKOUT1B  => open,
      CLKOUT2   => open,
      CLKOUT2B  => open,
      CLKOUT3   => open,
      CLKOUT3B  => open,
      CLKOUT4   => open,
      CLKOUT5   => open,
      CLKOUT6   => open,
      CLKFBOUT  => fb1,
      CLKFBOUTB => open,
      LOCKED => open,
      CLKIN1 => clk100,
      PWRDWN => '0',
      RST => '0',
      CLKFBIN => fb1
   );

    -- 70MHz * 11 / 25 = 30.8MHz

MMCME2_BASE_2 : MMCME2_BASE
   generic map (
      BANDWIDTH => "OPTIMIZED",
      CLKFBOUT_MULT_F => mult2, 
      CLKFBOUT_PHASE => 0.0,
      CLKIN1_PERIOD => period2_in,
      CLKOUT0_DIVIDE_F => div2,
      CLKOUT1_DIVIDE => 1,
      CLKOUT2_DIVIDE => 1,
      CLKOUT3_DIVIDE => 1,
      CLKOUT4_DIVIDE => 1,
      CLKOUT5_DIVIDE => 1,
      CLKOUT6_DIVIDE => 1,
      CLKOUT0_DUTY_CYCLE => 0.5,
      CLKOUT1_DUTY_CYCLE => 0.5,
      CLKOUT2_DUTY_CYCLE => 0.5,
      CLKOUT3_DUTY_CYCLE => 0.5,
      CLKOUT4_DUTY_CYCLE => 0.5,
      CLKOUT5_DUTY_CYCLE => 0.5,
      CLKOUT6_DUTY_CYCLE => 0.5,
      CLKOUT0_PHASE => 0.0,
      CLKOUT1_PHASE => 0.0,
      CLKOUT2_PHASE => 0.0,
      CLKOUT3_PHASE => 0.0,
      CLKOUT4_PHASE => 0.0,
      CLKOUT5_PHASE => 0.0,
      CLKOUT6_PHASE => 0.0,
      CLKOUT4_CASCADE => FALSE,
      DIVCLK_DIVIDE => 1,
      REF_JITTER1 => 0.0,
      STARTUP_WAIT => FALSE
   )
   port map (
      CLKOUT0   => CLK2,
      CLKOUT0B  => open,
      CLKOUT1   => open,
      CLKOUT1B  => open,
      CLKOUT2   => open,
      CLKOUT2B  => open,
      CLKOUT3   => open,
      CLKOUT3B  => open,
      CLKOUT4   => open,
      CLKOUT5   => open,
      CLKOUT6   => open,
      CLKFBOUT  => fb2,
      CLKFBOUTB => open,
      LOCKED => open,
      CLKIN1 => clk1,
      PWRDWN => '0',
      RST => '0',
      CLKFBIN => fb2
   );

    -- 30.8MHz
MMCME2_BASE_3 : MMCME2_BASE
      generic map (
         BANDWIDTH => "OPTIMIZED",
         CLKFBOUT_MULT_F => mult3, 
         CLKFBOUT_PHASE => 0.0,
         CLKIN1_PERIOD => period3_in,
         CLKOUT0_DIVIDE_F => div3,
         CLKOUT1_DIVIDE => 1,
         CLKOUT2_DIVIDE => 1,
         CLKOUT3_DIVIDE => 1,
         CLKOUT4_DIVIDE => 1,
         CLKOUT5_DIVIDE => 1,
         CLKOUT6_DIVIDE => 1,
         CLKOUT0_DUTY_CYCLE => 0.5,
         CLKOUT1_DUTY_CYCLE => 0.5,
         CLKOUT2_DUTY_CYCLE => 0.5,
         CLKOUT3_DUTY_CYCLE => 0.5,
         CLKOUT4_DUTY_CYCLE => 0.5,
         CLKOUT5_DUTY_CYCLE => 0.5,
         CLKOUT6_DUTY_CYCLE => 0.5,
         CLKOUT0_PHASE => 0.0,
         CLKOUT1_PHASE => 0.0,
         CLKOUT2_PHASE => 0.0,
         CLKOUT3_PHASE => 0.0,
         CLKOUT4_PHASE => 0.0,
         CLKOUT5_PHASE => 0.0,
         CLKOUT6_PHASE => 0.0,
         CLKOUT4_CASCADE => FALSE,
         DIVCLK_DIVIDE => 1,
         REF_JITTER1 => 0.0,
         STARTUP_WAIT => FALSE
      )
      port map (
         CLKOUT0   => clk3,
         CLKOUT0B  => open,
         CLKOUT1   => open,
         CLKOUT1B  => open,
         CLKOUT2   => open,
         CLKOUT2B  => open,
         CLKOUT3   => open,
         CLKOUT3B  => open,
         CLKOUT4   => open,
         CLKOUT5   => open,
         CLKOUT6   => open,
         CLKFBOUT  => fb3,
         CLKFBOUTB => open,
         LOCKED => open,
         CLKIN1 => clk2,
         PWRDWN => '0',
         RST => '0',
         CLKFBIN => fb3
      );

    -- 30.8MHz
MMCME2_BASE_4 : MMCME2_BASE
      generic map (
         BANDWIDTH => "OPTIMIZED",
         CLKFBOUT_MULT_F => mult4, 
         CLKFBOUT_PHASE => 0.0,
         CLKIN1_PERIOD => period4_in,
         CLKOUT0_DIVIDE_F => div4,
         CLKOUT1_DIVIDE => 1,
         CLKOUT2_DIVIDE => 1,
         CLKOUT3_DIVIDE => 1,
         CLKOUT4_DIVIDE => 1,
         CLKOUT5_DIVIDE => 1,
         CLKOUT6_DIVIDE => 1,
         CLKOUT0_DUTY_CYCLE => 0.5,
         CLKOUT1_DUTY_CYCLE => 0.5,
         CLKOUT2_DUTY_CYCLE => 0.5,
         CLKOUT3_DUTY_CYCLE => 0.5,
         CLKOUT4_DUTY_CYCLE => 0.5,
         CLKOUT5_DUTY_CYCLE => 0.5,
         CLKOUT6_DUTY_CYCLE => 0.5,
         CLKOUT0_PHASE => 0.0,
         CLKOUT1_PHASE => 0.0,
         CLKOUT2_PHASE => 0.0,
         CLKOUT3_PHASE => 0.0,
         CLKOUT4_PHASE => 0.0,
         CLKOUT5_PHASE => 0.0,
         CLKOUT6_PHASE => 0.0,
         CLKOUT4_CASCADE => FALSE,
         DIVCLK_DIVIDE => 1,
         REF_JITTER1 => 0.0,
         STARTUP_WAIT => FALSE
      )
      port map (
         CLKOUT0   => clk_final,
         CLKOUT0B  => open,
         CLKOUT1   => open,
         CLKOUT1B  => open,
         CLKOUT2   => open,
         CLKOUT2B  => open,
         CLKOUT3   => open,
         CLKOUT3B  => open,
         CLKOUT4   => open,
         CLKOUT5   => open,
         CLKOUT6   => open,
         CLKFBOUT  => fb4,
         CLKFBOUTB => open,
         LOCKED => open,
         CLKIN1 => clk3,
         PWRDWN => '0',
         RST => '0',
         CLKFBIN => fb4
      );
		 
ODDR_inst : ODDR
        generic map(
           DDR_CLK_EDGE => "SAME_EDGE", 
           INIT => '0',
           SRTYPE => "SYNC")
        port map (
           Q => test_signal,
           C => clk_final,
           CE => '1',
           D1 => '0',
           D2 => '1',
           R => '0',
           S => '0'
        );
       			
					
end Behavioral;

basys3.xdc

Constraints for the Basys3 board.

## Clock signal
set_property PACKAGE_PIN W5 [get_ports clk100]							
    set_property IOSTANDARD LVCMOS33 [get_ports clk100]
    create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk100]
    
#Sch name = JA1
set_property PACKAGE_PIN J1 [get_ports {test_signal}]                    
set_property IOSTANDARD LVCMOS33 [get_ports {test_signal}]

Personal tools