Commit 5889bebd authored by Jan Pospisil's avatar Jan Pospisil

added AD9512 OUT4 fine delay control

parent aa431040
......@@ -30,9 +30,10 @@
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author
-- Date Version Author Comment
-- 2016-06-21 0.1 Tom Levens
-- 2016-08-24 1.0 Jan Pospisil
-- 2016-09-07 1.1 Jan Pospisil added OUT4 fine delay configuration
-------------------------------------------------------------------------------
library ieee;
......@@ -52,6 +53,10 @@ entity Ad9512Control is
ClockSelection_i: in std_logic; -- 0 - CLK1, 1 - CLK2
ClockRatioMinus1_ib: in unsigned(4 downto 0);
FineDelayEnable_i: in std_logic;
FineDelay_ib: in unsigned(4 downto 0);
FineDelayCurrent_ib: in unsigned(2 downto 0);
FineDelayCapacitors_ib: in unsigned(2 downto 0);
SpiAd9512Sclk_o: out std_logic;
SpiAd9512Mosi_o: out std_logic;
......@@ -88,6 +93,10 @@ architecture syn of Ad9512Control is
signal ClockSelection: std_logic := '0';
signal ClockRatioMinus1_b: unsigned(ClockRatioMinus1_ib'range) := to_unsigned(1-1, ClockRatioMinus1_ib'length);
signal FineDelayEnable: std_logic := '0';
signal FineDelay_b: unsigned(FineDelay_ib'range) := to_unsigned(0, FineDelay_ib'length);
signal FineDelayCurrent_b: unsigned(FineDelayCurrent_ib'range) := to_unsigned(0, FineDelayCurrent_ib'length);
signal FineDelayCapacitors_b: unsigned(FineDelayCapacitors_ib'range) := to_unsigned(0, FineDelayCapacitors_ib'length);
------------------------------------------------------------------------
-- AD9512 config registers
......@@ -104,7 +113,7 @@ architecture syn of Ad9512Control is
return std_logic_vector(to_unsigned(0, ZerosToPad)) & Reg.Address & Reg.Data;
end function;
constant c_Ad9512RegisterCount: positive := 14;
constant c_Ad9512RegisterCount: positive := 17;
type t_Ad9512RegisterFiled is array (integer range <>) of t_Ad9512Register;
......@@ -200,7 +209,7 @@ architecture syn of Ad9512Control is
signal SeqCurrentState: t_State := c_ResetState;
-- Write counter
signal SeqCnt: unsigned(3 downto 0) := (others => '0');
signal SeqCnt: unsigned(f_log2(c_Ad9512RegisterCount)-1 downto 0) := (others => '0');
signal SeqCntEnable, SeqCntReset: std_logic := '0';
signal SeqCntOverflow: std_logic;
......@@ -213,15 +222,23 @@ begin
if Cfg_i = '1' then
ClockSelection <= ClockSelection_i;
ClockRatioMinus1_b <= ClockRatioMinus1_ib;
FineDelayEnable <= FineDelayEnable_i;
FineDelay_b <= FineDelay_ib;
FineDelayCurrent_b <= FineDelayCurrent_ib;
FineDelayCapacitors_b <= FineDelayCapacitors_ib;
end if;
end if;
end process;
Ad9512Registers <= (
-- fine delay on output OUT4
(X"34", if_slv(FineDelayEnable = '1', X"00", X"01")),
(X"35", "00" & std_logic_vector(FineDelayCapacitors_b) & std_logic_vector(FineDelayCurrent_b)),
(X"36", "00" & std_logic_vector(FineDelay_b) & "0"),
-- power down unused output (OUT2)
(X"3f", X"03"),
-- select CLK1 input, power down CLK2 input
(X"45", if_slv(ClockSelection = '0', X"05", X"02")),
(X"45", if_slv(ClockSelection = '1', X"02", X"05")),
-- output frequency 200 MHz (divide by 2)
(X"4a", f_CreateDivideReg1(ClockRatioMinus1_b)), -- OUT0
(X"4c", f_CreateDivideReg1(ClockRatioMinus1_b)), -- OUT1
......
......@@ -37,6 +37,7 @@
-- added clock_stable status bit
-- 2016-09-05 1.2 Jan Pospisil Independent Trigger Latency for the two
-- channels (issue 1389)
-- 2016-09-07 1.3 Jan Pospisil added AD9512 OUT4 fine delay
-------------------------------------------------------------------------------
library ieee;
......@@ -118,7 +119,7 @@ architecture syn of FfpgSlave is
signal LedSignal_b: std_logic_vector(4 downto 1);
signal Ad9512ClockSelectionChanged: std_logic;
signal Ad9512ClockSelectionChanged, Ad9512FineDelayEnableChanged: std_logic;
signal Ad9512ClockSelection, Ad9512StartConfig: std_logic;
signal Ad9512SyncePulse: std_logic;
......@@ -308,8 +309,22 @@ begin
Signal_ib => WbRegsOutput.control_clock_selection_o,
Change_o => Ad9512ClockSelectionChanged
);
cAd9512FineDelayEnableChange: entity work.EdgeDetector(both)
port map (
Clk_ik => Clk_ik,
Signal_i => WbRegsOutput.control_fine_delay_enable_o,
Edge_o => Ad9512FineDelayEnableChanged
);
Ad9512StartConfig <= WbRegsOutput.clock_ratio_m1_load_o or Ad9512ClockSelectionChanged;
Ad9512StartConfig <=
Ad9512ClockSelectionChanged or
WbRegsOutput.clock_ratio_m1_load_o or
Ad9512FineDelayEnableChanged or
(
(WbRegsOutput.fine_delay_value_load_o or WbRegsOutput.fine_delay_current_load_o or WbRegsOutput.fine_delay_capacitors_load_o)
and WbRegsOutput.control_fine_delay_enable_o
);
cAd9512Control: entity work.Ad9512Control(syn)
generic map (
......@@ -324,6 +339,10 @@ begin
ClockSelection_i => Ad9512ClockSelection,
ClockRatioMinus1_ib => WbRegsOutput.clock_ratio_m1_o,
FineDelayEnable_i => WbRegsOutput.control_fine_delay_enable_o,
FineDelay_ib => WbRegsOutput.fine_delay_value_o,
FineDelayCurrent_ib => WbRegsOutput.fine_delay_current_o,
FineDelayCapacitors_ib => WbRegsOutput.fine_delay_capacitors_o,
SpiAd9512Sclk_o => SpiAd9512Sclk_o,
SpiAd9512Mosi_o => SpiAd9512Mosi_o,
......
......@@ -32,6 +32,7 @@
-- 2016-08-24 1.0 Jan Pospisil
-- 2016-09-05 1.1 Jan Pospisil Independent Trigger Latency for the two
-- channels (issue 1389)
-- 2016-09-07 1.2 Jan Pospisil added AD9512 OUT4 fine delay
-------------------------------------------------------------------------------
library ieee;
......@@ -84,6 +85,9 @@ architecture syn of WbSlaveWrapper is
signal overflow: unsigned(15 downto 0) := (others => '0');
signal ch1_trigger_latency: unsigned(15 downto 0) := (others => '0');
signal ch2_trigger_latency: unsigned(15 downto 0) := (others => '0');
signal fine_delay_value: unsigned(4 downto 0) := (others => '0');
signal fine_delay_current: unsigned(2 downto 0) := (others => '0');
signal fine_delay_capacitors: unsigned(2 downto 0) := (others => '0');
-- delayed load signals for LOAD_EXT fields
signal vcxo_voltage_load: std_logic := '0';
signal clock_ratio_m1_load: std_logic := '0';
......@@ -95,6 +99,9 @@ architecture syn of WbSlaveWrapper is
signal overflow_load: std_logic := '0';
signal ch1_trigger_latency_load: std_logic := '0';
signal ch2_trigger_latency_load: std_logic := '0';
signal fine_delay_value_load: std_logic := '0';
signal fine_delay_current_load: std_logic := '0';
signal fine_delay_capacitors_load: std_logic := '0';
begin
......@@ -147,6 +154,9 @@ begin
overflow_load <= '0';
ch1_trigger_latency_load <= '0';
ch2_trigger_latency_load <= '0';
fine_delay_value_load <= '0';
fine_delay_current_load <= '0';
fine_delay_capacitors_load <= '0';
vcxo_voltage <= (others => '0');
clock_ratio_m1 <= (others => '0');
......@@ -158,6 +168,9 @@ begin
overflow <= (others => '0');
ch1_trigger_latency <= (others => '0');
ch2_trigger_latency <= (others => '0');
fine_delay_value <= (others => '0');
fine_delay_current <= (others => '0');
fine_delay_capacitors <= (others => '0');
else
vcxo_voltage_load <= '0';
clock_ratio_m1_load <= '0';
......@@ -169,6 +182,9 @@ begin
overflow_load <= '0';
ch1_trigger_latency_load <= '0';
ch2_trigger_latency_load <= '0';
fine_delay_value_load <= '0';
fine_delay_current_load <= '0';
fine_delay_capacitors_load <= '0';
if WbRegsOutput.vcxo_voltage_load_o = '1' then
vcxo_voltage <= WbRegsOutput.vcxo_voltage_o;
......@@ -210,13 +226,25 @@ begin
ch2_trigger_latency <= WbRegsOutput.ch2_trigger_latency_o;
ch2_trigger_latency_load <= '1';
end if;
if WbRegsOutput.fine_delay_value_load_o = '1' then
fine_delay_value <= WbRegsOutput.fine_delay_value_o;
fine_delay_value_load <= '1';
end if;
if WbRegsOutput.fine_delay_current_load_o = '1' then
fine_delay_current <= WbRegsOutput.fine_delay_current_o;
fine_delay_current_load <= '1';
end if;
if WbRegsOutput.fine_delay_capacitors_load_o = '1' then
fine_delay_capacitors <= WbRegsOutput.fine_delay_capacitors_o;
fine_delay_capacitors_load <= '1';
end if;
end if;
end if;
end process;
pInputRegisters: process (
WbRegs_i,
vcxo_voltage, clock_ratio_m1, ch1_delay_set, ch1_delay_reset, ch2_delay_set, ch2_delay_reset, trigger_threshold, overflow, ch1_trigger_latency, ch2_trigger_latency
vcxo_voltage, clock_ratio_m1, ch1_delay_set, ch1_delay_reset, ch2_delay_set, ch2_delay_reset, trigger_threshold, overflow, ch1_trigger_latency, ch2_trigger_latency, fine_delay_value, fine_delay_current, fine_delay_capacitors
) is begin
-- #!@& ISE doesn't know VHDL 2008 (... process (all) ...)
-- by default, all values are passed
......@@ -232,12 +260,15 @@ begin
WbRegsInput.overflow_i <= overflow;
WbRegsInput.ch1_trigger_latency_i <= ch1_trigger_latency;
WbRegsInput.ch2_trigger_latency_i <= ch2_trigger_latency;
WbRegsInput.fine_delay_value_i <= fine_delay_value;
WbRegsInput.fine_delay_current_i <= fine_delay_current;
WbRegsInput.fine_delay_capacitors_i <= fine_delay_capacitors;
end process;
pOutputRegisters: process (
WbRegsOutput,
vcxo_voltage, clock_ratio_m1, ch1_delay_set, ch1_delay_reset, ch2_delay_set, ch2_delay_reset, trigger_threshold, overflow, ch1_trigger_latency, ch2_trigger_latency,
vcxo_voltage_load, clock_ratio_m1_load, ch1_delay_set_load, ch1_delay_reset_load, ch2_delay_set_load, ch2_delay_reset_load, trigger_threshold_load, overflow_load, ch1_trigger_latency_load, ch2_trigger_latency_load
vcxo_voltage, clock_ratio_m1, ch1_delay_set, ch1_delay_reset, ch2_delay_set, ch2_delay_reset, trigger_threshold, overflow, ch1_trigger_latency, ch2_trigger_latency, fine_delay_value, fine_delay_current, fine_delay_capacitors,
vcxo_voltage_load, clock_ratio_m1_load, ch1_delay_set_load, ch1_delay_reset_load, ch2_delay_set_load, ch2_delay_reset_load, trigger_threshold_load, overflow_load, ch1_trigger_latency_load, ch2_trigger_latency_load, fine_delay_value_load, fine_delay_current_load, fine_delay_capacitors_load
) is begin
-- #!@& ISE doesn't know VHDL 2008 (... process(all) ...)
-- by default, all values are passed
......@@ -253,6 +284,9 @@ begin
WbRegs_o.overflow_o <= overflow;
WbRegs_o.ch1_trigger_latency_o <= ch1_trigger_latency;
WbRegs_o.ch2_trigger_latency_o <= ch2_trigger_latency;
WbRegs_o.fine_delay_value_o <= fine_delay_value;
WbRegs_o.fine_delay_current_o <= fine_delay_current;
WbRegs_o.fine_delay_capacitors_o <= fine_delay_capacitors;
WbRegs_o.vcxo_voltage_load_o <= vcxo_voltage_load;
WbRegs_o.clock_ratio_m1_load_o <= clock_ratio_m1_load;
......@@ -264,6 +298,9 @@ begin
WbRegs_o.overflow_load_o <= overflow_load;
WbRegs_o.ch1_trigger_latency_load_o <= ch1_trigger_latency_load;
WbRegs_o.ch2_trigger_latency_load_o <= ch2_trigger_latency_load;
WbRegs_o.fine_delay_value_load_o <= fine_delay_value_load;
WbRegs_o.fine_delay_current_load_o <= fine_delay_current_load;
WbRegs_o.fine_delay_capacitors_load_o <= fine_delay_capacitors_load;
end process;
end architecture;
\ No newline at end of file
......@@ -157,6 +157,15 @@ peripheral {
type = MONOSTABLE;
};
field {
name = "AD9512 OUT4 fine delay enable";
description = "If set to 1, fine delay on OUT4 output of AD9512 is enabled. Fine delay itself can be set in a separate register.";
prefix = "fine_delay_enable";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
......@@ -372,6 +381,42 @@ peripheral {
};
};
reg {
name = "AD9512 OUT4 fine delay";
prefix = "fine_delay";
description = "Value of the AD9512 OUT4 output fine delay. The actual delay applied to the OUT4 output has an offset, i.e. it is non-zero even when zero is written to this register (when the fine delay is enabled - see the status register for the enable bit).";
field {
name = "AD9512 OUT4 fine delay value";
prefix = "value";
type = UNSIGNED;
size = 5;
load = LOAD_EXT;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
};
field {
name = "Ramp current";
prefix = "current";
type = UNSIGNED;
size = 3;
load = LOAD_EXT;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
};
field {
name = "Ramp capacitors";
prefix = "capacitors";
type = UNSIGNED;
size = 3;
load = LOAD_EXT;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
};
};
ram {
name = "CH1 SET serial stream";
prefix = "ch1_set_mem";
......
......@@ -80,6 +80,13 @@ def StopAndDisable(pg, channel):
pg.StopChannel(channel)
pg.DisableChannel(channel)
def PrintFrequency(pg):
frequency = pg.GetFrequency()
if frequency is not None:
print("RF clock frequency: "+str(frequency/1.0e6) + " MHz")
else:
print("RF clock frequency: (unstable)")
# create FFPG driver for FMC slot
pg = Ffpg(fmcSlot = 0)
......@@ -104,11 +111,7 @@ TestSinglePulse(pg, channel = 1)
# print some info
pg.PrintVersion()
print("Actual temperature: "+str(pg.temp.ReadTemperature()) + " °C")
frequency = pg.GetFrequency()
if frequency is not None:
print("RF clock frequency: "+str(frequency/1.0e6) + " MHz")
else:
print("RF clock frequency: (unstable)")
PrintFrequency(pg)
pg.PrintControl()
pg.PrintStatus()
pg.PrintDebug()
......
......@@ -29,6 +29,7 @@
## Revisions :
## Date Version Author Comment
## 2016-09-06 1.0 Jan Pospisil Derived from the initial example driver
## 2016-09-07 1.1 Jan Pospisil added AD9512 OUT4 fine delay
##-----------------------------------------------------------------------------
import time
......@@ -386,3 +387,19 @@ class Ffpg(object):
# configure pulse positions
for bunch in bunches:
self._ConfigurePulse(channel, (bunch * rfToBunchRatio)+pulseStartBit, (bunch * rfToBunchRatio)+pulseStopBit, 1)
def SetClockFineDelay(self, fineDelay, current = 0, capacitors = 0):
"""
enable and set AD9512 OUT4 output fine delay
fineDelay = <0, 31>
"""
# enable fine delay
self.wb.SetBits("control", (1<<10))
# set fine delay
fineDelayReg = fineDelay & 0x1F
fineDelayReg |= (current & 0x7) << 5
fineDelayReg |= (capacitors & 0x7) << 8
self.wb.Write("fine_delay", fineDelayReg)
def DisableClockFineDelay(self):
self.wb.SetBits("control", (1<<10), 0)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment