different settling time/samples per point in sweep

This commit is contained in:
Jan Käberich 2020-09-14 11:03:37 +02:00
parent aae01a602e
commit 7d9d5e27eb
8 changed files with 147 additions and 114 deletions

View File

@ -45,12 +45,11 @@ entity SPICommands is
MAX2871_DEF_3 : out STD_LOGIC_VECTOR (31 downto 0);
MAX2871_DEF_1 : out STD_LOGIC_VECTOR (31 downto 0);
MAX2871_DEF_0 : out STD_LOGIC_VECTOR (31 downto 0);
SWEEP_DATA : out STD_LOGIC_VECTOR (111 downto 0);
SWEEP_DATA : out STD_LOGIC_VECTOR (95 downto 0);
SWEEP_ADDRESS : out STD_LOGIC_VECTOR (12 downto 0);
SWEEP_WRITE : out STD_LOGIC_VECTOR (0 downto 0);
SWEEP_POINTS : out STD_LOGIC_VECTOR (12 downto 0);
NSAMPLES : out STD_LOGIC_VECTOR (16 downto 0);
SETTLING_TIME : out STD_LOGIC_VECTOR (15 downto 0);
NSAMPLES : out STD_LOGIC_VECTOR (9 downto 0);
EXCITE_PORT1 : out STD_LOGIC;
EXCITE_PORT2 : out STD_LOGIC;
PORT1_EN : out STD_LOGIC;
@ -62,7 +61,7 @@ entity SPICommands is
SOURCE_CE_EN : out STD_LOGIC;
LO_CE_EN : out STD_LOGIC;
LEDS : out STD_LOGIC_VECTOR(2 downto 0);
SYNC_SETTING : out STD_LOGIC_VECTOR(1 downto 0);
WINDOW_SETTING : out STD_LOGIC_VECTOR(1 downto 0);
INTERRUPT_ASSERTED : out STD_LOGIC;
RESET_MINMAX : out STD_LOGIC;
SWEEP_HALTED : in STD_LOGIC;
@ -102,7 +101,7 @@ architecture Behavioral of SPICommands is
signal interrupt_status : std_logic_vector(15 downto 0);
signal latched_result : std_logic_vector(271 downto 0);
signal sweepconfig_buffer : std_logic_vector(95 downto 0);
signal sweepconfig_buffer : std_logic_vector(79 downto 0);
begin
SPI: spi_slave
GENERIC MAP(w => 16)
@ -131,7 +130,7 @@ begin
data_overrun <= '0';
SWEEP_POINTS <= (others => '0');
NSAMPLES <= (others => '0');
SETTLING_TIME <= (others => '0');
--SETTLING_TIME <= (others => '0');
PORT1_EN <= '0';
PORT2_EN <= '0';
REF_EN <= '0';
@ -141,7 +140,7 @@ begin
SOURCE_CE_EN <= '0';
LO_CE_EN <= '0';
LEDS <= (others => '1');
SYNC_SETTING <= "00";
WINDOW_SETTING <= "00";
unread_sampling_data <= '0';
interrupt_mask <= (others => '0');
RESET_MINMAX <= '0';
@ -191,8 +190,8 @@ begin
case selected_register is
when 0 => interrupt_mask <= spi_buf_out;
when 1 => SWEEP_POINTS <= spi_buf_out(12 downto 0);
when 2 => NSAMPLES(15 downto 0) <= spi_buf_out;
when 3 => NSAMPLES(16) <= spi_buf_out(0);
when 2 => NSAMPLES <= spi_buf_out(9 downto 0);
when 3 => --NSAMPLES(16) <= spi_buf_out(0);
PORT1_EN <= spi_buf_out(15);
PORT2_EN <= spi_buf_out(14);
REF_EN <= spi_buf_out(13);
@ -200,12 +199,12 @@ begin
SOURCE_RF_EN <= spi_buf_out(11);
LO_RF_EN <= spi_buf_out(10);
LEDS <= not spi_buf_out(9 downto 7);
SYNC_SETTING <= spi_buf_out(6 downto 5);
WINDOW_SETTING <= spi_buf_out(6 downto 5);
SOURCE_CE_EN <= spi_buf_out(4);
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 => SETTLING_TIME <= spi_buf_out;
when 8 => MAX2871_DEF_0(15 downto 0) <= spi_buf_out;
when 9 => MAX2871_DEF_0(31 downto 16) <= spi_buf_out;
@ -219,13 +218,13 @@ begin
end case;
selected_register <= selected_register + 1;
elsif state = WriteSweepConfig then
if word_cnt = 7 then
if word_cnt = 6 then
-- Sweep config data is complete pass on
SWEEP_DATA <= sweepconfig_buffer & spi_buf_out;
sweep_config_write <= '1';
else
-- shift next word into buffer
sweepconfig_buffer <= sweepconfig_buffer(79 downto 0) & spi_buf_out;
sweepconfig_buffer <= sweepconfig_buffer(63 downto 0) & spi_buf_out;
end if;
elsif state = ReadResult then
-- pass on next word of latched result

View File

@ -44,7 +44,7 @@ entity Sampling is
DONE : out STD_LOGIC;
PRE_DONE : out STD_LOGIC;
START : in STD_LOGIC;
SAMPLES : in STD_LOGIC_VECTOR (16 downto 0);
SAMPLES : in STD_LOGIC_VECTOR (9 downto 0);
PORT1_I : out STD_LOGIC_VECTOR (47 downto 0);
PORT1_Q : out STD_LOGIC_VECTOR (47 downto 0);
PORT2_I : out STD_LOGIC_VECTOR (47 downto 0);
@ -80,6 +80,7 @@ END COMPONENT;
signal r_Q : signed(47 downto 0);
signal clk_cnt : integer range 0 to CLK_DIV - 1;
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);
@ -194,6 +195,7 @@ begin
phase <= (others => '0');
if START = '1' then
state <= Sampling;
samples_to_take <= to_integer(unsigned(SAMPLES & "0000000"));
end if;
when Sampling =>
DONE <= '0';
@ -220,7 +222,7 @@ begin
DONE <= '0';
PRE_DONE <= '0';
phase <= std_logic_vector(unsigned(phase) + phase_inc);
if sample_cnt < unsigned(SAMPLES) then
if sample_cnt < samples_to_take then
sample_cnt <= sample_cnt + 1;
state <= Sampling;
else

View File

