Improved spectrum analyzer mode

- Faster sweeps by changing 2.LO only when necessary and using 400kHz I2C frequency
- Added FPGA settings for selectable ADC samplerate
- Additional measurement with different ADC samplerate when signal ID is on to remove ADC images
This commit is contained in:
Jan Käberich 2020-09-17 19:54:03 +02:00
parent 38e73365df
commit fc3ce7a828
22 changed files with 118 additions and 86 deletions

View File

@ -50,7 +50,7 @@ architecture Behavioral of MCP33131 is
signal div_cnt : integer range 0 to (CLK_DIV/2)-1;
signal sclk_phase : std_logic;
signal adc_data : std_logic_vector(15 downto 0);
type States is (Idle, Conversion, Transmission);
type States is (Idle, Conversion, WAIT_tEN, Transmission);
signal state : States;
signal min_int, max_int, data_int : signed(15 downto 0);
begin
@ -100,8 +100,10 @@ begin
div_cnt <= 0;
CONVSTART <= '0';
adc_data <= "0000000000000001";
state <= Transmission;
state <= WAIT_tEN;
end if;
when WAIT_tEN =>
state <= Transmission;
when Transmission =>
if(div_cnt < (CLK_DIV/2)-1) then
div_cnt <= div_cnt + 1;

View File

@ -60,8 +60,11 @@ entity SPICommands is
LO_RF_EN : out STD_LOGIC;
SOURCE_CE_EN : out STD_LOGIC;
LO_CE_EN : out STD_LOGIC;
PORTSWITCH_EN : out STD_LOGIC;
LEDS : out STD_LOGIC_VECTOR(2 downto 0);
WINDOW_SETTING : out STD_LOGIC_VECTOR(1 downto 0);
ADC_PRESCALER : out STD_LOGIC_VECTOR(7 downto 0);
ADC_PHASEINC : out STD_LOGIC_VECTOR(11 downto 0);
INTERRUPT_ASSERTED : out STD_LOGIC;
RESET_MINMAX : out STD_LOGIC;
SWEEP_HALTED : in STD_LOGIC;
@ -139,10 +142,13 @@ begin
LO_RF_EN <= '0';
SOURCE_CE_EN <= '0';
LO_CE_EN <= '0';
PORTSWITCH_EN <= '0';
LEDS <= (others => '1');
WINDOW_SETTING <= "00";
unread_sampling_data <= '0';
interrupt_mask <= (others => '0');
ADC_PRESCALER <= std_logic_vector(to_unsigned(112, 8));
ADC_PHASEINC <= std_logic_vector(to_unsigned(1120, 12));
RESET_MINMAX <= '0';
else
if sweep_config_write = '1' then
@ -191,7 +197,7 @@ begin
when 0 => interrupt_mask <= spi_buf_out;
when 1 => SWEEP_POINTS <= spi_buf_out(12 downto 0);
when 2 => NSAMPLES <= spi_buf_out(9 downto 0);
when 3 => --NSAMPLES(16) <= spi_buf_out(0);
when 3 => PORTSWITCH_EN <= spi_buf_out(0);
PORT1_EN <= spi_buf_out(15);
PORT2_EN <= spi_buf_out(14);
REF_EN <= spi_buf_out(13);
@ -204,8 +210,8 @@ begin
LO_CE_EN <= spi_buf_out(3);
EXCITE_PORT1 <= spi_buf_out(1);
EXCITE_PORT2 <= spi_buf_out(2);
--when 4 => SETTLING_TIME <= spi_buf_out;
when 4 => ADC_PRESCALER <= spi_buf_out(7 downto 0);
when 5 => ADC_PHASEINC <= spi_buf_out(11 downto 0);
when 8 => MAX2871_DEF_0(15 downto 0) <= spi_buf_out;
when 9 => MAX2871_DEF_0(31 downto 16) <= spi_buf_out;
when 10 => MAX2871_DEF_1(15 downto 0) <= spi_buf_out;

View File

