Commit a4f3e56c authored by Jan Pospisil's avatar Jan Pospisil

added trigger latency specification (not implemented yet); renamed some WB…

added trigger latency specification (not implemented yet); renamed some WB registers to better reflect it purpose
parent 9e19b2b1
......@@ -98,13 +98,15 @@ B) Controlling module logic
3.2) Modes of operation: There will be three modes of operation - a stop mode, a continuous mode
and an one-shot mode. In the *stop mode* no serial stream will be sent, no pulses will be
generated. In the *continuous mode*, streams will be outputted continually looping through
the memory. When the trigger signal will be received or memory overflow will happen (i.e.
progressing to the address of "overflow value"), a memory pointer will be reset to the
beginning of the memory. In the *one-shot mode*, the memory will be looped (up to "overflow
value") only once upon the trigger signal will be received. Then output serial streams will be
stopped, but mode selection will remain on one-shot.
the memory. When the memory overflow happen (i.e. progressing to the address of "overflow
value"), a memory pointer will be reset to the beginning of the memory. When the trigger
signal will be received, memory pointer will be set to predefined address "trigger latency".
In the *one-shot mode*, the memory will be looped (up to "overflow value") only once upon the
trigger signal will be received. Then output serial streams will be stopped, but mode
selection will remain on one-shot.
3.2.1) WB interface:
Overflow value (1 register common to both channels - value)
Trigger latency (1 register common to both channels - number of clock cycles)
Mode selection (in control register - 2x enum: stop/continuous/one-shot)
4) The temperature sensor will be connected as a separate slave inside FPGA module.
......
-- TODO:
-- - trigger latency
-- - modes
-- - synchronous to SerialClock_ik
......@@ -22,6 +23,7 @@ entity DelayedPulseGenerator is
ResMemData_ib32: in unsigned(31 downto 0);
ResMemReadStrobe_o: out std_logic;
Overflow_ib16: in unsigned(15 downto 0);
TriggerLatency_ib16: in unsigned(15 downto 0);
Mode_ib2: in std_logic_vector(1 downto 0);
Running_o: out std_logic;
-- generation (FMC), synchronous to SerialClock_ik
......
......@@ -106,10 +106,10 @@ begin
port map (
Clk_ik => Clk,
Reset_ir => Reset,
TriggerValue_ib16 => WbRegsOutput.trigger_register_o,
TriggerLoad_i => WbRegsOutput.trigger_register_load_o,
VcxoValue_ib16 => WbRegsOutput.vcxo_register_o,
VcxoLoad_i => WbRegsOutput.vcxo_register_load_o,
TriggerValue_ib16 => WbRegsOutput.trigger_threshold_o,
TriggerLoad_i => WbRegsOutput.trigger_threshold_load_o,
VcxoValue_ib16 => WbRegsOutput.vcxo_voltage_o,
VcxoLoad_i => WbRegsOutput.vcxo_voltage_load_o,
TriggerDac_o => TriggerDac_o,
VcxoDac_o => VcxoDac_o,
TriggerBusy_o => WbRegsInput.status_dac_trigger_busy_i,
......@@ -165,6 +165,7 @@ begin
ResMemData_ib32 => Ch1ResMemData_b32,
ResMemReadStrobe_o => Ch1ResMemReadStrobe,
Overflow_ib16 => WbRegsOutput.overflow_o,
TriggerLatency_ib16 => WbRegsOutput.trigger_latency_o,
Mode_ib2 => WbRegsOutput.control_ch1_mode_o,
Running_o => WbRegsInput.status_channel_1_running_i,
SerialClock_ik => SerialStreamClock,
......@@ -184,6 +185,7 @@ begin
ResMemData_ib32 => Ch2ResMemData_b32,
ResMemReadStrobe_o => Ch2ResMemReadStrobe,
Overflow_ib16 => WbRegsOutput.overflow_o,
TriggerLatency_ib16 => WbRegsOutput.trigger_latency_o,
Mode_ib2 => WbRegsOutput.control_ch2_mode_o,
Running_o => WbRegsInput.status_channel_2_running_i,
SerialClock_ik => SerialStreamClock,
......
......@@ -36,25 +36,25 @@ architecture syn of WbSlaveWrapper is
signal control_clock_selection: std_logic_vector(1 downto 0);
signal control_ch1_mode: std_logic_vector(1 downto 0);
signal control_ch2_mode: std_logic_vector(1 downto 0);
signal vcxo_register: unsigned(15 downto 0);
signal vcxo_voltage: unsigned(15 downto 0);
signal clock_divider_hi: unsigned(3 downto 0);
signal ch1_delay_set: unsigned(9 downto 0);
signal ch1_delay_reset: unsigned(9 downto 0);
signal ch2_delay_set: unsigned(9 downto 0);
signal ch2_delay_reset: unsigned(9 downto 0);
signal trigger_register: unsigned(15 downto 0);
signal trigger_threshold: unsigned(15 downto 0);
signal overflow: unsigned(15 downto 0);
-- delayed load signals for LOAD_EXT fields
signal control_clock_selection_load: std_logic;
signal control_ch1_mode_load: std_logic;
signal control_ch2_mode_load: std_logic;
signal vcxo_register_load: std_logic;
signal vcxo_voltage_load: std_logic;
signal clock_divider_hi_load: std_logic;
signal ch1_delay_set_load: std_logic;
signal ch1_delay_reset_load: std_logic;
signal ch2_delay_set_load: std_logic;
signal ch2_delay_reset_load: std_logic;
signal trigger_register_load: std_logic;
signal trigger_threshold_load: std_logic;
signal overflow_load: std_logic;
begin
......@@ -95,13 +95,13 @@ begin
control_clock_selection_load <= '0';
control_ch1_mode_load <= '0';
control_ch2_mode_load <= '0';
vcxo_register_load <= '0';
vcxo_voltage_load <= '0';
clock_divider_hi_load <= '0';
ch1_delay_set_load <= '0';
ch1_delay_reset_load <= '0';
ch2_delay_set_load <= '0';
ch2_delay_reset_load <= '0';
trigger_register_load <= '0';
trigger_threshold_load <= '0';
overflow_load <= '0';
if WbRegsOutput.control_clock_selection_load_o then
......@@ -116,9 +116,9 @@ begin
control_ch2_mode <= WbRegsOutput.control_ch2_mode_o;
control_ch2_mode_load <= '1';
end if;
if WbRegsOutput.vcxo_register_load_o then
vcxo_register <= WbRegsOutput.vcxo_register_o;
vcxo_register_load <= '1';
if WbRegsOutput.vcxo_voltage_load_o then
vcxo_voltage <= WbRegsOutput.vcxo_voltage_o;
vcxo_voltage_load <= '1';
end if;
if WbRegsOutput.clock_divider_hi_load_o then
clock_divider_hi <= WbRegsOutput.clock_divider_hi_o;
......@@ -140,9 +140,9 @@ begin
ch2_delay_reset <= WbRegsOutput.ch2_delay_reset_o;
ch2_delay_reset_load <= '1';
end if;
if WbRegsOutput.trigger_register_load_o then
trigger_register <= WbRegsOutput.trigger_register_o;
trigger_register_load <= '1';
if WbRegsOutput.trigger_threshold_load_o then
trigger_threshold <= WbRegsOutput.trigger_threshold_o;
trigger_threshold_load <= '1';
end if;
if WbRegsOutput.overflow_load_o then
overflow <= WbRegsOutput.overflow_o;
......@@ -158,13 +158,13 @@ begin
WbRegsInput.control_clock_selection_i <= control_clock_selection;
WbRegsInput.control_ch1_mode_i <= control_ch1_mode;
WbRegsInput.control_ch2_mode_i <= control_ch2_mode;
WbRegsInput.vcxo_register_i <= vcxo_register;
WbRegsInput.vcxo_voltage_i <= vcxo_voltage;
WbRegsInput.clock_divider_hi_i <= clock_divider_hi;
WbRegsInput.ch1_delay_set_i <= ch1_delay_set;
WbRegsInput.ch1_delay_reset_i <= ch1_delay_reset;
WbRegsInput.ch2_delay_set_i <= ch2_delay_set;
WbRegsInput.ch2_delay_reset_i <= ch2_delay_reset;
WbRegsInput.trigger_register_i <= trigger_register;
WbRegsInput.trigger_threshold_i <= trigger_threshold;
WbRegsInput.overflow_i <= overflow;
end process;
......@@ -175,24 +175,24 @@ begin
WbRegs_o.control_clock_selection_o <= control_clock_selection;
WbRegs_o.control_ch1_mode_o <= control_ch1_mode;
WbRegs_o.control_ch2_mode_o <= control_ch2_mode;
WbRegs_o.vcxo_register_o <= vcxo_register;
WbRegs_o.vcxo_voltage_o <= vcxo_voltage;
WbRegs_o.clock_divider_hi_o <= clock_divider_hi;
WbRegs_o.ch1_delay_set_o <= ch1_delay_set;
WbRegs_o.ch1_delay_reset_o <= ch1_delay_reset;
WbRegs_o.ch2_delay_set_o <= ch2_delay_set;
WbRegs_o.ch2_delay_reset_o <= ch2_delay_reset;
WbRegs_o.trigger_register_o <= trigger_register;
WbRegs_o.trigger_threshold_o <= trigger_threshold;
WbRegs_o.overflow_o <= overflow;
WbRegs_o.control_clock_selection_load_o <= control_clock_selection_load;
WbRegs_o.control_ch1_mode_load_o <= control_ch1_mode_load;
WbRegs_o.control_ch2_mode_load_o <= control_ch2_mode_load;
WbRegs_o.vcxo_register_load_o <= vcxo_register_load;
WbRegs_o.vcxo_voltage_load_o <= vcxo_voltage_load;
WbRegs_o.clock_divider_hi_load_o <= clock_divider_hi_load;
WbRegs_o.ch1_delay_set_load_o <= ch1_delay_set_load;
WbRegs_o.ch1_delay_reset_load_o <= ch1_delay_reset_load;
WbRegs_o.ch2_delay_set_load_o <= ch2_delay_set_load;
WbRegs_o.ch2_delay_reset_load_o <= ch2_delay_reset_load;
WbRegs_o.trigger_register_load_o <= trigger_register_load;
WbRegs_o.trigger_threshold_load_o <= trigger_threshold_load;
WbRegs_o.overflow_load_o <= overflow_load;
end process;
......
......@@ -105,8 +105,8 @@ package TestbenchPackage;
UniversalSubscriber #(.T(Ad5600Transaction)) TriggerDacSubscriber;
UniversalSubscriber #(.T(Ad5600Transaction)) VcxoDacSubscriber;
DacScoreboard #(.WbAddress(`GET_WB_WORD_ADDR(`ADDR_FFPG_TRIGGER_REGISTER))) TriggerDacScoreboard;
DacScoreboard #(.WbAddress(`GET_WB_WORD_ADDR(`ADDR_FFPG_VCXO_REGISTER))) VcxoDacScoreboard;
DacScoreboard #(.WbAddress(`GET_WB_WORD_ADDR(`ADDR_FFPG_TRIGGER_THRESHOLD))) TriggerDacScoreboard;
DacScoreboard #(.WbAddress(`GET_WB_WORD_ADDR(`ADDR_FFPG_VCXO_VOLTAGE))) VcxoDacScoreboard;
function new(string name, uvm_component parent);
super.new(name, parent);
......@@ -139,8 +139,8 @@ package TestbenchPackage;
TriggerDacSubscriber = UniversalSubscriber #(.T(Ad5600Transaction))::type_id::create("TriggerDacSubscriber", this);
VcxoDacSubscriber = UniversalSubscriber #(.T(Ad5600Transaction))::type_id::create("VcxoDacSubscriber", this);
TriggerDacScoreboard = DacScoreboard #(.WbAddress(`GET_WB_WORD_ADDR(`ADDR_FFPG_TRIGGER_REGISTER)))::type_id::create("TriggerDacScoreboard", this);
VcxoDacScoreboard = DacScoreboard #(.WbAddress(`GET_WB_WORD_ADDR(`ADDR_FFPG_VCXO_REGISTER)))::type_id::create("VcxoDacScoreboard", this);
TriggerDacScoreboard = DacScoreboard #(.WbAddress(`GET_WB_WORD_ADDR(`ADDR_FFPG_TRIGGER_THRESHOLD)))::type_id::create("TriggerDacScoreboard", this);
VcxoDacScoreboard = DacScoreboard #(.WbAddress(`GET_WB_WORD_ADDR(`ADDR_FFPG_VCXO_VOLTAGE)))::type_id::create("VcxoDacScoreboard", this);
endfunction
function void connect_phase(uvm_phase phase);
......@@ -303,6 +303,7 @@ package TestbenchPackage;
rand int Channel;
rand int Overflow;
rand int TriggerLatency;
rand logic [`WB_DATA_WIDTH-1:0] SetData [0:(`STREAM_SIZE/`WB_DATA_WIDTH)-1];
rand logic [`WB_DATA_WIDTH-1:0] ResData [0:(`STREAM_SIZE/`WB_DATA_WIDTH)-1];
......@@ -314,6 +315,11 @@ package TestbenchPackage;
Overflow inside {[0:`STREAM_SIZE-1]};
}
constraint TriggerLatencyConstraint {
TriggerLatency inside {[0:20]};
TriggerLatency < Overflow;
}
function new (string name = "");
super.new(name);
endfunction
......@@ -334,6 +340,16 @@ package TestbenchPackage;
finish_item(tx);
assert(tx.response_e == WB_B3_RESPONSE_ACK_OK);
// configure trigger latency
tx = td_wb_tx::type_id::create("tx");
start_item(tx);
assert(tx.randomize());
tx.direction_e = WB_B3_DIR_WRITE;
tx.address = `GET_WB_WORD_ADDR(`ADDR_FFPG_TRIGGER_LATENCY);
tx.data = TriggerLatency;
finish_item(tx);
assert(tx.response_e == WB_B3_RESPONSE_ACK_OK);
// configure Set and Res data
for (int i = 0; i < OverflowInWords; i++) begin
// SetData
......@@ -426,7 +442,7 @@ package TestbenchPackage;
// test trigger DAC
seq = SeqSetDac::type_id::create("seq");
seq.Chip = Env_h.TriggerDacChip;
seq.WbDacAddress = `GET_WB_WORD_ADDR(`ADDR_FFPG_TRIGGER_REGISTER);
seq.WbDacAddress = `GET_WB_WORD_ADDR(`ADDR_FFPG_TRIGGER_THRESHOLD);
seq.WbStatusBit = `FFPG_STATUS_DAC_TRIGGER_BUSY_OFFSET;
assert(seq.randomize());
seq.start(Env_h.WbAgent.seqr);
......@@ -434,7 +450,7 @@ package TestbenchPackage;
// test VCXO DAC
seq = SeqSetDac::type_id::create("seq");
seq.Chip = Env_h.VcxoDacChip;
seq.WbDacAddress = `GET_WB_WORD_ADDR(`ADDR_FFPG_VCXO_REGISTER);
seq.WbDacAddress = `GET_WB_WORD_ADDR(`ADDR_FFPG_VCXO_VOLTAGE);
seq.WbStatusBit = `FFPG_STATUS_DAC_VCXO_BUSY_OFFSET;
assert(seq.randomize());
seq.start(Env_h.WbAgent.seqr);
......
......@@ -28,7 +28,7 @@
`define FFPG_CONTROL_CH1_MODE 32'h00000030
`define FFPG_CONTROL_CH2_MODE_OFFSET 6
`define FFPG_CONTROL_CH2_MODE 32'h000000c0
`define ADDR_FFPG_VCXO_REGISTER 16'h8
`define ADDR_FFPG_VCXO_VOLTAGE 16'h8
`define ADDR_FFPG_CLOCK_DIVIDER 16'hc
`define FFPG_CLOCK_DIVIDER_LO_OFFSET 0
`define FFPG_CLOCK_DIVIDER_LO 32'h0000000f
......@@ -38,9 +38,10 @@
`define ADDR_FFPG_CH1_DELAY_RESET 16'h14
`define ADDR_FFPG_CH2_DELAY_SET 16'h18
`define ADDR_FFPG_CH2_DELAY_RESET 16'h1c
`define ADDR_FFPG_TRIGGER_REGISTER 16'h20
`define ADDR_FFPG_TRIGGER_THRESHOLD 16'h20
`define ADDR_FFPG_OVERFLOW 16'h24
`define ADDR_FFPG_FREQUENCY 16'h28
`define ADDR_FFPG_TRIGGER_LATENCY 16'h28
`define ADDR_FFPG_FREQUENCY 16'h2c
`define BASE_FFPG_CH1_SET_MEM 16'h2000
`define SIZE_FFPG_CH1_SET_MEM 32'h800
`define BASE_FFPG_CH1_RES_MEM 16'h4000
......
......@@ -148,7 +148,7 @@ peripheral {
reg {
name = "VCXO voltage register";
prefix = "vcxo_register";
prefix = "vcxo_voltage";
description = "This register value D determines output voltage of the VCXO DAC.\nVoltage should be V_OUT = D * 5 / 65536 [V] (see datasheet), but is limited by 3.3 V supply voltage of the DAC.";
field {
......@@ -252,7 +252,7 @@ peripheral {
reg {
name = "Trigger threshold voltage register";
prefix = "trigger_register";
prefix = "trigger_threshold";
description = "This register value D determines output voltage of the trigger threshold DAC.\nVoltage should be V_OUT = D * 5 / 65536 [V] (see datasheet).";
field {
......@@ -279,6 +279,20 @@ peripheral {
access_dev = READ_WRITE;
};
};
reg {
name = "Trigger latency";
prefix = "trigger_latency";
description = "The latency of the trigger in number of clock cycles of the serial stream clock. When trigger is received, serial stream memory pointer is set to this value.";
field {
name = "Trigger latency value";
type = UNSIGNED;
size = 16;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Clock frequency";
......
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