@ -34,7 +34,9 @@ entity Sweep is
RESET : in STD_LOGIC;
NPOINTS : in STD_LOGIC_VECTOR (12 downto 0);
CONFIG_ADDRESS : out STD_LOGIC_VECTOR (12 downto 0);
CONFIG_DATA : in STD_LOGIC_VECTOR (111 downto 0);
CONFIG_DATA : in STD_LOGIC_VECTOR (95 downto 0);
USER_NSAMPLES : in STD_LOGIC_VECTOR (9 downto 0);
NSAMPLES : out STD_LOGIC_VECTOR (9 downto 0);
SAMPLING_BUSY : in STD_LOGIC;
SAMPLING_DONE : in STD_LOGIC;
START_SAMPLING : out STD_LOGIC;
@ -63,7 +65,7 @@ entity Sweep is
ATTENUATOR : out STD_LOGIC_VECTOR(6 downto 0);
SOURCE_FILTER : out STD_LOGIC_VECTOR(1 downto 0);
SETTLING_TIME : in STD_LOGIC_VECTOR (15 downto 0);
--SETTLING_TIME : in STD_LOGIC_VECTOR (15 downto 0);
EXCITE_PORT1 : in STD_LOGIC;
EXCITE_PORT2 : in STD_LOGIC;
@ -78,40 +80,47 @@ architecture Behavioral of Sweep is
type Point_states is (TriggerSetup, SettingUp, SettlingPort1, ExcitingPort1, SettlingPort2, ExcitingPort2, Done);
signal state : Point_states;
signal settling_cnt : unsigned(15 downto 0);
signal settling_time : unsigned(15 downto 0);
begin
CONFIG_ADDRESS <= std_logic_vector(point_cnt);
-- assemble registers
-- sweep config content:
-- 15 downto 0: Source N divider
-- 27 downto 16: Source Frac
-- 39 downto 28: Source M
-- 45 downto 40: Source VCO selection
-- 48 downto 46: Source DIVA
-- 55 downto 49: Attenuator selection
-- 71 downto 56: LO N divider
-- 83 downto 72: LO Frac
-- 95 downto 84: LO M
-- 101 downto 96: LO VCO selection
-- 104 downto 102: LO DIVA
-- 106 downto 105: Source filter selection
-- 111 downto 107: reserved
SOURCE_REG_0 <= MAX2871_DEF_0(31) & CONFIG_DATA(15 downto 0) & CONFIG_DATA(27 downto 16) & "000";
-- source register 0: N divider and fractional division value
SOURCE_REG_0 <= MAX2871_DEF_0(31) & "000000000" & CONFIG_DATA(6 downto 0) & CONFIG_DATA(27 downto 16) & "000";
-- source register 1: Modulus value
SOURCE_REG_1 <= MAX2871_DEF_1(31 downto 15) & CONFIG_DATA(39 downto 28) & "001";
SOURCE_REG_3 <= CONFIG_DATA(45 downto 40) & MAX2871_DEF_3(25 downto 3) & "011";
-- source register 3: VCO selection
SOURCE_REG_3 <= CONFIG_DATA(12 downto 7) & MAX2871_DEF_3(25 downto 3) & "011";
-- output power A passed on from default registers, output B disabled
SOURCE_REG_4 <= MAX2871_DEF_4(31 downto 23) & CONFIG_DATA(48 downto 46) & MAX2871_DEF_4(19 downto 9) & "000" & MAX2871_DEF_4(5 downto 3) & "100";
SOURCE_REG_4 <= MAX2871_DEF_4(31 downto 23) & CONFIG_DATA(15 downto 13) & MAX2871_DEF_4(19 downto 9) & "000" & MAX2871_DEF_4(5 downto 3) & "100";
LO_REG_0 <= MAX2871_DEF_0(31) & CONFIG_DATA(71 downto 56) & CONFIG_DATA(83 downto 72) & "000";
LO_REG_1 <= MAX2871_DEF_1(31 downto 15) & CONFIG_DATA(95 downto 84) & "001";
LO_REG_3 <= CONFIG_DATA(101 downto 96) & MAX2871_DEF_3(25 downto 3) & "011";
-- LO register 0: N divider and fractional division value
LO_REG_0 <= MAX2871_DEF_0(31) & "000000000" & CONFIG_DATA(54 downto 48) & CONFIG_DATA(75 downto 64) & "000";
-- LO register 1: Modulus value
LO_REG_1 <= MAX2871_DEF_1(31 downto 15) & CONFIG_DATA(87 downto 76) & "001";
-- LO register 3: VCO selection
LO_REG_3 <= CONFIG_DATA(60 downto 55) & MAX2871_DEF_3(25 downto 3) & "011";
-- both outputs enabled at -1dbm
LO_REG_4 <= MAX2871_DEF_4(31 downto 23) & CONFIG_DATA(104 downto 102) & MAX2871_DEF_4(19 downto 9) & "101101100";
LO_REG_4 <= MAX2871_DEF_4(31 downto 23) & CONFIG_DATA(63 downto 61) & MAX2871_DEF_4(19 downto 9) & "101101100";
ATTENUATOR <= CONFIG_DATA(55 downto 49);
SOURCE_FILTER <= CONFIG_DATA(106 downto 105);
BAND_SELECT <= CONFIG_DATA(110);
ATTENUATOR <= CONFIG_DATA(46 downto 40);
SOURCE_FILTER <= CONFIG_DATA(89 downto 88);
BAND_SELECT <= CONFIG_DATA(47);
settling_time <= to_unsigned(2048, 16) when CONFIG_DATA(94 downto 93) = "00" else -- 20us
to_unsigned(6144, 16) when CONFIG_DATA(94 downto 93) = "01" else -- 60us
to_unsigned(18432, 16) when CONFIG_DATA(94 downto 93) = "10" else -- 180us
to_unsigned(55296, 16); -- 540us
NSAMPLES <= USER_NSAMPLES when CONFIG_DATA(92 downto 90) = "000" else
std_logic_vector(to_unsigned(1, 10)) when CONFIG_DATA(92 downto 90) = "001" else
std_logic_vector(to_unsigned(3, 10)) when CONFIG_DATA(92 downto 90) = "010" else
std_logic_vector(to_unsigned(7, 10)) when CONFIG_DATA(92 downto 90) = "011" else
std_logic_vector(to_unsigned(24, 10)) when CONFIG_DATA(92 downto 90) = "100" else
std_logic_vector(to_unsigned(71, 10)) when CONFIG_DATA(92 downto 90) = "101" else
std_logic_vector(to_unsigned(238, 10)) when CONFIG_DATA(92 downto 90) = "110" else
std_logic_vector(to_unsigned(714, 10));
DEBUG_STATUS(10 downto 8) <= "000" when state = TriggerSetup else
"001" when state = SettingUp else
@ -134,6 +143,7 @@ begin
state <= TriggerSetup;
START_SAMPLING <= '0';
RELOAD_PLL_REGS <= '0';
SWEEP_HALTED <= '0';
else
case state is
when TriggerSetup =>
@ -143,11 +153,11 @@ begin
end if;
when SettingUp =>
-- highest bit in CONFIG_DATA determines whether the sweep should be halted prior to sampling
SWEEP_HALTED <= CONFIG_DATA(111);
SWEEP_HALTED <= CONFIG_DATA(95);
RELOAD_PLL_REGS <= '0';
if PLL_RELOAD_DONE = '1' and PLL_LOCKED = '1' then
-- check if halted sweep is resumed
if CONFIG_DATA(111) = '0' or SWEEP_RESUME = '1' then
if CONFIG_DATA(95) = '0' or SWEEP_RESUME = '1' then
SWEEP_HALTED <= '0';
if EXCITE_PORT1 = '1' then
state <= SettlingPort1;
@ -156,7 +166,7 @@ begin
else
state <= Done;
end if;
settling_cnt <= unsigned(SETTLING_TIME);
settling_cnt <= settling_time;
end if;
end if;
when SettlingPort1 =>