@ -30,12 +30,11 @@ use IEEE.NUMERIC_STD.ALL;
--use UNISIM.VComponents.all;
entity Sampling is
Generic(CLK_DIV : integer;
CLK_FREQ : integer;
IF_FREQ : integer;
CLK_CYCLES_PRE_DONE : integer);
Generic(CLK_CYCLES_PRE_DONE : integer);
Port ( CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
ADC_PRESCALER : in STD_LOGIC_VECTOR(7 downto 0);
PHASEINC : in STD_LOGIC_VECTOR(11 downto 0);
PORT1 : in STD_LOGIC_VECTOR (15 downto 0);
PORT2 : in STD_LOGIC_VECTOR (15 downto 0);
REF : in STD_LOGIC_VECTOR (15 downto 0);
@ -87,11 +86,10 @@ END COMPONENT;
signal p2_Q : signed(47 downto 0);
signal r_I : signed(47 downto 0);
signal r_Q : signed(47 downto 0);
signal clk_cnt : integer range 0 to CLK_DIV - 1;
signal clk_cnt : integer range 0 to 255;
signal sample_cnt : integer range 0 to 131071;
signal samples_to_take : integer range 0 to 131071;
constant phase_inc : integer := IF_FREQ * 4096 * CLK_DIV / CLK_FREQ;
signal phase : std_logic_vector(11 downto 0);
signal sine : std_logic_vector(15 downto 0);
signal cosine : std_logic_vector(15 downto 0);
@ -206,7 +204,7 @@ begin
else
-- when not idle, generate pulses for ADCs
if state /= Idle then
if clk_cnt = CLK_DIV - 1 then
if clk_cnt = unsigned(ADC_PRESCALER) - 1 then
ADC_START <= '1';
clk_cnt <= 0;
else
@ -234,7 +232,7 @@ begin
phase <= (others => '0');
if START = '1' then
state <= Sampling;
samples_to_take <= to_integer(unsigned(SAMPLES & "0000000"));
samples_to_take <= to_integer(unsigned(SAMPLES & "0000000") - 1);
end if;
when Sampling =>
DONE <= '0';
@ -260,7 +258,7 @@ begin
ACTIVE <= '1';
DONE <= '0';
PRE_DONE <= '0';
phase <= std_logic_vector(unsigned(phase) + phase_inc);
phase <= std_logic_vector(unsigned(phase) + unsigned(PHASEINC));
if sample_cnt < samples_to_take then
sample_cnt <= sample_cnt + 1;
state <= Sampling;

View File

@ -79,7 +79,7 @@ BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: MCP33131
GENERIC MAP(CLK_DIV => 2,
CONVCYCLES => 71)
CONVCYCLES => 77)
PORT MAP (
CLK => CLK,
RESET => RESET,
@ -106,13 +106,13 @@ BEGIN
begin
-- hold reset state for 100 ns.
RESET <= '1';
wait for 100 ns;
wait for CLK_period*10.5;
RESET <= '0';
wait for CLK_period*10;
-- insert stimulus here
while True loop
wait for CLK_period*105;
wait for CLK_period*111;
START <= '1';
wait for CLK_period;
START <= '0';

View File

@ -47,9 +47,7 @@
<file xil_pn:branch="BehavioralSim" xil_pn:fileType="FILE_ISIM_EXE" xil_pn:name="Test_Sampling_isim_beh.exe"/>
<file xil_pn:branch="BehavioralSim" xil_pn:fileType="FILE_ISIM_EXE" xil_pn:name="Test_SinCos_isim_beh.exe"/>
<file xil_pn:branch="BehavioralSim" xil_pn:fileType="FILE_ISIM_EXE" xil_pn:name="Test_Sync_isim_beh.exe"/>
<file xil_pn:fileType="FILE_XST_PROJECT" xil_pn:name="Test_Window_beh.prj"/>
<file xil_pn:branch="BehavioralSim" xil_pn:fileType="FILE_ISIM_EXE" xil_pn:name="Test_Window_isim_beh.exe"/>
<file xil_pn:fileType="FILE_ISIM_MISC" xil_pn:name="Test_Window_isim_beh.wdb"/>
<file xil_pn:branch="BehavioralSim" xil_pn:fileType="FILE_ISIM_EXE" xil_pn:name="Test_top_isim_beh.exe"/>
<file xil_pn:fileType="FILE_CMD" xil_pn:name="_impact.cmd"/>
<file xil_pn:fileType="FILE_LOG" xil_pn:name="_impact.log"/>
@ -126,7 +124,7 @@
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1600256580" xil_pn:in_ck="6180625018917402544" xil_pn:name="TRAN_copyAbstractToPostAbstractSimulation" xil_pn:start_ts="1600256580">
<transform xil_pn:end_ts="1600358010" xil_pn:in_ck="6180625018917402544" xil_pn:name="TRAN_copyAbstractToPostAbstractSimulation" xil_pn:start_ts="1600358010">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<status xil_pn:value="OutOfDateForInputs"/>
@ -153,11 +151,11 @@
<outfile xil_pn:name="top.vhd"/>
<outfile xil_pn:name="window.vhd"/>
</transform>
<transform xil_pn:end_ts="1600256454" xil_pn:name="TRAN_xawsToSimhdl" xil_pn:prop_ck="7911631781232912461" xil_pn:start_ts="1600256454">
<transform xil_pn:end_ts="1600358010" xil_pn:name="TRAN_xawsToSimhdl" xil_pn:prop_ck="-1206566934435318832" xil_pn:start_ts="1600358010">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1600256454" xil_pn:name="TRAN_schematicsToHdlSim" xil_pn:prop_ck="-8348183349870037301" xil_pn:start_ts="1600256454">
<transform xil_pn:end_ts="1600358010" xil_pn:name="TRAN_schematicsToHdlSim" xil_pn:prop_ck="-273551377395144626" xil_pn:start_ts="1600358010">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
@ -172,7 +170,7 @@
<outfile xil_pn:name="ipcore_dir/SweepConfigMem.ngc"/>
<outfile xil_pn:name="ipcore_dir/SweepConfigMem.vhd"/>
</transform>
<transform xil_pn:end_ts="1600256580" xil_pn:in_ck="3204048457877733613" xil_pn:name="TRAN_copyPostAbstractToPreSimulation" xil_pn:start_ts="1600256580">
<transform xil_pn:end_ts="1600358010" xil_pn:in_ck="6180625018917402544" xil_pn:name="TRAN_copyPostAbstractToPreSimulation" xil_pn:start_ts="1600358010">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<status xil_pn:value="OutOfDateForInputs"/>
@ -196,15 +194,11 @@
<outfile xil_pn:name="Test_SinCos.vhd"/>
<outfile xil_pn:name="Test_Sync.vhd"/>
<outfile xil_pn:name="Test_Window.vhd"/>
<outfile xil_pn:name="ipcore_dir/PLL.vhd"/>
<outfile xil_pn:name="ipcore_dir/SinCos.vhd"/>
<outfile xil_pn:name="ipcore_dir/SinCosMult.vhd"/>
<outfile xil_pn:name="ipcore_dir/SweepConfigMem.vhd"/>
<outfile xil_pn:name="spi_slave.vhd"/>
<outfile xil_pn:name="top.vhd"/>
<outfile xil_pn:name="window.vhd"/>
</transform>
<transform xil_pn:end_ts="1600256582" xil_pn:in_ck="3204048457877733613" xil_pn:name="TRAN_ISimulateBehavioralModelRunFuse" xil_pn:prop_ck="-7714428255597766630" xil_pn:start_ts="1600256580">
<transform xil_pn:end_ts="1600358012" xil_pn:in_ck="3204048457877733613" xil_pn:name="TRAN_ISimulateBehavioralModelRunFuse" xil_pn:prop_ck="-3530939538078141760" xil_pn:start_ts="1600358010">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<status xil_pn:value="OutOfDateForInputs"/>
@ -213,21 +207,21 @@
<status xil_pn:value="OutOfDateForOutputs"/>
<status xil_pn:value="InputChanged"/>
<status xil_pn:value="OutputChanged"/>
<outfile xil_pn:name="Test_Window_beh.prj"/>
<outfile xil_pn:name="Test_Window_isim_beh.exe"/>
<outfile xil_pn:name="Test_MCP33131_beh.prj"/>
<outfile xil_pn:name="Test_MCP33131_isim_beh.exe"/>
<outfile xil_pn:name="fuse.log"/>
<outfile xil_pn:name="isim"/>
<outfile xil_pn:name="isim.log"/>
<outfile xil_pn:name="xilinxsim.ini"/>
</transform>
<transform xil_pn:end_ts="1600256582" xil_pn:in_ck="-6256802959996678011" xil_pn:name="TRAN_ISimulateBehavioralModel" xil_pn:prop_ck="-2271436731750578457" xil_pn:start_ts="1600256582">
<transform xil_pn:end_ts="1600358012" xil_pn:in_ck="-6256802959996678011" xil_pn:name="TRAN_ISimulateBehavioralModel" xil_pn:prop_ck="6352116336892055917" xil_pn:start_ts="1600358012">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<status xil_pn:value="OutOfDateForProperties"/>
<status xil_pn:value="OutOfDateForPredecessor"/>
<status xil_pn:value="OutOfDateForOutputs"/>
<status xil_pn:value="OutputChanged"/>
<outfile xil_pn:name="Test_Window_isim_beh.wdb"/>
<outfile xil_pn:name="Test_MCP33131_isim_beh.wdb"/>
<outfile xil_pn:name="isim.cmd"/>
<outfile xil_pn:name="isim.log"/>
</transform>
@ -266,7 +260,7 @@
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1600349756" xil_pn:in_ck="-1505308035655400832" xil_pn:name="TRANEXT_xstsynthesize_spartan6" xil_pn:prop_ck="3256065936432453276" xil_pn:start_ts="1600349735">
<transform xil_pn:end_ts="1600362196" xil_pn:in_ck="-1505308035655400832" xil_pn:name="TRANEXT_xstsynthesize_spartan6" xil_pn:prop_ck="3256065936432453276" xil_pn:start_ts="1600362176">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="WarningsGenerated"/>
<status xil_pn:value="ReadyToRun"/>
@ -288,7 +282,7 @@
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1600349762" xil_pn:in_ck="490340488621696080" xil_pn:name="TRANEXT_ngdbuild_FPGA" xil_pn:prop_ck="4604875190571501774" xil_pn:start_ts="1600349756">
<transform xil_pn:end_ts="1600362202" xil_pn:in_ck="490340488621696080" xil_pn:name="TRANEXT_ngdbuild_FPGA" xil_pn:prop_ck="4604875190571501774" xil_pn:start_ts="1600362196">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<outfile xil_pn:name="_ngo"/>
@ -297,10 +291,12 @@
<outfile xil_pn:name="top.ngd"/>
<outfile xil_pn:name="top_ngdbuild.xrpt"/>
</transform>
<transform xil_pn:end_ts="1600349804" xil_pn:in_ck="8512332261572065657" xil_pn:name="TRANEXT_map_spartan6" xil_pn:prop_ck="1448924893915930207" xil_pn:start_ts="1600349762">
<transform xil_pn:end_ts="1600362238" xil_pn:in_ck="8512332261572065657" xil_pn:name="TRANEXT_map_spartan6" xil_pn:prop_ck="1448924893915930207" xil_pn:start_ts="1600362202">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="WarningsGenerated"/>
<status xil_pn:value="ReadyToRun"/>
<status xil_pn:value="OutOfDateForOutputs"/>
<status xil_pn:value="OutputChanged"/>
<outfile xil_pn:name="_xmsgs/map.xmsgs"/>
<outfile xil_pn:name="top.pcf"/>
<outfile xil_pn:name="top_map.map"/>
@ -311,7 +307,7 @@
<outfile xil_pn:name="top_summary.xml"/>
<outfile xil_pn:name="top_usage.xml"/>
</transform>
<transform xil_pn:end_ts="1600349833" xil_pn:in_ck="1117507038335044978" xil_pn:name="TRANEXT_par_spartan6" xil_pn:prop_ck="93661965788626211" xil_pn:start_ts="1600349804">
<transform xil_pn:end_ts="1600362265" xil_pn:in_ck="1117507038335044978" xil_pn:name="TRANEXT_par_spartan6" xil_pn:prop_ck="93661965788626211" xil_pn:start_ts="1600362238">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<outfile xil_pn:name="_xmsgs/par.xmsgs"/>
@ -325,7 +321,7 @@
<outfile xil_pn:name="top_pad.txt"/>
<outfile xil_pn:name="top_par.xrpt"/>
</transform>
<transform xil_pn:end_ts="1600349846" xil_pn:in_ck="154288912438" xil_pn:name="TRANEXT_bitFile_spartan6" xil_pn:prop_ck="3274353840855015246" xil_pn:start_ts="1600349833">
<transform xil_pn:end_ts="1600362278" xil_pn:in_ck="154288912438" xil_pn:name="TRANEXT_bitFile_spartan6" xil_pn:prop_ck="3274353840855015246" xil_pn:start_ts="1600362265">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="WarningsGenerated"/>
<status xil_pn:value="ReadyToRun"/>
@ -371,7 +367,7 @@
<status xil_pn:value="OutputChanged"/>
<status xil_pn:value="OutputRemoved"/>
</transform>
<transform xil_pn:end_ts="1600349833" xil_pn:in_ck="8512326635937592693" xil_pn:name="TRAN_postRouteTrce" xil_pn:prop_ck="445577401284416184" xil_pn:start_ts="1600349826">
<transform xil_pn:end_ts="1600362265" xil_pn:in_ck="8512326635937592693" xil_pn:name="TRAN_postRouteTrce" xil_pn:prop_ck="445577401284416184" xil_pn:start_ts="1600362259">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<outfile xil_pn:name="_xmsgs/trce.xmsgs"/>

View File

@ -23,11 +23,11 @@
<association xil_pn:name="Implementation" xil_pn:seqID="0"/>
</file>
<file xil_pn:name="MCP33131.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="0"/>
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="1"/>
<association xil_pn:name="Implementation" xil_pn:seqID="10"/>
</file>
<file xil_pn:name="Test_MCP33131.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="0"/>
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="2"/>
<association xil_pn:name="PostMapSimulation" xil_pn:seqID="5"/>
<association xil_pn:name="PostRouteSimulation" xil_pn:seqID="5"/>
<association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="5"/>
@ -117,11 +117,11 @@
<association xil_pn:name="Implementation" xil_pn:seqID="5"/>
</file>
<file xil_pn:name="window.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="1"/>
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="0"/>
<association xil_pn:name="Implementation" xil_pn:seqID="1"/>
</file>
<file xil_pn:name="Test_Window.vhd" xil_pn:type="FILE_VHDL">
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="2"/>
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="0"/>
<association xil_pn:name="PostMapSimulation" xil_pn:seqID="139"/>
<association xil_pn:name="PostRouteSimulation" xil_pn:seqID="139"/>
<association xil_pn:name="PostTranslateSimulation" xil_pn:seqID="139"/>
@ -382,8 +382,8 @@
<property xil_pn:name="Run for Specified Time Translate" xil_pn:value="true" xil_pn:valueState="default"/>
<property xil_pn:name="Safe Implementation" xil_pn:value="No" xil_pn:valueState="default"/>
<property xil_pn:name="Security" xil_pn:value="Enable Readback and Reconfiguration" xil_pn:valueState="default"/>
<property xil_pn:name="Selected Module Instance Name" xil_pn:value="/Test_Window/uut" xil_pn:valueState="non-default"/>
<property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="work.window" xil_pn:valueState="non-default"/>
<property xil_pn:name="Selected Module Instance Name" xil_pn:value="/top/SPI" xil_pn:valueState="non-default"/>
<property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="work.SPICommands" xil_pn:valueState="non-default"/>
<property xil_pn:name="Selected Simulation Root Source Node Post-Map" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Selected Simulation Root Source Node Post-Route" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Selected Simulation Root Source Node Post-Translate" xil_pn:value="" xil_pn:valueState="default"/>
@ -401,7 +401,7 @@
<property xil_pn:name="Simulator" xil_pn:value="ISim (VHDL/Verilog)" xil_pn:valueState="default"/>
<property xil_pn:name="Slice Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/>
<property xil_pn:name="Specify 'define Macro Name and Value" xil_pn:value="" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Behavioral" xil_pn:value="work.window" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Behavioral" xil_pn:value="work.SPICommands" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Post-Map" xil_pn:value="Default" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Post-Route" xil_pn:value="Default" xil_pn:valueState="default"/>
<property xil_pn:name="Specify Top Level Instance Names Post-Translate" xil_pn:value="Default" xil_pn:valueState="default"/>
@ -453,7 +453,7 @@
<!-- -->
<!-- The following properties are for internal use only. These should not be modified.-->
<!-- -->
<property xil_pn:name="PROP_BehavioralSimTop" xil_pn:value="Architecture|Test_Window|behavior" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_BehavioralSimTop" xil_pn:value="Architecture|Test_MCP33131|behavior" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_DesignName" xil_pn:value="VNA" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_DevFamilyPMName" xil_pn:value="spartan6" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_FPGAConfiguration" xil_pn:value="FPGAConfiguration" xil_pn:valueState="default"/>

View File

@ -145,13 +145,12 @@ architecture Behavioral of top is
);
END COMPONENT;
COMPONENT Sampling
Generic(CLK_DIV : integer;
CLK_FREQ : integer;
IF_FREQ : integer;
CLK_CYCLES_PRE_DONE : integer);
Generic(CLK_CYCLES_PRE_DONE : integer);
PORT(
CLK : IN std_logic;
RESET : IN std_logic;
ADC_PRESCALER : in STD_LOGIC_VECTOR(7 downto 0);
PHASEINC : in STD_LOGIC_VECTOR(11 downto 0);
PORT1 : IN std_logic_vector(15 downto 0);
PORT2 : IN std_logic_vector(15 downto 0);
REF : IN std_logic_vector(15 downto 0);
@ -236,8 +235,11 @@ architecture Behavioral of top is
LO_RF_EN : out STD_LOGIC;
SOURCE_CE_EN : out STD_LOGIC;
LO_CE_EN : out STD_LOGIC;
PORTSWITCH_EN : out STD_LOGIC;
LEDS : out STD_LOGIC_VECTOR(2 downto 0);
WINDOW_SETTING : out STD_LOGIC_VECTOR(1 downto 0);
ADC_PRESCALER : out STD_LOGIC_VECTOR(7 downto 0);
ADC_PHASEINC : out STD_LOGIC_VECTOR(11 downto 0);
INTERRUPT_ASSERTED : OUT std_logic;
RESET_MINMAX : out STD_LOGIC;
SWEEP_HALTED : in STD_LOGIC;
@ -307,6 +309,8 @@ architecture Behavioral of top is
signal sampling_user_samples : std_logic_vector(9 downto 0);
signal sampling_result : std_logic_vector(287 downto 0);
signal sampling_window : std_logic_vector(1 downto 0);
signal sampling_prescaler : std_logic_vector(7 downto 0);
signal sampling_phaseinc : std_logic_vector(11 downto 0);
-- Sweep signals
signal sweep_points : std_logic_vector(12 downto 0);
@ -338,6 +342,7 @@ architecture Behavioral of top is
signal port1mix_en : std_logic;
signal port2mix_en : std_logic;
signal refmix_en : std_logic;
signal portswitch_en : std_logic;
-- PLL/SPI internal mux
signal fpga_select : std_logic;
@ -367,10 +372,10 @@ begin
LEDS(2) <= SOURCE_LD;
LEDS(3) <= LO1_LD;
-- Sweep and active port
PORT_SELECT2 <= not sweep_port_select;
PORT2_SELECT <= not sweep_port_select;
PORT_SELECT1 <= sweep_port_select;
PORT1_SELECT <= sweep_port_select;
PORT_SELECT2 <= not sweep_port_select and portswitch_en;
PORT2_SELECT <= not sweep_port_select and portswitch_en;
PORT_SELECT1 <= sweep_port_select and portswitch_en;
PORT1_SELECT <= sweep_port_select and portswitch_en;
BAND_SELECT_HIGH <= not sweep_band;
BAND_SELECT_LOW <= sweep_band;
PORT1_MIX2_EN <= port1mix_en;
@ -379,8 +384,8 @@ begin
PORT2_MIX1_EN <= not port2mix_en;
REF_MIX2_EN <= refmix_en;
REF_MIX1_EN <= not refmix_en;
LEDS(4) <= not (not sweep_reset and not sweep_port_select);
LEDS(5) <= not (not sweep_reset and sweep_port_select);
LEDS(4) <= not (not sweep_reset and not sweep_port_select and portswitch_en);
LEDS(5) <= not (not sweep_reset and sweep_port_select and portswitch_en);
-- Uncommitted LEDs
LEDS(7 downto 6) <= user_leds(1 downto 0);
--LEDS(7) <= '0';
@ -480,7 +485,7 @@ begin
Port1ADC: MCP33131
GENERIC MAP(CLK_DIV => 2,
CONVCYCLES => 73)
CONVCYCLES => 77)
PORT MAP(
CLK => clk160,
RESET => int_reset,
@ -496,7 +501,7 @@ begin
);
Port2ADC: MCP33131
GENERIC MAP(CLK_DIV => 2,
CONVCYCLES => 73)
CONVCYCLES => 77)
PORT MAP(
CLK => clk160,
RESET => int_reset,
@ -512,7 +517,7 @@ begin
);
RefADC: MCP33131
GENERIC MAP(CLK_DIV => 2,
CONVCYCLES => 73)
CONVCYCLES => 77)
PORT MAP(
CLK => clk160,
RESET => int_reset,
@ -528,13 +533,12 @@ begin
);
Sampler: Sampling
GENERIC MAP(CLK_DIV => 112,
CLK_FREQ => 102400000,
IF_FREQ => 250000,
CLK_CYCLES_PRE_DONE => 0)
GENERIC MAP(CLK_CYCLES_PRE_DONE => 0)
PORT MAP(
CLK => clk160,
RESET => sweep_reset,
ADC_PRESCALER => sampling_prescaler,
PHASEINC => sampling_phaseinc,
PORT1 => adc_port1_data,
PORT2 => adc_port2_data,
REF => adc_ref_data,
@ -648,8 +652,11 @@ begin
LO_RF_EN => LO1_RF_EN,
SOURCE_CE_EN => SOURCE_CE,
LO_CE_EN => LO1_CE,
PORTSWITCH_EN => portswitch_en,
LEDS => user_leds,
WINDOW_SETTING => sampling_window,
ADC_PRESCALER => sampling_prescaler,
ADC_PHASEINC => sampling_phaseinc,
INTERRUPT_ASSERTED => intr,
RESET_MINMAX => adc_reset_minmax,
SWEEP_HALTED => sweep_halted,

Binary file not shown.

View File

@ -189,8 +189,8 @@ SpectrumAnalyzer::SpectrumAnalyzer(AppWindow *window)
// if(pref.Startup.RememberSweepSettings) {
// LoadSweepSettings();
// } else {
settings.f_start = pref.Startup.DefaultSweep.start;
settings.f_stop = pref.Startup.DefaultSweep.stop;
settings.f_start = 950000000;
settings.f_stop = 1050000000;
ConstrainAndUpdateFrequencies();
SetRBW(10000);
settings.WindowType = 1;
@ -235,7 +235,7 @@ void SpectrumAnalyzer::SettingsChanged()
}
average.reset();
traceModel.clearVNAData();
TracePlot::UpdateSpan(settings.f_start, settings.f_stop);
emit traceModel.SpanChanged(settings.f_start, settings.f_stop);
}
void SpectrumAnalyzer::StartImpedanceMatching()

