Commit 9e14427f authored by Tim Mottram's avatar Tim Mottram Committed by Dimitris Lampridis

hdl: Preliminary support for logical OR of internal threshold triggers

Signed-off-by: 's avatarDimitris Lampridis <Dimitris.Lampridis@cern.ch>
parent b98da95d
This diff is collapsed.
......@@ -9,7 +9,7 @@
-- Dimitrios Lampridis <dimitrios.lampridis@cern.ch>
-- Company : CERN (BE-CO-HT)
-- Created : 2011-02-24
-- Last update: 2016-06-23
-- Last update: 2018-01-22
-- Standard : VHDL'93/02
-------------------------------------------------------------------------------
-- Description: FMC ADC 100Ms/s core.
......@@ -195,6 +195,8 @@ architecture rtl of fmc_adc_100Ms_core is
------------------------------------------------------------------------------
type t_acq_fsm_state is (IDLE, PRE_TRIG, WAIT_TRIG, POST_TRIG, TRIG_TAG, DECR_SHOT);
type t_data_pipe is array (natural range<>) of std_logic_vector(63 downto 0);
type t_fmc_adc_vec8_array is array (positive range<>) of std_logic_vector(7 downto 0);
type t_fmc_adc_vec16_array is array (positive range<>) of std_logic_vector(15 downto 0);
------------------------------------------------------------------------------
-- Signals declaration
......@@ -236,20 +238,22 @@ architecture rtl of fmc_adc_100Ms_core is
signal ext_trig_p, ext_trig_n : std_logic;
signal time_trig : std_logic;
signal int_trig : std_logic;
signal int_trig_over_thres : std_logic;
signal int_trig_over_thres_d : std_logic;
signal int_trig_over_thres_filt : std_logic;
signal int_trig_over_thres_filt_d : std_logic;
signal int_trig_sel : std_logic_vector(1 downto 0);
signal int_trig_data : std_logic_vector(15 downto 0);
signal int_trig_thres : std_logic_vector(15 downto 0);
signal int_ch_trig : std_logic_vector(1 to 4);
signal int_trig_over_thres : std_logic_vector(1 to 4);
signal int_trig_over_thres_d : std_logic_vector(1 to 4);
signal int_trig_over_thres_filt : std_logic_vector(1 to 4);
signal int_trig_over_thres_filt_d : std_logic_vector(1 to 4);
signal int_trig_data : t_fmc_adc_vec16_array(1 to 4);
signal int_trig_thres : t_fmc_adc_vec16_array(1 to 4);
signal int_trig_test_en : std_logic;
signal int_trig_thres_filt : std_logic_vector(7 downto 0);
signal int_trig_thres_filt : t_fmc_adc_vec8_array(1 to 4);
signal hw_trig_pol : std_logic;
signal int_trig_pol : std_logic_vector(1 to 4);
signal hw_trig : std_logic;
signal hw_trig_t : std_logic;
signal hw_trig_sel : std_logic_vector(1 downto 0);
signal hw_trig_en : std_logic;
signal int_trig_en : std_logic_vector(1 to 4);
signal sw_trig : std_logic;
signal sw_trig_t : std_logic;
signal sw_trig_en : std_logic;
......@@ -674,13 +678,26 @@ begin
trig_led_man <= csr_regout.ctl_trig_led_o;
acq_led_man <= csr_regout.ctl_acq_led_o;
hw_trig_sel <= csr_regout.trig_cfg_hw_trig_sel_o;
hw_trig_pol <= csr_regout.trig_cfg_hw_trig_pol_o;
hw_trig_pol <= csr_regout.trig_cfg_ex_hw_trig_pol_o;
int_trig_pol(1) <= csr_regout.ch1_trig_trig_pol_o;
int_trig_pol(2) <= csr_regout.ch2_trig_trig_pol_o;
int_trig_pol(3) <= csr_regout.ch3_trig_trig_pol_o;
int_trig_pol(4) <= csr_regout.ch4_trig_trig_pol_o;
hw_trig_en <= csr_regout.trig_cfg_hw_trig_en_o;
sw_trig_en <= csr_regout.trig_cfg_sw_trig_en_o;
int_trig_sel <= csr_regout.trig_cfg_int_trig_sel_o;
int_trig_en(1) <= csr_regout.ch1_trig_trig_en_o;
int_trig_en(2) <= csr_regout.ch2_trig_trig_en_o;
int_trig_en(3) <= csr_regout.ch3_trig_trig_en_o;
int_trig_en(4) <= csr_regout.ch4_trig_trig_en_o;
int_trig_test_en <= csr_regout.trig_cfg_int_trig_test_en_o;
int_trig_thres_filt <= csr_regout.trig_cfg_int_trig_thres_filt_o;
int_trig_thres <= csr_regout.trig_cfg_int_trig_thres_o;
int_trig_thres_filt(1) <= csr_regout.ch1_trig_int_trig_thres_filt_o;
int_trig_thres_filt(2) <= csr_regout.ch2_trig_int_trig_thres_filt_o;
int_trig_thres_filt(3) <= csr_regout.ch3_trig_int_trig_thres_filt_o;
int_trig_thres_filt(4) <= csr_regout.ch4_trig_int_trig_thres_filt_o;
int_trig_thres(1) <= csr_regout.ch1_trig_int_trig_thres_o;
int_trig_thres(2) <= csr_regout.ch2_trig_int_trig_thres_o;
int_trig_thres(3) <= csr_regout.ch3_trig_int_trig_thres_o;
int_trig_thres(4) <= csr_regout.ch4_trig_int_trig_thres_o;
trig_delay <= csr_regout.trig_dly_o;
sw_trig_t <= csr_regout.sw_trig_wr_o;
shots_value <= csr_regout.shots_nb_o;
......@@ -759,22 +776,19 @@ begin
ppulse_o => time_trig);
-- Internal hardware trigger
int_trig_data <= data_calibr_out(15 downto 0) when int_trig_sel = "00" else -- CH1 selected
data_calibr_out(31 downto 16) when int_trig_sel = "01" else -- CH2 selected
data_calibr_out(47 downto 32) when int_trig_sel = "10" else -- CH3 selected
data_calibr_out(63 downto 48) when int_trig_sel = "11" else -- CH4 selected
(others => '0');
g_int_trig : for I in 1 to 4 generate
int_trig_data(I) <= data_calibr_out(16*I-1 downto 16*I-16);
-- Detects input data going over the internal trigger threshold
p_int_trig : process (fs_clk, fs_rst_n)
begin
if fs_rst_n = '0' then
int_trig_over_thres <= '0';
if (fs_rst_n = '0' or int_trig_en(I) = '0') then
int_trig_over_thres(I) <= '0';
elsif rising_edge(fs_clk) then
if signed(int_trig_data) > signed(int_trig_thres) then
int_trig_over_thres <= '1';
if signed(int_trig_data(I)) > signed(int_trig_thres(I)) then
int_trig_over_thres(I) <= '1';
else
int_trig_over_thres <= '0';
int_trig_over_thres(I) <= '0';
end if;
end if;
end process p_int_trig;
......@@ -787,23 +801,26 @@ begin
port map(
clk_i => fs_clk,
rst_n_i => fs_rst_n,
len_i => int_trig_thres_filt(7 downto 0),
dat_i => int_trig_over_thres,
dat_o => int_trig_over_thres_filt
len_i => int_trig_thres_filt(I),
dat_i => int_trig_over_thres(I),
dat_o => int_trig_over_thres_filt(I)
);
-- Detects whether it's a positive or negative slope
p_int_trig_slope : process (fs_clk, fs_rst_n)
begin
if fs_rst_n = '0' then
int_trig_over_thres_filt_d <= '0';
int_trig_over_thres_filt_d(I) <= '0';
elsif rising_edge(fs_clk) then
int_trig_over_thres_filt_d <= int_trig_over_thres_filt;
int_trig_over_thres_filt_d(I) <= int_trig_over_thres_filt(I);
end if;
end process;
int_trig <= int_trig_over_thres_filt and not(int_trig_over_thres_filt_d) when hw_trig_pol = '0' else -- positive slope
not(int_trig_over_thres_filt) and int_trig_over_thres_filt_d; -- negative slope
int_ch_trig(I) <= int_trig_over_thres_filt(I) and not(int_trig_over_thres_filt_d(I)) when int_trig_pol(I) = '0' else -- positive slope
not(int_trig_over_thres_filt(I)) and int_trig_over_thres_filt_d(I); -- negative slope
end generate g_int_trig;
int_trig <= int_ch_trig(1) or int_ch_trig(2) or int_ch_trig(3) or int_ch_trig(4);
-- Hardware trigger selection
-- 00: internal = adc data threshold
......@@ -952,8 +969,8 @@ begin
end process;
-- Internal trigger test mode
int_trig_over_thres_tst <= X"1000" when int_trig_over_thres = '1' else X"0000";
int_trig_over_thres_filt_tst <= X"1000" when int_trig_over_thres_filt = '1' else X"0000";
int_trig_over_thres_tst <= X"1000" when int_trig_over_thres(1) = '1' else X"0000";
int_trig_over_thres_filt_tst <= X"1000" when int_trig_over_thres_filt(1) = '1' else X"0000";
trig_tst <= X"1000" when trig_align = '1' else X"0000";
-- Delay data to compoensate for internal trigger detection
......
This diff is collapsed.
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : ../rtl/fmc_adc_100Ms_csr_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from fmc_adc_100Ms_csr.wb
-- Created : Thu Jun 16 17:04:12 2016
-- Created : Mon Jan 22 15:24:47 2018
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE fmc_adc_100Ms_csr.wb
......@@ -63,13 +63,10 @@ package fmc_adc_100ms_csr_wbgen2_pkg is
ctl_trig_led_o : std_logic;
ctl_acq_led_o : std_logic;
trig_cfg_hw_trig_sel_o : std_logic_vector(1 downto 0);
trig_cfg_hw_trig_pol_o : std_logic;
trig_cfg_ex_hw_trig_pol_o : std_logic;
trig_cfg_hw_trig_en_o : std_logic;
trig_cfg_sw_trig_en_o : std_logic;
trig_cfg_int_trig_sel_o : std_logic_vector(1 downto 0);
trig_cfg_int_trig_test_en_o : std_logic;
trig_cfg_int_trig_thres_filt_o : std_logic_vector(7 downto 0);
trig_cfg_int_trig_thres_o : std_logic_vector(15 downto 0);
trig_dly_o : std_logic_vector(31 downto 0);
sw_trig_o : std_logic_vector(31 downto 0);
sw_trig_wr_o : std_logic;
......@@ -81,18 +78,38 @@ package fmc_adc_100ms_csr_wbgen2_pkg is
ch1_gain_val_o : std_logic_vector(15 downto 0);
ch1_offset_val_o : std_logic_vector(15 downto 0);
ch1_sat_val_o : std_logic_vector(14 downto 0);
ch1_trig_trig_en_o : std_logic;
ch1_trig_trig_pol_o : std_logic;
ch1_trig_reserved_o : std_logic_vector(5 downto 0);
ch1_trig_int_trig_thres_filt_o : std_logic_vector(7 downto 0);
ch1_trig_int_trig_thres_o : std_logic_vector(15 downto 0);
ch2_ctl_ssr_o : std_logic_vector(6 downto 0);
ch2_gain_val_o : std_logic_vector(15 downto 0);
ch2_offset_val_o : std_logic_vector(15 downto 0);
ch2_sat_val_o : std_logic_vector(14 downto 0);
ch2_trig_trig_en_o : std_logic;
ch2_trig_trig_pol_o : std_logic;
ch2_trig_reserved_o : std_logic_vector(5 downto 0);
ch2_trig_int_trig_thres_filt_o : std_logic_vector(7 downto 0);
ch2_trig_int_trig_thres_o : std_logic_vector(15 downto 0);
ch3_ctl_ssr_o : std_logic_vector(6 downto 0);
ch3_gain_val_o : std_logic_vector(15 downto 0);
ch3_offset_val_o : std_logic_vector(15 downto 0);
ch3_sat_val_o : std_logic_vector(14 downto 0);
ch3_trig_trig_en_o : std_logic;
ch3_trig_trig_pol_o : std_logic;
ch3_trig_reserved_o : std_logic_vector(5 downto 0);
ch3_trig_int_trig_thres_filt_o : std_logic_vector(7 downto 0);
ch3_trig_int_trig_thres_o : std_logic_vector(15 downto 0);
ch4_ctl_ssr_o : std_logic_vector(6 downto 0);
ch4_gain_val_o : std_logic_vector(15 downto 0);
ch4_offset_val_o : std_logic_vector(15 downto 0);
ch4_sat_val_o : std_logic_vector(14 downto 0);
ch4_trig_trig_en_o : std_logic;
ch4_trig_trig_pol_o : std_logic;
ch4_trig_reserved_o : std_logic_vector(5 downto 0);
ch4_trig_int_trig_thres_filt_o : std_logic_vector(7 downto 0);
ch4_trig_int_trig_thres_o : std_logic_vector(15 downto 0);
end record;
constant c_fmc_adc_100ms_csr_out_registers_init_value: t_fmc_adc_100ms_csr_out_registers := (
......@@ -105,13 +122,10 @@ package fmc_adc_100ms_csr_wbgen2_pkg is
ctl_trig_led_o => '0',
ctl_acq_led_o => '0',
trig_cfg_hw_trig_sel_o => (others => '0'),
trig_cfg_hw_trig_pol_o => '0',
trig_cfg_ex_hw_trig_pol_o => '0',
trig_cfg_hw_trig_en_o => '0',
trig_cfg_sw_trig_en_o => '0',
trig_cfg_int_trig_sel_o => (others => '0'),
trig_cfg_int_trig_test_en_o => '0',
trig_cfg_int_trig_thres_filt_o => (others => '0'),
trig_cfg_int_trig_thres_o => (others => '0'),
trig_dly_o => (others => '0'),
sw_trig_o => (others => '0'),
sw_trig_wr_o => '0',
......@@ -123,18 +137,38 @@ package fmc_adc_100ms_csr_wbgen2_pkg is
ch1_gain_val_o => (others => '0'),
ch1_offset_val_o => (others => '0'),
ch1_sat_val_o => (others => '0'),
ch1_trig_trig_en_o => '0',
ch1_trig_trig_pol_o => '0',
ch1_trig_reserved_o => (others => '0'),
ch1_trig_int_trig_thres_filt_o => (others => '0'),
ch1_trig_int_trig_thres_o => (others => '0'),
ch2_ctl_ssr_o => (others => '0'),
ch2_gain_val_o => (others => '0'),
ch2_offset_val_o => (others => '0'),
ch2_sat_val_o => (others => '0'),
ch2_trig_trig_en_o => '0',
ch2_trig_trig_pol_o => '0',
ch2_trig_reserved_o => (others => '0'),
ch2_trig_int_trig_thres_filt_o => (others => '0'),
ch2_trig_int_trig_thres_o => (others => '0'),
ch3_ctl_ssr_o => (others => '0'),
ch3_gain_val_o => (others => '0'),
ch3_offset_val_o => (others => '0'),
ch3_sat_val_o => (others => '0'),
ch3_trig_trig_en_o => '0',
ch3_trig_trig_pol_o => '0',
ch3_trig_reserved_o => (others => '0'),
ch3_trig_int_trig_thres_filt_o => (others => '0'),
ch3_trig_int_trig_thres_o => (others => '0'),
ch4_ctl_ssr_o => (others => '0'),
ch4_gain_val_o => (others => '0'),
ch4_offset_val_o => (others => '0'),
ch4_sat_val_o => (others => '0')
ch4_sat_val_o => (others => '0'),
ch4_trig_trig_en_o => '0',
ch4_trig_trig_pol_o => '0',
ch4_trig_reserved_o => (others => '0'),
ch4_trig_int_trig_thres_filt_o => (others => '0'),
ch4_trig_int_trig_thres_o => (others => '0')
);
function "or" (left, right: t_fmc_adc_100ms_csr_in_registers) return t_fmc_adc_100ms_csr_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
......@@ -154,10 +188,10 @@ function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '0';
if x(i) = '1' then
tmp(i):= '1';
else
tmp(i):=x(i);
tmp(i):= '0';
end if;
end loop;
return tmp;
......
This diff is collapsed.
This diff is collapsed.
......@@ -151,9 +151,9 @@ peripheral {
};
field {
name = "Hardware trigger polarity";
name = "External Hardware trigger polarity";
description = "0: positive edge/slope\n1: negative edge/slope";
prefix = "hw_trig_pol";
prefix = "ex_hw_trig_pol";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
......@@ -180,17 +180,6 @@ peripheral {
clock = "fs_clk_i";
};
field {
name = "Channel selection for internal trigger";
description = "00: channel 1\n01: channel 2\n10: channel 3\n11: channel 4";
prefix = "int_trig_sel";
type = SLV;
size = 2;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
field {
name = "Enable internal trigger test mode";
description = "Test mode:\n ch1 = Channel 1 input(analogue)\n ch2 = Channel input over threshold (digital)\n ch3 = Channel input over threshold filtered (digital)\n ch4 = Trigger (digital)";
......@@ -201,27 +190,18 @@ peripheral {
clock = "fs_clk_i";
};
--[[
field {
name = "Internal trigger threshold glitch filter";
description = "Configures the internal trigger threshold glitch filter length.";
prefix = "int_trig_thres_filt";
type = SLV;
size = 8;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
field {
name = "Threshold for internal trigger";
description = "Treated as binary two's complement and compared to raw ADC data.";
prefix = "int_trig_thres";
name = "Reserved";
description = "Ignore on read, write with 0's";
prefix = "reserved";
type = SLV;
size = 16;
size = 26;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
]]
};
reg {
......@@ -521,6 +501,59 @@ peripheral {
]]
};
reg {
name = "Channel 1 trigger configuration register";
prefix = "ch1_trig";
field {
name = "Trigger enable for channel 1";
discription = "0: disable\n1: enable, Active only if internal trigger in Trigger Configuration is enabled";
prefix = "trig_en";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
field {
name = "Trigger polarity";
description = "0: positive edge/slope\n1: negative edge/slope";
prefix = "trig_pol";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
field {
name = "Reserved";
description = "Ignore on read, write with 0's";
prefix = "reserved";
type = SLV;
size = 6;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Internal trigger threshold glitch filter for Channel 1";
description = "Configures the internal trigger threshold glitch filter length.";
prefix = "int_trig_thres_filt";
type = SLV;
size = 8;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
field {
name = "Threshold for Channel 1 internal trigger";
description = "Treated as binary two's complement and compared to raw ADC data.";
prefix = "int_trig_thres";
type = SLV;
size = 16;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
};
reg {
name = "Channel 2 control register";
prefix = "ch2_ctl";
......@@ -652,6 +685,59 @@ peripheral {
]]
};
reg {
name = "Channel 2 trigger configuration register";
prefix = "ch2_trig";
field {
name = "Trigger enable for channel 2";
discription = "0: disable\n1: enable, Active only if internal trigger in Trigger Configuration is enabled";
prefix = "trig_en";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
field {
name = "Trigger polarity";
description = "0: positive edge/slope\n1: negative edge/slope";
prefix = "trig_pol";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
field {
name = "Reserved";
description = "Ignore on read, write with 0's";
prefix = "reserved";
type = SLV;
size = 6;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Internal trigger threshold glitch filter for Channel 2";
description = "Configures the internal trigger threshold glitch filter length.";
prefix = "int_trig_thres_filt";
type = SLV;
size = 8;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
field {
name = "Threshold for Channel 2 internal trigger";
description = "Treated as binary two's complement and compared to raw ADC data.";
prefix = "int_trig_thres";
type = SLV;
size = 16;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
};
reg {
name = "Channel 3 control register";
prefix = "ch3_ctl";
......@@ -783,6 +869,59 @@ peripheral {
]]
};
reg {
name = "Channel 3 trigger configuration register";
prefix = "ch3_trig";
field {
name = "Trigger enable for channel 3";
discription = "0: disable\n1: enable, Active only if internal trigger in Trigger Configuration is enabled";
prefix = "trig_en";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
field {
name = "Trigger polarity";
description = "0: positive edge/slope\n1: negative edge/slope";
prefix = "trig_pol";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
field {
name = "Reserved";
description = "Ignore on read, write with 0's";
prefix = "reserved";
type = SLV;
size = 6;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Internal trigger threshold glitch filter for Channel 3";
description = "Configures the internal trigger threshold glitch filter length.";
prefix = "int_trig_thres_filt";
type = SLV;
size = 8;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
field {
name = "Threshold for Channel 3 internal trigger";
description = "Treated as binary two's complement and compared to raw ADC data.";
prefix = "int_trig_thres";
type = SLV;
size = 16;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
};
reg {
name = "Channel 4 control register";
prefix = "ch4_ctl";
......@@ -914,6 +1053,60 @@ peripheral {
]]
};
reg {
name = "Channel 4 trigger configuration register";
prefix = "ch4_trig";
field {
name = "Trigger enable for channel 4";
discription = "0: disable\n1: enable, Active only if internal trigger in Trigger Configuration is enabled";
prefix = "trig_en";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
field {
name = "trigger polarity";
description = "0: positive edge/slope\n1: negative edge/slope";
prefix = "trig_pol";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
field {
name = "Reserved";
description = "Ignore on read, write with 0's";
prefix = "reserved";
type = SLV;
size = 6;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
name = "Internal trigger threshold glitch filter for Channel 4";
description = "Configures the internal trigger threshold glitch filter length.";
prefix = "int_trig_thres_filt";
type = SLV;
size = 8;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
field {
name = "Threshold for Channel 4 internal trigger";
description = "Treated as binary two's complement and compared to raw ADC data.";
prefix = "int_trig_thres";
type = SLV;
size = 16;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
clock = "fs_clk_i";
};
};
reg {
name = "Multi-shot sample depth register";
prefix = "multi_depth";
......
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