View File

@ -142,6 +142,10 @@
<transform xil_pn:end_ts="1589440643" xil_pn:in_ck="-6165752171532536899" xil_pn:name="TRAN_regenerateCoresSim" xil_pn:prop_ck="-2723611991789822717" xil_pn:start_ts="1589440643">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<status xil_pn:value="OutOfDateForInputs"/>
<status xil_pn:value="OutOfDateForOutputs"/>
<status xil_pn:value="InputChanged"/>
<status xil_pn:value="OutputChanged"/>
<outfile xil_pn:name="ipcore_dir/PLL.vhd"/>
<outfile xil_pn:name="ipcore_dir/SinCos.ngc"/>
<outfile xil_pn:name="ipcore_dir/SinCos.vhd"/>
@ -192,7 +196,7 @@
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1589439388" xil_pn:in_ck="-6165752171532536899" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="-2723611991789822717" xil_pn:start_ts="1589439388">
<transform xil_pn:end_ts="1600073548" xil_pn:in_ck="-6165752171532536899" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="-2723611991789822717" xil_pn:start_ts="1600073547">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<outfile xil_pn:name="ipcore_dir/PLL.vhd"/>
@ -219,7 +223,7 @@
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1598796981" xil_pn:in_ck="-94812602667091528" xil_pn:name="TRANEXT_xstsynthesize_spartan6" xil_pn:prop_ck="3256065936432453276" xil_pn:start_ts="1598796963">
<transform xil_pn:end_ts="1600073684" xil_pn:in_ck="-94812602667091528" xil_pn:name="TRANEXT_xstsynthesize_spartan6" xil_pn:prop_ck="3256065936432453276" xil_pn:start_ts="1600073666">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="WarningsGenerated"/>
<status xil_pn:value="ReadyToRun"/>
@ -241,7 +245,7 @@
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1598796987" xil_pn:in_ck="490340488621696080" xil_pn:name="TRANEXT_ngdbuild_FPGA" xil_pn:prop_ck="4604875190571501774" xil_pn:start_ts="1598796981">
<transform xil_pn:end_ts="1600073692" xil_pn:in_ck="490340488621696080" xil_pn:name="TRANEXT_ngdbuild_FPGA" xil_pn:prop_ck="4604875190571501774" xil_pn:start_ts="1600073686">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<outfile xil_pn:name="_ngo"/>
@ -250,7 +254,7 @@
<outfile xil_pn:name="top.ngd"/>
<outfile xil_pn:name="top_ngdbuild.xrpt"/>
</transform>
<transform xil_pn:end_ts="1598797045" xil_pn:in_ck="8512332261572065657" xil_pn:name="TRANEXT_map_spartan6" xil_pn:prop_ck="1448924893915930207" xil_pn:start_ts="1598796987">
<transform xil_pn:end_ts="1600073728" xil_pn:in_ck="8512332261572065657" xil_pn:name="TRANEXT_map_spartan6" xil_pn:prop_ck="1448924893915930207" xil_pn:start_ts="1600073692">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="WarningsGenerated"/>
<status xil_pn:value="ReadyToRun"/>
@ -266,7 +270,7 @@
<outfile xil_pn:name="top_summary.xml"/>
<outfile xil_pn:name="top_usage.xml"/>
</transform>
<transform xil_pn:end_ts="1598797075" xil_pn:in_ck="1117507038335044978" xil_pn:name="TRANEXT_par_spartan6" xil_pn:prop_ck="93661965788626211" xil_pn:start_ts="1598797045">
<transform xil_pn:end_ts="1600073755" xil_pn:in_ck="1117507038335044978" xil_pn:name="TRANEXT_par_spartan6" xil_pn:prop_ck="93661965788626211" xil_pn:start_ts="1600073728">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<outfile xil_pn:name="_xmsgs/par.xmsgs"/>
@ -280,7 +284,7 @@
<outfile xil_pn:name="top_pad.txt"/>
<outfile xil_pn:name="top_par.xrpt"/>
</transform>
<transform xil_pn:end_ts="1598797089" xil_pn:in_ck="154288912438" xil_pn:name="TRANEXT_bitFile_spartan6" xil_pn:prop_ck="4970201210546912173" xil_pn:start_ts="1598797075">
<transform xil_pn:end_ts="1600073768" xil_pn:in_ck="154288912438" xil_pn:name="TRANEXT_bitFile_spartan6" xil_pn:prop_ck="4970201210546912173" xil_pn:start_ts="1600073755">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="WarningsGenerated"/>
<status xil_pn:value="ReadyToRun"/>
@ -326,7 +330,7 @@
<status xil_pn:value="OutputChanged"/>
<status xil_pn:value="OutputRemoved"/>
</transform>
<transform xil_pn:end_ts="1598797075" xil_pn:in_ck="8512326635937592693" xil_pn:name="TRAN_postRouteTrce" xil_pn:prop_ck="445577401284416184" xil_pn:start_ts="1598797068">
<transform xil_pn:end_ts="1600073755" xil_pn:in_ck="8512326635937592693" xil_pn:name="TRAN_postRouteTrce" xil_pn:prop_ck="445577401284416184" xil_pn:start_ts="1600073748">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
<outfile xil_pn:name="_xmsgs/trce.xmsgs"/>