View File

@ -146,6 +146,8 @@ TraceBodePlot::TraceBodePlot(TraceModel &model, QWidget *parent)
// enable autoscaling and set for full span (no information about actual span available yet)
setXAxis(0, 6000000000);
setXAxis(true, 0, 6000000000, 600000000);
// get notified when the span changes
connect(&model, &TraceModel::SpanChanged, this, qOverload<double, double>(&TraceBodePlot::setXAxis));
}
TraceBodePlot::~TraceBodePlot()

View File

@ -25,7 +25,9 @@ public:
std::vector<Trace*> getTraces();
bool PortExcitationRequired(int port);
signals:
void SpanChanged(double fmin, double fmax);
void traceAdded(Trace *t);
void traceRemoved(Trace *t);
void requiredExcitation(bool excitePort1, bool excitePort2);

View File

@ -48,13 +48,6 @@ void TracePlot::mouseDoubleClickEvent(QMouseEvent *) {
emit doubleClicked(this);
}
void TracePlot::UpdateSpan(double fmin, double fmax)
{
for(auto p : plots) {
p->setXAxis(fmin, fmax);
}
}
void TracePlot::initializeTraceInfo(TraceModel &model)
{
// Populate already present traces

View File

@ -19,7 +19,6 @@ public:
virtual void setXAxis(double min, double max){Q_UNUSED(min);Q_UNUSED(max)};
static std::set<TracePlot *> getPlots();
static void UpdateSpan(double fmin, double fmax);
signals:
void doubleClicked(QWidget *w);

View File

@ -544,7 +544,7 @@ void VNA::SettingsChanged()
average.reset();
traceModel.clearVNAData();
UpdateStatusPanel();
TracePlot::UpdateSpan(settings.f_start, settings.f_stop);
emit traceModel.SpanChanged(settings.f_start, settings.f_stop);
}
void VNA::StartImpedanceMatching()

