fix CDS: correct SPI word count and use LO phase rotation

SPIConfig.vhd fixes:
- Change word_cnt check from 5 to 6 (was triggering one word early)
- Restore sweepconfig_buffer to 80 bits
- Fix shift operation to use correct indices (63 downto 0)

Sweep.vhd changes:
- Rotate LO phase instead of Source phase for CDS
- This avoids affecting devices connected to ports that may have
  settling time requirements after phase changes
- The LO is internal, so phase rotation has the same measurement
  effect without external side effects

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Roger Henderson 2026-02-04 09:05:18 +13:00
parent 1ea012aa57
commit ff9318d220
2 changed files with 22 additions and 21 deletions

View file

@ -131,7 +131,7 @@ architecture Behavioral of SPICommands is
signal interrupt_status : std_logic_vector(15 downto 0);
signal latched_result : std_logic_vector(287 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,
@ -310,13 +310,13 @@ begin
end case;
selected_register <= selected_register + 1;
when WriteSweepConfig =>
if word_cnt = 5 then
if word_cnt = 6 then
-- Sweep config data is complete (96 bits = 6 x 16-bit words)
SWEEP_DATA <= sweepconfig_buffer(79 downto 0) & spi_buf_out;
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;
-- read already handled in pre_complete, ignore
when ReadResult =>

View file

@ -107,33 +107,33 @@ architecture Behavioral of Sweep is
-- CDS phase tracking: 0 = first measurement (phase 0), 1 = second measurement (phase 180)
signal cds_phase : std_logic;
-- Source phase value: computed from CDS state
-- LO phase value: computed from CDS state
-- When CDS disabled or cds_phase=0: phase = 0
-- When CDS enabled and cds_phase=1: phase = M/2 (180 degrees)
signal source_phase : std_logic_vector(11 downto 0);
signal source_M : std_logic_vector(11 downto 0);
-- We rotate the LO phase (not Source) to avoid affecting devices connected to ports
signal lo_phase : std_logic_vector(11 downto 0);
signal lo_M : std_logic_vector(11 downto 0);
begin
CONFIG_ADDRESS <= std_logic_vector(point_cnt);
-- Extract Source M from config (bits 38:27)
source_M <= config_reg(38 downto 27);
-- Extract LO M from config (bits 87:76)
lo_M <= config_reg(87 downto 76);
-- Compute source phase for CDS
-- Phase 0: source_phase = 0
-- Phase 180: source_phase = M/2 (right shift by 1)
source_phase <= (others => '0') when (CDS_ENABLED = '0' or cds_phase = '0')
else '0' & source_M(11 downto 1); -- M/2 for 180 degree shift
-- Compute LO phase for CDS
-- Phase 0: lo_phase = 0
-- Phase 180: lo_phase = M/2 (right shift by 1)
lo_phase <= (others => '0') when (CDS_ENABLED = '0' or cds_phase = '0')
else '0' & lo_M(11 downto 1); -- M/2 for 180 degree shift
-- Phase adjustment is enabled when source_phase is non-zero (i.e., CDS phase 1)
SOURCE_PHASE_ADJUST <= '0' when source_phase = x"000" else '1';
-- Phase adjustment output (active when LO phase is non-zero, i.e., CDS phase 1)
SOURCE_PHASE_ADJUST <= '0' when lo_phase = x"000" else '1';
-- assemble registers
-- source register 0: N divider and fractional division value
SOURCE_REG_0 <= MAX2871_DEF_0(31) & "000000000" & config_reg(93) & config_reg(5 downto 0) & config_reg(26 downto 15) & "000";
-- source register 1: Phase value P[11:0] and Modulus value M[11:0]
-- REG1 format: [31] reserved | [30:29] CPL | [28:27] CPT | [26:15] P | [14:3] M | [2:0] addr=001
SOURCE_REG_1 <= MAX2871_DEF_1(31 downto 27) & source_phase & config_reg(38 downto 27) & "001";
-- source register 1: Modulus value (no phase adjustment - we adjust LO instead)
SOURCE_REG_1 <= MAX2871_DEF_1(31 downto 15) & config_reg(38 downto 27) & "001";
-- source register 3: VCO selection
SOURCE_REG_3 <= config_reg(11 downto 6) & MAX2871_DEF_3(25 downto 3) & "011";
-- output power A from config, output B disabled
@ -141,8 +141,9 @@ begin
-- LO register 0: N divider and fractional division value
LO_REG_0 <= MAX2871_DEF_0(31) & "000000000" & config_reg(94) & config_reg(54 downto 49) & config_reg(75 downto 64) & "000";
-- LO register 1: Modulus value
LO_REG_1 <= MAX2871_DEF_1(31 downto 15) & config_reg(87 downto 76) & "001";
-- LO register 1: Phase value P[11:0] and Modulus value M[11:0]
-- REG1 format: [31] reserved | [30:29] CPL | [28:27] CPT | [26:15] P | [14:3] M | [2:0] addr=001
LO_REG_1 <= MAX2871_DEF_1(31 downto 27) & lo_phase & config_reg(87 downto 76) & "001";
-- LO register 3: VCO selection
LO_REG_3 <= config_reg(60 downto 55) & MAX2871_DEF_3(25 downto 3) & "011";
-- both outputs enabled at +5dbm