View File

@ -111,7 +111,9 @@ architecture Behavioral of top is
CLK : IN std_logic;
RESET : IN std_logic;
NPOINTS : IN std_logic_vector(12 downto 0);
CONFIG_DATA : IN std_logic_vector(111 downto 0);
CONFIG_DATA : IN std_logic_vector(95 downto 0);
USER_NSAMPLES : in STD_LOGIC_VECTOR (9 downto 0);
NSAMPLES : out STD_LOGIC_VECTOR (9 downto 0);
SAMPLING_BUSY : in STD_LOGIC;
SAMPLING_DONE : IN std_logic;
MAX2871_DEF_4 : IN std_logic_vector(31 downto 0);
@ -119,8 +121,7 @@ architecture Behavioral of top is
MAX2871_DEF_1 : IN std_logic_vector(31 downto 0);
MAX2871_DEF_0 : IN std_logic_vector(31 downto 0);
PLL_RELOAD_DONE : IN std_logic;
PLL_LOCKED : IN std_logic;
SETTLING_TIME : IN std_logic_vector(15 downto 0);
PLL_LOCKED : IN std_logic;
CONFIG_ADDRESS : OUT std_logic_vector(12 downto 0);
START_SAMPLING : OUT std_logic;
PORT_SELECT : OUT std_logic;
@ -138,8 +139,8 @@ architecture Behavioral of top is
SWEEP_RESUME : in STD_LOGIC;
ATTENUATOR : OUT std_logic_vector(6 downto 0);
SOURCE_FILTER : OUT std_logic_vector(1 downto 0);
EXCITE_PORT1 : out STD_LOGIC;
EXCITE_PORT2 : out STD_LOGIC;
EXCITE_PORT1 : in STD_LOGIC;
EXCITE_PORT2 : in STD_LOGIC;
DEBUG_STATUS : out STD_LOGIC_VECTOR (10 downto 0)
);
END COMPONENT;
@ -156,7 +157,7 @@ architecture Behavioral of top is
REF : IN std_logic_vector(15 downto 0);
NEW_SAMPLE : IN std_logic;
START : IN std_logic;
SAMPLES : IN std_logic_vector(16 downto 0);
SAMPLES : IN std_logic_vector(9 downto 0);
ADC_START : OUT std_logic;
DONE : OUT std_logic;
PRE_DONE : OUT std_logic;
@ -219,12 +220,11 @@ architecture Behavioral of top is
MAX2871_DEF_3 : OUT std_logic_vector(31 downto 0);
MAX2871_DEF_1 : OUT std_logic_vector(31 downto 0);
MAX2871_DEF_0 : OUT std_logic_vector(31 downto 0);
SWEEP_DATA : OUT std_logic_vector(111 downto 0);
SWEEP_DATA : OUT std_logic_vector(95 downto 0);
SWEEP_ADDRESS : OUT std_logic_vector(12 downto 0);
SWEEP_WRITE : OUT std_logic_vector(0 to 0);
SWEEP_POINTS : OUT std_logic_vector(12 downto 0);
NSAMPLES : OUT std_logic_vector(16 downto 0);
SETTLING_TIME : out STD_LOGIC_VECTOR (15 downto 0);
NSAMPLES : OUT std_logic_vector(9 downto 0);
EXCITE_PORT1 : out STD_LOGIC;
EXCITE_PORT2 : out STD_LOGIC;
PORT1_EN : out STD_LOGIC;
@ -236,7 +236,7 @@ architecture Behavioral of top is
SOURCE_CE_EN : out STD_LOGIC;
LO_CE_EN : out STD_LOGIC;
LEDS : out STD_LOGIC_VECTOR(2 downto 0);
SYNC_SETTING : out STD_LOGIC_VECTOR(1 downto 0);
WINDOW_SETTING : out STD_LOGIC_VECTOR(1 downto 0);
INTERRUPT_ASSERTED : OUT std_logic;
RESET_MINMAX : out STD_LOGIC;
SWEEP_HALTED : in STD_LOGIC;
@ -251,10 +251,10 @@ architecture Behavioral of top is
ena : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(111 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(95 DOWNTO 0);
clkb : IN STD_LOGIC;
addrb : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(111 DOWNTO 0)
doutb : OUT STD_LOGIC_VECTOR(95 DOWNTO 0)
);
END COMPONENT;
@ -302,18 +302,19 @@ architecture Behavioral of top is
signal sampling_busy : std_logic;
signal sampling_done : std_logic;
signal sampling_start : std_logic;
signal sampling_samples : std_logic_vector(16 downto 0);
signal sampling_samples : std_logic_vector(9 downto 0);
signal sampling_user_samples : std_logic_vector(9 downto 0);
signal sampling_result : std_logic_vector(287 downto 0);
-- Sweep signals
signal sweep_points : std_logic_vector(12 downto 0);
signal sweep_config_data : std_logic_vector(111 downto 0);
signal sweep_config_data : std_logic_vector(95 downto 0);
signal sweep_config_address : std_logic_vector(12 downto 0);
signal source_filter : std_logic_vector(1 downto 0);
signal sweep_port_select : std_logic;
signal sweep_config_write_address : std_logic_vector(12 downto 0);
signal sweep_config_write_data : std_logic_vector(111 downto 0);
signal sweep_config_write_data : std_logic_vector(95 downto 0);
signal sweep_config_write : std_logic_vector(0 downto 0);
signal sweep_reset : std_logic;
@ -558,6 +559,8 @@ begin
NPOINTS => sweep_points,
CONFIG_ADDRESS => sweep_config_address,
CONFIG_DATA => sweep_config_data,
USER_NSAMPLES => sampling_user_samples,
NSAMPLES => sampling_user_samples,
SAMPLING_BUSY => sampling_busy,
SAMPLING_DONE => sampling_done,
START_SAMPLING => sampling_start,
@ -582,7 +585,6 @@ begin
SWEEP_RESUME => sweep_resume,
ATTENUATOR => ATTENUATION,
SOURCE_FILTER => source_filter,
SETTLING_TIME => settling_time,
EXCITE_PORT1 => sweep_excite_port1,
EXCITE_PORT2 => sweep_excite_port2,
DEBUG_STATUS => debug
@ -632,7 +634,6 @@ begin
SWEEP_WRITE => sweep_config_write,
SWEEP_POINTS => sweep_points,
NSAMPLES => sampling_samples,
SETTLING_TIME => settling_time,
PORT1_EN => port1mix_en,
PORT2_EN => port2mix_en,
REF_EN => refmix_en,
@ -642,7 +643,7 @@ begin
SOURCE_CE_EN => SOURCE_CE,
LO_CE_EN => LO1_CE,
LEDS => user_leds,
SYNC_SETTING => open,
WINDOW_SETTING => open,
INTERRUPT_ASSERTED => intr,
RESET_MINMAX => adc_reset_minmax,
SWEEP_HALTED => sweep_halted,