View File

@ -21,7 +21,7 @@ static void SwitchBytes(int16_t &value) {
value = (value & 0xFF00) >> 8 | (value & 0x00FF) << 8;
}
void WriteRegister(FPGA::Reg reg, uint16_t value) {
void FPGA::WriteRegister(FPGA::Reg reg, uint16_t value) {
uint8_t cmd[4] = {0x80, (uint8_t) reg, (uint8_t) (value >> 8), (uint8_t) (value & 0xFF)};
Low(CS);
HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) cmd, 4, 100);

View File

@ -12,7 +12,8 @@ enum class Reg {
SweepPoints = 0x01,
SamplesPerPoint = 0x02,
SystemControl = 0x03,
SettlingTime = 0x04,
ADCPrescaler = 0x04,
PhaseIncrement = 0x05,
MAX2871Def0LSB = 0x08,
MAX2871Def0MSB = 0x09,
MAX2871Def1LSB = 0x0A,
@ -49,6 +50,7 @@ enum class Periphery {
LO1Chip = 0x0008,
ExcitePort2 = 0x0004,
ExcitePort1 = 0x0002,
PortSwitch = 0x0001,
};
enum class Interrupt {
@ -96,6 +98,7 @@ bool Configure(Flash *f, uint32_t start_address, uint32_t bitstream_size);
using HaltedCallback = void(*)(void);
bool Init(HaltedCallback cb = nullptr);
void WriteRegister(FPGA::Reg reg, uint16_t value);
void SetNumberOfPoints(uint16_t npoints);
void SetSamplesPerPoint(uint32_t nsamples);
void Enable(Periphery p, bool enable = true);

View File

@ -119,6 +119,10 @@ bool HW::Init(WorkRequest wr) {
return false;
}
// Set default ADC samplerate
FPGA::WriteRegister(FPGA::Reg::ADCPrescaler, 112);
FPGA::WriteRegister(FPGA::Reg::PhaseIncrement, 1120);
// Enable new data and sweep halt interrupt
FPGA::EnableInterrupt(FPGA::Interrupt::NewData);
FPGA::EnableInterrupt(FPGA::Interrupt::SweepHalted);
@ -211,6 +215,7 @@ void HW::SetIdle() {
FPGA::Enable(FPGA::Periphery::Port1Mixer, false);
FPGA::Enable(FPGA::Periphery::Port2Mixer, false);
FPGA::Enable(FPGA::Periphery::RefMixer, false);
FPGA::Enable(FPGA::Periphery::PortSwitch, false);
}
void HW::fillDeviceInfo(Protocol::DeviceInfo *info) {

View File

@ -71,6 +71,7 @@ void Manual::Setup(Protocol::ManualControl m) {
FPGA::Enable(FPGA::Periphery::RefMixer, m.RefEN);
FPGA::Enable(FPGA::Periphery::ExcitePort1, m.PortSwitch == 0);
FPGA::Enable(FPGA::Periphery::ExcitePort2, m.PortSwitch == 1);
FPGA::Enable(FPGA::Periphery::PortSwitch);
active = true;
FPGA::StartSweep();

View File

@ -17,6 +17,7 @@ static uint8_t signalIDstep;
static uint32_t sampleNum;
static Protocol::PacketInfo p;
static bool active = false;
static uint32_t lastLO2;
static float port1Measurement, port2Measurement;
@ -32,30 +33,44 @@ static void StartNextSample() {
// reset minimum amplitudes in first signal ID step
port1Measurement = std::numeric_limits<float>::max();
port2Measurement = std::numeric_limits<float>::max();
// Use default LO frequencies
LO1freq = freq + HW::IF1;
LO2freq = HW::IF1 - HW::IF2;
FPGA::WriteRegister(FPGA::Reg::ADCPrescaler, 112);
FPGA::WriteRegister(FPGA::Reg::PhaseIncrement, 1120);
break;
case 1:
// Shift first LO to other side
LO1freq = freq - HW::IF1;
LO2freq = HW::IF1 - HW::IF2;
break;
case 2:
// Shift both LOs to other side
LO1freq = freq + HW::IF1;
LO2freq = HW::IF1 + HW::IF2;
break;
case 3:
// Shift second LO to other side
LO1freq = freq - HW::IF1;
LO2freq = HW::IF1 + HW::IF2;
break;
case 4:
// Use default frequencies with different ADC samplerate to remove images in final IF
LO1freq = freq + HW::IF1;
LO2freq = HW::IF1 - HW::IF2;
FPGA::WriteRegister(FPGA::Reg::ADCPrescaler, 120);
FPGA::WriteRegister(FPGA::Reg::PhaseIncrement, 1200);
}
LO1.SetFrequency(LO1freq);
// LO1 is not able to reach all frequencies with the required precision, adjust LO2 to account for deviation
int32_t LO1deviation = (int64_t) LO1.GetActualFrequency() - LO1freq;
LO2freq += LO1deviation;
// Adjust LO2 PLL
// Generate second LO with Si5351
Si5351.SetCLK(SiChannel::Port1LO2, LO2freq, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
Si5351.SetCLK(SiChannel::Port2LO2, LO2freq, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
// only adjust LO2 PLL if necessary (if the deviation is significantly less than the RBW it does not matter)
if((uint32_t) abs(LO2freq - lastLO2) > s.RBW / 2) {
Si5351.SetCLK(SiChannel::Port1LO2, LO2freq, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
Si5351.SetCLK(SiChannel::Port2LO2, LO2freq, Si5351C::PLL::B, Si5351C::DriveStrength::mA2);
lastLO2 = LO2freq;
}
// Configure the sampling in the FPGA
FPGA::WriteSweepConfig(0, 0, Source.GetRegisters(), LO1.GetRegisters(), 0,
0, FPGA::SettlingTime::us20, FPGA::Samples::SPPRegister, 0,
@ -74,7 +89,7 @@ void SA::Setup(Protocol::SpectrumAnalyzerSettings settings) {
// individually start each point and do the sweep in the uC
FPGA::SetNumberOfPoints(1);
// calculate amount of required points
points = (s.f_stop - s.f_start) / s.RBW;
points = 2 * (s.f_stop - s.f_start) / s.RBW;
// adjust to integer multiple of requested result points (in order to have the same amount of measurements in each bin)
points += s.pointNum - points % s.pointNum;
binSize = points / s.pointNum;
@ -97,6 +112,7 @@ void SA::Setup(Protocol::SpectrumAnalyzerSettings settings) {
FPGA::Enable(FPGA::Periphery::ExcitePort1);
FPGA::Enable(FPGA::Periphery::Port1Mixer);
FPGA::Enable(FPGA::Periphery::Port2Mixer);
lastLO2 = 0;
active = true;
StartNextSample();
}
@ -121,7 +137,7 @@ void SA::Work() {
if(!active) {
return;
}
if(!s.SignalID || signalIDstep >= 3) {
if(!s.SignalID || signalIDstep >= 4) {
// this measurement point is done, handle result according to detector
uint16_t binIndex = pointCnt / binSize;
uint32_t pointInBin = pointCnt % binSize;

View File

@ -165,6 +165,7 @@ bool VNA::Setup(Protocol::SweepSettings s, SweepCallback cb) {
FPGA::Enable(FPGA::Periphery::LO1RF);
FPGA::Enable(FPGA::Periphery::ExcitePort1, s.excitePort1);
FPGA::Enable(FPGA::Periphery::ExcitePort2, s.excitePort2);
FPGA::Enable(FPGA::Periphery::PortSwitch);
pointCnt = 0;
// starting port depends on whether port 1 is active in sweep
excitingPort1 = s.excitePort1;

View File

@ -244,7 +244,7 @@ static void MX_I2C2_Init(void)
/* USER CODE END I2C2_Init 1 */
hi2c2.Instance = I2C2;
hi2c2.Init.Timing = 0x20B0D9FF;
hi2c2.Init.Timing = 0x00E057FD;
hi2c2.Init.OwnAddress1 = 0;
hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

View File

@ -85,8 +85,9 @@ FREERTOS.configENABLE_BACKWARD_COMPATIBILITY=1
FREERTOS.configTOTAL_HEAP_SIZE=2048
FREERTOS.configUSE_MUTEXES=1
File.Version=6
I2C2.IPParameters=Timing
I2C2.Timing=0x20B0D9FF
I2C2.I2C_Speed_Mode=I2C_Fast
I2C2.IPParameters=Timing,I2C_Speed_Mode
I2C2.Timing=0x00E057FD
KeepUserPlacement=false
Mcu.Family=STM32G4
Mcu.IP0=DMA