mirror of
https://github.com/jankae/LibreVNA.git
synced 2025-12-06 07:12:10 +01:00
486 lines
14 KiB
VHDL
486 lines
14 KiB
VHDL
----------------------------------------------------------------------------------
|
|
-- Company:
|
|
-- Engineer:
|
|
--
|
|
-- Create Date: 15:47:31 05/05/2020
|
|
-- Design Name:
|
|
-- Module Name: top - Behavioral
|
|
-- Project Name:
|
|
-- Target Devices:
|
|
-- Tool versions:
|
|
-- Description:
|
|
--
|
|
-- Dependencies:
|
|
--
|
|
-- Revision:
|
|
-- Revision 0.01 - File Created
|
|
-- Additional Comments:
|
|
--
|
|
----------------------------------------------------------------------------------
|
|
library IEEE;
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
|
|
|
-- Uncomment the following library declaration if using
|
|
-- arithmetic functions with Signed or Unsigned values
|
|
--use IEEE.NUMERIC_STD.ALL;
|
|
|
|
-- Uncomment the following library declaration if instantiating
|
|
-- any Xilinx primitives in this code.
|
|
--library UNISIM;
|
|
--use UNISIM.VComponents.all;
|
|
|
|
entity top is
|
|
Port ( CLK : in STD_LOGIC;
|
|
RESET : in STD_LOGIC;
|
|
MCU_MOSI : in STD_LOGIC;
|
|
MCU_NSS : in STD_LOGIC;
|
|
MCU_INTR : out STD_LOGIC;
|
|
MCU_SCK : in STD_LOGIC;
|
|
MCU_MISO : out STD_LOGIC;
|
|
MCU_AUX1 : in STD_LOGIC;
|
|
MCU_AUX2 : in STD_LOGIC;
|
|
MCU_AUX3 : in STD_LOGIC;
|
|
PORT2_CONVSTART : out STD_LOGIC;
|
|
PORT2_SDO : in STD_LOGIC;
|
|
PORT2_SCLK : out STD_LOGIC;
|
|
PORT2_MIX2_EN : out STD_LOGIC;
|
|
PORT2_MIX1_EN : out STD_LOGIC;
|
|
PORT1_CONVSTART : out STD_LOGIC;
|
|
PORT1_SDO : in STD_LOGIC;
|
|
PORT1_SCLK : out STD_LOGIC;
|
|
PORT1_MIX2_EN : out STD_LOGIC;
|
|
PORT1_MIX1_EN : out STD_LOGIC;
|
|
LO1_MUX : in STD_LOGIC;
|
|
LO1_RF_EN : out STD_LOGIC;
|
|
LO1_LD : in STD_LOGIC;
|
|
LO1_CLK : out STD_LOGIC;
|
|
LO1_MOSI : out STD_LOGIC;
|
|
LO1_LE : out STD_LOGIC;
|
|
LO1_CE : out STD_LOGIC;
|
|
LEDS : out STD_LOGIC_VECTOR (7 downto 0);
|
|
REF_MIX2_EN : out STD_LOGIC;
|
|
REF_MIX1_EN : out STD_LOGIC;
|
|
ATTENUATION : out STD_LOGIC_VECTOR (6 downto 0);
|
|
AMP_PWDN : out STD_LOGIC;
|
|
PORT1_SELECT : out STD_LOGIC; -- Port 1 additional isolation switch enable
|
|
PORT2_SELECT : out STD_LOGIC; -- Port 2 additional isolation switch enable
|
|
PORT_SELECT1 : out STD_LOGIC; -- Enable source -> port 1 switch
|
|
PORT_SELECT2 : out STD_LOGIC; -- Enable source -> port 2 switch
|
|
BAND_SELECT_HIGH : out STD_LOGIC;
|
|
BAND_SELECT_LOW : out STD_LOGIC;
|
|
FILT_OUT_C1 : out STD_LOGIC;
|
|
FILT_OUT_C2 : out STD_LOGIC;
|
|
FILT_IN_C1 : out STD_LOGIC;
|
|
FILT_IN_C2 : out STD_LOGIC;
|
|
SOURCE_RF_EN : out STD_LOGIC;
|
|
SOURCE_LD : in STD_LOGIC;
|
|
SOURCE_MUX : in STD_LOGIC;
|
|
SOURCE_CLK : out STD_LOGIC;
|
|
SOURCE_MOSI : out STD_LOGIC;
|
|
SOURCE_LE : out STD_LOGIC;
|
|
SOURCE_CE : out STD_LOGIC;
|
|
REF_CONVSTART : out STD_LOGIC;
|
|
REF_SDO : in STD_LOGIC;
|
|
REF_SCLK : out STD_LOGIC);
|
|
end top;
|
|
|
|
architecture Behavioral of top is
|
|
component PLL
|
|
port
|
|
(-- Clock in ports
|
|
CLK_IN1 : in std_logic;
|
|
-- Clock out ports
|
|
CLK_OUT1 : out std_logic;
|
|
-- Status and control signals
|
|
RESET : in std_logic;
|
|
LOCKED : out std_logic
|
|
);
|
|
end component;
|
|
|
|
COMPONENT ResetDelay
|
|
GENERIC(CLK_DELAY : integer);
|
|
PORT(
|
|
CLK : IN std_logic;
|
|
IN_RESET : IN std_logic;
|
|
OUT_RESET : OUT std_logic
|
|
);
|
|
END COMPONENT;
|
|
|
|
COMPONENT MAX2871
|
|
Generic (CLK_DIV : integer);
|
|
PORT(
|
|
CLK : IN std_logic;
|
|
RESET : IN std_logic;
|
|
REG4 : IN std_logic_vector(31 downto 0);
|
|
REG3 : IN std_logic_vector(31 downto 0);
|
|
REG1 : IN std_logic_vector(31 downto 0);
|
|
REG0 : IN std_logic_vector(31 downto 0);
|
|
RELOAD : IN std_logic;
|
|
CLK_OUT : OUT std_logic;
|
|
MOSI : OUT std_logic;
|
|
LE : OUT std_logic;
|
|
DONE : OUT std_logic
|
|
);
|
|
END COMPONENT;
|
|
COMPONENT SPICommands
|
|
PORT(
|
|
CLK : IN std_logic;
|
|
RESET : IN std_logic;
|
|
SCLK : IN std_logic;
|
|
MOSI : IN std_logic;
|
|
NSS : IN std_logic;
|
|
SOURCE_UNLOCKED : IN std_logic;
|
|
MOD_FIFO_UNDERFLOW : IN std_logic;
|
|
MOD_FIFO_OVERFLOW : IN std_logic;
|
|
MOD_FIFO_THRESHOLD_CROSSED : IN std_logic;
|
|
MISO : OUT std_logic;
|
|
SOURCE_FILTER : OUT std_logic_vector(1 downto 0);
|
|
SOURCE_ATTENUATION : OUT std_logic_vector(6 downto 0);
|
|
SOURCE_BANDSELECT : OUT std_logic;
|
|
SOURCE_PORTSELECT : OUT std_logic;
|
|
MOD_FIFO_DATA : OUT std_logic_vector(7 downto 0);
|
|
MOD_FIFO_WRITE : OUT std_logic;
|
|
MOD_FIFO_THRESHOLD : OUT std_logic_vector(10 downto 0);
|
|
MOD_LOOKUP_INDEX : out STD_LOGIC_VECTOR (7 downto 0);
|
|
MOD_LOOKUP_DATA : out STD_LOGIC_VECTOR (143 downto 0);
|
|
MOD_LOOKUP_WRITE : out STD_LOGIC;
|
|
MOD_ENABLE : OUT std_logic;
|
|
MOD_PHASE_INC : out STD_LOGIC_VECTOR (15 downto 0);
|
|
AMP_SHDN : OUT std_logic;
|
|
SOURCE_RF_EN : OUT std_logic;
|
|
SOURCE_CE_EN : OUT std_logic;
|
|
PORTSWITCH_EN : OUT std_logic;
|
|
LEDS : OUT std_logic_vector(2 downto 0);
|
|
INTERRUPT_ASSERTED : OUT std_logic
|
|
);
|
|
END COMPONENT;
|
|
|
|
COMPONENT Synchronizer
|
|
GENERIC(stages : integer);
|
|
PORT(
|
|
CLK : IN std_logic;
|
|
SYNC_IN : IN std_logic;
|
|
SYNC_OUT : OUT std_logic
|
|
);
|
|
END COMPONENT;
|
|
|
|
COMPONENT ModulationMemory
|
|
PORT (
|
|
clka : IN STD_LOGIC;
|
|
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
|
|
addra : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
dina : IN STD_LOGIC_VECTOR(143 DOWNTO 0);
|
|
clkb : IN STD_LOGIC;
|
|
addrb : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
|
|
doutb : OUT STD_LOGIC_VECTOR(143 DOWNTO 0)
|
|
);
|
|
END COMPONENT;
|
|
|
|
COMPONENT Modulator
|
|
PORT(
|
|
CLK : IN std_logic;
|
|
RESET : IN std_logic;
|
|
ACTIVE : IN std_logic;
|
|
SAMPLE_FREQ_WORD : IN std_logic_vector(15 downto 0);
|
|
SAMPLE_DATA : IN std_logic_vector(7 downto 0);
|
|
SAMPLE_LATCH : IN std_logic;
|
|
THRESHOLD_LEVEL : IN std_logic_vector(10 downto 0);
|
|
OVERFLOW : OUT std_logic;
|
|
UNDERFLOW : OUT std_logic;
|
|
THRESHOLD_CROSSED : OUT std_logic;
|
|
OUTPUT_SAMPLE : OUT std_logic_vector(7 downto 0);
|
|
NEW_OUTPUT : OUT std_logic
|
|
);
|
|
END COMPONENT;
|
|
|
|
signal clk_pll : std_logic;
|
|
signal clk_locked : std_logic;
|
|
signal inv_clk_locked : std_logic;
|
|
signal int_reset : std_logic;
|
|
|
|
-- PLL signals
|
|
signal source_reg_4 : std_logic_vector(31 downto 0);
|
|
signal source_reg_3 : std_logic_vector(31 downto 0);
|
|
signal source_reg_1 : std_logic_vector(31 downto 0);
|
|
signal source_reg_0 : std_logic_vector(31 downto 0);
|
|
signal source_reloaded : std_logic;
|
|
signal source_reloaded_last : std_logic;
|
|
signal source_unlocked : std_logic;
|
|
signal source_reload : std_logic;
|
|
|
|
signal source_filter : std_logic_vector(1 downto 0);
|
|
signal band_select : std_logic;
|
|
signal attenuator : std_logic_vector(6 downto 0);
|
|
signal port_select : std_logic;
|
|
signal amp_shutdown : std_logic;
|
|
|
|
-- Configuration signals
|
|
signal user_leds : std_logic_vector(2 downto 0);
|
|
signal portswitch_en : std_logic;
|
|
|
|
-- PLL/SPI internal mux
|
|
signal fpga_select : std_logic;
|
|
signal fpga_source_SCK : std_logic;
|
|
signal fpga_source_MOSI : std_logic;
|
|
signal fpga_source_LE : std_logic;
|
|
signal fpga_LO1_SCK : std_logic;
|
|
signal fpga_LO1_MOSI : std_logic;
|
|
signal fpga_LO1_LE : std_logic;
|
|
signal fpga_miso : std_logic;
|
|
|
|
-- synchronized asynchronous inputs
|
|
signal aux1_sync : std_logic;
|
|
signal aux2_sync : std_logic;
|
|
signal aux3_sync : std_logic;
|
|
signal lo_ld_sync : std_logic;
|
|
signal source_ld_sync : std_logic;
|
|
signal nss_sync : std_logic;
|
|
|
|
-- modulation signals
|
|
signal mod_enable : std_logic;
|
|
signal mod_reset : std_logic;
|
|
signal mod_active : std_logic;
|
|
signal mod_sample_word : std_logic_vector(15 downto 0);
|
|
signal mod_sample_data : std_logic_vector(7 downto 0);
|
|
signal mod_sample_latch : std_logic;
|
|
signal mod_threshold_level : std_logic_vector(10 downto 0);
|
|
signal mod_fifo_overflow : std_logic;
|
|
signal mod_fifo_underflow : std_logic;
|
|
signal mod_fifo_threshold_crossed : std_logic;
|
|
signal mod_attenuator : std_logic_vector(6 downto 0);
|
|
|
|
signal mod_lookup_write_data : std_logic_vector(143 downto 0);
|
|
signal mod_lookup_read_data : std_logic_vector(143 downto 0);
|
|
signal mod_lookup_write_index : std_logic_vector(7 downto 0);
|
|
signal mod_lookup_read_index : std_logic_vector(7 downto 0);
|
|
signal mod_lookup_write : std_logic;
|
|
signal mod_new_output : std_logic;
|
|
|
|
signal intr : std_logic;
|
|
begin
|
|
|
|
-- Reference CLK LED
|
|
LEDS(0) <= user_leds(2);
|
|
-- Lock status of PLLs
|
|
LEDS(1) <= clk_locked;
|
|
LEDS(2) <= SOURCE_LD;
|
|
LEDS(3) <= LO1_LD;
|
|
-- Sweep and active port
|
|
PORT_SELECT2 <= not port_select and not amp_shutdown;
|
|
PORT2_SELECT <= not port_select and not amp_shutdown;
|
|
PORT_SELECT1 <= port_select and not amp_shutdown;
|
|
PORT1_SELECT <= port_select and not amp_shutdown;
|
|
BAND_SELECT_HIGH <= not band_select;
|
|
BAND_SELECT_LOW <= band_select;
|
|
AMP_PWDN <= amp_shutdown;
|
|
|
|
ATTENUATION <= attenuator when (mod_reset = '1' or aux3_sync = '1') else mod_attenuator;
|
|
|
|
-- unused signals, ADCs not used
|
|
PORT1_MIX2_EN <= '0';
|
|
PORT1_MIX1_EN <= '1';
|
|
PORT2_MIX2_EN <= '0';
|
|
PORT2_MIX1_EN <= '1';
|
|
REF_MIX2_EN <= '0';
|
|
REF_MIX1_EN <= '1';
|
|
PORT1_CONVSTART <= '0';
|
|
PORT1_SCLK <= '0';
|
|
PORT2_CONVSTART <= '0';
|
|
PORT2_SCLK <= '0';
|
|
REF_CONVSTART <= '0';
|
|
REF_SCLK <= '0';
|
|
LO1_RF_EN <= '0';
|
|
LO1_CE <= '0';
|
|
|
|
LEDS(4) <= not (not port_select and not amp_shutdown);
|
|
LEDS(5) <= not (port_select and not amp_shutdown);
|
|
-- Uncommitted LEDs
|
|
LEDS(7 downto 6) <= user_leds(1 downto 0);
|
|
MCU_INTR <= intr;
|
|
|
|
MainCLK : PLL
|
|
port map(
|
|
-- Clock in ports
|
|
CLK_IN1 => CLK,
|
|
-- Clock out ports
|
|
CLK_OUT1 => clk_pll,
|
|
-- Status and control signals
|
|
RESET => RESET,
|
|
LOCKED => clk_locked
|
|
);
|
|
|
|
inv_clk_locked <= not clk_locked and not RESET;
|
|
|
|
Inst_ResetDelay: ResetDelay
|
|
GENERIC MAP(CLK_DELAY => 100)
|
|
PORT MAP(
|
|
CLK => clk_pll,
|
|
IN_RESET => inv_clk_locked,
|
|
OUT_RESET => int_reset
|
|
);
|
|
|
|
Sync_AUX1 : Synchronizer
|
|
GENERIC MAP(stages => 2)
|
|
PORT MAP(
|
|
CLK => clk_pll,
|
|
SYNC_IN => MCU_AUX1,
|
|
SYNC_OUT => aux1_sync
|
|
);
|
|
Sync_AUX2 : Synchronizer
|
|
GENERIC MAP(stages => 2)
|
|
PORT MAP(
|
|
CLK => clk_pll,
|
|
SYNC_IN => MCU_AUX2,
|
|
SYNC_OUT => aux2_sync
|
|
);
|
|
Sync_AUX3 : Synchronizer
|
|
GENERIC MAP(stages => 2)
|
|
PORT MAP(
|
|
CLK => clk_pll,
|
|
SYNC_IN => MCU_AUX3,
|
|
SYNC_OUT => aux3_sync
|
|
);
|
|
-- Sync_LO_LD : Synchronizer
|
|
-- GENERIC MAP(stages => 2)
|
|
-- PORT MAP(
|
|
-- CLK => clk_pll,
|
|
-- SYNC_IN => LO1_LD,
|
|
-- SYNC_OUT => lo_ld_sync
|
|
-- );
|
|
Sync_SOURCE_LD : Synchronizer
|
|
GENERIC MAP(stages => 2)
|
|
PORT MAP(
|
|
CLK => clk_pll,
|
|
SYNC_IN => SOURCE_LD,
|
|
SYNC_OUT => source_ld_sync
|
|
);
|
|
Sync_NSS : Synchronizer
|
|
GENERIC MAP(stages => 2)
|
|
PORT MAP(
|
|
CLK => clk_pll,
|
|
SYNC_IN => MCU_NSS,
|
|
SYNC_OUT => nss_sync
|
|
);
|
|
|
|
Source: MAX2871
|
|
GENERIC MAP(CLK_DIV => 10)
|
|
PORT MAP(
|
|
CLK => clk_pll,
|
|
RESET => int_reset,
|
|
REG4 => source_reg_4,
|
|
REG3 => source_reg_3,
|
|
REG1 => source_reg_1,
|
|
REG0 => source_reg_0,
|
|
RELOAD => source_reload,
|
|
CLK_OUT => fpga_source_SCK,
|
|
MOSI => fpga_source_MOSI,
|
|
LE => fpga_source_LE,
|
|
DONE => source_reloaded
|
|
);
|
|
|
|
-- Source filter mapping
|
|
FILT_IN_C1 <= '0' when source_filter = "00" or source_filter = "10" else '1';
|
|
FILT_IN_C2 <= '0' when source_filter = "11" or source_filter = "10" else '1';
|
|
FILT_OUT_C1 <= '0' when source_filter = "00" or source_filter = "10" else '1';
|
|
FILT_OUT_C2 <= '0' when source_filter = "00" or source_filter = "01" else '1';
|
|
|
|
-- PLL/SPI mux
|
|
-- only select FPGA SPI slave when both AUX1 and AUX2 are low
|
|
fpga_select <= nss_sync when aux1_sync = '0' and aux2_sync = '0' else '1';
|
|
-- direct connection between MCU and SOURCE when AUX1 is high
|
|
SOURCE_CLK <= MCU_SCK when aux1_sync = '1' else fpga_source_SCK;
|
|
SOURCE_MOSI <= MCU_MOSI when aux1_sync = '1' else fpga_source_MOSI;
|
|
SOURCE_LE <= MCU_NSS when aux1_sync = '1' else fpga_source_LE;
|
|
-- direct connection between MCU and LO1 when AUX2 is high
|
|
LO1_CLK <= MCU_SCK when aux2_sync = '1' else '0';
|
|
LO1_MOSI <= MCU_MOSI when aux2_sync = '1' else '0';
|
|
LO1_LE <= MCU_NSS when aux2_sync = '1' else '0';
|
|
-- select MISO source
|
|
MCU_MISO <= SOURCE_MUX when aux1_sync = '1' else
|
|
LO1_MUX when aux2_sync = '1' else
|
|
fpga_miso when MCU_NSS = '0' else
|
|
'Z';
|
|
|
|
source_unlocked <= not source_ld_sync;
|
|
|
|
SPI: SPICommands PORT MAP(
|
|
CLK => clk_pll,
|
|
RESET => int_reset,
|
|
SCLK => MCU_SCK,
|
|
MOSI => MCU_MOSI,
|
|
MISO => fpga_miso,
|
|
NSS => fpga_select,
|
|
SOURCE_FILTER => source_filter,
|
|
SOURCE_ATTENUATION => attenuator,
|
|
SOURCE_BANDSELECT => band_select,
|
|
SOURCE_PORTSELECT => port_select,
|
|
SOURCE_UNLOCKED => source_unlocked,
|
|
MOD_FIFO_DATA => mod_sample_data,
|
|
MOD_FIFO_WRITE => mod_sample_latch,
|
|
MOD_FIFO_UNDERFLOW => mod_fifo_underflow,
|
|
MOD_FIFO_OVERFLOW => mod_fifo_overflow,
|
|
MOD_FIFO_THRESHOLD_CROSSED => mod_fifo_threshold_crossed,
|
|
MOD_FIFO_THRESHOLD => mod_threshold_level,
|
|
MOD_LOOKUP_INDEX => mod_lookup_write_index,
|
|
MOD_LOOKUP_DATA => mod_lookup_write_data,
|
|
MOD_LOOKUP_WRITE => mod_lookup_write,
|
|
MOD_ENABLE => mod_enable,
|
|
MOD_PHASE_INC => mod_sample_word,
|
|
AMP_SHDN => amp_shutdown,
|
|
SOURCE_RF_EN => SOURCE_RF_EN,
|
|
SOURCE_CE_EN => SOURCE_CE,
|
|
PORTSWITCH_EN => portswitch_en,
|
|
LEDS => user_leds,
|
|
INTERRUPT_ASSERTED => intr
|
|
);
|
|
|
|
mod_reset <= not mod_enable;
|
|
mod_active <= not aux3_sync;
|
|
|
|
source_reg_0 <= mod_lookup_read_data(31 downto 0);
|
|
source_reg_1 <= mod_lookup_read_data(63 downto 32);
|
|
source_reg_3 <= mod_lookup_read_data(95 downto 64);
|
|
source_reg_4 <= mod_lookup_read_data(127 downto 96);
|
|
|
|
process(clk_pll)
|
|
begin
|
|
if rising_edge(clk_pll) then
|
|
source_reload <= mod_new_output;
|
|
|
|
source_reloaded_last <= source_reloaded;
|
|
if source_reloaded = '1' and source_reloaded_last = '0' then
|
|
-- source has been reloaded, update attenuator
|
|
mod_attenuator <= mod_lookup_read_data(134 downto 128);
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
ModulationMem : ModulationMemory
|
|
PORT MAP (
|
|
clka => clk_pll,
|
|
wea(0) => mod_lookup_write,
|
|
addra => mod_lookup_write_index,
|
|
dina => mod_lookup_write_data,
|
|
clkb => clk_pll,
|
|
addrb => mod_lookup_read_index,
|
|
doutb => mod_lookup_read_data
|
|
);
|
|
|
|
Modulation: Modulator PORT MAP(
|
|
CLK => clk_pll,
|
|
RESET => mod_reset,
|
|
ACTIVE => mod_active,
|
|
SAMPLE_FREQ_WORD => mod_sample_word,
|
|
SAMPLE_DATA => mod_sample_data,
|
|
SAMPLE_LATCH => mod_sample_latch,
|
|
OVERFLOW => mod_fifo_overflow,
|
|
UNDERFLOW => mod_fifo_underflow,
|
|
THRESHOLD_LEVEL => mod_threshold_level,
|
|
THRESHOLD_CROSSED => mod_fifo_threshold_crossed,
|
|
OUTPUT_SAMPLE => mod_lookup_read_index,
|
|
NEW_OUTPUT => mod_new_output
|
|
);
|
|
|
|
end Behavioral;
|
|
|