View File

@ -95,23 +95,11 @@ void FPGA::SetNumberOfPoints(uint16_t npoints) {
}
void FPGA::SetSamplesPerPoint(uint32_t nsamples) {
// register has to be set to number of nsamples - 1
nsamples--;
// register is in multiples of 128
nsamples /= 128;
// constrain to maximum value
nsamples &= 0x1FFFF;
// highest bit is located at the system control register
SysCtrlReg &= ~0x0001;
SysCtrlReg |= nsamples >> 16;
WriteRegister(Reg::SystemControl, SysCtrlReg);
WriteRegister(Reg::SamplesPerPoint, nsamples & 0xFFFF);
}
void FPGA::SetSettlingTime(uint16_t us) {
if (us > 639) {
us = 639;
}
uint16_t regval = (uint32_t) us * 1024 / 10;
WriteRegister(Reg::SettlingTime, regval);
nsamples &= 0x03FF;
WriteRegister(Reg::SamplesPerPoint, nsamples);
}
void FPGA::Enable(Periphery p, bool enable) {
@ -150,42 +138,53 @@ void FPGA::WriteMAX2871Default(uint32_t *DefaultRegs) {
}
void FPGA::WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceRegs, uint32_t *LORegs,
uint8_t attenuation, uint64_t frequency, bool halt, LowpassFilter filter) {
uint16_t send[8];
uint8_t attenuation, uint64_t frequency, SettlingTime settling, Samples samples, bool halt, LowpassFilter filter) {
uint16_t send[7];
// select which point this sweep config is for
send[0] = pointnum & 0x1FFF;
// assemble sweep config from required fields of PLL registers
send[1] = (LORegs[4] & 0x00700000) >> 14 | (LORegs[3] & 0xFC000000) >> 26;
uint16_t LO_N = (LORegs[0] & 0x7FFF8000) >> 15;
uint16_t LO_FRAC = (LORegs[0] & 0x00007FF8) >> 3;
uint16_t LO_M = (LORegs[1] & 0x00007FF8) >> 3;
uint16_t LO_VCO = (LORegs[3] & 0xFC000000) >> 26;
uint16_t LO_DIV_A = (LORegs[4] & 0x00700000) >> 20;
uint16_t Source_N = (SourceRegs[0] & 0x7FFF8000) >> 15;
uint16_t Source_FRAC = (SourceRegs[0] & 0x00007FF8) >> 3;
uint16_t Source_M = (SourceRegs[1] & 0x00007FF8) >> 3;
uint16_t Source_VCO = (SourceRegs[3] & 0xFC000000) >> 26;
uint16_t Source_DIV_A = (SourceRegs[4] & 0x00700000) >> 20;
send[1] = LO_M >> 4;
if (halt) {
send[1] |= 0x8000;
}
if (lowband) {
send[1] |= 0x4000;
}
switch(filter) {
case LowpassFilter::Auto:
send[1] |= (int) settling << 13;
send[1] |= (int) samples << 10;
if(filter == LowpassFilter::Auto) {
// Select source LP filter
if (frequency >= 3500000000) {
send[1] |= 0x0600;
send[1] |= (int) LowpassFilter::None << 8;
} else if (frequency >= 1800000000) {
send[1] |= 0x0400;
send[1] |= (int) LowpassFilter::M3500 << 8;
} else if (frequency >= 900000000) {
send[1] |= 0x0200;
send[1] |= (int) LowpassFilter::M1880 << 8;
} else {
send[1] |= (int) LowpassFilter::M947 << 8;
}
break;
case LowpassFilter::M947: break;
case LowpassFilter::M1880: send[1] |= 0x0200; break;
case LowpassFilter::M3500: send[1] |= 0x0400; break;
case LowpassFilter::None: send[1] |= 0x0600; break;
} else {
send[1] |= (int) filter << 8;
}
send[2] = (LORegs[1] & 0x00007FF8) << 1 | (LORegs[0] & 0x00007800) >> 11;
send[3] = (LORegs[0] & 0x000007F8) << 5 | (LORegs[0] & 0x7F800000) >> 23;
send[4] = (LORegs[0] & 0x007F8000) >> 7 | (attenuation & 0x7F) << 1 | (SourceRegs[4] & 0x00400000) >> 22;
send[5] = (SourceRegs[4] & 0x00300000) >> 6 | (SourceRegs[3] & 0xFC000000) >> 18 | (SourceRegs[1] & 0x00007F80) >> 7;
send[6] = (SourceRegs[1] & 0x00000078) << 9 | (SourceRegs[0] & 0x00007FF8) >> 3;
send[7] = (SourceRegs[0] & 0x7FFF8000) >> 15;
send[2] = (LO_M & 0x000F) << 12 | LO_FRAC;
send[3] = LO_DIV_A << 13 | LO_VCO << 7 | LO_N;
send[4] = (uint16_t) attenuation << 8 | Source_M >> 4;
if (lowband) {
send[4] |= 0x8000;
}
send[5] = (Source_M & 0x000F) << 12 | Source_FRAC;
send[6] = Source_DIV_A << 13 | Source_VCO << 7 | Source_N;
Low(CS);
HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) send, 8, 100);
HAL_SPI_Transmit(&FPGA_SPI, (uint8_t*) send, 7, 100);
High(CS);
}

View File

@ -67,20 +67,37 @@ enum class LowpassFilter {
Auto = 0xFF,
};
enum class SettlingTime {
us20 = 0x00,
us60 = 0x01,
us180 = 0x02,
us540 = 0x03,
};
enum class Samples {
SPPRegister = 0x00,
S128 = 0x01,
S384 = 0x02,
S896 = 0x03,
S3072 = 0x04,
S9088 = 0x05,
S30464 = 0x06,
S91392 = 0x07,
};
bool Configure(Flash *f, uint32_t start_address, uint32_t bitstream_size);
using HaltedCallback = void(*)(void);
bool Init(HaltedCallback cb = nullptr);
void SetNumberOfPoints(uint16_t npoints);
void SetSamplesPerPoint(uint32_t nsamples);
void SetSettlingTime(uint16_t us);
void Enable(Periphery p, bool enable = true);
void Disable(Periphery p);
void EnableInterrupt(Interrupt i);
void DisableInterrupt(Interrupt i);
void WriteMAX2871Default(uint32_t *DefaultRegs);
void WriteSweepConfig(uint16_t pointnum, bool lowband, uint32_t *SourceRegs, uint32_t *LORegs,
uint8_t attenuation, uint64_t frequency, bool halt = false, LowpassFilter filter = LowpassFilter::Auto);
uint8_t attenuation, uint64_t frequency, SettlingTime settling, Samples samples, bool halt = false, LowpassFilter filter = LowpassFilter::Auto);
using ReadCallback = void(*)(SamplingResult result);
bool InitiateSampleRead(ReadCallback cb);
ADCLimits GetADCLimits();

View File

@ -224,7 +224,6 @@ bool VNA::ConfigureSweep(Protocol::SweepSettings s, SweepCallback cb) {
FPGA::AbortSweep();
uint16_t points = settings.points <= FPGA::MaxPoints ? settings.points : FPGA::MaxPoints;
// Configure sweep
FPGA::SetSettlingTime(500);
FPGA::SetNumberOfPoints(points);
uint32_t samplesPerPoint = (1000000 / s.if_bandwidth);
// round up to next multiple of 128 (128 samples are spread across 35 IF2 periods)
@ -316,7 +315,9 @@ bool VNA::ConfigureSweep(Protocol::SweepSettings s, SweepCallback cb) {
needs_halt = true;
}
LO1.SetFrequency(freq + used_IF);
FPGA::WriteSweepConfig(i, lowband, Source.GetRegisters(), LO1.GetRegisters(), attenuator, freq, needs_halt);
FPGA::WriteSweepConfig(i, lowband, Source.GetRegisters(),
LO1.GetRegisters(), attenuator, freq, FPGA::SettlingTime::us540,
FPGA::Samples::SPPRegister, needs_halt);
last_lowband = lowband;
}
// // revert clk configuration to previous value (might have been changed in sweep calculation)
@ -382,11 +383,11 @@ bool VNA::ConfigureManual(Protocol::ManualControl m, StatusCallback cb) {
FPGA::SetNumberOfPoints(1);
FPGA::SetSamplesPerPoint(m.Samples);
FPGA::SetSettlingTime(1);
// Configure single sweep point
FPGA::WriteSweepConfig(0, !m.SourceHighband, Source.GetRegisters(),
LO1.GetRegisters(), m.attenuator, 0, 0,
LO1.GetRegisters(), m.attenuator, 0, FPGA::SettlingTime::us20,
FPGA::Samples::SPPRegister, 0,
(FPGA::LowpassFilter) m.SourceHighLowpass);
// Enable/Disable periphery